Skip to content

[UX] Add an 'only' action to select one store/platform only #3294

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 10, 2023
Merged
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
2 changes: 2 additions & 0 deletions public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,8 @@
"header": {
"all_categories": "All Categories",
"filters": "Filters",
"only": "only",
"reset": "Reset",
"show_available_games": "Show non-Available games",
"show_favourites_only": "Show Favourites only",
"show_hidden": "Show Hidden",
Expand Down
34 changes: 33 additions & 1 deletion src/frontend/components/UI/LibraryFilters/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
max-height: 0;
overflow: hidden;
gap: 0.3rem;
padding: 1rem 0;
padding: 1rem 0.5rem 1rem 0;

.toggleSwitchWrapper {
white-space: nowrap;
padding-inline-end: 1rem;
Expand All @@ -33,10 +34,18 @@
color: var(--accent);
}
}

& hr {
width: 80%;
}
& button[type='reset'] {
margin-inline-start: 0.5rem;
align-self: center;
font-size: 1rem;
padding: 0.3rem 0.8rem;
}
}

&:focus-within,
&:hover,
&:has(.dropdown:hover),
Expand All @@ -48,6 +57,29 @@
box-shadow: 4px 5px 5px 7px rgba(0, 0, 0, 0.2);
}
}

.toggleWithOnly {
display: flex;

& label {
flex-grow: 1;
}
.only {
opacity: 0.01;
background: none;
border: none;
color: var(--text);
text-decoration: underline;
cursor: pointer;
&:hover {
color: var(--accent);
}
}
&:hover .only,
&:focus-within .only {
opacity: 1;
}
}
}

