diff --git a/receivers/common/web/main/Preload.ts b/receivers/common/web/main/Preload.ts index 4e84536..c0902ca 100644 --- a/receivers/common/web/main/Preload.ts +++ b/receivers/common/web/main/Preload.ts @@ -1,5 +1,4 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ -/* eslint-disable @typescript-eslint/no-require-imports */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { toast, ToastIcon } from '../components/Toast'; @@ -12,7 +11,6 @@ declare global { } } -let deviceInfo: any; let preloadData: Record = {}; // @ts-ignore @@ -26,7 +24,7 @@ if (TARGET === 'electron') { }); electronAPI.ipcRenderer.on("device-info", (_event, value: any) => { - deviceInfo = value; + preloadData.deviceInfo = value; }) electronAPI.contextBridge.exposeInMainWorld('targetAPI', { @@ -34,49 +32,25 @@ if (TARGET === 'electron') { onDeviceInfo: (callback: any) => electronAPI.ipcRenderer.on("device-info", callback), onConnect: (callback: any) => electronAPI.ipcRenderer.on("connect", callback), onDisconnect: (callback: any) => electronAPI.ipcRenderer.on("disconnect", callback), - getDeviceInfo: () => deviceInfo, + getDeviceInfo: () => preloadData.deviceInfo, }); // @ts-ignore } else if (TARGET === 'webOS') { try { - require('lib/webOSTVjs-1.2.10/webOSTV.js'); - require('lib/webOSTVjs-1.2.10/webOSTV-dev.js'); - const serviceId = 'com.futo.fcast.receiver.service'; - let onStartupStorageClearCb = () => { localStorage.clear(); }; - let onDeviceInfoCb = () => { console.log('Main: Callback not set while fetching device info'); }; - let onConnectCb = (_, value: any) => { console.log('Main: Callback not set while calling onConnect'); }; - let onDisconnectCb = (_, value: any) => { console.log('Main: Callback not set while calling onDisconnect'); }; - - const getDeviceInfoService = window.webOS.service.request(`luna://${serviceId}/`, { - method:"getDeviceInfo", - parameters: {}, - onSuccess: (message: any) => { - console.log(`Main: getDeviceInfo ${JSON.stringify(message)}`); - - deviceInfo = message.value; - onDeviceInfoCb(); - }, - onFailure: (message: any) => { - console.error(`Main: getDeviceInfo ${JSON.stringify(message)}`); - toast(`Main: getDeviceInfo ${JSON.stringify(message)}`, ToastIcon.ERROR); - }, - // onComplete: (message) => {}, - }); - - window.targetAPI = { - onStartupStorageClear: (callback: () => void) => onStartupStorageClearCb = callback, - onDeviceInfo: (callback: () => void) => onDeviceInfoCb = callback, - onConnect: (callback: () => void) => onConnectCb = callback, - onDisconnect: (callback: () => void) => onDisconnectCb = callback, - getDeviceInfo: () => deviceInfo, + preloadData = { + onStartupStorageClearCb: () => { localStorage.clear(); }, + onDeviceInfoCb: () => { console.log('Main: Callback not set while fetching device info'); }, + onConnectCb: (_, value: any) => { console.log('Main: Callback not set while calling onConnect'); }, + onDisconnectCb: (_, value: any) => { console.log('Main: Callback not set while calling onDisconnect'); }, }; - preloadData = { - getDeviceInfoService: getDeviceInfoService, - onStartupStorageClearCb: onStartupStorageClearCb, - onConnectCb: onConnectCb, - onDisconnectCb: onDisconnectCb, + window.targetAPI = { + onStartupStorageClear: (callback: () => void) => preloadData.onStartupStorageClearCb = callback, + onDeviceInfo: (callback: () => void) => preloadData.onDeviceInfoCb = callback, + onConnect: (callback: (_, value: any) => void) => preloadData.onConnectCb = callback, + onDisconnect: (callback: (_, value: any) => void) => preloadData.onDisconnectCb = callback, + getDeviceInfo: () => preloadData.deviceInfo, }; } catch (err) { diff --git a/receivers/common/web/player/Preload.ts b/receivers/common/web/player/Preload.ts index 99e75ee..e8788dc 100644 --- a/receivers/common/web/player/Preload.ts +++ b/receivers/common/web/player/Preload.ts @@ -1,5 +1,4 @@ /* eslint-disable @typescript-eslint/ban-ts-comment */ -/* eslint-disable @typescript-eslint/no-require-imports */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { PlaybackErrorMessage, PlaybackUpdateMessage, VolumeUpdateMessage } from 'common/Packets'; export {}; @@ -34,219 +33,29 @@ if (TARGET === 'electron') { // @ts-ignore } else if (TARGET === 'webOS') { - require('lib/webOSTVjs-1.2.10/webOSTV.js'); - require('lib/webOSTVjs-1.2.10/webOSTV-dev.js'); - - const serviceId = 'com.futo.fcast.receiver.service'; - let onPlayCb, onPauseCb, onResumeCb; - let onSeekCb, onSetVolumeCb, onSetSpeedCb; - let playerWindowOpen = false; - - const playService = window.webOS.service.request(`luna://${serviceId}/`, { - method:"play", - parameters: {}, - onSuccess: (message: any) => { - // console.log(JSON.stringify(message)); - if (message.value.subscribed === true) { - console.log('Player: Registered play handler with service'); - } - - if (message.value.playData !== null) { - if (!playerWindowOpen) { - playerWindowOpen = true; - } - - if (onPlayCb === undefined) { - window.webOSAPI.pendingPlay = message.value.playData; - } - else { - onPlayCb(null, message.value.playData); - } - } - }, - onFailure: (message: any) => { - console.error(`Player: play ${JSON.stringify(message)}`); - }, - subscribe: true, - resubscribe: true - }); - - const pauseService = window.webOS.service.request(`luna://${serviceId}/`, { - method:"pause", - parameters: {}, - onSuccess: (message: any) => { - if (message.value.subscribed === true) { - console.log('Player: Registered pause handler with service'); - } - else { - onPauseCb(); - } - }, - onFailure: (message: any) => { - console.error(`Player: pause ${JSON.stringify(message)}`); - }, - subscribe: true, - resubscribe: true - }); - - const resumeService = window.webOS.service.request(`luna://${serviceId}/`, { - method:"resume", - parameters: {}, - onSuccess: (message: any) => { - if (message.value.subscribed === true) { - console.log('Player: Registered resume handler with service'); - } - else { - onResumeCb(); - } - }, - onFailure: (message: any) => { - console.error(`Player: resume ${JSON.stringify(message)}`); - }, - subscribe: true, - resubscribe: true - }); - - const stopService = window.webOS.service.request(`luna://${serviceId}/`, { - method:"stop", - parameters: {}, - onSuccess: (message: any) => { - if (message.value.subscribed === true) { - console.log('Player: Registered stop handler with service'); - } - else { - playerWindowOpen = false; - playService.cancel(); - pauseService.cancel(); - resumeService.cancel(); - stopService.cancel(); - seekService.cancel(); - setVolumeService.cancel(); - setSpeedService.cancel(); - - // WebOS 22 and earlier does not work well using the history API, - // so manually handling page navigation... - // history.back(); - window.open('../main_window/index.html'); - } - }, - onFailure: (message: any) => { - console.error(`Player: stop ${JSON.stringify(message)}`); - }, - subscribe: true, - resubscribe: true - }); - - const seekService = window.webOS.service.request(`luna://${serviceId}/`, { - method:"seek", - parameters: {}, - onSuccess: (message: any) => { - if (message.value.subscribed === true) { - console.log('Player: Registered seek handler with service'); - } - else { - onSeekCb(null, message.value); - } - }, - onFailure: (message: any) => { - console.error(`Player: seek ${JSON.stringify(message)}`); - }, - subscribe: true, - resubscribe: true - }); - - const setVolumeService = window.webOS.service.request(`luna://${serviceId}/`, { - method:"setvolume", - parameters: {}, - onSuccess: (message: any) => { - if (message.value.subscribed === true) { - console.log('Player: Registered setvolume handler with service'); - } - else { - onSetVolumeCb(null, message.value); - } - }, - onFailure: (message: any) => { - console.error(`Player: setvolume ${JSON.stringify(message)}`); - }, - subscribe: true, - resubscribe: true - }); - - const setSpeedService = window.webOS.service.request(`luna://${serviceId}/`, { - method:"setspeed", - parameters: {}, - onSuccess: (message: any) => { - if (message.value.subscribed === true) { - console.log('Player: Registered setspeed handler with service'); - } - else { - onSetSpeedCb(null, message.value); - } - }, - onFailure: (message: any) => { - console.error(`Player: setspeed ${JSON.stringify(message)}`); - }, - subscribe: true, - resubscribe: true - }); + preloadData = { + sendPlaybackErrorCb: () => { console.error('Player: Callback "send_playback_error" not set'); }, + sendPlaybackUpdateCb: () => { console.error('Player: Callback "send_playback_update" not set'); }, + sendVolumeUpdateCb: () => { console.error('Player: Callback "send_volume_update" not set'); }, + // onPlayCb: () => { console.error('Player: Callback "play" not set'); }, + onPlayCb: undefined, + onPauseCb: () => { console.error('Player: Callback "pause" not set'); }, + onResumeCb: () => { console.error('Player: Callback "resume" not set'); }, + onSeekCb: () => { console.error('Player: Callback "onseek" not set'); }, + onSetVolumeCb: () => { console.error('Player: Callback "setvolume" not set'); }, + onSetSpeedCb: () => { console.error('Player: Callback "setspeed" not set'); }, + }; window.targetAPI = { - sendPlaybackError: (error: PlaybackErrorMessage) => { - window.webOS.service.request(`luna://${serviceId}/`, { - method: 'send_playback_error', - parameters: { error }, - onSuccess: () => {}, - onFailure: (message: any) => { - console.error(`Player: send_playback_error ${JSON.stringify(message)}`); - }, - }); - }, - - sendPlaybackUpdate: (update: PlaybackUpdateMessage) => { - window.webOS.service.request(`luna://${serviceId}/`, { - method: 'send_playback_update', - parameters: { update }, - // onSuccess: (message: any) => { - // console.log(`Player: send_playback_update ${JSON.stringify(message)}`); - // }, - onSuccess: () => {}, - onFailure: (message: any) => { - console.error(`Player: send_playback_update ${JSON.stringify(message)}`); - }, - }); - }, - sendVolumeUpdate: (update: VolumeUpdateMessage) => { - window.webOS.service.request(`luna://${serviceId}/`, { - method: 'send_volume_update', - parameters: { update }, - onSuccess: () => {}, - onFailure: (message: any) => { - console.error(`Player: send_volume_update ${JSON.stringify(message)}`); - }, - }); - }, - onPlay: (callback: any) => { onPlayCb = callback; }, - onPause: (callback: any) => { onPauseCb = callback; }, - onResume: (callback: any) => { onResumeCb = callback; }, - onSeek: (callback: any) => { onSeekCb = callback; }, - onSetVolume: (callback: any) => { onSetVolumeCb = callback; }, - onSetSpeed: (callback: any) => { onSetSpeedCb = callback; } - }; - - window.webOSAPI = { - pendingPlay: null - }; - - preloadData = { - playerWindowOpen: playerWindowOpen, - playService: playService, - pauseService: pauseService, - resumeService: resumeService, - stopService: stopService, - seekService: seekService, - setVolumeService: setVolumeService, - setSpeedService: setSpeedService, + sendPlaybackError: (error: PlaybackErrorMessage) => { preloadData.sendPlaybackErrorCb(error); }, + sendPlaybackUpdate: (update: PlaybackUpdateMessage) => { preloadData.sendPlaybackUpdateCb(update); }, + sendVolumeUpdate: (update: VolumeUpdateMessage) => { preloadData.sendVolumeUpdateCb(update); }, + onPlay: (callback: any) => { preloadData.onPlayCb = callback; }, + onPause: (callback: any) => { preloadData.onPauseCb = callback; }, + onResume: (callback: any) => { preloadData.onResumeCb = callback; }, + onSeek: (callback: any) => { preloadData.onSeekCb = callback; }, + onSetVolume: (callback: any) => { preloadData.onSetVolumeCb = callback; }, + onSetSpeed: (callback: any) => { preloadData.onSetSpeedCb = callback; } }; } else { // @ts-ignore diff --git a/receivers/webos/fcast-receiver-service/src/Main.ts b/receivers/webos/fcast-receiver-service/src/Main.ts index 6ad6b82..a59fbf8 100644 --- a/receivers/webos/fcast-receiver-service/src/Main.ts +++ b/receivers/webos/fcast-receiver-service/src/Main.ts @@ -47,6 +47,7 @@ export class Main { }); const voidCb = (message: any) => { message.respond({ returnValue: true, value: {} }); }; + const objectCb = (message: any, value: any) => { message.respond({ returnValue: true, value: value }); }; let startupStorageClearClosureCb = null; service.register("startup-storage-clear", (message: any) => { @@ -64,10 +65,9 @@ export class Main { }); let toastClosureCb = null; - const toastCb = (message: any, value: any) => { message.respond({ returnValue: true, value: value }); }; service.register("toast", (message: any) => { if (message.isSubscription) { - toastClosureCb = toastCb.bind(this, message); + toastClosureCb = objectCb.bind(this, message); Main.emitter.on('toast', toastClosureCb); } @@ -89,10 +89,9 @@ export class Main { }); let connectClosureCb = null; - const connectCb = (message: any, value: any) => { message.respond({ returnValue: true, value: value }); }; service.register("connect", (message: any) => { if (message.isSubscription) { - connectClosureCb = connectCb.bind(this, message); + connectClosureCb = objectCb.bind(this, message); Main.emitter.on('connect', connectClosureCb); } @@ -105,10 +104,9 @@ export class Main { }); let disconnectClosureCb = null; - const disconnectCb = (message: any, value: any) => { message.respond({ returnValue: true, value: value }); }; service.register("disconnect", (message: any) => { if (message.isSubscription) { - disconnectClosureCb = disconnectCb.bind(this, message); + disconnectClosureCb = objectCb.bind(this, message); Main.emitter.on('disconnect', disconnectClosureCb); } diff --git a/receivers/webos/fcast-receiver/src/main/Preload.ts b/receivers/webos/fcast-receiver/src/main/Preload.ts index 6935679..cf834e2 100644 --- a/receivers/webos/fcast-receiver/src/main/Preload.ts +++ b/receivers/webos/fcast-receiver/src/main/Preload.ts @@ -1,6 +1,9 @@ +/* eslint-disable @typescript-eslint/no-require-imports */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { preloadData } from 'common/main/Preload'; import { toast, ToastIcon } from 'common/components/Toast'; +require('lib/webOSTVjs-1.2.10/webOSTV.js'); +require('lib/webOSTVjs-1.2.10/webOSTV-dev.js'); enum RemoteKeyCode { Stop = 413, @@ -12,116 +15,31 @@ enum RemoteKeyCode { } try { - const serviceId = 'com.futo.fcast.receiver.service'; + const startupStorageClearService = registerService('startup-storage-clear', () => { preloadData.onStartupStorageClearCb(); }); + const toastService = registerService('toast', (message: any) => { toast(message.value.message, message.value.icon, message.value.duration); }); + const getDeviceInfoService = registerService('getDeviceInfo', (message: any) => { + console.log(`Main: getDeviceInfo ${JSON.stringify(message)}`); + preloadData.deviceInfo = message.value; + preloadData.onDeviceInfoCb(); + }, false); + const onConnectService = registerService('connect', (message: any) => { preloadData.onConnectCb(null, message.value); }); + const onDisconnectService = registerService('disconnect', (message: any) => { preloadData.onDisconnectCb(null, message.value); }); + const playService = registerService('play', (message: any) => { + if (message.value !== undefined && message.value.playData !== undefined) { + console.log(`Main: Playing ${JSON.stringify(message)}`); + getDeviceInfoService.cancel(); + startupStorageClearService.cancel(); + toastService.cancel(); + onConnectService.cancel(); + onDisconnectService.cancel(); + playService.cancel(); - const startupStorageClearService = window.webOS.service.request(`luna://${serviceId}/`, { - method:"startup-storage-clear", - parameters: {}, - onSuccess: (message: any) => { - if (message.value.subscribed === true) { - console.log('Main: Registered startup-storage-clear handler with service'); - } - else { - preloadData.onStartupStorageClearCb(); - } - }, - onFailure: (message: any) => { - console.error(`Main: startup-storage-clear ${JSON.stringify(message)}`); - toast(`Main: startup-storage-clear ${JSON.stringify(message)}`, ToastIcon.ERROR); - }, - subscribe: true, - resubscribe: true - }); - - - const toastService = window.webOS.service.request(`luna://${serviceId}/`, { - method:"toast", - parameters: {}, - onSuccess: (message: any) => { - if (message.value.subscribed === true) { - console.log('Main: Registered toast handler with service'); - } - else { - toast(message.value.message, message.value.icon, message.value.duration); - } - }, - onFailure: (message: any) => { - console.error(`Main: toast ${JSON.stringify(message)}`); - toast(`Main: toast ${JSON.stringify(message)}`, ToastIcon.ERROR); - }, - subscribe: true, - resubscribe: true - }); - - const onConnectService = window.webOS.service.request(`luna://${serviceId}/`, { - method:"connect", - parameters: {}, - onSuccess: (message: any) => { - if (message.value.subscribed === true) { - console.log('Main: Registered connect handler with service'); - } - else { - preloadData.onConnectCb(null, message.value); - } - }, - onFailure: (message: any) => { - console.error(`Main: connect ${JSON.stringify(message)}`); - toast(`Main: connect ${JSON.stringify(message)}`, ToastIcon.ERROR); - }, - subscribe: true, - resubscribe: true - }); - - const onDisconnectService = window.webOS.service.request(`luna://${serviceId}/`, { - method:"disconnect", - parameters: {}, - onSuccess: (message: any) => { - if (message.value.subscribed === true) { - console.log('Main: Registered disconnect handler with service'); - } - else { - preloadData.onDisconnectCb(null, message.value); - } - }, - onFailure: (message: any) => { - console.error(`Main: disconnect ${JSON.stringify(message)}`); - toast(`Main: disconnect ${JSON.stringify(message)}`, ToastIcon.ERROR); - }, - subscribe: true, - resubscribe: true - }); - - const playService = window.webOS.service.request(`luna://${serviceId}/`, { - method:"play", - parameters: {}, - onSuccess: (message: any) => { - if (message.value.subscribed === true) { - console.log('Main: Registered play handler with service'); - } - else { - if (message.value !== undefined && message.value.playData !== undefined) { - console.log(`Main: Playing ${JSON.stringify(message)}`); - preloadData.getDeviceInfoService.cancel(); - startupStorageClearService.cancel(); - toastService.cancel(); - onConnectService.cancel(); - onDisconnectService.cancel(); - playService.cancel(); - - // WebOS 22 and earlier does not work well using the history API, - // so manually handling page navigation... - // history.pushState({}, '', '../main_window/index.html'); - window.open('../player/index.html'); - } - } - }, - onFailure: (message: any) => { - console.error(`Main: play ${JSON.stringify(message)}`); - toast(`Main: play ${JSON.stringify(message)}`, ToastIcon.ERROR); - }, - subscribe: true, - resubscribe: true - }); + // WebOS 22 and earlier does not work well using the history API, + // so manually handling page navigation... + // history.pushState({}, '', '../main_window/index.html'); + window.open('../player/index.html'); + } + }); const launchHandler = (args: any) => { // args don't seem to be passed in via event despite what documentation says... @@ -131,24 +49,12 @@ try { const lastTimestamp = localStorage.getItem('lastTimestamp'); if (params.playData !== undefined && params.timestamp != lastTimestamp) { localStorage.setItem('lastTimestamp', params.timestamp); - if (preloadData.getDeviceInfoService !== undefined) { - preloadData.getDeviceInfoService.cancel(); - } - if (startupStorageClearService !== undefined) { - startupStorageClearService.cancel(); - } - if (toastService !== undefined) { - toastService.cancel(); - } - if (onConnectService !== undefined) { - onConnectService.cancel(); - } - if (onDisconnectService !== undefined) { - onDisconnectService.cancel(); - } - if (playService !== undefined) { - playService.cancel(); - } + startupStorageClearService?.cancel(); + toastService?.cancel(); + getDeviceInfoService?.cancel(); + onConnectService?.cancel(); + onDisconnectService?.cancel(); + playService?.cancel(); // WebOS 22 and earlier does not work well using the history API, // so manually handling page navigation... @@ -183,3 +89,27 @@ catch (err) { console.error(`Main: preload ${JSON.stringify(err)}`); toast(`Main: preload ${JSON.stringify(err)}`, ToastIcon.ERROR); } + +function registerService(method: string, callback: (message: any) => void, subscribe: boolean = true): any { + const serviceId = 'com.futo.fcast.receiver.service'; + + return window.webOS.service.request(`luna://${serviceId}/`, { + method: method, + parameters: {}, + onSuccess: (message: any) => { + if (message.value.subscribed === true) { + console.log(`Main: Registered ${method} handler with service`); + } + else { + callback(message); + } + }, + onFailure: (message: any) => { + console.error(`Main: ${method} ${JSON.stringify(message)}`); + toast(`Main: ${method} ${JSON.stringify(message)}`, ToastIcon.ERROR); + }, + // onComplete: (message) => {}, + subscribe: subscribe, + resubscribe: subscribe + }); +} diff --git a/receivers/webos/fcast-receiver/src/player/Preload.ts b/receivers/webos/fcast-receiver/src/player/Preload.ts index 1588d0e..2cca473 100644 --- a/receivers/webos/fcast-receiver/src/player/Preload.ts +++ b/receivers/webos/fcast-receiver/src/player/Preload.ts @@ -1,46 +1,158 @@ +/* eslint-disable @typescript-eslint/no-require-imports */ /* eslint-disable @typescript-eslint/no-explicit-any */ import { preloadData } from 'common/player/Preload'; +import { PlaybackErrorMessage, PlaybackUpdateMessage, VolumeUpdateMessage } from 'common/Packets'; +import { toast, ToastIcon } from 'common/components/Toast'; +require('lib/webOSTVjs-1.2.10/webOSTV.js'); +require('lib/webOSTVjs-1.2.10/webOSTV-dev.js'); -const launchHandler = (args: any) => { - // args don't seem to be passed in via event despite what documentation says... - const params = window.webOSDev.launchParams(); - console.log(`Player: (Re)launching FCast Receiver with args: ${JSON.stringify(params)}`); +try { + const serviceId = 'com.futo.fcast.receiver.service'; + let playerWindowOpen = false; - const lastTimestamp = localStorage.getItem('lastTimestamp'); - if (params.playData !== undefined && params.timestamp != lastTimestamp) { - localStorage.setItem('lastTimestamp', params.timestamp); + window.webOSAPI = { + pendingPlay: null + }; - if (preloadData.playerWindowOpen !== undefined) { - preloadData.playerWindowOpen = false; - } - if (preloadData.playService !== undefined) { - preloadData.playService.cancel(); - } - if (preloadData.pauseService !== undefined) { - preloadData.pauseService.cancel(); - } - if (preloadData.resumeService !== undefined) { - preloadData.resumeService.cancel(); - } - if (preloadData.stopService !== undefined) { - preloadData.stopService.cancel(); - } - if (preloadData.seekService !== undefined) { - preloadData.seekService.cancel(); - } - if (preloadData.setVolumeService !== undefined) { - preloadData.setVolumeService.cancel(); - } - if (preloadData.setSpeedService !== undefined) { - preloadData.setSpeedService.cancel(); - } + preloadData.sendPlaybackErrorCb = (error: PlaybackErrorMessage) => { + window.webOS.service.request(`luna://${serviceId}/`, { + method: 'send_playback_error', + parameters: { error }, + onSuccess: () => {}, + onFailure: (message: any) => { + console.error(`Player: send_playback_error ${JSON.stringify(message)}`); + }, + }); + }; + preloadData.sendPlaybackUpdateCb = (update: PlaybackUpdateMessage) => { + window.webOS.service.request(`luna://${serviceId}/`, { + method: 'send_playback_update', + parameters: { update }, + // onSuccess: (message: any) => { + // console.log(`Player: send_playback_update ${JSON.stringify(message)}`); + // }, + onSuccess: () => {}, + onFailure: (message: any) => { + console.error(`Player: send_playback_update ${JSON.stringify(message)}`); + }, + }); + }; + preloadData.sendVolumeUpdateCb = (update: VolumeUpdateMessage) => { + window.webOS.service.request(`luna://${serviceId}/`, { + method: 'send_volume_update', + parameters: { update }, + onSuccess: () => {}, + onFailure: (message: any) => { + console.error(`Player: send_volume_update ${JSON.stringify(message)}`); + }, + }); + }; + + const playService = window.webOS.service.request(`luna://${serviceId}/`, { + method:"play", + parameters: {}, + onSuccess: (message: any) => { + // console.log(JSON.stringify(message)); + if (message.value.subscribed === true) { + console.log('Player: Registered play handler with service'); + } + + if (message.value.playData !== null) { + if (!playerWindowOpen) { + playerWindowOpen = true; + } + + if (preloadData.onPlayCb === undefined) { + window.webOSAPI.pendingPlay = message.value.playData; + } + else { + preloadData.onPlayCb(null, message.value.playData); + } + } + }, + onFailure: (message: any) => { + console.error(`Player: play ${JSON.stringify(message)}`); + }, + subscribe: true, + resubscribe: true + }); + + const pauseService = registerService('pause', () => { preloadData.onPauseCb(); }); + const resumeService = registerService('resume', () => { preloadData.onResumeCb(); }); + const stopService = registerService('stop', () => { + playerWindowOpen = false; + playService.cancel(); + pauseService.cancel(); + resumeService.cancel(); + stopService.cancel(); + seekService.cancel(); + setVolumeService.cancel(); + setSpeedService.cancel(); // WebOS 22 and earlier does not work well using the history API, // so manually handling page navigation... - // history.pushState({}, '', '../main_window/index.html'); - window.open('../player/index.html'); - } -}; + // history.back(); + window.open('../main_window/index.html'); + }); -document.addEventListener('webOSLaunch', (ags) => { console.log('lunch'); launchHandler(ags)}); -document.addEventListener('webOSRelaunch', (ags) => { console.log('relun'); launchHandler(ags)}); + const seekService = registerService('seek', (message: any) => { preloadData.onSeekCb(null, message.value); }); + const setVolumeService = registerService('setvolume', (message: any) => { preloadData.onSetVolumeCb(null, message.value); }); + const setSpeedService = registerService('setspeed', (message: any) => { preloadData.onSetSpeedCb(null, message.value); }); + + const launchHandler = (args: any) => { + // args don't seem to be passed in via event despite what documentation says... + const params = window.webOSDev.launchParams(); + console.log(`Player: (Re)launching FCast Receiver with args: ${JSON.stringify(params)}`); + + const lastTimestamp = localStorage.getItem('lastTimestamp'); + if (params.playData !== undefined && params.timestamp != lastTimestamp) { + localStorage.setItem('lastTimestamp', params.timestamp); + playerWindowOpen = false; + + playService?.cancel(); + pauseService?.cancel(); + resumeService?.cancel(); + stopService?.cancel(); + seekService?.cancel(); + setVolumeService?.cancel(); + setSpeedService?.cancel(); + + // WebOS 22 and earlier does not work well using the history API, + // so manually handling page navigation... + // history.pushState({}, '', '../main_window/index.html'); + window.open('../player/index.html'); + } + }; + + document.addEventListener('webOSLaunch', (ags) => { launchHandler(ags)}); + document.addEventListener('webOSRelaunch', (ags) => { launchHandler(ags)}); + +} +catch (err) { + console.error(`Player: preload ${JSON.stringify(err)}`); + toast(`Player: preload ${JSON.stringify(err)}`, ToastIcon.ERROR); +} + +function registerService(method: string, callback: (message: any) => void, subscribe: boolean = true): any { + const serviceId = 'com.futo.fcast.receiver.service'; + + return window.webOS.service.request(`luna://${serviceId}/`, { + method: method, + parameters: {}, + onSuccess: (message: any) => { + if (message.value.subscribed === true) { + console.log(`Player: Registered ${method} handler with service`); + } + else { + callback(message); + } + }, + onFailure: (message: any) => { + console.error(`Player: ${method} ${JSON.stringify(message)}`); + // toast(`Player: ${method} ${JSON.stringify(message)}`, ToastIcon.ERROR); + }, + // onComplete: (message) => {}, + subscribe: subscribe, + resubscribe: subscribe + }); +}