diff --git a/persistence/album_repository.go b/persistence/album_repository.go
index 8259533f..6a131e4b 100644
--- a/persistence/album_repository.go
+++ b/persistence/album_repository.go
@@ -24,6 +24,7 @@ func NewAlbumRepository(ctx context.Context, o orm.Ormer) model.AlbumRepository
r.tableName = "album"
r.sortMappings = map[string]string{
"artist": "compilation asc, album_artist asc, name asc",
+ "random": "RANDOM()",
}
r.filterMappings = map[string]filterFunc{
"name": fullTextFilter,
diff --git a/ui/src/album/AlbumGridView.js b/ui/src/album/AlbumGridView.js
index a5298465..45088389 100644
--- a/ui/src/album/AlbumGridView.js
+++ b/ui/src/album/AlbumGridView.js
@@ -1,11 +1,31 @@
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 withWidth from '@material-ui/core/withWidth'
import { Link } from 'react-router-dom'
import { linkToRecord } from 'ra-core'
import { Loading } from 'react-admin'
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) => ({
root: {
@@ -38,10 +58,39 @@ const getColsForWidth = (width) => {
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 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 (
+
+ } />
+ } />
+ } />
+ } />
+ } disabled={true} />
+
(
@@ -58,17 +58,15 @@ const AlbumList = (props) => {
}
- sort={{ field: 'name', order: 'ASC' }}
+ sort={albumView.params.sort}
exporter={false}
bulkActionButtons={false}
actions={}
filters={}
perPage={getPerPage(width)}
- pagination={
-
- }
+ pagination={}
>
- {albumView.mode === ALBUM_LIST_MODE ? (
+ {albumView.mode === ALBUM_MODE_LIST ? (
) : (
diff --git a/ui/src/album/AlbumListActions.js b/ui/src/album/AlbumListActions.js
index 739706d5..1dbbcb33 100644
--- a/ui/src/album/AlbumListActions.js
+++ b/ui/src/album/AlbumListActions.js
@@ -4,7 +4,7 @@ import { ButtonGroup } from '@material-ui/core'
import ViewHeadlineIcon from '@material-ui/icons/ViewHeadline'
import ViewModuleIcon from '@material-ui/icons/ViewModule'
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 = ({
currentSort,
@@ -44,15 +44,15 @@ const AlbumListActions = ({
>
diff --git a/ui/src/album/albumState.js b/ui/src/album/albumState.js
index f2ed109a..0eb8e806 100644
--- a/ui/src/album/albumState.js
+++ b/ui/src/album/albumState.js
@@ -1,23 +1,60 @@
-const ALBUM_GRID_MODE = 'ALBUM_GRID_MODE'
-const ALBUM_LIST_MODE = 'ALBUM_LIST_MODE'
-
+const ALBUM_MODE_GRID = 'ALBUM_GRID_MODE'
+const ALBUM_MODE_LIST = 'ALBUM_LIST_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 = (
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
) => {
const { type } = payload
switch (type) {
- case ALBUM_GRID_MODE:
- case ALBUM_LIST_MODE:
+ case ALBUM_MODE_GRID:
+ case ALBUM_MODE_LIST:
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:
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
+}