Skip to content

Add temporary sitemap diagnostics logging#1147

Open
timbms wants to merge 11 commits intodevelopfrom
feature/sitemap-diagnostics-logging
Open

Add temporary sitemap diagnostics logging#1147
timbms wants to merge 11 commits intodevelopfrom
feature/sitemap-diagnostics-logging

Conversation

@timbms
Copy link
Copy Markdown
Contributor

@timbms timbms commented Apr 15, 2026

Summary

  • add a temporary debug-gated sitemap diagnostics mode with exportable logs
  • log row diff/publish activity and targeted render activity for linked/icon/media paths
  • reduce known churn by gating foreground refresh while the sitemap is already healthy and by narrowing icon/media dependencies
  • make video stream teardown less eager during brief SwiftUI lifecycle churn
  • fix ApplicationPreferences backward decoding for the temporary diagnostics flag

Notes

This branch is intended to be easy to remove once the scrolling issue is diagnosed and fixed. The diagnostics are hidden behind the Sitemap Diagnostics Logging debug toggle.

Testing

  • exported tester logs and iterated on the instrumentation
  • no full local build/test completion was captured in this session

@timbms timbms marked this pull request as ready for review April 15, 2026 14:46
timbms and others added 11 commits April 18, 2026 08:16
…1138)

The SwiftUI sitemap introduced in 3.2.x hitches during inertial scrolling
when items update frequently. Every long-poll result previously called
reconcileWidgets + copyWidgetProperties unconditionally, then always
reassigned @published rowInputs — causing a broad objectWillChange
broadcast on every cycle even when nothing the list renders had changed.

Fix: snapshot row inputs from fresh page data before any widget mutation.
updateUI now returns early (skipping all reconciliation and @published
writes) when the computed preview inputs equal the current rowInputs and
the page title is unchanged. When searchText is active, reconciliation
still runs to keep currentPage fresh so clearing the filter won't expose
stale hidden widgets.

Widen widget-version granularity from bare widgetId to full RowID so
repeated widget IDs on one page track independently. widgetUpdateVersions
is now keyed by RowID.rawValue; bumpWidgetVersions increments by row-
identity pairs; SliderRowView, SegmentedRowView, SelectionRowView, and
ImageRowView pass input.rowID to the lookup; affected row-input types
carry their rowID.

Adds SitemapPageViewModelDiffingTests covering: stable rebuild equality,
objectWillChange suppression on unchanged data, structure-change rebuild,
bumpWidgetVersions no-op on identical inputs, per-row version isolation,
structure-change full bump, and repeated-widgetId independence.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
updateUI now replaces currentPage wholesale instead of mutating existing
OpenHABWidget objects through reconcileWidgets/copyWidgetProperties.
Row inputs are already computed from fresh page data before any stored
state changes, so the mutable widget graph was redundant as a rendering
model. Deletes:

- reconcileWidgets(_:with:) and copyWidgetProperties(from:to:) — 70 lines
  of in-place @published mutation that ran on every changed poll
- injectSendCommand(for:) — the injected widget.sendCommand closure was
  never invoked; all row views call viewModel.sendCommand(command,for:itemName)
  directly via @EnvironmentObject
- rowWidgetIndex / buildWidgetIndex / widget(for:) — the RowID→OpenHABWidget
  lookup was dead code; no row view called widget(for:)
- WidgetRenderKey and its five support types — only used by trackWidgetUpdates
  which was removed in the previous commit

loadCurrentPage drops the injectSendCommand call for the same reason.
rebuildRowInputs drops the index rebuild. No behaviour change for any
interactive row; slider optimistic values, segmented/selection sync, and
media refresh all go through the row-input and item-name paths that were
already in place.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
* Decouple hot sitemap rows from shared view model
* Clean up slider override decoupling
* Restore page-scoped icon identity

---------

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
* Lazy-load linked sitemap page navigation
* Remove redundant sitemap title modifiers
* Fix linked page mapper tests

---------

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
…rows

Text, generic, and linked rows had no update mechanism — no @EnvironmentObject
subscription and no widgetVersion — so SwiftUI could skip re-evaluating them
when rowInputs changed on foreground refresh.

Add widgetVersion to TextRowInput, GenericRowInput, and LinkedPageRowInput,
handle them in applyingWidgetVersions(), and remove the leftover @mainactor
factory-function pattern from TextRowView and GenericRowView.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
…t syntax

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
… model

Off-screen list rows rendered stale data when scrolled into view after a
foreground refresh. SwiftUI reuses cached renders for views with no observable
dependencies. Adding @EnvironmentObject to EmbeddingRowInputView ensures every
row is re-evaluated when rowInputs change, covering all row types at once.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
@timbms timbms force-pushed the feature/sitemap-diagnostics-logging branch from f14652c to 4e702a8 Compare April 18, 2026 06:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant