Notechondria

Version: 0.1.54 Build Date: 2026-04-22T17:43

What's Changed

Cross-app dedup — shared AppShellLogMixin (step 1 of 8)

  • Audit of the three _AppShellState classes after 0.1.53 found 63+ byte-identical methods. The fix is to promote the shared chunks up into notechondria_shared/lib/src/app_shell/ as Dart mixins on State<StatefulWidget>, with abstract getters for the few state fields each mixin needs. This round lands the first mixin and migrates editor_app to consume it, so the pattern can be repeated in subsequent rounds for the other seven planned mixins.

  • New AppShellLogMixin<W extends StatefulWidget> in notechondria_shared/lib/src/app_shell/app_shell_log_mixin.dart owns the uiLogs ring buffer, the DebugLogController, the log emitters (appendUiLog, log, timed<T>), and the refreshState / showMessage utilities every other shared mixin will depend on. 80-entry ring buffer cap matches the prior per-app convention. Persistence is delegated to an abstract persistUiLogs() method so each app keeps using its _LocalAppStore bucket (one SharedPreferences blob, not a parallel key per mixin).

  • editor_app/lib/app_shell.dart mixes in AppShellLogMixin<AppShell> and provides the abstract members. 216 private call sites renamed across editor_app/lib/ (_loglog, _uiLogsuiLogs, _refreshrefreshState, _showMessageshowMessage, _appendUiLogappendUiLog, _timedtimed, _logControllerlogController). Library-private members on a mixin shipped from another package have to be public — Dart privacy is per-library.

  • The per-app core/logging.dart extension (61 lines) is deleted; the same code now lives once in notechondria_shared.

Files Changed

  • frontend/notechondria_shared/lib/src/app_shell/app_shell_log_mixin.dart (new, 125 lines).
  • frontend/notechondria_shared/lib/notechondria_shared.dart — exports AppShellLogMixin.
  • frontend/notechondria_shared/pubspec.yaml — adds shared_preferences, http, file_selector, path_provider. Editor/planner/portal already pulled these as transitive deps.
  • frontend/editor_app/lib/app_shell.dart_AppShellState extends State<AppShell> with AppShellLogMixin<AppShell> and overrides the abstract uiLogs, logController, persistUiLogs().
  • 22 other files under frontend/editor_app/lib/ updated by the bulk rename.
  • frontend/editor_app/lib/core/logging.dart — deleted.
  • frontend/editor_app/lib/main.dart — drops the part 'core/logging.dart' line.

Notes

  • One {bool showMessage} named-parameter on _syncAllLocalData shadowed the new mixin method; renamed to {bool announce} across editor_app to fix the shadow.
  • Smoke test passes; analyzer clean. planner_app and portal_app still hold their own copies of these helpers — the next two rounds promote auth + OAuth (0.1.55, 0.1.56) and then bring the other two apps onto all three mixins (0.1.57, 0.1.58).