Skip to content

Commit

Permalink
[feat-684] applied changes with BadBeatMods API migration
Browse files Browse the repository at this point in the history
  • Loading branch information
silentrald committed Jan 4, 2025
1 parent 54b1d15 commit ad19d5b
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 68 deletions.
3 changes: 2 additions & 1 deletion assets/jsons/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -909,7 +909,8 @@
"mod-types": {
"all": "All",
"installed": "Installed",
"not-installed": "Not Installed"
"not-installed": "Not Installed",
"missing": "Missing"
}
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,30 @@ import { IpcService } from "renderer/services/ipc.service";
import { ModalComponent } from "renderer/services/modale.service";
import { lastValueFrom } from "rxjs";
import { BSVersion } from "shared/bs-version.interface";
import { getVersionName } from "shared/helpers/bs-version.helpers";
import { safeLt } from "shared/helpers/semver.helpers";
import { Mod } from "shared/models/mods";
import { BbmCategories, BbmFullMod, BbmModVersion } from "shared/models/mods/mod.interface";

enum Mode {
All = "all",
Installed = "installed",
NotInstalled = "not-installed",
Missing = "missing", // If mod is not found from the other version
}

// To save memory when caching
export interface ModCompareType {
id: number;
name: string;
version: string;
}

const simplifyFullMod = (mod: BbmFullMod) => ({
id: mod.mod.id,
name: mod.mod.name,
version: mod.version.modVersion
});

