Skip to content

Commit

Permalink
Merge pull request #85 from Tormak9970/dev
Browse files Browse the repository at this point in the history
chore: build v1.5.0
  • Loading branch information
Tormak9970 authored Aug 1, 2023
2 parents 2095788 + f04ad48 commit 42134fd
Show file tree
Hide file tree
Showing 12 changed files with 200 additions and 125 deletions.
4 changes: 0 additions & 4 deletions defaults/docs/Overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,4 @@ These docs serve as a reference for questions you may have, and a guide for help
<br/>


### Notes:
A few articles mention needing to close the library to see changes you make to tabs while in the library. This isn't true. You can just refresh the tabs in the TabMaster QAM menu, or simply switch tabs.


###### © Travis Lane (Tormak), Jessebofill
2 changes: 1 addition & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class Plugin:
friends: List[dict] = None
friends_games: Dict[str, List[int]] = None

docsDirPath = f"/{decky_plugin.DECKY_PLUGIN_DIR}/docs"
docsDirPath = f"{decky_plugin.DECKY_PLUGIN_DIR}/docs"
docs = {}

settings: SettingsManager
Expand Down
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"@types/react": "16.14.0",
"@types/uuid": "^9.0.2",
"@types/webpack": "^5.28.1",
"decky-frontend-lib": "^3.21.8",
"husky": "^8.0.3",
"markdown-it": "^13.0.1",
"rollup": "^2.79.1",
Expand All @@ -59,7 +60,6 @@
"typescript": "^4.9.5"
},
"dependencies": {
"decky-frontend-lib": "^3.21.8",
"mobx": "^5.15.7",
"react-icons": "^4.10.1",
"uuid": "^9.0.0"
Expand All @@ -68,7 +68,8 @@
"peerDependencyRules": {
"ignoreMissing": [
"react",
"react-dom"
"react-dom",
"decky-frontend-lib"
]
}
}
Expand Down
4 changes: 2 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,13 @@ export default defineConfig({
})
],
context: 'window',
external: ['react', 'react-dom'],
external: ['react', 'react-dom', 'decky-frontend-lib'],
output: {
file: 'dist/index.js',
globals: {
react: 'SP_REACT',
'react-dom': 'SP_REACTDOM',
'decky-frontend-lib': 'DFL'
},
format: 'iife',
exports: 'default',
Expand Down
54 changes: 30 additions & 24 deletions src/components/filters/FilterEntry.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
import { Fragment, VFC, useState } from "react";
import { FilterDefaultParams, FilterType, TabFilterSettings, canBeInverted } from "./Filters";
import { ButtonItem, Dropdown, Focusable } from "decky-frontend-lib";
import { ButtonItem, Dropdown, Focusable, afterPatch } from "decky-frontend-lib";
import { FaTrash } from "react-icons/fa";

type FilterEntryProps = {
index: number,
filter: TabFilterSettings<FilterType>,
containingGroupFilters: TabFilterSettings<FilterType>[],
setContainingGroupFilters: React.Dispatch<React.SetStateAction<TabFilterSettings<FilterType>[]>>
}
setContainingGroupFilters: React.Dispatch<React.SetStateAction<TabFilterSettings<FilterType>[]>>,
shouldFocus: boolean
};

