From 18fbf6bf0c71f1b12090748ae956f106043155cd Mon Sep 17 00:00:00 2001 From: Tormak <63308171+Tormak9970@users.noreply.github.com> Date: Thu, 27 Jun 2024 16:37:02 -0500 Subject: [PATCH] chore: initial implementation of family sharing filter done --- src/components/filters/FilterOptions.tsx | 19 +++++++++++++++++++ src/components/filters/FilterPreview.tsx | 6 ++++++ src/components/filters/Filters.tsx | 18 ++++++++++++++++-- src/patches/SettingsPatch.tsx | 2 -- src/types/stores/collectionStore.d.ts | 1 + 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/src/components/filters/FilterOptions.tsx b/src/components/filters/FilterOptions.tsx index f3426f2..370c9e0 100644 --- a/src/components/filters/FilterOptions.tsx +++ b/src/components/filters/FilterOptions.tsx @@ -727,6 +727,23 @@ const LastPlayedFilterOptions: VFC> = ({ index ); }; +/** + * The options for a family sharing filter. + */ +const FamilySharingFilterOptions: VFC> = ({ index, setContainingGroupFilters, filter, containingGroupFilters }) => { + function onChange(checked: boolean) { + const updatedFilter = { ...filter }; + updatedFilter.params.isFamilyShared = checked ?? false; + const updatedFilters = [...containingGroupFilters]; + updatedFilters[index] = updatedFilter; + setContainingGroupFilters(updatedFilters); + } + + return ( + + ); +}; + /** * The options for a demo filter. */ @@ -899,6 +916,8 @@ export const FilterOptions: VFC> = ({ index, filt return } containingGroupFilters={containingGroupFilters} setContainingGroupFilters={setContainingGroupFilters} />; case "last played": return } containingGroupFilters={containingGroupFilters} setContainingGroupFilters={setContainingGroupFilters} />; + case "family sharing": + return } containingGroupFilters={containingGroupFilters} setContainingGroupFilters={setContainingGroupFilters} />; case "demo": return } containingGroupFilters={containingGroupFilters} setContainingGroupFilters={setContainingGroupFilters} />; case "streamable": diff --git a/src/components/filters/FilterPreview.tsx b/src/components/filters/FilterPreview.tsx index 5b59832..b515497 100644 --- a/src/components/filters/FilterPreview.tsx +++ b/src/components/filters/FilterPreview.tsx @@ -110,6 +110,10 @@ const LastPlayedFilterPreview: VFC> = ({ filte return ; }; +const FamilySharingFilterPreview: VFC> = ({ filter }) => { + return ; +}; + const DemoFilterPreview: VFC> = ({ filter }) => { return ; }; @@ -169,6 +173,8 @@ export const FilterPreview: VFC> = ({ filter }) = return } />; case "last played": return } />; + case "family sharing": + return } />; case "demo": return } />; case "streamable": diff --git a/src/components/filters/Filters.tsx b/src/components/filters/Filters.tsx index 14d1543..0775014 100644 --- a/src/components/filters/Filters.tsx +++ b/src/components/filters/Filters.tsx @@ -6,11 +6,11 @@ import { STEAM_FEATURES_ID_MAP } from "./SteamFeatures"; import { FaCheckCircle, FaHdd, FaSdCard, FaTrophy, FaUserFriends } from "react-icons/fa"; import { IoGrid } from "react-icons/io5"; import { SiSteamdeck } from "react-icons/si"; -import { FaAward, FaBan, FaCalendarDays, FaCloudArrowDown, FaCompactDisc, FaListCheck, FaPlay, FaRegClock, FaSteam, FaTags } from "react-icons/fa6"; +import { FaAward, FaBan, FaCalendarDays, FaCloudArrowDown, FaCompactDisc, FaListCheck, FaPlay, FaRegClock, FaSteam, FaTags, FaUserPlus } from "react-icons/fa6"; import { BsClockHistory, BsRegex } from "react-icons/bs"; import { LuCombine } from "react-icons/lu"; -export type FilterType = 'collection' | 'installed' | 'regex' | 'friends' | 'tags' | 'whitelist' | 'blacklist' | 'merge' | 'platform' | 'deck compatibility' | 'review score' | 'time played' | 'size on disk' | 'release date' | 'last played' | 'demo' | 'streamable' | 'steam features' | 'achievements' | 'sd card'; +export type FilterType = 'collection' | 'installed' | 'regex' | 'friends' | 'tags' | 'whitelist' | 'blacklist' | 'merge' | 'platform' | 'deck compatibility' | 'review score' | 'time played' | 'size on disk' | 'release date' | 'last played' | 'family sharing' | 'demo' | 'streamable' | 'steam features' | 'achievements' | 'sd card'; export type TimeUnit = 'minutes' | 'hours' | 'days'; export type ThresholdCondition = 'above' | 'below'; @@ -41,6 +41,7 @@ type TimePlayedFilterParams = { timeThreshold: number, condition: ThresholdCondi type SizeOnDiskFilterParams = { gbThreshold: number, condition: ThresholdCondition }; type ReleaseDateFilterParams = { date?: DateObj, daysAgo?: number, condition: ThresholdCondition }; type LastPlayedFilterParams = { date?: DateObj, daysAgo?: number, condition: ThresholdCondition }; +type FamilySharingFilterParams = { isFamilyShared: boolean }; type DemoFilterParams = { isDemo: boolean }; type StreamableFilterParams = { isStreamable: boolean }; type SteamFeaturesFilterParams = { features: number[], mode: LogicalMode }; @@ -63,6 +64,7 @@ export type FilterParams = T extends 'size on disk' ? SizeOnDiskFilterParams : T extends 'release date' ? ReleaseDateFilterParams : T extends 'last played' ? LastPlayedFilterParams : + T extends 'family sharing' ? FamilySharingFilterParams : T extends 'demo' ? DemoFilterParams : T extends 'streamable' ? StreamableFilterParams : T extends 'steam features' ? SteamFeaturesFilterParams : @@ -99,6 +101,7 @@ export const FilterDefaultParams: { [key in FilterType]: FilterParams } = { "size on disk": { gbThreshold: 10, condition: 'above' }, "release date": { date: undefined, condition: 'above' }, "last played": { date: undefined, condition: 'above' }, + "family sharing": { isFamilyShared: true }, "demo": { isDemo: true }, "streamable": { isStreamable: true }, "steam features": { features: [], mode: 'and' }, @@ -125,6 +128,7 @@ export const FilterDescriptions: { [filterType in FilterType]: string } = { "size on disk": "Selects apps based on their install size.", "release date": "Selects apps based on their release date.", "last played": "Selects apps based on when they were last played.", + "family sharing": "Selects apps that are/aren't shared from family members.", demo: "Selects apps that are/aren't demos.", streamable: "Selects apps that can/can't be streamed from another computer.", achievements: "Selects apps based on their completion percentage.", @@ -151,6 +155,7 @@ export const FilterIcons: { [filterType in FilterType]: IconType } = { "size on disk": FaHdd, "release date": FaCalendarDays, "last played": BsClockHistory, + "family sharing": FaUserPlus, demo: FaCompactDisc, streamable: FaCloudArrowDown, "steam features": FaListCheck, @@ -186,6 +191,7 @@ export function canBeInverted(filter: TabFilterSettings): boolean { case "release date": case "last played": case "demo": + case "family sharing": case "streamable": return false; } @@ -225,6 +231,7 @@ export function isValidParams(filter: TabFilterSettings): boolean { case "review score": case "time played": case "demo": + case "family sharing": case "streamable": case "achievements": case "sd card": @@ -374,6 +381,7 @@ export function validateFilter(filter: TabFilterSettings): Validatio case "release date": case "last played": case "demo": + case "family sharing": case "streamable": case "steam features": case "achievements": @@ -512,6 +520,12 @@ export class Filter { lastPlayedTimeMs < new Date(today.getUTCFullYear(), today.getUTCMonth(), today.getUTCDate() + 1 - params.daysAgo!).getTime(); } }, + 'family sharing': (params: FilterParams<'family sharing'>, appOverview: SteamAppOverview) => { + const isInSharedCollection = collectionStore.sharedLibrariesCollections.some((collection) => { + return collection.allApps.includes(appOverview); + }); + return params.isFamilyShared ? isInSharedCollection : !isInSharedCollection; + }, demo: (params: FilterParams<'demo'>, appOverview: SteamAppOverview) => { return params.isDemo ? appOverview.app_type === 8 : appOverview.app_type !== 8; }, diff --git a/src/patches/SettingsPatch.tsx b/src/patches/SettingsPatch.tsx index 6e06f3a..67bcad5 100644 --- a/src/patches/SettingsPatch.tsx +++ b/src/patches/SettingsPatch.tsx @@ -32,8 +32,6 @@ export const patchSettings = (serverAPI: ServerAPI, tabMasterManager: TabMasterM } afterPatch(homeElement, 'type', (_: any, ret3: any) => { - console.log('ret 3', ret3); - const buttonElementContainer = ret3?.props?.children?.find((elt: React.ReactElement) => { return elt?.type?.toString?.().includes('HomeSettings'); }); diff --git a/src/types/stores/collectionStore.d.ts b/src/types/stores/collectionStore.d.ts index ebae36f..caeecfa 100644 --- a/src/types/stores/collectionStore.d.ts +++ b/src/types/stores/collectionStore.d.ts @@ -7,6 +7,7 @@ type CollectionStore = { userCollections: SteamCollection[], allGamesCollection: Collection, deckDesktopApps: Collection | null, + sharedLibrariesCollections: Collection[], userCollections: Collection[], localGamesCollection: Collection, allAppsCollection: Collection,