diff --git a/src/components/controls.tsx b/src/components/controls.tsx
index fe2e163..8638f23 100644
--- a/src/components/controls.tsx
+++ b/src/components/controls.tsx
@@ -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 = () => {
+
+
+
@@ -228,7 +248,7 @@ export const Controls = () => {
{message}
-
{discPresent && }
+ {discPresent && }
);
diff --git a/src/components/main.tsx b/src/components/main.tsx
index 7b0ec6c..35765fa 100644
--- a/src/components/main.tsx
+++ b/src/components/main.tsx
@@ -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([]);
@@ -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}
>
- {track.index + 1}
+
+ {track.index === deviceStatus?.track ?
+
+ {handleCurrentClick(event); event.stopPropagation();}} />
+ {handleCurrentClick(event); event.stopPropagation()}} />
+ :
+
+ {track.index + 1}
+ {handlePlayTrack(event, track.index); event.stopPropagation();}}
+ />
+ }
+
{track.title || `No Title`}
diff --git a/src/components/win95/controls.tsx b/src/components/win95/controls.tsx
index ab215c7..901fbea 100644
--- a/src/components/win95/controls.tsx
+++ b/src/components/win95/controls.tsx
@@ -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: {
+
diff --git a/src/redux/actions.ts b/src/redux/actions.ts
index 451258d..3874009 100644
--- a/src/redux/actions.ts
+++ b/src/redux/actions.ts
@@ -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;