Added a pause button to the bottom of the page
Added the possibility to jump to a specific track on the minidisc
This commit is contained in:
parent
2fa71f61a5
commit
6fffe61c14
|
@ -4,6 +4,7 @@ import PlayArrowIcon from '@material-ui/icons/PlayArrow';
|
|||
import StopIcon from '@material-ui/icons/Stop';
|
||||
import SkipNextIcon from '@material-ui/icons/SkipNext';
|
||||
import SkipPreviousIcon from '@material-ui/icons/SkipPrevious';
|
||||
import PauseIcon from '@material-ui/icons/Pause'
|
||||
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
import Box from '@material-ui/core/Box';
|
||||
|
@ -28,6 +29,11 @@ const useStyles = makeStyles(theme => ({
|
|||
},
|
||||
to: {},
|
||||
},
|
||||
'@keyframes blink': {
|
||||
'50%': {
|
||||
visibility: 'hidden',
|
||||
},
|
||||
},
|
||||
container: {
|
||||
display: 'flex',
|
||||
flex: '1 1 auto',
|
||||
|
@ -88,6 +94,12 @@ const useStyles = makeStyles(theme => ({
|
|||
top: 15,
|
||||
left: 1,
|
||||
},
|
||||
lcdBlink:{
|
||||
animationName: '$blink',
|
||||
animationTimingFunction: 'step-end',
|
||||
animationDuration: '1s',
|
||||
animationIterationCount: 'infinite'
|
||||
},
|
||||
button: {
|
||||
// padding: 8,
|
||||
},
|
||||
|
@ -112,11 +124,15 @@ export const Controls = () => {
|
|||
const handleNext = useCallback(() => {
|
||||
dispatch(control('next'));
|
||||
}, [dispatch]);
|
||||
const handlePause = useCallback(() => {
|
||||
dispatch(control('pause'));
|
||||
}, [dispatch]);
|
||||
|
||||
let message = ``;
|
||||
let trackIndex = deviceStatus?.track ?? null;
|
||||
let deviceState = deviceStatus?.state ?? null;
|
||||
let discPresent = deviceStatus?.discPresent ?? false;
|
||||
let paused = deviceStatus?.state === "paused";
|
||||
const tracks = getSortedTracks(disc);
|
||||
if (!discPresent) {
|
||||
message = ``;
|
||||
|
@ -187,6 +203,7 @@ export const Controls = () => {
|
|||
handlePrev,
|
||||
handlePlay,
|
||||
handleStop,
|
||||
handlePause,
|
||||
handleNext,
|
||||
|
||||
message,
|
||||
|
@ -208,6 +225,9 @@ export const Controls = () => {
|
|||
<IconButton aria-label="play" onClick={handlePlay} className={classes.button}>
|
||||
<PlayArrowIcon />
|
||||
</IconButton>
|
||||
<IconButton aria-label="pause" onClick={handlePause} className={classes.button}>
|
||||
<PauseIcon />
|
||||
</IconButton>
|
||||
<IconButton aria-label="stop" onClick={handleStop} className={classes.button}>
|
||||
<StopIcon />
|
||||
</IconButton>
|
||||
|
@ -228,7 +248,7 @@ export const Controls = () => {
|
|||
{message}
|
||||
</span>
|
||||
</div>
|
||||
<div className={classes.lcdDisc}>{discPresent && <DiscFrame className={classes.lcdDiscIcon} />}</div>
|
||||
<div className={classes.lcdDisc}>{discPresent && <DiscFrame className={classes.lcdDiscIcon + (paused ? ' ' + classes.lcdBlink : '')} />}</div>
|
||||
</div>
|
||||
</Box>
|
||||
);
|
||||
|
|
|
@ -8,6 +8,7 @@ import { actions as convertDialogActions } from '../redux/convert-dialog-feature
|
|||
import { actions as dumpDialogActions } from '../redux/dump-dialog-feature';
|
||||
|
||||
import { formatTimeFromFrames, getTracks } from 'netmd-js';
|
||||
import { control } from '../redux/actions';
|
||||
|
||||
import { belowDesktop, forAnyDesktop, getSortedTracks, useShallowEqualSelector } from '../utils';
|
||||
|
||||
|
@ -19,6 +20,8 @@ import AddIcon from '@material-ui/icons/Add';
|
|||
import DeleteIcon from '@material-ui/icons/Delete';
|
||||
import EditIcon from '@material-ui/icons/Edit';
|
||||
import Backdrop from '@material-ui/core/Backdrop';
|
||||
import PlayArrowIcon from '@material-ui/icons/PlayArrow';
|
||||
import PauseIcon from '@material-ui/icons/Pause'
|
||||
|
||||
import Table from '@material-ui/core/Table';
|
||||
import TableBody from '@material-ui/core/TableBody';
|
||||
|
@ -133,12 +136,53 @@ const useStyles = makeStyles(theme => ({
|
|||
textDecoration: 'underline',
|
||||
textDecorationStyle: 'dotted',
|
||||
},
|
||||
controlButtonInTrackCommon: {
|
||||
width: '.5em',
|
||||
verticalAlign: 'middle',
|
||||
},
|
||||
playButtonInTrackListPlaying: {
|
||||
color: theme.palette.primary.main,
|
||||
display: 'none',
|
||||
},
|
||||
pauseButtonInTrackListPlaying: {
|
||||
color: theme.palette.primary.main,
|
||||
display: 'none',
|
||||
},
|
||||
currentControlButton: {
|
||||
display: 'inline-block',
|
||||
},
|
||||
playButtonInTrackListNotPlaying: {
|
||||
visibility: 'hidden',
|
||||
},
|
||||
trackRow: {
|
||||
'&:hover': {
|
||||
/* For the tracks that aren't currently playing */
|
||||
"& $playButtonInTrackListNotPlaying":{
|
||||
visibility: 'visible',
|
||||
},
|
||||
"& $trackIndex":{
|
||||
display: 'none',
|
||||
},
|
||||
|
||||
/* For the current track */
|
||||
"& svg:not($currentControlButton)": {
|
||||
display: 'inline-block',
|
||||
},
|
||||
"& $currentControlButton": {
|
||||
display: 'none',
|
||||
}
|
||||
},
|
||||
},
|
||||
trackIndex:{
|
||||
display: 'inline-block',
|
||||
}
|
||||
}));
|
||||
|
||||
export const Main = (props: {}) => {
|
||||
let dispatch = useDispatch();
|
||||
let disc = useShallowEqualSelector(state => state.main.disc);
|
||||
let deviceName = useShallowEqualSelector(state => state.main.deviceName);
|
||||
const deviceStatus = useShallowEqualSelector(state => state.main.deviceStatus);
|
||||
const { vintageMode } = useShallowEqualSelector(state => state.appState);
|
||||
|
||||
const [selected, setSelected] = React.useState<number[]>([]);
|
||||
|
@ -229,6 +273,20 @@ export const Main = (props: {}) => {
|
|||
dispatch(deleteTracks(selected));
|
||||
};
|
||||
|
||||
const handlePlayTrack = async (event: React.MouseEvent, track: number) => {
|
||||
if(deviceStatus?.track !== track)
|
||||
dispatch(control('goto', track));
|
||||
if(deviceStatus?.state !== 'playing')
|
||||
dispatch(control('play'));
|
||||
};
|
||||
|
||||
const handleCurrentClick = async (event: React.MouseEvent) => {
|
||||
if(deviceStatus?.state === 'playing')
|
||||
dispatch(control('pause'));
|
||||
else
|
||||
dispatch(control('play'));
|
||||
}
|
||||
|
||||
if (vintageMode) {
|
||||
const p = {
|
||||
disc,
|
||||
|
@ -390,8 +448,26 @@ export const Main = (props: {}) => {
|
|||
key={track.index}
|
||||
onDoubleClick={event => handleRenameDoubleClick(event, track.index)}
|
||||
onClick={event => handleSelectClick(event, track.index)}
|
||||
className={classes.trackRow}
|
||||
>
|
||||
<TableCell className={classes.indexCell}>{track.index + 1}</TableCell>
|
||||
<TableCell className={classes.indexCell}>
|
||||
{track.index === deviceStatus?.track ?
|
||||
<span>
|
||||
<PlayArrowIcon
|
||||
className={`${classes.controlButtonInTrackCommon} ${classes.playButtonInTrackListPlaying} ${deviceStatus?.state === 'playing' ? classes.currentControlButton : ''}`}
|
||||
onClick={event => {handleCurrentClick(event); event.stopPropagation();}} />
|
||||
<PauseIcon
|
||||
className={`${classes.controlButtonInTrackCommon} ${classes.pauseButtonInTrackListPlaying} ${deviceStatus?.state !== 'playing' ? classes.currentControlButton : ''}`}
|
||||
onClick={event => {handleCurrentClick(event); event.stopPropagation()}} />
|
||||
</span> :
|
||||
<span>
|
||||
<span className={classes.trackIndex}>{track.index + 1}</span>
|
||||
<PlayArrowIcon
|
||||
className={`${classes.controlButtonInTrackCommon} ${classes.playButtonInTrackListNotPlaying}`}
|
||||
onClick={event => {handlePlayTrack(event, track.index); event.stopPropagation();}}
|
||||
/>
|
||||
</span>}
|
||||
</TableCell>
|
||||
<TableCell className={classes.titleCell} title={track.title}>
|
||||
{track.title || `No Title`}
|
||||
</TableCell>
|
||||
|
|
|
@ -6,6 +6,7 @@ import PlayArrowIcon from '@material-ui/icons/PlayArrow';
|
|||
import StopIcon from '@material-ui/icons/Stop';
|
||||
import SkipNextIcon from '@material-ui/icons/SkipNext';
|
||||
import SkipPreviousIcon from '@material-ui/icons/SkipPrevious';
|
||||
import PauseIcon from '@material-ui/icons/Pause';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
|
||||
const useStyles = makeStyles(theme => ({
|
||||
|
@ -32,6 +33,7 @@ export const W95Controls = (props: {
|
|||
handlePrev: () => void;
|
||||
handlePlay: () => void;
|
||||
handleStop: () => void;
|
||||
handlePause: () => void;
|
||||
handleNext: () => void;
|
||||
message: string;
|
||||
discPresent: boolean;
|
||||
|
@ -49,6 +51,9 @@ export const W95Controls = (props: {
|
|||
<Button onClick={props.handlePlay}>
|
||||
<PlayArrowIcon />
|
||||
</Button>
|
||||
<Button onClick={props.handlePause}>
|
||||
<PauseIcon />
|
||||
</Button>
|
||||
<Button onClick={props.handleStop}>
|
||||
<StopIcon />
|
||||
</Button>
|
||||
|
|
|
@ -14,7 +14,7 @@ import * as mm from 'music-metadata-browser';
|
|||
import { TitleFormatType, UploadFormat } from './convert-dialog-feature';
|
||||
import NotificationCompleteIconUrl from '../images/record-complete-notification-icon.png';
|
||||
|
||||
export function control(action: 'play' | 'stop' | 'next' | 'prev' | 'goto', params?: unknown) {
|
||||
export function control(action: 'play' | 'stop' | 'next' | 'prev' | 'goto' | 'pause', params?: unknown) {
|
||||
return async function(dispatch: AppDispatch, getState: () => RootState) {
|
||||
switch (action) {
|
||||
case 'play':
|
||||
|
@ -29,8 +29,11 @@ export function control(action: 'play' | 'stop' | 'next' | 'prev' | 'goto', para
|
|||
case 'prev':
|
||||
await serviceRegistry.netmdService!.prev();
|
||||
break;
|
||||
case 'pause':
|
||||
await serviceRegistry.netmdService!.pause();
|
||||
break;
|
||||
case 'goto':
|
||||
if (params && typeof params === 'number' && params >= 0) {
|
||||
if (params !== null && params !== undefined && typeof params === 'number' && params >= 0) {
|
||||
await serviceRegistry.netmdService!.gotoTrack(params);
|
||||
}
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue