From 5229ec34a787e26a97254ca5cd1f4bfac1967b36 Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Thu, 23 Jan 2025 22:34:18 +0100 Subject: [PATCH] Move frontend stuff into subfolders --- src/backend/database/mod.rs | 5 +- src/backend/federation/mod.rs | 2 +- src/backend/mod.rs | 3 +- src/backend/{ => utils}/config.rs | 0 src/backend/utils/mod.rs | 1 + src/frontend/app.rs | 78 ++++------- src/frontend/components/article_editor.rs | 2 +- src/frontend/components/article_nav.rs | 7 +- src/frontend/components/comment.rs | 7 +- src/frontend/components/edit_list.rs | 2 +- .../components/instance_follow_button.rs | 2 +- src/frontend/components/nav.rs | 8 +- src/frontend/components/protected_route.rs | 2 +- src/frontend/mod.rs | 123 +----------------- src/frontend/pages/article/actions.rs | 3 +- src/frontend/pages/article/create.rs | 2 +- src/frontend/pages/{ => article}/diff.rs | 4 +- src/frontend/pages/article/list.rs | 7 +- src/frontend/pages/article/mod.rs | 1 + src/frontend/pages/instance/details.rs | 10 +- src/frontend/pages/instance/list.rs | 3 +- src/frontend/pages/instance/mod.rs | 7 +- src/frontend/pages/{ => instance}/search.rs | 5 +- src/frontend/pages/mod.rs | 12 +- .../edit_profile.rs} | 2 +- src/frontend/pages/{ => user}/login.rs | 2 +- src/frontend/pages/user/mod.rs | 5 + .../pages/{ => user}/notifications.rs | 5 +- .../{user_profile.rs => user/profile.rs} | 2 +- src/frontend/pages/{ => user}/register.rs | 2 +- src/frontend/{ => utils}/dark_mode.rs | 2 +- src/frontend/utils/formatting.rs | 105 +++++++++++++++ src/frontend/utils/mod.rs | 17 +++ src/frontend/utils/resources.rs | 37 ++++++ src/main.rs | 2 +- tailwind.config.js | 1 - tests/common.rs | 2 +- 37 files changed, 251 insertions(+), 229 deletions(-) rename src/backend/{ => utils}/config.rs (100%) rename src/frontend/pages/{ => article}/diff.rs (96%) rename src/frontend/pages/{ => instance}/search.rs (97%) rename src/frontend/pages/{user_edit_profile.rs => user/edit_profile.rs} (98%) rename src/frontend/pages/{ => user}/login.rs (95%) create mode 100644 src/frontend/pages/user/mod.rs rename src/frontend/pages/{ => user}/notifications.rs (98%) rename src/frontend/pages/{user_profile.rs => user/profile.rs} (98%) rename src/frontend/pages/{ => user}/register.rs (96%) rename src/frontend/{ => utils}/dark_mode.rs (95%) create mode 100644 src/frontend/utils/formatting.rs create mode 100644 src/frontend/utils/mod.rs create mode 100644 src/frontend/utils/resources.rs diff --git a/src/backend/database/mod.rs b/src/backend/database/mod.rs index 736e9bd..4492e81 100644 --- a/src/backend/database/mod.rs +++ b/src/backend/database/mod.rs @@ -1,4 +1,7 @@ -use crate::backend::{config::IbisConfig, database::schema::jwt_secret, utils::error::MyResult}; +use crate::backend::{ + database::schema::jwt_secret, + utils::{config::IbisConfig, error::MyResult}, +}; use diesel::{ r2d2::{ConnectionManager, Pool}, PgConnection, diff --git a/src/backend/federation/mod.rs b/src/backend/federation/mod.rs index 318a11f..e39c70d 100644 --- a/src/backend/federation/mod.rs +++ b/src/backend/federation/mod.rs @@ -1,6 +1,6 @@ use super::utils::error::MyResult; use crate::{ - backend::{config::IbisConfig, database::IbisContext}, + backend::{database::IbisContext, utils::config::IbisConfig}, common::{instance::DbInstance, user::DbPerson}, }; use activities::announce::AnnounceActivity; diff --git a/src/backend/mod.rs b/src/backend/mod.rs index e352336..78af21a 100644 --- a/src/backend/mod.rs +++ b/src/backend/mod.rs @@ -1,9 +1,9 @@ use crate::{ backend::{ - config::IbisConfig, database::{article::DbArticleForm, instance::DbInstanceForm, IbisContext}, federation::{activities::submit_article_update, VerifyUrlData}, utils::{ + config::IbisConfig, error::{Error, MyResult}, generate_activity_id, }, @@ -37,7 +37,6 @@ use tokio::sync::oneshot; use utils::{generate_keypair, scheduled_tasks}; pub mod api; -pub mod config; pub mod database; pub mod federation; mod server; diff --git a/src/backend/config.rs b/src/backend/utils/config.rs similarity index 100% rename from src/backend/config.rs rename to src/backend/utils/config.rs diff --git a/src/backend/utils/mod.rs b/src/backend/utils/mod.rs index 5722606..47b5c9d 100644 --- a/src/backend/utils/mod.rs +++ b/src/backend/utils/mod.rs @@ -15,6 +15,7 @@ use rand::{distributions::Alphanumeric, thread_rng, Rng}; use std::sync::LazyLock; use url::{ParseError, Url}; +pub mod config; pub mod error; pub(super) mod scheduled_tasks; pub(super) mod validate; diff --git a/src/frontend/app.rs b/src/frontend/app.rs index b29a306..2cd58a2 100644 --- a/src/frontend/app.rs +++ b/src/frontend/app.rs @@ -1,30 +1,32 @@ -use crate::{ - common::instance::SiteView, - frontend::{ - api::CLIENT, - components::{nav::Nav, protected_route::IbisProtectedRoute}, - dark_mode::DarkMode, - instance_title, - pages::{ - article::{ - actions::ArticleActions, - create::CreateArticle, - discussion::ArticleDiscussion, - edit::EditArticle, - history::ArticleHistory, - list::ListArticles, - read::ReadArticle, - }, +use crate::frontend::{ + api::CLIENT, + components::{nav::Nav, protected_route::IbisProtectedRoute}, + pages::{ + article::{ + actions::ArticleActions, + create::CreateArticle, diff::EditDiff, - instance::{details::InstanceDetails, list::ListInstances, settings::InstanceSettings}, + discussion::ArticleDiscussion, + edit::EditArticle, + history::ArticleHistory, + list::ListArticles, + read::ReadArticle, + }, + instance::{ + details::InstanceDetails, + list::ListInstances, + search::Search, + settings::InstanceSettings, + }, + user::{ + edit_profile::UserEditProfile, login::Login, notifications::Notifications, + profile::UserProfile, register::Register, - search::Search, - user_edit_profile::UserEditProfile, - user_profile::UserProfile, }, }, + utils::{dark_mode::DarkMode, formatting::instance_title}, }; use leptos::prelude::*; use leptos_meta::{provide_meta_context, *}; @@ -33,40 +35,6 @@ use leptos_router::{ path, }; -pub fn site() -> Resource { - use_context::>().unwrap() -} - -pub fn is_logged_in() -> bool { - site().with_default(|site| site.my_profile.is_some()) -} -pub fn is_admin() -> bool { - site().with_default(|site| { - site.my_profile - .as_ref() - .map(|p| p.local_user.admin) - .unwrap_or(false) - }) -} -pub trait DefaultResource { - fn with_default(&self, f: impl FnOnce(&T) -> O) -> O; - fn get_default(&self) -> T; -} - -impl DefaultResource for Resource { - fn with_default(&self, f: impl FnOnce(&T) -> O) -> O { - self.with(|x| match x { - Some(x) => f(x), - None => f(&T::default()), - }) - } - fn get_default(&self) -> T { - match self.get() { - Some(x) => x.clone(), - None => T::default(), - } - } -} pub fn shell(options: LeptosOptions) -> impl IntoView { view! { diff --git a/src/frontend/components/article_editor.rs b/src/frontend/components/article_editor.rs index bf09f11..224b88e 100644 --- a/src/frontend/components/article_editor.rs +++ b/src/frontend/components/article_editor.rs @@ -1,4 +1,4 @@ -use crate::frontend::{markdown::render_article_markdown, use_cookie}; +use crate::frontend::{markdown::render_article_markdown, utils::use_cookie}; use leptos::{ev::beforeunload, html::Textarea, prelude::*}; use leptos_use::{use_event_listener, use_window}; diff --git a/src/frontend/components/article_nav.rs b/src/frontend/components/article_nav.rs index f2d69ab..b55846f 100644 --- a/src/frontend/components/article_nav.rs +++ b/src/frontend/components/article_nav.rs @@ -1,9 +1,8 @@ use crate::{ common::{article::DbArticleView, validation::can_edit_article}, - frontend::{ - app::{is_admin, is_logged_in}, - article_path, - article_title, + frontend::utils::{ + formatting::{article_path, article_title}, + resources::{is_admin, is_logged_in}, }, }; use leptos::prelude::*; diff --git a/src/frontend/components/comment.rs b/src/frontend/components/comment.rs index 774b495..42cff1a 100644 --- a/src/frontend/components/comment.rs +++ b/src/frontend/components/comment.rs @@ -6,11 +6,12 @@ use crate::{ }, frontend::{ api::CLIENT, - app::{site, DefaultResource}, components::comment_editor::{CommentEditorView, EditParams}, markdown::render_comment_markdown, - time_ago, - user_link, + utils::{ + formatting::{time_ago, user_link}, + resources::{site, DefaultResource}, + }, }, }; use leptos::prelude::*; diff --git a/src/frontend/components/edit_list.rs b/src/frontend/components/edit_list.rs index 8fecb02..487c2d8 100644 --- a/src/frontend/components/edit_list.rs +++ b/src/frontend/components/edit_list.rs @@ -1,6 +1,6 @@ use crate::{ common::{article::EditView, utils::extract_domain}, - frontend::{article_link, render_date_time, user_link}, + frontend::utils::formatting::{article_link, render_date_time, user_link}, }; use leptos::{either::Either, prelude::*}; diff --git a/src/frontend/components/instance_follow_button.rs b/src/frontend/components/instance_follow_button.rs index 02f5eb0..1499dd6 100644 --- a/src/frontend/components/instance_follow_button.rs +++ b/src/frontend/components/instance_follow_button.rs @@ -5,7 +5,7 @@ use crate::{ }, frontend::{ api::CLIENT, - app::{site, DefaultResource}, + utils::resources::{site, DefaultResource}, }, }; use leptos::prelude::*; diff --git a/src/frontend/components/nav.rs b/src/frontend/components/nav.rs index 09b32df..c43e8d7 100644 --- a/src/frontend/components/nav.rs +++ b/src/frontend/components/nav.rs @@ -1,8 +1,10 @@ use crate::frontend::{ api::CLIENT, - app::{is_admin, is_logged_in, site, DefaultResource}, - dark_mode::DarkMode, - instance_title, + utils::{ + dark_mode::DarkMode, + formatting::instance_title, + resources::{is_admin, is_logged_in, site, DefaultResource}, + }, }; use leptos::{component, prelude::*, view, IntoView, *}; use leptos_router::hooks::use_navigate; diff --git a/src/frontend/components/protected_route.rs b/src/frontend/components/protected_route.rs index d3182a7..842f4d9 100644 --- a/src/frontend/components/protected_route.rs +++ b/src/frontend/components/protected_route.rs @@ -1,4 +1,4 @@ -use crate::frontend::app::is_logged_in; +use crate::frontend::utils::resources::is_logged_in; use leptos::prelude::*; use leptos_router::{ components::{ProtectedRoute, ProtectedRouteProps}, diff --git a/src/frontend/mod.rs b/src/frontend/mod.rs index cb50f2f..716efe8 100644 --- a/src/frontend/mod.rs +++ b/src/frontend/mod.rs @@ -1,22 +1,11 @@ -use crate::common::{ - article::DbArticle, - instance::DbInstance, - user::DbPerson, - utils::extract_domain, -}; -use chrono::{DateTime, Duration, Local, Utc}; -use codee::string::FromToStringCodec; -use leptos::prelude::*; -use leptos_use::{use_cookie_with_options, SameSite, UseCookieOptions}; -use std::sync::OnceLock; -use timeago::Formatter; +use crate::common::article::DbArticle; pub mod api; pub mod app; mod components; -pub mod dark_mode; -pub mod markdown; -pub mod pages; +mod markdown; +mod pages; +mod utils; #[cfg(feature = "hydrate")] #[wasm_bindgen::prelude::wasm_bindgen] @@ -26,107 +15,3 @@ pub fn hydrate() { console_error_panic_hook::set_once(); leptos::mount::hydrate_body(App); } - -fn article_path(article: &DbArticle) -> String { - if article.local { - format!("/article/{}", article.title) - } else { - format!( - "/article/{}@{}", - article.title, - extract_domain(&article.ap_id) - ) - } -} - -fn article_link(article: &DbArticle) -> impl IntoView { - let article_path = article_path(article); - view! { - - {article.title.clone()} - - } -} - -fn article_title(article: &DbArticle) -> String { - let title = article.title.replace('_', " "); - if article.local { - title - } else { - format!("{}@{}", title, extract_domain(&article.ap_id)) - } -} - -fn user_title(person: &DbPerson) -> String { - let name = person - .display_name - .clone() - .unwrap_or(person.username.clone()); - if person.local { - format!("@{name}") - } else { - format!("@{}@{}", name, extract_domain(&person.ap_id)) - } -} - -fn user_link(person: &DbPerson) -> impl IntoView { - let creator_path = if person.local { - format!("/user/{}", person.username) - } else { - format!( - "/user/{}@{}", - person.username, - extract_domain(&person.ap_id) - ) - }; - view! { - - {user_title(person)} - - } -} - -fn render_date_time(date_time: DateTime) -> String { - date_time - .with_timezone(&Local) - .format("%Y-%m-%d %H:%M:%S") - .to_string() -} - -fn use_cookie(name: &str) -> (Signal>, WriteSignal>) { - let expires = (Local::now() + Duration::days(356)).timestamp(); - let cookie_options = UseCookieOptions::default() - .path("/") - .expires(expires) - .same_site(SameSite::Strict); - use_cookie_with_options::(name, cookie_options) -} - -fn time_ago(time: DateTime) -> String { - static INSTANCE: OnceLock = OnceLock::new(); - let secs = Utc::now().signed_duration_since(time).num_seconds(); - let duration = std::time::Duration::from_secs(secs.try_into().unwrap_or_default()); - INSTANCE.get_or_init(Formatter::new).convert(duration) -} - -fn instance_title_with_domain(instance: &DbInstance) -> String { - let name = instance.name.clone(); - let domain = instance.domain.clone(); - if let Some(name) = name { - format!("{name} ({domain})") - } else { - domain - } -} - -fn instance_title(instance: &DbInstance) -> String { - instance.name.clone().unwrap_or(instance.domain.clone()) -} - -fn instance_updated(instance: &DbInstance) -> String { - if instance.local { - "Local".to_string() - } else { - format!("Updated {}", time_ago(instance.last_refreshed_at)) - } -} diff --git a/src/frontend/pages/article/actions.rs b/src/frontend/pages/article/actions.rs index 9f45624..9832686 100644 --- a/src/frontend/pages/article/actions.rs +++ b/src/frontend/pages/article/actions.rs @@ -5,10 +5,9 @@ use crate::{ }, frontend::{ api::CLIENT, - app::is_admin, - article_path, components::article_nav::{ActiveTab, ArticleNav}, pages::article_resource, + utils::{formatting::article_path, resources::is_admin}, DbArticle, }, }; diff --git a/src/frontend/pages/article/create.rs b/src/frontend/pages/article/create.rs index 30b3d70..e21eb67 100644 --- a/src/frontend/pages/article/create.rs +++ b/src/frontend/pages/article/create.rs @@ -2,8 +2,8 @@ use crate::{ common::article::CreateArticleParams, frontend::{ api::CLIENT, - app::{is_admin, site, DefaultResource}, components::article_editor::EditorView, + utils::resources::{is_admin, site, DefaultResource}, }, }; use leptos::{html::Textarea, prelude::*}; diff --git a/src/frontend/pages/diff.rs b/src/frontend/pages/article/diff.rs similarity index 96% rename from src/frontend/pages/diff.rs rename to src/frontend/pages/article/diff.rs index cdd5e4f..b36bd0b 100644 --- a/src/frontend/pages/diff.rs +++ b/src/frontend/pages/article/diff.rs @@ -1,9 +1,7 @@ use crate::frontend::{ - article_title, components::article_nav::{ActiveTab, ArticleNav}, pages::{article_edits_resource, article_resource}, - render_date_time, - user_link, + utils::formatting::{article_title, render_date_time, user_link}, }; use leptos::prelude::*; use leptos_meta::Title; diff --git a/src/frontend/pages/article/list.rs b/src/frontend/pages/article/list.rs index 33e670d..91f4db5 100644 --- a/src/frontend/pages/article/list.rs +++ b/src/frontend/pages/article/list.rs @@ -2,10 +2,11 @@ use crate::{ common::article::ListArticlesParams, frontend::{ api::CLIENT, - app::DefaultResource, - article_path, - article_title, components::connect::ConnectView, + utils::{ + formatting::{article_path, article_title}, + resources::DefaultResource, + }, }, }; use leptos::prelude::*; diff --git a/src/frontend/pages/article/mod.rs b/src/frontend/pages/article/mod.rs index 013523d..0654613 100644 --- a/src/frontend/pages/article/mod.rs +++ b/src/frontend/pages/article/mod.rs @@ -1,5 +1,6 @@ pub mod actions; pub mod create; +pub mod diff; pub mod discussion; pub mod edit; pub mod history; diff --git a/src/frontend/pages/instance/details.rs b/src/frontend/pages/instance/details.rs index b92a49b..09d6f9e 100644 --- a/src/frontend/pages/instance/details.rs +++ b/src/frontend/pages/instance/details.rs @@ -2,11 +2,13 @@ use crate::{ common::{article::ListArticlesParams, instance::DbInstance, utils::http_protocol_str}, frontend::{ api::CLIENT, - article_path, - article_title, components::instance_follow_button::InstanceFollowButton, - instance_title_with_domain, - instance_updated, + utils::formatting::{ + article_path, + article_title, + instance_title_with_domain, + instance_updated, + }, }, }; use leptos::prelude::*; diff --git a/src/frontend/pages/instance/list.rs b/src/frontend/pages/instance/list.rs index d5a6b11..4cb54a3 100644 --- a/src/frontend/pages/instance/list.rs +++ b/src/frontend/pages/instance/list.rs @@ -1,8 +1,7 @@ use crate::frontend::{ api::CLIENT, components::connect::ConnectView, - instance_title_with_domain, - instance_updated, + utils::formatting::{instance_title_with_domain, instance_updated}, }; use leptos::prelude::*; use leptos_meta::Title; diff --git a/src/frontend/pages/instance/mod.rs b/src/frontend/pages/instance/mod.rs index ab754b2..c7d8365 100644 --- a/src/frontend/pages/instance/mod.rs +++ b/src/frontend/pages/instance/mod.rs @@ -1,3 +1,4 @@ -pub(crate) mod details; -pub(crate) mod list; -pub(crate) mod settings; +pub mod details; +pub mod list; +pub mod search; +pub mod settings; diff --git a/src/frontend/pages/search.rs b/src/frontend/pages/instance/search.rs similarity index 97% rename from src/frontend/pages/search.rs rename to src/frontend/pages/instance/search.rs index dcc366b..2783482 100644 --- a/src/frontend/pages/search.rs +++ b/src/frontend/pages/instance/search.rs @@ -3,7 +3,10 @@ use crate::{ article::{DbArticle, SearchArticleParams}, instance::DbInstance, }, - frontend::{api::CLIENT, article_path, article_title}, + frontend::{ + api::CLIENT, + utils::formatting::{article_path, article_title}, + }, }; use leptos::prelude::*; use leptos_meta::Title; diff --git a/src/frontend/pages/mod.rs b/src/frontend/pages/mod.rs index 24b0661..c648f24 100644 --- a/src/frontend/pages/mod.rs +++ b/src/frontend/pages/mod.rs @@ -8,15 +8,9 @@ use crate::{ use leptos::prelude::*; use leptos_router::hooks::use_params_map; -pub(crate) mod article; -pub(crate) mod diff; -pub(crate) mod instance; -pub(crate) mod login; -pub(crate) mod notifications; -pub(crate) mod register; -pub(crate) mod search; -pub(crate) mod user_edit_profile; -pub(crate) mod user_profile; +pub mod article; +pub mod instance; +pub mod user; fn article_resource() -> Resource { let params = use_params_map(); diff --git a/src/frontend/pages/user_edit_profile.rs b/src/frontend/pages/user/edit_profile.rs similarity index 98% rename from src/frontend/pages/user_edit_profile.rs rename to src/frontend/pages/user/edit_profile.rs index aabc9d3..f82f7e1 100644 --- a/src/frontend/pages/user_edit_profile.rs +++ b/src/frontend/pages/user/edit_profile.rs @@ -2,7 +2,7 @@ use crate::{ common::user::UpdateUserParams, frontend::{ api::CLIENT, - app::{site, DefaultResource}, + utils::resources::{site, DefaultResource}, }, }; use leptos::prelude::*; diff --git a/src/frontend/pages/login.rs b/src/frontend/pages/user/login.rs similarity index 95% rename from src/frontend/pages/login.rs rename to src/frontend/pages/user/login.rs index 29772cc..d4d4ac0 100644 --- a/src/frontend/pages/login.rs +++ b/src/frontend/pages/user/login.rs @@ -1,6 +1,6 @@ use crate::{ common::user::LoginUserParams, - frontend::{api::CLIENT, app::site, components::credentials::*}, + frontend::{api::CLIENT, components::credentials::*, utils::resources::site}, }; use leptos::prelude::*; use leptos_meta::Title; diff --git a/src/frontend/pages/user/mod.rs b/src/frontend/pages/user/mod.rs new file mode 100644 index 0000000..56930ef --- /dev/null +++ b/src/frontend/pages/user/mod.rs @@ -0,0 +1,5 @@ +pub mod edit_profile; +pub mod login; +pub mod notifications; +pub mod profile; +pub mod register; diff --git a/src/frontend/pages/notifications.rs b/src/frontend/pages/user/notifications.rs similarity index 98% rename from src/frontend/pages/notifications.rs rename to src/frontend/pages/user/notifications.rs index 9f7b719..104054e 100644 --- a/src/frontend/pages/notifications.rs +++ b/src/frontend/pages/user/notifications.rs @@ -1,6 +1,9 @@ use crate::{ common::Notification, - frontend::{api::CLIENT, article_path, article_title}, + frontend::{ + api::CLIENT, + utils::formatting::{article_path, article_title}, + }, }; use leptos::prelude::*; use leptos_meta::Title; diff --git a/src/frontend/pages/user_profile.rs b/src/frontend/pages/user/profile.rs similarity index 98% rename from src/frontend/pages/user_profile.rs rename to src/frontend/pages/user/profile.rs index 60ba568..a317607 100644 --- a/src/frontend/pages/user_profile.rs +++ b/src/frontend/pages/user/profile.rs @@ -4,7 +4,7 @@ use crate::{ api::CLIENT, components::edit_list::EditList, markdown::render_article_markdown, - user_title, + utils::formatting::user_title, }, }; use leptos::prelude::*; diff --git a/src/frontend/pages/register.rs b/src/frontend/pages/user/register.rs similarity index 96% rename from src/frontend/pages/register.rs rename to src/frontend/pages/user/register.rs index 343ca3d..7240db4 100644 --- a/src/frontend/pages/register.rs +++ b/src/frontend/pages/user/register.rs @@ -1,6 +1,6 @@ use crate::{ common::user::RegisterUserParams, - frontend::{api::CLIENT, app::site, components::credentials::*}, + frontend::{api::CLIENT, components::credentials::*, utils::resources::site}, }; use leptos::prelude::*; use leptos_meta::Title; diff --git a/src/frontend/dark_mode.rs b/src/frontend/utils/dark_mode.rs similarity index 95% rename from src/frontend/dark_mode.rs rename to src/frontend/utils/dark_mode.rs index 90fc374..855239a 100644 --- a/src/frontend/dark_mode.rs +++ b/src/frontend/utils/dark_mode.rs @@ -1,4 +1,4 @@ -use super::use_cookie; +use crate::frontend::utils::use_cookie; use leptos::prelude::*; use leptos_use::use_preferred_dark; diff --git a/src/frontend/utils/formatting.rs b/src/frontend/utils/formatting.rs new file mode 100644 index 0000000..aee5ccf --- /dev/null +++ b/src/frontend/utils/formatting.rs @@ -0,0 +1,105 @@ +use crate::common::{ + article::DbArticle, + instance::DbInstance, + user::DbPerson, + utils::extract_domain, +}; +use chrono::{DateTime, Local, Utc}; +use leptos::prelude::*; +use std::sync::OnceLock; +use timeago::Formatter; + +pub fn article_path(article: &DbArticle) -> String { + if article.local { + format!("/article/{}", article.title) + } else { + format!( + "/article/{}@{}", + article.title, + extract_domain(&article.ap_id) + ) + } +} + +pub fn article_link(article: &DbArticle) -> impl IntoView { + let article_path = article_path(article); + view! { + + {article.title.clone()} + + } +} + +pub fn article_title(article: &DbArticle) -> String { + let title = article.title.replace('_', " "); + if article.local { + title + } else { + format!("{}@{}", title, extract_domain(&article.ap_id)) + } +} + +pub fn user_title(person: &DbPerson) -> String { + let name = person + .display_name + .clone() + .unwrap_or(person.username.clone()); + if person.local { + format!("@{name}") + } else { + format!("@{}@{}", name, extract_domain(&person.ap_id)) + } +} + +pub fn user_link(person: &DbPerson) -> impl IntoView { + let creator_path = if person.local { + format!("/user/{}", person.username) + } else { + format!( + "/user/{}@{}", + person.username, + extract_domain(&person.ap_id) + ) + }; + view! { + + {user_title(person)} + + } +} + +pub fn render_date_time(date_time: DateTime) -> String { + date_time + .with_timezone(&Local) + .format("%Y-%m-%d %H:%M:%S") + .to_string() +} + +pub fn time_ago(time: DateTime) -> String { + static INSTANCE: OnceLock = OnceLock::new(); + let secs = Utc::now().signed_duration_since(time).num_seconds(); + let duration = std::time::Duration::from_secs(secs.try_into().unwrap_or_default()); + INSTANCE.get_or_init(Formatter::new).convert(duration) +} + +pub fn instance_title_with_domain(instance: &DbInstance) -> String { + let name = instance.name.clone(); + let domain = instance.domain.clone(); + if let Some(name) = name { + format!("{name} ({domain})") + } else { + domain + } +} + +pub fn instance_title(instance: &DbInstance) -> String { + instance.name.clone().unwrap_or(instance.domain.clone()) +} + +pub fn instance_updated(instance: &DbInstance) -> String { + if instance.local { + "Local".to_string() + } else { + format!("Updated {}", time_ago(instance.last_refreshed_at)) + } +} diff --git a/src/frontend/utils/mod.rs b/src/frontend/utils/mod.rs new file mode 100644 index 0000000..fd9b4da --- /dev/null +++ b/src/frontend/utils/mod.rs @@ -0,0 +1,17 @@ +use chrono::{Duration, Local}; +use codee::string::FromToStringCodec; +use leptos::prelude::*; +use leptos_use::{use_cookie_with_options, SameSite, UseCookieOptions}; + +pub mod dark_mode; +pub mod formatting; +pub mod resources; + +pub fn use_cookie(name: &str) -> (Signal>, WriteSignal>) { + let expires = (Local::now() + Duration::days(356)).timestamp(); + let cookie_options = UseCookieOptions::default() + .path("/") + .expires(expires) + .same_site(SameSite::Strict); + use_cookie_with_options::(name, cookie_options) +} diff --git a/src/frontend/utils/resources.rs b/src/frontend/utils/resources.rs new file mode 100644 index 0000000..c0ae814 --- /dev/null +++ b/src/frontend/utils/resources.rs @@ -0,0 +1,37 @@ +use crate::common::instance::SiteView; +use leptos::prelude::*; + +pub fn site() -> Resource { + use_context::>().unwrap() +} + +pub fn is_logged_in() -> bool { + site().with_default(|site| site.my_profile.is_some()) +} +pub fn is_admin() -> bool { + site().with_default(|site| { + site.my_profile + .as_ref() + .map(|p| p.local_user.admin) + .unwrap_or(false) + }) +} +pub trait DefaultResource { + fn with_default(&self, f: impl FnOnce(&T) -> O) -> O; + fn get_default(&self) -> T; +} + +impl DefaultResource for Resource { + fn with_default(&self, f: impl FnOnce(&T) -> O) -> O { + self.with(|x| match x { + Some(x) => f(x), + None => f(&T::default()), + }) + } + fn get_default(&self) -> T { + match self.get() { + Some(x) => x.clone(), + None => T::default(), + } + } +} diff --git a/src/main.rs b/src/main.rs index bd4c161..8b6ba91 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,7 @@ #[cfg(feature = "ssr")] #[tokio::main] pub async fn main() -> ibis::backend::utils::error::MyResult<()> { - use ibis::backend::config::IbisConfig; + use ibis::backend::utils::config::IbisConfig; use log::LevelFilter; if std::env::args().collect::>().get(1) == Some(&"--print-config".to_string()) { diff --git a/tailwind.config.js b/tailwind.config.js index 6a665e0..cb35b9e 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -11,7 +11,6 @@ module.exports = { require('@tailwindcss/typography') ], daisyui: { - //themes: ["emerald", "dim"] themes: [ { emerald: { diff --git a/tests/common.rs b/tests/common.rs index 402d834..6d851d0 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -3,8 +3,8 @@ use anyhow::Result; use ibis::{ backend::{ - config::{IbisConfig, IbisConfigDatabase, IbisConfigFederation}, start, + utils::config::{IbisConfig, IbisConfigDatabase, IbisConfigFederation}, }, common::{instance::Options, user::RegisterUserParams}, frontend::api::ApiClient,