feat: initial implementation of album lists

This commit is contained in:
Deluan
2020-03-28 23:25:49 -04:00
parent fec8b5f731
commit 46f4f63212
5 changed files with 105 additions and 20 deletions
+1
View File
@@ -24,6 +24,7 @@ func NewAlbumRepository(ctx context.Context, o orm.Ormer) model.AlbumRepository
r.tableName = "album" r.tableName = "album"
r.sortMappings = map[string]string{ r.sortMappings = map[string]string{
"artist": "compilation asc, album_artist asc, name asc", "artist": "compilation asc, album_artist asc, name asc",
"random": "RANDOM()",
} }
r.filterMappings = map[string]filterFunc{ r.filterMappings = map[string]filterFunc{
"name": fullTextFilter, "name": fullTextFilter,
+50 -1
View File
@@ -1,11 +1,31 @@
import React from 'react' import React from 'react'
import { GridList, GridListTile, GridListTileBar } from '@material-ui/core' import { useDispatch, useSelector } from 'react-redux'
import {
GridList,
GridListTile,
GridListTileBar,
Tabs,
Tab
} from '@material-ui/core'
import { makeStyles } from '@material-ui/core/styles' import { makeStyles } from '@material-ui/core/styles'
import withWidth from '@material-ui/core/withWidth' import withWidth from '@material-ui/core/withWidth'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import { linkToRecord } from 'ra-core' import { linkToRecord } from 'ra-core'
import { Loading } from 'react-admin' import { Loading } from 'react-admin'
import { subsonicUrl } from '../subsonic' import { subsonicUrl } from '../subsonic'
import AllInclusiveIcon from '@material-ui/icons/AllInclusive'
import ShuffleIcon from '@material-ui/icons/Shuffle'
import StarIcon from '@material-ui/icons/Star'
import LibraryAddIcon from '@material-ui/icons/LibraryAdd'
import VideoLibraryIcon from '@material-ui/icons/VideoLibrary'
import {
ALBUM_LIST_ALL,
ALBUM_LIST_NEWEST,
ALBUM_LIST_RANDOM,
ALBUM_LIST_RECENT,
ALBUM_LIST_STARRED,
selectAlbumList
} from './albumState'
const useStyles = makeStyles((theme) => ({ const useStyles = makeStyles((theme) => ({
root: { root: {
@@ -38,10 +58,39 @@ const getColsForWidth = (width) => {
return 7 return 7
} }
const tabOrder = [
ALBUM_LIST_ALL,
ALBUM_LIST_RANDOM,
ALBUM_LIST_NEWEST,
ALBUM_LIST_RECENT,
ALBUM_LIST_STARRED
]
const LoadedAlbumGrid = ({ ids, data, basePath, width }) => { const LoadedAlbumGrid = ({ ids, data, basePath, width }) => {
const classes = useStyles() const classes = useStyles()
const dispatch = useDispatch()
const albumView = useSelector((state) => state.albumView)
const tabSelected = tabOrder.indexOf(albumView.list)
const handleChange = (event, newValue) => {
dispatch(selectAlbumList(tabOrder[newValue]))
}
return ( return (
<div className={classes.root}> <div className={classes.root}>
<Tabs
value={tabSelected}
indicatorColor="primary"
textColor="primary"
aria-label="disabled tabs example"
onChange={handleChange}
>
<Tab label="All" icon={<AllInclusiveIcon />} />
<Tab label="Random" icon={<ShuffleIcon />} />
<Tab label="Newest" icon={<LibraryAddIcon />} />
<Tab label="Recently Played" icon={<VideoLibraryIcon />} />
<Tab label="Starred" icon={<StarIcon />} disabled={true} />
</Tabs>
<GridList <GridList
cellHeight={'auto'} cellHeight={'auto'}
cols={getColsForWidth(width)} cols={getColsForWidth(width)}
+4 -6
View File
@@ -15,7 +15,7 @@ import { withWidth } from '@material-ui/core'
import AlbumListActions from './AlbumListActions' import AlbumListActions from './AlbumListActions'
import AlbumListView from './AlbumListView' import AlbumListView from './AlbumListView'
import AlbumGridView from './AlbumGridView' import AlbumGridView from './AlbumGridView'
import { ALBUM_LIST_MODE } from './albumState' import { ALBUM_MODE_LIST } from './albumState'
const AlbumFilter = (props) => ( const AlbumFilter = (props) => (
<Filter {...props}> <Filter {...props}>
@@ -58,17 +58,15 @@ const AlbumList = (props) => {
<List <List
{...props} {...props}
title={<Title subTitle={'Albums'} />} title={<Title subTitle={'Albums'} />}
sort={{ field: 'name', order: 'ASC' }} sort={albumView.params.sort}
exporter={false} exporter={false}
bulkActionButtons={false} bulkActionButtons={false}
actions={<AlbumListActions />} actions={<AlbumListActions />}
filters={<AlbumFilter />} filters={<AlbumFilter />}
perPage={getPerPage(width)} perPage={getPerPage(width)}
pagination={ pagination={<Pagination rowsPerPageOptions={getPerPageOptions(width)} />}
<Pagination rowsPerPageOptions={getPerPageOptions(width)} {...props} />
}
> >
{albumView.mode === ALBUM_LIST_MODE ? ( {albumView.mode === ALBUM_MODE_LIST ? (
<AlbumListView {...props} /> <AlbumListView {...props} />
) : ( ) : (
<AlbumGridView {...props} /> <AlbumGridView {...props} />
+5 -5
View File
@@ -4,7 +4,7 @@ import { ButtonGroup } from '@material-ui/core'
import ViewHeadlineIcon from '@material-ui/icons/ViewHeadline' import ViewHeadlineIcon from '@material-ui/icons/ViewHeadline'
import ViewModuleIcon from '@material-ui/icons/ViewModule' import ViewModuleIcon from '@material-ui/icons/ViewModule'
import { useDispatch, useSelector } from 'react-redux' import { useDispatch, useSelector } from 'react-redux'
import { ALBUM_GRID_MODE, ALBUM_LIST_MODE, selectViewMode } from './albumState' import { ALBUM_MODE_GRID, ALBUM_MODE_LIST, selectViewMode } from './albumState'
const AlbumListActions = ({ const AlbumListActions = ({
currentSort, currentSort,
@@ -44,15 +44,15 @@ const AlbumListActions = ({
> >
<Button <Button
size="small" size="small"
color={albumView.mode === ALBUM_LIST_MODE ? 'primary' : 'secondary'} color={albumView.mode === ALBUM_MODE_LIST ? 'primary' : 'secondary'}
onClick={() => dispatch(selectViewMode(ALBUM_LIST_MODE))} onClick={() => dispatch(selectViewMode(ALBUM_MODE_LIST))}
> >
<ViewHeadlineIcon fontSize="inherit" /> <ViewHeadlineIcon fontSize="inherit" />
</Button> </Button>
<Button <Button
size="small" size="small"
color={albumView.mode === ALBUM_GRID_MODE ? 'primary' : 'secondary'} color={albumView.mode === ALBUM_MODE_GRID ? 'primary' : 'secondary'}
onClick={() => dispatch(selectViewMode(ALBUM_GRID_MODE))} onClick={() => dispatch(selectViewMode(ALBUM_MODE_GRID))}
> >
<ViewModuleIcon fontSize="inherit" /> <ViewModuleIcon fontSize="inherit" />
</Button> </Button>
+45 -8
View File
@@ -1,23 +1,60 @@
const ALBUM_GRID_MODE = 'ALBUM_GRID_MODE' const ALBUM_MODE_GRID = 'ALBUM_GRID_MODE'
const ALBUM_LIST_MODE = 'ALBUM_LIST_MODE' const ALBUM_MODE_LIST = 'ALBUM_LIST_MODE'
const selectViewMode = (mode) => ({ type: mode }) const selectViewMode = (mode) => ({ type: mode })
const ALBUM_LIST_ALL = 'ALBUM_LIST_ALL'
const ALBUM_LIST_RANDOM = 'ALBUM_LIST_RANDOM'
const ALBUM_LIST_NEWEST = 'ALBUM_LIST_NEWEST'
const ALBUM_LIST_RECENT = 'ALBUM_LIST_RECENT'
const ALBUM_LIST_STARRED = 'ALBUM_LIST_STARRED'
const albumListParams = {
ALBUM_LIST_ALL: { sort: { field: 'name', order: 'ASC' } },
ALBUM_LIST_RANDOM: { sort: { field: 'random' } },
ALBUM_LIST_NEWEST: { sort: { field: 'created_at', order: 'DESC' } },
ALBUM_LIST_RECENT: {
sort: { field: 'starred_at', order: 'DESC' },
filter: { starred: true }
}
}
const selectAlbumList = (mode) => ({ type: mode })
const albumViewReducer = ( const albumViewReducer = (
previousState = { previousState = {
mode: localStorage.getItem('albumViewMode') || ALBUM_LIST_MODE mode: localStorage.getItem('albumViewMode') || ALBUM_MODE_LIST,
list: localStorage.getItem('albumListType') || ALBUM_LIST_ALL,
params: { sort: {}, filter: {} }
}, },
payload payload
) => { ) => {
const { type } = payload const { type } = payload
switch (type) { switch (type) {
case ALBUM_GRID_MODE: case ALBUM_MODE_GRID:
case ALBUM_LIST_MODE: case ALBUM_MODE_LIST:
localStorage.setItem('albumViewMode', type) localStorage.setItem('albumViewMode', type)
return { mode: type } return { ...previousState, mode: type }
case ALBUM_LIST_ALL:
case ALBUM_LIST_RANDOM:
case ALBUM_LIST_NEWEST:
case ALBUM_LIST_RECENT:
case ALBUM_LIST_STARRED:
localStorage.setItem('albumListType', type)
return { ...previousState, list: type, params: albumListParams[type] }
default: default:
return previousState return previousState
} }
} }
export { ALBUM_LIST_MODE, ALBUM_GRID_MODE, albumViewReducer, selectViewMode } export {
ALBUM_MODE_LIST,
ALBUM_MODE_GRID,
ALBUM_LIST_ALL,
ALBUM_LIST_RANDOM,
ALBUM_LIST_NEWEST,
ALBUM_LIST_RECENT,
ALBUM_LIST_STARRED,
albumViewReducer,
selectViewMode,
selectAlbumList
}