feat: events working

This commit is contained in:
Zamitto 2024-05-19 14:15:07 -03:00
parent 3b17953a82
commit 811878e364
12 changed files with 182 additions and 82 deletions

View File

@ -1,42 +1,79 @@
import { AppUpdaterEvents } from "@types"; import { AppUpdaterEvents } from "@types";
import { registerEvent } from "../register-event"; import { registerEvent } from "../register-event";
import updater, { import updater, { ProgressInfo, UpdateInfo } from "electron-updater";
ProgressInfo, import { WindowManager } from "@main/services";
UpdateDownloadedEvent, import { app } from "electron";
UpdateInfo,
} from "electron-updater";
const { autoUpdater } = updater; const { autoUpdater } = updater;
const checkForUpdates = async ( const checkForUpdates = async (_event: Electron.IpcMainInvokeEvent) => {
_event: Electron.IpcMainInvokeEvent, const sendEvent = (event: AppUpdaterEvents) => {
cb: (value: AppUpdaterEvents) => void WindowManager.splashWindow?.webContents.send("autoUpdaterEvent", event);
) => { };
console.log("check for updates event");
autoUpdater autoUpdater
.addListener("error", (error: Error, message?: string) => { .once("error", () => {
cb({ error, message }); sendEvent({ type: "error" });
}) })
.addListener("checking-for-update", () => { .once("checking-for-update", () => {
cb("checking-for-updates"); sendEvent({ type: "checking-for-updates" });
}) })
.addListener("update-not-available", (info: UpdateInfo) => { .once("update-not-available", (info: UpdateInfo) => {
cb(info); sendEvent({ type: "update-not-available", info });
}) })
.addListener("update-available", (info: UpdateInfo) => { .once("update-available", (info: UpdateInfo) => {
cb(info); sendEvent({ type: "update-available", info });
}) })
.addListener("update-downloaded", (event: UpdateDownloadedEvent) => { .once("update-downloaded", () => {
cb(event); sendEvent({ type: "update-downloaded" });
}) })
.addListener("download-progress", (info: ProgressInfo) => { .addListener("download-progress", (info: ProgressInfo) => {
cb(info); sendEvent({ type: "download-progress", info });
}) })
.addListener("update-cancelled", (info: UpdateInfo) => { .once("update-cancelled", (info: UpdateInfo) => {
cb(info); sendEvent({ type: "update-cancelled", info });
}); });
if (app.isPackaged) {
autoUpdater.checkForUpdates(); autoUpdater.checkForUpdates();
} else {
// electron updater does not check for updates in dev build, so mocking here to test the ui
const sleep = (ms: number) =>
new Promise((resolve) => setTimeout(resolve, ms));
sendEvent({ type: "checking-for-updates" });
await sleep(1500);
sendEvent({
type: "update-available",
info: {
version: "1.2.2",
files: [],
releaseDate: "19/05/2024",
path: "",
sha512: "",
},
});
await sleep(500);
const total = 123456;
for (let i = 0; i <= 5; i++) {
sendEvent({
type: "download-progress",
info: {
total: total,
delta: 123,
transferred: (total * i) / 5,
percent: (total * i) / 5 / total,
bytesPerSecond: 4568,
},
});
await sleep(500);
}
sendEvent({ type: "update-downloaded" });
}
}; };
registerEvent("checkForUpdates", checkForUpdates); registerEvent("checkForUpdates", checkForUpdates);

View File

@ -0,0 +1,9 @@
import { WindowManager } from "@main/services";
import { registerEvent } from "../register-event";
const continueToMainWindow = async (_event: Electron.IpcMainInvokeEvent) => {
WindowManager.splashWindow?.close();
WindowManager.createMainWindow();
};
registerEvent("continueToMainWindow", continueToMainWindow);

View File

@ -0,0 +1,17 @@
import { app } from "electron";
import { registerEvent } from "../register-event";
import updater from "electron-updater";
import { WindowManager } from "@main/services";
const { autoUpdater } = updater;
const restartAndInstallUpdate = async (_event: Electron.IpcMainInvokeEvent) => {
if (app.isPackaged) {
autoUpdater.quitAndInstall();
} else {
WindowManager.splashWindow?.close();
WindowManager.createMainWindow();
}
};
registerEvent("restartAndInstallUpdate", restartAndInstallUpdate);

View File