function useHeader({
version,
loading,
Expand All @@ -35,11 +50,11 @@ function useHeader({

const [mode, setMode] = useState(Mode.All);
const [otherVersion, setOtherVersion] = useState(null as BSVersion | null);
const [otherAvailableModsMap, setOtherAvailableModsMap] = useState(new Map<string, Mod[]>());
const [otherInstalledModsMap, setOtherInstalledModsMap] = useState(new Map<string, Mod[]>());
const [otherAvailableModsMap, setOtherAvailableModsMap] = useState(null as Map<BbmCategories, ModCompareType[]>);
const [otherInstalledModsMap, setOtherInstalledModsMap] = useState(null as Map<BbmCategories, ModCompareType[]>);
const [modsMapCache, setModsMapCache] = useState(new Map<BSVersion, Readonly<{
availableModsMap: Map<string, Mod[]>;
installedModsMap: Map<string, Mod[]>;
availableModsMap: Map<BbmCategories, ModCompareType[]>;
installedModsMap: Map<BbmCategories, ModCompareType[]>;
}>>());

const modeOptions: BsmSelectOption<Mode>[] = useConstant(() =>
Expand Down Expand Up @@ -76,19 +91,10 @@ function useHeader({
return v1.name.localeCompare(v2.name);
return safeLt(v1.BSVersion, v2.BSVersion) ? 1 : -1;
})
.map(v => {
let { name } = v;
if (v.steam) {
name = "Steam";
} else if (v.oculus) {
name = "Oculus";
}

return {
text: `${v.BSVersion} - ${name}`,
value: v
};
}),
.map(v => ({
text: getVersionName(v),
value: v
})),
...availableVersions
.filter(v => v.BSVersion !== version.BSVersion)
.map(v => ({ text: v.BSVersion, value: v }))
Expand All @@ -100,39 +106,53 @@ function useHeader({

useEffect(() => {
if (!otherVersion) {
const empty = new Map<string, Mod[]>();
setOtherAvailableModsMap(empty);
setOtherInstalledModsMap(empty);
setOtherAvailableModsMap(null);
setOtherInstalledModsMap(null);
return;
}

const cached = modsMapCache.get(otherVersion);
if (cached) {
setOtherAvailableModsMap(cached.availableModsMap);
setOtherInstalledModsMap(cached.installedModsMap);
const cache = modsMapCache.get(otherVersion);
if (cache) {
setOtherAvailableModsMap(cache.availableModsMap);
setOtherInstalledModsMap(cache.installedModsMap);
return;
}

setLoading(true);

const promises = [lastValueFrom(ipc.sendV2("bs-mods.get-available-mods", otherVersion))];
const promises: Promise<BbmFullMod[] | BbmModVersion[]>[] = [
lastValueFrom(ipc.sendV2("bs-mods.get-available-mods", otherVersion))
];
if (otherVersion.path) {
promises.push(lastValueFrom(ipc.sendV2("bs-mods.get-installed-mods", otherVersion)))
}

Promise.all(promises).then(([availableMods, installedMods]) => {
const availableModsMap = new Map<string, Mod[]>();
const installedModsMap = new Map<string, Mod[]>();

availableMods.forEach(mod => availableModsMap.set(
mod.category,
[...(availableModsMap.get(mod.category) ?? []), mod]
const availableModsMap = new Map<BbmCategories, ModCompareType[]>();
const installedModsMap = new Map<BbmCategories, ModCompareType[]>();

(availableMods as BbmFullMod[]).forEach(fullMod => availableModsMap.set(
fullMod.mod.category,
[
...(availableModsMap.get(fullMod.mod.category) ?? []),
simplifyFullMod(fullMod)
]
));
if (installedMods) {
installedMods.forEach(mod => installedModsMap.set(
mod.category,
[...(installedModsMap.get(mod.category) ?? []), mod]
));
(installedMods as BbmModVersion[])
.map(mod => (availableMods as BbmFullMod[])
.find(availMod => availMod.mod.id === mod.id)
)
.forEach(fullMod => {
if (!fullMod) { return; }
installedModsMap.set(
fullMod.mod.category,
[
...(availableModsMap.get(fullMod.mod.category) ?? []),
simplifyFullMod(fullMod)
]
);
});
}

// Manual in-memory caching
Expand All @@ -148,14 +168,13 @@ function useHeader({
});
}, [otherVersion]);


return {
mode,
otherVersion, otherAvailableModsMap, otherInstalledModsMap,

renderHeader: () => <div className="grid grid-cols-2 text-large mb-2">
<div className="flex justify-center gap-x-2">
<div>{version.BSVersion} - {version.name}</div>
<div>{getVersionName(version)}</div>

<BsmSelect
options={modeOptions}
Expand Down Expand Up @@ -183,9 +202,9 @@ function ModCompare({
otherInstalledLocal,
loading,
}: Readonly<{
mod: Mod | null;
mod: ModCompareType | null;
otherMod: ModCompareType | null;
installed: boolean;
otherMod: Mod | null;
otherInstalled: boolean;
// Check if the other version is installed locally
otherInstalledLocal: boolean;
Expand Down Expand Up @@ -284,15 +303,15 @@ function ModCategory({
mode: Mode;
category: string;
otherVersion: BSVersion;
availableMods: Mod[];
installedMods: Mod[];
otherAvailableMods: Mod[];
otherInstalledMods: Mod[];
availableMods: ModCompareType[];
installedMods: ModCompareType[];
otherAvailableMods: ModCompareType[];
otherInstalledMods: ModCompareType[];
loading: boolean;
}>) {
const otherInstalledLocal = !!otherVersion?.path;

let combinedMods: Mod[] = [];
let combinedMods: ModCompareType[] = [];
switch (mode) {
case Mode.All:
combinedMods = [...availableMods];
Expand All @@ -301,13 +320,15 @@ function ModCategory({
}

combinedMods.push(...otherAvailableMods.filter(
mod => combinedMods.findIndex(cm => cm.name === mod.name) === -1
mod => combinedMods.findIndex(cm => cm.id === mod.id) === -1
));
combinedMods.sort((m1, m2) => m1.name.localeCompare(m2.name));
break;

case Mode.Installed:
combinedMods = [...installedMods];
combinedMods = availableMods.filter(
mod => installedMods.findIndex(im => im.name === mod.name) > -1
);
break;

case Mode.NotInstalled:
Expand All @@ -316,6 +337,15 @@ function ModCategory({
);
break;

case Mode.Missing:
if (otherAvailableMods.length === 0) {
break;
}
combinedMods = otherAvailableMods.filter(
mod => availableMods.findIndex(am => am.name === mod.name) === -1
);
break;

default:
}

Expand All @@ -324,7 +354,7 @@ function ModCategory({
}

return <div className="bg-gray-500 py-2 px-4 rounded-md mb-4">
<h2 className="text-xl font-bold text-center mb-2">
<h2 className="text-xl font-bold capitalize text-center mb-2">
{category}
</h2>

Expand All @@ -348,32 +378,37 @@ function ModCategory({

export const ModsVersionCompareModal: ModalComponent<void, Readonly<{
version: BSVersion;
availableModsMap: Map<string, Mod[]>;
installedModsMap: Map<string, Mod[]>;
availableModsMap: Map<BbmCategories, BbmFullMod[]>;
installedModsMap: Map<BbmCategories, BbmFullMod[]>;
}>> = ({ options: { data: {
version,
availableModsMap,
installedModsMap
} } }) => {
const { text: t } = useTranslationV2();

const simpleAvailableModsMap = useConstant(() => {
const map = new Map<BbmCategories, ModCompareType[]>();
availableModsMap.forEach((mods, category) =>
map.set(category, mods.map(simplifyFullMod))
);
return map;
});
const simpleInstalledModsMap = useConstant(() => {
const map = new Map<BbmCategories, ModCompareType[]>();
installedModsMap.forEach((mods, category) =>
map.set(category, mods.map(simplifyFullMod))
);
return map;
});

const [loading, setLoading] = useState(false);
const {
mode,
otherVersion, otherAvailableModsMap, otherInstalledModsMap,
renderHeader,
} = useHeader({ version, loading, setLoading });

let categories = mode === Mode.Installed
? [...installedModsMap.keys()]
: [...availableModsMap.keys()];
if (otherAvailableModsMap.size > 0) {
categories = [...new Set([
...categories, ...otherAvailableModsMap.keys()
])];
categories.sort((c1, c2) => c1.localeCompare(c2));
}

return (
<div>
<h1 className="tracking-wide w-full uppercase text-3xl text-center mb-4">
Expand All @@ -383,16 +418,16 @@ export const ModsVersionCompareModal: ModalComponent<void, Readonly<{
{renderHeader()}

<div className="h-[500px] overflow-y-auto">
{categories.map(category =>
{Object.values(BbmCategories).map(category =>
<ModCategory
key={category}
mode={mode}
category={category}
otherVersion={otherVersion}
availableMods={availableModsMap.get(category) || []}
installedMods={installedModsMap.get(category) || []}
otherAvailableMods={otherAvailableModsMap.get(category) || []}
otherInstalledMods={otherInstalledModsMap.get(category) || []}
availableMods={simpleAvailableModsMap.get(category) || []}
installedMods={simpleInstalledModsMap.get(category) || []}
otherAvailableMods={otherAvailableModsMap?.get(category) || []}
otherInstalledMods={otherInstalledModsMap?.get(category) || []}
loading={loading}
/>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import BeatWaitingImg from "../../../../../../assets/images/apngs/beat-waiting.p
import BeatConflictImg from "../../../../../../assets/images/apngs/beat-conflict.png";
import { useObservable } from "renderer/hooks/use-observable.hook";
import { lastValueFrom } from "rxjs";
import { useTranslation, useTranslationV2 } from "renderer/hooks/use-translation.hook";
import { useTranslationV2 } from "renderer/hooks/use-translation.hook";
import { LinkOpenerService } from "renderer/services/link-opener.service";
import { useInView } from "framer-motion";
import { ModalExitCode, ModalService } from "renderer/services/modale.service";
Expand Down Expand Up @@ -319,7 +319,7 @@ export function ModsSlide({ version, onDisclamerDecline }: { version: BSVersion;
}

function ModStatus({ text, image, spin = false, children }: { text: string; image: string; spin?: boolean, children?: ReactNode}) {
const t = useTranslation();
const { text: t } = useTranslationV2();

return (
<div className="w-full h-full flex flex-col items-center justify-center text-gray-800 dark:text-gray-200">
Expand Down
10 changes: 10 additions & 0 deletions src/shared/helpers/bs-version.helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { BSVersion } from "shared/bs-version.interface";

export function getVersionName(version: BSVersion) {
let { name } = version;
if (!name) {
name = version.steam
? "Steam" : "Oculus";
}
return `${version.BSVersion} - ${name}`;
}

0 comments on commit ad19d5b

Please sign in to comment.