mirror of
https://github.com/Nutomic/ibis.git
synced 2025-02-03 16:01:35 +00:00
Move frontend stuff into subfolders
This commit is contained in:
parent
ae44c169ba
commit
5229ec34a7
37 changed files with 251 additions and 229 deletions
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<SiteView> {
|
||||
use_context::<Resource<SiteView>>().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<T> {
|
||||
fn with_default<O>(&self, f: impl FnOnce(&T) -> O) -> O;
|
||||
fn get_default(&self) -> T;
|
||||
}
|
||||
|
||||
impl<T: Default + Send + Sync + Clone> DefaultResource<T> for Resource<T> {
|
||||
fn with_default<O>(&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! {
|
||||
<!DOCTYPE html>
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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::*;
|
||||
|
|
|
@ -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::*;
|
||||
|
|
|
@ -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::*};
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::{
|
|||
},
|
||||
frontend::{
|
||||
api::CLIENT,
|
||||
app::{site, DefaultResource},
|
||||
utils::resources::{site, DefaultResource},
|
||||
},
|
||||
};
|
||||
use leptos::prelude::*;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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! {
|
||||
<a class="link" href=article_path>
|
||||
{article.title.clone()}
|
||||
</a>
|
||||
}
|
||||
}
|
||||
|
||||
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! {
|
||||
<a class="link" href=creator_path>
|
||||
{user_title(person)}
|
||||
</a>
|
||||
}
|
||||
}
|
||||
|
||||
fn render_date_time(date_time: DateTime<Utc>) -> String {
|
||||
date_time
|
||||
.with_timezone(&Local)
|
||||
.format("%Y-%m-%d %H:%M:%S")
|
||||
.to_string()
|
||||
}
|
||||
|
||||
fn use_cookie(name: &str) -> (Signal<Option<bool>>, WriteSignal<Option<bool>>) {
|
||||
let expires = (Local::now() + Duration::days(356)).timestamp();
|
||||
let cookie_options = UseCookieOptions::default()
|
||||
.path("/")
|
||||
.expires(expires)
|
||||
.same_site(SameSite::Strict);
|
||||
use_cookie_with_options::<bool, FromToStringCodec>(name, cookie_options)
|
||||
}
|
||||
|
||||
fn time_ago(time: DateTime<Utc>) -> String {
|
||||
static INSTANCE: OnceLock<Formatter> = 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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -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::*};
|
||||
|
|
|
@ -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;
|
|
@ -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::*;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
pub mod actions;
|
||||
pub mod create;
|
||||
pub mod diff;
|
||||
pub mod discussion;
|
||||
pub mod edit;
|
||||
pub mod history;
|
||||
|
|
|
@ -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::*;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
|
@ -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<DbArticleView> {
|
||||
let params = use_params_map();
|
||||
|
|
|
@ -2,7 +2,7 @@ use crate::{
|
|||
common::user::UpdateUserParams,
|
||||
frontend::{
|
||||
api::CLIENT,
|
||||
app::{site, DefaultResource},
|
||||
utils::resources::{site, DefaultResource},
|
||||
},
|
||||
};
|
||||
use leptos::prelude::*;
|
|
@ -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;
|
5
src/frontend/pages/user/mod.rs
Normal file
5
src/frontend/pages/user/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
|||
pub mod edit_profile;
|
||||
pub mod login;
|
||||
pub mod notifications;
|
||||
pub mod profile;
|
||||
pub mod register;
|
|
@ -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;
|
|
@ -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::*;
|
|
@ -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;
|
|
@ -1,4 +1,4 @@
|
|||
use super::use_cookie;
|
||||
use crate::frontend::utils::use_cookie;
|
||||
use leptos::prelude::*;
|
||||
use leptos_use::use_preferred_dark;
|
||||
|
105
src/frontend/utils/formatting.rs
Normal file
105
src/frontend/utils/formatting.rs
Normal file
|
@ -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! {
|
||||
<a class="link" href=article_path>
|
||||
{article.title.clone()}
|
||||
</a>
|
||||
}
|
||||
}
|
||||
|
||||
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! {
|
||||
<a class="link" href=creator_path>
|
||||
{user_title(person)}
|
||||
</a>
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_date_time(date_time: DateTime<Utc>) -> String {
|
||||
date_time
|
||||
.with_timezone(&Local)
|
||||
.format("%Y-%m-%d %H:%M:%S")
|
||||
.to_string()
|
||||
}
|
||||
|
||||
pub fn time_ago(time: DateTime<Utc>) -> String {
|
||||
static INSTANCE: OnceLock<Formatter> = 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))
|
||||
}
|
||||
}
|
17
src/frontend/utils/mod.rs
Normal file
17
src/frontend/utils/mod.rs
Normal file
|
@ -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<Option<bool>>, WriteSignal<Option<bool>>) {
|
||||
let expires = (Local::now() + Duration::days(356)).timestamp();
|
||||
let cookie_options = UseCookieOptions::default()
|
||||
.path("/")
|
||||
.expires(expires)
|
||||
.same_site(SameSite::Strict);
|
||||
use_cookie_with_options::<bool, FromToStringCodec>(name, cookie_options)
|
||||
}
|
37
src/frontend/utils/resources.rs
Normal file
37
src/frontend/utils/resources.rs
Normal file
|
@ -0,0 +1,37 @@
|
|||
use crate::common::instance::SiteView;
|
||||
use leptos::prelude::*;
|
||||
|
||||
pub fn site() -> Resource<SiteView> {
|
||||
use_context::<Resource<SiteView>>().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<T> {
|
||||
fn with_default<O>(&self, f: impl FnOnce(&T) -> O) -> O;
|
||||
fn get_default(&self) -> T;
|
||||
}
|
||||
|
||||
impl<T: Default + Send + Sync + Clone> DefaultResource<T> for Resource<T> {
|
||||
fn with_default<O>(&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(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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::<Vec<_>>().get(1) == Some(&"--print-config".to_string()) {
|
||||
|
|
|
@ -11,7 +11,6 @@ module.exports = {
|
|||
require('@tailwindcss/typography')
|
||||
],
|
||||
daisyui: {
|
||||
//themes: ["emerald", "dim"]
|
||||
themes: [
|
||||
{
|
||||
emerald: {
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue