Skip to content

Commit

Permalink
Allow to update second swipe action in web app
Browse files Browse the repository at this point in the history
  • Loading branch information
pabera committed Dec 28, 2024
1 parent 91e9a72 commit e2d2e43
Show file tree
Hide file tree
Showing 7 changed files with 93 additions and 61 deletions.
5 changes: 1 addition & 4 deletions resources/default-settings/jukebox.default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,7 @@ alsawave:
playermpd:
host: localhost
status_file: ../../shared/settings/music_player_status.json
second_swipe_action:
# Note: Does not follow the RPC alias convention (yet)
# Must be one of: 'toggle', 'play', 'skip', 'rewind', 'replay', 'none'
alias: toggle
second_swipe_action: toggle # Must be one of: 'toggle', 'next', 'rewind', 'none'
library:
update_on_startup: true
check_user_rights: true
Expand Down
48 changes: 17 additions & 31 deletions src/jukebox/components/playermpd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,8 @@ def __init__(self):
self.music_player_status = self.nvm.load(cfg.getn('playermpd', 'status_file'))

self.second_swipe_action_dict = {'toggle': self.toggle,
'play': self.play,
'skip': self.next,
'rewind': self.rewind,
'replay': self.replay,
'replay_if_stopped': self.replay_if_stopped}
'next': self.next,
'rewind': self.rewind}
self.second_swipe_action = None
self.decode_second_swipe_action()

Expand Down Expand Up @@ -254,16 +251,12 @@ def decode_second_swipe_action(self):
"""
Decode the second swipe option from the configuration
"""
logger.debug("Decoding second swipe option")
second_swipe_action = cfg.getn('playermpd', 'second_swipe_action', 'none')
logger.debug(f"Second swipe option from config: {second_swipe_action}")

if second_swipe_action in self.second_swipe_action_dict:
self.second_swipe_action = self.second_swipe_action_dict[second_swipe_action]
logger.debug(f"Second swipe action set to: {self.second_swipe_action}")
else:
self.second_swipe_action = None
logger.debug("No valid second swipe action found, setting to None")