@ -28,6 +28,8 @@ import "./user-preferences/get-user-preferences";
import "./user-preferences/update-user-preferences"; import "./user-preferences/update-user-preferences";
import "./user-preferences/auto-launch"; import "./user-preferences/auto-launch";
import "./autoupdater/check-for-updates"; import "./autoupdater/check-for-updates";
import "./autoupdater/restart-and-install-update";
import "./autoupdater/continue-to-main-window";
ipcMain.handle("ping", () => "pong"); ipcMain.handle("ping", () => "pong");
ipcMain.handle("getVersion", () => app.getVersion()); ipcMain.handle("getVersion", () => app.getVersion());

View File

@ -7,7 +7,7 @@ import { resolveDatabaseUpdates, WindowManager } from "@main/services";
import { dataSource } from "@main/data-source"; import { dataSource } from "@main/data-source";
import * as resources from "@locales"; import * as resources from "@locales";
import { userPreferencesRepository } from "@main/repository"; import { userPreferencesRepository } from "@main/repository";
import electronLog from "electron-log"; import electronLog, { MainLogger } from "electron-log";
const { autoUpdater } = updater; const { autoUpdater } = updater;
autoUpdater.setFeedURL({ autoUpdater.setFeedURL({
@ -17,7 +17,7 @@ autoUpdater.setFeedURL({
}); });
autoUpdater.logger = electronLog; autoUpdater.logger = electronLog;
autoUpdater.logger.transports.file.level = "info"; (autoUpdater.logger as MainLogger).transports.file.level = "info";
const gotTheLock = app.requestSingleInstanceLock(); const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) app.quit(); if (!gotTheLock) app.quit();
@ -67,18 +67,7 @@ app.whenReady().then(() => {
}); });
WindowManager.createSplashScreen(); WindowManager.createSplashScreen();
WindowManager.createSystemTray(userPreferences?.language || "en"); WindowManager.createSystemTray(userPreferences?.language || "en");
WindowManager.splashWindow?.on("ready-to-show", () => {
console.log("ready to show");
autoUpdater.checkForUpdates().then((r) => {
console.log(r);
//WindowManager.splashWindow?.close();
//WindowManager.createMainWindow();
});
});
}); });
}); });

View File