body.isRTL .libraryFilters .dropdown {
Expand Down
90 changes: 82 additions & 8 deletions src/frontend/components/UI/LibraryFilters/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ export default function LibraryFilters() {
showInstalledOnly,
showNonAvailable,
storesFilters,
toggleStoreFilter,
setStoresFilters,
platformsFilters,
togglePlatformFilter
setPlatformsFilters
} = useContext(LibraryContext)

const toggleShowHidden = () => {
Expand All @@ -47,12 +47,51 @@ export default function LibraryFilters() {
setShowInstalledOnly(!showInstalledOnly)
}

const toggleStoreFilter = (store: Category) => {
const currentValue = storesFilters[store]
const newFilters = { ...storesFilters, [store]: !currentValue }
setStoresFilters(newFilters)
}

const togglePlatformFilter = (plat: string) => {
const currentValue = platformsFilters[plat]
const newFilters = { ...platformsFilters, [plat]: !currentValue }
setPlatformsFilters(newFilters)
}

const setPlatformOnly = (plat: string) => {
let newFilters = { win: false, linux: false, mac: false, browser: false }
newFilters = { ...newFilters, [plat]: true }
setPlatformsFilters(newFilters)
}
const setStoreOnly = (store: Category) => {
let newFilters = {
legendary: false,
gog: false,
nile: false,
sideload: false
}
newFilters = { ...newFilters, [store]: true }
setStoresFilters(newFilters)
}

const toggleWithOnly = (toggle: JSX.Element, onOnlyClicked: () => void) => {
return (
<div className="toggleWithOnly">
{toggle}
<button className="only" onClick={() => onOnlyClicked()}>
{t('header.only', 'only')}
</button>
</div>
)
}

// t('platforms.browser', 'Browser')
// t('platforms.linux', 'Linux')
// t('platforms.mac', 'Mac')
// t('platforms.win', 'Windows')
const platformToggle = (plat: string) => {
return (
const toggle = (
<ToggleSwitch
key={plat}
htmlId={plat}
Expand All @@ -61,14 +100,20 @@ export default function LibraryFilters() {
title={t(`platforms.${plat}`)}
/>
)

const onOnlyClick = () => {
setPlatformOnly(plat)
}

return toggleWithOnly(toggle, onOnlyClick)
}

// t('Epic Games', 'Epic Games')
// t('GOG', 'GOG')
// t('Amazon Games', 'Amazon Games')
// t('Other', 'Other')
const storeToggle = (store: string) => {
return (
const storeToggle = (store: Category) => {
const toggle = (
<ToggleSwitch
key={store}
htmlId={store}
Expand All @@ -77,13 +122,34 @@ export default function LibraryFilters() {
title={t(RunnerToStore[store])}
/>
)
const onOnlyClick = () => {
setStoreOnly(store)
}
return toggleWithOnly(toggle, onOnlyClick)
}

const resetFilters = () => {
setStoresFilters({
legendary: true,
gog: true,
nile: true,
sideload: true
})
setPlatformsFilters({
win: true,
linux: true,
mac: true,
browser: true
})
setShowHidden(true)
setShowNonAvailable(true)
setShowFavourites(false)
setShowInstalledOnly(false)
}

return (
<div className="libraryFilters">
<button className="button is-primary">
{t('header.filters', 'Filters')}
</button>
<button className="selectStyle">{t('header.filters', 'Filters')}</button>
<div className="dropdown">
{epic.username && storeToggle('legendary')}
{gog.username && storeToggle('gog')}
Expand Down Expand Up @@ -127,6 +193,14 @@ export default function LibraryFilters() {
value={showInstalledOnly}
title={t('header.show_installed_only', 'Show Installed only')}
/>
<hr />
<button
type="reset"
className="button is-primary"
onClick={() => resetFilters()}
>
{t('header.reset', 'Reset')}
</button>
</div>
</div>
)
Expand Down
7 changes: 6 additions & 1 deletion src/frontend/components/UI/SelectField/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
grid-template-areas: 'label' 'select';
}

.selectFieldWrapper select {
.selectFieldWrapper select,
.selectStyle {
border-radius: var(--space-3xs);
grid-area: select;
width: 100%;
Expand Down Expand Up @@ -43,6 +44,10 @@
min-width: 100px;
}

.selectStyle {
padding-inline-end: 4rem;
}

.selectFieldWrapper.isRTL select {
background-position:
calc(15px) calc(50% + 1px),
Expand Down
4 changes: 2 additions & 2 deletions src/frontend/screens/Library/LibraryContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ const initialContext: LibraryContextType = {
storesFilters: { legendary: true, gog: true, nile: true, sideload: true },
platformsFilters: { win: true, linux: true, mac: true, browser: true },
filterText: '',
toggleStoreFilter: () => null,
setStoresFilters: () => null,
handleLayout: () => null,
togglePlatformFilter: () => null,
setPlatformsFilters: () => null,
handleSearch: () => null,
layout: 'grid',
showHidden: false,
Expand Down
20 changes: 8 additions & 12 deletions src/frontend/screens/Library/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,14 +86,12 @@ export default React.memo(function Library(): JSX.Element {
}
}

const [storesFilters, setStoresFilters] =
const [storesFilters, setStoresFilters_] =
useState<StoresFilters>(initialStoresfilters)

const toggleStoreFilter = (store: Category) => {
const currentValue = storesFilters[store]
const newFilters = { ...storesFilters, [store]: !currentValue }
const setStoresFilters = (newFilters: StoresFilters) => {
storage.setItem('storesFilters', JSON.stringify(newFilters))
setStoresFilters(newFilters)
setStoresFilters_(newFilters)
}

let initialPlatformsfilters
Expand All @@ -115,15 +113,13 @@ export default React.memo(function Library(): JSX.Element {
}
}

const [platformsFilters, setPlatformsFilters] = useState<PlatformsFilters>(
const [platformsFilters, setPlatformsFilters_] = useState<PlatformsFilters>(
initialPlatformsfilters
)

const togglePlatformFilter = (platform: string) => {
const currentValue = platformsFilters[platform]
const newFilters = { ...platformsFilters, [platform]: !currentValue }
const setPlatformsFilters = (newFilters: PlatformsFilters) => {
storage.setItem('platformsFilters', JSON.stringify(newFilters))
setPlatformsFilters(newFilters)
setPlatformsFilters_(newFilters)
}

const [filterText, setFilterText] = useState('')
Expand Down Expand Up @@ -534,9 +530,9 @@ export default React.memo(function Library(): JSX.Element {
showInstalledOnly,
showNonAvailable,
filterText,
toggleStoreFilter,
setStoresFilters,
handleLayout: handleLayout,
togglePlatformFilter,
setPlatformsFilters,
handleSearch: setFilterText,
setShowHidden: handleShowHidden,
setShowFavourites: handleShowFavourites,
Expand Down
4 changes: 2 additions & 2 deletions src/frontend/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,8 @@ export interface LibraryContextType {
storesFilters: StoresFilters
platformsFilters: PlatformsFilters
filterText: string
toggleStoreFilter: (store: Category) => void
togglePlatformFilter: (platform: string) => void
setStoresFilters: (filters: StoresFilters) => void
setPlatformsFilters: (filters: PlatformsFilters) => void
handleLayout: (value: string) => void
handleSearch: (input: string) => void
layout: string
Expand Down