54 lines
2.7 KiB
JavaScript
54 lines
2.7 KiB
JavaScript
// Jellyfin Web's supported window plugin API supplies the native playback manager.
|
|
window.DecoderChannelPlayback = async () => class DecoderChannelPlayback {
|
|
constructor({ playbackManager, toast }) {
|
|
this.id = 'decoder-channel-playback';
|
|
this.name = 'Decoder channel playback';
|
|
this.type = 'integration';
|
|
const play = async (id, serverId) => {
|
|
const api = window.ApiClient;
|
|
if (!api?.getCurrentUserId() || (serverId && api.serverId() !== serverId)) return false;
|
|
const item = await api.getItem(api.getCurrentUserId(), id);
|
|
if (item.Type !== 'TvChannel') throw Error('Expected a TV channel');
|
|
await playbackManager.play({ items: [item] });
|
|
return true;
|
|
};
|
|
let pending;
|
|
const handleRoute = () => {
|
|
clearTimeout(pending);
|
|
const route = location.hash;
|
|
const query = new URLSearchParams(route.split('?')[1] || '');
|
|
const id = query.get('decoderPlay');
|
|
if (!id || !/^[a-f\d]{32}$|^[a-f\d-]{36}$/i.test(id)) return;
|
|
const deadline = Date.now() + 30000;
|
|
const attempt = async () => {
|
|
if (location.hash !== route) return;
|
|
if (!window.ApiClient?.getCurrentUserId()) {
|
|
if (Date.now() < deadline) pending = setTimeout(attempt, 250);
|
|
return;
|
|
}
|
|
query.delete('decoderPlay');
|
|
history.replaceState(null, '', location.pathname + location.search + route.split('?')[0] + (query.size ? '?' + query : ''));
|
|
try { await play(id, query.get('serverId')); }
|
|
catch (error) { console.error('Decoder channel playback failed', error); toast('Nie udało się uruchomić kanału.'); }
|
|
};
|
|
void attempt();
|
|
};
|
|
window.addEventListener('hashchange', handleRoute);
|
|
handleRoute();
|
|
// Channel image/name clicks in native channel cards should also play immediately.
|
|
document.addEventListener('click', event => {
|
|
if (event.button !== 0 || event.ctrlKey || event.metaKey || event.shiftKey || event.altKey) return;
|
|
const link = event.target.closest('a.cardImageContainer, a.itemAction.textActionButton');
|
|
const card = link?.closest('[data-type="TvChannel"]');
|
|
if (!card) return;
|
|
const id = card.dataset.id;
|
|
if (!id) return;
|
|
event.preventDefault(); event.stopImmediatePropagation();
|
|
void play(id, card.dataset.serverid).catch(error => {
|
|
console.error('Decoder channel playback failed', error);
|
|
toast('Nie udało się uruchomić kanału.');
|
|
});
|
|
}, true);
|
|
}
|
|
};
|