From 180515f3f6f65d1229f1563537f99bcf5139ae14 Mon Sep 17 00:00:00 2001 From: pabera <1260686+pabera@users.noreply.github.com> Date: Mon, 25 Dec 2023 13:09:03 +0100 Subject: [PATCH 01/17] Adding additional player controls to assign to cards --- src/webapp/public/locales/de/translation.json | 9 ++++++++- src/webapp/public/locales/en/translation.json | 9 ++++++++- src/webapp/src/commands/index.js | 5 +++++ src/webapp/src/config.js | 9 ++++++++- 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/src/webapp/public/locales/de/translation.json b/src/webapp/public/locales/de/translation.json index 85d39b879..c872c6070 100644 --- a/src/webapp/public/locales/de/translation.json +++ b/src/webapp/public/locales/de/translation.json @@ -23,7 +23,14 @@ "timer_fade_volume": "Fade volume", "toggle_output": "Audio-Ausgang umschalten", "sync_rfidcards_all": "Alle Audiodateien und Karteneinträge synchronisieren", - "sync_rfidcards_change_on_rfid_scan": "Aktivierung ändern für 'on RFID scan' " + "sync_rfidcards_change_on_rfid_scan": "Aktivierung ändern für 'on RFID scan'", + "next": "Nächter Song", + "pause": "Pause", + "play": "Abspielen", + "previous": "Vorheriger Song", + "shuffle": "Shuffle aktivieren/deaktivieren", + "repeat": "Wiederholen aktivieren/deaktivieren", + "toggle": "Abspielen/Pause" } }, "controls-selector": { diff --git a/src/webapp/public/locales/en/translation.json b/src/webapp/public/locales/en/translation.json index d03941eb6..06e84fbf1 100644 --- a/src/webapp/public/locales/en/translation.json +++ b/src/webapp/public/locales/en/translation.json @@ -23,7 +23,14 @@ "timer_fade_volume": "Fade volume", "toggle_output": "Toggle audio output", "sync_rfidcards_all": "Sync all audiofiles and card entries", - "sync_rfidcards_change_on_rfid_scan": "Change activation of 'on RFID scan'" + "sync_rfidcards_change_on_rfid_scan": "Change activation of 'on RFID scan'", + "next": "Next song", + "pause": "Pause", + "play": "Play", + "previous": "Pevious song", + "shuffle": "Toggle Shuffle", + "repeat": "Toggle Repeat", + "toggle": "Toggle Play/Pause" } }, "controls-selector": { diff --git a/src/webapp/src/commands/index.js b/src/webapp/src/commands/index.js index bd8fd782e..ccadbe4cb 100644 --- a/src/webapp/src/commands/index.js +++ b/src/webapp/src/commands/index.js @@ -87,6 +87,11 @@ const commands = { plugin: 'ctrl', method: 'next', }, + toggle: { + _package: 'player', + plugin: 'ctrl', + method: 'toggle', + }, shuffle: { _package: 'player', plugin: 'ctrl', diff --git a/src/webapp/src/config.js b/src/webapp/src/config.js index 35b5a980e..e0d8615c4 100644 --- a/src/webapp/src/config.js +++ b/src/webapp/src/config.js @@ -42,7 +42,14 @@ const JUKEBOX_ACTIONS_MAP = { audio: { commands: { change_volume: {}, - toggle_output: {} + toggle_output: {}, + play: {}, + pause: {}, + toggle: {}, + next: {}, + previous: {}, + shuffle: {}, + repeat: {} }, }, From 41d43f291179062243b0de2ffaeb7d6fd32c9f4d Mon Sep 17 00:00:00 2001 From: pabera <1260686+pabera@users.noreply.github.com> Date: Mon, 25 Dec 2023 22:45:55 +0100 Subject: [PATCH 02/17] streamline some RPC command namings across jukebox and webapp --- src/webapp/public/locales/de/translation.json | 4 ++-- src/webapp/public/locales/en/translation.json | 9 +++++---- src/webapp/src/commands/index.js | 6 +++--- src/webapp/src/components/Player/controls.js | 16 ++++++++-------- src/webapp/src/config.js | 4 ++-- 5 files changed, 20 insertions(+), 19 deletions(-) diff --git a/src/webapp/public/locales/de/translation.json b/src/webapp/public/locales/de/translation.json index c872c6070..571b38f70 100644 --- a/src/webapp/public/locales/de/translation.json +++ b/src/webapp/public/locales/de/translation.json @@ -148,10 +148,10 @@ "activate": "Shuffle aktivieren", "deactivate": "Shuffle deaktivieren" }, - "skip": "Zurück", + "prev_song": "Zurück", "play": "Abspielen", "pause": "Pause", - "next": "Weiter", + "next_song": "Weiter", "repeat": { "activate": "Wiederholen aktivieren", "activate-single": "1 Wiederholen aktivieren", diff --git a/src/webapp/public/locales/en/translation.json b/src/webapp/public/locales/en/translation.json index 06e84fbf1..bce819823 100644 --- a/src/webapp/public/locales/en/translation.json +++ b/src/webapp/public/locales/en/translation.json @@ -24,10 +24,10 @@ "toggle_output": "Toggle audio output", "sync_rfidcards_all": "Sync all audiofiles and card entries", "sync_rfidcards_change_on_rfid_scan": "Change activation of 'on RFID scan'", - "next": "Next song", + "next_song": "Next song", "pause": "Pause", "play": "Play", - "previous": "Pevious song", + "prev_song": "Pevious song", "shuffle": "Toggle Shuffle", "repeat": "Toggle Repeat", "toggle": "Toggle Play/Pause" @@ -148,10 +148,10 @@ "activate": "Activate shuffle", "deactivate": "Deactivate shuffle" }, - "skip": "Skip previous track", + "prev_song": "Skip to previous track", "play": "Play", "pause": "Pause", - "next": "Skip next track", + "next_song": "Skip to next track", "repeat": { "activate": "Activate repeat", "activate-single": "Activate single repeat", @@ -214,6 +214,7 @@ }, "secondswipe": { "title": "Second Swipe", + "description": "Second action after the same card swiped again", "restart": "Restart playlist", "toggle": "Toggle pause / play", "skip": "Skip to next track", diff --git a/src/webapp/src/commands/index.js b/src/webapp/src/commands/index.js index ccadbe4cb..7c7d00c5f 100644 --- a/src/webapp/src/commands/index.js +++ b/src/webapp/src/commands/index.js @@ -17,7 +17,7 @@ const commands = { songList: { _package: 'player', plugin: 'ctrl', - method: 'list_song_by_artist_and_album', + method: 'list_songs_by_artist_and_album', }, getSongByUrl: { _package: 'player', @@ -77,12 +77,12 @@ const commands = { plugin: 'ctrl', method: 'pause', }, - previous: { + prev_song: { _package: 'player', plugin: 'ctrl', method: 'prev', }, - next: { + next_song: { _package: 'player', plugin: 'ctrl', method: 'next', diff --git a/src/webapp/src/components/Player/controls.js b/src/webapp/src/components/Player/controls.js index dc433cef8..8e071a501 100644 --- a/src/webapp/src/components/Player/controls.js +++ b/src/webapp/src/components/Player/controls.js @@ -89,14 +89,14 @@ const Controls = () => { - {/* Skip previous track */} + {/* Skip to previous song */} request('previous')} + onClick={e => request('prev_song')} size="large" sx={iconStyles} - title={t('player.controls.skip')} + title={t('player.controls.prev_song')} > @@ -127,14 +127,14 @@ const Controls = () => { } - {/* Skip next track */} + {/* Skip to next song */} request('next')} + onClick={e => request('next_song')} size="large" sx={iconStyles} - title={t('player.controls.next')} + title={t('player.controls.next_song')} > diff --git a/src/webapp/src/config.js b/src/webapp/src/config.js index e0d8615c4..9d317b8d0 100644 --- a/src/webapp/src/config.js +++ b/src/webapp/src/config.js @@ -46,8 +46,8 @@ const JUKEBOX_ACTIONS_MAP = { play: {}, pause: {}, toggle: {}, - next: {}, - previous: {}, + next_song: {}, + prev_song: {}, shuffle: {}, repeat: {} }, From 0e7a31816f8ea535df5c0e5b31e6046c05f68c9b Mon Sep 17 00:00:00 2001 From: pabera <1260686+pabera@users.noreply.github.com> Date: Tue, 26 Dec 2023 00:24:40 +0100 Subject: [PATCH 03/17] Fix typos --- src/webapp/public/locales/de/translation.json | 2 +- src/webapp/public/locales/en/translation.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/webapp/public/locales/de/translation.json b/src/webapp/public/locales/de/translation.json index 571b38f70..9e84beceb 100644 --- a/src/webapp/public/locales/de/translation.json +++ b/src/webapp/public/locales/de/translation.json @@ -24,7 +24,7 @@ "toggle_output": "Audio-Ausgang umschalten", "sync_rfidcards_all": "Alle Audiodateien und Karteneinträge synchronisieren", "sync_rfidcards_change_on_rfid_scan": "Aktivierung ändern für 'on RFID scan'", - "next": "Nächter Song", + "next": "Nächster Song", "pause": "Pause", "play": "Abspielen", "previous": "Vorheriger Song", diff --git a/src/webapp/public/locales/en/translation.json b/src/webapp/public/locales/en/translation.json index bce819823..8149267d5 100644 --- a/src/webapp/public/locales/en/translation.json +++ b/src/webapp/public/locales/en/translation.json @@ -27,7 +27,7 @@ "next_song": "Next song", "pause": "Pause", "play": "Play", - "prev_song": "Pevious song", + "prev_song": "Previous song", "shuffle": "Toggle Shuffle", "repeat": "Toggle Repeat", "toggle": "Toggle Play/Pause" From cfc4d205e58d29476f641ce2aec55fef7c9d5fe2 Mon Sep 17 00:00:00 2001 From: pabera <1260686+pabera@users.noreply.github.com> Date: Sun, 31 Dec 2023 01:15:54 +0100 Subject: [PATCH 04/17] Fix Repeat toggles --- documentation/developers/docker.md | 15 ++++++++++++++- src/jukebox/components/playermpd/__init__.py | 15 ++++++++++++++- src/jukebox/components/rpc_command_alias.py | 12 +++++++++--- src/webapp/public/locales/de/translation.json | 9 +++++---- src/webapp/public/locales/en/translation.json | 5 +++-- src/webapp/src/commands/index.js | 2 +- src/webapp/src/components/Player/controls.js | 2 +- src/webapp/src/config.js | 3 ++- 8 files changed, 49 insertions(+), 14 deletions(-) diff --git a/documentation/developers/docker.md b/documentation/developers/docker.md index 79c2ada2a..c261fe1ec 100644 --- a/documentation/developers/docker.md +++ b/documentation/developers/docker.md @@ -47,7 +47,20 @@ They can be run individually or in combination. To do that, we use ### Mac 1. [Install Docker & Compose (Mac)](https://docs.docker.com/docker-for-mac/install/) -2. [Install pulseaudio](https://gist.github.com/seongyongkim/b7d630a03e74c7ab1c6b53473b592712) (Other references: [[1]](https://devops.datenkollektiv.de/running-a-docker-soundbox-on-mac.html), [[2]](https://stackoverflow.com/a/50939994/1062438)) +2. Install pulseaudio + 1. Use Homebrew to install + ``` + $ brew install pulseaudio + ``` + 2. Enable pulseaudio network capabilities. In an editor, open `/opt/homebrew/Cellar/pulseaudio/16.1/etc/pulse/default.pa` (you might need to adapt this path to your own system settings). Uncomment the following line. + ``` + load-module module-native-protocol-tcp + ``` + 3. Restart the pulseaudio service + ``` + $ brew services restart pulseaudio + ``` + 4. If you have trouble with your audio, try these resources to troubleshoot: [[1]](https://gist.github.com/seongyongkim/b7d630a03e74c7ab1c6b53473b592712), [[2]](https://devops.datenkollektiv.de/running-a-docker-soundbox-on-mac.html), [[3]](https://stackoverflow.com/a/50939994/1062438) ``` bash // Build Images diff --git a/src/jukebox/components/playermpd/__init__.py b/src/jukebox/components/playermpd/__init__.py index e854ee5ee..12548599d 100644 --- a/src/jukebox/components/playermpd/__init__.py +++ b/src/jukebox/components/playermpd/__init__.py @@ -363,7 +363,6 @@ def replay(self): @plugs.tag def toggle(self): """Toggle pause state, i.e. do a pause / resume depending on current state""" - logger.debug("Toggle") with self.mpd_lock: self.mpd_client.pause() @@ -394,6 +393,20 @@ def repeatmode(self, mode): self.mpd_client.repeat(repeat) self.mpd_client.single(single) + @plugs.tag + def toggle_repeat(self): + if self.mpd_status['repeat'] == '0': + self.repeatmode('repeat') + else: + self.repeatmode(None) + + @plugs.tag + def toggle_repeat_single(self): + if self.mpd_status['single'] == '0': + self.repeatmode('single') + else: + self.repeatmode(None) + @plugs.tag def get_current_song(self, param): return self.mpd_status diff --git a/src/jukebox/components/rpc_command_alias.py b/src/jukebox/components/rpc_command_alias.py index 2c722b0c0..039b10373 100644 --- a/src/jukebox/components/rpc_command_alias.py +++ b/src/jukebox/components/rpc_command_alias.py @@ -69,11 +69,17 @@ 'method': 'shuffle', 'note': 'Toggles Shuffle', 'ignore_card_removal_action': True}, - 'repeat': { + 'toggle_repeat': { 'package': 'player', 'plugin': 'ctrl', - 'method': 'repeat', - 'note': 'Switches Repeat option', + 'method': 'toggle_repeat', + 'note': 'Toggles repeat option', + 'ignore_card_removal_action': True}, + 'toggle_repeat_single': { + 'package': 'player', + 'plugin': 'ctrl', + 'method': 'toggle_repeat_single', + 'note': 'Toggles single repeat option', 'ignore_card_removal_action': True}, # VOLUME diff --git a/src/webapp/public/locales/de/translation.json b/src/webapp/public/locales/de/translation.json index 9e84beceb..00973aba7 100644 --- a/src/webapp/public/locales/de/translation.json +++ b/src/webapp/public/locales/de/translation.json @@ -24,13 +24,14 @@ "toggle_output": "Audio-Ausgang umschalten", "sync_rfidcards_all": "Alle Audiodateien und Karteneinträge synchronisieren", "sync_rfidcards_change_on_rfid_scan": "Aktivierung ändern für 'on RFID scan'", - "next": "Nächster Song", + "next_song": "Nächster Song", "pause": "Pause", "play": "Abspielen", - "previous": "Vorheriger Song", + "prev_song": "Vorheriger Song", "shuffle": "Shuffle aktivieren/deaktivieren", - "repeat": "Wiederholen aktivieren/deaktivieren", - "toggle": "Abspielen/Pause" + "toggle_repeat": "Wiederholen aktivieren/deaktivieren", + "toggle_repeat_single": "1 wiederholen aktivieren/deaktivieren", + "toggle": "Abspielen/Pause umschalten" } }, "controls-selector": { diff --git a/src/webapp/public/locales/en/translation.json b/src/webapp/public/locales/en/translation.json index 8149267d5..1a2ee568c 100644 --- a/src/webapp/public/locales/en/translation.json +++ b/src/webapp/public/locales/en/translation.json @@ -28,8 +28,9 @@ "pause": "Pause", "play": "Play", "prev_song": "Previous song", - "shuffle": "Toggle Shuffle", - "repeat": "Toggle Repeat", + "shuffle": "Toggle shuffle", + "toggle_repeat": "Toggle repeat", + "toggle_repeat_single": "Toggle single repeat", "toggle": "Toggle Play/Pause" } }, diff --git a/src/webapp/src/commands/index.js b/src/webapp/src/commands/index.js index 095cdd954..d8911c4ab 100644 --- a/src/webapp/src/commands/index.js +++ b/src/webapp/src/commands/index.js @@ -102,7 +102,7 @@ const commands = { plugin: 'ctrl', method: 'shuffle', }, - repeat: { + repeatmode: { _package: 'player', plugin: 'ctrl', method: 'repeatmode', diff --git a/src/webapp/src/components/Player/controls.js b/src/webapp/src/components/Player/controls.js index 8e071a501..d50be06d9 100644 --- a/src/webapp/src/components/Player/controls.js +++ b/src/webapp/src/components/Player/controls.js @@ -40,7 +40,7 @@ const Controls = () => { if (!isRepeat && !isSingle) mode = 'repeat'; if (isRepeat && !isSingle) mode = 'single'; - request('repeat', { mode }); + request('repeatmode', { mode }); } useEffect(() => { diff --git a/src/webapp/src/config.js b/src/webapp/src/config.js index 9d317b8d0..5280af6ca 100644 --- a/src/webapp/src/config.js +++ b/src/webapp/src/config.js @@ -49,7 +49,8 @@ const JUKEBOX_ACTIONS_MAP = { next_song: {}, prev_song: {}, shuffle: {}, - repeat: {} + toggle_repeat: {}, + toggle_repeat_single: {} }, }, From 59452622a7cafff8356039ffa112b3afd7dd4b61 Mon Sep 17 00:00:00 2001 From: pabera <1260686+pabera@users.noreply.github.com> Date: Wed, 3 Jan 2024 10:38:39 +0100 Subject: [PATCH 05/17] Fix toggle_shuffle --- src/jukebox/components/playermpd/__init__.py | 7 +++++++ src/jukebox/components/rpc_command_alias.py | 4 ++-- src/webapp/public/locales/en/translation.json | 2 +- src/webapp/src/config.js | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/jukebox/components/playermpd/__init__.py b/src/jukebox/components/playermpd/__init__.py index 12548599d..0a0466f2f 100644 --- a/src/jukebox/components/playermpd/__init__.py +++ b/src/jukebox/components/playermpd/__init__.py @@ -340,6 +340,13 @@ def shuffle(self, random): # As long as we don't work with waiting lists (aka playlist), this implementation is ok! self.mpd_retry_with_mutex(self.mpd_client.random, 1 if random else 0) + @plugs.tag + def toggle_shuffle(self): + if self.mpd_status['shuffle'] == '0': + self.shuffle(1) + else: + self.shuffle(0) + @plugs.tag def rewind(self): """ diff --git a/src/jukebox/components/rpc_command_alias.py b/src/jukebox/components/rpc_command_alias.py index 039b10373..56c67b255 100644 --- a/src/jukebox/components/rpc_command_alias.py +++ b/src/jukebox/components/rpc_command_alias.py @@ -63,10 +63,10 @@ 'plugin': 'ctrl', 'method': 'toggle', 'ignore_card_removal_action': True}, - 'shuffle': { + 'toggle_shuffle': { 'package': 'player', 'plugin': 'ctrl', - 'method': 'shuffle', + 'method': 'toggle_shuffle', 'note': 'Toggles Shuffle', 'ignore_card_removal_action': True}, 'toggle_repeat': { diff --git a/src/webapp/public/locales/en/translation.json b/src/webapp/public/locales/en/translation.json index 1a2ee568c..d2c05a708 100644 --- a/src/webapp/public/locales/en/translation.json +++ b/src/webapp/public/locales/en/translation.json @@ -28,7 +28,7 @@ "pause": "Pause", "play": "Play", "prev_song": "Previous song", - "shuffle": "Toggle shuffle", + "toogle_shuffle": "Toggle shuffle", "toggle_repeat": "Toggle repeat", "toggle_repeat_single": "Toggle single repeat", "toggle": "Toggle Play/Pause" diff --git a/src/webapp/src/config.js b/src/webapp/src/config.js index 5280af6ca..6854b81d5 100644 --- a/src/webapp/src/config.js +++ b/src/webapp/src/config.js @@ -48,7 +48,7 @@ const JUKEBOX_ACTIONS_MAP = { toggle: {}, next_song: {}, prev_song: {}, - shuffle: {}, + toogle_shuffle: {}, toggle_repeat: {}, toggle_repeat_single: {} }, From e909212cfb5f27314e8a9dd1927cfac7fb2986f0 Mon Sep 17 00:00:00 2001 From: pabera <1260686+pabera@users.noreply.github.com> Date: Wed, 3 Jan 2024 10:48:48 +0100 Subject: [PATCH 06/17] Fix typo in command --- src/webapp/public/locales/de/translation.json | 2 +- src/webapp/public/locales/en/translation.json | 2 +- src/webapp/src/config.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/webapp/public/locales/de/translation.json b/src/webapp/public/locales/de/translation.json index 00973aba7..84a6e080d 100644 --- a/src/webapp/public/locales/de/translation.json +++ b/src/webapp/public/locales/de/translation.json @@ -28,7 +28,7 @@ "pause": "Pause", "play": "Abspielen", "prev_song": "Vorheriger Song", - "shuffle": "Shuffle aktivieren/deaktivieren", + "toogle_shuffle": "Shuffle aktivieren/deaktivieren", "toggle_repeat": "Wiederholen aktivieren/deaktivieren", "toggle_repeat_single": "1 wiederholen aktivieren/deaktivieren", "toggle": "Abspielen/Pause umschalten" diff --git a/src/webapp/public/locales/en/translation.json b/src/webapp/public/locales/en/translation.json index d2c05a708..e5075d7c5 100644 --- a/src/webapp/public/locales/en/translation.json +++ b/src/webapp/public/locales/en/translation.json @@ -28,7 +28,7 @@ "pause": "Pause", "play": "Play", "prev_song": "Previous song", - "toogle_shuffle": "Toggle shuffle", + "toggle_shuffle": "Toggle shuffle", "toggle_repeat": "Toggle repeat", "toggle_repeat_single": "Toggle single repeat", "toggle": "Toggle Play/Pause" diff --git a/src/webapp/src/config.js b/src/webapp/src/config.js index 6854b81d5..fde88d596 100644 --- a/src/webapp/src/config.js +++ b/src/webapp/src/config.js @@ -48,7 +48,7 @@ const JUKEBOX_ACTIONS_MAP = { toggle: {}, next_song: {}, prev_song: {}, - toogle_shuffle: {}, + toggle_shuffle: {}, toggle_repeat: {}, toggle_repeat_single: {} }, From bf937cbb153f98b527f76f4ab61f09fd25b94550 Mon Sep 17 00:00:00 2001 From: pabera <1260686+pabera@users.noreply.github.com> Date: Wed, 3 Jan 2024 14:23:55 +0100 Subject: [PATCH 07/17] Fix another typo --- src/webapp/public/locales/de/translation.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webapp/public/locales/de/translation.json b/src/webapp/public/locales/de/translation.json index 84a6e080d..f817e330a 100644 --- a/src/webapp/public/locales/de/translation.json +++ b/src/webapp/public/locales/de/translation.json @@ -28,7 +28,7 @@ "pause": "Pause", "play": "Abspielen", "prev_song": "Vorheriger Song", - "toogle_shuffle": "Shuffle aktivieren/deaktivieren", + "toggle_shuffle": "Shuffle aktivieren/deaktivieren", "toggle_repeat": "Wiederholen aktivieren/deaktivieren", "toggle_repeat_single": "1 wiederholen aktivieren/deaktivieren", "toggle": "Abspielen/Pause umschalten" From 7fb7241bc1cfcfe82d3b81d7bc38e6d93cc3ffbe Mon Sep 17 00:00:00 2001 From: pabera <1260686+pabera@users.noreply.github.com> Date: Wed, 3 Jan 2024 15:07:48 +0100 Subject: [PATCH 08/17] Fix wrong parameter for shuffle --- src/jukebox/components/playermpd/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jukebox/components/playermpd/__init__.py b/src/jukebox/components/playermpd/__init__.py index 0a0466f2f..83593a04e 100644 --- a/src/jukebox/components/playermpd/__init__.py +++ b/src/jukebox/components/playermpd/__init__.py @@ -342,7 +342,7 @@ def shuffle(self, random): @plugs.tag def toggle_shuffle(self): - if self.mpd_status['shuffle'] == '0': + if self.mpd_status['random'] == '0': self.shuffle(1) else: self.shuffle(0) From 035689dd069ba0e207548c16660f48893f6e60d7 Mon Sep 17 00:00:00 2001 From: pabera <1260686+pabera@users.noreply.github.com> Date: Thu, 4 Jan 2024 00:05:55 +0100 Subject: [PATCH 09/17] Update German translation for single-repeat --- src/webapp/public/locales/de/translation.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/webapp/public/locales/de/translation.json b/src/webapp/public/locales/de/translation.json index f817e330a..b4853f7bb 100644 --- a/src/webapp/public/locales/de/translation.json +++ b/src/webapp/public/locales/de/translation.json @@ -29,8 +29,8 @@ "play": "Abspielen", "prev_song": "Vorheriger Song", "toggle_shuffle": "Shuffle aktivieren/deaktivieren", - "toggle_repeat": "Wiederholen aktivieren/deaktivieren", - "toggle_repeat_single": "1 wiederholen aktivieren/deaktivieren", + "toggle_repeat": "Wiedergabeliste Wiederholen aktivieren/deaktivieren", + "toggle_repeat_single": "Song Wiederholen aktivieren/deaktivieren", "toggle": "Abspielen/Pause umschalten" } }, @@ -154,8 +154,8 @@ "pause": "Pause", "next_song": "Weiter", "repeat": { - "activate": "Wiederholen aktivieren", - "activate-single": "1 Wiederholen aktivieren", + "activate": "Wiedergabeliste Wiederholen aktivieren", + "activate-single": "Song Wiederholen aktivieren", "deactivate": "Wiederholen deaktivieren" } }, From d526ba1f97eb5622d6508f90034234a6e035722c Mon Sep 17 00:00:00 2001 From: pabera <1260686+pabera@users.noreply.github.com> Date: Thu, 4 Jan 2024 08:08:14 +0100 Subject: [PATCH 10/17] Simplify Shuffle option --- src/jukebox/components/playermpd/__init__.py | 11 ++- src/jukebox/components/rpc_command_alias.py | 6 +- src/webapp/public/locales/de/translation.json | 18 +++-- src/webapp/public/locales/en/translation.json | 18 +++-- src/webapp/src/commands/index.js | 5 +- .../Cards/controls/actions/audio/index.js | 11 ++- .../controls/actions/audio/shuffle-options.js | 67 +++++++++++++++++++ .../actions/audio/slider-change-volume.js | 4 +- src/webapp/src/components/Player/controls.js | 4 +- src/webapp/src/config.js | 2 +- src/webapp/src/i18n.js | 1 + 11 files changed, 122 insertions(+), 25 deletions(-) create mode 100644 src/webapp/src/components/Cards/controls/actions/audio/shuffle-options.js diff --git a/src/jukebox/components/playermpd/__init__.py b/src/jukebox/components/playermpd/__init__.py index 83593a04e..87df9e0ac 100644 --- a/src/jukebox/components/playermpd/__init__.py +++ b/src/jukebox/components/playermpd/__init__.py @@ -341,10 +341,15 @@ def shuffle(self, random): self.mpd_retry_with_mutex(self.mpd_client.random, 1 if random else 0) @plugs.tag - def toggle_shuffle(self): - if self.mpd_status['random'] == '0': + def set_shuffle(self, option='toggle'): + if option == 'toggle': + if self.mpd_status['random'] == '0': + self.shuffle(1) + else: + self.shuffle(0) + elif option == 'enable': self.shuffle(1) - else: + elif option == 'disable': self.shuffle(0) @plugs.tag diff --git a/src/jukebox/components/rpc_command_alias.py b/src/jukebox/components/rpc_command_alias.py index 56c67b255..bdfe64bc1 100644 --- a/src/jukebox/components/rpc_command_alias.py +++ b/src/jukebox/components/rpc_command_alias.py @@ -63,11 +63,11 @@ 'plugin': 'ctrl', 'method': 'toggle', 'ignore_card_removal_action': True}, - 'toggle_shuffle': { + 'set_shuffle': { 'package': 'player', 'plugin': 'ctrl', - 'method': 'toggle_shuffle', - 'note': 'Toggles Shuffle', + 'method': 'set_shuffle', + 'note': 'Shuffle', 'ignore_card_removal_action': True}, 'toggle_repeat': { 'package': 'player', diff --git a/src/webapp/public/locales/de/translation.json b/src/webapp/public/locales/de/translation.json index b4853f7bb..ec23c79fb 100644 --- a/src/webapp/public/locales/de/translation.json +++ b/src/webapp/public/locales/de/translation.json @@ -28,7 +28,7 @@ "pause": "Pause", "play": "Abspielen", "prev_song": "Vorheriger Song", - "toggle_shuffle": "Shuffle aktivieren/deaktivieren", + "set_shuffle": "Zufallswiedergabe", "toggle_repeat": "Wiedergabeliste Wiederholen aktivieren/deaktivieren", "toggle_repeat_single": "Song Wiederholen aktivieren/deaktivieren", "toggle": "Abspielen/Pause umschalten" @@ -64,8 +64,16 @@ "no-music-selected": "Es ist keine Musik ausgewählt.", "loading-song-error": "Während des Ladens des Songs ist ein Fehler aufgetreten." }, - "volume": { - "title": "Lautstärke Stufen" + "audio": { + "shuffle": { + "description": "Wähle den zu setzenden Status.", + "label-toggle": "Umschalten", + "label-enable": "Aktivieren", + "label-disable": "Deaktivieren" + }, + "volume": { + "title": "Volume steps" + } }, "timers": { "description": "Wähle die Anzahl der Minuten nachdem die Aktion ausgeführt werden soll." @@ -146,8 +154,8 @@ "player": { "controls": { "shuffle": { - "activate": "Shuffle aktivieren", - "deactivate": "Shuffle deaktivieren" + "enable": "Zufallswiedergabe aktivieren", + "disable": "Zufallswiedergabe deaktivieren" }, "prev_song": "Zurück", "play": "Abspielen", diff --git a/src/webapp/public/locales/en/translation.json b/src/webapp/public/locales/en/translation.json index e5075d7c5..9fc86468c 100644 --- a/src/webapp/public/locales/en/translation.json +++ b/src/webapp/public/locales/en/translation.json @@ -28,7 +28,7 @@ "pause": "Pause", "play": "Play", "prev_song": "Previous song", - "toggle_shuffle": "Toggle shuffle", + "set_shuffle": "Shuffle", "toggle_repeat": "Toggle repeat", "toggle_repeat_single": "Toggle single repeat", "toggle": "Toggle Play/Pause" @@ -64,8 +64,16 @@ "no-music-selected": "No music selected", "loading-song-error": "An error occurred while loading song." }, - "volume": { - "title": "Volume steps" + "audio": { + "shuffle": { + "description": "Choose the state to set.", + "label-toggle": "Toggle", + "label-enable": "Enable", + "label-disable": "Disable" + }, + "volume": { + "title": "Volume steps" + } }, "timers": { "description": "Choose the amount of minutes you want the action to be performed." @@ -146,8 +154,8 @@ "player": { "controls": { "shuffle": { - "activate": "Activate shuffle", - "deactivate": "Deactivate shuffle" + "enable": "Enable shuffle", + "disable": "Disable shuffle" }, "prev_song": "Skip to previous track", "play": "Play", diff --git a/src/webapp/src/commands/index.js b/src/webapp/src/commands/index.js index d8911c4ab..02862ec0e 100644 --- a/src/webapp/src/commands/index.js +++ b/src/webapp/src/commands/index.js @@ -97,10 +97,11 @@ const commands = { plugin: 'ctrl', method: 'toggle', }, - shuffle: { + set_shuffle: { _package: 'player', plugin: 'ctrl', - method: 'shuffle', + method: 'set_shuffle', + argKeys: ['option'], }, repeatmode: { _package: 'player', diff --git a/src/webapp/src/components/Cards/controls/actions/audio/index.js b/src/webapp/src/components/Cards/controls/actions/audio/index.js index 1d3ddc465..374ca05ef 100644 --- a/src/webapp/src/components/Cards/controls/actions/audio/index.js +++ b/src/webapp/src/components/Cards/controls/actions/audio/index.js @@ -2,10 +2,11 @@ import React from 'react'; import CommandSelector from '../../command-selector'; import SliderChangeVolume from './slider-change-volume'; +import ShuffleOptions from './shuffle-options'; import { getActionAndCommand } from '../../../utils'; -const SelectVolume = ({ +const SelectAudioVolume = ({ actionData, handleActionDataChange, }) => { @@ -23,8 +24,14 @@ const SelectVolume = ({ handleActionDataChange={handleActionDataChange} /> } + {command === 'set_shuffle' && + + } ); }; -export default SelectVolume; \ No newline at end of file +export default SelectAudioVolume; \ No newline at end of file diff --git a/src/webapp/src/components/Cards/controls/actions/audio/shuffle-options.js b/src/webapp/src/components/Cards/controls/actions/audio/shuffle-options.js new file mode 100644 index 000000000..6c13bc754 --- /dev/null +++ b/src/webapp/src/components/Cards/controls/actions/audio/shuffle-options.js @@ -0,0 +1,67 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { + Grid, + FormControl, + FormControlLabel, + Radio, + RadioGroup, + Typography, +} from '@mui/material'; + +import { + getActionAndCommand, + getArgsValues, +} from '../../../utils'; + + +const ShuffleOptions = ({ + actionData, + handleActionDataChange, +}) => { + const { t } = useTranslation(); + + const { action, command } = getActionAndCommand(actionData); + const [option] = getArgsValues(actionData); + + const onChange = (event, option) => { + handleActionDataChange(action, command, { option }) + }; + + return ( + + + + {t('cards.controls.actions.audio.shuffle.description')} + + + + } + label={t('cards.controls.actions.audio.shuffle.label-toggle')} + value="toggle" + /> + } + label={t('cards.controls.actions.audio.shuffle.label-enable')} + value="enable" + /> + } + label={t('cards.controls.actions.audio.shuffle.label-disable')} + value="disable" + /> + + + + + ); +}; + +export default ShuffleOptions; diff --git a/src/webapp/src/components/Cards/controls/actions/audio/slider-change-volume.js b/src/webapp/src/components/Cards/controls/actions/audio/slider-change-volume.js index 2e70b489a..64f5edada 100644 --- a/src/webapp/src/components/Cards/controls/actions/audio/slider-change-volume.js +++ b/src/webapp/src/components/Cards/controls/actions/audio/slider-change-volume.js @@ -37,12 +37,12 @@ const SliderChangeVolume = ({ - {t('cards.controls.actions.volume.title')} + {t('cards.controls.actions.audio.volume.title')} { const labelShuffle = () => ( isShuffle - ? t('player.controls.shuffle.deactivate') - : t('player.controls.shuffle.activate') + ? t('player.controls.shuffle.disable') + : t('player.controls.shuffle.enable') ); const labelRepeat = () => { diff --git a/src/webapp/src/config.js b/src/webapp/src/config.js index fde88d596..77e71257e 100644 --- a/src/webapp/src/config.js +++ b/src/webapp/src/config.js @@ -48,7 +48,7 @@ const JUKEBOX_ACTIONS_MAP = { toggle: {}, next_song: {}, prev_song: {}, - toggle_shuffle: {}, + set_shuffle: {}, toggle_repeat: {}, toggle_repeat_single: {} }, diff --git a/src/webapp/src/i18n.js b/src/webapp/src/i18n.js index b2a752fdd..d374abae3 100644 --- a/src/webapp/src/i18n.js +++ b/src/webapp/src/i18n.js @@ -18,6 +18,7 @@ i18n // for all options read: https://www.i18next.com/overview/configuration-options .init({ debug: true, + // lng: 'en', fallbackLng: 'en', interpolation: { escapeValue: false, // not needed for react as it escapes by default From 15d438fda8f00cd5c6dcb08d88c8c52cbbbfd166 Mon Sep 17 00:00:00 2001 From: pabera <1260686+pabera@users.noreply.github.com> Date: Thu, 4 Jan 2024 08:54:41 +0100 Subject: [PATCH 11/17] Simplify Repeat option --- src/jukebox/components/playermpd/__init__.py | 24 +++++- src/jukebox/components/rpc_command_alias.py | 12 +-- src/webapp/public/locales/de/translation.json | 12 ++- src/webapp/public/locales/en/translation.json | 12 ++- src/webapp/src/commands/index.js | 6 ++ .../Cards/controls/actions/audio/index.js | 7 ++ .../controls/actions/audio/repeat-options.js | 82 +++++++++++++++++++ src/webapp/src/config.js | 3 +- 8 files changed, 142 insertions(+), 16 deletions(-) create mode 100644 src/webapp/src/components/Cards/controls/actions/audio/repeat-options.js diff --git a/src/jukebox/components/playermpd/__init__.py b/src/jukebox/components/playermpd/__init__.py index 87df9e0ac..348359e1c 100644 --- a/src/jukebox/components/playermpd/__init__.py +++ b/src/jukebox/components/playermpd/__init__.py @@ -351,6 +351,8 @@ def set_shuffle(self, option='toggle'): self.shuffle(1) elif option == 'disable': self.shuffle(0) + else: + logger.error(f"'{option}' does not exist for set_shuffle") @plugs.tag def rewind(self): @@ -406,13 +408,33 @@ def repeatmode(self, mode): self.mpd_client.single(single) @plugs.tag + def set_repeat(self, option='toggle'): + if option == 'toggle': + if self.mpd_status['repeat'] == '0': + self.repeatmode('repeat') + elif self.mpd_status['repeat'] == '1' and self.mpd_status['single'] == '0': + self.repeatmode('single') + else: + self.repeatmode(None) + elif option == 'toggle_repeat': + self.toggle_repeat() + elif option == 'toggle_repeat_single': + self.toggle_repeat_single() + elif option == 'enable_repeat': + self.repeatmode('repeat') + elif option == 'enable_repeat_single': + self.repeatmode('single') + elif option == 'disable': + self.repeatmode(None) + else: + logger.error(f"'{option}' does not exist for set_repeat") + def toggle_repeat(self): if self.mpd_status['repeat'] == '0': self.repeatmode('repeat') else: self.repeatmode(None) - @plugs.tag def toggle_repeat_single(self): if self.mpd_status['single'] == '0': self.repeatmode('single') diff --git a/src/jukebox/components/rpc_command_alias.py b/src/jukebox/components/rpc_command_alias.py index bdfe64bc1..0322040ff 100644 --- a/src/jukebox/components/rpc_command_alias.py +++ b/src/jukebox/components/rpc_command_alias.py @@ -69,17 +69,11 @@ 'method': 'set_shuffle', 'note': 'Shuffle', 'ignore_card_removal_action': True}, - 'toggle_repeat': { + 'set_repeat': { 'package': 'player', 'plugin': 'ctrl', - 'method': 'toggle_repeat', - 'note': 'Toggles repeat option', - 'ignore_card_removal_action': True}, - 'toggle_repeat_single': { - 'package': 'player', - 'plugin': 'ctrl', - 'method': 'toggle_repeat_single', - 'note': 'Toggles single repeat option', + 'method': 'set_repeat', + 'note': 'Repeat', 'ignore_card_removal_action': True}, # VOLUME diff --git a/src/webapp/public/locales/de/translation.json b/src/webapp/public/locales/de/translation.json index ec23c79fb..7291a62e8 100644 --- a/src/webapp/public/locales/de/translation.json +++ b/src/webapp/public/locales/de/translation.json @@ -29,8 +29,7 @@ "play": "Abspielen", "prev_song": "Vorheriger Song", "set_shuffle": "Zufallswiedergabe", - "toggle_repeat": "Wiedergabeliste Wiederholen aktivieren/deaktivieren", - "toggle_repeat_single": "Song Wiederholen aktivieren/deaktivieren", + "set_repeat": "Wiedergabe wiederholen", "toggle": "Abspielen/Pause umschalten" } }, @@ -65,6 +64,15 @@ "loading-song-error": "Während des Ladens des Songs ist ein Fehler aufgetreten." }, "audio": { + "repeat": { + "description": "Wähle den zu setzenden Status.", + "label-toggle": "Umschalten - Schaltet durch 1) Wiedergabeliste Wiederholen, 2) Song Wiederholen, 3) Wiederholen Deaktiveren", + "label-toggle-repeat": "Wiedergabeliste Wiederholen umschalten", + "label-toggle-repeat-single": "Song Wiederholen umschalten", + "label-enable-repeat": "Wiedergabeliste Wiederholen aktivieren", + "label-enable-repeat-single": "Song Wiederholen aktivieren", + "label-disable": "Wiederholen deaktivieren" + }, "shuffle": { "description": "Wähle den zu setzenden Status.", "label-toggle": "Umschalten", diff --git a/src/webapp/public/locales/en/translation.json b/src/webapp/public/locales/en/translation.json index 9fc86468c..d7c13e31e 100644 --- a/src/webapp/public/locales/en/translation.json +++ b/src/webapp/public/locales/en/translation.json @@ -29,8 +29,7 @@ "play": "Play", "prev_song": "Previous song", "set_shuffle": "Shuffle", - "toggle_repeat": "Toggle repeat", - "toggle_repeat_single": "Toggle single repeat", + "set_repeat": "Repeat", "toggle": "Toggle Play/Pause" } }, @@ -65,6 +64,15 @@ "loading-song-error": "An error occurred while loading song." }, "audio": { + "repeat": { + "description": "Choose the state to set.", + "label-toggle": "Toggle - Loops through 1) Repeat playlist, 2) Repeat song, 3) Disable repeat", + "label-toggle-repeat": "Toggle Repeat Playlist", + "label-toggle-repeat-single": "Toggle Repeat Song", + "label-enable-repeat": "Enable Repeat Playlist", + "label-enable-repeat-single": "Enable Repeat Song", + "label-disable": "Disable" + }, "shuffle": { "description": "Choose the state to set.", "label-toggle": "Toggle", diff --git a/src/webapp/src/commands/index.js b/src/webapp/src/commands/index.js index 02862ec0e..26a28bdc2 100644 --- a/src/webapp/src/commands/index.js +++ b/src/webapp/src/commands/index.js @@ -103,6 +103,12 @@ const commands = { method: 'set_shuffle', argKeys: ['option'], }, + set_repeat: { + _package: 'player', + plugin: 'ctrl', + method: 'set_repeat', + argKeys: ['option'], + }, repeatmode: { _package: 'player', plugin: 'ctrl', diff --git a/src/webapp/src/components/Cards/controls/actions/audio/index.js b/src/webapp/src/components/Cards/controls/actions/audio/index.js index 374ca05ef..2e8a4d0c8 100644 --- a/src/webapp/src/components/Cards/controls/actions/audio/index.js +++ b/src/webapp/src/components/Cards/controls/actions/audio/index.js @@ -2,6 +2,7 @@ import React from 'react'; import CommandSelector from '../../command-selector'; import SliderChangeVolume from './slider-change-volume'; +import RepeatOptions from './repeat-options'; import ShuffleOptions from './shuffle-options'; import { getActionAndCommand } from '../../../utils'; @@ -30,6 +31,12 @@ const SelectAudioVolume = ({ handleActionDataChange={handleActionDataChange} /> } + {command === 'set_repeat' && + + } ); }; diff --git a/src/webapp/src/components/Cards/controls/actions/audio/repeat-options.js b/src/webapp/src/components/Cards/controls/actions/audio/repeat-options.js new file mode 100644 index 000000000..58f6f40c1 --- /dev/null +++ b/src/webapp/src/components/Cards/controls/actions/audio/repeat-options.js @@ -0,0 +1,82 @@ +import React from 'react'; +import { useTranslation } from 'react-i18next'; + +import { + Grid, + FormControl, + FormControlLabel, + Radio, + RadioGroup, + Typography, +} from '@mui/material'; + +import { + getActionAndCommand, + getArgsValues, +} from '../../../utils'; + + +const RepeatOptions = ({ + actionData, + handleActionDataChange, +}) => { + const { t } = useTranslation(); + + const { action, command } = getActionAndCommand(actionData); + const [option] = getArgsValues(actionData); + + const onChange = (event, option) => { + handleActionDataChange(action, command, { option }) + }; + + return ( + + + + {t('cards.controls.actions.audio.repeat.description')} + + + + } + label={t('cards.controls.actions.audio.repeat.label-toggle')} + value="toggle" + /> + } + label={t('cards.controls.actions.audio.repeat.label-toggle-repeat')} + value="toggle_repeat" + /> + } + label={t('cards.controls.actions.audio.repeat.label-toggle-repeat-single')} + value="toggle_repeat_single" + /> + } + label={t('cards.controls.actions.audio.repeat.label-enable-repeat')} + value="enable_repeat" + /> + } + label={t('cards.controls.actions.audio.repeat.label-enable-repeat-single')} + value="enable_repeat_single" + /> + } + label={t('cards.controls.actions.audio.repeat.label-disable')} + value="disable" + /> + + + + + ); +}; + +export default RepeatOptions; diff --git a/src/webapp/src/config.js b/src/webapp/src/config.js index 77e71257e..2a6d1fb17 100644 --- a/src/webapp/src/config.js +++ b/src/webapp/src/config.js @@ -49,8 +49,7 @@ const JUKEBOX_ACTIONS_MAP = { next_song: {}, prev_song: {}, set_shuffle: {}, - toggle_repeat: {}, - toggle_repeat_single: {} + set_repeat: {}, }, }, From 008a6dedd28cc4c14d44576f79b19d257173c851 Mon Sep 17 00:00:00 2001 From: pabera <1260686+pabera@users.noreply.github.com> Date: Thu, 4 Jan 2024 09:02:13 +0100 Subject: [PATCH 12/17] Streamline Player functions with new set_ methods in jukebox --- src/webapp/src/commands/index.js | 5 ----- src/webapp/src/components/Player/controls.js | 8 ++------ 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/src/webapp/src/commands/index.js b/src/webapp/src/commands/index.js index 26a28bdc2..4c5ac4253 100644 --- a/src/webapp/src/commands/index.js +++ b/src/webapp/src/commands/index.js @@ -109,11 +109,6 @@ const commands = { method: 'set_repeat', argKeys: ['option'], }, - repeatmode: { - _package: 'player', - plugin: 'ctrl', - method: 'repeatmode', - }, seek: { _package: 'player', plugin: 'ctrl', diff --git a/src/webapp/src/components/Player/controls.js b/src/webapp/src/components/Player/controls.js index f89308a43..ea16ff2ad 100644 --- a/src/webapp/src/components/Player/controls.js +++ b/src/webapp/src/components/Player/controls.js @@ -32,15 +32,11 @@ const Controls = () => { } = state; const toggleShuffle = () => { - request('shuffle', { random: !isShuffle }); + request('set_shuffle', { option: 'toggle' }); } const toggleRepeat = () => { - let mode = null; - if (!isRepeat && !isSingle) mode = 'repeat'; - if (isRepeat && !isSingle) mode = 'single'; - - request('repeatmode', { mode }); + request('set_repeat', { option: 'toggle' }); } useEffect(() => { From 5286b7d40e1531238f5ef1a88afab92f2a48f634 Mon Sep 17 00:00:00 2001 From: pabera <1260686+pabera@users.noreply.github.com> Date: Thu, 4 Jan 2024 09:45:56 +0100 Subject: [PATCH 13/17] Abstract OptionsSelector --- .../Cards/controls/actions/audio/index.js | 24 +++++- .../controls/actions/audio/repeat-options.js | 82 ------------------- .../controls/actions/synchronisation/index.js | 10 ++- .../rfidcards/change-on-rfid-scan-options.js | 67 --------------- ...shuffle-options.js => options-selector.js} | 42 ++++------ 5 files changed, 47 insertions(+), 178 deletions(-) delete mode 100644 src/webapp/src/components/Cards/controls/actions/audio/repeat-options.js delete mode 100644 src/webapp/src/components/Cards/controls/actions/synchronisation/rfidcards/change-on-rfid-scan-options.js rename src/webapp/src/components/Cards/controls/{actions/audio/shuffle-options.js => options-selector.js} (51%) diff --git a/src/webapp/src/components/Cards/controls/actions/audio/index.js b/src/webapp/src/components/Cards/controls/actions/audio/index.js index 2e8a4d0c8..6048a3963 100644 --- a/src/webapp/src/components/Cards/controls/actions/audio/index.js +++ b/src/webapp/src/components/Cards/controls/actions/audio/index.js @@ -2,8 +2,7 @@ import React from 'react'; import CommandSelector from '../../command-selector'; import SliderChangeVolume from './slider-change-volume'; -import RepeatOptions from './repeat-options'; -import ShuffleOptions from './shuffle-options'; +import OptionsSelector from '../../options-selector'; import { getActionAndCommand } from '../../../utils'; @@ -26,15 +25,32 @@ const SelectAudioVolume = ({ /> } {command === 'set_shuffle' && - } {command === 'set_repeat' && - } diff --git a/src/webapp/src/components/Cards/controls/actions/audio/repeat-options.js b/src/webapp/src/components/Cards/controls/actions/audio/repeat-options.js deleted file mode 100644 index 58f6f40c1..000000000 --- a/src/webapp/src/components/Cards/controls/actions/audio/repeat-options.js +++ /dev/null @@ -1,82 +0,0 @@ -import React from 'react'; -import { useTranslation } from 'react-i18next'; - -import { - Grid, - FormControl, - FormControlLabel, - Radio, - RadioGroup, - Typography, -} from '@mui/material'; - -import { - getActionAndCommand, - getArgsValues, -} from '../../../utils'; - - -const RepeatOptions = ({ - actionData, - handleActionDataChange, -}) => { - const { t } = useTranslation(); - - const { action, command } = getActionAndCommand(actionData); - const [option] = getArgsValues(actionData); - - const onChange = (event, option) => { - handleActionDataChange(action, command, { option }) - }; - - return ( - - - - {t('cards.controls.actions.audio.repeat.description')} - - - - } - label={t('cards.controls.actions.audio.repeat.label-toggle')} - value="toggle" - /> - } - label={t('cards.controls.actions.audio.repeat.label-toggle-repeat')} - value="toggle_repeat" - /> - } - label={t('cards.controls.actions.audio.repeat.label-toggle-repeat-single')} - value="toggle_repeat_single" - /> - } - label={t('cards.controls.actions.audio.repeat.label-enable-repeat')} - value="enable_repeat" - /> - } - label={t('cards.controls.actions.audio.repeat.label-enable-repeat-single')} - value="enable_repeat_single" - /> - } - label={t('cards.controls.actions.audio.repeat.label-disable')} - value="disable" - /> - - - - - ); -}; - -export default RepeatOptions; diff --git a/src/webapp/src/components/Cards/controls/actions/synchronisation/index.js b/src/webapp/src/components/Cards/controls/actions/synchronisation/index.js index f554da1a3..fdfb4319b 100644 --- a/src/webapp/src/components/Cards/controls/actions/synchronisation/index.js +++ b/src/webapp/src/components/Cards/controls/actions/synchronisation/index.js @@ -1,6 +1,7 @@ import React from 'react'; import CommandSelector from '../../command-selector'; +import OptionsSelector from '../../options-selector'; import ChangeOnRfidScan from './rfidcards/change-on-rfid-scan-options'; import { getActionAndCommand } from '../../../utils'; @@ -18,9 +19,16 @@ const SelectSynchronisation = ({ handleActionDataChange={handleActionDataChange} /> {command === 'sync_rfidcards_change_on_rfid_scan' && - } diff --git a/src/webapp/src/components/Cards/controls/actions/synchronisation/rfidcards/change-on-rfid-scan-options.js b/src/webapp/src/components/Cards/controls/actions/synchronisation/rfidcards/change-on-rfid-scan-options.js deleted file mode 100644 index 6d2b2fde6..000000000 --- a/src/webapp/src/components/Cards/controls/actions/synchronisation/rfidcards/change-on-rfid-scan-options.js +++ /dev/null @@ -1,67 +0,0 @@ -import React from 'react'; -import { useTranslation } from 'react-i18next'; - -import { - Grid, - FormControl, - FormControlLabel, - Radio, - RadioGroup, - Typography, -} from '@mui/material'; - -import { - getActionAndCommand, - getArgsValues, -} from '../../../../utils'; - - -const ChangeOnRfidScan = ({ - actionData, - handleActionDataChange, -}) => { - const { t } = useTranslation(); - - const { action, command } = getActionAndCommand(actionData); - const [option] = getArgsValues(actionData); - - const onChange = (event, option) => { - handleActionDataChange(action, command, { option }) - }; - - return ( - - - - {t('cards.controls.actions.synchronisation.rfidcards.description')} - - - - } - label={t('cards.controls.actions.synchronisation.rfidcards.label-toggle')} - value="toggle" - /> - } - label={t('cards.controls.actions.synchronisation.rfidcards.label-enable')} - value="enable" - /> - } - label={t('cards.controls.actions.synchronisation.rfidcards.label-disable')} - value="disable" - /> - - - - - ); -}; - -export default ChangeOnRfidScan; diff --git a/src/webapp/src/components/Cards/controls/actions/audio/shuffle-options.js b/src/webapp/src/components/Cards/controls/options-selector.js similarity index 51% rename from src/webapp/src/components/Cards/controls/actions/audio/shuffle-options.js rename to src/webapp/src/components/Cards/controls/options-selector.js index 6c13bc754..7a2fd1b22 100644 --- a/src/webapp/src/components/Cards/controls/actions/audio/shuffle-options.js +++ b/src/webapp/src/components/Cards/controls/options-selector.js @@ -13,15 +13,16 @@ import { import { getActionAndCommand, getArgsValues, -} from '../../../utils'; +} from '../utils.js'; - -const ShuffleOptions = ({ +const OptionsSelector = ({ + actionType, actionData, handleActionDataChange, + optionLabel, + options, }) => { const { t } = useTranslation(); - const { action, command } = getActionAndCommand(actionData); const [option] = getArgsValues(actionData); @@ -33,30 +34,23 @@ const ShuffleOptions = ({ - {t('cards.controls.actions.audio.shuffle.description')} + {t(optionLabel)} - } - label={t('cards.controls.actions.audio.shuffle.label-toggle')} - value="toggle" - /> - } - label={t('cards.controls.actions.audio.shuffle.label-enable')} - value="enable" - /> - } - label={t('cards.controls.actions.audio.shuffle.label-disable')} - value="disable" - /> + {options.map(({ labelKey, value }) => ( + } + label={t(labelKey)} + value={value} + /> + ))} @@ -64,4 +58,4 @@ const ShuffleOptions = ({ ); }; -export default ShuffleOptions; +export default OptionsSelector; From 1a3dd69d36d3bee79067a1fcf7c736dce4c49526 Mon Sep 17 00:00:00 2001 From: pabera <1260686+pabera@users.noreply.github.com> Date: Thu, 4 Jan 2024 11:24:01 +0100 Subject: [PATCH 14/17] Refactor some code --- documentation/developers/status.md | 7 +- src/jukebox/components/playermpd/__init__.py | 74 +++++++++---------- src/webapp/public/locales/de/translation.json | 8 +- src/webapp/public/locales/en/translation.json | 6 +- .../controls/actions/synchronisation/index.js | 1 - src/webapp/src/components/Player/controls.js | 6 +- 6 files changed, 47 insertions(+), 55 deletions(-) diff --git a/documentation/developers/status.md b/documentation/developers/status.md index 2fb92897f..eb0e526d2 100644 --- a/documentation/developers/status.md +++ b/documentation/developers/status.md @@ -107,10 +107,9 @@ Topics marked _in progress_ are already in the process of implementation by comm - [ ] Folder configuration (_in progress_) - [ ] [Reference](https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki/MANUAL#manage-playout-behaviour) - [ ] Resume: Save and restore position (how interact with shuffle?) - - [ ] Single: Enable mpc single - - [ ] Shuffle: Enable mpc random (not shuffle) - - Rename to random, as this is mpc random - - [ ] Loop: Loop playlist + - [x] Repeat Playlist + - [x] Repeat Song + - [X] Shuffle ### MPD Player diff --git a/src/jukebox/components/playermpd/__init__.py b/src/jukebox/components/playermpd/__init__.py index 348359e1c..c17cd09b8 100644 --- a/src/jukebox/components/playermpd/__init__.py +++ b/src/jukebox/components/playermpd/__init__.py @@ -335,25 +335,6 @@ def seek(self, new_time): with self.mpd_lock: self.mpd_client.seekcur(new_time) - @plugs.tag - def shuffle(self, random): - # As long as we don't work with waiting lists (aka playlist), this implementation is ok! - self.mpd_retry_with_mutex(self.mpd_client.random, 1 if random else 0) - - @plugs.tag - def set_shuffle(self, option='toggle'): - if option == 'toggle': - if self.mpd_status['random'] == '0': - self.shuffle(1) - else: - self.shuffle(0) - elif option == 'enable': - self.shuffle(1) - elif option == 'disable': - self.shuffle(0) - else: - logger.error(f"'{option}' does not exist for set_shuffle") - @plugs.tag def rewind(self): """ @@ -391,8 +372,27 @@ def replay_if_stopped(self): if self.mpd_status['state'] == 'stop': self.play_folder(self.music_player_status['player_status']['last_played_folder']) + # Shuffle + def _shuffle(self, random): + # As long as we don't work with waiting lists (aka playlist), this implementation is ok! + self.mpd_retry_with_mutex(self.mpd_client.random, 1 if random else 0) + @plugs.tag - def repeatmode(self, mode): + def set_shuffle(self, option='toggle'): + if option == 'toggle': + if self.mpd_status['random'] == '0': + self._shuffle(1) + else: + self._shuffle(0) + elif option == 'enable': + self._shuffle(1) + elif option == 'disable': + self._shuffle(0) + else: + logger.error(f"'{option}' does not exist for set_shuffle") + + # Repeat + def _repeatmode(self, mode): if mode == 'repeat': repeat = 1 single = 0 @@ -411,36 +411,30 @@ def repeatmode(self, mode): def set_repeat(self, option='toggle'): if option == 'toggle': if self.mpd_status['repeat'] == '0': - self.repeatmode('repeat') + self._repeatmode('repeat') elif self.mpd_status['repeat'] == '1' and self.mpd_status['single'] == '0': - self.repeatmode('single') + self._repeatmode('single') else: - self.repeatmode(None) + self._repeatmode(None) elif option == 'toggle_repeat': - self.toggle_repeat() + if self.mpd_status['repeat'] == '0': + self._repeatmode('repeat') + else: + self._repeatmode(None) elif option == 'toggle_repeat_single': - self.toggle_repeat_single() + if self.mpd_status['single'] == '0': + self._repeatmode('single') + else: + self._repeatmode(None) elif option == 'enable_repeat': - self.repeatmode('repeat') + self._repeatmode('repeat') elif option == 'enable_repeat_single': - self.repeatmode('single') + self._repeatmode('single') elif option == 'disable': - self.repeatmode(None) + self._repeatmode(None) else: logger.error(f"'{option}' does not exist for set_repeat") - def toggle_repeat(self): - if self.mpd_status['repeat'] == '0': - self.repeatmode('repeat') - else: - self.repeatmode(None) - - def toggle_repeat_single(self): - if self.mpd_status['single'] == '0': - self.repeatmode('single') - else: - self.repeatmode(None) - @plugs.tag def get_current_song(self, param): return self.mpd_status diff --git a/src/webapp/public/locales/de/translation.json b/src/webapp/public/locales/de/translation.json index 7291a62e8..4201d7522 100644 --- a/src/webapp/public/locales/de/translation.json +++ b/src/webapp/public/locales/de/translation.json @@ -80,7 +80,7 @@ "label-disable": "Deaktivieren" }, "volume": { - "title": "Volume steps" + "title": "Lautstärke Stufen" } }, "timers": { @@ -170,9 +170,9 @@ "pause": "Pause", "next_song": "Weiter", "repeat": { - "activate": "Wiedergabeliste Wiederholen aktivieren", - "activate-single": "Song Wiederholen aktivieren", - "deactivate": "Wiederholen deaktivieren" + "enable": "Wiedergabeliste Wiederholen aktivieren", + "enable-single": "Song Wiederholen aktivieren", + "disable": "Wiederholen deaktivieren" } }, "cover": { diff --git a/src/webapp/public/locales/en/translation.json b/src/webapp/public/locales/en/translation.json index d7c13e31e..1fac1b83c 100644 --- a/src/webapp/public/locales/en/translation.json +++ b/src/webapp/public/locales/en/translation.json @@ -170,9 +170,9 @@ "pause": "Pause", "next_song": "Skip to next track", "repeat": { - "activate": "Activate repeat", - "activate-single": "Activate single repeat", - "deactivate": "Deactivate repeat" + "enable": "Enable Playlist repeat", + "enable-single": "Enable Song repeat", + "disable": "Disable repeat" } }, "cover": { diff --git a/src/webapp/src/components/Cards/controls/actions/synchronisation/index.js b/src/webapp/src/components/Cards/controls/actions/synchronisation/index.js index fdfb4319b..f1d4e3b26 100644 --- a/src/webapp/src/components/Cards/controls/actions/synchronisation/index.js +++ b/src/webapp/src/components/Cards/controls/actions/synchronisation/index.js @@ -2,7 +2,6 @@ import React from 'react'; import CommandSelector from '../../command-selector'; import OptionsSelector from '../../options-selector'; -import ChangeOnRfidScan from './rfidcards/change-on-rfid-scan-options'; import { getActionAndCommand } from '../../../utils'; diff --git a/src/webapp/src/components/Player/controls.js b/src/webapp/src/components/Player/controls.js index ea16ff2ad..e502c0038 100644 --- a/src/webapp/src/components/Player/controls.js +++ b/src/webapp/src/components/Player/controls.js @@ -59,9 +59,9 @@ const Controls = () => { ); const labelRepeat = () => { - if (!isRepeat) return t('player.controls.repeat.activate'); - if (isRepeat && !isSingle) return t('player.controls.repeat.activate-single'); - if (isRepeat && isSingle) return t('player.controls.repeat.deactivate'); + if (!isRepeat) return t('player.controls.repeat.enable'); + if (isRepeat && !isSingle) return t('player.controls.repeat.enable-single'); + if (isRepeat && isSingle) return t('player.controls.repeat.disable'); }; return ( From 0272f9b99d5e9209b02d9226f196bdb23a3e437d Mon Sep 17 00:00:00 2001 From: pabera <1260686+pabera@users.noreply.github.com> Date: Thu, 4 Jan 2024 11:28:47 +0100 Subject: [PATCH 15/17] Fix indentation --- src/jukebox/components/playermpd/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jukebox/components/playermpd/__init__.py b/src/jukebox/components/playermpd/__init__.py index c17cd09b8..175fea7cf 100644 --- a/src/jukebox/components/playermpd/__init__.py +++ b/src/jukebox/components/playermpd/__init__.py @@ -411,7 +411,7 @@ def _repeatmode(self, mode): def set_repeat(self, option='toggle'): if option == 'toggle': if self.mpd_status['repeat'] == '0': - self._repeatmode('repeat') + self._repeatmode('repeat') elif self.mpd_status['repeat'] == '1' and self.mpd_status['single'] == '0': self._repeatmode('single') else: From 48dbe1f66e0a69d0100e9ffb2a661f4d574ea73e Mon Sep 17 00:00:00 2001 From: pabera <1260686+pabera@users.noreply.github.com> Date: Thu, 4 Jan 2024 11:37:12 +0100 Subject: [PATCH 16/17] Rename set_ methods --- src/jukebox/components/playermpd/__init__.py | 8 ++++---- src/jukebox/components/rpc_command_alias.py | 8 ++++---- src/webapp/public/locales/de/translation.json | 4 ++-- src/webapp/public/locales/en/translation.json | 4 ++-- src/webapp/src/commands/index.js | 8 ++++---- .../src/components/Cards/controls/actions/audio/index.js | 4 ++-- src/webapp/src/components/Player/controls.js | 4 ++-- src/webapp/src/config.js | 4 ++-- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/jukebox/components/playermpd/__init__.py b/src/jukebox/components/playermpd/__init__.py index 175fea7cf..c77c21051 100644 --- a/src/jukebox/components/playermpd/__init__.py +++ b/src/jukebox/components/playermpd/__init__.py @@ -378,7 +378,7 @@ def _shuffle(self, random): self.mpd_retry_with_mutex(self.mpd_client.random, 1 if random else 0) @plugs.tag - def set_shuffle(self, option='toggle'): + def shuffle(self, option='toggle'): if option == 'toggle': if self.mpd_status['random'] == '0': self._shuffle(1) @@ -389,7 +389,7 @@ def set_shuffle(self, option='toggle'): elif option == 'disable': self._shuffle(0) else: - logger.error(f"'{option}' does not exist for set_shuffle") + logger.error(f"'{option}' does not exist for 'shuffle'") # Repeat def _repeatmode(self, mode): @@ -408,7 +408,7 @@ def _repeatmode(self, mode): self.mpd_client.single(single) @plugs.tag - def set_repeat(self, option='toggle'): + def repeat(self, option='toggle'): if option == 'toggle': if self.mpd_status['repeat'] == '0': self._repeatmode('repeat') @@ -433,7 +433,7 @@ def set_repeat(self, option='toggle'): elif option == 'disable': self._repeatmode(None) else: - logger.error(f"'{option}' does not exist for set_repeat") + logger.error(f"'{option}' does not exist for 'repeat'") @plugs.tag def get_current_song(self, param): diff --git a/src/jukebox/components/rpc_command_alias.py b/src/jukebox/components/rpc_command_alias.py index 0322040ff..e56727ff4 100644 --- a/src/jukebox/components/rpc_command_alias.py +++ b/src/jukebox/components/rpc_command_alias.py @@ -63,16 +63,16 @@ 'plugin': 'ctrl', 'method': 'toggle', 'ignore_card_removal_action': True}, - 'set_shuffle': { + 'shuffle': { 'package': 'player', 'plugin': 'ctrl', - 'method': 'set_shuffle', + 'method': 'shuffle', 'note': 'Shuffle', 'ignore_card_removal_action': True}, - 'set_repeat': { + 'repeat': { 'package': 'player', 'plugin': 'ctrl', - 'method': 'set_repeat', + 'method': 'repeat', 'note': 'Repeat', 'ignore_card_removal_action': True}, diff --git a/src/webapp/public/locales/de/translation.json b/src/webapp/public/locales/de/translation.json index 4201d7522..f3bd89782 100644 --- a/src/webapp/public/locales/de/translation.json +++ b/src/webapp/public/locales/de/translation.json @@ -28,8 +28,8 @@ "pause": "Pause", "play": "Abspielen", "prev_song": "Vorheriger Song", - "set_shuffle": "Zufallswiedergabe", - "set_repeat": "Wiedergabe wiederholen", + "shuffle": "Zufallswiedergabe", + "repeat": "Wiedergabe wiederholen", "toggle": "Abspielen/Pause umschalten" } }, diff --git a/src/webapp/public/locales/en/translation.json b/src/webapp/public/locales/en/translation.json index 1fac1b83c..348d3771d 100644 --- a/src/webapp/public/locales/en/translation.json +++ b/src/webapp/public/locales/en/translation.json @@ -28,8 +28,8 @@ "pause": "Pause", "play": "Play", "prev_song": "Previous song", - "set_shuffle": "Shuffle", - "set_repeat": "Repeat", + "shuffle": "Shuffle", + "repeat": "Repeat", "toggle": "Toggle Play/Pause" } }, diff --git a/src/webapp/src/commands/index.js b/src/webapp/src/commands/index.js index 4c5ac4253..8c844d8da 100644 --- a/src/webapp/src/commands/index.js +++ b/src/webapp/src/commands/index.js @@ -97,16 +97,16 @@ const commands = { plugin: 'ctrl', method: 'toggle', }, - set_shuffle: { + shuffle: { _package: 'player', plugin: 'ctrl', - method: 'set_shuffle', + method: 'shuffle', argKeys: ['option'], }, - set_repeat: { + repeat: { _package: 'player', plugin: 'ctrl', - method: 'set_repeat', + method: 'repeat', argKeys: ['option'], }, seek: { diff --git a/src/webapp/src/components/Cards/controls/actions/audio/index.js b/src/webapp/src/components/Cards/controls/actions/audio/index.js index 6048a3963..aba96cdc2 100644 --- a/src/webapp/src/components/Cards/controls/actions/audio/index.js +++ b/src/webapp/src/components/Cards/controls/actions/audio/index.js @@ -24,7 +24,7 @@ const SelectAudioVolume = ({ handleActionDataChange={handleActionDataChange} /> } - {command === 'set_shuffle' && + {command === 'shuffle' && } - {command === 'set_repeat' && + {command === 'repeat' && { } = state; const toggleShuffle = () => { - request('set_shuffle', { option: 'toggle' }); + request('shuffle', { option: 'toggle' }); } const toggleRepeat = () => { - request('set_repeat', { option: 'toggle' }); + request('repeat', { option: 'toggle' }); } useEffect(() => { diff --git a/src/webapp/src/config.js b/src/webapp/src/config.js index 2a6d1fb17..482db205e 100644 --- a/src/webapp/src/config.js +++ b/src/webapp/src/config.js @@ -48,8 +48,8 @@ const JUKEBOX_ACTIONS_MAP = { toggle: {}, next_song: {}, prev_song: {}, - set_shuffle: {}, - set_repeat: {}, + shuffle: {}, + repeat: {}, }, }, From 70f6a8415cf7b5806b38036bad759734eb234bd5 Mon Sep 17 00:00:00 2001 From: pabera <1260686+pabera@users.noreply.github.com> Date: Thu, 4 Jan 2024 12:38:25 +0100 Subject: [PATCH 17/17] Undo some doc changes --- documentation/developers/status.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/documentation/developers/status.md b/documentation/developers/status.md index eb0e526d2..48c2b6c3b 100644 --- a/documentation/developers/status.md +++ b/documentation/developers/status.md @@ -107,9 +107,9 @@ Topics marked _in progress_ are already in the process of implementation by comm - [ ] Folder configuration (_in progress_) - [ ] [Reference](https://github.com/MiczFlor/RPi-Jukebox-RFID/wiki/MANUAL#manage-playout-behaviour) - [ ] Resume: Save and restore position (how interact with shuffle?) - - [x] Repeat Playlist - - [x] Repeat Song - - [X] Shuffle + - [ ] Repeat Playlist + - [ ] Repeat Song + - [ ] Shuffle ### MPD Player