commit b1a5dd6cab0cc298eb9454ef5ea01e857ef53181
parent d12e5b363cb2328650ef1c1a0bd4f513ff57a0e0
Author: William Casarin <jb55@jb55.com>
Date: Thu, 31 Jul 2025 16:03:13 -0700
add NotedeckOptions and feature flags, add notebook feature
This switches from bools to flags in our Args struct. We also add
notebook as an optional feature flag (--notebook) since its not ready.
Diffstat:
11 files changed, 100 insertions(+), 46 deletions(-)
diff --git a/Cargo.lock b/Cargo.lock
@@ -3483,6 +3483,7 @@ dependencies = [
"base32",
"bech32",
"bincode",
+ "bitflags 2.9.1",
"blurhash",
"dirs",
"eframe",
diff --git a/crates/notedeck/Cargo.toml b/crates/notedeck/Cargo.toml
@@ -47,6 +47,7 @@ fluent-langneg = { workspace = true }
unic-langid = { workspace = true }
once_cell = { workspace = true }
md5 = { workspace = true }
+bitflags = { workspace = true }
regex = "1"
[dev-dependencies]
diff --git a/crates/notedeck/src/app.rs b/crates/notedeck/src/app.rs
@@ -4,6 +4,7 @@ use crate::persist::{AppSizeHandler, SettingsHandler};
use crate::wallet::GlobalWallet;
use crate::zaps::Zaps;
use crate::JobPool;
+use crate::NotedeckOptions;
use crate::{
frame_history::FrameHistory, AccountStorage, Accounts, AppContext, Args, DataPath,
DataPathType, Directory, Images, NoteAction, NoteCache, RelayDebugView, UnknownIds,
@@ -109,7 +110,7 @@ impl eframe::App for Notedeck {
});
self.app_size.try_save_app_size(ctx);
- if self.args.relay_debug {
+ if self.args.options.contains(NotedeckOptions::RelayDebug) {
if self.pool.debug.is_none() {
self.pool.use_debug();
}
@@ -170,7 +171,7 @@ impl Notedeck {
let config = Config::new().set_ingester_threads(2).set_mapsize(map_size);
- let keystore = if parsed_args.use_keystore {
+ let keystore = if parsed_args.options.contains(NotedeckOptions::UseKeystore) {
let keys_path = path.path(DataPathType::Keys);
let selected_key_path = path.path(DataPathType::SelectedKey);
Some(AccountStorage::new(
@@ -276,6 +277,10 @@ impl Notedeck {
}
}
+ pub fn options(&self) -> NotedeckOptions {
+ self.args.options
+ }
+
pub fn app<A: App + 'static>(mut self, app: A) -> Self {
self.set_app(app);
self
diff --git a/crates/notedeck/src/args.rs b/crates/notedeck/src/args.rs
@@ -1,23 +1,15 @@
use std::collections::BTreeSet;
+use crate::NotedeckOptions;
use enostr::{Keypair, Pubkey, SecretKey};
use tracing::error;
use unic_langid::{LanguageIdentifier, LanguageIdentifierError};
pub struct Args {
pub relays: Vec<String>,
- pub is_mobile: Option<bool>,
pub locale: Option<LanguageIdentifier>,
- pub show_note_client: bool,
pub keys: Vec<Keypair>,
- pub light: bool,
- pub debug: bool,
- pub relay_debug: bool,
-
- /// Enable when running tests so we don't panic on app startup
- pub tests: bool,
-
- pub use_keystore: bool,
+ pub options: NotedeckOptions,
pub dbpath: Option<String>,
pub datapath: Option<String>,
}
@@ -28,14 +20,8 @@ impl Args {
let mut unrecognized_args = BTreeSet::new();
let mut res = Args {
relays: vec![],
- is_mobile: None,
keys: vec![],
- light: false,
- show_note_client: false,
- debug: false,
- relay_debug: false,
- tests: false,
- use_keystore: true,
+ options: NotedeckOptions::default(),
dbpath: None,
datapath: None,
locale: None,
@@ -47,9 +33,9 @@ impl Args {
let arg = &args[i];
if arg == "--mobile" {
- res.is_mobile = Some(true);
+ res.options.set(NotedeckOptions::Mobile, true);
} else if arg == "--light" {
- res.light = true;
+ res.options.set(NotedeckOptions::LightTheme, true);
} else if arg == "--locale" {
i += 1;
let Some(locale) = args.get(i) else {
@@ -68,11 +54,11 @@ impl Args {
}
}
} else if arg == "--dark" {
- res.light = false;
+ res.options.set(NotedeckOptions::LightTheme, false);
} else if arg == "--debug" {
- res.debug = true;
+ res.options.set(NotedeckOptions::Debug, true);
} else if arg == "--testrunner" {
- res.tests = true;
+ res.options.set(NotedeckOptions::Tests, true);
} else if arg == "--pub" || arg == "--npub" {
i += 1;
let pubstr = if let Some(next_arg) = args.get(i) {
@@ -135,11 +121,13 @@ impl Args {
};
res.relays.push(relay.clone());
} else if arg == "--no-keystore" {
- res.use_keystore = false;
+ res.options.set(NotedeckOptions::UseKeystore, true);
} else if arg == "--relay-debug" {
- res.relay_debug = true;
- } else if arg == "--show-note-client" {
- res.show_note_client = true;
+ res.options.set(NotedeckOptions::RelayDebug, true);
+ } else if arg == "--show-client" {
+ res.options.set(NotedeckOptions::ShowClient, true);
+ } else if arg == "--notebook" {
+ res.options.set(NotedeckOptions::FeatureNotebook, true);
} else {
unrecognized_args.insert(arg.clone());
}
diff --git a/crates/notedeck/src/lib.rs b/crates/notedeck/src/lib.rs
@@ -18,6 +18,7 @@ mod muted;
pub mod name;
pub mod note;
mod notecache;
+mod options;
mod persist;
pub mod platform;
pub mod profile;
@@ -68,6 +69,7 @@ pub use note::{
RootIdError, RootNoteId, RootNoteIdBuf, ScrollInfo, ZapAction,
};
pub use notecache::{CachedNote, NoteCache};
+pub use options::NotedeckOptions;
pub use persist::*;
pub use profile::get_profile_url;
pub use relay_debug::RelayDebugView;
diff --git a/crates/notedeck/src/options.rs b/crates/notedeck/src/options.rs
@@ -0,0 +1,39 @@
+use bitflags::bitflags;
+
+bitflags! {
+ #[repr(transparent)]
+ #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+ pub struct NotedeckOptions: u64 {
+ // ===== Settings ======
+ /// Are we on light theme?
+ const LightTheme = 1 << 0;
+
+ /// Debug controls, fps stats
+ const Debug = 1 << 1;
+
+ /// Show relay debug window?
+ const RelayDebug = 1 << 2;
+
+ /// Are we running as tests?
+ const Tests = 1 << 3;
+
+ /// Use keystore?
+ const UseKeystore = 1 << 4;
+
+ /// Show client on notes?
+ const ShowClient = 1 << 5;
+
+ /// Simulate is_compiled_as_mobile ?
+ const Mobile = 1 << 6;
+
+ // ===== Feature Flags ======
+ /// Is notebook enabled?
+ const FeatureNotebook = 1 << 32;
+ }
+}
+
+impl Default for NotedeckOptions {
+ fn default() -> Self {
+ NotedeckOptions::UseKeystore
+ }
+}
diff --git a/crates/notedeck_chrome/src/android.rs b/crates/notedeck_chrome/src/android.rs
@@ -97,7 +97,13 @@ pub async fn android_main(app: AndroidApp) {
chrome.add_app(NotedeckApp::Columns(Box::new(columns)));
chrome.add_app(NotedeckApp::Dave(Box::new(dave)));
- chrome.add_app(NotedeckApp::Notebook(Box::new(notebook)));
+
+ if notedeck
+ .options()
+ .contains(NotedeckOptions::FeaturesNotebook)
+ {
+ chrome.add_app(NotedeckApp::Notebook(Box::default()));
+ }
// test dav
chrome.set_active(0);
diff --git a/crates/notedeck_chrome/src/chrome.rs b/crates/notedeck_chrome/src/chrome.rs
@@ -6,7 +6,8 @@ use egui::{vec2, Button, Color32, Label, Layout, Rect, RichText, ThemePreference
use egui_extras::{Size, StripBuilder};
use nostrdb::{ProfileRecord, Transaction};
use notedeck::{
- tr, App, AppAction, AppContext, Localization, NotedeckTextStyle, UserAccount, WalletType,
+ tr, App, AppAction, AppContext, Localization, NotedeckOptions, NotedeckTextStyle, UserAccount,
+ WalletType,
};
use notedeck_columns::{
column::SelectionResult, timeline::kind::ListKind, timeline::TimelineKind, Damus,
@@ -612,10 +613,10 @@ fn accounts_button(ui: &mut egui::Ui) -> egui::Response {
fn notebook_button(ui: &mut egui::Ui) -> egui::Response {
expanding_button(
- "columns-button",
+ "notebook-button",
40.0,
- app_images::new_message_image(),
- app_images::new_message_image(),
+ app_images::algo_image(),
+ app_images::algo_image(),
ui,
)
}
@@ -898,7 +899,7 @@ fn bottomup_sidebar(
.add(wallet_button())
.on_hover_cursor(egui::CursorIcon::PointingHand);
- if ctx.args.debug {
+ if ctx.args.options.contains(NotedeckOptions::Debug) {
ui.weak(format!("{}", ctx.frame_history.fps() as i32));
ui.weak(format!(
"{:10.1}",
diff --git a/crates/notedeck_chrome/src/notedeck.rs b/crates/notedeck_chrome/src/notedeck.rs
@@ -10,14 +10,13 @@ static GLOBAL: AccountingAllocator<std::alloc::System> =
AccountingAllocator::new(std::alloc::System);
use notedeck::enostr::Error;
-use notedeck::{DataPath, DataPathType, Notedeck};
+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 notedeck_notebook::Notebook;
use tracing::error;
use tracing_appender::non_blocking::WorkerGuard;
use tracing_subscriber::EnvFilter;
@@ -98,7 +97,6 @@ async fn main() {
let mut chrome = Chrome::new();
let columns = Damus::new(&mut notedeck.app_context(), &args);
let dave = Dave::new(cc.wgpu_render_state.as_ref());
- let notebook = Notebook::default();
setup_chrome(
ctx,
@@ -121,7 +119,13 @@ async fn main() {
chrome.add_app(NotedeckApp::Columns(Box::new(columns)));
chrome.add_app(NotedeckApp::Dave(Box::new(dave)));
- chrome.add_app(NotedeckApp::Notebook(Box::new(notebook)));
+
+ if notedeck
+ .options()
+ .contains(NotedeckOptions::FeatureNotebook)
+ {
+ chrome.add_app(NotedeckApp::Notebook(Box::default()));
+ }
chrome.set_active(0);
diff --git a/crates/notedeck_chrome/src/setup.rs b/crates/notedeck_chrome/src/setup.rs
@@ -2,7 +2,7 @@ use crate::{fonts, theme};
use eframe::NativeOptions;
use egui::{FontId, ThemePreference};
-use notedeck::{AppSizeHandler, DataPath, NotedeckTextStyle};
+use notedeck::{AppSizeHandler, DataPath, NotedeckOptions, NotedeckTextStyle};
use notedeck_ui::app_images;
use tracing::info;
@@ -13,16 +13,20 @@ pub fn setup_chrome(
note_body_font_size: f32,
zoom_factor: f32,
) {
- let is_mobile = args
- .is_mobile
- .unwrap_or(notedeck::ui::is_compiled_as_mobile());
+ 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.tests && cfg!(debug_assertions) && !args.debug {
+ 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!(
+ "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!("---------------------------------");
diff --git a/crates/notedeck_columns/src/app.rs b/crates/notedeck_columns/src/app.rs
@@ -19,7 +19,7 @@ use enostr::{ClientMessage, PoolRelay, Pubkey, RelayEvent, RelayMessage, RelayPo
use nostrdb::Transaction;
use notedeck::{
tr, ui::is_narrow, Accounts, AppAction, AppContext, DataPath, DataPathType, FilterState,
- Images, JobsCache, Localization, SettingsHandler, UnknownIds,
+ Images, JobsCache, Localization, NotedeckOptions, SettingsHandler, UnknownIds,
};
use notedeck_ui::{
media::{MediaViewer, MediaViewerFlags, MediaViewerState},
@@ -442,7 +442,10 @@ impl Damus {
let mut options = AppOptions::default();
let tmp_columns = !parsed_args.columns.is_empty();
options.set(AppOptions::TmpColumns, tmp_columns);
- options.set(AppOptions::Debug, app_context.args.debug);
+ options.set(
+ AppOptions::Debug,
+ app_context.args.options.contains(NotedeckOptions::Debug),
+ );
options.set(
AppOptions::SinceOptimize,
parsed_args.is_flag_set(ColumnsFlag::SinceOptimize),