Update-Check: sichtbares Ergebnis-Fenster für „🔄 Updates prüfen“ (Sly-Wunsch 20.10.).

Befund: der Check funktionierte die ganze Zeit — die Rückmeldung kam aber
NUR in der Statuszeile („Du bist auf dem neusten Stand (…).“) und verblasst
dort schnell → las sich wie „tut nichts“. Probe (echter Menü-Klick): Check
läuft, ls-remote ok, Status korrekt.

Fix: nach dem MANUELLEN Check (report=true) öffnet ein kleines AcceptDialog
„Update-Check“ mit Klartext-Ergebnis (Stil wie Map-Check-Dialog):
- up_to_date: „Du bist auf dem neusten Stand (<sha>).“
- update_available: Zusätzlich zum Banner das Fenster mit local → remote
  und Hinweis auf „Jetzt updaten“.
- unreachable / auth_failed / error: gleicher Klartext wie Statuszeile.
Der Still-Start-Check (report=false) zeigt bewusst KEIN Fenster (nur Banner
bei „Update verfügbar“) — Probe belegt: Popup sichtbar=false.
Probe: probe_update_check (echter Menü-Klick → Popup sichtbar + Text).
Suiten: test_updater 75 OK, test_resize_dialog 44 OK, test_theme 35 OK,
test_gui_smoke 92 OK, test_ux 137 OK, test_ui_layout 79 OK.
This commit is contained in:
Hermes (scopedvr-dev) 2026-10-20 18:37:38 +00:00
parent ae551f387a
commit d637314b82
2 changed files with 66 additions and 0 deletions

View file

