From d2bd49b36409a86cb6f6a9a2406fbd2dd590881e Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Sat, 18 Aug 2018 01:11:14 +0200 Subject: [PATCH] Sync changes on playback volume or state with events and web UI --- .../backend/http/static/css/widgets/music.css | 15 +++++++ .../backend/http/static/js/widgets/music.js | 41 +++++++++++++++++ .../backend/http/templates/widgets/music.html | 32 +++++++++++++ platypush/backend/music/mpd/__init__.py | 26 ++++++++++- platypush/message/event/music/__init__.py | 45 +++++++++++++++++++ 5 files changed, 158 insertions(+), 1 deletion(-) diff --git a/platypush/backend/http/static/css/widgets/music.css b/platypush/backend/http/static/css/widgets/music.css index bad32853..126c625f 100644 --- a/platypush/backend/http/static/css/widgets/music.css +++ b/platypush/backend/http/static/css/widgets/music.css @@ -1,4 +1,5 @@ .music-container { + position: relative; width: inherit; height: inherit; display: table-cell; @@ -51,3 +52,17 @@ font-size: 25px; } +.playback-status-container { + position: absolute; + bottom: 0; + width: 100%; + border-top: 1px solid #ddd; + padding: 1rem 0; + font-size: 1.22rem; + color: #757f70; +} + + .playback-status-container > .playback-status-values { + font-weight: bold; + } + diff --git a/platypush/backend/http/static/js/widgets/music.js b/platypush/backend/http/static/js/widgets/music.js index 24d5c2a7..866ffa18 100644 --- a/platypush/backend/http/static/js/widgets/music.js +++ b/platypush/backend/http/static/js/widgets/music.js @@ -2,6 +2,7 @@ $(document).ready(function() { var $widget = $('.widget.music'), $trackContainer = $widget.find('.track-container'), $timeContainer = $widget.find('.time-container'), + $playbackStatusContainer = $widget.find('.playback-status-container'), $noTrackElement = $trackContainer.find('.no-track-info'), $trackElement = $trackContainer.find('.track-info'), $artistElement = $trackElement.find('[data-bind=artist]'), @@ -9,6 +10,11 @@ $(document).ready(function() { $timeElapsedElement = $timeContainer.find('.time-elapsed'), $timeTotalElement = $timeContainer.find('.time-total'), $elapsedTimeBar = $widget.find('.time-bar > .elapsed'), + $volumeElement = $playbackStatusContainer.find('[data-bind=playback-volume]'), + $randomElement = $playbackStatusContainer.find('[data-bind=playback-random]'), + $repeatElement = $playbackStatusContainer.find('[data-bind=playback-repeat]'), + $singleElement = $playbackStatusContainer.find('[data-bind=playback-single]'), + $consumeElement = $playbackStatusContainer.find('[data-bind=playback-consume]'), timeElapsed, timeTotal, refreshElapsedInterval; @@ -30,6 +36,14 @@ $(document).ready(function() { case 'platypush.message.event.music.MusicStopEvent': refreshStatus(event.args.status); break; + + case 'platypush.message.event.music.VolumeChangeEvent': + case 'platypush.message.event.music.PlaybackRepeatModeChangeEvent': + case 'platypush.message.event.music.PlaybackRandomModeChangeEvent': + case 'platypush.message.event.music.PlaybackConsumeModeChangeEvent': + case 'platypush.message.event.music.PlaybackSingleModeChangeEvent': + refreshPlaybackStatus(event.args.status); + break; } }; @@ -103,6 +117,32 @@ $(document).ready(function() { $titleElement.text(track.title); }; + var refreshPlaybackStatus = function(status) { + if ('volume' in status) { + $volumeElement.text(status.volume + '%'); + } + + if ('random' in status) { + var state = !!parseInt(status.random); + $randomElement.text(state ? 'ON' : 'OFF'); + } + + if ('repeat' in status) { + var state = !!parseInt(status.repeat); + $repeatElement.text(state ? 'ON' : 'OFF'); + } + + if ('single' in status) { + var state = !!parseInt(status.single); + $singleElement.text(state ? 'ON' : 'OFF'); + } + + if ('consume' in status) { + var state = !!parseInt(status.consume); + $consumeElement.text(state ? 'ON' : 'OFF'); + } + }; + var initWidget = function() { $.when( execute({ type: 'request', action: 'music.mpd.currentsong' }), @@ -110,6 +150,7 @@ $(document).ready(function() { ).done(function(t, s) { refreshTrack(t[0].response.output); refreshStatus(s[0].response.output); + refreshPlaybackStatus(s[0].response.output); }); }; diff --git a/platypush/backend/http/templates/widgets/music.html b/platypush/backend/http/templates/widgets/music.html index 61f065f0..40e64f9c 100644 --- a/platypush/backend/http/templates/widgets/music.html +++ b/platypush/backend/http/templates/widgets/music.html @@ -27,5 +27,37 @@ + +
+
+
Volume
+
Random
+
Repeat
+
Single
+
Consume
+
+ +
+
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+
+
diff --git a/platypush/backend/music/mpd/__init__.py b/platypush/backend/music/mpd/__init__.py index 6d42c533..ec9f543b 100644 --- a/platypush/backend/music/mpd/__init__.py +++ b/platypush/backend/music/mpd/__init__.py @@ -4,7 +4,9 @@ import time from platypush.backend import Backend from platypush.context import get_plugin from platypush.message.event.music import MusicPlayEvent, MusicPauseEvent, \ - MusicStopEvent, NewPlayingTrackEvent, PlaylistChangeEvent + MusicStopEvent, NewPlayingTrackEvent, PlaylistChangeEvent, VolumeChangeEvent, \ + PlaybackConsumeModeChangeEvent, PlaybackSingleModeChangeEvent, \ + PlaybackRepeatModeChangeEvent, PlaybackRandomModeChangeEvent class MusicMpdBackend(Backend): @@ -40,6 +42,7 @@ class MusicMpdBackend(Backend): def run(self): super().run() + last_status = {} last_state = None last_track = None last_playlist = None @@ -79,6 +82,27 @@ class MusicMpdBackend(Backend): if state == 'play' and track != last_track: self.bus.post(NewPlayingTrackEvent(status=status, track=track)) + if last_status.get('volume', None) != status['volume']: + self.bus.post(VolumeChangeEvent( + volume=int(status['volume']), status=status, track=track)) + + if last_status.get('random', None) != status['random']: + self.bus.post(PlaybackRandomModeChangeEvent( + state=bool(int(status['random'])), status=status, track=track)) + + if last_status.get('repeat', None) != status['repeat']: + self.bus.post(PlaybackRepeatModeChangeEvent( + state=bool(int(status['repeat'])), status=status, track=track)) + + if last_status.get('consume', None) != status['consume']: + self.bus.post(PlaybackConsumeModeChangeEvent( + state=bool(int(status['consume'])), status=status, track=track)) + + if last_status.get('single', None) != status['single']: + self.bus.post(PlaybackSingleModeChangeEvent( + state=bool(int(status['single'])), status=status, track=track)) + + last_status = status last_state = state last_track = track time.sleep(self.poll_seconds) diff --git a/platypush/message/event/music/__init__.py b/platypush/message/event/music/__init__.py index 32979d0e..d1ebc39d 100644 --- a/platypush/message/event/music/__init__.py +++ b/platypush/message/event/music/__init__.py @@ -43,6 +43,51 @@ class MusicPauseEvent(MusicEvent): super().__init__(*args, **kwargs) +class VolumeChangeEvent(MusicEvent): + """ + Event fired upon volume change + """ + + def __init__(self, volume, status=None, track=None, *args, **kwargs): + super().__init__(volume=volume, status=status, track=track, *args, **kwargs) + + +class PlaybackRepeatModeChangeEvent(MusicEvent): + """ + Event fired upon repeat mode change + """ + + def __init__(self, state, status=None, track=None, *args, **kwargs): + super().__init__(state=state, status=status, track=track, *args, **kwargs) + + +class PlaybackRandomModeChangeEvent(MusicEvent): + """ + Event fired upon random mode change + """ + + def __init__(self, state, status=None, track=None, *args, **kwargs): + super().__init__(state=state, status=status, track=track, *args, **kwargs) + + +class PlaybackConsumeModeChangeEvent(MusicEvent): + """ + Event fired upon consume mode change + """ + + def __init__(self, state, status=None, track=None, *args, **kwargs): + super().__init__(state=state, status=status, track=track, *args, **kwargs) + + +class PlaybackSingleModeChangeEvent(MusicEvent): + """ + Event fired upon single mode change + """ + + def __init__(self, state, status=None, track=None, *args, **kwargs): + super().__init__(state=state, status=status, track=track, *args, **kwargs) + + class PlaylistChangeEvent(MusicEvent): """ Event fired upon playlist change