Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dark mode #104

Merged
merged 4 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion backend/Cargo.toml
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] }
uuid = { version = "1.2", features = ["v4", "serde"] }

[dev-dependencies]
lettre = { version = "0.10", default-features = false, features=["smtp-transport", "hostname", "builder"] }
lettre = { version = "0.10", default-features = false, features=[
"builder",
"hostname",
"smtp-transport"
] }
fake = { version = "2.5", features=["derive"]}
reqwest = { version = "0.11", features = ["json"] }
local-ip-address = "0.5"
13 changes: 12 additions & 1 deletion frontend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,17 @@ serde-json-wasm = "0.5"
timeago = "0.4"
wasm-bindgen = "0.2"
wasm-bindgen-futures = "0.4"
web-sys = { version = "0.3", features = ["Event", "EventTarget", "NodeList", "HtmlLinkElement", "HtmlIFrameElement", "CssStyleDeclaration"] }
web-sys = { version = "0.3", features = [
"CssStyleDeclaration",
"DomTokenList",
"Element",
"Event",
"EventTarget",
"HtmlElement",
"HtmlIFrameElement",
"HtmlLinkElement",
"MediaQueryList",
"NodeList"
] }
yew = "0.20"
yew-hooks = "0.2"
3 changes: 3 additions & 0 deletions frontend/img/dark-mode.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 13 additions & 1 deletion frontend/img/envelope-open.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 15 additions & 1 deletion frontend/img/envelope.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 3 additions & 1 deletion frontend/img/trash.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
73 changes: 73 additions & 0 deletions frontend/src/dark_mode.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
const DARK: &str = "dark";
const LIGHT: &str = "light";
const DARK_MODE_KEY: &str = "dark-mode";

const BODY_INVERT_KEY: &str = "body-invert";
const INVERT: &str = "invert";
const NO_INVERT: &str = "no-invert";

pub fn init_dark_mode() {
// fetch dark mode setting with media query, override with local storage
let local_storage = web_sys::window().unwrap().local_storage().unwrap().unwrap();
let dark_mode = match local_storage.get_item(DARK_MODE_KEY).unwrap().as_deref() {
Some(DARK) => true,
Some(LIGHT) => false,
_ => {
web_sys::window()
.unwrap()
.match_media("(prefers-color-scheme: dark)")
.unwrap()
.map(|l| l.matches())
== Some(true)
}
};

let body_invert = matches!(local_storage.get_item(BODY_INVERT_KEY).unwrap().as_deref(), Some(INVERT));

let body = web_sys::window()
.unwrap()
.document()
.unwrap()
.body()
.unwrap();
body.class_list()
.add_1(if dark_mode { DARK } else { LIGHT })
.unwrap();
body.class_list()
.add_1(if body_invert { INVERT } else { NO_INVERT })
.unwrap();
}

pub fn toggle_dark_mode() {
let body = web_sys::window()
.unwrap()
.document()
.unwrap()
.body()
.unwrap();
let dark_mode = body.class_list().contains(DARK);
let new_mode = if dark_mode { LIGHT } else { DARK };

body.class_list().remove_2(DARK, LIGHT).unwrap();
body.class_list().add_1(new_mode).unwrap();

let local_storage = web_sys::window().unwrap().local_storage().unwrap().unwrap();
local_storage.set_item(DARK_MODE_KEY, new_mode).unwrap()
}

pub fn toggle_body_invert() {
let body = web_sys::window()
.unwrap()
.document()
.unwrap()
.body()
.unwrap();
let body_invert = body.class_list().contains(INVERT);
let new_mode = if body_invert { NO_INVERT } else { INVERT };

body.class_list().remove_2(NO_INVERT, INVERT).unwrap();
body.class_list().add_1(new_mode).unwrap();

let local_storage = web_sys::window().unwrap().local_storage().unwrap().unwrap();
local_storage.set_item(BODY_INVERT_KEY, new_mode).unwrap()
}
1 change: 1 addition & 0 deletions frontend/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use overview::Overview;

mod api;
mod dark_mode;
mod formatted;
mod list;
mod message_header;
Expand Down
11 changes: 8 additions & 3 deletions frontend/src/message_header.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::types::MailMessage;
use yew::{function_component, html, html_nested, Html, Properties};
use crate::{dark_mode::toggle_body_invert, types::MailMessage};
use yew::{function_component, html, html_nested, Callback, Html, Properties};

#[derive(Properties, Eq, PartialEq)]
pub struct MessageHeaderProps {
Expand Down Expand Up @@ -68,7 +68,7 @@ pub fn view(props: &MessageHeaderProps) -> Html {
</tr>
</tbody>
</table>
<div class="attachments">
<div class="actions">
{message.attachments.iter().map(|a| {
html! {
<a
Expand All @@ -81,6 +81,11 @@ pub fn view(props: &MessageHeaderProps) -> Html {
</a>
}
}).collect::<Html>()}
<button class="invert-body" onclick={Callback::from(|_| {
toggle_body_invert();
})}>
{"Invert body"}
</button>
</div>
</>
}
Expand Down
20 changes: 15 additions & 5 deletions frontend/src/overview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use wasm_bindgen_futures::spawn_local;
use yew::prelude::*;

use crate::api::fetch_messages_metadata;
use crate::dark_mode::{init_dark_mode, toggle_dark_mode};
use crate::list::MessageList;
use crate::types::{Action, MailMessageMetadata};
use crate::view::ViewMessage;
Expand Down Expand Up @@ -58,6 +59,10 @@ impl Component for Overview {
}
});

spawn_local(async {
init_dark_mode();
});

Self {
messages: vec![],
tab: Tab::Formatted,
Expand Down Expand Up @@ -128,11 +133,16 @@ impl Component for Overview {
<>
<header>
<h1>{"Mail"}<span>{"Crab"}</span></h1>
if !self.messages.is_empty() {
<button onclick={link.callback(|_| Msg::RemoveAll)}>
{"Remove all"}<span>{"("}{self.messages.len()}{")"}</span>
</button>
}
<div>
if !self.messages.is_empty() {
<button onclick={link.callback(|_| Msg::RemoveAll)}>
{"Remove all"}<span>{"("}{self.messages.len()}{")"}</span>
</button>
}
<button class="dark-mode" title="Toggle dark mode" onclick={Callback::from(|_| {
toggle_dark_mode();
})} />
</div>
</header>
if self.messages.is_empty() {
<div class="empty">
Expand Down
Loading