Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@
"sortAscending": "Sort Ascending",
"sortByStatus": "Sort by Status",
"sortDescending": "Sort Descending",
"sortRandom": "Sort Randomly",
"toggleLayout": {
"grid": "Toggle to a grid layout",
"list": "Toggle to a list layout"
Expand Down
57 changes: 39 additions & 18 deletions src/frontend/components/UI/ActionIcons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import {
faArrowDownZA,
faHardDrive as hardDriveSolid,
faFilter,
faFilterCircleXmark
faFilterCircleXmark,
faShuffle
} from '@fortawesome/free-solid-svg-icons'
import { faHardDrive as hardDriveLight } from '@fortawesome/free-regular-svg-icons'

Expand All @@ -20,6 +21,7 @@ import classNames from 'classnames'
import LibraryContext from 'frontend/screens/Library/LibraryContext'
import TourButton from 'frontend/components/Tour/TourButton'
import { LIBRARY_TOUR_ID } from 'frontend/screens/Library/components/LibraryTour'
import { SortOptions } from 'frontend/types'

interface ActionIconsProps {
'data-tour'?: string
Expand All @@ -34,8 +36,8 @@ export default React.memo(function ActionIcons({
const {
handleLayout,
layout,
sortDescending,
setSortDescending,
currentSort,
setCurrentSort,
sortInstalled,
setSortInstalled,
showAlphabetFilter,
Expand Down Expand Up @@ -70,21 +72,40 @@ export default React.memo(function ActionIcons({
/>
</button>
)}
<button
className="FormControl__button"
title={
sortDescending
? t('library.sortDescending', 'Sort Descending')
: t('library.sortAscending', 'Sort Ascending')
}
onClick={() => setSortDescending(!sortDescending)}
>
<FontAwesomeIcon
className="FormControl__segmentedFaIcon"
icon={sortDescending ? faArrowDownZA : faArrowDownAZ}
data-tour="library-sort-az"
/>
</button>
{currentSort === SortOptions.random ? (
<button
className="FormControl__button"
title={t('library.sortRandom', 'Sort Randomly')}
onClick={() => setCurrentSort(SortOptions.alphaAsc)}
>
<FontAwesomeIcon
className="FormControl__segmentedFaIcon"
icon={faShuffle}
/>
</button>
) : currentSort === SortOptions.alphaDesc ? (
<button
className="FormControl__button"
title={t('library.sortDescending', 'Sort Descending')}
onClick={() => setCurrentSort(SortOptions.random)}
>
<FontAwesomeIcon
className="FormControl__segmentedFaIcon"
icon={faArrowDownZA}
/>
</button>
) : (
<button
className="FormControl__button"
title={t('library.sortAscending', 'Sort Ascending')}
onClick={() => setCurrentSort(SortOptions.alphaDesc)}
>
<FontAwesomeIcon
className="FormControl__segmentedFaIcon"
icon={faArrowDownAZ}
/>
</button>
)}
<button
className="FormControl__button"
title={t('library.sortByStatus', 'Sort by Status')}
Expand Down
6 changes: 3 additions & 3 deletions src/frontend/screens/Library/LibraryContext.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'

import { GameInfo } from 'common/types'
import { LibraryContextType } from 'frontend/types'
import { LibraryContextType, SortOptions } from 'frontend/types'

const initialContext: LibraryContextType = {
storesFilters: {
Expand All @@ -26,8 +26,8 @@ const initialContext: LibraryContextType = {
setShowNonAvailable: () => null,
showInstalledOnly: false,
setShowInstalledOnly: () => null,
sortDescending: true,
setSortDescending: () => null,
currentSort: SortOptions.alphaAsc,
setCurrentSort: () => null,
sortInstalled: true,
setSortInstalled: () => null,
showSupportOfflineOnly: false,
Expand Down
28 changes: 18 additions & 10 deletions src/frontend/screens/Library/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,12 @@ import {
} from 'frontend/helpers/library'
import RecentlyPlayed from './components/RecentlyPlayed'
import LibraryContext from './LibraryContext'
import { Category, PlatformsFilters, StoresFilters } from 'frontend/types'
import {
Category,
PlatformsFilters,
SortOptions,
StoresFilters
} from 'frontend/types'
import { hasHelp } from 'frontend/hooks/hasHelp'
import EmptyLibraryMessage from './components/EmptyLibrary'
import CategoriesManager from './components/CategoriesManager'
Expand Down Expand Up @@ -205,12 +210,12 @@ export default React.memo(function Library(): JSX.Element {
string | null
>(null)

const [sortDescending, setSortDescending] = useState(
JSON.parse(storage?.getItem('sortDescending') || 'false')
const [currentSort, setCurrentSort] = useState<SortOptions>(
(storage?.getItem('currentSort') as SortOptions) || SortOptions.alphaAsc
)
function handleSortDescending(value: boolean) {
storage.setItem('sortDescending', JSON.stringify(value))
setSortDescending(value)
function handleCurrentSort(value: SortOptions) {
storage.setItem('currentSort', JSON.stringify(value))
setCurrentSort(value)
}

const [sortInstalled, setSortInstalled] = useState(
Expand Down Expand Up @@ -607,9 +612,12 @@ export default React.memo(function Library(): JSX.Element {

// sort
library = library.sort((a, b) => {
if (currentSort === SortOptions.random) {
return 0.5 - Math.random()
}
const gameA = a.title.toUpperCase().replace('THE ', '')
const gameB = b.title.toUpperCase().replace('THE ', '')
return sortDescending
return currentSort === SortOptions.alphaDesc
? -gameA.localeCompare(gameB)
: gameA.localeCompare(gameB)
})
Expand All @@ -629,7 +637,7 @@ export default React.memo(function Library(): JSX.Element {
}, [
gamesForAlphabetFilter,
alphabetFilterLetter,
sortDescending,
currentSort,
sortInstalled,
installing
])
Expand Down Expand Up @@ -698,15 +706,15 @@ export default React.memo(function Library(): JSX.Element {
setShowFavourites: handleShowFavourites,
setShowInstalledOnly: handleShowInstalledOnly,
setShowNonAvailable: handleShowNonAvailable,
setSortDescending: handleSortDescending,
setCurrentSort: handleCurrentSort,
setSortInstalled: handleSortInstalled,
showSupportOfflineOnly,
setShowSupportOfflineOnly: handleShowSupportOfflineOnly,
showThirdPartyManagedOnly,
setShowThirdPartyManagedOnly: handleShowThirdPartyOnly,
showUpdatesOnly,
setShowUpdatesOnly: handleShowUpdatesOnly,
sortDescending,
currentSort,
sortInstalled,
handleAddGameButtonClick: () => handleModal('', 'sideload', null),
setShowCategories,
Expand Down
10 changes: 8 additions & 2 deletions src/frontend/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,12 @@ export interface PlatformsFilters {
browser: boolean
}

export enum SortOptions {
alphaAsc = 'alphaAsc',
alphaDesc = 'alphaDesc',
random = 'random'
}

export interface LibraryContextType {
storesFilters: StoresFilters
platformsFilters: PlatformsFilters
Expand All @@ -238,8 +244,8 @@ export interface LibraryContextType {
setShowInstalledOnly: (value: boolean) => void
showNonAvailable: boolean
setShowNonAvailable: (value: boolean) => void
sortDescending: boolean
setSortDescending: (value: boolean) => void
currentSort: SortOptions
setCurrentSort: (value: SortOptions) => void
sortInstalled: boolean
setSortInstalled: (value: boolean) => void
showSupportOfflineOnly: boolean
Expand Down
Loading