From bdfaca87b1fe9a94c234ca1524d43b75abdf4a95 Mon Sep 17 00:00:00 2001 From: silentrald Date: Sun, 29 Dec 2024 11:24:19 +0800 Subject: [PATCH] [feat-684] add icons for mods version comparison --- .../mods-version-compare-modal.component.tsx | 104 +++++++++++++----- .../components/svgs/bsm-icon.component.tsx | 7 +- .../svgs/icons/compare-icon.component.tsx | 15 +++ .../svgs/icons/down-icon.component.tsx | 15 +++ .../svgs/icons/equals-icon.component.tsx | 15 +++ .../svgs/icons/remove-icon.component.tsx | 15 +++ .../svgs/icons/up-icon.component.tsx | 15 +++ .../slides/mods/mods-grid.component.tsx | 2 +- 8 files changed, 158 insertions(+), 30 deletions(-) create mode 100644 src/renderer/components/svgs/icons/compare-icon.component.tsx create mode 100644 src/renderer/components/svgs/icons/down-icon.component.tsx create mode 100644 src/renderer/components/svgs/icons/equals-icon.component.tsx create mode 100644 src/renderer/components/svgs/icons/remove-icon.component.tsx create mode 100644 src/renderer/components/svgs/icons/up-icon.component.tsx diff --git a/src/renderer/components/modal/modal-types/mods/mods-version-compare-modal.component.tsx b/src/renderer/components/modal/modal-types/mods/mods-version-compare-modal.component.tsx index d418456d1..1a14db7bc 100644 --- a/src/renderer/components/modal/modal-types/mods/mods-version-compare-modal.component.tsx +++ b/src/renderer/components/modal/modal-types/mods/mods-version-compare-modal.component.tsx @@ -1,6 +1,11 @@ import { useEffect, useState } from "react"; import { logRenderError } from "renderer"; import { BsmSelect, BsmSelectOption } from "renderer/components/shared/bsm-select.component"; +import { AddIcon } from "renderer/components/svgs/icons/add-icon.component"; +import { DownIcon } from "renderer/components/svgs/icons/down-icon.component"; +import { EqualIcon } from "renderer/components/svgs/icons/equals-icon.component"; +import { RemoveIcon } from "renderer/components/svgs/icons/remove-icon.component"; +import { UpIcon } from "renderer/components/svgs/icons/up-icon.component"; import { useConstant } from "renderer/hooks/use-constant.hook"; import { useService } from "renderer/hooks/use-service.hook"; import { useTranslationV2 } from "renderer/hooks/use-translation.hook"; @@ -131,10 +136,11 @@ function useHeader({ } // Manual in-memory caching - modsMapCache.set(otherVersion, { + const newCache = new Map(modsMapCache); + newCache.set(otherVersion, { availableModsMap, installedModsMap, }); - setModsMapCache(modsMapCache); + setModsMapCache(newCache); setOtherAvailableModsMap(availableModsMap); setOtherInstalledModsMap(installedModsMap); @@ -144,7 +150,8 @@ function useHeader({ return { - mode, otherAvailableModsMap, otherInstalledModsMap, + mode, + otherVersion, otherAvailableModsMap, otherInstalledModsMap, renderHeader: () =>
@@ -165,7 +172,6 @@ function useHeader({ onChange={setOtherVersion} />
- }; } @@ -174,65 +180,101 @@ function ModCompare({ installed, otherMod, otherInstalled, + otherInstalledLocal, loading, }: Readonly<{ mod: Mod | null; installed: boolean; otherMod: Mod | null; otherInstalled: boolean; + // Check if the other version is installed locally + otherInstalledLocal: boolean; loading: boolean; }>) { const name = mod?.name || otherMod?.name; - const render = (renderMod: Mod | null, installed_: boolean, loading_: boolean = false) => { - if (loading_) { + const renderMod = () => { + if (!mod) { + return
{name}
+ } + + let modClass = "flex justify-between py-1 px-2 gap-x-2"; + if (installed) { + modClass += " bg-green-700"; + } else { + modClass += " bg-red-700"; + } + + return
+
{name}
+
{mod.version}
+
+ } + + const renderOtherMod = () => { + if (loading) { return
TODO: Rainbow Lazy Loading
} - if (!renderMod) { + if (!otherMod) { return
{name}
} let modClass = "flex justify-between py-1 px-2 gap-x-2"; - if (installed_) { + if (!otherInstalledLocal) { + modClass += " bg-blue-700"; // Change, just for visual prototyping + } else if (otherInstalled) { modClass += " bg-green-700"; } else { modClass += " bg-red-700"; } - return
+ return
{name}
-
{renderMod.version}
+
{otherMod.version}
} - const renderSymbol = () => { - let symbol = ""; + const renderIcon = () => { + if (loading) { + return
+ } + if (mod && !otherMod) { - symbol = "-"; // Removed / Not Submitted Yet - } else if (!mod && otherMod) { - symbol = "+"; // Added - } else if (mod.version === otherMod.version) { - symbol = "="; // Equals - } else if (safeLt(mod.version, otherMod.version)) { - symbol = "^"; // Upgraded - } else { - symbol = "v"; // Downgraded + // Removed / Not Submitted Yet + return + } + + if (!mod && otherMod) { + // Added + return + } + + if (mod.version === otherMod.version) { + // Equals + return } - return
{symbol}
+ if (safeLt(mod.version, otherMod.version)) { + // Upgraded + return + } + + // Downgraded + return } return <> - {render(mod, installed)} - {renderSymbol()} - {render(otherMod, otherInstalled, loading)} + {renderMod()} + {renderIcon()} + {renderOtherMod()} } function ModCategory({ mode, category, + otherVersion, availableMods, installedMods, otherAvailableMods, @@ -241,12 +283,15 @@ function ModCategory({ }: Readonly<{ mode: Mode; category: string; + otherVersion: BSVersion; availableMods: Mod[]; installedMods: Mod[]; otherAvailableMods: Mod[]; otherInstalledMods: Mod[]; loading: boolean; }>) { + const otherInstalledLocal = !!otherVersion?.path; + let combinedMods: Mod[] = []; switch (mode) { case Mode.All: @@ -255,7 +300,7 @@ function ModCategory({ break; } - availableMods.forEach(mod => { + otherAvailableMods.forEach(mod => { if (combinedMods.findIndex(cm => cm.name === mod.name) === -1) { combinedMods.push(mod); } @@ -286,7 +331,7 @@ function ModCategory({
{combinedMods.map(mod => im.name === mod.name) > -1} otherMod={otherAvailableMods.find(oam => oam.name === mod.name)} otherInstalled={otherInstalledMods.findIndex(oim => oim.name === mod.name) > -1} + otherInstalledLocal={otherInstalledLocal} loading={loading} /> )} @@ -315,7 +361,8 @@ export const ModsVersionCompareModal: ModalComponent { // TODO : Very ugly very messy, need to find a better way to do this @@ -288,6 +289,10 @@ export const BsmIcon = memo(({ className, icon, style }: { className?: string; i return } + if (icon === "compare") { + return + } + return ; diff --git a/src/renderer/components/svgs/icons/compare-icon.component.tsx b/src/renderer/components/svgs/icons/compare-icon.component.tsx new file mode 100644 index 000000000..465a2e11e --- /dev/null +++ b/src/renderer/components/svgs/icons/compare-icon.component.tsx @@ -0,0 +1,15 @@ +import { CSSProperties } from "react"; + +export function CompareIcon(props: Readonly<{ className?: string; style?: CSSProperties }>) { + return ( + + + + ); +} diff --git a/src/renderer/components/svgs/icons/down-icon.component.tsx b/src/renderer/components/svgs/icons/down-icon.component.tsx new file mode 100644 index 000000000..5abec0a5b --- /dev/null +++ b/src/renderer/components/svgs/icons/down-icon.component.tsx @@ -0,0 +1,15 @@ +import { CSSProperties } from "react"; + +export function DownIcon(props: Readonly<{ className?: string; style?: CSSProperties }>) { + return ( + + + + ); +} diff --git a/src/renderer/components/svgs/icons/equals-icon.component.tsx b/src/renderer/components/svgs/icons/equals-icon.component.tsx new file mode 100644 index 000000000..69b51d629 --- /dev/null +++ b/src/renderer/components/svgs/icons/equals-icon.component.tsx @@ -0,0 +1,15 @@ +import { CSSProperties } from "react"; + +export function EqualIcon(props: Readonly<{ className?: string; style?: CSSProperties }>) { + return ( + + + + ); +} diff --git a/src/renderer/components/svgs/icons/remove-icon.component.tsx b/src/renderer/components/svgs/icons/remove-icon.component.tsx new file mode 100644 index 000000000..c035ec268 --- /dev/null +++ b/src/renderer/components/svgs/icons/remove-icon.component.tsx @@ -0,0 +1,15 @@ +import { CSSProperties } from "react"; + +export function RemoveIcon(props: Readonly<{ className?: string; style?: CSSProperties }>) { + return ( + + + + ) +} diff --git a/src/renderer/components/svgs/icons/up-icon.component.tsx b/src/renderer/components/svgs/icons/up-icon.component.tsx new file mode 100644 index 000000000..f8bca33a5 --- /dev/null +++ b/src/renderer/components/svgs/icons/up-icon.component.tsx @@ -0,0 +1,15 @@ +import { CSSProperties } from "react"; + +export function UpIcon(props: Readonly<{ className?: string; style?: CSSProperties }>) { + return ( + + + + ); +} diff --git a/src/renderer/components/version-viewer/slides/mods/mods-grid.component.tsx b/src/renderer/components/version-viewer/slides/mods/mods-grid.component.tsx index d5a6e5cbe..6f4c7316a 100644 --- a/src/renderer/components/version-viewer/slides/mods/mods-grid.component.tsx +++ b/src/renderer/components/version-viewer/slides/mods/mods-grid.component.tsx @@ -71,7 +71,7 @@ export function ModsGrid({ modsMap, installed, modsSelected, onModChange, moreIn openModsDropZone?.() }, - { text: "pages.version-viewer.mods.mods-grid.header-bar.dropdown.compare-mods", icon: "null", onClick: () => openModsVersionCompare?.() }, + { text: "pages.version-viewer.mods.mods-grid.header-bar.dropdown.compare-mods", icon: "compare", onClick: () => openModsVersionCompare?.() }, { text: "pages.version-viewer.mods.mods-grid.header-bar.dropdown.unselect-all", icon: "cancel", onClick: () => unselectAllMods?.() }, { text: "pages.version-viewer.mods.mods-grid.header-bar.dropdown.uninstall-all", icon: "trash", onClick: () => uninstallAllMods?.() } ]} />