Skip to content
This repository has been archived by the owner on Jul 23, 2023. It is now read-only.

Commit

Permalink
Filter mods by tags (#182)
Browse files Browse the repository at this point in the history
* show tag buttons

* working tag filter

* add tags everywhere hopefully

* adjust style
  • Loading branch information
Raicuparta committed Dec 23, 2022
1 parent 585ff14 commit da03c10
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 6 deletions.
52 changes: 49 additions & 3 deletions app/components/Mods/ModsToolbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,34 @@ import { useRecoilState, useRecoilValue } from 'recoil';

import { modsText } from '../../helpers/static-text';
import FilterInput from '../FilterInput';
import { modFilterState, settingsState } from '../../store';
import {
modFilterState,
modTagsListState,
modTagsSelectionState,
settingsState,
} from '../../store';
import { openDirectory } from '../../services';

const useStyles = makeStyles((theme) => ({
wrapper: {
padding: `${theme.spacing(1)}px`,
},
toolBar: {
justifyContent: 'space-between',
minHeight: 0,
padding: `${theme.spacing(1)}px ${theme.spacing(2)}px`,
padding: 0,
marginBottom: `${theme.spacing(1)}px`,
// padding: `${theme.spacing(1)}px ${theme.spacing(2)}px`,
},
tagsWrapper: {
display: 'flex',
flexWrap: 'wrap',
margin: `-${theme.spacing(0.5)}px 0 0 -${theme.spacing(0.5)}px`,
},
tag: {
margin: `${theme.spacing(0.5)}px 0 0 ${theme.spacing(0.5)}px`,
fontSize: '10px',
lineHeight: '100%',
},
}));

Expand All @@ -21,8 +41,13 @@ const ModsToolbar: React.FunctionComponent = () => {
const inAlphaMode = useRecoilValue(settingsState).alphaMode;
const [filter, setFilter] = useRecoilState(modFilterState);
const { owmlPath, alphaPath } = useRecoilValue(settingsState);
const tags = useRecoilValue(modTagsListState);
const [tagsSelection, setTagsSelection] = useRecoilState(
modTagsSelectionState
);

return (
<Paper>
<Paper className={styles.wrapper}>
<Toolbar className={styles.toolBar}>
<FilterInput
value={filter}
Expand All @@ -41,6 +66,27 @@ const ModsToolbar: React.FunctionComponent = () => {
{modsText.toolbar.modsDirectory}
</Button>
</Toolbar>
<div className={styles.tagsWrapper}>
{tags.map((tag) => (
<Button
key={tag}
size="small"
className={styles.tag}
onClick={() => {
const selection = new Set(tagsSelection);
if (tagsSelection.has(tag)) {
selection.delete(tag);
} else {
selection.add(tag);
}
setTagsSelection(selection);
}}
variant={tagsSelection.has(tag) ? 'contained' : 'outlined'}
>
{tag}
</Button>
))}
</div>
</Paper>
);
};
Expand Down
1 change: 1 addition & 0 deletions app/globals.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type Mod = {
addons: string[];
isAlpha?: boolean;
authorDisplay?: string;
tags: string[];
};

type ModManager = {
Expand Down
3 changes: 1 addition & 2 deletions app/services/analytics-token.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
// Secret is inserted here on a pre-build script. Don't tell anyone!
export const analyticsApiSecret = '';
export const analyticsApiSecret = 'undefined';
5 changes: 5 additions & 0 deletions app/services/get-local-mods.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ function getOwml(owmlPath: string) {
errors: [],
dependencies: [],
addons: [],
tags: [],
};
return owml;
}
Expand All @@ -49,6 +50,7 @@ function getBepInEx(alphaPath: string) {
dependencies: [],
addons: [],
isAlpha: true,
tags: [],
};
return bepInEx;
}
Expand All @@ -72,6 +74,7 @@ function getOwaml(owamlPath: string) {
dependencies: ['bbepis.BepInEx'],
addons: [],
isAlpha: true,
tags: [],
};
return owaml;
}
Expand Down Expand Up @@ -117,6 +120,7 @@ function pushModsFromDirectory(
pathsToPreserve: manifest.pathsToPreserve,
addons: [],
isAlpha,
tags: [],
};

