mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-13 04:26:16 -08:00
fix double-click external playback handling
This commit is contained in:
1 parent
626948f2f5
commit
e350a2ea96
10 files changed
+184
-27
No files matched your search
+20
@@ -0,0 +1,20 @@
|
||||
import { ChannelActions } from 'm3u-state';
|
||||
import { Channel } from 'shared-interfaces';
|
||||
import { createM3uChannelPlaybackRequest } from './m3u-channel-playback-actions';
|
||||
|
||||
describe('createM3uChannelPlaybackRequest', () => {
|
||||
it('marks channel activation as an explicit playback request', () => {
|
||||
const channel = {
|
||||
id: 'channel-1',
|
||||
name: 'Sample TV',
|
||||
url: 'http://localhost/live.m3u8',
|
||||
} as Channel;
|
||||
|
||||
expect(createM3uChannelPlaybackRequest(channel)).toEqual(
|
||||
ChannelActions.setActiveChannel({
|
||||
channel,
|
||||
startPlayback: true,
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
import { ChannelActions } from 'm3u-state';
|
||||
import { Channel } from 'shared-interfaces';
|
||||
|
||||
export function createM3uChannelPlaybackRequest(channel: Channel) {
|
||||
return ChannelActions.setActiveChannel({
|
||||
channel,
|
||||
startPlayback: true,
|
||||
});
|
||||
}
|
||||
+32
-2
@@ -495,14 +495,44 @@ describe('VideoPlayerComponent', () => {
|
||||
expect(overlayRef.attach).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('switches channels by number through the store action', () => {
|
||||
it('switches channels by number through a playback request', () => {
|
||||
syncStoreState(sampleChannel);
|
||||
fixture.detectChanges();
|
||||
|
||||
component.switchToChannelByNumber(1);
|
||||
|
||||
expect(storeMock.dispatch).toHaveBeenCalledWith(
|
||||
ChannelActions.setActiveChannel({ channel: sampleChannel })
|
||||
ChannelActions.setActiveChannel({
|
||||
channel: sampleChannel,
|
||||
startPlayback: true,
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('changes channels from remote navigation through a playback request', () => {
|
||||
const nextChannel = {
|
||||
...sampleChannel,
|
||||
id: 'channel-2',
|
||||
url: 'http://localhost/next.m3u8',
|
||||
name: 'Next TV',
|
||||
};
|
||||
activeChannel.set(sampleChannel);
|
||||
activeChannel$.next(sampleChannel);
|
||||
channels.set([sampleChannel, nextChannel]);
|
||||
channels$.next([sampleChannel, nextChannel]);
|
||||
fixture.detectChanges();
|
||||
|
||||
(
|
||||
component as unknown as {
|
||||
handleRemoteChannelChange(direction: 'up' | 'down'): void;
|
||||
}
|
||||
).handleRemoteChannelChange('down');
|
||||
|
||||
expect(storeMock.dispatch).toHaveBeenCalledWith(
|
||||
ChannelActions.setActiveChannel({
|
||||
channel: nextChannel,
|
||||
startPlayback: true,
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -88,6 +88,7 @@ import {
|
||||
Settings,
|
||||
VideoPlayer,
|
||||
} from 'shared-interfaces';
|
||||
import { createM3uChannelPlaybackRequest } from './m3u-channel-playback-actions';
|
||||
|
||||
const M3U_MULTI_EPG_HEADER_ACTION_ID = 'm3u-multi-epg';
|
||||
const M3U_SIDEBAR_STORAGE_KEY = 'm3u-sidebar-width';
|
||||
@@ -459,9 +460,7 @@ export class VideoPlayerComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
this.store.dispatch(
|
||||
ChannelActions.setActiveChannel({
|
||||
channel: nextChannel,
|
||||
})
|
||||
createM3uChannelPlaybackRequest(nextChannel)
|
||||
);
|
||||
},
|
||||
error: (err) => {
|
||||
@@ -739,7 +738,7 @@ export class VideoPlayerComponent implements OnInit, OnDestroy {
|
||||
.subscribe((channel) => {
|
||||
if (channel) {
|
||||
this.store.dispatch(
|
||||
ChannelActions.setActiveChannel({ channel })
|
||||
createM3uChannelPlaybackRequest(channel)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
+11
@@ -403,6 +403,17 @@ describe('StalkerLiveStreamLayoutComponent', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('does not attach a dangling finally cleanup to failed playback resolution', async () => {
|
||||
const playbackError = new Error('nothing_to_play');
|
||||
const playbackPromise = Promise.reject(playbackError);
|
||||
const finallySpy = jest.spyOn(playbackPromise, 'finally');
|
||||
resolveItvPlayback.mockReturnValue(playbackPromise);
|
||||
|
||||
await component.playChannel(itvChannels()[0]);
|
||||
|
||||
expect(finallySpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('starts external playback from remote channel navigation when double-click opening is enabled', async () => {
|
||||
settingsStore.openStreamOnDoubleClick.set(true);
|
||||
portalPlayer.isEmbeddedPlayer.mockReturnValue(false);
|
||||
|
||||
+4
-2
@@ -404,11 +404,13 @@ export class StalkerLiveStreamLayoutComponent implements OnDestroy {
|
||||
const promise = this.stalkerStore.resolveItvPlayback(item);
|
||||
this.playbackResolution = { channelId, promise };
|
||||
|
||||
void promise.finally(() => {
|
||||
const cleanup = () => {
|
||||
if (this.playbackResolution?.promise === promise) {
|
||||
this.playbackResolution = null;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
void promise.then(cleanup, cleanup);
|
||||
|
||||
return promise;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user