feat(playback): recommend recovery actions (#1374)

* docs(playback): design recovery recommendations

* docs(playback): plan recovery recommendations

* refactor(playback): extract diagnostic utilities

* feat(playback): define recovery recommendation contracts

* feat(playback): rank recovery recommendations

* feat(playback): track session recovery attempts

* feat(playback): identify content recovery sessions

* feat(ui): add ranked playback diagnostic panel

* feat(playback): switch temporarily to recommended players

* test(playback): cover temporary player recommendation

* test(playback): verify recommendation capability guards

* docs(playback): document recovery recommendations

* fix(playback): keep recovery keys credential-free

* fix(playback): remove derived tracking ownership

* fix(playback): preserve distinct recovery fallbacks

* fix(playback): reset resume for new sources

* fix(playback): preserve desktop recovery guidance

* docs(playback): clarify recovery policy exceptions

* fix(playback): reject stale progress updates

* fix(playback): keep protected recovery guidance neutral

* test(playback): cover stale progress output

* fix(playback): neutralize protected diagnostic copy

* fix(playback): harden runtime guidance ownership

* fix(playback): stabilize recovery application ownership

* fix(ci): classify playback util coverage

* fix(e2e): preserve playback fixture bytes
This commit is contained in:
4gray authored and GitHub committed 2026-08-08 01:04:39 +02:00
1 parent 5e4f2ca3dd
commit fd96b85c19
176 files changed
+15228 -1908

No files matched your search

@@ -383,6 +383,10 @@ describe('UnifiedFavoritesDataService', () => {
'https://example.com/2.m3u8',
'https://example.com/1.m3u8',
]);
expect(items.map((item) => item.uid)).toEqual([
'm3u::m3u-1::https://example.com/2.m3u8',
'm3u::m3u-1::https://example.com/1.m3u8',
]);
expect(items[1].channelId).toBe('channel-1');
expect(items[0].radio).toBe('true');
expect(items[0].m3uChannel).toBe(m3uChannels[1]);
@@ -195,6 +195,7 @@ describe('UnifiedRecentDataService', () => {
expect(items).toHaveLength(1);
expect(items[0]).toMatchObject({
uid: 'm3u::m3u-1::https://example.com/2.m3u8',
sourceType: 'm3u',
streamUrl: 'https://example.com/2.m3u8',
channelId: 'channel-2',