def mpd_retry_with_mutex(self, mpd_cmd, *args):
"""
Expand Down Expand Up @@ -419,34 +412,12 @@ def rewind(self):
with self.mpd_lock:
self.mpd_client.play(0)

@plugs.tag
def replay(self):
"""
Re-start playing the last-played folder
Will reset settings to folder config"""
logger.debug("Replay")
with self.mpd_lock:
self.play_folder(self.music_player_status['player_status']['last_played_folder'])

@plugs.tag
def toggle(self):
"""Toggle pause state, i.e. do a pause / resume depending on current state"""
with self.mpd_lock:
self.mpd_client.pause()

@plugs.tag
def replay_if_stopped(self):
"""
Re-start playing the last-played folder unless playlist is still playing
> [!NOTE]
> To me this seems much like the behaviour of play,
> but we keep it as it is specifically implemented in box 2.X"""
with self.mpd_lock:
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!
Expand Down Expand Up @@ -773,6 +744,21 @@ def get_song_by_url(self, song_url):

return song

@plugs.tag
def get_second_swipe_action(self):
action = cfg.getn('playermpd', 'second_swipe_action', default='None')

return action

@plugs.tag
def set_second_swipe_action(self, action):
if action is None:
cfg.setn('playermpd', 'second_swipe_action', value='None')
else:
cfg.setn('playermpd', 'second_swipe_action', value=action)

self.decode_second_swipe_action()

def get_volume(self):
"""
Get the current volume
Expand Down
6 changes: 3 additions & 3 deletions src/webapp/public/locales/de/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,10 @@
"secondswipe": {
"title": "Erneute Aktivierung (Second Swipe)",
"description": "Aktion, wenn dieselbe Karte ein weiteres Mal aktiviert wird",
"restart": "Wiedergabeliste neu starten",
"rewind": "Wiedergabeliste neu starten",
"toggle": "Pause / Wiedergabe umschalten",
"skip": "Zum nächsten Track springen",
"ignore": "Nur Systembefehle mehrfach ausführen"
"next": "Zum nächsten Track springen",
"none": "Keine Aktion"
},
"status": {
"title": "Systemstatus",
Expand Down
6 changes: 3 additions & 3 deletions src/webapp/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -260,10 +260,10 @@
"secondswipe": {
"title": "Second Swipe",
"description": "Second action after the same card swiped again",
"restart": "Restart playlist",
"rewind": "Restart playlist",
"toggle": "Toggle pause / play",
"skip": "Skip to next track",
"ignore": "Ignore audio playout triggers, only system commands"
"next": "Skip to next track",
"none": "No action"
},
"status": {
"title": "System",
Expand Down
12 changes: 12 additions & 0 deletions src/webapp/src/commands/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,18 @@ const commands = {
plugin: 'ctrl',
method: 'playerstatus'
},
// Player Options
getSecondSwipeAction: {
_package: 'player',
plugin: 'ctrl',
method: 'get_second_swipe_action',
},
setSecondSwipeAction: {
_package: 'player',
plugin: 'ctrl',
method: 'set_second_swipe_action',
argKeys: ['action']
},

// Player Actions
play: {
Expand Down
1 change: 1 addition & 0 deletions src/webapp/src/components/Settings/autohotspot.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { SwitchWithLoader } from '../general';

import request from '../../utils/request';

// TODO: Update the help URL
const helpUrl = 'https://rpi-jukebox-rfid.readthedocs.io/en/latest/userguide/autohotspot.html';

const SettingsAutoHotpot = () => {
Expand Down
76 changes: 56 additions & 20 deletions src/webapp/src/components/Settings/secondswipe.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';

import {
Card,
CardContent,
Expand All @@ -11,44 +10,81 @@ import {
Radio,
RadioGroup,
} from '@mui/material';
import request from '../../utils/request';

const SettingsSecondSwipe = () => {
const { t } = useTranslation();
const [secondSwipeAction, setSecondSwipeAction] = useState('None');
const [isLoading, setIsLoading] = useState(true);

const getSecondSwipeStatus = async () => {
const { result, error } = await request('getSecondSwipeAction');
if (result && result !== 'error') setSecondSwipeAction(result);
if ((result && result === 'error') || error) console.error(error);
};

const setSecondSwipeStatus = async (action) => {
setIsLoading(true);
const { result, error } = await request('setSecondSwipeAction', {
action: action
});

if (error || result === 'error') {
console.error('An error occurred while setting second swipe status');
await getSecondSwipeStatus(); // Revert to previous state
} else {
setSecondSwipeAction(action);
}
setIsLoading(false);
};

useEffect(() => {
const fetchSecondSwipeStatus = async () => {
setIsLoading(true);
await getSecondSwipeStatus();
setIsLoading(false);
};
fetchSecondSwipeStatus();
}, []);

const handleChange = (event) => {
setSecondSwipeStatus(event.target.value);
};

return (
<Card>
<CardHeader
title={t('settings.secondswipe.title')}
subheader={t('settings.feature-not-enabled')}
/>
<Divider />
<CardContent>
<Grid container direction="column">
<Grid item>
<RadioGroup aria-label="gender" name="gender1">
<RadioGroup
aria-label="second-swipe-action"
name="action"
value={secondSwipeAction || ''}
onChange={handleChange}
>
<FormControlLabel
value="restart"
control={<Radio />}
label={t('settings.secondswipe.restart')}
disabled={true}
value="toggle"
control={<Radio disabled={isLoading} />}
label={t('settings.secondswipe.toggle')}
/>
<FormControlLabel
value="pause"
control={<Radio />}
label={t('settings.secondswipe.toggle')}
disabled={true}
value="rewind"
control={<Radio disabled={isLoading} />}
label={t('settings.secondswipe.rewind')}
/>
<FormControlLabel
value="skipnext"
control={<Radio />}
label={t('settings.secondswipe.skip')}
disabled={true}
value="next"
control={<Radio disabled={isLoading} />}
label={t('settings.secondswipe.next')}
/>
<FormControlLabel
value="noaudioplay"
control={<Radio />}
label={t('settings.secondswipe.ignore')}
disabled={true}
value="None"
control={<Radio disabled={isLoading} />}
label={t('settings.secondswipe.none')}
/>
</RadioGroup>
</Grid>
Expand Down

0 comments on commit e2d2e43

Please sign in to comment.