Skip to content
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

chore: build v2.6.0 #194

Merged
merged 7 commits into from
Jun 29, 2024
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: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "tabmaster",
"version": "2.5.5",
"version": "2.5.6",
"description": "Gives you full control over your Steam library! Support for customizing, adding, and hiding Library Tabs.",
"scripts": {
"build": "shx rm -rf dist && rollup -c",
Expand Down
3 changes: 1 addition & 2 deletions src/components/CustomTabContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,8 @@ export class CustomTabContainer implements TabContainer {
this.collection.allApps = appsList;
this.collection.visibleApps = [...appsList];

const allAppsMap = collectionStore.allAppsCollection.apps;
const appMap = new Map<AppId, SteamAppOverview>();
appsList.forEach((appItem: SteamAppOverview) => appMap.set(appItem.appid, allAppsMap.get(appItem.appid)!));
appsList.forEach((appItem: SteamAppOverview) => appMap.set(appItem.appid, appItem));

this.collection.apps = appMap;
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/QuickAccessContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export const QuickAccessContent: VFC<{}> = ({ }) => {

return (
<div className="tab-master-scope">
{LogController.errorFlag && <div style={{ padding: '0 15px', marginBottom: '40px' }}>
{LogController.errorFlag && <Focusable style={{ padding: '0 15px', marginBottom: '40px' }} onActivate={() => {}}>
<h3>
<FaCircleExclamation style={{ height: '.8em', marginRight: '5px' }} fill="red" />
Tab Master encountered an error
Expand All @@ -80,7 +80,7 @@ export const QuickAccessContent: VFC<{}> = ({ }) => {
<br />
for support.
</div>
</div>}
</Focusable>}
{hasSdTabs && !isMicroSDeckInstalled && !microSDeckNoticeHidden && (
<div className='notice-field-cont' style={{ paddingBottom: '10px' }}>
<Field>
Expand Down
19 changes: 19 additions & 0 deletions src/components/filters/FilterOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,23 @@ const LastPlayedFilterOptions: VFC<FilterOptionsProps<'last played'>> = ({ index
);
};

/**
* The options for a family sharing filter.
*/
const FamilySharingFilterOptions: VFC<FilterOptionsProps<'family sharing'>> = ({ 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 (
<ToggleField label="Is from a family member?" checked={filter.params.isFamilyShared} onChange={onChange} />
);
};

/**
* The options for a demo filter.
*/
Expand Down Expand Up @@ -899,6 +916,8 @@ export const FilterOptions: VFC<FilterOptionsProps<FilterType>> = ({ index, filt
return <ReleaseDateFilterOptions index={index} filter={filterCopy as TabFilterSettings<'release date'>} containingGroupFilters={containingGroupFilters} setContainingGroupFilters={setContainingGroupFilters} />;
case "last played":
return <LastPlayedFilterOptions index={index} filter={filterCopy as TabFilterSettings<'last played'>} containingGroupFilters={containingGroupFilters} setContainingGroupFilters={setContainingGroupFilters} />;
case "family sharing":
return <FamilySharingFilterOptions index={index} filter={filterCopy as TabFilterSettings<'family sharing'>} containingGroupFilters={containingGroupFilters} setContainingGroupFilters={setContainingGroupFilters} />;
case "demo":
return <DemoFilterOptions index={index} filter={filterCopy as TabFilterSettings<'demo'>} containingGroupFilters={containingGroupFilters} setContainingGroupFilters={setContainingGroupFilters} />;
case "streamable":
Expand Down
6 changes: 6 additions & 0 deletions src/components/filters/FilterPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ const LastPlayedFilterPreview: VFC<FilterPreviewProps<'last played'>> = ({ filte
return <FilterPreviewGeneric filter={filter} displayData={displayData} />;
};

const FamilySharingFilterPreview: VFC<FilterPreviewProps<'family sharing'>> = ({ filter }) => {
return <FilterPreviewGeneric filter={filter} displayData={filter.params.isFamilyShared ? "yes" : "no"} />;
};

const DemoFilterPreview: VFC<FilterPreviewProps<'demo'>> = ({ filter }) => {
return <FilterPreviewGeneric filter={filter} displayData={filter.params.isDemo ? "yes" : "no"} />;
};
Expand Down Expand Up @@ -169,6 +173,8 @@ export const FilterPreview: VFC<FilterPreviewProps<FilterType>> = ({ filter }) =
return <ReleaseDateFilterPreview filter={filter as TabFilterSettings<'release date'>} />;
case "last played":
return <LastPlayedFilterPreview filter={filter as TabFilterSettings<'last played'>} />;
case "family sharing":
return <FamilySharingFilterPreview filter={filter as TabFilterSettings<'family sharing'>} />;
case "demo":
return <DemoFilterPreview filter={filter as TabFilterSettings<'demo'>} />;
case "streamable":
Expand Down
18 changes: 16 additions & 2 deletions src/components/filters/Filters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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 };
Expand All @@ -63,6 +64,7 @@ export type FilterParams<T extends FilterType> =
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 :
Expand Down Expand Up @@ -99,6 +101,7 @@ export const FilterDefaultParams: { [key in FilterType]: FilterParams<key> } = {
"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' },
Expand All @@ -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.",
Expand All @@ -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,
Expand Down Expand Up @@ -186,6 +191,7 @@ export function canBeInverted(filter: TabFilterSettings<FilterType>): boolean {
case "release date":
case "last played":
case "demo":
case "family sharing":
case "streamable":
return false;
}
Expand Down Expand Up @@ -225,6 +231,7 @@ export function isValidParams(filter: TabFilterSettings<FilterType>): boolean {
case "review score":
case "time played":
case "demo":
case "family sharing":
case "streamable":
case "achievements":
case "sd card":
Expand Down Expand Up @@ -374,6 +381,7 @@ export function validateFilter(filter: TabFilterSettings<FilterType>): Validatio
case "release date":
case "last played":
case "demo":
case "family sharing":
case "streamable":
case "steam features":
case "achievements":
Expand Down Expand Up @@ -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;
},
Expand Down
6 changes: 1 addition & 5 deletions src/patches/SettingsPatch.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const patchSettings = (serverAPI: ServerAPI, tabMasterManager: TabMasterM
}

afterPatch(ret1, 'type', (_: any, ret2: any) => {
const homeElement = ret2?.props?.children?.props?.pages?.find((obj: any) => obj.route === '/settings/home')?.content?.props?.children[1];
const homeElement = ret2?.props?.children?.props?.pages?.find((obj: any) => obj.route === '/settings/home')?.content;
if (homeElement === undefined) {
LogController.raiseError("Couldn't find home element to patch in settings");
return ret2;
Expand All @@ -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');
});
Expand All @@ -44,8 +42,6 @@ export const patchSettings = (serverAPI: ServerAPI, tabMasterManager: TabMasterM
}

afterPatch(buttonElementContainer, 'type', (_: any, ret4: any) => {
console.log('ret 4', ret4);

//* if ret exists but cannot find onClick then raise error because it is assumed valve has changed something
if (ret4 && !ret4.props?.onClick) {
LogController.raiseError("Couldn't patch button onClick fn in settings");
Expand Down
37 changes: 18 additions & 19 deletions src/state/TabMasterManager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -513,8 +513,7 @@ export class TabMasterManager {
asyncLoadOther() {
PythonInterop.getTags().then((res: TagResponse[] | Error) => {
if (res instanceof Error) {
LogController.log("TabMaster couldn't load tags settings");
LogController.error(res.message);
LogController.raiseError(`Error loading tags \n ${res.message}`)
} else {
if (this.allStoreTags.length === 0) {
this.allStoreTags = res;
Expand All @@ -523,8 +522,7 @@ export class TabMasterManager {
});
PythonInterop.getFriends().then((res: FriendEntry[] | Error) => {
if (res instanceof Error) {
LogController.log("TabMaster couldn't load friends settings");
LogController.error(res.message);
LogController.raiseError(`Error loading friends \n ${res.message}`)
} else {
if (this.currentUsersFriends.length === 0) {
this.currentUsersFriends = res;
Expand All @@ -533,8 +531,7 @@ export class TabMasterManager {
});
PythonInterop.getFriendsGames().then((res: Map<number, number[]> | Error) => {
if (res instanceof Error) {
LogController.log("TabMaster couldn't load friends games settings");
LogController.error(res.message);
LogController.raiseError(`Error loading friends games \n ${res.message}`)
} else {
if (this.friendsGameMap.size === 0) {
this.friendsGameMap = res;
Expand All @@ -552,20 +549,22 @@ export class TabMasterManager {
const profiles = await PythonInterop.getTabProfiles();

this.asyncLoadOther();

if (settings instanceof Error) {
LogController.log("TabMaster couldn't load tab settings");
LogController.error(settings.message);
return;
}
if (profiles instanceof Error) {
LogController.log("TabMaster couldn't load tab profiles");
LogController.error(profiles.message);
return;
try {
if (settings instanceof Error) {
throw new Error(`Error loading tab settings \n ${settings.message}`)
}
if (profiles instanceof Error) {
throw new Error(`Error loading tab profiles \n ${profiles.message}`)
}

this.tabProfileManager = new TabProfileManager(profiles);
TabErrorController.validateSettingsOnLoad((Object.keys(settings).length > 0) ? settings : defaultTabsSettings, this, this.finishLoadingTabs.bind(this));

} catch(e) {
if(e instanceof Error) {
LogController.raiseError(`Encountered an error while loading \n ${e.message}`)
}
}

this.tabProfileManager = new TabProfileManager(profiles);
TabErrorController.validateSettingsOnLoad((Object.keys(settings).length > 0) ? settings : defaultTabsSettings, this, this.finishLoadingTabs.bind(this));
};

/**
Expand Down
1 change: 1 addition & 0 deletions src/types/stores/collectionStore.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ type CollectionStore = {
userCollections: SteamCollection[],
allGamesCollection: Collection,
deckDesktopApps: Collection | null,
sharedLibrariesCollections: Collection[],
userCollections: Collection[],
localGamesCollection: Collection,
allAppsCollection: Collection,
Expand Down
Loading