Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New card actions: play, pause, prev, next, toggle, repeat, shuffle #2179

Merged
merged 19 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion documentation/developers/docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

> [!NOTE]
> In order for Pulseaudio to work properly with Docker on your Mac, you need to start Pulseaudio in a specific way. Otherwise MPD will throw an exception. See [Pulseaudio issues on Mac](#pulseaudio-issue-on-mac) for more info.
Expand Down
22 changes: 21 additions & 1 deletion src/jukebox/components/playermpd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
"""
Expand All @@ -363,7 +370,6 @@ def replay(self):
@plugs.tag
def toggle(self):
pabera marked this conversation as resolved.
Show resolved Hide resolved
"""Toggle pause state, i.e. do a pause / resume depending on current state"""
logger.debug("Toggle")
with self.mpd_lock:
self.mpd_client.pause()

Expand Down Expand Up @@ -394,6 +400,20 @@ def repeatmode(self, mode):
self.mpd_client.repeat(repeat)
self.mpd_client.single(single)

@plugs.tag
def toggle_repeat(self):
pabera marked this conversation as resolved.
Show resolved Hide resolved
if self.mpd_status['repeat'] == '0':
self.repeatmode('repeat')
else:
self.repeatmode(None)

@plugs.tag
def toggle_repeat_single(self):
pabera marked this conversation as resolved.
Show resolved Hide resolved
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
Expand Down
24 changes: 24 additions & 0 deletions src/jukebox/components/rpc_command_alias.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@
'package': 'player',
'plugin': 'ctrl',
'method': 'play_folder'},
'play': {
'package': 'player',
'plugin': 'ctrl',
'method': 'play',
'note': 'Play the currently selected song',
'ignore_card_removal_action': True},
'pause': {
'package': 'player',
'plugin': 'ctrl',
Expand All @@ -57,6 +63,24 @@
'plugin': 'ctrl',
'method': 'toggle',
'ignore_card_removal_action': True},
'toggle_shuffle': {
pabera marked this conversation as resolved.
Show resolved Hide resolved
'package': 'player',
'plugin': 'ctrl',
'method': 'toggle_shuffle',
'note': 'Toggles Shuffle',
'ignore_card_removal_action': True},
'toggle_repeat': {
pabera marked this conversation as resolved.
Show resolved Hide resolved
'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',
'ignore_card_removal_action': True},

# VOLUME
'set_volume': {
Expand Down
14 changes: 11 additions & 3 deletions src/webapp/public/locales/de/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,15 @@
"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_song": "Nächster Song",
"pause": "Pause",
"play": "Abspielen",
"prev_song": "Vorheriger Song",
"toogle_shuffle": "Shuffle aktivieren/deaktivieren",
pabera marked this conversation as resolved.
Show resolved Hide resolved
"toggle_repeat": "Wiederholen aktivieren/deaktivieren",
"toggle_repeat_single": "1 wiederholen aktivieren/deaktivieren",
pabera marked this conversation as resolved.
Show resolved Hide resolved
"toggle": "Abspielen/Pause umschalten"
}
},
"controls-selector": {
Expand Down Expand Up @@ -141,10 +149,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",
Expand Down
15 changes: 12 additions & 3 deletions src/webapp/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,15 @@
"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_song": "Next song",
"pause": "Pause",
"play": "Play",
"prev_song": "Previous song",
"toggle_shuffle": "Toggle shuffle",
"toggle_repeat": "Toggle repeat",
"toggle_repeat_single": "Toggle single repeat",
"toggle": "Toggle Play/Pause"
}
},
"controls-selector": {
Expand Down Expand Up @@ -141,10 +149,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",
pabera marked this conversation as resolved.
Show resolved Hide resolved
"activate-single": "Activate single repeat",
Expand Down Expand Up @@ -207,6 +215,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",
Expand Down
11 changes: 8 additions & 3 deletions src/webapp/src/commands/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,22 +82,27 @@ const commands = {
plugin: 'ctrl',
method: 'pause',
},
previous: {
prev_song: {
_package: 'player',
plugin: 'ctrl',
method: 'prev',
},
next: {
next_song: {
_package: 'player',
plugin: 'ctrl',
method: 'next',
},
toggle: {
_package: 'player',
plugin: 'ctrl',
method: 'toggle',
},
shuffle: {
_package: 'player',
plugin: 'ctrl',
method: 'shuffle',
},
repeat: {
repeatmode: {
_package: 'player',
plugin: 'ctrl',
method: 'repeatmode',
Expand Down
18 changes: 9 additions & 9 deletions src/webapp/src/components/Player/controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const Controls = () => {
if (!isRepeat && !isSingle) mode = 'repeat';
if (isRepeat && !isSingle) mode = 'single';

request('repeat', { mode });
request('repeatmode', { mode });
}

useEffect(() => {
Expand Down Expand Up @@ -89,14 +89,14 @@ const Controls = () => {
<ShuffleRoundedIcon style={{ fontSize: 22 }} />
</IconButton>

{/* Skip previous track */}
{/* Skip to previous song */}
<IconButton
aria-label={t('player.controls.skip')}
aria-label={t('player.controls.prev_song')}
disabled={!songIsScheduled}
onClick={e => request('previous')}
onClick={e => request('prev_song')}
size="large"
sx={iconStyles}
title={t('player.controls.skip')}
title={t('player.controls.prev_song')}
>
<SkipPreviousRoundedIcon style={{ fontSize: 35 }} />
</IconButton>
Expand Down Expand Up @@ -127,14 +127,14 @@ const Controls = () => {
</IconButton>
}

{/* Skip next track */}
{/* Skip to next song */}
<IconButton
aria-label={t('player.controls.next')}
aria-label={t('player.controls.next_song')}
disabled={!songIsScheduled}
onClick={e => request('next')}
onClick={e => request('next_song')}
size="large"
sx={iconStyles}
title={t('player.controls.next')}
title={t('player.controls.next_song')}
>
<SkipNextRoundedIcon style={{ fontSize: 35 }} />
</IconButton>
Expand Down
6 changes: 5 additions & 1 deletion src/webapp/src/components/Player/cover.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ const Cover = ({ coverImage }) => {
<img
alt={t('player.cover.title')}
src={coverImage}
style={{ width: '100%', height: '100%' }}
style={{
borderRadius: '5px',
height: '100%',
width: '100%',
}}
/>}
{!coverImage &&
<MusicNoteIcon
Expand Down
2 changes: 1 addition & 1 deletion src/webapp/src/components/Player/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const Player = () => {
if (result) {
setCoverImage(`/cover-cache/${result}`);
setBackgroundImage([
'linear-gradient(to bottom, rgba(18, 18, 18, 0.7), rgba(18, 18, 18, 1))',
'linear-gradient(to bottom, rgba(18, 18, 18, 0.5), rgba(18, 18, 18, 1))',
`url(/cover-cache/${result})`
].join(','));
};
Expand Down
2 changes: 1 addition & 1 deletion src/webapp/src/components/Player/seekbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const SeekBar = () => {
direction="row"
justifyContent="space-between"
sx={ {
marginTop: '-20px',
marginTop: '-10px',
}}
>
<Grid item>
Expand Down
10 changes: 9 additions & 1 deletion src/webapp/src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,15 @@ const JUKEBOX_ACTIONS_MAP = {
audio: {
commands: {
change_volume: {},
toggle_output: {}
toggle_output: {},
play: {},
pause: {},
toggle: {},
next_song: {},
prev_song: {},
toggle_shuffle: {},
toggle_repeat: {},
toggle_repeat_single: {}
},
},

Expand Down