From a5af979bc4458b4f553058e31385323413b91ac1 Mon Sep 17 00:00:00 2001 From: Vitalii Mikhailov Date: Fri, 26 Apr 2024 01:49:09 +0300 Subject: [PATCH] Added detection of additionally installed mods via Steam --- package.json | 2 +- src/utils/loadOrder/manager.tsx | 23 +++++++++++--- src/utils/vortexLauncherManager.ts | 8 +++++ .../LoadOrderItemRenderer.tsx | 30 +++++++++++++++++-- yarn.lock | 8 ++--- 5 files changed, 59 insertions(+), 12 deletions(-) diff --git a/package.json b/package.json index 4060e15..d2e200e 100644 --- a/package.json +++ b/package.json @@ -66,7 +66,7 @@ "xml2js": "^0.5.0" }, "dependencies": { - "@butr/vortexextensionnative": "1.0.103", + "@butr/vortexextensionnative": "1.0.108", "ticks-to-date": "^1.0.3" }, "resolutions": { diff --git a/src/utils/loadOrder/manager.tsx b/src/utils/loadOrder/manager.tsx index a29983c..dac6e4f 100644 --- a/src/utils/loadOrder/manager.tsx +++ b/src/utils/loadOrder/manager.tsx @@ -12,6 +12,7 @@ export class LoadOrderManager implements types.IFBLOGameInfo { private _api: types.IExtensionApi; private _manager: VortexLauncherManager; private _isInitialized = false; + private _allModules: vetypes.ModuleInfoExtendedWithMetadata[] = []; public gameId: string = GAME_ID; public toggleableEntries = true; @@ -26,11 +27,24 @@ export class LoadOrderManager implements types.IFBLOGameInfo { constructor(api: types.IExtensionApi, manager: VortexLauncherManager) { this._api = api; this._manager = manager; - this.customItemRenderer = ({ className = '', item }) => ( - - ); - const refresh = () => this.forceRefresh(); this.usageInstructions = () => ; + + this.customItemRenderer = ({ className = '', item }) => { + const availableProviders = this._allModules + .filter((x) => x.id === item.loEntry.id) + .map((x) => x.moduleProviderType); + + return ( + + ); + }; + const refresh = () => this.forceRefresh(); } private forceRefresh = (): void => { @@ -116,6 +130,7 @@ export class LoadOrderManager implements types.IFBLOGameInfo { // Make sure the LauncherManager has the latest module list this._manager.refreshModules(); + this._allModules = this._manager.getAllModulesWithDuplicates(); // Get the saved Load Order const allModules = this._manager.getAllModules(); diff --git a/src/utils/vortexLauncherManager.ts b/src/utils/vortexLauncherManager.ts index 205bbb5..b967dd0 100644 --- a/src/utils/vortexLauncherManager.ts +++ b/src/utils/vortexLauncherManager.ts @@ -126,6 +126,14 @@ export class VortexLauncherManager { }, {}); }; + /** + * Gets all modules with duplicates - when installed in /Modules and Steam Workshop + * @return + */ + public getAllModulesWithDuplicates = (): vetypes.ModuleInfoExtendedWithMetadata[] => { + return this._launcherManager.getAllModules(); + }; + /** * Will sort the available Modules based on the provided LoadOrder * @param loadOrder diff --git a/src/views/LoadOrderItemRenderer/LoadOrderItemRenderer.tsx b/src/views/LoadOrderItemRenderer/LoadOrderItemRenderer.tsx index 99e494c..b0ab396 100644 --- a/src/views/LoadOrderItemRenderer/LoadOrderItemRenderer.tsx +++ b/src/views/LoadOrderItemRenderer/LoadOrderItemRenderer.tsx @@ -8,13 +8,14 @@ import { actions, Icon, selectors, tooltip, types, util } from 'vortex-api'; import { IVortexViewModelData } from '../../types'; import { versionToString } from '../../utils'; import { MODULE_LOGO, STEAM_LOGO, TW_LOGO } from '../../common'; -import { Utils } from '@butr/vortexextensionnative'; +import { types as vetypes, Utils } from '@butr/vortexextensionnative'; import { TooltipImage } from '../Controls'; interface IBaseProps { api: types.IExtensionApi; className?: string; item: types.IFBLOItemRendererProps; + availableProviders: vetypes.ModuleProviderType[]; } interface IConnectedProps { @@ -72,6 +73,7 @@ export function BannerlordItemRenderer(props: IBaseProps): JSX.Element { {renderModuleIcon(item.loEntry)}

{name} ({version})

{renderExternalBanner(item.loEntry)} + {renderModuleDuplicates(props, item.loEntry)} {renderModuleProviderIcon(item.loEntry)} {checkBox()} {lock()} @@ -79,7 +81,7 @@ export function BannerlordItemRenderer(props: IBaseProps): JSX.Element { ); } -function renderModuleIcon(item: types.IFBLOLoadOrderEntry): JSX.Element | null { +function renderModuleIcon(item: types.IFBLOLoadOrderEntry): JSX.Element { const isOfficial = item.data !== undefined && item.data.moduleInfoExtended.isOfficial; const isCommunity = item.data !== undefined && !item.data.moduleInfoExtended.isOfficial; const dependencies = item.data !== undefined ? Utils.getDependencyHint(item.data.moduleInfoExtended) : ''; @@ -136,7 +138,7 @@ function renderExternalBanner(item: types.IFBLOLoadOrderEntry): JSX.Element | null { +function renderModuleProviderIcon(item: types.IFBLOLoadOrderEntry): JSX.Element { const [t] = useTranslation(['common']); if (isSteamWorksop(item)) { @@ -154,6 +156,28 @@ function renderModuleProviderIcon(item: types.IFBLOLoadOrderEntry): JSX.Element | null { + const { availableProviders } = props; + + if (availableProviders.length <= 1) { + return
; + } + + if (item.data?.moduleInfoExtended.moduleProviderType) { + const redundantProviders = availableProviders.filter((provider) => provider !== item.data?.moduleInfoExtended.moduleProviderType); + return ( + + + ); + } + + return
; +} + function isLocked(item: types.IFBLOLoadOrderEntry): boolean { return [true, 'true', 'always'].includes(item.locked as types.FBLOLockState); } diff --git a/yarn.lock b/yarn.lock index 474e381..30abc06 100644 --- a/yarn.lock +++ b/yarn.lock @@ -22,10 +22,10 @@ dependencies: regenerator-runtime "^0.14.0" -"@butr/vortexextensionnative@1.0.103": - version "1.0.103" - resolved "https://registry.yarnpkg.com/@butr/vortexextensionnative/-/vortexextensionnative-1.0.103.tgz#ca468ec5dbc838ad748cd55a249afa7428120e39" - integrity sha512-Gl/ENuWbKJdWZjRYyKPRb2dcFuPOgMBqH8R6/SEkRZpxJEVZy/N3PS+W3z5KBM1m1hEkuxrCGmAjmrnYEnJ6CA== +"@butr/vortexextensionnative@1.0.108": + version "1.0.108" + resolved "https://registry.yarnpkg.com/@butr/vortexextensionnative/-/vortexextensionnative-1.0.108.tgz#6f0cb83657d91ddb789b390fb4bf0c7dbb4d819b" + integrity sha512-cO/+X/68LhCHPfNb2hObUo6rpoRMVpqnYLsg+IOrBoT602nAVoaI8Hooreqd5rBR61gm+OVzebrUeqSs2ZL4ug== "@cspotcode/source-map-support@^0.8.0": version "0.8.1"