commit dac786e60fe48887c3ca543c36ac245316b42aeb
parent 09eeb57bd918e34e9539d6b823e318f8be43892c
Author: William Casarin <jb55@jb55.com>
Date: Thu, 31 Jul 2025 17:07:25 -0700
chrome: remove duplication in app setup
Also move debug warning to chrome so that headless
notedeck apps don't hit that.
Diffstat:
12 files changed, 449 insertions(+), 467 deletions(-)
diff --git a/crates/notedeck/src/app.rs b/crates/notedeck/src/app.rs
@@ -3,6 +3,7 @@ use crate::i18n::Localization;
use crate::persist::{AppSizeHandler, SettingsHandler};
use crate::wallet::GlobalWallet;
use crate::zaps::Zaps;
+use crate::Error;
use crate::JobPool;
use crate::NotedeckOptions;
use crate::{
@@ -252,9 +253,6 @@ impl Notedeck {
}
}
- // Initialize global i18n context
- //crate::i18n::init_global_i18n(i18n.clone());
-
Self {
ndb,
img_cache,
@@ -277,10 +275,44 @@ impl Notedeck {
}
}
+ /// Setup egui context
+ pub fn setup(&self, ctx: &egui::Context) {
+ // Initialize global i18n context
+ //crate::i18n::init_global_i18n(i18n.clone());
+ crate::setup::setup_egui_context(
+ ctx,
+ self.args.options,
+ self.theme(),
+ self.note_body_font_size(),
+ self.zoom_factor(),
+ );
+ }
+
+ /// ensure we recognized all the arguments
+ pub fn check_args(&self, other_app_args: &BTreeSet<String>) -> Result<(), Error> {
+ let completely_unrecognized: Vec<String> = self
+ .unrecognized_args()
+ .intersection(other_app_args)
+ .cloned()
+ .collect();
+ if !completely_unrecognized.is_empty() {
+ let err = format!("Unrecognized arguments: {:?}", completely_unrecognized);
+ tracing::error!("{}", &err);
+ return Err(Error::Generic(err));
+ }
+
+ Ok(())
+ }
+
+ #[inline]
pub fn options(&self) -> NotedeckOptions {
self.args.options
}
+ pub fn has_option(&self, option: NotedeckOptions) -> bool {
+ self.options().contains(option)
+ }
+
pub fn app<A: App + 'static>(mut self, app: A) -> Self {
self.set_app(app);
self
diff --git a/crates/notedeck/src/fonts.rs b/crates/notedeck/src/fonts.rs
@@ -1,4 +1,9 @@
use crate::{ui, NotedeckTextStyle};
+use egui::FontData;
+use egui::FontDefinitions;
+use egui::FontTweak;
+use std::collections::BTreeMap;
+use std::sync::Arc;
pub enum NamedFontFamily {
Medium,
@@ -58,3 +63,148 @@ pub fn get_font_size(ctx: &egui::Context, text_style: &NotedeckTextStyle) -> f32
desktop_font_size(text_style)
}
}
+
+// Use gossip's approach to font loading. This includes japanese fonts
+// for rending stuff from japanese users.
+pub fn setup_fonts(ctx: &egui::Context) {
+ let mut font_data: BTreeMap<String, Arc<FontData>> = BTreeMap::new();
+ let mut families = BTreeMap::new();
+
+ font_data.insert(
+ "Onest".to_owned(),
+ Arc::new(FontData::from_static(include_bytes!(
+ "../../../assets/fonts/onest/OnestRegular1602-hint.ttf"
+ ))),
+ );
+
+ font_data.insert(
+ "OnestMedium".to_owned(),
+ Arc::new(FontData::from_static(include_bytes!(
+ "../../../assets/fonts/onest/OnestMedium1602-hint.ttf"
+ ))),
+ );
+
+ font_data.insert(
+ "DejaVuSans".to_owned(),
+ Arc::new(FontData::from_static(include_bytes!(
+ "../../../assets/fonts/DejaVuSansSansEmoji.ttf"
+ ))),
+ );
+
+ font_data.insert(
+ "OnestBold".to_owned(),
+ Arc::new(FontData::from_static(include_bytes!(
+ "../../../assets/fonts/onest/OnestBold1602-hint.ttf"
+ ))),
+ );
+
+ /*
+ font_data.insert(
+ "DejaVuSansBold".to_owned(),
+ FontData::from_static(include_bytes!(
+ "../assets/fonts/DejaVuSans-Bold-SansEmoji.ttf"
+ )),
+ );
+
+ font_data.insert(
+ "DejaVuSans".to_owned(),
+ FontData::from_static(include_bytes!("../assets/fonts/DejaVuSansSansEmoji.ttf")),
+ );
+ font_data.insert(
+ "DejaVuSansBold".to_owned(),
+ FontData::from_static(include_bytes!(
+ "../assets/fonts/DejaVuSans-Bold-SansEmoji.ttf"
+ )),
+ );
+ */
+
+ font_data.insert(
+ "Inconsolata".to_owned(),
+ Arc::new(
+ FontData::from_static(include_bytes!(
+ "../../../assets/fonts/Inconsolata-Regular.ttf"
+ ))
+ .tweak(FontTweak {
+ scale: 1.22, // This font is smaller than DejaVuSans
+ y_offset_factor: -0.18, // and too low
+ y_offset: 0.0,
+ baseline_offset_factor: 0.0,
+ }),
+ ),
+ );
+
+ font_data.insert(
+ "NotoSansCJK".to_owned(),
+ Arc::new(FontData::from_static(include_bytes!(
+ "../../../assets/fonts/NotoSansCJK-Regular.ttc"
+ ))),
+ );
+
+ font_data.insert(
+ "NotoSansThai".to_owned(),
+ Arc::new(FontData::from_static(include_bytes!(
+ "../../../assets/fonts/NotoSansThai-Regular.ttf"
+ ))),
+ );
+
+ // Some good looking emojis. Use as first priority:
+ font_data.insert(
+ "NotoEmoji".to_owned(),
+ Arc::new(
+ FontData::from_static(include_bytes!(
+ "../../../assets/fonts/NotoEmoji-Regular.ttf"
+ ))
+ .tweak(FontTweak {
+ scale: 1.1, // make them a touch larger
+ y_offset_factor: 0.0,
+ y_offset: 0.0,
+ baseline_offset_factor: 0.0,
+ }),
+ ),
+ );
+
+ let base_fonts = vec![
+ "DejaVuSans".to_owned(),
+ "NotoEmoji".to_owned(),
+ "NotoSansCJK".to_owned(),
+ "NotoSansThai".to_owned(),
+ ];
+
+ let mut proportional = vec!["Onest".to_owned()];
+ proportional.extend(base_fonts.clone());
+
+ let mut medium = vec!["OnestMedium".to_owned()];
+ medium.extend(base_fonts.clone());
+
+ let mut mono = vec!["Inconsolata".to_owned()];
+ mono.extend(base_fonts.clone());
+
+ let mut bold = vec!["OnestBold".to_owned()];
+ bold.extend(base_fonts.clone());
+
+ let emoji = vec!["NotoEmoji".to_owned()];
+
+ families.insert(egui::FontFamily::Proportional, proportional);
+ families.insert(egui::FontFamily::Monospace, mono);
+ families.insert(
+ egui::FontFamily::Name(NamedFontFamily::Medium.as_str().into()),
+ medium,
+ );
+ families.insert(
+ egui::FontFamily::Name(NamedFontFamily::Bold.as_str().into()),
+ bold,
+ );
+ families.insert(
+ egui::FontFamily::Name(NamedFontFamily::Emoji.as_str().into()),
+ emoji,
+ );
+
+ tracing::debug!("fonts: {:?}", families);
+
+ let defs = FontDefinitions {
+ font_data,
+ families,
+ };
+
+ ctx.set_fonts(defs);
+}
diff --git a/crates/notedeck/src/lib.rs b/crates/notedeck/src/lib.rs
@@ -25,6 +25,7 @@ pub mod profile;
pub mod relay_debug;
pub mod relayspec;
mod result;
+mod setup;
pub mod storage;
mod style;
pub mod theme;
diff --git a/crates/notedeck/src/setup.rs b/crates/notedeck/src/setup.rs
@@ -0,0 +1,47 @@
+use crate::fonts;
+use crate::theme;
+use crate::NotedeckOptions;
+use crate::NotedeckTextStyle;
+use egui::FontId;
+use egui::ThemePreference;
+
+pub fn setup_egui_context(
+ ctx: &egui::Context,
+ options: NotedeckOptions,
+ theme: ThemePreference,
+ note_body_font_size: f32,
+ zoom_factor: f32,
+) {
+ let is_mobile = options.contains(NotedeckOptions::Mobile) || crate::ui::is_compiled_as_mobile();
+
+ let is_oled = crate::ui::is_oled();
+
+ ctx.options_mut(|o| {
+ tracing::info!("Loaded theme {:?} from disk", theme);
+ o.theme_preference = theme;
+ });
+ ctx.set_visuals_of(egui::Theme::Dark, theme::dark_mode(is_oled));
+ ctx.set_visuals_of(egui::Theme::Light, theme::light_mode());
+
+ fonts::setup_fonts(ctx);
+
+ if crate::ui::is_compiled_as_mobile() {
+ ctx.set_pixels_per_point(ctx.pixels_per_point() + 0.2);
+ }
+
+ egui_extras::install_image_loaders(ctx);
+
+ ctx.options_mut(|o| {
+ o.input_options.max_click_duration = 0.4;
+ });
+ ctx.all_styles_mut(|style| crate::theme::add_custom_style(is_mobile, style));
+
+ ctx.set_zoom_factor(zoom_factor);
+
+ let mut style = (*ctx.style()).clone();
+ style.text_styles.insert(
+ NotedeckTextStyle::NoteBody.text_style(),
+ FontId::proportional(note_body_font_size),
+ );
+ ctx.set_style(style);
+}
diff --git a/crates/notedeck/src/theme.rs b/crates/notedeck/src/theme.rs
@@ -1,7 +1,35 @@
-use egui::{
- style::{Selection, WidgetVisuals, Widgets},
- Color32, CornerRadius, Stroke, Visuals,
-};
+use crate::{fonts, NotedeckTextStyle};
+use egui::style::Interaction;
+use egui::style::Selection;
+use egui::style::WidgetVisuals;
+use egui::style::Widgets;
+use egui::Color32;
+use egui::CornerRadius;
+use egui::FontId;
+use egui::Stroke;
+use egui::Style;
+use egui::Visuals;
+use strum::IntoEnumIterator;
+
+pub const PURPLE: Color32 = Color32::from_rgb(0xCC, 0x43, 0xC5);
+const PURPLE_ALT: Color32 = Color32::from_rgb(0x82, 0x56, 0xDD);
+//pub const DARK_BG: Color32 = egui::Color32::from_rgb(40, 44, 52);
+pub const GRAY_SECONDARY: Color32 = Color32::from_rgb(0x8A, 0x8A, 0x8A);
+const BLACK: Color32 = Color32::from_rgb(0x00, 0x00, 0x00);
+const RED_700: Color32 = Color32::from_rgb(0xC7, 0x37, 0x5A);
+const ORANGE_700: Color32 = Color32::from_rgb(0xF6, 0xB1, 0x4A);
+
+// BACKGROUNDS
+const SEMI_DARKER_BG: Color32 = Color32::from_rgb(0x39, 0x39, 0x39);
+const DARKER_BG: Color32 = Color32::from_rgb(0x1F, 0x1F, 0x1F);
+const DARK_BG: Color32 = Color32::from_rgb(0x2C, 0x2C, 0x2C);
+const DARK_ISH_BG: Color32 = Color32::from_rgb(0x25, 0x25, 0x25);
+const SEMI_DARK_BG: Color32 = Color32::from_rgb(0x44, 0x44, 0x44);
+
+const LIGHTER_GRAY: Color32 = Color32::from_rgb(0xf8, 0xf8, 0xf8);
+const LIGHT_GRAY: Color32 = Color32::from_rgb(0xc8, 0xc8, 0xc8); // 78%
+const DARKER_GRAY: Color32 = Color32::from_rgb(0xa5, 0xa5, 0xa5); // 65%
+const EVEN_DARKER_GRAY: Color32 = Color32::from_rgb(0x89, 0x89, 0x89); // 54%
pub struct ColorTheme {
// VISUALS
@@ -86,3 +114,131 @@ pub fn create_themed_visuals(theme: ColorTheme, default: Visuals) -> Visuals {
..default
}
}
+
+pub fn desktop_dark_color_theme() -> ColorTheme {
+ ColorTheme {
+ // VISUALS
+ panel_fill: DARKER_BG,
+ extreme_bg_color: DARK_ISH_BG,
+ text_color: Color32::WHITE,
+ err_fg_color: RED_700,
+ warn_fg_color: ORANGE_700,
+ hyperlink_color: PURPLE,
+ selection_color: PURPLE_ALT,
+
+ // WINDOW
+ window_fill: DARK_ISH_BG,
+ window_stroke_color: DARK_BG,
+
+ // NONINTERACTIVE WIDGET
+ noninteractive_bg_fill: DARK_ISH_BG,
+ noninteractive_weak_bg_fill: DARK_BG,
+ noninteractive_bg_stroke_color: SEMI_DARKER_BG,
+ noninteractive_fg_stroke_color: GRAY_SECONDARY,
+
+ // INACTIVE WIDGET
+ inactive_bg_stroke_color: SEMI_DARKER_BG,
+ inactive_bg_fill: Color32::from_rgb(0x25, 0x25, 0x25),
+ inactive_weak_bg_fill: SEMI_DARK_BG,
+ }
+}
+
+pub fn mobile_dark_color_theme() -> ColorTheme {
+ ColorTheme {
+ panel_fill: Color32::BLACK,
+ noninteractive_weak_bg_fill: Color32::from_rgb(0x1F, 0x1F, 0x1F),
+ ..desktop_dark_color_theme()
+ }
+}
+
+pub fn light_color_theme() -> ColorTheme {
+ ColorTheme {
+ // VISUALS
+ panel_fill: Color32::WHITE,
+ extreme_bg_color: LIGHTER_GRAY,
+ text_color: BLACK,
+ err_fg_color: RED_700,
+ warn_fg_color: ORANGE_700,
+ hyperlink_color: PURPLE,
+ selection_color: PURPLE_ALT,
+
+ // WINDOW
+ window_fill: Color32::WHITE,
+ window_stroke_color: DARKER_GRAY,
+
+ // NONINTERACTIVE WIDGET
+ noninteractive_bg_fill: Color32::WHITE,
+ noninteractive_weak_bg_fill: LIGHTER_GRAY,
+ noninteractive_bg_stroke_color: LIGHT_GRAY,
+ noninteractive_fg_stroke_color: GRAY_SECONDARY,
+
+ // INACTIVE WIDGET
+ inactive_bg_stroke_color: EVEN_DARKER_GRAY,
+ inactive_bg_fill: LIGHTER_GRAY,
+ inactive_weak_bg_fill: LIGHTER_GRAY,
+ }
+}
+
+/// Create custom text sizes for any FontSizes
+pub fn add_custom_style(is_mobile: bool, style: &mut Style) {
+ let font_size = if is_mobile {
+ fonts::mobile_font_size
+ } else {
+ fonts::desktop_font_size
+ };
+
+ style.text_styles = NotedeckTextStyle::iter()
+ .map(|text_style| {
+ (
+ text_style.text_style(),
+ FontId::new(font_size(&text_style), text_style.font_family()),
+ )
+ })
+ .collect();
+
+ style.interaction = Interaction {
+ tooltip_delay: 0.1,
+ show_tooltips_only_when_still: false,
+ ..Interaction::default()
+ };
+
+ // debug: show callstack for the current widget on hover if all
+ // modifier keys are pressed down.
+ /*
+ #[cfg(feature = "debug-widget-callstack")]
+ {
+ #[cfg(not(debug_assertions))]
+ compile_error!(
+ "The `debug-widget-callstack` feature requires a debug build, \
+ release builds are unsupported."
+ );
+ style.debug.debug_on_hover_with_all_modifiers = true;
+ }
+
+ // debug: show an overlay on all interactive widgets
+ #[cfg(feature = "debug-interactive-widgets")]
+ {
+ #[cfg(not(debug_assertions))]
+ compile_error!(
+ "The `debug-interactive-widgets` feature requires a debug build, \
+ release builds are unsupported."
+ );
+ style.debug.show_interactive_widgets = true;
+ }
+ */
+}
+
+pub fn light_mode() -> Visuals {
+ create_themed_visuals(crate::theme::light_color_theme(), Visuals::light())
+}
+
+pub fn dark_mode(is_oled: bool) -> Visuals {
+ create_themed_visuals(
+ if is_oled {
+ mobile_dark_color_theme()
+ } else {
+ desktop_dark_color_theme()
+ },
+ Visuals::dark(),
+ )
+}
diff --git a/crates/notedeck_chrome/src/android.rs b/crates/notedeck_chrome/src/android.rs
@@ -7,7 +7,7 @@ use notedeck_columns::Damus;
use notedeck_dave::Dave;
use notedeck_notebook::Notebook;
-use crate::{app::NotedeckApp, chrome::Chrome, setup::setup_chrome};
+use crate::{app::NotedeckApp, chrome::Chrome, setup::setup_egui_context};
use notedeck::Notedeck;
use tracing::error;
@@ -70,44 +70,9 @@ pub async fn android_main(app: AndroidApp) {
Box::new(move |cc| {
let ctx = &cc.egui_ctx;
let mut notedeck = Notedeck::new(ctx, path, &app_args);
- setup_chrome(
- ctx,
- ¬edeck.args(),
- notedeck.theme(),
- notedeck.note_body_font_size(),
- notedeck.zoom_factor(),
- );
-
- let context = &mut notedeck.app_context();
- let dave = Dave::new(cc.wgpu_render_state.as_ref());
- let columns = Damus::new(context, &app_args);
- let notebook = Notebook::new();
- let mut chrome = Chrome::new();
-
- // ensure we recognized all the arguments
- let completely_unrecognized: Vec<String> = notedeck
- .unrecognized_args()
- .intersection(columns.unrecognized_args())
- .cloned()
- .collect();
- if !completely_unrecognized.is_empty() {
- error!("Unrecognized arguments: {:?}", completely_unrecognized);
- return Err(Error::Empty.into());
- }
-
- chrome.add_app(NotedeckApp::Columns(Box::new(columns)));
- chrome.add_app(NotedeckApp::Dave(Box::new(dave)));
-
- if notedeck
- .options()
- .contains(NotedeckOptions::FeaturesNotebook)
- {
- chrome.add_app(NotedeckApp::Notebook(Box::default()));
- }
-
- // test dav
- chrome.set_active(0);
+ notedeck.setup()?;
+ let chrome = Chrome::new_with_apps(&mut notedeck);
notedeck.set_app(chrome);
Ok(Box::new(notedeck))
diff --git a/crates/notedeck_chrome/src/chrome.rs b/crates/notedeck_chrome/src/chrome.rs
@@ -2,12 +2,14 @@
//#[cfg(target_arch = "wasm32")]
//use wasm_bindgen::prelude::*;
use crate::app::NotedeckApp;
+use eframe::CreationContext;
use egui::{vec2, Button, Color32, Label, Layout, Rect, RichText, ThemePreference, Widget};
use egui_extras::{Size, StripBuilder};
use nostrdb::{ProfileRecord, Transaction};
+use notedeck::Error;
use notedeck::{
- tr, App, AppAction, AppContext, Localization, NotedeckOptions, NotedeckTextStyle, UserAccount,
- WalletType,
+ tr, App, AppAction, AppContext, Localization, Notedeck, NotedeckOptions, NotedeckTextStyle,
+ UserAccount, WalletType,
};
use notedeck_columns::{
column::SelectionResult, timeline::kind::ListKind, timeline::TimelineKind, Damus,
@@ -168,9 +170,49 @@ impl ChromePanelAction {
}
}
+/// Some people have been running notedeck in debug, let's catch that!
+fn stop_debug_mode(options: NotedeckOptions) {
+ if !options.contains(NotedeckOptions::Tests)
+ && cfg!(debug_assertions)
+ && !options.contains(NotedeckOptions::Debug)
+ {
+ println!("--- WELCOME TO DAMUS NOTEDECK! ---");
+ println!(
+ "It looks like are running notedeck in debug mode, unless you are a developer, this is not likely what you want."
+ );
+ println!("If you are a developer, run `cargo run -- --debug` to skip this message.");
+ println!("For everyone else, try again with `cargo run --release`. Enjoy!");
+ println!("---------------------------------");
+ panic!();
+ }
+}
+
impl Chrome {
- pub fn new() -> Self {
- Chrome::default()
+ /// Create a new chrome with the default app setup
+ pub fn new_with_apps(
+ cc: &CreationContext,
+ app_args: &[String],
+ notedeck: &mut Notedeck,
+ ) -> Result<Self, Error> {
+ stop_debug_mode(notedeck.options());
+
+ let context = &mut notedeck.app_context();
+ let dave = Dave::new(cc.wgpu_render_state.as_ref());
+ let columns = Damus::new(context, app_args);
+ let mut chrome = Chrome::default();
+
+ notedeck.check_args(columns.unrecognized_args())?;
+
+ chrome.add_app(NotedeckApp::Columns(Box::new(columns)));
+ chrome.add_app(NotedeckApp::Dave(Box::new(dave)));
+
+ if notedeck.has_option(NotedeckOptions::FeatureNotebook) {
+ chrome.add_app(NotedeckApp::Notebook(Box::default()));
+ }
+
+ chrome.set_active(0);
+
+ Ok(chrome)
}
pub fn toggle(&mut self) {
diff --git a/crates/notedeck_chrome/src/fonts.rs b/crates/notedeck_chrome/src/fonts.rs
@@ -1,151 +0,0 @@
-use egui::{FontData, FontDefinitions, FontTweak};
-use std::collections::BTreeMap;
-use std::sync::Arc;
-use tracing::debug;
-
-use notedeck::fonts::NamedFontFamily;
-
-// Use gossip's approach to font loading. This includes japanese fonts
-// for rending stuff from japanese users.
-pub fn setup_fonts(ctx: &egui::Context) {
- let mut font_data: BTreeMap<String, Arc<FontData>> = BTreeMap::new();
- let mut families = BTreeMap::new();
-
- font_data.insert(
- "Onest".to_owned(),
- Arc::new(FontData::from_static(include_bytes!(
- "../../../assets/fonts/onest/OnestRegular1602-hint.ttf"
- ))),
- );
-
- font_data.insert(
- "OnestMedium".to_owned(),
- Arc::new(FontData::from_static(include_bytes!(
- "../../../assets/fonts/onest/OnestMedium1602-hint.ttf"
- ))),
- );
-
- font_data.insert(
- "DejaVuSans".to_owned(),
- Arc::new(FontData::from_static(include_bytes!(
- "../../../assets/fonts/DejaVuSansSansEmoji.ttf"
- ))),
- );
-
- font_data.insert(
- "OnestBold".to_owned(),
- Arc::new(FontData::from_static(include_bytes!(
- "../../../assets/fonts/onest/OnestBold1602-hint.ttf"
- ))),
- );
-
- /*
- font_data.insert(
- "DejaVuSansBold".to_owned(),
- FontData::from_static(include_bytes!(
- "../assets/fonts/DejaVuSans-Bold-SansEmoji.ttf"
- )),
- );
-
- font_data.insert(
- "DejaVuSans".to_owned(),
- FontData::from_static(include_bytes!("../assets/fonts/DejaVuSansSansEmoji.ttf")),
- );
- font_data.insert(
- "DejaVuSansBold".to_owned(),
- FontData::from_static(include_bytes!(
- "../assets/fonts/DejaVuSans-Bold-SansEmoji.ttf"
- )),
- );
- */
-
- font_data.insert(
- "Inconsolata".to_owned(),
- Arc::new(
- FontData::from_static(include_bytes!(
- "../../../assets/fonts/Inconsolata-Regular.ttf"
- ))
- .tweak(FontTweak {
- scale: 1.22, // This font is smaller than DejaVuSans
- y_offset_factor: -0.18, // and too low
- y_offset: 0.0,
- baseline_offset_factor: 0.0,
- }),
- ),
- );
-
- font_data.insert(
- "NotoSansCJK".to_owned(),
- Arc::new(FontData::from_static(include_bytes!(
- "../../../assets/fonts/NotoSansCJK-Regular.ttc"
- ))),
- );
-
- font_data.insert(
- "NotoSansThai".to_owned(),
- Arc::new(FontData::from_static(include_bytes!(
- "../../../assets/fonts/NotoSansThai-Regular.ttf"
- ))),
- );
-
- // Some good looking emojis. Use as first priority:
- font_data.insert(
- "NotoEmoji".to_owned(),
- Arc::new(
- FontData::from_static(include_bytes!(
- "../../../assets/fonts/NotoEmoji-Regular.ttf"
- ))
- .tweak(FontTweak {
- scale: 1.1, // make them a touch larger
- y_offset_factor: 0.0,
- y_offset: 0.0,
- baseline_offset_factor: 0.0,
- }),
- ),
- );
-
- let base_fonts = vec![
- "DejaVuSans".to_owned(),
- "NotoEmoji".to_owned(),
- "NotoSansCJK".to_owned(),
- "NotoSansThai".to_owned(),
- ];
-
- let mut proportional = vec!["Onest".to_owned()];
- proportional.extend(base_fonts.clone());
-
- let mut medium = vec!["OnestMedium".to_owned()];
- medium.extend(base_fonts.clone());
-
- let mut mono = vec!["Inconsolata".to_owned()];
- mono.extend(base_fonts.clone());
-
- let mut bold = vec!["OnestBold".to_owned()];
- bold.extend(base_fonts.clone());
-
- let emoji = vec!["NotoEmoji".to_owned()];
-
- families.insert(egui::FontFamily::Proportional, proportional);
- families.insert(egui::FontFamily::Monospace, mono);
- families.insert(
- egui::FontFamily::Name(NamedFontFamily::Medium.as_str().into()),
- medium,
- );
- families.insert(
- egui::FontFamily::Name(NamedFontFamily::Bold.as_str().into()),
- bold,
- );
- families.insert(
- egui::FontFamily::Name(NamedFontFamily::Emoji.as_str().into()),
- emoji,
- );
-
- debug!("fonts: {:?}", families);
-
- let defs = FontDefinitions {
- font_data,
- families,
- };
-
- ctx.set_fonts(defs);
-}
diff --git a/crates/notedeck_chrome/src/lib.rs b/crates/notedeck_chrome/src/lib.rs
@@ -1,6 +1,4 @@
-pub mod fonts;
pub mod setup;
-pub mod theme;
#[cfg(target_os = "android")]
mod android;
diff --git a/crates/notedeck_chrome/src/notedeck.rs b/crates/notedeck_chrome/src/notedeck.rs
@@ -9,15 +9,8 @@ use re_memory::AccountingAllocator;
static GLOBAL: AccountingAllocator<std::alloc::System> =
AccountingAllocator::new(std::alloc::System);
-use notedeck::enostr::Error;
-use notedeck::{DataPath, DataPathType, Notedeck, NotedeckOptions};
-use notedeck_chrome::{
- setup::{generate_native_options, setup_chrome},
- Chrome, NotedeckApp,
-};
-use notedeck_columns::Damus;
-use notedeck_dave::Dave;
-use tracing::error;
+use notedeck::{DataPath, DataPathType, Notedeck};
+use notedeck_chrome::{setup::generate_native_options, Chrome};
use tracing_appender::non_blocking::WorkerGuard;
use tracing_subscriber::EnvFilter;
@@ -93,42 +86,8 @@ async fn main() {
let ctx = &cc.egui_ctx;
let mut notedeck = Notedeck::new(ctx, base_path, &args);
-
- let mut chrome = Chrome::new();
- let columns = Damus::new(&mut notedeck.app_context(), &args);
- let dave = Dave::new(cc.wgpu_render_state.as_ref());
-
- setup_chrome(
- ctx,
- notedeck.args(),
- notedeck.theme(),
- notedeck.note_body_font_size(),
- notedeck.zoom_factor(),
- );
-
- // ensure we recognized all the arguments
- let completely_unrecognized: Vec<String> = notedeck
- .unrecognized_args()
- .intersection(columns.unrecognized_args())
- .cloned()
- .collect();
- if !completely_unrecognized.is_empty() {
- error!("Unrecognized arguments: {:?}", completely_unrecognized);
- return Err(Error::Empty.into());
- }
-
- chrome.add_app(NotedeckApp::Columns(Box::new(columns)));
- chrome.add_app(NotedeckApp::Dave(Box::new(dave)));
-
- if notedeck
- .options()
- .contains(NotedeckOptions::FeatureNotebook)
- {
- chrome.add_app(NotedeckApp::Notebook(Box::default()));
- }
-
- chrome.set_active(0);
-
+ notedeck.setup(ctx);
+ let chrome = Chrome::new_with_apps(cc, &args, &mut notedeck)?;
notedeck.set_app(chrome);
Ok(Box::new(notedeck))
@@ -162,7 +121,8 @@ pub fn main() {
#[cfg(test)]
mod tests {
- use super::{Damus, Notedeck};
+ use super::Notedeck;
+ use notedeck_columns::Damus;
use std::path::{Path, PathBuf};
fn create_tmp_dir() -> PathBuf {
diff --git a/crates/notedeck_chrome/src/setup.rs b/crates/notedeck_chrome/src/setup.rs
@@ -1,75 +1,6 @@
-use crate::{fonts, theme};
-
use eframe::NativeOptions;
-use egui::{FontId, ThemePreference};
-use notedeck::{AppSizeHandler, DataPath, NotedeckOptions, NotedeckTextStyle};
+use notedeck::{AppSizeHandler, DataPath};
use notedeck_ui::app_images;
-use tracing::info;
-
-pub fn setup_chrome(
- ctx: &egui::Context,
- args: ¬edeck::Args,
- theme: ThemePreference,
- note_body_font_size: f32,
- zoom_factor: f32,
-) {
- let is_mobile =
- args.options.contains(NotedeckOptions::Mobile) || notedeck::ui::is_compiled_as_mobile();
-
- let is_oled = notedeck::ui::is_oled();
-
- // Some people have been running notedeck in debug, let's catch that!
- if !args.options.contains(NotedeckOptions::Tests)
- && cfg!(debug_assertions)
- && !args.options.contains(NotedeckOptions::Debug)
- {
- println!("--- WELCOME TO DAMUS NOTEDECK! ---");
- println!(
- "It looks like are running notedeck in debug mode, unless you are a developer, this is not likely what you want."
- );
- println!("If you are a developer, run `cargo run -- --debug` to skip this message.");
- println!("For everyone else, try again with `cargo run --release`. Enjoy!");
- println!("---------------------------------");
- panic!();
- }
-
- ctx.options_mut(|o| {
- info!("Loaded theme {:?} from disk", theme);
- o.theme_preference = theme;
- });
- ctx.set_visuals_of(egui::Theme::Dark, theme::dark_mode(is_oled));
- ctx.set_visuals_of(egui::Theme::Light, theme::light_mode());
-
- setup_cc(ctx, is_mobile);
-
- ctx.set_zoom_factor(zoom_factor);
-
- let mut style = (*ctx.style()).clone();
- style.text_styles.insert(
- NotedeckTextStyle::NoteBody.text_style(),
- FontId::proportional(note_body_font_size),
- );
- ctx.set_style(style);
-}
-
-pub fn setup_cc(ctx: &egui::Context, is_mobile: bool) {
- fonts::setup_fonts(ctx);
-
- if notedeck::ui::is_compiled_as_mobile() {
- ctx.set_pixels_per_point(ctx.pixels_per_point() + 0.2);
- }
- //ctx.set_pixels_per_point(1.0);
- //
- //
- //ctx.tessellation_options_mut(|to| to.feathering = false);
-
- egui_extras::install_image_loaders(ctx);
-
- ctx.options_mut(|o| {
- o.input_options.max_click_duration = 0.4;
- });
- ctx.all_styles_mut(|style| theme::add_custom_style(is_mobile, style));
-}
pub fn generate_native_options(paths: DataPath) -> NativeOptions {
let window_builder = Box::new(move |builder: egui::ViewportBuilder| {
diff --git a/crates/notedeck_chrome/src/theme.rs b/crates/notedeck_chrome/src/theme.rs
@@ -1,149 +0,0 @@
-use egui::{style::Interaction, Color32, FontId, Style, Visuals};
-use notedeck::{ColorTheme, NotedeckTextStyle};
-use strum::IntoEnumIterator;
-
-pub const PURPLE: Color32 = Color32::from_rgb(0xCC, 0x43, 0xC5);
-const PURPLE_ALT: Color32 = Color32::from_rgb(0x82, 0x56, 0xDD);
-//pub const DARK_BG: Color32 = egui::Color32::from_rgb(40, 44, 52);
-pub const GRAY_SECONDARY: Color32 = Color32::from_rgb(0x8A, 0x8A, 0x8A);
-const BLACK: Color32 = Color32::from_rgb(0x00, 0x00, 0x00);
-const RED_700: Color32 = Color32::from_rgb(0xC7, 0x37, 0x5A);
-const ORANGE_700: Color32 = Color32::from_rgb(0xF6, 0xB1, 0x4A);
-
-// BACKGROUNDS
-const SEMI_DARKER_BG: Color32 = Color32::from_rgb(0x39, 0x39, 0x39);
-const DARKER_BG: Color32 = Color32::from_rgb(0x1F, 0x1F, 0x1F);
-const DARK_BG: Color32 = Color32::from_rgb(0x2C, 0x2C, 0x2C);
-const DARK_ISH_BG: Color32 = Color32::from_rgb(0x25, 0x25, 0x25);
-const SEMI_DARK_BG: Color32 = Color32::from_rgb(0x44, 0x44, 0x44);
-
-const LIGHTER_GRAY: Color32 = Color32::from_rgb(0xf8, 0xf8, 0xf8);
-const LIGHT_GRAY: Color32 = Color32::from_rgb(0xc8, 0xc8, 0xc8); // 78%
-const DARKER_GRAY: Color32 = Color32::from_rgb(0xa5, 0xa5, 0xa5); // 65%
-const EVEN_DARKER_GRAY: Color32 = Color32::from_rgb(0x89, 0x89, 0x89); // 54%
-
-pub fn desktop_dark_color_theme() -> ColorTheme {
- ColorTheme {
- // VISUALS
- panel_fill: DARKER_BG,
- extreme_bg_color: DARK_ISH_BG,
- text_color: Color32::WHITE,
- err_fg_color: RED_700,
- warn_fg_color: ORANGE_700,
- hyperlink_color: PURPLE,
- selection_color: PURPLE_ALT,
-
- // WINDOW
- window_fill: DARK_ISH_BG,
- window_stroke_color: DARK_BG,
-
- // NONINTERACTIVE WIDGET
- noninteractive_bg_fill: DARK_ISH_BG,
- noninteractive_weak_bg_fill: DARK_BG,
- noninteractive_bg_stroke_color: SEMI_DARKER_BG,
- noninteractive_fg_stroke_color: GRAY_SECONDARY,
-
- // INACTIVE WIDGET
- inactive_bg_stroke_color: SEMI_DARKER_BG,
- inactive_bg_fill: Color32::from_rgb(0x25, 0x25, 0x25),
- inactive_weak_bg_fill: SEMI_DARK_BG,
- }
-}
-
-pub fn mobile_dark_color_theme() -> ColorTheme {
- ColorTheme {
- panel_fill: Color32::BLACK,
- noninteractive_weak_bg_fill: Color32::from_rgb(0x1F, 0x1F, 0x1F),
- ..desktop_dark_color_theme()
- }
-}
-
-pub fn light_color_theme() -> ColorTheme {
- ColorTheme {
- // VISUALS
- panel_fill: Color32::WHITE,
- extreme_bg_color: LIGHTER_GRAY,
- text_color: BLACK,
- err_fg_color: RED_700,
- warn_fg_color: ORANGE_700,
- hyperlink_color: PURPLE,
- selection_color: PURPLE_ALT,
-
- // WINDOW
- window_fill: Color32::WHITE,
- window_stroke_color: DARKER_GRAY,
-
- // NONINTERACTIVE WIDGET
- noninteractive_bg_fill: Color32::WHITE,
- noninteractive_weak_bg_fill: LIGHTER_GRAY,
- noninteractive_bg_stroke_color: LIGHT_GRAY,
- noninteractive_fg_stroke_color: GRAY_SECONDARY,
-
- // INACTIVE WIDGET
- inactive_bg_stroke_color: EVEN_DARKER_GRAY,
- inactive_bg_fill: LIGHTER_GRAY,
- inactive_weak_bg_fill: LIGHTER_GRAY,
- }
-}
-
-pub fn light_mode() -> Visuals {
- notedeck::theme::create_themed_visuals(light_color_theme(), Visuals::light())
-}
-
-pub fn dark_mode(is_oled: bool) -> Visuals {
- notedeck::theme::create_themed_visuals(
- if is_oled {
- mobile_dark_color_theme()
- } else {
- desktop_dark_color_theme()
- },
- Visuals::dark(),
- )
-}
-
-/// Create custom text sizes for any FontSizes
-pub fn add_custom_style(is_mobile: bool, style: &mut Style) {
- let font_size = if is_mobile {
- notedeck::fonts::mobile_font_size
- } else {
- notedeck::fonts::desktop_font_size
- };
-
- style.text_styles = NotedeckTextStyle::iter()
- .map(|text_style| {
- (
- text_style.text_style(),
- FontId::new(font_size(&text_style), text_style.font_family()),
- )
- })
- .collect();
-
- style.interaction = Interaction {
- tooltip_delay: 0.1,
- show_tooltips_only_when_still: false,
- ..Interaction::default()
- };
-
- // debug: show callstack for the current widget on hover if all
- // modifier keys are pressed down.
- #[cfg(feature = "debug-widget-callstack")]
- {
- #[cfg(not(debug_assertions))]
- compile_error!(
- "The `debug-widget-callstack` feature requires a debug build, \
- release builds are unsupported."
- );
- style.debug.debug_on_hover_with_all_modifiers = true;
- }
-
- // debug: show an overlay on all interactive widgets
- #[cfg(feature = "debug-interactive-widgets")]
- {
- #[cfg(not(debug_assertions))]
- compile_error!(
- "The `debug-interactive-widgets` feature requires a debug build, \
- release builds are unsupported."
- );
- style.debug.show_interactive_widgets = true;
- }
-}