From 39a1b98924e8dd59b284ba90951b24c8bc1a3cdf Mon Sep 17 00:00:00 2001 From: Ethanfel Date: Thu, 26 Feb 2026 18:11:11 +0100 Subject: [PATCH] Fix history snapshot corruption, missing dir crash, stale batch delete - Deep-copy node data on restore to prevent edits from mutating stored history snapshots - Guard glob calls against non-existent current_dir - Read current selection at delete time instead of using stale render-time capture Co-Authored-By: Claude Opus 4.6 --- main.py | 6 ++++++ tab_timeline_ng.py | 7 ++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/main.py b/main.py index f99f00e..bb73de7 100644 --- a/main.py +++ b/main.py @@ -224,6 +224,9 @@ def index(): 'text-caption q-pa-md') def _render_pane_file_selector(pane_state: AppState): + if not pane_state.current_dir.exists(): + ui.label('Directory not found.').classes('text-warning') + return json_files = sorted(pane_state.current_dir.glob('*.json')) json_files = [f for f in json_files if f.name not in ( '.editor_config.json', '.editor_snippets.json')] @@ -422,6 +425,9 @@ def render_sidebar(state: AppState, dual_pane: dict): with ui.card().classes('w-full q-pa-md q-mb-md'): @ui.refreshable def render_file_list(): + if not state.current_dir.exists(): + ui.label('Directory not found.').classes('text-warning') + return json_files = sorted(state.current_dir.glob('*.json')) json_files = [f for f in json_files if f.name not in ('.editor_config.json', '.editor_snippets.json')] diff --git a/tab_timeline_ng.py b/tab_timeline_ng.py index 7f49b09..6c0c004 100644 --- a/tab_timeline_ng.py +++ b/tab_timeline_ng.py @@ -130,10 +130,11 @@ def _render_batch_delete(htree, data, file_path, state, refresh_fn): ).classes('text-warning q-mt-md') def do_batch_delete(): - _delete_nodes(htree, data, file_path, valid) + current_valid = state.timeline_selected_nodes & set(htree.nodes.keys()) + _delete_nodes(htree, data, file_path, current_valid) state.timeline_selected_nodes = set() ui.notify( - f'Deleted {count} node{"s" if count != 1 else ""}!', + f'Deleted {len(current_valid)} node{"s" if len(current_valid) != 1 else ""}!', type='positive') refresh_fn() @@ -288,7 +289,7 @@ def _render_graphviz(dot_source: str): def _restore_node(data, node, htree, file_path, state: AppState): """Restore a history node as the current version.""" - node_data = node['data'] + node_data = copy.deepcopy(node['data']) if KEY_BATCH_DATA not in node_data and KEY_BATCH_DATA in data: del data[KEY_BATCH_DATA] data.update(node_data)