@ -57,7 +57,7 @@ export class WindowManager {
this.splashWindow = new BrowserWindow({ this.splashWindow = new BrowserWindow({
width: 400, width: 400,
height: 400, height: 400,
frame: true, frame: false,
alwaysOnTop: false, alwaysOnTop: false,
webPreferences: { webPreferences: {
preload: path.join(__dirname, "../preload/index.mjs"), preload: path.join(__dirname, "../preload/index.mjs"),

View File

@ -115,6 +115,19 @@ contextBridge.exposeInMainWorld("electron", {
platform: process.platform, platform: process.platform,
/* Splash */ /* Splash */
checkForUpdates: (cb: (value: AppUpdaterEvents) => void) => onAutoUpdaterEvent: (cb: (value: AppUpdaterEvents) => void) => {
ipcRenderer.invoke("checkForUpdates", cb), const listener = (
_event: Electron.IpcRendererEvent,
value: AppUpdaterEvents
) => cb(value);
ipcRenderer.on("autoUpdaterEvent", listener);
return () => {
ipcRenderer.removeListener("autoUpdaterEvent", listener);
};
},
checkForUpdates: () => ipcRenderer.invoke("checkForUpdates"),
restartAndInstallUpdate: () => ipcRenderer.invoke("restartAndInstallUpdate"),
continueToMainWindow: () => ipcRenderer.invoke("continueToMainWindow"),
}); });

View File

@ -1,4 +1,5 @@
import type { import type {
AppUpdaterEvents,
CatalogueCategory, CatalogueCategory,
CatalogueEntry, CatalogueEntry,
Game, Game,
@ -92,7 +93,12 @@ declare global {
platform: NodeJS.Platform; platform: NodeJS.Platform;
/* Splash */ /* Splash */
checkForUpdates: (cb: (value: AppUpdaterEvents) => void) => Promise<void>; onAutoUpdaterEvent: (
cb: (event: AppUpdaterEvents) => void
) => () => Electron.IpcRenderer;
checkForUpdates: () => Promise<void>;
restartAndInstallUpdate: () => Promise<void>;
continueToMainWindow: () => Promise<void>;
} }
interface Window { interface Window {

View File

@ -48,9 +48,9 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
<Provider store={store}> <Provider store={store}>
<HashRouter> <HashRouter>
<Routes> <Routes>
<Route path="/" Component={Splash} /> <Route path="/splash" Component={Splash} />
<Route element={<App />}> <Route element={<App />}>
<Route path="/teste" Component={Home} /> <Route path="/" Component={Home} />
<Route path="/catalogue" Component={Catalogue} /> <Route path="/catalogue" Component={Catalogue} />
<Route path="/downloads" Component={Downloads} /> <Route path="/downloads" Component={Downloads} />
<Route path="/game/:shop/:objectID" Component={GameDetails} /> <Route path="/game/:shop/:objectID" Component={GameDetails} />

View File

@ -14,5 +14,5 @@ export const main = style({
}); });
export const splashIcon = style({ export const splashIcon = style({
width: "300px", width: "250px",
}); });

View File

@ -3,22 +3,73 @@ import * as styles from "./splash.css";
import { themeClass } from "../../theme.css"; import { themeClass } from "../../theme.css";
import "../../app.css"; import "../../app.css";
import { useEffect } from "react"; import { useEffect, useState } from "react";
import { AppUpdaterEvents } from "@types";
document.body.classList.add(themeClass); document.body.classList.add(themeClass);
export default function Splash() { export default function Splash() {
const [status, setStatus] = useState<AppUpdaterEvents | null>(null);
useEffect(() => { useEffect(() => {
window.electron.checkForUpdates((event) => { console.log("subscribing");
console.log("-----------"); const unsubscribe = window.electron.onAutoUpdaterEvent(
console.log(event); (event: AppUpdaterEvents) => {
}); console.log("event from screen: " + event.type);
setStatus(event);
switch (event.type) {
case "download-progress":
console.log(event.info);
break;
case "checking-for-updates":
break;
case "error":
window.electron.continueToMainWindow();
break;
case "update-available":
break;
case "update-cancelled":
window.electron.continueToMainWindow();
break;
case "update-downloaded":
window.electron.restartAndInstallUpdate();
break;
case "update-not-available":
window.electron.continueToMainWindow();
break;
}
}
);
window.electron.checkForUpdates();
return () => {
unsubscribe();
};
}, []); }, []);
const renderSwitch = () => {
switch (status?.type) {
case "download-progress":
return (
<>
<p>Baixando</p>
<p>{status.info.percent}</p>
</>
);
case "checking-for-updates":
return <p>Buscando atualizações</p>;
case "update-available":
return <p>Atualização encontrada</p>;
default:
return <></>;
}
};
return ( return (
<main className={styles.main}> <main className={styles.main}>
<img src={icon} className={styles.splashIcon} alt="" /> <img src={icon} className={styles.splashIcon} alt="" />
<p>Procurando atualizaçoes</p> {renderSwitch()}
</main> </main>
); );
} }

View File

@ -1,9 +1,5 @@
import type { Downloader, GameStatus } from "@shared"; import type { Downloader, GameStatus } from "@shared";
import { import { ProgressInfo, UpdateInfo } from "electron-updater";
ProgressInfo,
UpdateDownloadedEvent,
UpdateInfo,
} from "electron-updater";
export type GameShop = "steam" | "epic"; export type GameShop = "steam" | "epic";
export type CatalogueCategory = "recently_added" | "trending"; export type CatalogueCategory = "recently_added" | "trending";
@ -149,31 +145,11 @@ export interface SteamGame {
clientIcon: string | null; clientIcon: string | null;
} }
interface ErrorEvent {
error: Error;
message?: string;
}
interface UpdateNotAvailable {
info: UpdateInfo;
}
interface UpdateAvailable {
info: UpdateInfo;
}
interface UpdateDownloaded {
event: UpdateDownloadedEvent;
}
interface DownloadProgress {
info: ProgressInfo;
}
interface UpdateCancelled {
info: UpdateInfo;
}
export type AppUpdaterEvents = export type AppUpdaterEvents =
| ErrorEvent | { type: "error" }
| UpdateNotAvailable | { type: "checking-for-updates" }
| UpdateAvailable | { type: "update-not-available"; info: UpdateInfo }
| UpdateDownloaded | { type: "update-available"; info: UpdateInfo }
| DownloadProgress | { type: "update-downloaded" }
| UpdateCancelled; | { type: "download-progress"; info: ProgressInfo }
| { type: "update-cancelled"; info: UpdateInfo };