Skip to content

Commit

Permalink
Added installation progress bar
Browse files Browse the repository at this point in the history
  • Loading branch information
olegbl committed Jun 24, 2024
1 parent 389b508 commit b5bcbcf
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 14 deletions.
5 changes: 1 addition & 4 deletions ROADMAP.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
# Mod Manager

- Improved made possible by new architecture
- Auto-scroll console to latest message while intalling mods
- Show progress bar (mod N/M) while installing mods
- Show progress bar while downloading update
- Show progress bar while downloading update
- Mod config actions
- Typeahead config
- Check for mod updates via GitHub
Expand Down
12 changes: 12 additions & 0 deletions src/main/worker/BridgeAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { Relative } from 'bridge/Relative';
import type { TSVDataRow } from 'bridge/TSV';
import packageManifest from '../../../release/app/package.json';
import { getAppPath, getHomePath } from './AppInfoAPI';
import { BroadcastAPI } from './BroadcastAPI';
import { dwordPtr, getCascLib, processErrorCode, voidPtrPtr } from './CascLib';
import { provideAPI } from './IPC';
import { InstallationRuntime } from './InstallationRuntime';
Expand Down Expand Up @@ -1021,6 +1022,11 @@ const config = JSON.parse(D2RMM.getConfigJSON());
}

for (let i = 0; i < runtime.modsToInstall.length; i = i + 1) {
BroadcastAPI.send(
'installationProgress',
i,
runtime.modsToInstall.length,
);
runtime.mod = runtime.modsToInstall[i];
let code: string = '';
let sourceMap: string = '';
Expand Down Expand Up @@ -1095,6 +1101,12 @@ const config = JSON.parse(D2RMM.getConfigJSON());
}
runtime.mod = null;

BroadcastAPI.send(
'installationProgress',
runtime.modsToInstall.length,
runtime.modsToInstall.length,
);

if (!runtime.options.isPreExtractedData) {
await BridgeAPI.closeStorage();
}
Expand Down
17 changes: 12 additions & 5 deletions src/renderer/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Box, Divider, Tab } from '@mui/material';
import './App.css';
import ErrorBoundary from './ErrorBoundary';
import { InstallContextProvider } from './InstallContext';
import InstallationProgressBar from './InstallationProgressBar';
import { LogsProvider } from './Logs';
import ModList from './ModList';
import ModManagerLogs from './ModManagerLogs';
Expand Down Expand Up @@ -58,11 +59,17 @@ function D2RMMRootView() {
overflow: 'hidden',
}}
>
<TabList onChange={(_event, value) => setTab(value)}>
<Tab label="Mods" value="mods" />
<Tab label="Settings" value="settings" />
<Tab label="Logs" value="logs" />
</TabList>
<Box
sx={{ display: 'flex', flexDirection: 'row', alignItems: 'center' }}
>
<TabList onChange={(_event, value) => setTab(value)}>
<Tab label="Mods" value="mods" />
<Tab label="Settings" value="settings" />
<Tab label="Logs" value="logs" />
</TabList>
<Box sx={{ flex: 1 }} />
<InstallationProgressBar />
</Box>
<Divider />
<TabPanelBox value="mods">
<ModList />
Expand Down
38 changes: 33 additions & 5 deletions src/renderer/InstallContext.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import React, { useMemo } from 'react';
import React, { useContext, useEffect, useMemo, useState } from 'react';
import { BroadcastAPI } from './BroadcastAPI';

type SetIsInstalling = React.Dispatch<React.SetStateAction<boolean>>;
type SetProgress = React.Dispatch<React.SetStateAction<number>>;

export type IInstallContext = {
isInstalling: boolean;
setIsInstalling: SetIsInstalling;
progress: number;
setProgress: SetProgress;
};

const InstallContext = React.createContext<IInstallContext | null>(null);
Expand All @@ -14,13 +18,27 @@ export function InstallContextProvider({
}: {
children: React.ReactNode;
}): JSX.Element {
const [isInstalling, setIsInstalling] = React.useState<boolean>(false);
const [isInstalling, setIsInstalling] = useState<boolean>(false);
const [progress, setProgress] = useState<number>(0);

const context = useMemo(
() => ({ isInstalling, setIsInstalling }),
[isInstalling, setIsInstalling],
() => ({ isInstalling, setIsInstalling, progress, setProgress }),
[isInstalling, setIsInstalling, progress, setProgress],
);

useEffect(() => {
const listener = async (
installedModsCount: unknown,
totalModsCount: unknown,
) =>
setProgress(
((installedModsCount as number) / (totalModsCount as number)) * 100,
);
BroadcastAPI.addEventListener('installationProgress', listener);
return () =>
BroadcastAPI.removeEventListener('installationProgress', listener);
}, [setProgress]);

return (
<InstallContext.Provider value={context}>
{children}
Expand All @@ -29,9 +47,19 @@ export function InstallContextProvider({
}

export function useIsInstalling(): [boolean, SetIsInstalling] {
const context = React.useContext(InstallContext);
const context = useContext(InstallContext);
if (context == null) {
throw new Error('useIsInstalling used outside of a InstallContextProvider');
}
return [context.isInstalling, context.setIsInstalling];
}

export function useInstallationProgress(): [number, SetProgress] {
const context = useContext(InstallContext);
if (context == null) {
throw new Error(
'useInstallationProgress used outside of a InstallContextProvider',
);
}
return [context.progress, context.setProgress];
}
20 changes: 20 additions & 0 deletions src/renderer/InstallationProgressBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Box, LinearProgress, Tab } from '@mui/material';
import { useInstallationProgress, useIsInstalling } from './InstallContext';

export default function InstallationProgressBar() {
const [isInstalling] = useIsInstalling();
const [installationProgress] = useInstallationProgress();

if (!isInstalling) {
return null;
}

return (
<>
<Box sx={{ flex: 1 }}>
<LinearProgress variant="determinate" value={installationProgress} />
</Box>
<Tab label={`${installationProgress.toFixed(0)}%`} disabled={true} />
</>
);
}

0 comments on commit b5bcbcf

Please sign in to comment.