webcomment/webui/src/api.rs
2023-07-13 11:36:31 +02:00

119 lines
2.7 KiB
Rust

use crate::types::*;
use webcomment_common::{api::*, types::*};
use gloo::{console, net::http};
use parking_lot::RwLock;
use std::collections::HashMap;
use std::sync::Arc;
pub struct ApiInner {
pub admin_psw: Option<String>,
pub comments: HashMap<CommentId, StoredComment>,
/// Comments that are not yet attributed CommentId by the server
pub local_comments: HashMap<CommentId, StoredComment>,
pub url: String,
}
#[derive(Clone)]
pub struct Api {
pub inner: Arc<RwLock<ApiInner>>,
}
impl Api {
pub async fn get_comments_by_topic(&self, topic: String) {
match http::Request::post(&format!("{}/api/comments_by_topic", &self.inner.read().url))
.body(
serde_json::to_string(&queries::CommentsByTopic {
mutation_token: None,
topic,
})
.unwrap(),
)
.unwrap()
.send()
.await
{
Ok(resp) => {
let Ok(Ok(resps::Response::CommentsByTopic(resp))) = resp.json::<resps::Result>().await else {
// TODO error
return;
};
let mut inner = self.inner.write();
for comment in resp.approved_comments {
let Ok(comment_id) = CommentId::from_base64(&comment.id) else {
continue
};
inner.comments.insert(
comment_id,
StoredComment {
author: comment.author,
email: comment.email,
last_edit_time: comment.last_edit_time,
post_time: comment.post_time,
text: comment.text,
},
);
}
}
Err(e) => console::log!("get_comments_by_topic: {}", e.to_string()),
}
}
pub async fn new_comment(&self, new_comment: StoredComment, topic: String) {
let local_id = CommentId::new();
self.inner
.write()
.local_comments
.insert(local_id.clone(), new_comment.clone());
match http::Request::post(&format!("{}/api/new_comment", &self.inner.read().url))
.body(
serde_json::to_string(&queries::NewComment {
author: new_comment.author,
topic,
email: new_comment.email.unwrap_or_default(),
text: new_comment.text,
})
.unwrap(),
)
.unwrap()
.send()
.await
{
Ok(resp) => {
let Ok(Ok(resps::Response::NewComment(resp))) = resp.json::<resps::Result>().await else {
// TODO error
return;
};
let mut inner = self.inner.write();
let Ok(comment_id) = CommentId::from_base64(&resp.id) else {
// TODO error
return;
};
let Some(comment) = inner.local_comments.remove(&local_id) else {
// TODO error
return;
};
inner.comments.insert(comment_id, comment);
}
Err(e) => console::log!("get_comments_by_topic: {}", e.to_string()),
}
}
}
impl PartialEq<Api> for Api {
fn eq(&self, rhs: &Self) -> bool {
true
}
}
/*pub enum Msg {
NewComment {
new_comment: StoredComment, topic: String
}
}
pub async fn msg_handler(yew::platform::pinned::mpsc::) {
}*/