开始编写后端管理页面
This commit is contained in:
parent
bacad0cd1c
commit
04475489ff
|
@ -1,5 +1,5 @@
|
|||
max_width = 120
|
||||
fn_single_line = true
|
||||
merge_imports = true
|
||||
imports_granularity = "Crate"
|
||||
match_block_trailing_comma = true
|
||||
newline_style = "Native"
|
|
@ -25,13 +25,13 @@ hyper = "0.14"
|
|||
image = { version = "0.23", features = ["jpeg", "png", "gif"] }
|
||||
lazy_static = "1.4"
|
||||
lazy-static-include = "3"
|
||||
once_cell = "1.7"
|
||||
parking_lot = "0.11"
|
||||
password-hash = { version = "0.1", features = ["rand_core"] }
|
||||
# percent-encoding = "2.1"
|
||||
# pulldown-cmark = "0.8"
|
||||
once_cell = "1.7"
|
||||
rand = "0.8"
|
||||
v_htmlescape = "0.13"
|
||||
regex = "1.4"
|
||||
# subtle = "2"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
|
@ -41,6 +41,7 @@ scrypt = { version = "0.6" }
|
|||
tokio = { version = "1", features = ["fs", "io-util", "macros", "rt", "rt-multi-thread", "signal", "time"] }
|
||||
uuid = { version = "0.8", features = ["v5"] }
|
||||
urlencoding = "1.1"
|
||||
v_htmlescape = "0.13"
|
||||
warp = "0.3"
|
||||
|
||||
# https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#platform-specific-dependencies
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>About</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>配置</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
博客基本信息配置
|
||||
</h1>
|
||||
<form class="pure-form pure-form-aligned">
|
||||
<fieldset>
|
||||
<div class="pure-control-group">
|
||||
<label for="aligned-name">博客名称</label>
|
||||
<input type="text" id="aligned-name" placeholder="博客名称" />
|
||||
<span class="pure-form-message-inline">This is a required field.</span>
|
||||
</div>
|
||||
<div class="pure-control-group">
|
||||
<label for="aligned-password">版权信息</label>
|
||||
<input type="password" id="aligned-password" placeholder="Password" />
|
||||
</div>
|
||||
<div class="pure-control-group">
|
||||
<label for="aligned-email">备案信息</label>
|
||||
<input type="email" id="aligned-email" placeholder="Email Address" />
|
||||
</div>
|
||||
<div class="pure-controls">
|
||||
<button type="submit" class="pure-button pure-button-primary">Submit</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -1,12 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Index</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
Welcome to Songday
|
||||
</h1>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,29 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>配置管理用户</title>
|
||||
</head>
|
||||
<body>
|
||||
<form class="pure-form pure-form-aligned" action="/user/login">
|
||||
<fieldset>
|
||||
<div class="pure-control-group">
|
||||
<label for="aligned-email">邮箱地址</label>
|
||||
<input type="email" id="aligned-email" placeholder="邮箱地址" />
|
||||
<span class="pure-form-message-inline">用于管理博客或忘记密码之用.</span>
|
||||
</div>
|
||||
<div class="pure-control-group">
|
||||
<label for="aligned-password1">登录密码</label>
|
||||
<input type="password" id="aligned-password1" placeholder="密码" />
|
||||
</div>
|
||||
<div class="pure-control-group">
|
||||
<label for="aligned-password2">确认密码</label>
|
||||
<input type="password" id="aligned-password2" placeholder="密码" />
|
||||
</div>
|
||||
<div class="pure-controls">
|
||||
<button type="submit" class="pure-button pure-button-primary">提交</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,29 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>配置管理用户</title>
|
||||
</head>
|
||||
<body>
|
||||
<form class="pure-form pure-form-aligned" action="/user/reg">
|
||||
<fieldset>
|
||||
<div class="pure-control-group">
|
||||
<label for="aligned-email">邮箱地址</label>
|
||||
<input type="email" id="aligned-email" placeholder="邮箱地址" />
|
||||
<span class="pure-form-message-inline">用于管理博客或忘记密码之用.</span>
|
||||
</div>
|
||||
<div class="pure-control-group">
|
||||
<label for="aligned-password1">登录密码</label>
|
||||
<input type="password" id="aligned-password1" placeholder="密码" />
|
||||
</div>
|
||||
<div class="pure-control-group">
|
||||
<label for="aligned-password2">确认密码</label>
|
||||
<input type="password" id="aligned-password2" placeholder="密码" />
|
||||
</div>
|
||||
<div class="pure-controls">
|
||||
<button type="submit" class="pure-button pure-button-primary">提交</button>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
</body>
|
||||
</html>
|
|
@ -14,11 +14,11 @@ use model::Tag;
|
|||
|
||||
use crate::util::result::Result;
|
||||
|
||||
pub mod model;
|
||||
pub(crate) mod post;
|
||||
mod setting;
|
||||
pub(crate) mod tag;
|
||||
pub(crate) mod user;
|
||||
mod setting;
|
||||
pub mod model;
|
||||
|
||||
type SqliteConnPool = sqlx::Pool<Sqlite>;
|
||||
|
||||
|
|
|
@ -1,24 +1,27 @@
|
|||
use core::time::Duration;
|
||||
use std::time::SystemTime;
|
||||
|
||||
use comrak::{ComrakOptions, markdown_to_html};
|
||||
use sqlx::{Sqlite, Row};
|
||||
use comrak::{markdown_to_html, ComrakOptions};
|
||||
use sqlx::{Row, Sqlite};
|
||||
|
||||
use blog_common::{
|
||||
dto::{
|
||||
post::{PostDetail, NewPost},
|
||||
post::{NewPost, PostDetail},
|
||||
PaginationData,
|
||||
},
|
||||
result::Error,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
db::{self, DATA_SOURCE, SqlParam, tag},
|
||||
util::snowflake,
|
||||
db::{
|
||||
self,
|
||||
model::{Post, Tag, TagUsage},
|
||||
tag,
|
||||
tag::get_names,
|
||||
SqlParam, DATA_SOURCE,
|
||||
},
|
||||
util::{result::Result, snowflake},
|
||||
};
|
||||
use crate::db::model::{Post, Tag, TagUsage};
|
||||
use crate::util::result::Result;
|
||||
use crate::db::tag::get_names;
|
||||
|
||||
pub async fn list(page_num: u8, page_size: u8) -> Result<PaginationData<Vec<PostDetail>>> {
|
||||
let offset: i32 = ((page_num - 1) * page_size) as i32;
|
||||
|
@ -62,24 +65,20 @@ pub async fn list_by_tag(tag_name: String, page_num: u8, page_size: u8) -> Resul
|
|||
.await?;
|
||||
let r = r.try_get::<i64, usize>(1);
|
||||
if let Err(e) = r {
|
||||
return Err(Error::SqliteDbError.into())
|
||||
return Err(Error::SqliteDbError.into());
|
||||
}
|
||||
let total = r.unwrap() as u64;
|
||||
if total < 1 {
|
||||
return Ok(PaginationData {
|
||||
total,
|
||||
data: vec![],
|
||||
});
|
||||
return Ok(PaginationData { total, data: vec![] });
|
||||
}
|
||||
let d = sqlx::query_as::<Sqlite, Post>("SELECT p.* FROM post WHERE id IN (SELECT post_id FROM tag_usage WHERE tag_id = ? LIMIT ?, ?)")
|
||||
.bind(tag.id)
|
||||
.fetch_all(&DATA_SOURCE.get().unwrap().sqlite)
|
||||
.await?;
|
||||
let d = sqlx::query_as::<Sqlite, Post>(
|
||||
"SELECT p.* FROM post WHERE id IN (SELECT post_id FROM tag_usage WHERE tag_id = ? LIMIT ?, ?)",
|
||||
)
|
||||
.bind(tag.id)
|
||||
.fetch_all(&DATA_SOURCE.get().unwrap().sqlite)
|
||||
.await?;
|
||||
let d = d.iter().map(|i| i.into()).collect::<Vec<_>>();
|
||||
Ok(PaginationData {
|
||||
total,
|
||||
data: d,
|
||||
})
|
||||
Ok(PaginationData { total, data: d })
|
||||
}
|
||||
|
||||
pub async fn save(new_post: NewPost) -> Result<PostDetail> {
|
||||
|
@ -106,17 +105,16 @@ pub async fn save(new_post: NewPost) -> Result<PostDetail> {
|
|||
};
|
||||
|
||||
// save to sqlite
|
||||
let last_insert_rowid = sqlx::query(
|
||||
"INSERT INTO post(id, title, markdown_content, rendered_content, created_at)VALUES(?,?,?,?,?,?)",
|
||||
)
|
||||
.bind(&post_detail.id)
|
||||
.bind(&post_detail.title)
|
||||
.bind(&new_post.content)
|
||||
.bind(&post_detail.content)
|
||||
.bind(&post_detail.created_at.timestamp_millis())
|
||||
.execute(&DATA_SOURCE.get().unwrap().sqlite)
|
||||
.await?
|
||||
.last_insert_rowid();
|
||||
let last_insert_rowid =
|
||||
sqlx::query("INSERT INTO post(id, title, markdown_content, rendered_content, created_at)VALUES(?,?,?,?,?,?)")
|
||||
.bind(&post_detail.id)
|
||||
.bind(&post_detail.title)
|
||||
.bind(&new_post.content)
|
||||
.bind(&post_detail.content)
|
||||
.bind(&post_detail.created_at.timestamp_millis())
|
||||
.execute(&DATA_SOURCE.get().unwrap().sqlite)
|
||||
.await?
|
||||
.last_insert_rowid();
|
||||
|
||||
if last_insert_rowid < 1 {
|
||||
// println!("last_insert_rowid {}", last_insert_rowid);
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
|
|
@ -12,25 +12,23 @@ use ahash::AHasher;
|
|||
use bytes::{Buf, Bytes, BytesMut};
|
||||
use lazy_static::lazy_static;
|
||||
use parking_lot::RwLock;
|
||||
use sqlx::Sqlite;
|
||||
use tokio::{
|
||||
fs::{File, OpenOptions, remove_file, rename},
|
||||
// io::{self, AsyncReadExt, AsyncWriteExt, BufReader, BufWriter},
|
||||
fs::{remove_file, rename, File, OpenOptions},
|
||||
io::{self, AsyncReadExt, AsyncSeekExt, AsyncWriteExt, BufReader, BufWriter},
|
||||
};
|
||||
use sqlx::Sqlite;
|
||||
|
||||
use blog_common::result::Error;
|
||||
|
||||
use crate::db::model::Tag;
|
||||
use crate::{
|
||||
db::{self, DATA_SOURCE},
|
||||
util::{crypt, snowflake},
|
||||
db::{self, model::Tag, DATA_SOURCE},
|
||||
util::{crypt, result::Result, snowflake},
|
||||
};
|
||||
use crate::util::result::Result;
|
||||
|
||||
pub async fn list() -> Result<Vec<String>> {
|
||||
let tag_list = sqlx::query_as::<Sqlite, Tag>("SELECT name FROM tag ORDER BY created_at DESC")
|
||||
.fetch_all(&DATA_SOURCE.get().unwrap().sqlite).await?;
|
||||
.fetch_all(&DATA_SOURCE.get().unwrap().sqlite)
|
||||
.await?;
|
||||
let name_list = tag_list.iter().map(|i| i.name.clone()).collect::<Vec<String>>();
|
||||
Ok(name_list)
|
||||
}
|
||||
|
@ -48,7 +46,8 @@ pub async fn get_names(id_array: Vec<i64>) -> Result<Vec<String>> {
|
|||
sql.push('-');
|
||||
sql.replace(",-", ") ORDER BY created_at DESC");
|
||||
let tag_list = sqlx::query_as::<Sqlite, Tag>(sql.as_str())
|
||||
.fetch_all(&DATA_SOURCE.get().unwrap().sqlite).await?;
|
||||
.fetch_all(&DATA_SOURCE.get().unwrap().sqlite)
|
||||
.await?;
|
||||
let name_list = tag_list.iter().map(|i| i.name.clone()).collect::<Vec<String>>();
|
||||
Ok(name_list)
|
||||
}
|
||||
|
@ -65,12 +64,15 @@ pub(super) async fn record_usage(post_id: u64, tags: &Vec<String>) -> Result<()>
|
|||
for tag in tags.iter() {
|
||||
query = query.bind(tag);
|
||||
}
|
||||
let tags = query.fetch_all(&DATA_SOURCE.get().unwrap().sqlite)
|
||||
.await?;
|
||||
let tags = query.fetch_all(&DATA_SOURCE.get().unwrap().sqlite).await?;
|
||||
|
||||
let post_id = post_id as i64;
|
||||
for tag in tags {
|
||||
sqlx::query("INSERT INTO tag_usage(post_id, tag_id)VALUES(?,?)").bind(post_id).bind(tag.id).execute(&DATA_SOURCE.get().unwrap().sqlite).await?;
|
||||
sqlx::query("INSERT INTO tag_usage(post_id, tag_id)VALUES(?,?)")
|
||||
.bind(post_id)
|
||||
.bind(tag.id)
|
||||
.execute(&DATA_SOURCE.get().unwrap().sqlite)
|
||||
.await?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
use chrono::prelude::*;
|
||||
|
||||
use sqlx::{
|
||||
Sqlite,
|
||||
};
|
||||
|
||||
use sqlx::Sqlite;
|
||||
|
||||
use blog_common::{
|
||||
dto::user::{RegisterParams, UserInfo},
|
||||
|
@ -11,13 +8,31 @@ use blog_common::{
|
|||
};
|
||||
|
||||
use crate::{
|
||||
db::{self, DATA_SOURCE},
|
||||
util::{crypt, snowflake},
|
||||
db::{self, model::User, DATA_SOURCE},
|
||||
util::{crypt, result::Result, snowflake},
|
||||
};
|
||||
use crate::db::model::User;
|
||||
use crate::util::result::Result;
|
||||
use sqlx::Row;
|
||||
|
||||
pub async fn have_user() -> bool {
|
||||
let row = match sqlx::query("SELECT COUNT(*) FROM user")
|
||||
.fetch_one(&DATA_SOURCE.get().unwrap().sqlite)
|
||||
.await {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
eprintln!("{}", e);
|
||||
return false;
|
||||
},
|
||||
};
|
||||
let r = match row.try_get::<i64, usize>(1) {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
eprintln!("{}", e);
|
||||
return false;
|
||||
},
|
||||
};
|
||||
r > 0
|
||||
}
|
||||
|
||||
pub async fn register(username: &str, password: &str) -> Result<UserInfo> {
|
||||
let r = sqlx::query("SELECT id FROM user WHERE username = ?")
|
||||
.bind(username)
|
||||
|
|
|
@ -1,13 +1,6 @@
|
|||
use warp::{
|
||||
Rejection, Reply,
|
||||
};
|
||||
use warp::{Rejection, Reply};
|
||||
|
||||
pub async fn index() -> Result<impl Reply, Rejection> {
|
||||
let s = include_str!("../asset/page/index.html");
|
||||
Ok(warp::reply::html(s))
|
||||
}
|
||||
|
||||
pub async fn about() -> Result<impl Reply, Rejection> {
|
||||
let s = include_str!("../asset/page/about.html");
|
||||
Ok(warp::reply::html(s))
|
||||
// let s = include_str!("../asset/page/index.html");
|
||||
Ok(warp::reply::html(""))
|
||||
}
|
||||
|
|
|
@ -11,10 +11,7 @@ use warp::{
|
|||
};
|
||||
|
||||
use blog_common::{
|
||||
dto::{
|
||||
post::UploadImage,
|
||||
user::UserInfo,
|
||||
},
|
||||
dto::{post::UploadImage, user::UserInfo},
|
||||
result::{Error, ErrorResponse},
|
||||
val,
|
||||
};
|
||||
|
@ -22,10 +19,12 @@ use blog_common::{
|
|||
use crate::{
|
||||
db::user,
|
||||
facade::{auth_cookie, response_data, response_err},
|
||||
util::common,
|
||||
util::io::{self, SupportFileType},
|
||||
service::status,
|
||||
image::image,
|
||||
service::status,
|
||||
util::{
|
||||
common,
|
||||
io::{self, SupportFileType},
|
||||
},
|
||||
};
|
||||
|
||||
pub async fn verify_image(token: Option<String>) -> Result<WarpResponse, Rejection> {
|
||||
|
@ -55,7 +54,8 @@ pub async fn upload(user: Option<UserInfo>, data: FormData) -> Result<impl Reply
|
|||
let file_info = io::save_upload_file(
|
||||
data,
|
||||
&[SupportFileType::Png, SupportFileType::Jpg, SupportFileType::Gif],
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
if let Err(e) = file_info {
|
||||
return Ok(response_err(500, e));
|
||||
}
|
||||
|
@ -65,26 +65,23 @@ pub async fn upload(user: Option<UserInfo>, data: FormData) -> Result<impl Reply
|
|||
Ok(response_data(&d))
|
||||
}
|
||||
|
||||
pub async fn save(
|
||||
filename: String,
|
||||
user: Option<UserInfo>,
|
||||
body: impl Buf,
|
||||
) -> Result<impl Reply, Rejection> {
|
||||
pub async fn save(filename: String, user: Option<UserInfo>, body: impl Buf) -> Result<impl Reply, Rejection> {
|
||||
if user.is_none() {
|
||||
return Ok(response_err(500, Error::NotAuthed));
|
||||
}
|
||||
let filename = match urlencoding::decode(&filename){
|
||||
let filename = match urlencoding::decode(&filename) {
|
||||
Ok(f) => f,
|
||||
Err(e) => {
|
||||
eprintln!("{:#?}", e);
|
||||
return Ok(response_err(500, Error::BadRequest));
|
||||
}
|
||||
},
|
||||
};
|
||||
let file_info = io::save_upload_stream(
|
||||
filename,
|
||||
body,
|
||||
&[SupportFileType::Png, SupportFileType::Jpg, SupportFileType::Gif],
|
||||
).await;
|
||||
)
|
||||
.await;
|
||||
if let Err(e) = file_info {
|
||||
return Ok(response_err(500, e));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
use warp::{
|
||||
Rejection, Reply,
|
||||
};
|
||||
|
||||
use crate::db::user;
|
||||
use crate::service::status;
|
||||
|
||||
const CONFIG_HTML:&'static str = include_str!("../asset/page/config.html");
|
||||
const LOGIN_HTML:&'static str = include_str!("../asset/page/login.html");
|
||||
const REG_HTML:&'static str = include_str!("../asset/page/reg.html");
|
||||
|
||||
pub async fn index(token: Option<String>) -> Result<impl Reply, Rejection> {
|
||||
let html;
|
||||
if user::have_user().await {
|
||||
if matches!(token, Some(t) if status::check_auth(&t).is_ok()) {
|
||||
html = CONFIG_HTML;
|
||||
} else {
|
||||
html = LOGIN_HTML;
|
||||
}
|
||||
} else {
|
||||
html = REG_HTML;
|
||||
}
|
||||
Ok(warp::reply::html(html))
|
||||
}
|
||||
|
||||
pub async fn config(token: Option<String>) -> Result<impl Reply, Rejection> {
|
||||
Ok(warp::reply::html(CONFIG_HTML))
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
pub(crate) mod user;
|
||||
pub(crate) mod post;
|
||||
pub(crate) mod image;
|
||||
pub(crate) mod tag;
|
||||
pub(crate) mod asset;
|
||||
pub(crate) mod image;
|
||||
pub(crate) mod post;
|
||||
pub(crate) mod tag;
|
||||
pub(crate) mod user;
|
||||
pub(crate) mod management;
|
||||
|
||||
use core::{convert::Infallible, result::Result};
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@ use blog_common::{
|
|||
use crate::{
|
||||
db::post,
|
||||
facade::{auth_cookie, response_data, response_err},
|
||||
util::common,
|
||||
service::status,
|
||||
util::common,
|
||||
};
|
||||
|
||||
pub async fn list(mut page_num: u8) -> Result<impl Reply, Rejection> {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
use core::{convert::Infallible, result::Result};
|
||||
|
||||
use warp::{
|
||||
Rejection, Reply,
|
||||
};
|
||||
use warp::{Rejection, Reply};
|
||||
|
||||
use crate::{
|
||||
db::tag,
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
use core::{convert::Infallible, result::Result};
|
||||
|
||||
use bytes::Buf;
|
||||
use hyper::header::{self, HeaderMap, HeaderValue};
|
||||
use serde::Serialize;
|
||||
use warp::{
|
||||
filters::multipart::FormData,
|
||||
http::{response::Response, StatusCode},
|
||||
reply::{Json, Response as WarpResponse},
|
||||
Rejection, Reply,
|
||||
};
|
||||
|
@ -13,7 +9,6 @@ use warp::{
|
|||
use blog_common::{
|
||||
dto::{
|
||||
user::{LoginParams, RegisterParams, UserInfo, UserInfoWrapper},
|
||||
Response as ApiResponse,
|
||||
},
|
||||
result::{Error, ErrorResponse},
|
||||
val,
|
||||
|
@ -22,17 +17,25 @@ use blog_common::{
|
|||
use crate::{
|
||||
db::user,
|
||||
facade::{auth_cookie, response_data, response_err},
|
||||
util::common,
|
||||
service::status,
|
||||
util::common,
|
||||
};
|
||||
|
||||
pub async fn register(params: RegisterParams) -> Result<impl Reply, Rejection> {
|
||||
if params.password1 != params.password2 {
|
||||
return Ok(response_err(500, Error::BadRequest).into_response());
|
||||
if user::have_user().await {
|
||||
return Ok(response_err(500, Error::BusinessException("已有管理用户,若忘记密码,请使用“找回密码”功能".to_string())).into_response());
|
||||
}
|
||||
|
||||
if params.email.len() < 6 || params.password1.len() < 5 {
|
||||
return Ok(response_err(500, Error::BadRequest).into_response());
|
||||
if params.password1.len() < 3 {
|
||||
return Ok(response_err(500, Error::BusinessException("输入的密码不能少于3位".to_string())).into_response());
|
||||
}
|
||||
|
||||
if params.email.len() < 5 || !common::EMAIL_REGEX.is_match(¶ms.email) {
|
||||
return Ok(response_err(500, Error::BusinessException("输入的邮箱地址不合法".to_string())).into_response());
|
||||
}
|
||||
|
||||
if params.password1 != params.password2 {
|
||||
return Ok(response_err(500, Error::BusinessException("登录密码与确认密码不一致".to_string())).into_response());
|
||||
}
|
||||
|
||||
match user::register(¶ms.email, ¶ms.password1).await {
|
||||
|
@ -60,8 +63,12 @@ pub async fn login(token: Option<String>, params: LoginParams) -> Result<WarpRes
|
|||
return Ok(response_err(500, Error::InvalidSessionId).into_response());
|
||||
}
|
||||
|
||||
if params.email.len() < 6 || params.password.len() < 5 {
|
||||
return Ok(response_err(500, Error::LoginFailed).into_response());
|
||||
if params.password.len() < 3 {
|
||||
return Ok(response_err(500, Error::BusinessException("输入的密码不能少于3位".to_string())).into_response());
|
||||
}
|
||||
|
||||
if params.email.len() < 5 || !common::EMAIL_REGEX.is_match(¶ms.email) {
|
||||
return Ok(response_err(500, Error::BusinessException("输入的邮箱地址不合法".to_string())).into_response());
|
||||
}
|
||||
|
||||
let token = token.unwrap();
|
||||
|
|
|
@ -3,21 +3,18 @@ use std::{io::Write, path::Path, vec::Vec};
|
|||
use bytes::{buf::BufMut, Bytes, BytesMut};
|
||||
use image::{
|
||||
self,
|
||||
codecs::jpeg::JpegEncoder,
|
||||
// png::PngEncoder,
|
||||
codecs::png::{CompressionType, FilterType, PngEncoder},
|
||||
codecs::{
|
||||
jpeg::JpegEncoder,
|
||||
png::{CompressionType, FilterType, PngEncoder},
|
||||
},
|
||||
ColorType, DynamicImage, GenericImage, GenericImageView, ImageBuffer, ImageFormat, Luma, Rgb, Rgba, RgbaImage,
|
||||
};
|
||||
use rand::{thread_rng, Rng};
|
||||
use tokio::fs::copy;
|
||||
|
||||
use blog_common::{
|
||||
dto::UploadFileInfo,
|
||||
result::{Error},
|
||||
};
|
||||
use blog_common::{dto::UploadFileInfo, result::Error};
|
||||
|
||||
use crate::util::val;
|
||||
use crate::util::result::Result;
|
||||
use crate::util::{result::Result, val};
|
||||
|
||||
pub type ImageWidth = u32;
|
||||
pub type ImageHeight = u32;
|
||||
|
@ -82,7 +79,12 @@ pub fn gen_verify_image(numbers: &[u8]) -> Bytes {
|
|||
img.put_pixel(
|
||||
x,
|
||||
y,
|
||||
Rgba([rng.gen_range(0..=255), rng.gen_range(0..=255), rng.gen_range(0..=255), 100]),
|
||||
Rgba([
|
||||
rng.gen_range(0..=255),
|
||||
rng.gen_range(0..=255),
|
||||
rng.gen_range(0..=255),
|
||||
100,
|
||||
]),
|
||||
);
|
||||
} else {
|
||||
img.put_pixel(x + x_offset, y, *pixel);
|
||||
|
|
|
@ -3,15 +3,14 @@ use tokio::{
|
|||
sync::oneshot,
|
||||
};
|
||||
|
||||
use blog_backend::{db, serve::server, service};
|
||||
use blog_backend::util::result;
|
||||
use blog_backend::{db, serve::server, service, util::result};
|
||||
|
||||
fn main() -> result::Result<()> {
|
||||
let runtime = Builder::new_multi_thread()
|
||||
.worker_threads(4)
|
||||
.enable_all()
|
||||
.thread_name("songday-web-service")
|
||||
.thread_stack_size(64 * 1024)
|
||||
.thread_name("Songday-blog-service")
|
||||
.thread_stack_size(1024 * 1024)
|
||||
.build()?;
|
||||
|
||||
let (tx, rx) = oneshot::channel::<()>();
|
||||
|
|
|
@ -1 +1 @@
|
|||
pub mod server;
|
||||
pub mod server;
|
||||
|
|
|
@ -2,7 +2,7 @@ use std::{convert::Infallible, net::SocketAddr, sync::Arc};
|
|||
|
||||
use futures::future::Future;
|
||||
use tokio::sync::oneshot::Receiver;
|
||||
use warp::{self, Filter, reject, Rejection, Server};
|
||||
use warp::{self, reject, Filter, Rejection, Server};
|
||||
|
||||
use blog_common::{
|
||||
dto::{
|
||||
|
@ -12,8 +12,12 @@ use blog_common::{
|
|||
val,
|
||||
};
|
||||
|
||||
use crate::{db::DataSource, util::result::Result, service::status};
|
||||
use crate::facade::{self, asset, image, post, tag, user};
|
||||
use crate::{
|
||||
db::DataSource,
|
||||
facade::{self, asset, image, post, tag, user, management},
|
||||
service::status,
|
||||
util::result::Result,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct FilterError;
|
||||
|
@ -66,11 +70,17 @@ fn auth() -> impl Filter<Extract = (Option<UserInfo>,), Error = Infallible> + Cl
|
|||
|
||||
pub async fn create_warp_server(address: &str, receiver: Receiver<()>) -> Result<impl Future<Output = ()> + 'static> {
|
||||
let index = warp::get().and(warp::path::end()).and_then(asset::index);
|
||||
let about = warp::get()
|
||||
.and(warp::path("about"))
|
||||
let management = warp::get()
|
||||
.and(warp::path("management"))
|
||||
.and(warp::path::end())
|
||||
.and(warp::get())
|
||||
.and_then(asset::about);
|
||||
.and(warp::cookie::optional(val::AUTH_HEADER_NAME))
|
||||
.and_then(management::index);
|
||||
let config = warp::get()
|
||||
.and(warp::path("management"))
|
||||
.and(warp::path("config"))
|
||||
.and(warp::path::end())
|
||||
.and(warp::cookie::optional(val::AUTH_HEADER_NAME))
|
||||
.and_then(management::config);
|
||||
let user_login = warp::post()
|
||||
.and(warp::path("user"))
|
||||
.and(warp::path("login"))
|
||||
|
@ -172,7 +182,8 @@ pub async fn create_warp_server(address: &str, receiver: Receiver<()>) -> Result
|
|||
.build();
|
||||
|
||||
let routes = index
|
||||
.or(about)
|
||||
.or(management)
|
||||
.or(config)
|
||||
.or(user_login)
|
||||
.or(user_register)
|
||||
.or(user_logout)
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
use std::{collections::HashMap, path::Path, sync::Arc};
|
||||
|
||||
use bytes::Buf;
|
||||
use v_htmlescape;
|
||||
use warp::filters::multipart::{FormData, Part};
|
||||
|
||||
use blog_common::{
|
||||
dto::{
|
||||
blog::{BlogDetail, NewBlog, UploadImage},
|
||||
PaginationData,
|
||||
},
|
||||
result::Error,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
db::blog,
|
||||
image::image,
|
||||
util::io::{self, SupportFileType},
|
||||
};
|
||||
use crate::db::model::Tag;
|
||||
use crate::util::result::Result;
|
||||
|
||||
pub async fn list(mut page_num: u8) -> Result<PaginationData<Vec<BlogDetail>>> {
|
||||
if page_num < 1 {
|
||||
page_num = 1;
|
||||
}
|
||||
blog::list(page_num, crate::var::BLOG_PAGE_SIZE).await
|
||||
}
|
||||
|
||||
pub async fn tags() -> Result<Vec<Tag>> { blog::tags() }
|
||||
|
||||
pub async fn list_by_tag(tag: String, mut page_num: u8) -> Result<PaginationData<Vec<BlogDetail>>> {
|
||||
let tag = urlencoding::decode(&tag)?;
|
||||
|
||||
if page_num < 1 {
|
||||
page_num = 1;
|
||||
}
|
||||
blog::list_by_tag(tag, page_num, crate::var::BLOG_PAGE_SIZE).await
|
||||
}
|
||||
|
||||
pub async fn save(mut blog: NewBlog) -> Result<BlogDetail> {
|
||||
if blog.title.len() < 3 || blog.title.len() > 60 {
|
||||
return Err(Error::SaveBlogFailed.into());
|
||||
}
|
||||
if blog.content.len() < 5 || blog.content.len() > 65535 {
|
||||
return Err(Error::SaveBlogFailed.into());
|
||||
}
|
||||
blog.content = format!("{}", v_htmlescape::escape(&blog.content));
|
||||
blog::save(blog).await
|
||||
}
|
||||
|
||||
pub async fn show(id: u64) -> Result<BlogDetail> {
|
||||
if id < 10000 {
|
||||
return Err(Error::CannotFoundBlog.into());
|
||||
}
|
||||
blog::show(id).await
|
||||
}
|
||||
|
|
@ -6,19 +6,20 @@ use warp::filters::multipart::{FormData, Part};
|
|||
|
||||
use blog_common::{
|
||||
dto::{
|
||||
post::{PostDetail, NewPost, UploadImage},
|
||||
post::{NewPost, PostDetail, UploadImage},
|
||||
PaginationData,
|
||||
},
|
||||
result::Error,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
db::post,
|
||||
db::{model::Tag, post},
|
||||
image::image,
|
||||
util::io::{self, SupportFileType},
|
||||
util::{
|
||||
io::{self, SupportFileType},
|
||||
result::Result,
|
||||
},
|
||||
};
|
||||
use crate::db::model::Tag;
|
||||
use crate::util::result::Result;
|
||||
|
||||
pub async fn upload(data: FormData) -> Result<UploadImage> {
|
||||
let file_info = io::save_upload_file(
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
pub mod status;
|
||||
mod image;
|
||||
pub mod status;
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
use blog_common::{dto::user::UserInfo, result::Error};
|
||||
|
||||
use crate::{
|
||||
db::{DataSource, SqlParam, user},
|
||||
service::status,
|
||||
};
|
||||
use crate::util::result::{ErrorWrapper, Result};
|
||||
|
||||
pub async fn register(token: &str, email: &str, password: &str) -> Result<UserInfo> {
|
||||
if email.len() < 6 || password.len() < 5 {
|
||||
return Err(ErrorWrapper(Error::RegisterFailed));
|
||||
}
|
||||
let u = user::register(email, password).await?;
|
||||
status::user_online(&token, u.clone());
|
||||
Ok(u)
|
||||
}
|
||||
|
||||
pub async fn login(token: &str, email: &str, password: &str) -> Result<UserInfo> {
|
||||
if email.len() < 6 || password.len() < 5 {
|
||||
return Err(ErrorWrapper(Error::LoginFailed));
|
||||
}
|
||||
let u = user::login(email, password).await?;
|
||||
status::user_online(&token, u.clone());
|
||||
Ok(u)
|
||||
}
|
|
@ -1,5 +1,7 @@
|
|||
use rand::{rngs::OsRng, RngCore};
|
||||
use regex::Regex;
|
||||
use uuid::Uuid;
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
pub fn simple_uuid_with_name(name: &[u8]) -> String {
|
||||
let uuid = Uuid::new_v5(&Uuid::NAMESPACE_URL, name);
|
||||
|
@ -12,3 +14,7 @@ pub fn simple_uuid() -> String {
|
|||
|
||||
simple_uuid_with_name(&salt)
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
pub static ref EMAIL_REGEX: Regex = Regex::new(r"[^@ \t\r\n]+@[^@ \t\r\n]+\.[^@ \t\r\n]+").unwrap();
|
||||
}
|
|
@ -2,7 +2,7 @@ use base64;
|
|||
use rand::{rngs::OsRng, RngCore};
|
||||
use scrypt::{
|
||||
password_hash::{PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
|
||||
Scrypt
|
||||
Scrypt,
|
||||
};
|
||||
// use subtle::ConstantTimeEq;
|
||||
|
||||
|
@ -12,7 +12,10 @@ pub fn encrypt_password(password: &str) -> String {
|
|||
}
|
||||
|
||||
fn encrypt_password_with_salt(password: &[u8], salt: &SaltString) -> String {
|
||||
Scrypt.hash_password_simple(password, salt.as_ref()).unwrap().to_string()
|
||||
Scrypt
|
||||
.hash_password_simple(password, salt.as_ref())
|
||||
.unwrap()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
pub fn verify_password(password: &str, encrypted_password: &str) -> bool {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
pub(crate) mod common;
|
||||
pub(crate) mod crypt;
|
||||
pub(crate) mod io;
|
||||
pub(crate) mod num;
|
||||
pub(crate) mod snowflake;
|
||||
pub mod result;
|
||||
pub(crate) mod common;
|
||||
pub(crate) mod crypt;
|
||||
pub(crate) mod io;
|
||||
pub(crate) mod num;
|
||||
pub mod result;
|
||||
pub(crate) mod snowflake;
|
||||
pub(crate) mod val;
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
use std::vec::Vec;
|
||||
use std::rc::Rc;
|
||||
use std::{rc::Rc, vec::Vec};
|
||||
|
||||
use rand::{thread_rng, Rng};
|
||||
use rand::distributions::uniform::{SampleUniform, SampleRange};
|
||||
use rand::{
|
||||
distributions::uniform::{SampleRange, SampleUniform},
|
||||
thread_rng, Rng,
|
||||
};
|
||||
|
||||
// const NUMERIC: [u8; 10] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
|
||||
|
||||
pub fn rand_numbers<T>(min: T, max: T, amount: usize) -> Vec<T>
|
||||
where
|
||||
T: SampleUniform + PartialOrd + Copy,
|
||||
where
|
||||
T: SampleUniform + PartialOrd + Copy,
|
||||
{
|
||||
let mut d = Vec::<T>::with_capacity(amount);
|
||||
let mut rng = thread_rng();
|
||||
|
|
|
@ -5,8 +5,8 @@ use serde::{Deserialize, Serialize};
|
|||
use crate::result::ErrorResponse;
|
||||
|
||||
pub mod post;
|
||||
pub mod user;
|
||||
mod setting;
|
||||
pub mod user;
|
||||
|
||||
//https://stackoverflow.com/questions/49953960/cannot-resolve-t-serdedeserializea-when-deriving-deserialize-on-a-generic
|
||||
//https://stackoverflow.com/questions/54761790/how-to-deserialize-with-for-a-container-using-serde-in-rust
|
||||
|
|
|
@ -4,4 +4,4 @@ pub struct Setting {
|
|||
pub license: String,
|
||||
pub manager_user: String,
|
||||
pub manager_password: String,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ pub enum Error {
|
|||
SerdeError,
|
||||
#[error("Page not found")]
|
||||
NotFound,
|
||||
#[error("Bad request")]
|
||||
#[error("请求参数不合法,请检查输入是否正确")]
|
||||
BadRequest,
|
||||
#[error("Method not allowed")]
|
||||
MethodNotAllowed,
|
||||
|
@ -28,11 +28,11 @@ pub enum Error {
|
|||
InternalServerError,
|
||||
|
||||
// business
|
||||
#[error("Invalid session id")]
|
||||
#[error("无效的 Session ID")]
|
||||
InvalidSessionId,
|
||||
#[error("Invalid verify code")]
|
||||
#[error("无效的验证码")]
|
||||
InvalidVerifyCode,
|
||||
#[error("Current user have not authorized, please login again")]
|
||||
#[error("登录信息失效,请重新登录")]
|
||||
NotAuthed,
|
||||
#[error("Login failed")]
|
||||
LoginFailed,
|
||||
|
@ -58,6 +58,9 @@ pub enum Error {
|
|||
ReadBlogIdDataByTagFailed,
|
||||
#[error("Saving blog id data by tag failed")]
|
||||
SaveBlogIdDataByTagFailed,
|
||||
|
||||
#[error("{0}")]
|
||||
BusinessException(String),
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
|
|
|
@ -0,0 +1,758 @@
|
|||
|
||||
let wasm;
|
||||
|
||||
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
||||
|
||||
cachedTextDecoder.decode();
|
||||
|
||||
let cachegetUint8Memory0 = null;
|
||||
function getUint8Memory0() {
|
||||
if (cachegetUint8Memory0 === null || cachegetUint8Memory0.buffer !== wasm.memory.buffer) {
|
||||
cachegetUint8Memory0 = new Uint8Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetUint8Memory0;
|
||||
}
|
||||
|
||||
function getStringFromWasm0(ptr, len) {
|
||||
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
|
||||
}
|
||||
|
||||
const heap = new Array(32).fill(undefined);
|
||||
|
||||
heap.push(undefined, null, true, false);
|
||||
|
||||
let heap_next = heap.length;
|
||||
|
||||
function addHeapObject(obj) {
|
||||
if (heap_next === heap.length) heap.push(heap.length + 1);
|
||||
const idx = heap_next;
|
||||
heap_next = heap[idx];
|
||||
|
||||
heap[idx] = obj;
|
||||
return idx;
|
||||
}
|
||||
|
||||
function getObject(idx) { return heap[idx]; }
|
||||
|
||||
function dropObject(idx) {
|
||||
if (idx < 36) return;
|
||||
heap[idx] = heap_next;
|
||||
heap_next = idx;
|
||||
}
|
||||
|
||||
function takeObject(idx) {
|
||||
const ret = getObject(idx);
|
||||
dropObject(idx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
let WASM_VECTOR_LEN = 0;
|
||||
|
||||
let cachedTextEncoder = new TextEncoder('utf-8');
|
||||
|
||||
const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
|
||||
? function (arg, view) {
|
||||
return cachedTextEncoder.encodeInto(arg, view);
|
||||
}
|
||||
: function (arg, view) {
|
||||
const buf = cachedTextEncoder.encode(arg);
|
||||
view.set(buf);
|
||||
return {
|
||||
read: arg.length,
|
||||
written: buf.length
|
||||
};
|
||||
});
|
||||
|
||||
function passStringToWasm0(arg, malloc, realloc) {
|
||||
|
||||
if (realloc === undefined) {
|
||||
const buf = cachedTextEncoder.encode(arg);
|
||||
const ptr = malloc(buf.length);
|
||||
getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf);
|
||||
WASM_VECTOR_LEN = buf.length;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
let len = arg.length;
|
||||
let ptr = malloc(len);
|
||||
|
||||
const mem = getUint8Memory0();
|
||||
|
||||
let offset = 0;
|
||||
|
||||
for (; offset < len; offset++) {
|
||||
const code = arg.charCodeAt(offset);
|
||||
if (code > 0x7F) break;
|
||||
mem[ptr + offset] = code;
|
||||
}
|
||||
|
||||
if (offset !== len) {
|
||||
if (offset !== 0) {
|
||||
arg = arg.slice(offset);
|
||||
}
|
||||
ptr = realloc(ptr, len, len = offset + arg.length * 3);
|
||||
const view = getUint8Memory0().subarray(ptr + offset, ptr + len);
|
||||
const ret = encodeString(arg, view);
|
||||
|
||||
offset += ret.written;
|
||||
}
|
||||
|
||||
WASM_VECTOR_LEN = offset;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
function isLikeNone(x) {
|
||||
return x === undefined || x === null;
|
||||
}
|
||||
|
||||
let cachegetInt32Memory0 = null;
|
||||
function getInt32Memory0() {
|
||||
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
|
||||
cachegetInt32Memory0 = new Int32Array(wasm.memory.buffer);
|
||||
}
|
||||
return cachegetInt32Memory0;
|
||||
}
|
||||
|
||||
function debugString(val) {
|
||||
// primitive types
|
||||
const type = typeof val;
|
||||
if (type == 'number' || type == 'boolean' || val == null) {
|
||||
return `${val}`;
|
||||
}
|
||||
if (type == 'string') {
|
||||
return `"${val}"`;
|
||||
}
|
||||
if (type == 'symbol') {
|
||||
const description = val.description;
|
||||
if (description == null) {
|
||||
return 'Symbol';
|
||||
} else {
|
||||
return `Symbol(${description})`;
|
||||
}
|
||||
}
|
||||
if (type == 'function') {
|
||||
const name = val.name;
|
||||
if (typeof name == 'string' && name.length > 0) {
|
||||
return `Function(${name})`;
|
||||
} else {
|
||||
return 'Function';
|
||||
}
|
||||
}
|
||||
// objects
|
||||
if (Array.isArray(val)) {
|
||||
const length = val.length;
|
||||
let debug = '[';
|
||||
if (length > 0) {
|
||||
debug += debugString(val[0]);
|
||||
}
|
||||
for(let i = 1; i < length; i++) {
|
||||
debug += ', ' + debugString(val[i]);
|
||||
}
|
||||
debug += ']';
|
||||
return debug;
|
||||
}
|
||||
// Test for built-in
|
||||
const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val));
|
||||
let className;
|
||||
if (builtInMatches.length > 1) {
|
||||
className = builtInMatches[1];
|
||||
} else {
|
||||
// Failed to match the standard '[object ClassName]'
|
||||
return toString.call(val);
|
||||
}
|
||||
if (className == 'Object') {
|
||||
// we're a user defined class or Object
|
||||
// JSON.stringify avoids problems with cycles, and is generally much
|
||||
// easier than looping through ownProperties of `val`.
|
||||
try {
|
||||
return 'Object(' + JSON.stringify(val) + ')';
|
||||
} catch (_) {
|
||||
return 'Object';
|
||||
}
|
||||
}
|
||||
// errors
|
||||
if (val instanceof Error) {
|
||||
return `${val.name}: ${val.message}\n${val.stack}`;
|
||||
}
|
||||
// TODO we could test for more things here, like `Set`s and `Map`s.
|
||||
return className;
|
||||
}
|
||||
|
||||
function makeMutClosure(arg0, arg1, dtor, f) {
|
||||
const state = { a: arg0, b: arg1, cnt: 1, dtor };
|
||||
const real = (...args) => {
|
||||
// First up with a closure we increment the internal reference
|
||||
// count. This ensures that the Rust closure environment won't
|
||||
// be deallocated while we're invoking it.
|
||||
state.cnt++;
|
||||
const a = state.a;
|
||||
state.a = 0;
|
||||
try {
|
||||
return f(a, state.b, ...args);
|
||||
} finally {
|
||||
if (--state.cnt === 0) {
|
||||
wasm.__wbindgen_export_2.get(state.dtor)(a, state.b);
|
||||
|
||||
} else {
|
||||
state.a = a;
|
||||
}
|
||||
}
|
||||
};
|
||||
real.original = state;
|
||||
|
||||
return real;
|
||||
}
|
||||
|
||||
let stack_pointer = 32;
|
||||
|
||||
function addBorrowedObject(obj) {
|
||||
if (stack_pointer == 1) throw new Error('out of js stack');
|
||||
heap[--stack_pointer] = obj;
|
||||
return stack_pointer;
|
||||
}
|
||||
function __wbg_adapter_24(arg0, arg1, arg2) {
|
||||
try {
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h77e9687c6edbcb34(arg0, arg1, addBorrowedObject(arg2));
|
||||
} finally {
|
||||
heap[stack_pointer++] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function __wbg_adapter_27(arg0, arg1, arg2) {
|
||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h8c8ed20052ee0288(arg0, arg1, addHeapObject(arg2));
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
export function run_app() {
|
||||
wasm.run_app();
|
||||
}
|
||||
|
||||
function handleError(f) {
|
||||
return function () {
|
||||
try {
|
||||
return f.apply(this, arguments);
|
||||
|
||||
} catch (e) {
|
||||
wasm.__wbindgen_exn_store(addHeapObject(e));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async function load(module, imports) {
|
||||
if (typeof Response === 'function' && module instanceof Response) {
|
||||
|
||||
if (typeof WebAssembly.instantiateStreaming === 'function') {
|
||||
try {
|
||||
return await WebAssembly.instantiateStreaming(module, imports);
|
||||
|
||||
} catch (e) {
|
||||
if (module.headers.get('Content-Type') != 'application/wasm') {
|
||||
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
|
||||
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const bytes = await module.arrayBuffer();
|
||||
return await WebAssembly.instantiate(bytes, imports);
|
||||
|
||||
} else {
|
||||
|
||||
const instance = await WebAssembly.instantiate(module, imports);
|
||||
|
||||
if (instance instanceof WebAssembly.Instance) {
|
||||
return { instance, module };
|
||||
|
||||
} else {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function init(input) {
|
||||
if (typeof input === 'undefined') {
|
||||
input = new URL('index-75330f91aa5baa0a_bg.wasm', import.meta.url);
|
||||
}
|
||||
const imports = {};
|
||||
imports.wbg = {};
|
||||
imports.wbg.__wbindgen_string_new = function(arg0, arg1) {
|
||||
var ret = getStringFromWasm0(arg0, arg1);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
|
||||
var ret = getObject(arg0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_is_undefined = function(arg0) {
|
||||
var ret = getObject(arg0) === undefined;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_Window_6f26ab8994cdec9b = function(arg0) {
|
||||
var ret = getObject(arg0).Window;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_WorkerGlobalScope_65696f271e05e492 = function(arg0) {
|
||||
var ret = getObject(arg0).WorkerGlobalScope;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_cb_drop = function(arg0) {
|
||||
const obj = takeObject(arg0).original;
|
||||
if (obj.cnt-- == 1) {
|
||||
obj.a = 0;
|
||||
return true;
|
||||
}
|
||||
var ret = false;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
|
||||
takeObject(arg0);
|
||||
};
|
||||
imports.wbg.__wbg_instanceof_Window_fa4595281eb5ba83 = function(arg0) {
|
||||
var ret = getObject(arg0) instanceof Window;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_document_d8cce4c1031c64eb = function(arg0) {
|
||||
var ret = getObject(arg0).document;
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_location_f8de588551329bf4 = function(arg0) {
|
||||
var ret = getObject(arg0).location;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_history_ea580f62f8cb1285 = handleError(function(arg0) {
|
||||
var ret = getObject(arg0).history;
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_localStorage_a79a5d8ee7487fcb = handleError(function(arg0) {
|
||||
var ret = getObject(arg0).localStorage;
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_sessionStorage_dea744376f5440ac = handleError(function(arg0) {
|
||||
var ret = getObject(arg0).sessionStorage;
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_fetch_6c1ec0777d07eee3 = function(arg0, arg1, arg2) {
|
||||
var ret = getObject(arg0).fetch(getObject(arg1), getObject(arg2));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_createElement_695120dd76150487 = handleError(function(arg0, arg1, arg2) {
|
||||
var ret = getObject(arg0).createElement(getStringFromWasm0(arg1, arg2));
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_createElementNS_9e443d140d5b4a33 = handleError(function(arg0, arg1, arg2, arg3, arg4) {
|
||||
var ret = getObject(arg0).createElementNS(arg1 === 0 ? undefined : getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_createTextNode_6f0cfbce3a2487fb = function(arg0, arg1, arg2) {
|
||||
var ret = getObject(arg0).createTextNode(getStringFromWasm0(arg1, arg2));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_querySelector_5cba5f6b2ed68e05 = handleError(function(arg0, arg1, arg2) {
|
||||
var ret = getObject(arg0).querySelector(getStringFromWasm0(arg1, arg2));
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_pathname_bbcab59ebce24546 = handleError(function(arg0, arg1) {
|
||||
var ret = getObject(arg1).pathname;
|
||||
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||
});
|
||||
imports.wbg.__wbg_search_63bdf6fe2b15d1d4 = handleError(function(arg0, arg1) {
|
||||
var ret = getObject(arg1).search;
|
||||
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||
});
|
||||
imports.wbg.__wbg_hash_f1a1e37355e44338 = handleError(function(arg0, arg1) {
|
||||
var ret = getObject(arg1).hash;
|
||||
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||
});
|
||||
imports.wbg.__wbg_newwithstrsequencesequence_68686c6e9a188d2f = handleError(function(arg0) {
|
||||
var ret = new Headers(getObject(arg0));
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_instanceof_HtmlSelectElement_3d87bb1722a1aab7 = function(arg0) {
|
||||
var ret = getObject(arg0) instanceof HTMLSelectElement;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_newwithstrandinit_18c41e1aaab4972f = handleError(function(arg0, arg1, arg2) {
|
||||
var ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_status_050df54e85254c67 = function(arg0) {
|
||||
var ret = getObject(arg0).status;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_headers_b803c3e004351cb0 = function(arg0) {
|
||||
var ret = getObject(arg0).headers;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_arrayBuffer_c5e630358019dfa0 = handleError(function(arg0) {
|
||||
var ret = getObject(arg0).arrayBuffer();
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_text_5332e729fad5779e = handleError(function(arg0) {
|
||||
var ret = getObject(arg0).text();
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_readyState_ffd9215b205bbc7e = function(arg0) {
|
||||
var ret = getObject(arg0).readyState;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_result_0f2e720d85f5b799 = handleError(function(arg0) {
|
||||
var ret = getObject(arg0).result;
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_new_549a5d72a89fabbc = handleError(function() {
|
||||
var ret = new FileReader();
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_abort_4ce1d711728e85aa = function(arg0) {
|
||||
getObject(arg0).abort();
|
||||
};
|
||||
imports.wbg.__wbg_readAsArrayBuffer_66a1d5aa15dd98a7 = handleError(function(arg0, arg1) {
|
||||
getObject(arg0).readAsArrayBuffer(getObject(arg1));
|
||||
});
|
||||
imports.wbg.__wbg_instanceof_HtmlTextAreaElement_1bd106832e7a2d85 = function(arg0) {
|
||||
var ret = getObject(arg0) instanceof HTMLTextAreaElement;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_value_022eba9b8dd4fb1e = function(arg0, arg1) {
|
||||
var ret = getObject(arg1).value;
|
||||
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||
};
|
||||
imports.wbg.__wbg_setvalue_d3112c6f38991024 = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
|
||||
};
|
||||
imports.wbg.__wbg_signal_564fb4b932a62647 = function(arg0) {
|
||||
var ret = getObject(arg0).signal;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_new_b25ae9c0ad6843ae = handleError(function() {
|
||||
var ret = new AbortController();
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_abort_9c58ad5988ed06e1 = function(arg0) {
|
||||
getObject(arg0).abort();
|
||||
};
|
||||
imports.wbg.__wbg_instanceof_HtmlButtonElement_3d160e69f22feabe = function(arg0) {
|
||||
var ret = getObject(arg0) instanceof HTMLButtonElement;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_settype_3a62f424c2f2cc6e = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).type = getStringFromWasm0(arg1, arg2);
|
||||
};
|
||||
imports.wbg.__wbg_now_9f22124bc74da886 = function(arg0) {
|
||||
var ret = getObject(arg0).now();
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_namespaceURI_e79b3e59fe6e51eb = function(arg0, arg1) {
|
||||
var ret = getObject(arg1).namespaceURI;
|
||||
var ptr0 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||
};
|
||||
imports.wbg.__wbg_setinnerHTML_a8b2c66f141a2b24 = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).innerHTML = getStringFromWasm0(arg1, arg2);
|
||||
};
|
||||
imports.wbg.__wbg_getAttribute_3d19bb0ff8904532 = function(arg0, arg1, arg2, arg3) {
|
||||
var ret = getObject(arg1).getAttribute(getStringFromWasm0(arg2, arg3));
|
||||
var ptr0 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||
};
|
||||
imports.wbg.__wbg_removeAttribute_4bc290dbe2b7214f = handleError(function(arg0, arg1, arg2) {
|
||||
getObject(arg0).removeAttribute(getStringFromWasm0(arg1, arg2));
|
||||
});
|
||||
imports.wbg.__wbg_setAttribute_fb8737b4573a65f8 = handleError(function(arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).setAttribute(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||
});
|
||||
imports.wbg.__wbg_log_8485ead621ceded9 = function(arg0) {
|
||||
console.log(getObject(arg0));
|
||||
};
|
||||
imports.wbg.__wbg_instanceof_HtmlInputElement_bcbf72cd9188bbf5 = function(arg0) {
|
||||
var ret = getObject(arg0) instanceof HTMLInputElement;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_setchecked_c59c4e3455f1971c = function(arg0, arg1) {
|
||||
getObject(arg0).checked = arg1 !== 0;
|
||||
};
|
||||
imports.wbg.__wbg_files_75aaa5e919bf42c4 = function(arg0) {
|
||||
var ret = getObject(arg0).files;
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_settype_78a0fe790fa56fa7 = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).type = getStringFromWasm0(arg1, arg2);
|
||||
};
|
||||
imports.wbg.__wbg_value_9c8f7cca5ded6671 = function(arg0, arg1) {
|
||||
var ret = getObject(arg1).value;
|
||||
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||
};
|
||||
imports.wbg.__wbg_setvalue_44d4bd0ac437904f = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
|
||||
};
|
||||
imports.wbg.__wbg_fetch_045d28bb4e9368fb = function(arg0, arg1, arg2) {
|
||||
var ret = getObject(arg0).fetch(getObject(arg1), getObject(arg2));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_preventDefault_2a53c6dce5093030 = function(arg0) {
|
||||
getObject(arg0).preventDefault();
|
||||
};
|
||||
imports.wbg.__wbg_addEventListener_bb3090f03a1e2df6 = handleError(function(arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), getObject(arg4));
|
||||
});
|
||||
imports.wbg.__wbg_removeEventListener_fd27aefbf65efcfb = handleError(function(arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).removeEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), arg4 !== 0);
|
||||
});
|
||||
imports.wbg.__wbg_instanceof_PopStateEvent_a695582c8f771c6d = function(arg0) {
|
||||
var ret = getObject(arg0) instanceof PopStateEvent;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_state_2705fc307f614d01 = function(arg0) {
|
||||
var ret = getObject(arg0).state;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_name_2db5213e1d312b59 = function(arg0, arg1) {
|
||||
var ret = getObject(arg1).name;
|
||||
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||
};
|
||||
imports.wbg.__wbg_state_3f3bf78ca919bce7 = handleError(function(arg0) {
|
||||
var ret = getObject(arg0).state;
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_pushState_10c51a6fb23b182f = handleError(function(arg0, arg1, arg2, arg3, arg4, arg5) {
|
||||
getObject(arg0).pushState(getObject(arg1), getStringFromWasm0(arg2, arg3), arg4 === 0 ? undefined : getStringFromWasm0(arg4, arg5));
|
||||
});
|
||||
imports.wbg.__wbg_replaceState_084b0aa9320d3fa3 = handleError(function(arg0, arg1, arg2, arg3, arg4, arg5) {
|
||||
getObject(arg0).replaceState(getObject(arg1), getStringFromWasm0(arg2, arg3), arg4 === 0 ? undefined : getStringFromWasm0(arg4, arg5));
|
||||
});
|
||||
imports.wbg.__wbg_nodeName_55cf450b6364b57f = function(arg0, arg1) {
|
||||
var ret = getObject(arg1).nodeName;
|
||||
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||
};
|
||||
imports.wbg.__wbg_lastChild_6362c4c702857757 = function(arg0) {
|
||||
var ret = getObject(arg0).lastChild;
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_setnodeValue_80e9e070bf4261d2 = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).nodeValue = arg1 === 0 ? undefined : getStringFromWasm0(arg1, arg2);
|
||||
};
|
||||
imports.wbg.__wbg_textContent_04ca15fd48e65efe = function(arg0, arg1) {
|
||||
var ret = getObject(arg1).textContent;
|
||||
var ptr0 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||
};
|
||||
imports.wbg.__wbg_appendChild_9ba4c99688714f13 = handleError(function(arg0, arg1) {
|
||||
var ret = getObject(arg0).appendChild(getObject(arg1));
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_insertBefore_9ddb982d7f5d6824 = handleError(function(arg0, arg1, arg2) {
|
||||
var ret = getObject(arg0).insertBefore(getObject(arg1), getObject(arg2));
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_removeChild_e02df31f6d70392a = handleError(function(arg0, arg1) {
|
||||
var ret = getObject(arg0).removeChild(getObject(arg1));
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_getItem_3fc9a85a5c86c097 = handleError(function(arg0, arg1, arg2, arg3) {
|
||||
var ret = getObject(arg1).getItem(getStringFromWasm0(arg2, arg3));
|
||||
var ptr0 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||
});
|
||||
imports.wbg.__wbg_removeItem_608dad41f63cff4c = handleError(function(arg0, arg1, arg2) {
|
||||
getObject(arg0).removeItem(getStringFromWasm0(arg1, arg2));
|
||||
});
|
||||
imports.wbg.__wbg_setItem_99592651ffc703f6 = handleError(function(arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).setItem(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||
});
|
||||
imports.wbg.__wbg_new_04918f9bdadadf45 = function() {
|
||||
var ret = new Array();
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_get_40375c2067f479fc = function(arg0, arg1) {
|
||||
var ret = getObject(arg0)[arg1 >>> 0];
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_from_87d2b71ada3c04df = function(arg0) {
|
||||
var ret = Array.from(getObject(arg0));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_push_60db4345d488a9b8 = function(arg0, arg1) {
|
||||
var ret = getObject(arg0).push(getObject(arg1));
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_toString_7ba29b72020636b1 = function(arg0) {
|
||||
var ret = getObject(arg0).toString();
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_newnoargs_179d393e4626fcf7 = function(arg0, arg1) {
|
||||
var ret = new Function(getStringFromWasm0(arg0, arg1));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_call_8487a9f580e47219 = handleError(function(arg0, arg1) {
|
||||
var ret = getObject(arg0).call(getObject(arg1));
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_next_9bb15512a3ee3434 = handleError(function(arg0) {
|
||||
var ret = getObject(arg0).next();
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_next_cb5f2b7832bb897e = function(arg0) {
|
||||
var ret = getObject(arg0).next;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_done_16917a81a3b84f69 = function(arg0) {
|
||||
var ret = getObject(arg0).done;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_value_f66e28875493aed6 = function(arg0) {
|
||||
var ret = getObject(arg0).value;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_is_736e7316d8240b8e = function(arg0, arg1) {
|
||||
var ret = Object.is(getObject(arg0), getObject(arg1));
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_new_b0b535e7b597e9c1 = function() {
|
||||
var ret = new Object();
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_iterator_09cc2e58591459c9 = function() {
|
||||
var ret = Symbol.iterator;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_resolve_dcf7d6a479f5b166 = function(arg0) {
|
||||
var ret = Promise.resolve(getObject(arg0));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_then_16d483233321aac8 = function(arg0, arg1) {
|
||||
var ret = getObject(arg0).then(getObject(arg1));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_then_c95977e365944fff = function(arg0, arg1, arg2) {
|
||||
var ret = getObject(arg0).then(getObject(arg1), getObject(arg2));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_globalThis_a2669bee93faee43 = handleError(function() {
|
||||
var ret = globalThis.globalThis;
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_self_eeabd9085c04fc17 = handleError(function() {
|
||||
var ret = self.self;
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_window_f110c13310da2c8f = handleError(function() {
|
||||
var ret = window.window;
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_global_a5584d717f4d6761 = handleError(function() {
|
||||
var ret = global.global;
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_new_139e70222494b1ff = function(arg0) {
|
||||
var ret = new Uint8Array(getObject(arg0));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_newwithbyteoffsetandlength_836859e5deb44d3f = function(arg0, arg1, arg2) {
|
||||
var ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_length_2cfa674c2a529bc1 = function(arg0) {
|
||||
var ret = getObject(arg0).length;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_set_d771848e3c7935bb = function(arg0, arg1, arg2) {
|
||||
getObject(arg0).set(getObject(arg1), arg2 >>> 0);
|
||||
};
|
||||
imports.wbg.__wbg_buffer_e35e010c3ba9f945 = function(arg0) {
|
||||
var ret = getObject(arg0).buffer;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_is_function = function(arg0) {
|
||||
var ret = typeof(getObject(arg0)) === 'function';
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbindgen_is_object = function(arg0) {
|
||||
const val = getObject(arg0);
|
||||
var ret = typeof(val) === 'object' && val !== null;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_get_a96a2f48856bb1c3 = handleError(function(arg0, arg1) {
|
||||
var ret = Reflect.get(getObject(arg0), getObject(arg1));
|
||||
return addHeapObject(ret);
|
||||
});
|
||||
imports.wbg.__wbg_set_c1d44124a051a5e7 = handleError(function(arg0, arg1, arg2) {
|
||||
var ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
|
||||
return ret;
|
||||
});
|
||||
imports.wbg.__wbindgen_string_get = function(arg0, arg1) {
|
||||
const obj = getObject(arg1);
|
||||
var ret = typeof(obj) === 'string' ? obj : undefined;
|
||||
var ptr0 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||
};
|
||||
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
|
||||
var ret = debugString(getObject(arg1));
|
||||
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
var len0 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||
};
|
||||
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
|
||||
throw new Error(getStringFromWasm0(arg0, arg1));
|
||||
};
|
||||
imports.wbg.__wbindgen_memory = function() {
|
||||
var ret = wasm.memory;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper13033 = function(arg0, arg1, arg2) {
|
||||
var ret = makeMutClosure(arg0, arg1, 666, __wbg_adapter_24);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper14244 = function(arg0, arg1, arg2) {
|
||||
var ret = makeMutClosure(arg0, arg1, 736, __wbg_adapter_27);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
|
||||
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
|
||||
input = fetch(input);
|
||||
}
|
||||
|
||||
const { instance, module } = await load(await input, imports);
|
||||
|
||||
wasm = instance.exports;
|
||||
init.__wbindgen_wasm_module = module;
|
||||
wasm.__wbindgen_start();
|
||||
return wasm;
|
||||
}
|
||||
|
||||
export default init;
|
||||
|
Binary file not shown.
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html><html lang="en"><head>
|
||||
<meta charset="utf-8">
|
||||
<title>70年代、80年代、90年代,怀旧、复古、回忆</title>
|
||||
<link rel="stylesheet" href="asset/main.css">
|
||||
<style type="text/css">
|
||||
body{padding:20px}
|
||||
.tar{text-align:right}
|
||||
.tac{text-align:center}
|
||||
.tag-btn{color:white;border-radius:4px;text-shadow:0 1px 1px rgba(0, 0, 0, 0.2);background:rgb(28, 184, 65);margin-right:6px}
|
||||
.tag-link{margin-right:6px}
|
||||
</style>
|
||||
<script type="module">import init from '/index-75330f91aa5baa0a.js';init('/index-75330f91aa5baa0a_bg.wasm');</script></head>
|
||||
<body>
|
||||
</body></html>
|
|
@ -3,11 +3,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>70年代、80年代、90年代,怀旧、复古、回忆</title>
|
||||
<script type="module">
|
||||
import init from "./songday.js"
|
||||
init()
|
||||
</script>
|
||||
<link rel="stylesheet" href="main.css">
|
||||
<link rel="stylesheet" href="asset/purecss.min.css">
|
||||
<style type="text/css">
|
||||
body{padding:20px}
|
||||
.tar{text-align:right}
|
|
@ -85,7 +85,7 @@ impl Component for Model {
|
|||
match msg {
|
||||
Msg::Authenticated(user) => {
|
||||
ConsoleService::log("signed in");
|
||||
store::save(CommonVar::AUTH_HEADER_NAME, Some(user.access_token));
|
||||
store::save(CommonVal::AUTH_HEADER_NAME, Some(user.access_token));
|
||||
ConsoleService::log("saved auth to store");
|
||||
self.user = Some(user.user_info);
|
||||
return true;
|
||||
|
@ -96,7 +96,7 @@ impl Component for Model {
|
|||
self.fetch_task = Some(r);
|
||||
},
|
||||
Msg::LogoutResponse(Ok::<String, _>(s)) => {
|
||||
store::save(CommonVar::AUTH_HEADER_NAME, None);
|
||||
store::save(CommonVal::AUTH_HEADER_NAME, None);
|
||||
ConsoleService::log("signed out");
|
||||
self.user = None;
|
||||
self.fetch_task = None;
|
||||
|
@ -181,7 +181,7 @@ impl Component for Model {
|
|||
fn rendered(&mut self, first_render: bool) {
|
||||
// Get current user info if a token is available when mounted
|
||||
if first_render {
|
||||
let token = store::get(CommonVar::AUTH_HEADER_NAME);
|
||||
let token = store::get(CommonVal::AUTH_HEADER_NAME);
|
||||
if token.is_some() {
|
||||
// let token = token.as_ref().unwrap();
|
||||
let r = request::get(val::USER_INFO_URL, self.link.callback(Msg::UserInfoResponse));
|
||||
|
|
|
@ -6,7 +6,7 @@ use yew::{
|
|||
};
|
||||
use yew_router::{agent::RouteRequest::ChangeRoute, prelude::*};
|
||||
|
||||
use blog_common::dto::post::{PostDetail, NewPost, Tag};
|
||||
use blog_common::dto::post::{NewPost, PostDetail, Tag};
|
||||
|
||||
use crate::{
|
||||
app::AppRoute,
|
||||
|
|
|
@ -10,7 +10,7 @@ use yew::{
|
|||
use yew_router::{agent::RouteRequest::ChangeRoute, prelude::*};
|
||||
|
||||
use blog_common::dto::{
|
||||
post::{PostDetail, NewPost},
|
||||
post::{NewPost, PostDetail},
|
||||
PaginationData,
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue