Skip to content
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
11 changes: 10 additions & 1 deletion src/gui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ pub struct LauncherApp {
pub note_save_on_close: bool,
pub note_always_overwrite: bool,
pub note_images_as_links: bool,
pub note_show_details: bool,
pub note_external_open: NoteExternalOpen,
pub note_font_size: f32,
pub note_more_limit: usize,
Expand Down Expand Up @@ -966,6 +967,7 @@ impl LauncherApp {
note_save_on_close: Option<bool>,
note_always_overwrite: Option<bool>,
note_images_as_links: Option<bool>,
note_show_details: Option<bool>,
note_more_limit: Option<usize>,
show_dashboard_diagnostics: Option<bool>,
) {
Expand Down Expand Up @@ -1075,6 +1077,9 @@ impl LauncherApp {
if let Some(v) = note_images_as_links {
self.note_images_as_links = v;
}
if let Some(v) = note_show_details {
self.note_show_details = v;
}
if let Some(v) = note_more_limit {
self.note_more_limit = v;
}
Expand Down Expand Up @@ -1460,6 +1465,7 @@ impl LauncherApp {
note_save_on_close: settings.note_save_on_close,
note_always_overwrite: settings.note_always_overwrite,
note_images_as_links: settings.note_images_as_links,
note_show_details: settings.note_show_details,
note_external_open,
note_font_size: 16.0,
note_more_limit: settings.note_more_limit,
Expand Down Expand Up @@ -4991,7 +4997,10 @@ impl LauncherApp {
},
);
}
self.note_panels.push(NotePanel::from_note(note));
self.note_panels.push(NotePanel::from_note_with_details(
note,
self.note_show_details,
));
// Allow keyboard shortcuts like Esc/Cmd+W to immediately close the panel
self.update_panel_stack();
}
Expand Down
88 changes: 82 additions & 6 deletions src/gui/note_panel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,42 @@ impl NotePanel {
}
}

fn set_show_metadata(&mut self, app: &mut LauncherApp, show_metadata: bool) {
if self.show_metadata == show_metadata {
return;
}
self.show_metadata = show_metadata;
self.persist_details_visibility(app);
}

fn persist_details_visibility(&self, app: &mut LauncherApp) {
match crate::settings::Settings::load(&app.settings_path) {
Ok(mut settings) => {
if settings.note_show_details == self.show_metadata {
return;
}
settings.note_show_details = self.show_metadata;
if let Err(err) = settings.save(&app.settings_path) {
app.set_error(format!(
"Failed to save note detail visibility setting: {err}"
));
} else {
app.note_show_details = self.show_metadata;
}
}
Err(err) => {
app.set_error(format!(
"Failed to load settings for note detail visibility: {err}"
));
}
}
}

pub fn from_note(note: Note) -> Self {
Self::from_note_with_details(note, true)
}

