From d2b732428c26feda9782ae805b8291e2bdd9552a Mon Sep 17 00:00:00 2001 From: Colin Date: Wed, 31 Jul 2024 20:39:22 +0100 Subject: [PATCH] feat: Platform and Play Mode adv filters --- lang/en.json | 1 + src/renderer/components/Header.tsx | 3 +- src/renderer/components/SearchBar.tsx | 42 ++++++++++++----- src/renderer/components/pages/BrowsePage.tsx | 2 +- src/renderer/store/search/slice.ts | 2 - src/shared/lang.ts | 1 + src/shared/preferences/util.ts | 2 +- src/shared/search/util.ts | 47 +++++++++++++++----- typings/flashpoint-launcher.d.ts | 4 +- 9 files changed, 76 insertions(+), 28 deletions(-) diff --git a/lang/en.json b/lang/en.json index a33683d38..ae759c9bb 100644 --- a/lang/en.json +++ b/lang/en.json @@ -390,6 +390,7 @@ "busy": "Please Wait...", "openGameDataBrowser": "Open Game Data Browser", "allGenericEntries": "All Entries", + "usePlaylistOrder": "Use Playlist Order", "notArchived": "Not Archived", "archived": "Archived", "playOnline": "Play Online" diff --git a/src/renderer/components/Header.tsx b/src/renderer/components/Header.tsx index 7ada4502f..0828ddde9 100644 --- a/src/renderer/components/Header.tsx +++ b/src/renderer/components/Header.tsx @@ -123,7 +123,8 @@ export class Header extends React.Component { customViews, }, true); this.props.searchActions.addViews({ - views: [name] + views: [name], + areLibraries: false, }); setTimeout(() => { this.props.history.push(joinLibraryRoute(name)); diff --git a/src/renderer/components/SearchBar.tsx b/src/renderer/components/SearchBar.tsx index 98a3afac8..ee22e5ee2 100644 --- a/src/renderer/components/SearchBar.tsx +++ b/src/renderer/components/SearchBar.tsx @@ -9,16 +9,16 @@ import { ArrowKeyStepper, AutoSizer, List, ListRowProps } from 'react-virtualize import { AdvancedFilter } from 'flashpoint-launcher'; import { useContext } from 'react'; import { LangContext } from '@renderer/util/lang'; +import { useAppSelector } from '@renderer/hooks/useAppSelector'; -export type SearchBarProps = { - libraries: string[]; -}; +export type SearchBarProps = {}; export function SearchBar(props: SearchBarProps) { const view = useView(); const dispatch = useDispatch(); const [expanded, setExpanded] = React.useState(true); const strings = useContext(LangContext); + const mainState = useAppSelector((state) => state.main); const onTextChange = (event: React.ChangeEvent) => { dispatch(setSearchText({ @@ -113,8 +113,14 @@ export function SearchBar(props: SearchBarProps) { }; }; - const onToggleLibrary = onToggleFactory('libraries'); - const onClearLibraries = onClearFactory('libraries'); + const onToggleLibrary = onToggleFactory('library'); + const onClearLibraries = onClearFactory('library'); + + const onTogglePlayMode = onToggleFactory('playMode'); + const onClearPlayMode = onClearFactory('playMode'); + + const onTogglePlatform = onToggleFactory('platform'); + const onClearPlatform = onClearFactory('platform'); return (
@@ -131,7 +137,7 @@ export function SearchBar(props: SearchBarProps) { } }} ref={searchInputRef} - placeholder="Search" + placeholder={strings.app.searchPlaceholder} className="search-bar-text-input" value={view.text} onChange={onTextChange} /> @@ -157,27 +163,39 @@ export function SearchBar(props: SearchBarProps) { (
{ view.selectedPlaylist && ( )} { window.Shared.preferences.data.useCustomViews && ( { return strings.libraries[item] || item; }}/> )} + +
) } @@ -284,7 +302,7 @@ function SearchableSelect(props: SearchableSelectProps) {
{expanded && (
- +
{(() => { if (this.props.preferencesData.browsePageLayout === BrowsePageLayout.grid) { diff --git a/src/renderer/store/search/slice.ts b/src/renderer/store/search/slice.ts index 9f47651a1..cb982ec97 100644 --- a/src/renderer/store/search/slice.ts +++ b/src/renderer/store/search/slice.ts @@ -7,7 +7,6 @@ import { import { BackIn, PageKeyset, SearchQuery } from '@shared/back/types'; import { VIEW_PAGE_SIZE } from '@shared/constants'; import { getDefaultAdvancedFilter, getDefaultGameSearch } from '@shared/search/util'; -import { num } from '@shared/utils/Coerce'; import { updatePreferencesData } from '@shared/preferences/util'; export const GENERAL_VIEW_ID = '!general!'; @@ -479,7 +478,6 @@ const searchSlice = createSlice({ } }, addData(state: SearchState, { payload }: PayloadAction) { - const startTime = Date.now(); const data = payload.data; console.log(payload); const view = state.views[payload.view]; diff --git a/src/shared/lang.ts b/src/shared/lang.ts index 17375ac27..f20b08b7e 100644 --- a/src/shared/lang.ts +++ b/src/shared/lang.ts @@ -405,6 +405,7 @@ const langTemplate = { 'busy', 'openGameDataBrowser', 'allGenericEntries', + 'usePlaylistOrder', ] as const, tags: [ 'name', diff --git a/src/shared/preferences/util.ts b/src/shared/preferences/util.ts index 040f05222..ea264f04d 100644 --- a/src/shared/preferences/util.ts +++ b/src/shared/preferences/util.ts @@ -393,7 +393,7 @@ function parseGameMetadataSource(parser: IObjectParserProp): function parseAdvancedFilter(parser: IObjectParserProp, output: AdvancedFilter) { parser.prop('installed', v => output.installed = v === undefined ? undefined : !!v, true); - parser.prop('libraries').arrayRaw((item, index) => output.libraries[index] = str(item)); + parser.prop('library').arrayRaw((item, index) => output.library[index] = str(item)); parser.prop('playlistOrder', v => output.playlistOrder = !!v, true); } diff --git a/src/shared/search/util.ts b/src/shared/search/util.ts index f525844a0..0f66b85ca 100644 --- a/src/shared/search/util.ts +++ b/src/shared/search/util.ts @@ -1,4 +1,4 @@ -import { GameFilter, GameSearch } from '@fparchive/flashpoint-archive'; +import { FieldFilter, GameFilter, GameSearch } from '@fparchive/flashpoint-archive'; import { AdvancedFilter } from 'flashpoint-launcher'; export function getDefaultGameSearch(): GameSearch { @@ -22,7 +22,9 @@ export function getDefaultGameSearch(): GameSearch { export function getDefaultAdvancedFilter(library?: string): AdvancedFilter { return { playlistOrder: true, - libraries: library ? [library] : [], + library: library ? [library] : [], + playMode: [], + platform: [], }; } @@ -44,7 +46,9 @@ export function getDefaultGameFilter(): GameFilter { export function isAdvFilterEmpty(advFilter: AdvancedFilter): boolean { return ( advFilter.installed === undefined && - advFilter.libraries.length === 0 + advFilter.library.length === 0 && + advFilter.playMode.length === 0 && + advFilter.platform.length === 0 ); } @@ -55,13 +59,36 @@ export function parseAdvancedFilter(advFilter: AdvancedFilter): GameFilter { filter.boolComp.installed = advFilter.installed; } - if (advFilter.libraries.length > 0) { - console.log(`setting libraries - ${advFilter.libraries.join(' ; ')}`); - const newFilter = getDefaultGameFilter(); - newFilter.matchAny = true; - newFilter.exactWhitelist.library = advFilter.libraries; - filter.subfilters.push(newFilter); - } + const exactFunc = (key: keyof AdvancedFilter, fieldKey: keyof FieldFilter) => { + const val = advFilter[key] as string[]; + if (val.length > 0) { + const newFilter = getDefaultGameFilter(); + newFilter.matchAny = true; + newFilter.exactWhitelist[fieldKey] = val; + filter.subfilters.push(newFilter); + } + }; + + const nonExactFunc = (key: keyof AdvancedFilter, fieldKey: keyof FieldFilter) => { + const val = advFilter[key] as string[]; + if (val.length > 0) { + if (val.length === 1 && val[0] === '') { + const newFilter = getDefaultGameFilter(); + newFilter.matchAny = true; + newFilter.exactWhitelist[fieldKey] = ['']; + filter.subfilters.push(newFilter); + } else { + const newFilter = getDefaultGameFilter(); + newFilter.matchAny = true; + newFilter.whitelist[fieldKey] = val; + filter.subfilters.push(newFilter); + } + } + }; + + exactFunc('library', 'library'); + exactFunc('platform', 'platforms'); + nonExactFunc('playMode', 'playMode'); return filter; } diff --git a/typings/flashpoint-launcher.d.ts b/typings/flashpoint-launcher.d.ts index 04d39da33..bf662e28e 100644 --- a/typings/flashpoint-launcher.d.ts +++ b/typings/flashpoint-launcher.d.ts @@ -1087,7 +1087,9 @@ declare module 'flashpoint-launcher' { type AdvancedFilter = { installed?: boolean; playlistOrder: boolean; - libraries: string[]; + library: string[]; + playMode: string[]; + platform: string[]; } enum ScreenshotPreviewMode {