Make note save status transient

This commit is contained in:
hz
2026-07-18 22:25:08 -05:00
parent d0bb271b14
commit 819a108451
3 changed files with 33 additions and 5 deletions
+2 -3
View File
@@ -10,6 +10,7 @@ const MAX_CONTENT_LENGTH := 50000
signal content_changed(content: String) signal content_changed(content: String)
signal state_changed(state: String) signal state_changed(state: String)
signal conflict_detected(server_content: String) signal conflict_detected(server_content: String)
signal save_succeeded
var api_url := DEFAULT_API_URL var api_url := DEFAULT_API_URL
var content := "" var content := ""
@@ -113,10 +114,7 @@ func resolve_conflict_use_synced() -> void:
func status_text() -> String: func status_text() -> String:
match state: match state:
"loading": return "Loading..." "loading": return "Loading..."
"dirty": return "Unsaved changes"
"saving": return "Saving..." "saving": return "Saving..."
"saved": return "Saved"
"offline": return "Saved locally - waiting for connection"
"conflict": return "Changes found on another device" "conflict": return "Changes found on another device"
_: return "" _: return ""
@@ -271,6 +269,7 @@ func _apply_remote_save(server: Dictionary) -> void:
if content == sent_content: if content == sent_content:
dirty = false dirty = false
_set_state("saved") _set_state("saved")
save_succeeded.emit()
else: else:
dirty = true dirty = true
_set_state("dirty") _set_state("dirty")
+22 -2
View File
@@ -9,6 +9,7 @@ var conflict_panel: PanelContainer
var applying_content := false var applying_content := false
var notes_service: Node var notes_service: Node
var theme_service: Node var theme_service: Node
var saved_status_timer: Timer
func _ready() -> void: func _ready() -> void:
@@ -28,6 +29,11 @@ func _ready() -> void:
count_label = Label.new() count_label = Label.new()
Brand.apply_font(count_label) Brand.apply_font(count_label)
metadata_row.add_child(count_label) metadata_row.add_child(count_label)
saved_status_timer = Timer.new()
saved_status_timer.one_shot = true
saved_status_timer.wait_time = 2.0
saved_status_timer.timeout.connect(_clear_saved_status)
add_child(saved_status_timer)
editor = TextEdit.new() editor = TextEdit.new()
editor.placeholder_text = "Write notes..." editor.placeholder_text = "Write notes..."
@@ -65,6 +71,7 @@ func _ready() -> void:
notes_service.content_changed.connect(_on_service_content_changed) notes_service.content_changed.connect(_on_service_content_changed)
notes_service.state_changed.connect(_on_service_state_changed) notes_service.state_changed.connect(_on_service_state_changed)
notes_service.save_succeeded.connect(_on_save_succeeded)
theme_service.theme_changed.connect(_on_theme_changed) theme_service.theme_changed.connect(_on_theme_changed)
_refresh_from_service() _refresh_from_service()
_apply_theme() _apply_theme()
@@ -104,6 +111,8 @@ func _on_service_content_changed(value: String) -> void:
func _on_service_state_changed(_new_state: String) -> void: func _on_service_state_changed(_new_state: String) -> void:
_refresh_metadata() _refresh_metadata()
if notes_service.state != "saved":
saved_status_timer.stop()
func _refresh_from_service() -> void: func _refresh_from_service() -> void:
@@ -111,7 +120,8 @@ func _refresh_from_service() -> void:
func _refresh_metadata() -> void: func _refresh_metadata() -> void:
status_label.text = notes_service.status_text() if status_label.text != "Saved" or saved_status_timer.time_left <= 0.0:
status_label.text = notes_service.status_text()
count_label.text = "%s / %s" % [ count_label.text = "%s / %s" % [
_format_count(editor.text.length()), _format_count(editor.text.length()),
_format_count(notes_service.MAX_CONTENT_LENGTH) _format_count(notes_service.MAX_CONTENT_LENGTH)
@@ -119,7 +129,17 @@ func _refresh_metadata() -> void:
conflict_panel.visible = notes_service.conflict_active conflict_panel.visible = notes_service.conflict_active
status_label.add_theme_color_override( status_label.add_theme_color_override(
"font_color", "font_color",
Brand.AMBER if notes_service.state in ["dirty", "offline", "conflict"] else Brand.muted_color(theme_service.is_dark_mode())) Brand.AMBER if notes_service.state == "conflict" else Brand.muted_color(theme_service.is_dark_mode()))
func _on_save_succeeded() -> void:
status_label.text = "Saved"
saved_status_timer.start()
func _clear_saved_status() -> void:
if status_label.text == "Saved":
status_label.text = ""
func _format_count(value: int) -> String: func _format_count(value: int) -> String:
+9
View File
@@ -18,6 +18,15 @@ func _run() -> void:
_assert(editor.editor != null, "notes editor should create a text editor") _assert(editor.editor != null, "notes editor should create a text editor")
_assert(editor.editor.wrap_mode == TextEdit.LINE_WRAPPING_BOUNDARY, "notes should wrap plain text") _assert(editor.editor.wrap_mode == TextEdit.LINE_WRAPPING_BOUNDARY, "notes should wrap plain text")
_assert(NavigationRoutes.key_for_screen("notes") == "notes", "notes should have a navigation route") _assert(NavigationRoutes.key_for_screen("notes") == "notes", "notes should have a navigation route")
var notes_service = root.get_node("NotesService")
var prior_state: String = notes_service.state
notes_service.state = "offline"
_assert(notes_service.status_text().is_empty(), "offline note retries should not leave a persistent status message")
editor._on_save_succeeded()
_assert(editor.status_label.text == "Saved", "successful remote saves should show a Saved confirmation")
editor._clear_saved_status()
_assert(editor.status_label.text.is_empty(), "the Saved confirmation should clear after its display window")
notes_service.state = prior_state
var dialog := NotesDialog.new() var dialog := NotesDialog.new()
root.add_child(dialog) root.add_child(dialog)