Compare commits
3 Commits
792b06a2eb
...
2b36a7c669
| Author | SHA1 | Date | |
|---|---|---|---|
| 2b36a7c669 | |||
| aa68dc4c55 | |||
| f855a9a6cd |
@ -3,12 +3,15 @@ use dioxus::prelude::*;
|
|||||||
use crate::api::comments::create_comment;
|
use crate::api::comments::create_comment;
|
||||||
use crate::components::comments::section::CommentContext;
|
use crate::components::comments::section::CommentContext;
|
||||||
use crate::components::forms::{INPUT_CLASS, BUTTON_PRIMARY_CLASS, AlertBox};
|
use crate::components::forms::{INPUT_CLASS, BUTTON_PRIMARY_CLASS, AlertBox};
|
||||||
|
use crate::hooks::comment_storage::{self, PendingComment};
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn CommentForm(post_id: i32, parent_id: Option<i64>) -> Element {
|
pub fn CommentForm(post_id: i32, parent_id: Option<i64>) -> Element {
|
||||||
let ctx: CommentContext = use_context();
|
let ctx: CommentContext = use_context();
|
||||||
let mut active_reply = ctx.active_reply;
|
let mut active_reply = ctx.active_reply;
|
||||||
let mut refresh_trigger = ctx.refresh_trigger;
|
let mut refresh_trigger = ctx.refresh_trigger;
|
||||||
|
let mut pending_comments = ctx.pending_comments;
|
||||||
|
|
||||||
let mut author_name = use_signal(String::new);
|
let mut author_name = use_signal(String::new);
|
||||||
let mut author_email = use_signal(String::new);
|
let mut author_email = use_signal(String::new);
|
||||||
let mut author_url = use_signal(String::new);
|
let mut author_url = use_signal(String::new);
|
||||||
@ -16,6 +19,19 @@ pub fn CommentForm(post_id: i32, parent_id: Option<i64>) -> Element {
|
|||||||
let mut honeypot = use_signal(String::new);
|
let mut honeypot = use_signal(String::new);
|
||||||
let mut submitting = use_signal(|| false);
|
let mut submitting = use_signal(|| false);
|
||||||
let mut message = use_signal(|| Option::<(String, &'static str)>::None);
|
let mut message = use_signal(|| Option::<(String, &'static str)>::None);
|
||||||
|
let mut loaded = use_signal(|| false);
|
||||||
|
|
||||||
|
use_effect(move || {
|
||||||
|
if loaded() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
loaded.set(true);
|
||||||
|
if let Some(info) = comment_storage::load_author() {
|
||||||
|
author_name.set(info.name);
|
||||||
|
author_email.set(info.email);
|
||||||
|
author_url.set(info.url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if let Some(pid) = parent_id {
|
if let Some(pid) = parent_id {
|
||||||
if active_reply() != Some(pid) {
|
if active_reply() != Some(pid) {
|
||||||
@ -103,6 +119,10 @@ pub fn CommentForm(post_id: i32, parent_id: Option<i64>) -> Element {
|
|||||||
class: BUTTON_PRIMARY_CLASS,
|
class: BUTTON_PRIMARY_CLASS,
|
||||||
disabled: submitting(),
|
disabled: submitting(),
|
||||||
onclick: move |_| {
|
onclick: move |_| {
|
||||||
|
if submitting() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let post_id = post_id;
|
let post_id = post_id;
|
||||||
let parent_id = parent_id;
|
let parent_id = parent_id;
|
||||||
let name = author_name();
|
let name = author_name();
|
||||||
@ -127,10 +147,10 @@ pub fn CommentForm(post_id: i32, parent_id: Option<i64>) -> Element {
|
|||||||
let result = create_comment(
|
let result = create_comment(
|
||||||
post_id,
|
post_id,
|
||||||
parent_id,
|
parent_id,
|
||||||
name,
|
name.clone(),
|
||||||
email,
|
email.clone(),
|
||||||
if url_val.trim().is_empty() { None } else { Some(url_val) },
|
if url_val.trim().is_empty() { None } else { Some(url_val.clone()) },
|
||||||
content,
|
content.clone(),
|
||||||
).await;
|
).await;
|
||||||
|
|
||||||
submitting.set(false);
|
submitting.set(false);
|
||||||
@ -138,6 +158,33 @@ pub fn CommentForm(post_id: i32, parent_id: Option<i64>) -> Element {
|
|||||||
match result {
|
match result {
|
||||||
Ok(resp) => {
|
Ok(resp) => {
|
||||||
if resp.success {
|
if resp.success {
|
||||||
|
comment_storage::save_author(
|
||||||
|
&name,
|
||||||
|
&email,
|
||||||
|
&url_val,
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(comment_id) = resp.comment_id {
|
||||||
|
let avatar_url = resp.avatar_url.unwrap_or_default();
|
||||||
|
let depth = resp.depth.unwrap_or(0);
|
||||||
|
|
||||||
|
let now = chrono::Utc::now().to_rfc3339();
|
||||||
|
let pending = PendingComment {
|
||||||
|
id: comment_id,
|
||||||
|
parent_id,
|
||||||
|
depth,
|
||||||
|
author_name: name.clone(),
|
||||||
|
author_url: if url_val.trim().is_empty() { None } else { Some(url_val) },
|
||||||
|
avatar_url,
|
||||||
|
content_md: content,
|
||||||
|
created_at: now.clone(),
|
||||||
|
stored_at: now,
|
||||||
|
};
|
||||||
|
|
||||||
|
comment_storage::save_pending_comment(post_id, pending.clone());
|
||||||
|
pending_comments.write().push(pending);
|
||||||
|
}
|
||||||
|
|
||||||
content_md.set(String::new());
|
content_md.set(String::new());
|
||||||
message.set(Some((resp.message, "success")));
|
message.set(Some((resp.message, "success")));
|
||||||
if parent_id.is_some() {
|
if parent_id.is_some() {
|
||||||
|
|||||||
@ -46,16 +46,12 @@ pub fn CommentList(
|
|||||||
rsx! {
|
rsx! {
|
||||||
div { class: "space-y-0 divide-y divide-gray-100 dark:divide-[#2a2a2a]",
|
div { class: "space-y-0 divide-y divide-gray-100 dark:divide-[#2a2a2a]",
|
||||||
for item in merged {
|
for item in merged {
|
||||||
let key_id = match &item {
|
|
||||||
MergedComment::Approved(c) => c.id,
|
|
||||||
MergedComment::Pending(c) => c.id,
|
|
||||||
};
|
|
||||||
match item {
|
match item {
|
||||||
MergedComment::Approved(comment) => rsx! {
|
MergedComment::Approved(comment) => rsx! {
|
||||||
CommentItem { key: "{key_id}", comment, post_id }
|
CommentItem { key: "{comment.id}", comment, post_id }
|
||||||
},
|
},
|
||||||
MergedComment::Pending(comment) => rsx! {
|
MergedComment::Pending(comment) => rsx! {
|
||||||
PendingCommentItem { key: "{key_id}", comment, post_id }
|
PendingCommentItem { key: "{comment.id}", comment, post_id }
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,8 @@ use dioxus::prelude::*;
|
|||||||
use crate::hooks::comment_storage::{PendingComment, render_pending_content};
|
use crate::hooks::comment_storage::{PendingComment, render_pending_content};
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn PendingCommentItem(comment: PendingComment, _post_id: i32) -> Element {
|
#[allow(unused_variables)]
|
||||||
|
pub fn PendingCommentItem(comment: PendingComment, post_id: i32) -> Element {
|
||||||
|
|
||||||
let depth = if comment.parent_id.is_none() && comment.depth > 0 {
|
let depth = if comment.parent_id.is_none() && comment.depth > 0 {
|
||||||
0
|
0
|
||||||
|
|||||||
@ -45,8 +45,8 @@ pub fn CommentSection(post_id: i32) -> Element {
|
|||||||
pending.write().retain(|c| !to_remove.contains(&c.id));
|
pending.write().retain(|c| !to_remove.contains(&c.id));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(_e) => {
|
||||||
tracing::warn!("check_pending_status failed: {}", e);
|
// Silently ignore on WASM; server-only logging not available
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
use chrono::{DateTime, Utc};
|
use chrono::DateTime;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
const AUTHOR_KEY: &str = "yggdrasil-comment-author";
|
const AUTHOR_KEY: &str = "yggdrasil-comment-author";
|
||||||
@ -28,6 +28,7 @@ pub struct PendingComment {
|
|||||||
|
|
||||||
type PendingMap = std::collections::HashMap<String, Vec<PendingComment>>;
|
type PendingMap = std::collections::HashMap<String, Vec<PendingComment>>;
|
||||||
|
|
||||||
|
#[allow(unused_variables)]
|
||||||
fn read_storage(key: &str) -> Option<String> {
|
fn read_storage(key: &str) -> Option<String> {
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
{
|
{
|
||||||
@ -41,6 +42,7 @@ fn read_storage(key: &str) -> Option<String> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused_variables)]
|
||||||
fn write_storage(key: &str, value: &str) {
|
fn write_storage(key: &str, value: &str) {
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user