#663

feat(web): remember Classic/V2 preference for tray Open Vibepollo

Draftdonny110wants to merge intofrom

Problem

Vibepollo exposes both Classic (/) and V2 (/v2/) configuration interfaces, but Open Vibepollo in the Windows tray does not remember which one the user last selected. After explicitly switching to V2, the tray can still return to Classic. A user should not have to repeatedly navigate to their preferred UI.

Proposed behavior

  • Clicking Use V2 Web UI in Classic saves web_ui_preference = v2 before navigating.
  • Clicking Classic interface in V2 saves web_ui_preference = legacy before navigating.
  • The existing tray Open Vibepollo action reads the selected preference and opens /v2/ or / accordingly.
  • This preference persists in the host config (across browser closures and service restarts), not only in per-browser local storage.
  • The default remains Classic (legacy) for backward compatibility; there are no additional tray items.
  • The preference accepts only legacy or v2. Both links retain normal native navigation for modifier/middle clicks.

Scope / implementation

This PR is based directly on the current upstream master rather than the earlier experimental branch (which was 286 commits behind at the time of porting).

  • src/config.{h,cpp}: declare and parse the restricted host preference.
  • src/system_tray.cpp: select the existing launcher URL from the persisted configuration, including a saved update not yet applied while an active session defers config reload.
  • src_assets/common/assets/web-legacy/views/DashboardView.vue: save on Classic → V2 switch.
  • src_assets/common/assets/web/components/layout/AppShell.vue: save on V2 → Classic switch.
  • src_assets/common/assets/web-legacy/public/assets/locale/en.json: support the existing switch label.
  • src_assets/common/assets/web/e2e/ui.spec.ts: add an isolated navigation/persistence contract test; its fake Classic landing intercept matches the exact root URL, not **/ (which would also shadow the V2 app).
  • docs/configuration.md: document the preference and allowed values.

No stream, display, input, or encoder policy is intentionally changed. Not related to the accepted display-restore and log-download contributions (#616, #619).

Validation — Draft

  • Ported only the intended eight-file change onto recent upstream code.
  • Verified the PR branch is ahead of the latest upstream master with no behind commits at creation.
  • Checked the V2 link markup is singular, and fixed the earlier browser-test route wildcard.
  • Run frontend production build and Playwright browser regression (the test has been added, not yet executed).
  • Run Windows build/CI and review any regression failures.
  • Manually switch Classic → V2, close the browser, then reopen via tray. Confirm V2 opens.
  • Manually switch V2 → Classic, then reopen via tray. Confirm Classic opens.
  • Restart the Windows Vibepollo service and verify the last selection survives.
  • Verify ordinary tray behavior and streaming sessions remain intact.
  • Add UI screenshots or a short screen recording illustrating the before/after behavior if required for review.

This is AI-assisted code. It must be independently reviewed and tested on real hardware in accordance with Vibepollo contributing guidelines. Automated test source alone is not evidence of a successful run.

UX question for maintainers

The proposed preference is host-wide, matching how the Windows tray opens the host UI. If a browser-specific preference is preferred instead, feedback is welcome before merge.

Activity

28
donny11011d ago

Thanks for the careful review — all three findings are valid. I have revised this draft PR rather than trying to patch the general config endpoint.

  • P1 (pending restart-only settings): Both interface-switch links now call a dedicated, authenticated/CSRF-protected POST /api/web-ui-preference. It writes only the independent preference sidecar and never calls apply_config_now() or modifies sunshine.conf. A pending port update therefore cannot be accidentally activated by simply switching UIs.
  • P2 (tray/config data race): The mutable config::sunshine.web_ui_preference field and unsynchronized read are removed. The tray and endpoint use the same mutex-protected preference store; the tray no longer reads the config string during reload.
  • P2 (lost user comments): The selected interface is persisted separately in the app-data web-ui-preference file through the existing atomic file replacement helper. No general config parse/rewrite occurs when switching interfaces.

I added a focused C++ regression suite (validation, pending-config/comment preservation, concurrent reads/writes, failure) and updated the Playwright navigation test to assert a preference POST and zero generic config PATCHes. The PR description now documents the changes and the remaining tests.

The initial host-regression check has passed, but the full CI/Windows workflows and manual end-to-end Windows validation are still pending. Keeping this PR Draft until those results are established. Review of the new storage/API design is welcome.

donny11011d ago

Thanks again for the review. Before making any further code changes, I'd appreciate your opinion on the storage boundary.

Would you consider the dedicated web-ui-preference sidecar file (with its small authenticated endpoint) an appropriate, sufficiently surgical design for this host-wide UI choice? It deliberately avoids both the general sunshine.conf update/reload path and the existing vibeshine_state.json state/recovery machinery. If you would prefer the latter, or a smaller integration, I'd be interested in your reasoning before changing the approach.

Two additional improvements are noted for consideration, not yet implemented:

  1. Real integration coverage: the unit tests use injected/fake storage and the browser test mocks the endpoint. A Windows integration test should check that changing UI with an unapplied port change preserves the active listener/tray URL and leaves # comments untouched.
  2. Persistence failure UX: both switch links currently navigate even if saving the preference fails. We could surface a clear error or avoid navigating until save succeeds, so the user's selection doesn't silently differ from what the tray opens.

For now I'm leaving the PR as-is and in Draft, pending your architectural feedback and the remaining Windows validation/build results. No additional code changes are planned without discussing them first. (codex assisted)

This pull request is a draft

Merging is unavailable until it is marked ready for review.