From 948202ab726ca063d86650d4df155eb9f64a079f Mon Sep 17 00:00:00 2001 From: Mike Dilger Date: Fri, 18 Aug 2023 13:13:09 +1200 Subject: [PATCH] Settings: defaults from storage defaults; load() from storage individual fields --- src/settings.rs | 291 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 208 insertions(+), 83 deletions(-) diff --git a/src/settings.rs b/src/settings.rs index d5219828..845174c6 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -1,8 +1,38 @@ -use crate::ui::{Theme, ThemeVariant}; +use crate::error::Error; +use crate::globals::GLOBALS; +use crate::storage::Storage; +use crate::ui::Theme; use nostr_types::{EventKind, PublicKey}; +use paste::paste; use serde::{Deserialize, Serialize}; use speedy::{Readable, Writable}; +macro_rules! load_setting { + ($field:ident) => { + paste! { + GLOBALS.storage.[]() + } + }; +} + +macro_rules! default_setting { + ($field:ident) => { + paste! { + Storage::[]() + } + }; +} + +macro_rules! save_setting { + ($field:ident, $slf:ident, $txn:ident) => { + paste! { + GLOBALS.storage.[](&$slf.$field, Some(&mut $txn))?; + } + }; +} + +/// Settings are stored in GLOBALS.storage individually. Usually we don't need them together +/// as an object. But the UI uses this to cache changes before committing them. #[derive(Clone, Debug, Serialize, Deserialize, Readable, Writable, PartialEq)] pub struct Settings { // ID settings @@ -88,92 +118,187 @@ pub struct Settings { impl Default for Settings { fn default() -> Settings { Settings { - // ID settings - public_key: None, - log_n: 18, - - // Network settings - offline: false, - load_avatars: true, - load_media: true, - check_nip05: true, - automatically_fetch_metadata: true, - - // Relay settings - num_relays_per_person: 2, - max_relays: 50, - - // Feed settings - feed_chunk: 60 * 60 * 12, // 12 hours - replies_chunk: 60 * 60 * 24 * 7, // 1 week - person_feed_chunk: 60 * 60 * 24 * 30, // 1 month - overlap: 300, // 5 minutes - - // Event Selection - reposts: true, - show_long_form: false, - show_mentions: true, - direct_messages: true, - future_allowance_secs: 60 * 15, // 15 minutes - - // Event Content Settings - reactions: true, - enable_zap_receipts: true, - show_media: true, - - // Posting settings - pow: 0, - set_client_tag: false, - set_user_agent: false, - delegatee_tag: String::new(), - - // UI settings - max_fps: 12, - recompute_feed_periodically: true, - feed_recompute_interval_ms: 8000, - theme: Theme { - variant: ThemeVariant::Default, - dark_mode: false, - follow_os_dark_mode: false, - }, - override_dpi: None, - highlight_unread_events: true, - posting_area_at_top: true, - status_bar: false, - image_resize_algorithm: "CatmullRom".to_owned(), - - // Staletime settings - relay_list_becomes_stale_hours: 8, - metadata_becomes_stale_hours: 8, - nip05_becomes_stale_if_valid_hours: 8, - nip05_becomes_stale_if_invalid_minutes: 30, // 30 minutes - avatar_becomes_stale_hours: 8, - media_becomes_stale_hours: 8, - - // Websocket settings - max_websocket_message_size_kb: 1024, // 1 MB - max_websocket_frame_size_kb: 1024, // 1 MB - websocket_accept_unmasked_frames: false, - websocket_connect_timeout_sec: 15, - websocket_ping_frequency_sec: 55, - - // HTTP settings - fetcher_metadata_looptime_ms: 3000, - fetcher_looptime_ms: 1800, - fetcher_connect_timeout_sec: 15, - fetcher_timeout_sec: 30, - fetcher_max_requests_per_host: 3, - fetcher_host_exclusion_on_low_error_secs: 30, - fetcher_host_exclusion_on_med_error_secs: 60, - fetcher_host_exclusion_on_high_error_secs: 600, - nip11_lines_to_output_on_error: 10, - - // Database settings - prune_period_days: 30, + public_key: default_setting!(public_key), + log_n: default_setting!(log_n), + offline: default_setting!(offline), + load_avatars: default_setting!(load_avatars), + load_media: default_setting!(load_media), + check_nip05: default_setting!(check_nip05), + automatically_fetch_metadata: default_setting!(automatically_fetch_metadata), + num_relays_per_person: default_setting!(num_relays_per_person), + max_relays: default_setting!(max_relays), + feed_chunk: default_setting!(feed_chunk), + replies_chunk: default_setting!(replies_chunk), + person_feed_chunk: default_setting!(person_feed_chunk), + overlap: default_setting!(overlap), + reposts: default_setting!(reposts), + show_long_form: default_setting!(show_long_form), + show_mentions: default_setting!(show_mentions), + direct_messages: default_setting!(direct_messages), + future_allowance_secs: default_setting!(future_allowance_secs), + reactions: default_setting!(reactions), + enable_zap_receipts: default_setting!(enable_zap_receipts), + show_media: default_setting!(show_media), + pow: default_setting!(pow), + set_client_tag: default_setting!(set_client_tag), + set_user_agent: default_setting!(set_user_agent), + delegatee_tag: default_setting!(delegatee_tag), + max_fps: default_setting!(max_fps), + recompute_feed_periodically: default_setting!(recompute_feed_periodically), + feed_recompute_interval_ms: default_setting!(feed_recompute_interval_ms), + theme: default_setting!(theme), + override_dpi: default_setting!(override_dpi), + highlight_unread_events: default_setting!(highlight_unread_events), + posting_area_at_top: default_setting!(posting_area_at_top), + status_bar: default_setting!(status_bar), + image_resize_algorithm: default_setting!(image_resize_algorithm), + relay_list_becomes_stale_hours: default_setting!(relay_list_becomes_stale_hours), + metadata_becomes_stale_hours: default_setting!(metadata_becomes_stale_hours), + nip05_becomes_stale_if_valid_hours: default_setting!(nip05_becomes_stale_if_valid_hours), + nip05_becomes_stale_if_invalid_minutes: default_setting!(nip05_becomes_stale_if_invalid_minutes), + avatar_becomes_stale_hours: default_setting!(avatar_becomes_stale_hours), + media_becomes_stale_hours: default_setting!(media_becomes_stale_hours), + max_websocket_message_size_kb: default_setting!(max_websocket_message_size_kb), + max_websocket_frame_size_kb: default_setting!(max_websocket_frame_size_kb), + websocket_accept_unmasked_frames: default_setting!(websocket_accept_unmasked_frames), + websocket_connect_timeout_sec: default_setting!(websocket_connect_timeout_sec), + websocket_ping_frequency_sec: default_setting!(websocket_ping_frequency_sec), + fetcher_metadata_looptime_ms: default_setting!(fetcher_metadata_looptime_ms), + fetcher_looptime_ms: default_setting!(fetcher_looptime_ms), + fetcher_connect_timeout_sec: default_setting!(fetcher_connect_timeout_sec), + fetcher_timeout_sec: default_setting!(fetcher_timeout_sec), + fetcher_max_requests_per_host: default_setting!(fetcher_max_requests_per_host), + fetcher_host_exclusion_on_low_error_secs: default_setting!(fetcher_host_exclusion_on_low_error_secs), + fetcher_host_exclusion_on_med_error_secs: default_setting!(fetcher_host_exclusion_on_med_error_secs), + fetcher_host_exclusion_on_high_error_secs: default_setting!(fetcher_host_exclusion_on_high_error_secs), + nip11_lines_to_output_on_error: default_setting!(nip11_lines_to_output_on_error), + prune_period_days: default_setting!(prune_period_days), } } } +impl Settings { + pub fn load() -> Settings { + Settings { + public_key: load_setting!(public_key), + log_n: load_setting!(log_n), + offline: load_setting!(offline), + load_avatars: load_setting!(load_avatars), + load_media: load_setting!(load_media), + check_nip05: load_setting!(check_nip05), + automatically_fetch_metadata: load_setting!(automatically_fetch_metadata), + num_relays_per_person: load_setting!(num_relays_per_person), + max_relays: load_setting!(max_relays), + feed_chunk: load_setting!(feed_chunk), + replies_chunk: load_setting!(replies_chunk), + person_feed_chunk: load_setting!(person_feed_chunk), + overlap: load_setting!(overlap), + reposts: load_setting!(reposts), + show_long_form: load_setting!(show_long_form), + show_mentions: load_setting!(show_mentions), + direct_messages: load_setting!(direct_messages), + future_allowance_secs: load_setting!(future_allowance_secs), + reactions: load_setting!(reactions), + enable_zap_receipts: load_setting!(enable_zap_receipts), + show_media: load_setting!(show_media), + pow: load_setting!(pow), + set_client_tag: load_setting!(set_client_tag), + set_user_agent: load_setting!(set_user_agent), + delegatee_tag: load_setting!(delegatee_tag), + max_fps: load_setting!(max_fps), + recompute_feed_periodically: load_setting!(recompute_feed_periodically), + feed_recompute_interval_ms: load_setting!(feed_recompute_interval_ms), + theme: load_setting!(theme), + override_dpi: load_setting!(override_dpi), + highlight_unread_events: load_setting!(highlight_unread_events), + posting_area_at_top: load_setting!(posting_area_at_top), + status_bar: load_setting!(status_bar), + image_resize_algorithm: load_setting!(image_resize_algorithm), + relay_list_becomes_stale_hours: load_setting!(relay_list_becomes_stale_hours), + metadata_becomes_stale_hours: load_setting!(metadata_becomes_stale_hours), + nip05_becomes_stale_if_valid_hours: load_setting!(nip05_becomes_stale_if_valid_hours), + nip05_becomes_stale_if_invalid_minutes: load_setting!(nip05_becomes_stale_if_invalid_minutes), + avatar_becomes_stale_hours: load_setting!(avatar_becomes_stale_hours), + media_becomes_stale_hours: load_setting!(media_becomes_stale_hours), + max_websocket_message_size_kb: load_setting!(max_websocket_message_size_kb), + max_websocket_frame_size_kb: load_setting!(max_websocket_frame_size_kb), + websocket_accept_unmasked_frames: load_setting!(websocket_accept_unmasked_frames), + websocket_connect_timeout_sec: load_setting!(websocket_connect_timeout_sec), + websocket_ping_frequency_sec: load_setting!(websocket_ping_frequency_sec), + fetcher_metadata_looptime_ms: load_setting!(fetcher_metadata_looptime_ms), + fetcher_looptime_ms: load_setting!(fetcher_looptime_ms), + fetcher_connect_timeout_sec: load_setting!(fetcher_connect_timeout_sec), + fetcher_timeout_sec: load_setting!(fetcher_timeout_sec), + fetcher_max_requests_per_host: load_setting!(fetcher_max_requests_per_host), + fetcher_host_exclusion_on_low_error_secs: load_setting!(fetcher_host_exclusion_on_low_error_secs), + fetcher_host_exclusion_on_med_error_secs: load_setting!(fetcher_host_exclusion_on_med_error_secs), + fetcher_host_exclusion_on_high_error_secs: load_setting!(fetcher_host_exclusion_on_high_error_secs), + nip11_lines_to_output_on_error: load_setting!(nip11_lines_to_output_on_error), + prune_period_days: load_setting!(prune_period_days), + } + } + + pub fn save(&self) -> Result<(), Error> { + let mut txn = GLOBALS.storage.get_write_txn()?; + save_setting!(public_key, self, txn); + save_setting!(log_n, self, txn); + save_setting!(offline, self, txn); + save_setting!(load_avatars, self, txn); + save_setting!(load_media, self, txn); + save_setting!(check_nip05, self, txn); + save_setting!(automatically_fetch_metadata, self, txn); + save_setting!(num_relays_per_person, self, txn); + save_setting!(max_relays, self, txn); + save_setting!(feed_chunk, self, txn); + save_setting!(replies_chunk, self, txn); + save_setting!(person_feed_chunk, self, txn); + save_setting!(overlap, self, txn); + save_setting!(reposts, self, txn); + save_setting!(show_long_form, self, txn); + save_setting!(show_mentions, self, txn); + save_setting!(direct_messages, self, txn); + save_setting!(future_allowance_secs, self, txn); + save_setting!(reactions, self, txn); + save_setting!(enable_zap_receipts, self, txn); + save_setting!(show_media, self, txn); + save_setting!(pow, self, txn); + save_setting!(set_client_tag, self, txn); + save_setting!(set_user_agent, self, txn); + save_setting!(delegatee_tag, self, txn); + save_setting!(max_fps, self, txn); + save_setting!(recompute_feed_periodically, self, txn); + save_setting!(feed_recompute_interval_ms, self, txn); + save_setting!(theme, self, txn); + save_setting!(override_dpi, self, txn); + save_setting!(highlight_unread_events, self, txn); + save_setting!(posting_area_at_top, self, txn); + save_setting!(status_bar, self, txn); + save_setting!(image_resize_algorithm, self, txn); + save_setting!(relay_list_becomes_stale_hours, self, txn); + save_setting!(metadata_becomes_stale_hours, self, txn); + save_setting!(nip05_becomes_stale_if_valid_hours, self, txn); + save_setting!(nip05_becomes_stale_if_invalid_minutes, self, txn); + save_setting!(avatar_becomes_stale_hours, self, txn); + save_setting!(media_becomes_stale_hours, self, txn); + save_setting!(max_websocket_message_size_kb, self, txn); + save_setting!(max_websocket_frame_size_kb, self, txn); + save_setting!(websocket_accept_unmasked_frames, self, txn); + save_setting!(websocket_connect_timeout_sec, self, txn); + save_setting!(websocket_ping_frequency_sec, self, txn); + save_setting!(fetcher_metadata_looptime_ms, self, txn); + save_setting!(fetcher_looptime_ms, self, txn); + save_setting!(fetcher_connect_timeout_sec, self, txn); + save_setting!(fetcher_timeout_sec, self, txn); + save_setting!(fetcher_max_requests_per_host, self, txn); + save_setting!(fetcher_host_exclusion_on_low_error_secs, self, txn); + save_setting!(fetcher_host_exclusion_on_med_error_secs, self, txn); + save_setting!(fetcher_host_exclusion_on_high_error_secs, self, txn); + save_setting!(nip11_lines_to_output_on_error, self, txn); + save_setting!(prune_period_days, self, txn); + Ok(()) + } +} + impl Settings { pub fn enabled_event_kinds(&self) -> Vec { EventKind::iter()