/**
* An individual filter for a tab.
*/
export const FilterEntry: VFC<FilterEntryProps> = ({ index, filter, containingGroupFilters, setContainingGroupFilters }) => {
const filterTypeOptions = Object.keys(FilterDefaultParams).map(type => { return { label: type, data: type } });
export const FilterEntry: VFC<FilterEntryProps> = ({ index, filter, containingGroupFilters, setContainingGroupFilters, shouldFocus }) => {
const filterTypeOptions = Object.keys(FilterDefaultParams).map(type => { return { label: type, data: type }; });
const invertOptions = [
{
label: "default",
Expand All @@ -26,22 +27,22 @@ export const FilterEntry: VFC<FilterEntryProps> = ({ index, filter, containingGr
}
];

const [ isInverted, setIsInverted ] = useState(filter.inverted);
const [isInverted, setIsInverted] = useState(filter.inverted);

//* new filter is made with default params
function onChange(data: {data: FilterType}) {
function onChange(data: { data: FilterType; }) {
const updatedFilter = {
type: data.data,
inverted: isInverted,
params: {...FilterDefaultParams[data.data]}
}
};
const updatedFilters = [...containingGroupFilters];
updatedFilters[index] = updatedFilter;
setContainingGroupFilters(updatedFilters);
}

function onInvertedChange(data: { data: boolean }) {
const updatedFilter = { ...filter }
function onInvertedChange(data: { data: boolean; }) {
const updatedFilter = { ...filter };
updatedFilter.inverted = data.data;

const updatedFilters = [...containingGroupFilters];
Expand All @@ -58,26 +59,31 @@ export const FilterEntry: VFC<FilterEntryProps> = ({ index, filter, containingGr
}

if (filter) {

const filterTypeDropdownElt = (
<Focusable style={!canBeInverted(filter) ? { width: "calc(100% - 55px)" } : { width: "calc(100% - 185px)" }}>
<Dropdown rgOptions={filterTypeOptions} selectedOption={filter.type} onChange={onChange} />
</Focusable>
);

//single shot patch the filter type dropdown to get it's navNode and tell it to take focus on first render
if (shouldFocus) {
afterPatch(filterTypeDropdownElt.type, 'render', (_: any, ret: any) => {
setTimeout(() => ret.props.value.BTakeFocus(3), 1);
return ret;
}, { singleShot: true });
}

return (
<div className="filter-entry">
<Focusable style={{
width: "100%",
display: "flex",
flexDirection: "row"
}}>
{!canBeInverted(filter) ? (
<Focusable style={{
width: "calc(100% - 55px)"
}}>
<Dropdown rgOptions={filterTypeOptions} selectedOption={filter.type} onChange={onChange} />
</Focusable>
) : (
{!canBeInverted(filter) ? filterTypeDropdownElt : (
<>
<Focusable style={{
width: "calc(100% - 185px)"
}}>
<Dropdown rgOptions={filterTypeOptions} selectedOption={filter.type} onChange={onChange} />
</Focusable>
{filterTypeDropdownElt}
<Focusable style={{
marginLeft: "10px",
width: "120px"
Expand All @@ -96,10 +102,10 @@ export const FilterEntry: VFC<FilterEntryProps> = ({ index, filter, containingGr
</Focusable>
</Focusable>
</div>
)
);
} else {
return (
<Fragment />
);
}
}
};
1 change: 1 addition & 0 deletions src/components/filters/FilterOptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ const MergeFilterOptions: VFC<FilterOptionsProps<'merge'>> = ({ index, filter, c
mergeParams={mergeParams}
saveMerge={saveMerge}
closeModal={() => modal.instance.Close()}
isEditing={isEditing}
/>
</TabMasterContextProvider>
);
Expand Down
179 changes: 101 additions & 78 deletions src/components/filters/FiltersPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { PanelSection, PanelSectionRow, Field, ButtonItem, Dropdown, Toggle } from "decky-frontend-lib"
import { VFC, Fragment } from "react"
import { FilterEntry } from "./FilterEntry"
import { FilterOptions } from "./FilterOptions"
import { TabFilterSettings, FilterType } from "./Filters"
import { FilterSectionAccordion } from "../accordions/FilterSectionAccordion"
import { PanelSection, PanelSectionRow, Field, ButtonItem, Dropdown, Toggle, afterPatch, Focusable } from "decky-frontend-lib";
import { VFC, Fragment, useMemo, useCallback } from "react";
import { FilterEntry } from "./FilterEntry";
import { FilterOptions } from "./FilterOptions";
import { TabFilterSettings, FilterType } from "./Filters";
import { FilterSectionAccordion } from "../accordions/FilterSectionAccordion";

interface FiltersPanelProps {
groupFilters: TabFilterSettings<FilterType>[],
Expand All @@ -13,83 +13,106 @@ interface FiltersPanelProps {
setGroupLogicMode: React.Dispatch<React.SetStateAction<LogicalMode>>,
setGroupIncludesHidden: React.Dispatch<React.SetStateAction<boolean>>,
addFilter: () => void,
canAddFilter: boolean
canAddFilter: boolean,
shouldFocusAddButton?: boolean,
collapseFilters?: boolean
}

export const FiltersPanel: VFC<FiltersPanelProps> = ({ groupFilters, groupLogicMode, groupIncludesHidden, setGroupFilters, setGroupLogicMode, setGroupIncludesHidden, addFilter, canAddFilter }) => {
export const FiltersPanel: VFC<FiltersPanelProps> = ({ groupFilters, groupLogicMode, groupIncludesHidden, setGroupFilters, setGroupLogicMode, setGroupIncludesHidden, addFilter, canAddFilter, shouldFocusAddButton, collapseFilters }) => {
const modeOptions = [
{ label: "And", data: "and" },
{ label: "Or", data: "or" }
];

return (
<PanelSection title="Filters">
<PanelSectionRow>
<Field
label="Group Combination Logic"
childrenLayout="inline"
childrenContainerWidth="min"
inlineWrap="keep-inline"
className="no-sep"
>
<div style={{ width: "150px" }}>
<Dropdown rgOptions={modeOptions} selectedOption={groupLogicMode} onChange={(option) => setGroupLogicMode(option.data)} focusable={true} />
//this sets whether filter entry type dropdown should take focus when being rendered, ie when a filter is added
let shouldFocusFilterDropdown = false;
const cb = useCallback((() => {
let firstCall = true;
return () => firstCall ? firstCall = false : true;
})(), []);
useMemo(() => shouldFocusFilterDropdown = cb(), [groupFilters.length]);

const element = (
<Focusable>
<PanelSection title="Filters">
<PanelSectionRow>
<Field
label="Group Combination Logic"
childrenLayout="inline"
childrenContainerWidth="min"
inlineWrap="keep-inline"
className="no-sep"
>
<div style={{ width: "150px" }}>
<Dropdown rgOptions={modeOptions} selectedOption={groupLogicMode} onChange={(option) => setGroupLogicMode(option.data)} focusable={true} />
</div>
</Field>
</PanelSectionRow>
<PanelSectionRow>
<Field
label="Include Hidden Games"
childrenLayout="inline"
childrenContainerWidth="min"
inlineWrap="keep-inline"
className="no-sep"
>
<Toggle value={groupIncludesHidden} onChange={(checked) => setGroupIncludesHidden(checked)} />
</Field>
</PanelSectionRow>
<PanelSectionRow>
{groupFilters.map((filter, index) => {
return (
<>
<FilterSectionAccordion
index={index}
filter={filter}
isOpen={shouldFocusFilterDropdown ? index === groupFilters.length - 1 : !collapseFilters}
>
<div className="no-sep">
<Field
label="Filter Type"
description={<FilterEntry index={index} filter={filter} containingGroupFilters={groupFilters} setContainingGroupFilters={setGroupFilters} shouldFocus={shouldFocusFilterDropdown && index === groupFilters.length - 1} />}
/>
</div>
<div className="no-sep" key={`${filter.type}`}>
<FilterOptions index={index} filter={filter} containingGroupFilters={groupFilters} setContainingGroupFilters={setGroupFilters} />
</div>
</FilterSectionAccordion>
{index == groupFilters.length - 1 ? (
<div className="filter-start-cont" style={{ marginTop: "8px" }}>
<div className="filter-line" />
</div>
) : (
<Fragment />
)}
</>
);
})}
</PanelSectionRow>
<PanelSectionRow>
<div className="styled-btn no-sep">
{!canAddFilter ? (
<div style={{ marginTop: "10px" }}>Please finish the current filter before adding another</div>
) : (
<Fragment />
)}
<ButtonItem onClick={addFilter} disabled={!canAddFilter}>
Add Filter
</ButtonItem>
</div>
</Field>
</PanelSectionRow>
<PanelSectionRow>
<Field
label="Include Hidden Games"
childrenLayout="inline"
childrenContainerWidth="min"
inlineWrap="keep-inline"
className="no-sep"
>
<Toggle value={groupIncludesHidden} onChange={(checked) => setGroupIncludesHidden(checked)} />
</Field>
</PanelSectionRow>
<PanelSectionRow>
{groupFilters.map((filter, index) => {
return (
<>
<FilterSectionAccordion
index={index}
filter={filter}
isOpen={true}
>
<div className="no-sep">
<Field
label="Filter Type"
description={<FilterEntry index={index} filter={filter} containingGroupFilters={groupFilters} setContainingGroupFilters={setGroupFilters} />}
/>
</div>
<div className="no-sep" key={`${filter.type}`}>
<FilterOptions index={index} filter={filter} containingGroupFilters={groupFilters} setContainingGroupFilters={setGroupFilters} />
</div>
</FilterSectionAccordion>
{index == groupFilters.length - 1 ? (
<div className="filter-start-cont" style={{ marginTop: "8px" }}>
<div className="filter-line" />
</div>
) : (
<Fragment />
)}
</>
);
})}
</PanelSectionRow>
<PanelSectionRow>
<div className="styled-btn no-sep">
{!canAddFilter ? (
<div style={{ marginTop: "10px" }}>Please finish the current filter before adding another</div>
) : (
<Fragment />
)}
<ButtonItem onClick={addFilter} disabled={!canAddFilter}>
Add Filter
</ButtonItem>
</div>
</PanelSectionRow>
</PanelSection>
)
}
</PanelSectionRow>
</PanelSection>
</Focusable>
);

if (shouldFocusAddButton) {
//wrap the whole panel in a focusable and one shot patch it to grab it's navNode and set focus to it's last child
//which is the add filter button
afterPatch(element.type, 'render', (_: any, ret: any) => {
setTimeout(() => ret.props.value.BFocusLastChild(3), 1);
return ret;
}, { singleShot: true });
}

return element;
};
Loading

0 comments on commit 42134fd

Please sign in to comment.