if (missingAttributes.length > 0) {
Expand Down Expand Up @@ -148,6 +152,7 @@ function pushModsFromDirectory(
localVersion: '-',
addons: [],
isAlpha,
tags: [],
});
}
});
Expand Down
3 changes: 3 additions & 0 deletions app/services/get-mod-database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type RemoteMod = {
};
alpha?: boolean;
authorDisplay?: string;
tags: string[];
};

type RemoteModDatabase = {
Expand Down Expand Up @@ -64,6 +65,7 @@ export async function getModDatabase(
parent,
alpha,
authorDisplay,
tags,
}: RemoteMod) => {
// TODO doesnt make sense for this to be here in remote mods
const modPath = alpha
Expand All @@ -89,6 +91,7 @@ export async function getModDatabase(
.filter((release) => release.parent === uniqueName)
.map((addon) => addon.uniqueName),
isAlpha: alpha,
tags,
};

return mod;
Expand Down
1 change: 1 addition & 0 deletions app/store/mods-state/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './mod-dependencies-state';
export * from './mod-categories-state';
export * from './mod-filter-state';
export * from './mod-tags-state';
export * from './mod-progress-state';
export * from './mods-state';
17 changes: 16 additions & 1 deletion app/store/mods-state/mod-filter-state.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,19 @@
import { atom, selector } from 'recoil';
import { modTagsSelectionState } from './mod-tags-state';

import { modList } from './mods-state';

const filterByTags = (mod: Mod, tags: Set<string>) => {
if (tags.size === 0) return true;

for (let i = 0; i < mod.tags.length; i += 1) {
if (tags.has(mod.tags[i])) {
return true;
}
}
return false;
};

const filterByText = (filter: string, mod: Mod, mods: Mod[]): boolean => {
const lowerCaseFilter = filter.toLowerCase();
const nameMatch = mod.name?.toLowerCase().includes(lowerCaseFilter);
Expand Down Expand Up @@ -47,9 +59,12 @@ export const filteredModList = selector({
get: ({ get }) => {
const filter = get(modFilterState);
const mods = get(modList);
const tagsSelection = get(modTagsSelectionState);
return mods
.filter((mod) => {
return filterByText(filter, mod, mods);
return (
filterByText(filter, mod, mods) && filterByTags(mod, tagsSelection)
);
})
.sort(
(modA, modB) => (modB.downloadCount ?? 0) - (modA.downloadCount ?? 0)
Expand Down
32 changes: 32 additions & 0 deletions app/store/mods-state/mod-tags-state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { selector, atom } from 'recoil';

import { remoteModList } from './mods-state';

export const modTagsSelectionState = atom<Set<string>>({
key: 'ModTagsSelection',
default: new Set(),
});

export const modTagsListState = selector({
key: 'ModTags',
get: ({ get }) => {
const mods = get(remoteModList);
const tags: Set<string> = new Set<string>();
const counts: Record<string, number> = {};

if (!mods) {
return [];
}

mods.forEach((mod) => {
mod.tags.forEach((tag) => {
tags.add(tag);
counts[tag] = (counts[tag] ?? 0) + 1;
});
});

return Array.from(tags).sort(
(tagA, tagB) => (counts[tagB] ?? 0) - (counts[tagA] ?? 0)
);
},
});
1 change: 1 addition & 0 deletions app/store/mods-state/mods-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export const modList = selector({
dependencies: [],
addons: [],
isAlpha: get(settingsState).alphaMode,
tags: [],
});
},
});

0 comments on commit da03c10

Please sign in to comment.