From 25b5b0dd2933ce5ee45132fe8eec314df3cf5f64 Mon Sep 17 00:00:00 2001 From: Damian Kacperski <7dami77@gmail.com> Date: Tue, 9 Jan 2024 18:38:19 +0100 Subject: [PATCH 1/2] Move btnPlayPause from remotecontrol to separate component --- src/components/remotecontrol/btnPlayPause.js | 130 ++++++++++++++++++ src/components/remotecontrol/remotecontrol.js | 35 +---- 2 files changed, 135 insertions(+), 30 deletions(-) create mode 100644 src/components/remotecontrol/btnPlayPause.js diff --git a/src/components/remotecontrol/btnPlayPause.js b/src/components/remotecontrol/btnPlayPause.js new file mode 100644 index 000000000000..51bb856c0d24 --- /dev/null +++ b/src/components/remotecontrol/btnPlayPause.js @@ -0,0 +1,130 @@ +import { playbackManager } from 'components/playback/playbackmanager'; +import Events from '../../utils/events.ts'; + +function buttonVisible(btn, enabled) { + if (enabled) { + btn.classList.remove('hide'); + } else { + btn.classList.add('hide'); + } +} + +export default function () { + function updatePlayerState(player, context, state) { + const item = state.NowPlayingItem; + const playState = state.PlayState || {}; + + updatePlayPauseState(playState.IsPaused, item != null); + } + + function updatePlayPauseState(isPaused, isActive) { + const context = dlg; + const btnPlayPause = context.querySelector('.btnPlayPause'); + const btnPlayPauseIcon = btnPlayPause.querySelector('.material-icons'); + + btnPlayPauseIcon.classList.remove('play_circle_filled', 'pause_circle_filled'); + btnPlayPauseIcon.classList.add(isPaused ? 'play_circle_filled' : 'pause_circle_filled'); + + const playlistIndicator = context.querySelector('.playlistIndexIndicatorImage'); + if (playlistIndicator) { + playlistIndicator.classList.toggle('playlistIndexIndicatorPausedImage', isPaused); + } + + buttonVisible(btnPlayPause, isActive); + } + + function onPlaybackStart(e, state) { + const player = this; + onStateChanged.call(player, e, state); + } + + function onPlaybackStopped(e, state) { + const player = this; + + if (!state.NextMediaType) { + updatePlayerState(player, dlg, {}); + } + } + + function onPlayPauseStateChanged() { + updatePlayPauseState(this.paused(), true); + } + + function onStateChanged(event, state) { + const player = this; + updatePlayerState(player, dlg, state); + } + + function releaseCurrentPlayer() { + const player = currentPlayer; + + if (player) { + Events.off(player, 'playbackstart', onPlaybackStart); + Events.off(player, 'statechange', onStateChanged); + Events.off(player, 'playbackstop', onPlaybackStopped); + Events.off(player, 'pause', onPlayPauseStateChanged); + Events.off(player, 'unpause', onPlayPauseStateChanged); + currentPlayer = null; + } + } + + function bindToPlayer(context, player) { + releaseCurrentPlayer(); + currentPlayer = player; + + if (player) { + const state = playbackManager.getPlayerState(player); + onStateChanged.call(player, { + type: 'init' + }, state); + Events.on(player, 'playbackstart', onPlaybackStart); + Events.on(player, 'statechange', onStateChanged); + Events.on(player, 'playbackstop', onPlaybackStopped); + Events.on(player, 'pause', onPlayPauseStateChanged); + Events.on(player, 'unpause', onPlayPauseStateChanged); + } + } + + function bindEvents(context) { + context.querySelector('.btnPlayPause').addEventListener('click', function () { + if (currentPlayer) { + playbackManager.playPause(currentPlayer); + } + }); + } + + function onPlayerChange() { + bindToPlayer(dlg, playbackManager.getCurrentPlayer()); + } + + function init(ownerView, context) { + bindEvents(context); + Events.on(playbackManager, 'playerchange', onPlayerChange); + } + + function onDialogClosed() { + releaseCurrentPlayer(); + Events.off(playbackManager, 'playerchange', onPlayerChange); + } + + function onShow(context) { + bindToPlayer(context, playbackManager.getCurrentPlayer()); + } + + let dlg; + let currentPlayer; + const self = this; + + self.init = function (ownerView, context) { + dlg = context; + init(ownerView, dlg); + }; + + self.onShow = function () { + onShow(dlg); + }; + + self.destroy = function () { + onDialogClosed(); + }; +} diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index 99862a4ce965..f7e25954f42e 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -22,6 +22,7 @@ import ServerConnections from '../ServerConnections'; import toast from '../toast/toast'; import { appRouter } from '../router/appRouter'; import { getDefaultBackgroundClass } from '../cardbuilder/cardBuilderUtils'; +import BtnPlayPause from './btnPlayPause'; let showMuteButton = true; let showVolumeSlider = true; @@ -353,7 +354,6 @@ export default function () { positionSlider.setIsClear(isProgressClear); } - updatePlayPauseState(playState.IsPaused, item != null); updateTimeDisplay(playState.PositionTicks, item ? item.RunTimeTicks : null); updatePlayerVolumeState(context, playState.IsMuted, playState.VolumeLevel); @@ -451,22 +451,6 @@ export default function () { } } - function updatePlayPauseState(isPaused, isActive) { - const context = dlg; - const btnPlayPause = context.querySelector('.btnPlayPause'); - const btnPlayPauseIcon = btnPlayPause.querySelector('.material-icons'); - - btnPlayPauseIcon.classList.remove('play_circle_filled', 'pause_circle_filled'); - btnPlayPauseIcon.classList.add(isPaused ? 'play_circle_filled' : 'pause_circle_filled'); - - const playlistIndicator = context.querySelector('.playlistIndexIndicatorImage'); - if (playlistIndicator) { - playlistIndicator.classList.toggle('playlistIndexIndicatorPausedImage', isPaused); - } - - buttonVisible(btnPlayPause, isActive); - } - function updateTimeDisplay(positionTicks, runtimeTicks) { const context = dlg; const positionSlider = context.querySelector('.nowPlayingPositionSlider'); @@ -606,10 +590,6 @@ export default function () { } } - function onPlayPauseStateChanged() { - updatePlayPauseState(this.paused(), true); - } - function onStateChanged(event, state) { const player = this; updatePlayerState(player, dlg, state); @@ -645,8 +625,6 @@ export default function () { Events.off(player, 'playlistitemadd', onPlaylistUpdate); Events.off(player, 'playbackstop', onPlaybackStopped); Events.off(player, 'volumechange', onVolumeChanged); - Events.off(player, 'pause', onPlayPauseStateChanged); - Events.off(player, 'unpause', onPlayPauseStateChanged); Events.off(player, 'timeupdate', onTimeUpdate); currentPlayer = null; } @@ -670,8 +648,6 @@ export default function () { Events.on(player, 'playlistitemadd', onPlaylistUpdate); Events.on(player, 'playbackstop', onPlaybackStopped); Events.on(player, 'volumechange', onVolumeChanged); - Events.on(player, 'pause', onPlayPauseStateChanged); - Events.on(player, 'unpause', onPlayPauseStateChanged); Events.on(player, 'timeupdate', onTimeUpdate); const playerInfo = playbackManager.getPlayerInfo(); const supportedCommands = playerInfo.supportedCommands; @@ -744,11 +720,6 @@ export default function () { playbackManager.stop(currentPlayer); } }); - context.querySelector('.btnPlayPause').addEventListener('click', function () { - if (currentPlayer) { - playbackManager.playPause(currentPlayer); - } - }); context.querySelector('.btnNextTrack').addEventListener('click', function () { if (currentPlayer) { playbackManager.nextTrack(currentPlayer); @@ -949,18 +920,22 @@ export default function () { let currentPlayerSupportedCommands = []; let lastUpdateTime = 0; let currentRuntimeTicks = 0; + const btnPlayPause = new BtnPlayPause(); const self = this; self.init = function (ownerView, context) { dlg = context; init(ownerView, dlg); + btnPlayPause.init(ownerView, context); }; self.onShow = function () { onShow(dlg); + btnPlayPause.onShow(); }; self.destroy = function () { onDialogClosed(); + btnPlayPause.destroy(); }; } From 7fea3d3d2627ac4a6e4f65d010e1a4759f25d855 Mon Sep 17 00:00:00 2001 From: Damian Kacperski <7dami77@gmail.com> Date: Tue, 9 Jan 2024 18:43:25 +0100 Subject: [PATCH 2/2] Move events from btnPlayPause that should be watched by the parent --- src/components/remotecontrol/btnPlayPause.js | 51 +++++++------------ src/components/remotecontrol/remotecontrol.js | 6 ++- 2 files changed, 22 insertions(+), 35 deletions(-) diff --git a/src/components/remotecontrol/btnPlayPause.js b/src/components/remotecontrol/btnPlayPause.js index 51bb856c0d24..1e7fc9764eff 100644 --- a/src/components/remotecontrol/btnPlayPause.js +++ b/src/components/remotecontrol/btnPlayPause.js @@ -33,35 +33,14 @@ export default function () { buttonVisible(btnPlayPause, isActive); } - function onPlaybackStart(e, state) { - const player = this; - onStateChanged.call(player, e, state); - } - - function onPlaybackStopped(e, state) { - const player = this; - - if (!state.NextMediaType) { - updatePlayerState(player, dlg, {}); - } - } - function onPlayPauseStateChanged() { updatePlayPauseState(this.paused(), true); } - function onStateChanged(event, state) { - const player = this; - updatePlayerState(player, dlg, state); - } - function releaseCurrentPlayer() { const player = currentPlayer; if (player) { - Events.off(player, 'playbackstart', onPlaybackStart); - Events.off(player, 'statechange', onStateChanged); - Events.off(player, 'playbackstop', onPlaybackStopped); Events.off(player, 'pause', onPlayPauseStateChanged); Events.off(player, 'unpause', onPlayPauseStateChanged); currentPlayer = null; @@ -73,13 +52,6 @@ export default function () { currentPlayer = player; if (player) { - const state = playbackManager.getPlayerState(player); - onStateChanged.call(player, { - type: 'init' - }, state); - Events.on(player, 'playbackstart', onPlaybackStart); - Events.on(player, 'statechange', onStateChanged); - Events.on(player, 'playbackstop', onPlaybackStopped); Events.on(player, 'pause', onPlayPauseStateChanged); Events.on(player, 'unpause', onPlayPauseStateChanged); } @@ -93,18 +65,12 @@ export default function () { }); } - function onPlayerChange() { - bindToPlayer(dlg, playbackManager.getCurrentPlayer()); - } - function init(ownerView, context) { bindEvents(context); - Events.on(playbackManager, 'playerchange', onPlayerChange); } function onDialogClosed() { releaseCurrentPlayer(); - Events.off(playbackManager, 'playerchange', onPlayerChange); } function onShow(context) { @@ -115,6 +81,23 @@ export default function () { let currentPlayer; const self = this; + self.onPlaybackStopped = function (e, state) { + const player = this; + + if (!state.NextMediaType) { + updatePlayerState(player, dlg, {}); + } + }; + + self.onStateChanged = function (event, state) { + const player = this; + updatePlayerState(player, dlg, state); + }; + + self.onPlayerChange = function (context, player) { + bindToPlayer(context, player); + }; + self.init = function (ownerView, context) { dlg = context; init(ownerView, dlg); diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index f7e25954f42e..c74ea63c5f91 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -584,6 +584,7 @@ export default function () { console.debug('remotecontrol event: ' + e.type); const player = this; + btnPlayPause.onPlaybackStopped(e, state); if (!state.NextMediaType) { updatePlayerState(player, dlg, {}); appRouter.back(); @@ -594,6 +595,7 @@ export default function () { const player = this; updatePlayerState(player, dlg, state); onPlaylistUpdate(); + btnPlayPause.onStateChanged(event, state); } function onTimeUpdate() { @@ -833,7 +835,9 @@ export default function () { } function onPlayerChange() { - bindToPlayer(dlg, playbackManager.getCurrentPlayer()); + const player = playbackManager.getCurrentPlayer(); + bindToPlayer(dlg, player); + btnPlayPause.onPlayerChange(dlg, player); } function onMessageSubmit(e) {