mirror of
https://github.com/Nutomic/ibis.git
synced 2024-12-24 12:41:23 +00:00
finally compiling
This commit is contained in:
parent
5847e99128
commit
688ead9217
5 changed files with 136 additions and 132 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
@ -1781,6 +1781,7 @@ dependencies = [
|
||||||
"getrandom",
|
"getrandom",
|
||||||
"gloo-net",
|
"gloo-net",
|
||||||
"hex",
|
"hex",
|
||||||
|
"http",
|
||||||
"jsonwebtoken",
|
"jsonwebtoken",
|
||||||
"katex",
|
"katex",
|
||||||
"leptos",
|
"leptos",
|
||||||
|
@ -1803,6 +1804,7 @@ dependencies = [
|
||||||
"send_wrapper",
|
"send_wrapper",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"serde_urlencoded",
|
||||||
"sha2",
|
"sha2",
|
||||||
"smart-default",
|
"smart-default",
|
||||||
"time",
|
"time",
|
||||||
|
|
16
Cargo.toml
16
Cargo.toml
|
@ -29,12 +29,9 @@ ssr = [
|
||||||
"config",
|
"config",
|
||||||
"tower",
|
"tower",
|
||||||
"tower-layer",
|
"tower-layer",
|
||||||
|
"reqwest","diesel-derive-newtype"
|
||||||
]
|
]
|
||||||
hydrate = [
|
hydrate = ["leptos/hydrate", "katex/wasm-js", "gloo-net"]
|
||||||
"leptos/hydrate",
|
|
||||||
"katex/wasm-js",
|
|
||||||
]
|
|
||||||
diesel-derive-newtype = ["dep:diesel-derive-newtype"]
|
|
||||||
|
|
||||||
# This profile significantly speeds up build time. If debug info is needed you can comment the line
|
# This profile significantly speeds up build time. If debug info is needed you can comment the line
|
||||||
# out temporarily, but make sure to leave this in the main branch.
|
# out temporarily, but make sure to leave this in the main branch.
|
||||||
|
@ -73,7 +70,10 @@ sha2 = "0.10.8"
|
||||||
uuid = { version = "1.11.0", features = ["serde"] }
|
uuid = { version = "1.11.0", features = ["serde"] }
|
||||||
serde = { version = "1.0.215", features = ["derive"] }
|
serde = { version = "1.0.215", features = ["derive"] }
|
||||||
url = { version = "2.5.3", features = ["serde"] }
|
url = { version = "2.5.3", features = ["serde"] }
|
||||||
reqwest = { version = "0.12.9", features = ["json", "cookies"] }
|
reqwest = { version = "0.12.9", features = [
|
||||||
|
"json",
|
||||||
|
"cookies",
|
||||||
|
], optional = true }
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
tracing = "0.1.40"
|
tracing = "0.1.40"
|
||||||
once_cell = "1.20.2"
|
once_cell = "1.20.2"
|
||||||
|
@ -121,8 +121,10 @@ tower = { version = "0.5.1", optional = true }
|
||||||
tower-layer = { version = "0.3.3", optional = true }
|
tower-layer = { version = "0.3.3", optional = true }
|
||||||
console_log = "1.0.0"
|
console_log = "1.0.0"
|
||||||
send_wrapper = "0.6.0"
|
send_wrapper = "0.6.0"
|
||||||
gloo-net = "0.6.0"
|
gloo-net = { version = "0.6.0", optional = true }
|
||||||
web-sys = "0.3.72"
|
web-sys = "0.3.72"
|
||||||
|
http = "1.1.0"
|
||||||
|
serde_urlencoded = "0.7.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = "1.4.1"
|
pretty_assertions = "1.4.1"
|
||||||
|
|
|
@ -36,7 +36,7 @@ pub struct GetArticleForm {
|
||||||
pub id: Option<ArticleId>,
|
pub id: Option<ArticleId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Clone, Default)]
|
#[derive(Deserialize, Serialize, Clone, Default, Debug)]
|
||||||
pub struct ListArticlesForm {
|
pub struct ListArticlesForm {
|
||||||
pub only_local: Option<bool>,
|
pub only_local: Option<bool>,
|
||||||
pub instance_id: Option<InstanceId>,
|
pub instance_id: Option<InstanceId>,
|
||||||
|
@ -128,13 +128,13 @@ impl Default for EditVersion {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Clone)]
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
pub struct RegisterUserForm {
|
pub struct RegisterUserForm {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub password: String,
|
pub password: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
pub struct LoginUserForm {
|
pub struct LoginUserForm {
|
||||||
pub username: String,
|
pub username: String,
|
||||||
pub password: String,
|
pub password: String,
|
||||||
|
@ -188,7 +188,7 @@ impl DbPerson {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
pub struct CreateArticleForm {
|
pub struct CreateArticleForm {
|
||||||
pub title: String,
|
pub title: String,
|
||||||
pub text: String,
|
pub text: String,
|
||||||
|
@ -217,19 +217,19 @@ pub struct ProtectArticleForm {
|
||||||
pub protected: bool,
|
pub protected: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
pub struct ForkArticleForm {
|
pub struct ForkArticleForm {
|
||||||
pub article_id: ArticleId,
|
pub article_id: ArticleId,
|
||||||
pub new_title: String,
|
pub new_title: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
pub struct ApproveArticleForm {
|
pub struct ApproveArticleForm {
|
||||||
pub article_id: ArticleId,
|
pub article_id: ArticleId,
|
||||||
pub approve: bool,
|
pub approve: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
pub struct DeleteConflictForm {
|
pub struct DeleteConflictForm {
|
||||||
pub conflict_id: ConflictId,
|
pub conflict_id: ConflictId,
|
||||||
}
|
}
|
||||||
|
@ -244,12 +244,12 @@ pub struct FollowInstance {
|
||||||
pub id: InstanceId,
|
pub id: InstanceId,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Clone)]
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
pub struct SearchArticleForm {
|
pub struct SearchArticleForm {
|
||||||
pub query: String,
|
pub query: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
pub struct ResolveObject {
|
pub struct ResolveObject {
|
||||||
pub id: Url,
|
pub id: Url,
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,37 +11,40 @@ use crate::{
|
||||||
frontend::error::MyResult,
|
frontend::error::MyResult,
|
||||||
};
|
};
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use reqwest::{Client, RequestBuilder, StatusCode};
|
use http::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::fmt::Debug;
|
||||||
use std::sync::LazyLock;
|
use std::sync::LazyLock;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
pub static CLIENT: LazyLock<ApiClient> = LazyLock::new(|| ApiClient::new(Client::new(), None));
|
pub static CLIENT: LazyLock<ApiClient> = LazyLock::new(|| {
|
||||||
|
#[cfg(feature = "ssr")]
|
||||||
|
{
|
||||||
|
ApiClient::new(reqwest::Client::new(), None)
|
||||||
|
}
|
||||||
|
#[cfg(not(feature = "ssr"))]
|
||||||
|
{
|
||||||
|
ApiClient::new()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ApiClient {
|
pub struct ApiClient {
|
||||||
client: Client,
|
#[cfg(feature = "ssr")]
|
||||||
|
client: reqwest::Client,
|
||||||
pub hostname: String,
|
pub hostname: String,
|
||||||
ssl: bool,
|
ssl: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ApiClient {
|
impl ApiClient {
|
||||||
pub fn new(client: Client, hostname_: Option<String>) -> Self {
|
#[cfg(feature = "ssr")]
|
||||||
|
pub fn new(client: reqwest::Client, hostname_: Option<String>) -> Self {
|
||||||
let mut hostname;
|
let mut hostname;
|
||||||
let ssl;
|
let ssl;
|
||||||
#[cfg(not(feature = "ssr"))]
|
|
||||||
{
|
|
||||||
use leptos_use::use_document;
|
|
||||||
hostname = use_document().location().unwrap().host().unwrap();
|
|
||||||
ssl = !cfg!(debug_assertions);
|
|
||||||
}
|
|
||||||
#[cfg(feature = "ssr")]
|
|
||||||
{
|
|
||||||
use leptos::config::get_config_from_str;
|
use leptos::config::get_config_from_str;
|
||||||
let leptos_options = get_config_from_str(include_str!("../../Cargo.toml")).unwrap();
|
let leptos_options = get_config_from_str(include_str!("../../Cargo.toml")).unwrap();
|
||||||
hostname = leptos_options.site_addr.to_string();
|
hostname = leptos_options.site_addr.to_string();
|
||||||
ssl = false;
|
ssl = false;
|
||||||
}
|
|
||||||
// required for tests
|
// required for tests
|
||||||
if let Some(hostname_) = hostname_ {
|
if let Some(hostname_) = hostname_ {
|
||||||
hostname = hostname_;
|
hostname = hostname_;
|
||||||
|
@ -52,17 +55,12 @@ impl ApiClient {
|
||||||
ssl,
|
ssl,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(not(feature = "ssr"))]
|
||||||
async fn get<T, R>(&self, endpoint: &str, query: Option<R>) -> MyResult<T>
|
pub fn new() -> Self {
|
||||||
where
|
use leptos_use::use_document;
|
||||||
T: for<'de> Deserialize<'de>,
|
let hostname = use_document().location().unwrap().host().unwrap();
|
||||||
R: Serialize,
|
let ssl = !cfg!(debug_assertions);
|
||||||
{
|
Self { hostname, ssl }
|
||||||
let mut req = self.client.get(self.request_endpoint(endpoint));
|
|
||||||
if let Some(query) = query {
|
|
||||||
req = req.query(&query);
|
|
||||||
}
|
|
||||||
self.send::<T>(req).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_article(&self, data: GetArticleForm) -> MyResult<ArticleView> {
|
pub async fn get_article(&self, data: GetArticleForm) -> MyResult<ArticleView> {
|
||||||
|
@ -74,38 +72,24 @@ impl ApiClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn register(&self, register_form: RegisterUserForm) -> MyResult<LocalUserView> {
|
pub async fn register(&self, register_form: RegisterUserForm) -> MyResult<LocalUserView> {
|
||||||
let req = self
|
self.post("/api/v1/account/register", Some(®ister_form))
|
||||||
.client
|
.await
|
||||||
.post(self.request_endpoint("/api/v1/account/register"))
|
|
||||||
.form(®ister_form);
|
|
||||||
self.send::<LocalUserView>(req).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn login(&self, login_form: LoginUserForm) -> MyResult<LocalUserView> {
|
pub async fn login(&self, login_form: LoginUserForm) -> MyResult<LocalUserView> {
|
||||||
let req = self
|
self.post("/api/v1/account/login", Some(&login_form)).await
|
||||||
.client
|
|
||||||
.post(self.request_endpoint("/api/v1/account/login"))
|
|
||||||
.form(&login_form);
|
|
||||||
self.send::<LocalUserView>(req).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_article(&self, data: &CreateArticleForm) -> MyResult<ArticleView> {
|
pub async fn create_article(&self, data: &CreateArticleForm) -> MyResult<ArticleView> {
|
||||||
let req = self
|
self.send(Method::POST, "/api/v1/article", Some(&data))
|
||||||
.client
|
.await
|
||||||
.post(self.request_endpoint("/api/v1/article"))
|
|
||||||
.form(data);
|
|
||||||
self.send(req).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn edit_article_with_conflict(
|
pub async fn edit_article_with_conflict(
|
||||||
&self,
|
&self,
|
||||||
edit_form: &EditArticleForm,
|
edit_form: &EditArticleForm,
|
||||||
) -> MyResult<Option<ApiConflict>> {
|
) -> MyResult<Option<ApiConflict>> {
|
||||||
let req = self
|
self.get("/api/v1/article", Some(&edit_form)).await
|
||||||
.client
|
|
||||||
.patch(self.request_endpoint("/api/v1/article"))
|
|
||||||
.form(edit_form);
|
|
||||||
self.send(req).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn edit_article(&self, edit_form: &EditArticleForm) -> MyResult<ArticleView> {
|
pub async fn edit_article(&self, edit_form: &EditArticleForm) -> MyResult<ArticleView> {
|
||||||
|
@ -121,17 +105,13 @@ impl ApiClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn notifications_list(&self) -> MyResult<Vec<Notification>> {
|
pub async fn notifications_list(&self) -> MyResult<Vec<Notification>> {
|
||||||
let req = self
|
self.get("/api/v1/user/notifications/list", None::<()>)
|
||||||
.client
|
.await
|
||||||
.get(self.request_endpoint("/api/v1/user/notifications/list"));
|
|
||||||
self.send(req).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn notifications_count(&self) -> MyResult<usize> {
|
pub async fn notifications_count(&self) -> MyResult<usize> {
|
||||||
let req = self
|
self.get("/api/v1/user/notifications/count", None::<()>)
|
||||||
.client
|
.await
|
||||||
.get(self.request_endpoint("/api/v1/user/notifications/count"));
|
|
||||||
self.send(req).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn approve_article(&self, article_id: ArticleId, approve: bool) -> MyResult<()> {
|
pub async fn approve_article(&self, article_id: ArticleId, approve: bool) -> MyResult<()> {
|
||||||
|
@ -139,20 +119,13 @@ impl ApiClient {
|
||||||
article_id,
|
article_id,
|
||||||
approve,
|
approve,
|
||||||
};
|
};
|
||||||
let req = self
|
self.post("/api/v1/article/approve", Some(&form)).await
|
||||||
.client
|
|
||||||
.post(self.request_endpoint("/api/v1/article/approve"))
|
|
||||||
.form(&form);
|
|
||||||
self.send(req).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete_conflict(&self, conflict_id: ConflictId) -> MyResult<()> {
|
pub async fn delete_conflict(&self, conflict_id: ConflictId) -> MyResult<()> {
|
||||||
let form = DeleteConflictForm { conflict_id };
|
let form = DeleteConflictForm { conflict_id };
|
||||||
let req = self
|
self.send(Method::DELETE, "/api/v1/conflict", Some(form))
|
||||||
.client
|
.await
|
||||||
.delete(self.request_endpoint("/api/v1/conflict"))
|
|
||||||
.form(&form);
|
|
||||||
self.send(req).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn search(&self, search_form: &SearchArticleForm) -> MyResult<Vec<DbArticle>> {
|
pub async fn search(&self, search_form: &SearchArticleForm) -> MyResult<Vec<DbArticle>> {
|
||||||
|
@ -164,7 +137,7 @@ impl ApiClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_instance(&self, get_form: &GetInstance) -> MyResult<InstanceView> {
|
pub async fn get_instance(&self, get_form: &GetInstance) -> MyResult<InstanceView> {
|
||||||
self.get("/api/v1/instance", Some(get_form)).await
|
self.get("/api/v1/instance", Some(&get_form)).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn list_instances(&self) -> MyResult<Vec<DbInstance>> {
|
pub async fn list_instances(&self) -> MyResult<Vec<DbInstance>> {
|
||||||
|
@ -210,31 +183,22 @@ impl ApiClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn site(&self) -> MyResult<SiteView> {
|
pub async fn site(&self) -> MyResult<SiteView> {
|
||||||
let req = self.client.get(self.request_endpoint("/api/v1/site"));
|
self.get("/api/v1/site", None::<()>).await
|
||||||
self.send(req).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn logout(&self) -> MyResult<()> {
|
pub async fn logout(&self) -> MyResult<()> {
|
||||||
let req = self
|
Ok(self
|
||||||
.client
|
.get("/api/v1/account/logout", None::<()>)
|
||||||
.get(self.request_endpoint("/api/v1/account/logout"));
|
.await
|
||||||
Ok(self.send(req).await.unwrap())
|
.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn fork_article(&self, form: &ForkArticleForm) -> MyResult<ArticleView> {
|
pub async fn fork_article(&self, form: &ForkArticleForm) -> MyResult<ArticleView> {
|
||||||
let req = self
|
Ok(self.post("/api/v1/article/fork", Some(form)).await.unwrap())
|
||||||
.client
|
|
||||||
.post(self.request_endpoint("/api/v1/article/fork"))
|
|
||||||
.form(form);
|
|
||||||
Ok(self.send(req).await.unwrap())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn protect_article(&self, params: &ProtectArticleForm) -> MyResult<DbArticle> {
|
pub async fn protect_article(&self, params: &ProtectArticleForm) -> MyResult<DbArticle> {
|
||||||
let req = self
|
self.post("/api/v1/article/protect", Some(params)).await
|
||||||
.client
|
|
||||||
.post(self.request_endpoint("/api/v1/article/protect"))
|
|
||||||
.form(params);
|
|
||||||
self.send(req).await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn resolve_article(&self, id: Url) -> MyResult<ArticleView> {
|
pub async fn resolve_article(&self, id: Url) -> MyResult<ArticleView> {
|
||||||
|
@ -245,47 +209,67 @@ impl ApiClient {
|
||||||
|
|
||||||
pub async fn resolve_instance(&self, id: Url) -> MyResult<DbInstance> {
|
pub async fn resolve_instance(&self, id: Url) -> MyResult<DbInstance> {
|
||||||
let resolve_object = ResolveObject { id };
|
let resolve_object = ResolveObject { id };
|
||||||
self.get("/api/v1/instance/resolve", Some(resolve_object))
|
self.get("/api/v1/user", Some(resolve_object)).await
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
pub async fn get_user(&self, data: GetUserForm) -> MyResult<DbPerson> {
|
pub async fn get_user(&self, data: GetUserForm) -> MyResult<DbPerson> {
|
||||||
self.get("/api/v1/user", Some(data)).await
|
self.get("/api/v1/user", Some(data)).await
|
||||||
}
|
}
|
||||||
#[cfg(feature = "ssr")]
|
|
||||||
async fn send<T>(&self, mut req: RequestBuilder) -> MyResult<T>
|
async fn get<T, R>(&self, endpoint: &str, query: Option<R>) -> MyResult<T>
|
||||||
where
|
where
|
||||||
T: for<'de> Deserialize<'de>,
|
T: for<'de> Deserialize<'de>,
|
||||||
|
R: Serialize + Debug,
|
||||||
|
{
|
||||||
|
self.send(Method::GET, endpoint, query).await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn post<T, R>(&self, endpoint: &str, query: Option<R>) -> MyResult<T>
|
||||||
|
where
|
||||||
|
T: for<'de> Deserialize<'de>,
|
||||||
|
R: Serialize + Debug,
|
||||||
|
{
|
||||||
|
self.send(Method::POST, endpoint, query).await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "ssr")]
|
||||||
|
async fn send<P, T>(&self, method: Method, path: &str, params: Option<P>) -> MyResult<T>
|
||||||
|
where
|
||||||
|
P: Serialize + Debug,
|
||||||
|
T: for<'de> Deserialize<'de>,
|
||||||
{
|
{
|
||||||
use crate::common::{Auth, AUTH_COOKIE};
|
use crate::common::{Auth, AUTH_COOKIE};
|
||||||
use leptos::prelude::use_context;
|
use leptos::prelude::use_context;
|
||||||
use reqwest::header::HeaderName;
|
use reqwest::header::HeaderName;
|
||||||
|
let mut req = self
|
||||||
|
.client
|
||||||
|
.request(method, self.request_endpoint(path))
|
||||||
|
.query(¶ms);
|
||||||
let auth = use_context::<Auth>();
|
let auth = use_context::<Auth>();
|
||||||
if let Some(Auth(Some(auth))) = auth {
|
if let Some(Auth(Some(auth))) = auth {
|
||||||
req = req.header(HeaderName::from_static(AUTH_COOKIE), auth);
|
req = req.header(HeaderName::from_static(AUTH_COOKIE), auth);
|
||||||
}
|
}
|
||||||
let res = req.send().await?;
|
let res = req.send().await?;
|
||||||
let status = res.status();
|
let status = res.status();
|
||||||
let text = res.text().await?;
|
let text = res.text().await?.to_string();
|
||||||
if status == StatusCode::OK {
|
Self::response(status.into(), text)
|
||||||
Ok(serde_json::from_str(&text).map_err(|e| anyhow!("Json error on {text}: {e}"))?)
|
|
||||||
} else {
|
|
||||||
Err(anyhow!("API error: {text}").into())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "hydrate")]
|
#[cfg(not(feature = "ssr"))]
|
||||||
fn send<T>(
|
fn send<'a, P, T>(
|
||||||
&self,
|
&'a self,
|
||||||
mut req: RequestBuilder,
|
method: Method,
|
||||||
) -> impl std::future::Future<Output = MyResult<T>> + Send
|
path: &'a str,
|
||||||
|
params: Option<P>,
|
||||||
|
) -> impl std::future::Future<Output = MyResult<T>> + Send + 'a
|
||||||
where
|
where
|
||||||
|
P: Serialize + Debug + 'a,
|
||||||
T: for<'de> Deserialize<'de>,
|
T: for<'de> Deserialize<'de>,
|
||||||
{
|
{
|
||||||
use gloo_net::http::*;
|
use gloo_net::http::*;
|
||||||
use leptos::prelude::on_cleanup;
|
use leptos::prelude::on_cleanup;
|
||||||
use send_wrapper::SendWrapper;
|
use send_wrapper::SendWrapper;
|
||||||
use web_sys::RequestCredentials;
|
use std::collections::HashMap;
|
||||||
|
use web_sys::{RequestCredentials, UrlSearchParams};
|
||||||
|
|
||||||
SendWrapper::new(async move {
|
SendWrapper::new(async move {
|
||||||
let abort_controller = SendWrapper::new(web_sys::AbortController::new().ok());
|
let abort_controller = SendWrapper::new(web_sys::AbortController::new().ok());
|
||||||
|
@ -298,24 +282,40 @@ impl ApiClient {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
let path_with_endpoint = self.request_endpoint(path);
|
||||||
|
let path = if method == Method::GET {
|
||||||
|
let query = serde_urlencoded::to_string(¶ms).unwrap();
|
||||||
|
format!("{path_with_endpoint}?{query}")
|
||||||
|
} else {
|
||||||
|
path_with_endpoint
|
||||||
|
};
|
||||||
|
log::info!("{path}");
|
||||||
|
let builder = RequestBuilder::new(&path)
|
||||||
|
.method(method.clone())
|
||||||
|
.abort_signal(abort_signal.as_ref())
|
||||||
|
.credentials(RequestCredentials::Include);
|
||||||
|
let req = if method == Method::POST {
|
||||||
|
builder.json(¶ms)
|
||||||
|
} else {
|
||||||
|
builder.build()
|
||||||
|
}
|
||||||
|
.unwrap();
|
||||||
|
let res = req.send().await.unwrap();
|
||||||
|
let status = res.status();
|
||||||
|
let text = res.text().await.unwrap();
|
||||||
|
Self::response(status, text)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn response<T>(status: u16, text: String) -> MyResult<T>
|
||||||
|
where
|
||||||
|
T: for<'de> Deserialize<'de>,
|
||||||
|
{
|
||||||
if status == StatusCode::OK {
|
if status == StatusCode::OK {
|
||||||
Ok(serde_json::from_str(&text).map_err(|e| anyhow!("Json error on {text}: {e}"))?)
|
Ok(serde_json::from_str(&text).map_err(|e| anyhow!("Json error on {text}: {e}"))?)
|
||||||
} else {
|
} else {
|
||||||
Err(anyhow!("API error: {text}").into())
|
Err(anyhow!("API error: {text}").into())
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
Ok(RequestBuilder::new("/api/v1/site")
|
|
||||||
.method(Method::GET)
|
|
||||||
.abort_signal(abort_signal.as_ref())
|
|
||||||
.credentials(RequestCredentials::Include)
|
|
||||||
.send()
|
|
||||||
.await
|
|
||||||
.unwrap()
|
|
||||||
.json()
|
|
||||||
.await
|
|
||||||
.unwrap())
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn request_endpoint(&self, path: &str) -> String {
|
fn request_endpoint(&self, path: &str) -> String {
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub fn hydrate() {
|
||||||
use crate::frontend::app::App;
|
use crate::frontend::app::App;
|
||||||
console_log::init_with_level(log::Level::Debug).expect("error initializing logger");
|
console_log::init_with_level(log::Level::Debug).expect("error initializing logger");
|
||||||
console_error_panic_hook::set_once();
|
console_error_panic_hook::set_once();
|
||||||
mount_to_body(App);
|
leptos::mount::hydrate_body(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn article_link(article: &DbArticle) -> String {
|
fn article_link(article: &DbArticle) -> String {
|
||||||
|
|
Loading…
Reference in a new issue