mirror of
https://github.com/Nutomic/ibis.git
synced 2024-11-22 12:01:08 +00:00
Better dark mode storage using cookie
This commit is contained in:
parent
519a6c4848
commit
6cd87cf790
6 changed files with 52 additions and 32 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
@ -1780,6 +1780,7 @@ dependencies = [
|
||||||
"axum-macros",
|
"axum-macros",
|
||||||
"bcrypt",
|
"bcrypt",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
"codee",
|
||||||
"config",
|
"config",
|
||||||
"console_error_panic_hook",
|
"console_error_panic_hook",
|
||||||
"diesel",
|
"diesel",
|
||||||
|
@ -1796,7 +1797,6 @@ dependencies = [
|
||||||
"leptos",
|
"leptos",
|
||||||
"leptos-use",
|
"leptos-use",
|
||||||
"leptos_axum",
|
"leptos_axum",
|
||||||
"leptos_darkmode",
|
|
||||||
"leptos_meta",
|
"leptos_meta",
|
||||||
"leptos_router",
|
"leptos_router",
|
||||||
"log",
|
"log",
|
||||||
|
@ -2022,9 +2022,11 @@ dependencies = [
|
||||||
"default-struct-builder",
|
"default-struct-builder",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"gloo-timers",
|
"gloo-timers",
|
||||||
|
"http",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"leptos",
|
"leptos",
|
||||||
|
"leptos_axum",
|
||||||
"paste",
|
"paste",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"unic-langid",
|
"unic-langid",
|
||||||
|
@ -2070,16 +2072,6 @@ dependencies = [
|
||||||
"typed-builder",
|
"typed-builder",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "leptos_darkmode"
|
|
||||||
version = "0.2.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "35ec7c7c56b312da0a739680cc2cb70d641eb82adbc1f83a565c2e9562a96253"
|
|
||||||
dependencies = [
|
|
||||||
"leptos",
|
|
||||||
"web-sys",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "leptos_dom"
|
name = "leptos_dom"
|
||||||
version = "0.6.15"
|
version = "0.6.15"
|
||||||
|
|
|
@ -20,6 +20,7 @@ ssr = [
|
||||||
"katex/duktape",
|
"katex/duktape",
|
||||||
"leptos/ssr",
|
"leptos/ssr",
|
||||||
"leptos-use/ssr",
|
"leptos-use/ssr",
|
||||||
|
"leptos-use/axum"
|
||||||
]
|
]
|
||||||
hydrate = [
|
hydrate = [
|
||||||
"leptos/hydrate",
|
"leptos/hydrate",
|
||||||
|
@ -108,7 +109,7 @@ markdown-it-footnote = "0.2.0"
|
||||||
markdown-it-sub = "1.0.0"
|
markdown-it-sub = "1.0.0"
|
||||||
markdown-it-sup = "1.0.0"
|
markdown-it-sup = "1.0.0"
|
||||||
leptos-use = "0.13.6"
|
leptos-use = "0.13.6"
|
||||||
leptos_darkmode = "0.2.0"
|
codee = "0.2.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
pretty_assertions = "1.4.1"
|
pretty_assertions = "1.4.1"
|
||||||
|
|
|
@ -3,6 +3,7 @@ use crate::{
|
||||||
frontend::{
|
frontend::{
|
||||||
api::ApiClient,
|
api::ApiClient,
|
||||||
components::nav::Nav,
|
components::nav::Nav,
|
||||||
|
dark_mode::DarkMode,
|
||||||
pages::{
|
pages::{
|
||||||
article::{
|
article::{
|
||||||
actions::ArticleActions,
|
actions::ArticleActions,
|
||||||
|
@ -37,7 +38,6 @@ use leptos::{
|
||||||
SignalGetUntracked,
|
SignalGetUntracked,
|
||||||
SignalUpdate,
|
SignalUpdate,
|
||||||
};
|
};
|
||||||
use leptos_darkmode::Darkmode;
|
|
||||||
use leptos_meta::{provide_meta_context, *};
|
use leptos_meta::{provide_meta_context, *};
|
||||||
use leptos_router::{Route, Router, Routes};
|
use leptos_router::{Route, Router, Routes};
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
|
@ -91,18 +91,11 @@ pub fn App() -> impl IntoView {
|
||||||
GlobalState::update_my_profile();
|
GlobalState::update_my_profile();
|
||||||
provide_context(create_rw_signal(global_state));
|
provide_context(create_rw_signal(global_state));
|
||||||
|
|
||||||
let darkmode = Darkmode::init();
|
let darkmode = DarkMode::init();
|
||||||
provide_context(darkmode.clone());
|
provide_context(darkmode.clone());
|
||||||
let theme = move || {
|
|
||||||
if darkmode.is_light() {
|
|
||||||
"emerald"
|
|
||||||
} else {
|
|
||||||
"dim"
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<Html attr:data-theme=theme class="h-full" />
|
<Html attr:data-theme=darkmode.theme class="h-full" />
|
||||||
<Body class="min-h-full flex max-sm:flex-col md:divide-x divide-slate-400 divide-solid" />
|
<Body class="min-h-full flex max-sm:flex-col md:divide-x divide-slate-400 divide-solid" />
|
||||||
<>
|
<>
|
||||||
<Stylesheet id="ibis" href="/pkg/ibis.css" />
|
<Stylesheet id="ibis" href="/pkg/ibis.css" />
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::frontend::app::GlobalState;
|
use crate::frontend::{app::GlobalState, dark_mode::DarkMode};
|
||||||
use leptos::{component, use_context, view, IntoView, RwSignal, SignalWith, *};
|
use leptos::{component, use_context, view, IntoView, RwSignal, SignalWith, *};
|
||||||
use leptos_darkmode::Darkmode;
|
|
||||||
use leptos_router::*;
|
use leptos_router::*;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
|
@ -22,6 +21,7 @@ pub fn Nav() -> impl IntoView {
|
||||||
);
|
);
|
||||||
|
|
||||||
let (search_query, set_search_query) = create_signal(String::new());
|
let (search_query, set_search_query) = create_signal(String::new());
|
||||||
|
let mut dark_mode = expect_context::<DarkMode>();
|
||||||
view! {
|
view! {
|
||||||
<nav class="max-sm:navbar p-2.5">
|
<nav class="max-sm:navbar p-2.5">
|
||||||
<div
|
<div
|
||||||
|
@ -126,14 +126,8 @@ pub fn Nav() -> impl IntoView {
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="toggle"
|
class="toggle"
|
||||||
checked=move || {
|
prop:checked=dark_mode.is_dark
|
||||||
if expect_context::<Darkmode>().is_light() {
|
on:click=move |_| { dark_mode.toggle() }
|
||||||
"checked"
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
on:click=move |_| { expect_context::<Darkmode>().toggle() }
|
|
||||||
/>
|
/>
|
||||||
<span class="label-text">Dark</span>
|
<span class="label-text">Dark</span>
|
||||||
</label>
|
</label>
|
||||||
|
|
39
src/frontend/dark_mode.rs
Normal file
39
src/frontend/dark_mode.rs
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
use chrono::{Duration, Local};
|
||||||
|
use codee::string::FromToStringCodec;
|
||||||
|
use leptos::{Signal, SignalGet, SignalGetUntracked, SignalSet, WriteSignal};
|
||||||
|
use leptos_use::{use_cookie_with_options, use_preferred_dark, SameSite, UseCookieOptions};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct DarkMode {
|
||||||
|
cookie: WriteSignal<Option<bool>>,
|
||||||
|
pub is_dark: Signal<bool>,
|
||||||
|
pub theme: Signal<&'static str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DarkMode {
|
||||||
|
pub fn init() -> Self {
|
||||||
|
let expires = (Local::now() + Duration::days(356)).timestamp();
|
||||||
|
let cookie_options = UseCookieOptions::default()
|
||||||
|
.path("/")
|
||||||
|
.expires(expires)
|
||||||
|
.same_site(SameSite::Strict);
|
||||||
|
let cookie =
|
||||||
|
use_cookie_with_options::<bool, FromToStringCodec>("dark_mode", cookie_options);
|
||||||
|
|
||||||
|
let is_dark = Signal::derive(move || {
|
||||||
|
let default = || use_preferred_dark().get_untracked();
|
||||||
|
cookie.0.get().unwrap_or_else(default)
|
||||||
|
});
|
||||||
|
let theme = Signal::derive(move || if is_dark.get() { "dim" } else { "emerald" });
|
||||||
|
Self {
|
||||||
|
cookie: cookie.1,
|
||||||
|
is_dark,
|
||||||
|
theme,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn toggle(&mut self) {
|
||||||
|
let new = !self.is_dark.get_untracked();
|
||||||
|
self.cookie.set(Some(new));
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@ use leptos::*;
|
||||||
pub mod api;
|
pub mod api;
|
||||||
pub mod app;
|
pub mod app;
|
||||||
mod components;
|
mod components;
|
||||||
|
pub mod dark_mode;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod markdown;
|
pub mod markdown;
|
||||||
pub mod pages;
|
pub mod pages;
|
||||||
|
|
Loading…
Reference in a new issue