pub fn from_note_with_details(note: Note, show_details: bool) -> Self {
let mut panel = Self {
open: true,
note,
Expand All @@ -229,7 +264,7 @@ impl NotePanel {
image_cache: HashMap::new(),
overwrite_prompt: false,
show_open_with_menu: false,
show_metadata: true,
show_metadata: show_details,
tags_expanded: false,
links_expanded: false,
backlink_tab: BacklinkTab::LinkedTodos,
Expand Down Expand Up @@ -448,7 +483,7 @@ impl NotePanel {
}
}
if ui.button(self.details_toggle_label()).clicked() {
self.show_metadata = !self.show_metadata;
self.set_show_metadata(app, !self.show_metadata);
let was_focused = self
.last_textedit_id
.map(|id| ui.ctx().memory(|m| m.has_focus(id)))
Expand Down Expand Up @@ -2160,13 +2195,17 @@ mod tests {
}

#[test]
fn toggle_button_label_reflects_state() {
let mut panel = NotePanel::from_note(empty_note("body"));
assert_eq!(panel.details_toggle_label(), "Hide Details");
panel.show_metadata = false;
fn constructor_with_hidden_details_shows_show_details_label() {
let panel = NotePanel::from_note_with_details(empty_note("body"), false);
assert_eq!(panel.details_toggle_label(), "Show Details");
}

#[test]
fn constructor_with_visible_details_shows_hide_details_label() {
let panel = NotePanel::from_note_with_details(empty_note("body"), true);
assert_eq!(panel.details_toggle_label(), "Hide Details");
}

#[test]
fn toggle_preserves_tab_and_pagination_state() {
let mut panel = NotePanel::from_note(empty_note("body"));
Expand All @@ -2180,6 +2219,43 @@ mod tests {
assert_eq!(panel.backlink_page, 2);
}

#[test]
fn toggle_persists_note_detail_visibility_once_per_change() {
use std::{fs, thread, time::Duration};
use tempfile::tempdir;

let ctx = egui::Context::default();
let mut app = new_app(&ctx);
let dir = tempdir().expect("tempdir");
let settings_path = dir.path().join("settings.json");

let mut settings = Settings::default();
settings.note_show_details = false;
settings
.save(settings_path.to_str().expect("settings path"))
.expect("write settings");
app.settings_path = settings_path.to_string_lossy().to_string();

let mut panel = NotePanel::from_note_with_details(empty_note("body"), false);
panel.set_show_metadata(&mut app, true);

let persisted = Settings::load(app.settings_path.as_str()).expect("load settings");
assert!(persisted.note_show_details);

let first_modified = fs::metadata(&settings_path)
.expect("metadata")
.modified()
.expect("modified time");
thread::sleep(Duration::from_millis(20));
panel.set_show_metadata(&mut app, true);
let second_modified = fs::metadata(&settings_path)
.expect("metadata")
.modified()
.expect("modified time");

assert_eq!(first_modified, second_modified);
}

#[test]
fn derived_metadata_is_reused_without_save() {
let ctx = egui::Context::default();
Expand Down
1 change: 1 addition & 0 deletions src/plugin_editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ impl PluginEditor {
Some(s.note_save_on_close),
Some(s.note_always_overwrite),
Some(s.note_images_as_links),
Some(s.note_show_details),
Some(s.note_more_limit),
Some(s.show_dashboard_diagnostics),
);
Expand Down
28 changes: 28 additions & 0 deletions src/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,9 @@ pub struct Settings {
/// textures directly in the preview.
#[serde(default)]
pub note_images_as_links: bool,
/// Whether note metadata/details sections are visible by default.
#[serde(default = "default_note_show_details")]
pub note_show_details: bool,
/// Number of tags or links shown before an expandable "... (more)" control
/// appears in the note panel.
#[serde(default = "default_note_more_limit")]
Expand Down Expand Up @@ -559,6 +562,10 @@ fn default_note_save_on_close() -> bool {
false
}

fn default_note_show_details() -> bool {
false
}

fn default_note_more_limit() -> usize {
5
}
Expand Down Expand Up @@ -604,6 +611,7 @@ impl Default for Settings {
note_save_on_close: default_note_save_on_close(),
note_always_overwrite: false,
note_images_as_links: false,
note_show_details: default_note_show_details(),
note_more_limit: default_note_more_limit(),
enable_toasts: true,
toast_duration: default_toast_duration(),
Expand Down Expand Up @@ -755,4 +763,24 @@ mod tests {
let restored: Settings = serde_json::from_str(&json).expect("deserialize settings");
assert_eq!(restored.query_results_layout, settings.query_results_layout);
}

#[test]
fn note_show_details_defaults_to_hidden_when_missing() {
let parsed: Settings = serde_json::from_str("{}").expect("settings should deserialize");
assert!(!parsed.note_show_details);
}

#[test]
fn note_show_details_round_trip_serialization() {
let mut settings = Settings::default();
settings.note_show_details = true;
let json = serde_json::to_string(&settings).expect("serialize settings");
let restored: Settings = serde_json::from_str(&json).expect("deserialize settings");
assert!(restored.note_show_details);

settings.note_show_details = false;
let json = serde_json::to_string(&settings).expect("serialize settings");
let restored: Settings = serde_json::from_str(&json).expect("deserialize settings");
assert!(!restored.note_show_details);
}
}
15 changes: 14 additions & 1 deletion src/settings_editor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ pub struct SettingsEditor {
note_save_on_close: bool,
note_always_overwrite: bool,
note_images_as_links: bool,
note_show_details: bool,
note_more_limit: usize,
query_scale: f32,
list_scale: f32,
Expand Down Expand Up @@ -98,7 +99,7 @@ impl SettingsEditor {
}
}

pub fn new(settings: &Settings) -> Self {
pub fn from_settings(settings: &Settings) -> Self {
let hotkey = settings.hotkey.clone().unwrap_or_default();
let hotkey_valid = parse_hotkey(&hotkey).is_some();
let default_hotkey = Settings::default().hotkey.unwrap_or_else(|| "F2".into());
Expand Down Expand Up @@ -162,6 +163,7 @@ impl SettingsEditor {
note_save_on_close: settings.note_save_on_close,
note_always_overwrite: settings.note_always_overwrite,
note_images_as_links: settings.note_images_as_links,
note_show_details: settings.note_show_details,
note_more_limit: settings.note_more_limit,
query_scale: settings.query_scale.unwrap_or(1.0),
list_scale: settings.list_scale.unwrap_or(1.0),
Expand Down Expand Up @@ -232,6 +234,10 @@ impl SettingsEditor {
s
}

pub fn new(settings: &Settings) -> Self {
Self::from_settings(settings)
}

pub fn new_with_plugins(settings: &Settings) -> Self {
let mut s = Self::new(settings);
s.sync_from_plugin_settings();
Expand Down Expand Up @@ -338,6 +344,7 @@ impl SettingsEditor {
note_save_on_close: self.note_save_on_close,
note_always_overwrite: self.note_always_overwrite,
note_images_as_links: self.note_images_as_links,
note_show_details: self.note_show_details,
note_more_limit: self.note_more_limit,
query_scale: Some(self.query_scale),
list_scale: Some(self.list_scale),
Expand Down Expand Up @@ -759,6 +766,10 @@ impl SettingsEditor {
&mut self.note_images_as_links,
"Display images as links",
);
ui.checkbox(
&mut self.note_show_details,
"Show note details by default",
);
ui.horizontal(|ui| {
ui.label("Tag/link preview limit");
ui.add(
Expand Down Expand Up @@ -901,6 +912,7 @@ impl SettingsEditor {
Some(new_settings.note_save_on_close),
Some(new_settings.note_always_overwrite),
Some(new_settings.note_images_as_links),
Some(new_settings.note_show_details),
Some(new_settings.note_more_limit),
Some(new_settings.show_dashboard_diagnostics),
);
Expand All @@ -919,6 +931,7 @@ impl SettingsEditor {
app.history_limit = new_settings.history_limit;
app.clipboard_limit = new_settings.clipboard_limit;
app.page_jump = new_settings.page_jump;
app.note_show_details = new_settings.note_show_details;
app.preserve_command = new_settings.preserve_command;
app.clear_query_after_run = new_settings.clear_query_after_run;
app.require_confirm_destructive = new_settings.require_confirm_destructive;
Expand Down
1 change: 1 addition & 0 deletions tests/hide_after_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ fn run_action(action: &str) -> bool {
None,
None,
None,
None,
);
flag.store(true, Ordering::SeqCst);
let a = app.results[0].clone();
Expand Down