Skip to content

Commit

Permalink
Added play / shuffle actions on Search and Label view
Browse files Browse the repository at this point in the history
  • Loading branch information
chronoDave committed May 5, 2019
1 parent 494d54e commit e534975
Show file tree
Hide file tree
Showing 17 changed files with 207 additions and 52 deletions.
2 changes: 0 additions & 2 deletions public/actions/populateDatabase.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,6 @@ module.exports = function populateDatabase(Database, rootFolder, sender) {
batchCounterSong = 0;
payloadSong.clear();
}

next();
});
}
next();
Expand Down
20 changes: 10 additions & 10 deletions public/events/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,30 @@ const { populateDatabase } = require('../actions');

module.exports = {
ipcListener(Database) {
ipcMain.on('FETCH_ALL', (event, view) => {
Database.songs.find({}).sort({ label: 1, album: 2, track: 3, year: 4 }).exec((err, payload) => {
ipcMain.on('FETCH_ALL', (event, payload) => {
Database.songs.find({}).sort(Object.assign({}, ...payload.options)).exec((err, songs) => {
if (err) throw Error(err);

const albums = _.values(_.mapValues(_.groupBy(payload, 'album')));
const labels = _.values(_.mapValues(_.groupBy(payload, 'label')));
const albums = _.values(_.mapValues(_.groupBy(songs, 'album')));
const labels = _.values(_.mapValues(_.groupBy(songs, 'label')));

switch (view) {
switch (payload.view) {
case 'VIEW_LABEL':
event.sender.send('RECEIVE_COLLECTION', {
type: view,
type: payload.view,
payload: labels
});
break;
case 'VIEW_ALBUM':
event.sender.send('RECEIVE_COLLECTION', {
type: view,
type: payload.view,
payload: albums
});
break;
case 'VIEW_SONG':
event.sender.send('RECEIVE_COLLECTION', {
type: view,
payload
type: payload.view,
payload: songs
});
break;
default:
Expand All @@ -39,7 +39,7 @@ module.exports = {
payload: {
label: labels.length,
album: albums.length,
song: payload.length
song: songs.length
}
});
});
Expand Down
8 changes: 6 additions & 2 deletions src/actions/fetchActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@ import {
// eslint-disable-next-line no-undef
const { ipcRenderer } = window.require('electron');

export const fetchAll = view => dispatch => {
export const fetchAll = (view, options) => dispatch => {
dispatch({ type: FETCH_ALL });
ipcRenderer.send(FETCH_ALL, view);

ipcRenderer.send(FETCH_ALL, {
view,
options: options || [{ label: 1 }, { album: 1 }, { track: 1 }, { year: 1 }]
});
};

export const fetchBackground = () => dispatch => {
Expand Down
19 changes: 14 additions & 5 deletions src/components/Drawer/AlbumDrawer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import PropTypes from 'prop-types';
import PlayIcon from '@material-ui/icons/PlayArrow';
import ShuffleIcon from '@material-ui/icons/Shuffle';
import AddPlaylistIcon from '@material-ui/icons/PlaylistAdd';
import AddIcon from '@material-ui/icons/AddCircle';

// Core
import withStyles from '@material-ui/core/styles/withStyles';
Expand Down Expand Up @@ -194,11 +195,19 @@ const AlbumDrawer = props => {
}}
/>
<ListItemSecondaryAction>
<ListItemText
primary={getDurationFormat(song.duration)}
primaryTypographyProps={{ variant: 'caption' }}
classes={{ primary: classes.light }}
/>
<GridContainer direction="column" alignItems="center">
<ListItemText
primary={getDurationFormat(song.duration)}
primaryTypographyProps={{ variant: 'caption' }}
classes={{ primary: classes.light }}
/>
<ListItemIcon
classes={{ root: classes.light }}
onClick={() => addToPlaylist([song])}
>
<AddIcon />
</ListItemIcon>
</GridContainer>
</ListItemSecondaryAction>
</ListItem>
))}
Expand Down
17 changes: 17 additions & 0 deletions src/components/Icons/SortIcon.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react';

// Core
import SvgIcon from '@material-ui/core/SvgIcon';

const SortIcon = props => {
const { ...rest } = props;

return (
<SvgIcon {...rest}>
{/* eslint-disable-next-line max-len */}
<path d="M10,13V11H18V13H10M10,19V17H14V19H10M10,7V5H22V7H10M6,17H8.5L5,20.5L1.5,17H4V7H1.5L5,3.5L8.5,7H6V17Z" />
</SvgIcon>
);
};

export default SortIcon;
4 changes: 3 additions & 1 deletion src/components/Icons/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import DatabaseAddIcon from './DatabaseAddIcon';
import DatabaseUpdateIcon from './DatabaseUpdateIcon';
import DatabaseRemoveIcon from './DatabaseRemoveIcon';
import SortIcon from './SortIcon';

export {
DatabaseAddIcon,
DatabaseUpdateIcon,
DatabaseRemoveIcon
DatabaseRemoveIcon,
SortIcon
};
17 changes: 9 additions & 8 deletions src/components/Main/Main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,15 @@ import { deleteDatabase, setDatabaseCreated } from '../../actions/databaseAction
import { setPlaylist } from '../../actions/playlistActions';
import { setSong, setStatus, setPosition } from '../../actions/songActions';

// Types
// Utils
import {
VIEW_PLAYLIST,
VIEW_LABEL,
VIEW_ALBUM,
VIEW_SONG,
VIEW_SEARCH
} from '../../actionTypes/windowTypes';

// Img
// import MainBackgroundImage from '../../assets/images/bg.jpg';
import { cleanUrl } from '../../utils';

// Style
import MainStyle from './MainStyle';
Expand Down Expand Up @@ -109,10 +107,13 @@ class Main extends Component {
}
}

// Set playlist on next/previous song or shuffle
// Set playlist on next/previous song or shuffle, but keep the same on playlist add
if (
prevProps.playlistIndex !== playlistIndex
|| prevProps.playlist !== playlist
|| (
prevProps.playlist !== playlist
&& prevProps.playlist.length === playlist.length
)
) {
setCurrentSong(playlist[playlistIndex]);
}
Expand Down Expand Up @@ -197,7 +198,7 @@ class Main extends Component {
<div
className={classes.root}
style={{
backgroundImage: `url("file://${backgroundImage}")`,
backgroundImage: `url("file://${cleanUrl(backgroundImage || '')}")`,
backgroundRepeat: 'no-repeat',
backgroundSize: 'cover',
}}
Expand Down Expand Up @@ -276,7 +277,7 @@ const mapStateToProps = state => ({
const mapDispatchToProps = dispatch => ({
setSongStatus: status => dispatch(setStatus(status)),
setSongPosition: position => dispatch(setPosition(position)),
getAll: view => dispatch(fetchAll(view)),
getAll: (view, options) => dispatch(fetchAll(view, options)),
getBackgroundImage: () => dispatch(fetchBackground()),
setCurrentPlaylist: collection => dispatch(setPlaylist(collection)),
setCurrentSong: song => dispatch(setSong(song)),
Expand Down
25 changes: 19 additions & 6 deletions src/components/ViewItem/SongItem.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import React from 'react';
import PropTypes from 'prop-types';

// Icons
import AddIcon from '@material-ui/icons/AddCircle';

// Core
import withStyles from '@material-ui/core/styles/withStyles';
import ListItem from '@material-ui/core/ListItem';
import ListItemText from '@material-ui/core/ListItemText';
import ListItemIcon from '@material-ui/core/ListItemIcon';

import { GridContainer, GridItem } from '../Grid';

Expand All @@ -25,19 +29,18 @@ const SongItem = props => {
duration,
classes,
active,
onAddPlaylist,
disableIcon
} = props;

return (
<div style={style}>
<ListItem
button
onClick={onClick}
className={active ? classes.active : undefined}
>
<ListItem className={active ? classes.active : undefined}>
<GridContainer
wrap="nowrap"
justify="space-between"
alignItems="center"
onClick={onClick}
>
<GridItem xs={3}>
<ListItemText
Expand Down Expand Up @@ -76,6 +79,14 @@ const SongItem = props => {
primary={getDurationFormat(duration)}
/>
</GridContainer>
{!disableIcon && (
<ListItemIcon
onClick={() => onAddPlaylist()}
classes={{ root: classes.white }}
>
<AddIcon />
</ListItemIcon>
)}
</ListItem>
</div>
);
Expand All @@ -90,7 +101,9 @@ SongItem.propTypes = {
label: PropTypes.string,
duration: PropTypes.number,
classes: PropTypes.object.isRequired,
active: PropTypes.bool
active: PropTypes.bool,
onAddPlaylist: PropTypes.func,
disableIcon: PropTypes.bool
};

export default withStyles(SongItemStyle)(SongItem);
3 changes: 3 additions & 0 deletions src/components/ViewItem/SongItemStyle.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ const SongItemStyle = theme => createStyles({
},
duration: {
maxWidth: 60
},
white: {
color: theme.palette.grey[50]
}
});

Expand Down
2 changes: 1 addition & 1 deletion src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import store from './store';

ReactDOM.render(
<Provider store={store}>
<SnackbarProvider maxSnack={5}>
<SnackbarProvider maxSnack={5} dense>
<IpcListener />
<App />
</SnackbarProvider>
Expand Down
3 changes: 0 additions & 3 deletions src/reducers/windowReducer.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import {
VIEW_ALBUM,
VIEW_SONG,
VIEW_LABEL,
VIEW_PLAYLIST,
SET_VIEW,
TOGGLE_DRAWER
} from '../actionTypes/windowTypes';
Expand Down
59 changes: 54 additions & 5 deletions src/views/LabelView.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,66 @@ import AutoSizer from 'react-virtualized-auto-sizer';
import { connect } from 'react-redux';
import _ from 'lodash';

// Icons
import PlayIcon from '@material-ui/icons/PlayArrow';
import ShuffleIcon from '@material-ui/icons/Shuffle';

// Core
import withStyles from '@material-ui/core/styles/withStyles';
import IconButton from '@material-ui/core/IconButton';

import ViewHeader from '../components/ViewHeader/ViewHeader';
import { LabelItem } from '../components/ViewItem';

// Actions
import { setStatus, setPosition } from '../actions/songActions';
import { shufflePlaylist, setPlaylist } from '../actions/playlistActions';

// Style
import LabelViewStyle from './LabelViewStyle';

const LabelView = props => {
const {
classes,
size,
labelList
labelList,
setCurrentPlaylist,
resetPosition,
setPlaying,
shuffle,
} = props;

const handlePlay = () => {
const collection = labelList.reduce((acc, val) => acc.concat(val), []);
setCurrentPlaylist(collection);
resetPosition();
setPlaying();
};

const handleShuffle = () => {
handlePlay();
shuffle();
};

return (
<div className={classes.root}>
<ViewHeader
size={size}
title="Label collection"
type="labels"
>
a
<IconButton
classes={{ root: classes.icon }}
onClick={() => handlePlay()}
>
<PlayIcon />
</IconButton>
<IconButton
classes={{ root: classes.icon }}
onClick={() => handleShuffle()}
>
<ShuffleIcon />
</IconButton>
</ViewHeader>
<AutoSizer>
{({ height, width }) => {
Expand Down Expand Up @@ -86,15 +122,28 @@ const LabelView = props => {

const mapStateToProps = state => ({
size: state.list.labelSize,
labelList: state.list.labelList
labelList: state.list.labelList,
view: state.window.view
});

const mapDispatchToProps = dispatch => ({
setPlaying: () => dispatch(setStatus('PLAYING')),
resetPosition: () => dispatch(setPosition(0)),
setCurrentPlaylist: collection => dispatch(setPlaylist(collection)),
shuffle: () => dispatch(shufflePlaylist()),
});

LabelView.propTypes = {
classes: PropTypes.object.isRequired,
size: PropTypes.number,
labelList: PropTypes.array
labelList: PropTypes.array,
setCurrentPlaylist: PropTypes.func,
resetPosition: PropTypes.func,
setPlaying: PropTypes.func,
shuffle: PropTypes.func,
};

export default connect(
mapStateToProps
mapStateToProps,
mapDispatchToProps
)(withStyles(LabelViewStyle)(LabelView));
5 changes: 4 additions & 1 deletion src/views/LabelViewStyle.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ const LabelViewStyle = theme => createStyles({
height: '100%',
paddingLeft: theme.spacing.unit * 4
},
scrollbar: theme.scrollbar
scrollbar: theme.scrollbar,
icon: {
color: theme.palette.grey[50]
}
});

export default LabelViewStyle;
Loading

0 comments on commit e534975

Please sign in to comment.