@ -177,6 +177,11 @@ var error_text: Label
var check_dialog: AcceptDialog var check_dialog: AcceptDialog
var check_text: Label var check_text: Label
# Update-Check-Ergebnis (Menü „🔄 Updates prüfen“, Sly 20.10.: nur die
# Statuszeile las sich wie „tut nichts“ → kleines Ergebnis-Fenster).
var update_dialog: AcceptDialog
var update_text: Label
# Karte testen (Karte t_b84af40f) # Karte testen (Karte t_b84af40f)
var test_btn: Button var test_btn: Button
@ -470,6 +475,18 @@ func _build_dialogs_and_overlays() -> void:
check_dialog.add_child(check_text) check_dialog.add_child(check_text)
add_child(check_dialog) add_child(check_dialog)
# Update-Check-Ergebnis (Sly 20.10.: „tut nichts“ — weil die Rückmeldung
# NUR in der Statuszeile kam und dort schnell wieder weg war). Kleines
# Fenster mit dem Klartext-Ergebnis, Stil wie der Map-Check-Dialog.
update_dialog = AcceptDialog.new()
update_dialog.title = "Update-Check"
update_dialog.ok_button_text = "Alles klar"
update_text = Label.new()
update_text.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
update_text.custom_minimum_size = UIScale.v2(560, 0)
update_dialog.add_child(update_text)
add_child(update_dialog)
# Karte 3/3 (t_11b5c25b): Dirty-Schutz vor „Neue Map“ / „Öffnen“ — deutsche # Karte 3/3 (t_11b5c25b): Dirty-Schutz vor „Neue Map“ / „Öffnen“ — deutsche
# Klartext-Frage, „Verwerfen“ führt die wartende Aktion aus, „Abbrechen“ tut # Klartext-Frage, „Verwerfen“ führt die wartende Aktion aus, „Abbrechen“ tut
# nichts (Map bleibt, wie sie ist). # nichts (Map bleibt, wie sie ist).
@ -911,6 +928,16 @@ func _updater_check_thread(report: bool) -> void:
call_deferred("_updater_check_done", result, report) call_deferred("_updater_check_done", result, report)
## Klartext-Ergebnis-Fenster für den manuellen Update-Check (Sly 20.10.:
## Statuszeile allein las sich wie „tut nichts“). Nur bei MANUELLEM Check
## (report=true), der Still-Start-Check bleibt still.
func _show_update_popup(text: String) -> void:
if update_dialog == null or not is_instance_valid(update_dialog):
return # UI wurde gerade neu aufgebaut (UI-Größe) — nichts anfassen
update_text.text = text
update_dialog.popup_centered()
func _updater_check_done(result: Dictionary, report: bool) -> void: func _updater_check_done(result: Dictionary, report: bool) -> void:
_update_check_busy = false _update_check_busy = false
_join(check_thread) _join(check_thread)
@ -922,20 +949,27 @@ func _updater_check_done(result: Dictionary, report: bool) -> void:
_set_status("🔄 Update verfügbar: %s → %s — im Banner „Jetzt updaten“ klicken." % [ _set_status("🔄 Update verfügbar: %s → %s — im Banner „Jetzt updaten“ klicken." % [
EditorUpdater.short_sha(str(result["local"])), EditorUpdater.short_sha(str(result["local"])),
EditorUpdater.short_sha(str(result["remote"]))]) EditorUpdater.short_sha(str(result["remote"]))])
_show_update_popup("🔄 Update verfügbar: %s → %s.\n\nIm Banner oben „Jetzt updaten“ klicken — der Editor holt sich den Stand, baut ihn und startet neu." % [
EditorUpdater.short_sha(str(result["local"])),
EditorUpdater.short_sha(str(result["remote"]))])
"up_to_date": "up_to_date":
if report: if report:
_set_status("Du bist auf dem neusten Stand (%s)." % EditorUpdater.short_sha(str(result["local"]))) _set_status("Du bist auf dem neusten Stand (%s)." % EditorUpdater.short_sha(str(result["local"])))
_show_update_popup("Du bist auf dem neusten Stand (%s).\n\nAktuelle Version ist installiert — es gibt nichts zu tun." % EditorUpdater.short_sha(str(result["local"])))
"unreachable": "unreachable":
if report: if report:
_set_status("Update-Check nicht erreichbar (offline oder Tunnel weg) — später nochmal probieren.", true) _set_status("Update-Check nicht erreichbar (offline oder Tunnel weg) — später nochmal probieren.", true)
_show_update_popup("Update-Check nicht erreichbar.\n\nDer Server ist gerade nicht erreichbar (offline oder Tunnel weg) — später nochmal probieren.")
"auth_failed": "auth_failed":
# Karte t_1457e935: Zugangsdaten fehlen → klarer Hinweis statt # Karte t_1457e935: Zugangsdaten fehlen → klarer Hinweis statt
# GUI-Login-Dialog (Askpass ist im Updater abgeschaltet). # GUI-Login-Dialog (Askpass ist im Updater abgeschaltet).
if report: if report:
_set_status(EditorUpdater.AUTH_ERROR_TEXT, true) _set_status(EditorUpdater.AUTH_ERROR_TEXT, true)
_show_update_popup(EditorUpdater.AUTH_ERROR_TEXT)
_: _:
if report: if report:
_set_status("Update-Check fehlgeschlagen: %s" % str(result.get("error", "")), true) _set_status("Update-Check fehlgeschlagen: %s" % str(result.get("error", "")), true)
_show_update_popup("Update-Check fehlgeschlagen:\n%s" % str(result.get("error", "")))
func _show_update_banner(local_sha: String, remote_sha: String) -> void: func _show_update_banner(local_sha: String, remote_sha: String) -> void:

View file

@ -0,0 +1,32 @@
extends SceneTree
## „🔄 Updates prüfen“ per echtem Menü-Signal auslösen und den Statuszeilen-
## Text beobachten — deckt ab: Menü-Pfad, Thread, Statusmeldung.
func _initialize() -> void:
_run.call_deferred()
func _run() -> void:
var scene: PackedScene = load("res://scenes/main.tscn")
var main: Control = scene.instantiate()
root.add_child(main)
await process_frame
await process_frame
main._start_with_new_map()
# Echter Menü-Pfad: Datei-Popup id_pressed(7).
var file_menu_btn: MenuButton = null
for n in main.find_children("*", "MenuButton", true, false):
if n is MenuButton and n.text == "Datei":
file_menu_btn = n
(file_menu_btn.get_popup() as PopupMenu).id_pressed.emit(7)
print("PROBE direkt nach Klick: status='", main.status_label.text if "status_label" in main else "?", "' busy=", main._update_check_busy)
for i in 60:
await process_frame
if not main._update_check_busy:
break
print("PROBE nach Thread: busy=", main._update_check_busy, " status='", main.status_label.text, "'")
print("PROBE popup: visible=", main.update_dialog.visible, " text='", main.update_text.text, "'")
# Still-Start-Check (report=false) darf KEIN Popup zeigen.
main.update_dialog.hide()
main._updater_check_done({"status": "up_to_date", "local": "abc", "remote": "abc"}, false)
print("PROBE still-check: popup sichtbar=", main.update_dialog.visible)
quit(0)