Skip to content

Commit d765da0

Browse files
committed
feat: Move Updates to background via toast
1 parent c5a76d7 commit d765da0

File tree

6 files changed

+78
-50
lines changed

6 files changed

+78
-50
lines changed

src/back/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ export const state: BackState = {
9999
isExit: false,
100100
isDev: false,
101101
verbose: false,
102+
updateInProgress: false,
102103
logFile: createErrorProxy('logFile'),
103104
socketServer: new SocketServer(),
104105
curationsReady: false,

src/back/responses.ts

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,15 @@ export function registerRequestCallbacks(state: BackState, init: () => Promise<v
414414
});
415415

416416
state.socketServer.register(BackIn.SYNC_ALL, async (event, source) => {
417+
if (state.updateInProgress) {
418+
const openDialog = state.socketServer.showMessageBoxBack(state, event.client);
419+
openDialog({
420+
largeMessage: true,
421+
message: 'Update already in progress.',
422+
buttons: ['Ok']
423+
});
424+
return false;
425+
}
417426
if (!state.isDev) {
418427
// Make sure we meet minimum verison requirements
419428
const updatesReady = state.componentStatuses.filter(c => c.id === 'core-launcher' && c.state === ComponentState.NEEDS_UPDATE).length > 0;
@@ -424,7 +433,7 @@ export function registerRequestCallbacks(state: BackState, init: () => Promise<v
424433
if (!updatesReady) {
425434
// No software update ready but metadata server requires it
426435
const openDialog = state.socketServer.showMessageBoxBack(state, event.client);
427-
await openDialog({
436+
openDialog({
428437
largeMessage: true,
429438
message: state.languageContainer.app.noLauncherUpdateReady,
430439
buttons: [state.languageContainer.misc.ok]
@@ -433,7 +442,7 @@ export function registerRequestCallbacks(state: BackState, init: () => Promise<v
433442
}
434443
// Too old to sync metadata, prompt a software update
435444
const openDialog = state.socketServer.showMessageBoxBack(state, event.client);
436-
const dialogId = await openDialog({
445+
const dialogId = openDialog({
437446
largeMessage: true,
438447
message: state.languageContainer.app.softwareUpdateRequired,
439448
buttons: [state.languageContainer.misc.yes, state.languageContainer.misc.no],
@@ -450,6 +459,8 @@ export function registerRequestCallbacks(state: BackState, init: () => Promise<v
450459
}
451460
}
452461

462+
state.updateInProgress = true;
463+
453464
let totalGames = 0;
454465
try {
455466
totalGames = await fpDatabase.countGames();
@@ -468,31 +479,27 @@ export function registerRequestCallbacks(state: BackState, init: () => Promise<v
468479
};
469480
}
470481

471-
// Fetch pre-update info to estimate progress bar size
472-
const total = await getMetaUpdateInfo(source, true, totalGames === 0);
473-
const chunks = Math.ceil(total / 2500);
474-
475-
const openDialog = state.socketServer.showMessageBoxBack(state, event.client);
476-
const dialogId = await openDialog({
477-
largeMessage: true,
478-
message: `Syncing metadata from ${source.name}...`,
479-
buttons: [],
480-
fields: [
481-
{
482-
type: 'progress',
483-
name: 'progress',
484-
message: `${total} Updates...`,
485-
value: 0
486-
}
487-
]
488-
});
482+
const updateToast = (content: string) => {
483+
state.socketServer.broadcast(BackOut.TOAST, 'sync', content, {
484+
autoClose: false,
485+
closeButton: false,
486+
});
487+
};
489488

489+
// Fetch pre-update info to estimate progress bar size
490490
try {
491+
updateToast('Getting Update Info...');
492+
const totalUpdateGames = await getMetaUpdateInfo(source, true, totalGames === 0);
493+
const chunks = Math.ceil(totalUpdateGames / 2500);
494+
491495
// Tags and platforms
492496
const newDate = new Date();
493497
let lastDate = new Date();
498+
updateToast('Updating Platforms...');
494499
const lastDatePlats = await syncPlatforms(source);
500+
updateToast('Updating Tags...');
495501
const lastDateTags = await syncTags(source);
502+
496503
if (lastDatePlats > lastDateTags) {
497504
lastDate = lastDatePlats;
498505
} else {
@@ -510,11 +517,12 @@ export function registerRequestCallbacks(state: BackState, init: () => Promise<v
510517
console.log('games');
511518
const dataPacksFolder = path.join(state.config.flashpointPath, state.preferences.dataPacksFolderPath);
512519
let chunk = 0;
520+
updateToast('Updating Games...');
513521
lastDate = await syncGames(source, dataPacksFolder, () => {
514522
chunk = chunk + 1;
515-
const progress = chunk / chunks;
516-
state.socketServer.broadcast(BackOut.UPDATE_DIALOG_FIELD_VALUE, dialogId, 'progress', progress * 100);
523+
updateToast(`Updating Games... (Batch ${chunk} of ${chunks})`);
517524
});
525+
updateToast('Updating Game Redirects...');
518526
await syncRedirects(source);
519527
if (sourceIdx !== -1) {
520528
state.preferences.gameMetadataSources[sourceIdx].games.latestUpdateTime = lastDate.toISOString();
@@ -525,6 +533,7 @@ export function registerRequestCallbacks(state: BackState, init: () => Promise<v
525533
state.socketServer.broadcast(BackOut.UPDATE_PREFERENCES_RESPONSE, state.preferences);
526534
}
527535

536+
updateToast('Updating Search Suggestions...');
528537
// Send out new suggestions and library lists
529538
state.suggestions = {
530539
tags: [],
@@ -538,9 +547,21 @@ export function registerRequestCallbacks(state: BackState, init: () => Promise<v
538547
const total = await fpDatabase.countGames();
539548
const cats = await fpDatabase.findAllTagCategories();
540549
state.socketServer.broadcast(BackOut.POST_SYNC_CHANGES, state.suggestions.library, state.suggestions, state.platformAppPaths, cats, total);
550+
state.socketServer.broadcast(BackOut.TOAST, 'sync', 'Update Complete', {
551+
type: 'success',
552+
autoClose: false,
553+
closeButton: true,
554+
});
541555
return true;
556+
} catch (err: any) {
557+
state.socketServer.broadcast(BackOut.TOAST, 'sync', `Update Failure - ${err.message}`, {
558+
type: 'error',
559+
autoClose: false,
560+
closeButton: true,
561+
});
562+
return false;
542563
} finally {
543-
state.socketServer.broadcast(BackOut.CANCEL_DIALOG, dialogId);
564+
state.updateInProgress = false;
544565
}
545566
});
546567

src/back/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export type BackState = {
3030
runInit: boolean;
3131
isExit: boolean;
3232
isDev: boolean;
33+
updateInProgress: boolean;
3334
verbose: boolean;
3435
socketServer: SocketServer;
3536
curationsReady: boolean;

src/renderer/components/app.tsx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ import * as path from 'node:path';
3030
import * as React from 'react';
3131
import { Activity, useState } from 'react';
3232
import { Route, Routes, useLocation, useNavigate } from 'react-router-dom';
33-
import { ToastContainer } from 'react-toastify';
33+
import { toast, ToastContainer } from 'react-toastify';
3434
import { axios, getGameImagePath, getGameImageURL, getGamePath, openUrlInWindow } from '../Util';
3535
import { LangContext } from '../util/lang';
3636
import { ActivityRoutes } from './ActivityRoutes';
@@ -751,6 +751,29 @@ function registerWebsocketListeners(dispatch: AppDispatch) {
751751
});
752752
};
753753

754+
window.Shared.back.register(BackOut.TOAST, (event, toastId, content, data) => {
755+
if (!toastId) {
756+
throw 'Toast ID required.';
757+
}
758+
if (toast.isActive(toastId)) {
759+
toast.update(toastId, {
760+
...data,
761+
render: <div>{content}</div>
762+
});
763+
} else {
764+
toast(content, {
765+
...data,
766+
toastId,
767+
} as any);
768+
}
769+
});
770+
771+
window.Shared.back.register(BackOut.CANCEL_TOAST, (event, toastId) => {
772+
if (toast.isActive(toastId)) {
773+
toast.dismiss(toastId);
774+
}
775+
});
776+
754777
window.Shared.back.register(BackOut.INIT_EVENT, (event, data) => {
755778
for (const index of data.done) {
756779
switch (+index) { // DO NOT REMOVE - Fails to convert to enum without explicitint conversion

src/renderer/components/pages/HomePage.tsx

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
import { FancyAnimation } from '@renderer/components/FancyAnimation';
22
import { useAppDispatch, useAppSelector } from '@renderer/hooks/useAppSelector';
3-
import { createDialog, setUpdateInfo } from '@renderer/store/main/slice';
3+
import { setUpdateInfo } from '@renderer/store/main/slice';
44
import { setHomePageBoxOpen } from '@renderer/store/preferences/slice';
55
import { launchGame } from '@renderer/Util';
66
import { BackIn } from '@shared/back/types';
77
import { formatString } from '@shared/utils/StringFormatter';
8-
import { uuid } from '@shared/utils/uuid';
9-
import { DialogState, GameLaunchOverride, GameMetadataSource } from 'flashpoint-launcher';
8+
import { GameLaunchOverride, GameMetadataSource } from 'flashpoint-launcher';
109
import { HomePageComponentProps } from 'flashpoint-launcher-renderer';
1110
import * as React from 'react';
11+
import { useContext, useEffect, useRef, useState } from 'react';
1212
import { LangContext } from '../../util/lang';
1313
import { DynamicComponent } from '../DynamicComponent';
1414
import { SimpleButton } from '../SimpleButton';
15-
import { useContext, useEffect, useRef, useState } from 'react';
1615

1716
export type HomePageProps = {
1817
/** Generator for game context menu */
@@ -132,30 +131,8 @@ function UpdateComponent() {
132131
} else {
133132
// Do update
134133
return window.Shared.back.request(BackIn.SYNC_ALL, source)
135-
.then((success) => {
136-
if (success) {
137-
const dialog: DialogState = {
138-
largeMessage: true,
139-
message: strings.updateComplete,
140-
buttons: [allStrings.misc.ok],
141-
id: uuid()
142-
};
143-
dispatch(createDialog(dialog));
144-
dispatch(setUpdateInfo({
145-
id: source.id,
146-
total: 0
147-
}));
148-
}
149-
})
150134
.catch((err) => {
151135
log.error('Launcher', `Error updating metadata: ${err}`);
152-
const dialog: DialogState = {
153-
largeMessage: true,
154-
message: `ERROR: ${err}`,
155-
buttons: [allStrings.misc.ok],
156-
id: uuid()
157-
};
158-
dispatch(createDialog(dialog));
159136
})
160137
.finally(() => {
161138
setUpdating(false);

src/shared/back/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import { Theme } from '../ThemeFile';
4646
import { AppConfigData, AppExtConfigData } from '../config/interfaces';
4747
import { ExecMapping, GamePropSuggestions, IService, ProcessAction, Task } from '../interfaces';
4848
import { LangFile } from '../lang';
49+
import { UpdateOptions } from 'react-toastify';
4950

5051
export enum BackIn {
5152
UNKNOWN = 1000,
@@ -305,6 +306,8 @@ export enum BackOut {
305306
CANCEL_DIALOG,
306307
UPDATE_DIALOG_MESSAGE,
307308
UPDATE_DIALOG_FIELD_VALUE,
309+
TOAST,
310+
CANCEL_TOAST,
308311

309312
OPEN_DYNAMIC_PAGE,
310313

@@ -567,6 +570,8 @@ export type BackOutTemplate = SocketTemplate<BackOut, {
567570
[BackOut.CANCEL_DIALOG]: (dialogId: string) => void;
568571
[BackOut.UPDATE_DIALOG_MESSAGE]: (message: string, dialogId: string) => void;
569572
[BackOut.UPDATE_DIALOG_FIELD_VALUE]: (dialogId: string, name: string, value: any) => void;
573+
[BackOut.TOAST]: (toastId: string, content: string, opts?: UpdateOptions<unknown>) => void;
574+
[BackOut.CANCEL_TOAST]: (toastId: string) => void;
570575

571576
[BackOut.OPEN_DYNAMIC_PAGE]: (componentName: string, props: any) => void;
572577

0 commit comments

Comments
 (0)