mirror of
https://github.com/gesellix/Bose-SoundTouch.git
synced 2026-08-13 06:06:15 +00:00
Closes the AfterTouch-side half of issue #234. After a factory reset the speaker's /sources only lists the always-on local entries (AUX, BLUETOOTH, AIRPLAY, NOTIFICATION, QPLAY, plus a SpotifyConnectUserName placeholder); TUNEIN, LOCAL_INTERNET_RADIO, DEEZER, and linked Spotify accounts are absent until the device receives the <sourcesUpdated/> notification the reporter ran by hand. SyncDeviceData now POSTs that notification as the final step, so users get the visible-source-list recovery for free when they click Data Sync. The other half — re-creating Marge.xml so playback resumes — is already handled by the wizard's pair-account flow: it detects an empty <margeAccountUUID/> in /info and prompts the user to pick a known account or generate a new one. The wizard's pairing UI is deliberately user-driven (the user picks the ID); the notification nudge is purely automatic because there's no choice to make. Implementation routes through the existing client surface rather than reinventing it. setup.notifySpeakerSourcesUpdated delegates to pkg/client.Client.NotifySourcesUpdated — the same path handlers_mgmt.go already uses after music-service account changes (handlers_mgmt.go:304, :637). The wire shape lives in one place (pkg/models.NewSourcesUpdatedNotification). Fire-and-forget: a notification failure logs but doesn't fail the sync. Adjacent UX changes: - docs/guides/TROUBLESHOOTING.md: new section "Presets flash then revert to 'Select a preset' after a factory reset". Names the symptom, the Marge.xml + reduced-/sources cause, and walks the user through re-opening the Migration tab + Data Sync. - pkg/service/handlers/web/js/script.js: devices list now renders a "⚠ Not paired — re-pair" badge in the account-ID column for speakers whose live /info reports an empty margeAccountUUID. Clicking it opens the Migration tab pre-filled with that device, surfacing the wizard's existing "Not paired (factory-reset or never paired)" flow without making users discover it cold. - pkg/service/testing/fakespeaker/testdata/info.xml: demo speaker now reports margeAccountUUID=1234567 instead of the misleading 0000000 (which AfterTouch happens to accept as syntactically valid but is not a documented sentinel anywhere — the convention is empty for factory-reset, a real 7-digit number otherwise, matching pkg/client/testdata/info_response_st{10,20}.xml). Screenshots regenerated accordingly. Test scaffolding: - fakespeaker grows a POST /notification recorder that captures body + Content-Type; tests assert on s.Notifications(). - TestIssue234_FactoryResetSpeakerSyncsReducedSources now drives SyncDeviceData end-to-end (exercises the wiring) and asserts the notification fires with the right deviceID and shape. - TestFakeSpeakerNotificationRecorder pins the recorder contract and the POST-only method gate. Refs #234. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
33 lines
1.2 KiB
XML
33 lines
1.2 KiB
XML
<?xml version="1.0" encoding="UTF-8" ?>
|
|
<info deviceID="DEADBEEFCAFE">
|
|
<name>Demo SoundTouch</name>
|
|
<type>SoundTouch 10</type>
|
|
<margeAccountUUID>1234567</margeAccountUUID>
|
|
<components>
|
|
<component>
|
|
<componentCategory>SCM</componentCategory>
|
|
<softwareVersion>27.0.6.46330.5043500 epdbuild.trunk.demo.2026-01-01T00:00:00</softwareVersion>
|
|
<serialNumber>SN0000000000000000DEMO</serialNumber>
|
|
</component>
|
|
<component>
|
|
<componentCategory>PackagedProduct</componentCategory>
|
|
<softwareVersion>27.0.6.46330.5043500 epdbuild.trunk.demo.2026-01-01T00:00:00</softwareVersion>
|
|
<serialNumber>000000P00000000DEMO</serialNumber>
|
|
</component>
|
|
</components>
|
|
<margeURL>https://streaming.bose.com</margeURL>
|
|
<networkInfo type="SCM">
|
|
<macAddress>02:00:00:00:00:01</macAddress>
|
|
<ipAddress>127.0.0.1</ipAddress>
|
|
</networkInfo>
|
|
<networkInfo type="SMSC">
|
|
<macAddress>02:00:00:00:00:01</macAddress>
|
|
<ipAddress>127.0.0.1</ipAddress>
|
|
</networkInfo>
|
|
<moduleType>sm2</moduleType>
|
|
<variant>rhino</variant>
|
|
<variantMode>normal</variantMode>
|
|
<countryCode>GB</countryCode>
|
|
<regionCode>GB</regionCode>
|
|
</info>
|