From daefb874f9d3725c8bf289e42177dca01163d818 Mon Sep 17 00:00:00 2001 From: Tormak <63308171+Tormak9970@users.noreply.github.com> Date: Mon, 20 Nov 2023 17:20:48 -0600 Subject: [PATCH] feat: unified modal setups and changed styles to match 3.5 --- .vscode/extensions.json | 4 +- src/components/filters/FilterSelect.tsx | 87 ++++++--------- src/components/filters/Filters.tsx | 28 ++++- src/components/modals/EditTabModal.tsx | 6 +- src/components/modals/ErrorHelpModal.tsx | 0 src/components/modals/FixMergeFilterModal.tsx | 58 +++++----- src/components/modals/FixTabErrorsModal.tsx | 22 ++-- src/components/modals/ListSearchModal.tsx | 102 +++++++++--------- .../styles/FilterSelectionStyles.tsx | 6 +- src/components/styles/FixModalStyles.tsx | 4 + .../styles/ListSearchModalStyles.tsx | 6 +- src/components/styles/ModalStyles.tsx | 6 ++ 12 files changed, 179 insertions(+), 150 deletions(-) delete mode 100644 src/components/modals/ErrorHelpModal.tsx diff --git a/.vscode/extensions.json b/.vscode/extensions.json index aeab145..23cea6a 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -2,9 +2,9 @@ "recommendations": [ "stevencl.adddoccomments", "ms-vscode.vscode-typescript-next", - "aaron-bond.better-comments", + "EdwinHuiSH.better-comments-next", "editorconfig.editorconfig", "ms-vscode-remote.remote-ssh", "ms-vscode.remote-explorer" ] -} \ No newline at end of file +} diff --git a/src/components/filters/FilterSelect.tsx b/src/components/filters/FilterSelect.tsx index 34dab5d..2314411 100644 --- a/src/components/filters/FilterSelect.tsx +++ b/src/components/filters/FilterSelect.tsx @@ -1,6 +1,6 @@ import { Fragment, VFC, useEffect, useState } from "react"; import { Focusable, ModalRoot, showModal } from "decky-frontend-lib"; -import { FilterDefaultParams, FilterType } from "./Filters"; +import { FilterDefaultParams, FilterDescriptions, FilterType } from "./Filters"; import { capitalizeEachWord } from "../../lib/Utils"; import { FilterSelectStyles, achievementClasses, mainMenuAppRunningClasses } from "../styles/FilterSelectionStyles"; import { CustomButton } from '../generic/CustomButton'; @@ -16,25 +16,6 @@ const FilterSelectModal: VFC = ({ selectedOption, onSele const [focusable, setFocusable] = useState(false); const [selected, setSelected] = useState(selectedOption); const filterTypeOptions = Object.keys(FilterDefaultParams) as FilterType[]; - const filterDescriptions: { [filterType in FilterType]: string } = { - collection: "Selects apps that are in a certain Steam Collection.", - installed: "Selects apps that are installed/uninstalled.", - regex: "Selects apps whose titles match a regular expression.", - friends: "Selects apps that are also owned by friends.", - tags: "Selects apps that have specific community tags.", - whitelist: "Selects apps that are added to the list.", - blacklist: "Selects apps that are not added to the list.", - merge: "Selects apps that pass a subgroup of filters.", - platform: "Selects Steam or non-Steam apps.", - "deck compatibility": "Selects apps that have a specific Steam Deck compatibilty status.", - "review score": "Selects apps based on their metacritic/steam review score.", - "time played": "Selects apps based on your play time.", - "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.", - demo: "Selects apps that are/aren't demos.", - streamable: "Selects apps that can/can't be streamed from another computer." - } useEffect(() => {setTimeout(() => setFocusable(true), 10)}, []); @@ -47,39 +28,41 @@ const FilterSelectModal: VFC = ({ selectedOption, onSele return ( <> - handleSelect(selected)} onEscKeypress={() => handleSelect(selected)}> -

- Change Filter Type -

-
- {filterTypeOptions.map((filterType: FilterType) => { - return ( - {} : undefined} - style={{ width: "100%", margin: 0, marginBottom: "10px", padding: 0 }} - onOKButton={focusable || selected === filterType ? () => handleSelect(filterType) : undefined} - > -
+ handleSelect(selected)} onEscKeypress={() => handleSelect(selected)}> +

+ Change Filter Type +

+
+ {filterTypeOptions.map((filterType: FilterType) => { + return ( + {} : undefined} + style={{ width: "100%", margin: 0, marginBottom: "10px", padding: 0 }} + onOKButton={focusable || selected === filterType ? () => handleSelect(filterType) : undefined} > -
{capitalizeEachWord(filterType)}
-
{filterDescriptions[filterType]}
-
- - ); - })} -
- +
+
{capitalizeEachWord(filterType)}
+
{FilterDescriptions[filterType]}
+
+
+ ); + })} +
+
+ ); }; diff --git a/src/components/filters/Filters.tsx b/src/components/filters/Filters.tsx index 1d98895..54ae439 100644 --- a/src/components/filters/Filters.tsx +++ b/src/components/filters/Filters.tsx @@ -85,7 +85,30 @@ export const FilterDefaultParams: { [key in FilterType]: FilterParams } = { "last played": { date: undefined, condition: 'above' }, "demo": { isDemo: true }, "streamable": { isStreamable: true } -}; +} + +/** + * Dictionary of descriptions for each filter. + */ +export const FilterDescriptions: { [filterType in FilterType]: string } = { + collection: "Selects apps that are in a certain Steam Collection.", + installed: "Selects apps that are installed/uninstalled.", + regex: "Selects apps whose titles match a regular expression.", + friends: "Selects apps that are also owned by friends.", + tags: "Selects apps that have specific community tags.", + whitelist: "Selects apps that are added to the list.", + blacklist: "Selects apps that are not added to the list.", + merge: "Selects apps that pass a subgroup of filters.", + platform: "Selects Steam or non-Steam apps.", + "deck compatibility": "Selects apps that have a specific Steam Deck compatibilty status.", + "review score": "Selects apps based on their metacritic/steam review score.", + "time played": "Selects apps based on your play time.", + "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.", + demo: "Selects apps that are/aren't demos.", + streamable: "Selects apps that can/can't be streamed from another computer." +} /** * Whether the filter should have an invert option. @@ -116,8 +139,7 @@ export function canBeInverted(filter: TabFilterSettings): boolean { } } -//* I changed this from 'isDefaultParams' because some default params can still be valid -//* make sure the check is the inversion from before going forward +// * make sure the check is the inversion from before going forward /** * Checks if a filter has valid params. * @param filter The filter to check. diff --git a/src/components/modals/EditTabModal.tsx b/src/components/modals/EditTabModal.tsx index 02e4404..95209fa 100644 --- a/src/components/modals/EditTabModal.tsx +++ b/src/components/modals/EditTabModal.tsx @@ -43,13 +43,13 @@ export const EditTabModal: VFC = ({ closeModal, onConfirm, ta const [canAddFilter, setCanAddFilter] = useState(true); const [patchInput, setPatchInput] = useState(true); - const nameInputElt = ; + const nameInputElement = ; //reference to input field class component instance, which has a focus method let inputComponentInstance: any; if (patchInput) { - afterPatch(nameInputElt.type.prototype, 'render', function (_: any, ret: any) { + afterPatch(nameInputElement.type.prototype, 'render', function (_: any, ret: any) { //@ts-ignore get reference to instance inputComponentInstance = this; return ret; @@ -117,7 +117,7 @@ export const EditTabModal: VFC = ({ closeModal, onConfirm, ta
Name
- {nameInputElt} + {nameInputElement} } /> diff --git a/src/components/modals/ErrorHelpModal.tsx b/src/components/modals/ErrorHelpModal.tsx deleted file mode 100644 index e69de29..0000000 diff --git a/src/components/modals/FixMergeFilterModal.tsx b/src/components/modals/FixMergeFilterModal.tsx index 717134c..0970f79 100644 --- a/src/components/modals/FixMergeFilterModal.tsx +++ b/src/components/modals/FixMergeFilterModal.tsx @@ -1,5 +1,5 @@ import { ConfirmModal, showModal } from "decky-frontend-lib" -import { VFC, useState } from "react" +import { VFC, useState, Fragment } from "react" import { TabFilterSettings, FilterType } from "../filters/Filters" import { PythonInterop } from "../../lib/controllers/PythonInterop" import { ErroredFiltersPanel } from "../changes-needed/ErroredFiltersPanel" @@ -47,35 +47,37 @@ export const FixMergeFilterModal: VFC = ({ mergeParams } return ( - { - showModal( - - Are you sure you want save these fixes to this merge group? This can't be can't be changed later. - - ); - }} - bOKDisabled={!isPassing} - strOKButtonText={"Save Changes"} - onCancel={closeModal} - strCancelButtonText={"Discard Changes"} - strTitle={`Fix Merge Group in Tab ${tabName}`} - > + <>
- {isPassing &&
All errors have been resolved.
} - - - + { + showModal( + + Are you sure you want save these fixes to this merge group? This can't be can't be changed later. + + ); + }} + bOKDisabled={!isPassing} + strOKButtonText={"Save Changes"} + onCancel={closeModal} + strCancelButtonText={"Discard Changes"} + strTitle={`Fix Merge Group in Tab ${tabName}`} + > + {isPassing &&
All errors have been resolved.
} + + + +
-
+ ) } diff --git a/src/components/modals/FixTabErrorsModal.tsx b/src/components/modals/FixTabErrorsModal.tsx index a0716e0..810c3be 100644 --- a/src/components/modals/FixTabErrorsModal.tsx +++ b/src/components/modals/FixTabErrorsModal.tsx @@ -4,7 +4,7 @@ import { PanelSection, PanelSectionRow, } from "decky-frontend-lib"; -import { useState, VFC, useEffect } from "react"; +import { useState, VFC, useEffect, Fragment } from "react"; import { PythonInterop } from "../../lib/controllers/PythonInterop"; import { TabMasterContextProvider } from "../../state/TabMasterContext"; import type { TabMasterManager } from "../../state/TabMasterManager"; @@ -24,13 +24,15 @@ type FixTabErrorsModalRootProps = { */ export const FixTabErrorsModalRoot: VFC = ({ closeModal, onConfirm, tabs, erroredFiltersMap, tabMasterManager }) => { return ( - // Steam throws a fit if onCancel isn't present, so we made it do nothing - {}}> - - - - - +
+ + {/* Steam throws a fit if onCancel isn't present, so we made it do nothing */} + {}}> + + + + +
); }; @@ -78,7 +80,7 @@ const FixTabErrorsModal: VFC = ({ onConfirm, closeModal, } return ( -
+ <>

Fixes Needed for One or More Tabs

@@ -104,6 +106,6 @@ const FixTabErrorsModal: VFC = ({ onConfirm, closeModal,
-
+ ); }; diff --git a/src/components/modals/ListSearchModal.tsx b/src/components/modals/ListSearchModal.tsx index 27b02e7..28013cd 100644 --- a/src/components/modals/ListSearchModal.tsx +++ b/src/components/modals/ListSearchModal.tsx @@ -60,58 +60,60 @@ export const ListSearchModal: VFC = ({ rgOptions: list, en }; return ( - +
- - - -
- -
-
- { setQuery(e.target.value); }} - style={{ height: "100%" }} - /> -
-
-
- - - - - {/* @ts-ignore */} - {({ height, width }) => ( - - {ListEntry} - - )} - + + + + +
+ +
+
+ { setQuery(e.target.value); }} + style={{ height: "100%" }} + /> +
-
-
-
- + + + + + + {/* @ts-ignore */} + {({ height, width }) => ( + + {ListEntry} + + )} + + + + + + +
); }; diff --git a/src/components/styles/FilterSelectionStyles.tsx b/src/components/styles/FilterSelectionStyles.tsx index 0828e26..1e6402a 100644 --- a/src/components/styles/FilterSelectionStyles.tsx +++ b/src/components/styles/FilterSelectionStyles.tsx @@ -1,4 +1,4 @@ -import { findModule } from "decky-frontend-lib"; +import { findModule, gamepadDialogClasses } from "decky-frontend-lib"; import { VFC } from "react"; type AchievementClasses = Record< @@ -109,6 +109,10 @@ export const FilterSelectStyles: VFC<{}> = ({}) => { height: auto; } + .tab-master-filter-select .${gamepadDialogClasses.ModalPosition} > .${gamepadDialogClasses.GamepadDialogContent} { + background: radial-gradient(155.42% 100% at 0% 0%, #060a0e 0 0%, #0e141b 100%); + } + .tab-master-filter-select .gpfocuswithin .${achievementClasses.AchievementListItemBase} { background: #767a8773; } diff --git a/src/components/styles/FixModalStyles.tsx b/src/components/styles/FixModalStyles.tsx index 2f0a48b..0b95c2b 100644 --- a/src/components/styles/FixModalStyles.tsx +++ b/src/components/styles/FixModalStyles.tsx @@ -10,6 +10,10 @@ export const FixModalStyles: VFC<{}> = ({}) => { .tab-master-fix-modal-scope .${gamepadDialogClasses.GamepadDialogContent} .DialogHeader { margin-left: 15px; } + + .tab-master-fix-modal-scope .${gamepadDialogClasses.ModalPosition} > .${gamepadDialogClasses.GamepadDialogContent} { + background: radial-gradient(155.42% 100% at 0% 0%, #060a0e 0 0%, #0e141b 100%); + } /* The button item */ .tab-master-fix-modal-scope .styled-btn { diff --git a/src/components/styles/ListSearchModalStyles.tsx b/src/components/styles/ListSearchModalStyles.tsx index 96b53a6..9aab61d 100644 --- a/src/components/styles/ListSearchModalStyles.tsx +++ b/src/components/styles/ListSearchModalStyles.tsx @@ -1,4 +1,4 @@ -import { quickAccessControlsClasses } from "decky-frontend-lib"; +import { gamepadDialogClasses, quickAccessControlsClasses } from "decky-frontend-lib"; import { VFC } from "react"; /** @@ -14,6 +14,10 @@ export const ListSearchModalStyles: VFC<{}> = ({}) => { .tab-master-list-search-modal .${quickAccessControlsClasses.PanelSection}:first-of-type { margin: 0px; } + + .tab-master-list-search-modal .${gamepadDialogClasses.ModalPosition} > .${gamepadDialogClasses.GamepadDialogContent} { + background: radial-gradient(155.42% 100% at 0% 0%, #060a0e 0 0%, #0e141b 100%); + } `} ); } diff --git a/src/components/styles/ModalStyles.tsx b/src/components/styles/ModalStyles.tsx index 2493023..6e150d8 100644 --- a/src/components/styles/ModalStyles.tsx +++ b/src/components/styles/ModalStyles.tsx @@ -3,6 +3,8 @@ import { VFC } from "react"; export const modalMargin = '16px + 2.8vw'; +// New modal background should be "radial-gradient(155.42% 100% at 0% 0%, #060a0e 0 0%, #0e141b 100%)" + /** * All css styling for TabMaster's modals. */ @@ -12,6 +14,10 @@ export const ModalStyles: VFC<{}> = ({}) => { .tab-master-modal-scope .${gamepadDialogClasses.GamepadDialogContent} .DialogHeader { margin-left: 15px; } + + .tab-master-modal-scope .${gamepadDialogClasses.ModalPosition} > .${gamepadDialogClasses.GamepadDialogContent} { + background: radial-gradient(155.42% 100% at 0% 0%, #060a0e 0 0%, #0e141b 100%); + } /* The button item */ .tab-master-modal-scope .styled-btn {