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 { registerEvent } from "../register-event";
import updater, {
ProgressInfo,
UpdateDownloadedEvent,
UpdateInfo,
} from "electron-updater";
import updater, { ProgressInfo, UpdateInfo } from "electron-updater";
import { WindowManager } from "@main/services";
import { app } from "electron";
const { autoUpdater } = updater;
const checkForUpdates = async (
_event: Electron.IpcMainInvokeEvent,
cb: (value: AppUpdaterEvents) => void
) => {
console.log("check for updates event");
const checkForUpdates = async (_event: Electron.IpcMainInvokeEvent) => {
const sendEvent = (event: AppUpdaterEvents) => {
WindowManager.splashWindow?.webContents.send("autoUpdaterEvent", event);
};
autoUpdater
.addListener("error", (error: Error, message?: string) => {
cb({ error, message });
.once("error", () => {
sendEvent({ type: "error" });
})
.addListener("checking-for-update", () => {
cb("checking-for-updates");
.once("checking-for-update", () => {
sendEvent({ type: "checking-for-updates" });
})
.addListener("update-not-available", (info: UpdateInfo) => {
cb(info);
.once("update-not-available", (info: UpdateInfo) => {
sendEvent({ type: "update-not-available", info });
})
.addListener("update-available", (info: UpdateInfo) => {
cb(info);
.once("update-available", (info: UpdateInfo) => {
sendEvent({ type: "update-available", info });
})
.addListener("update-downloaded", (event: UpdateDownloadedEvent) => {
cb(event);
.once("update-downloaded", () => {
sendEvent({ type: "update-downloaded" });
})
.addListener("download-progress", (info: ProgressInfo) => {
cb(info);
sendEvent({ type: "download-progress", info });
})
.addListener("update-cancelled", (info: UpdateInfo) => {
cb(info);
.once("update-cancelled", (info: UpdateInfo) => {
sendEvent({ type: "update-cancelled", info });
});
autoUpdater.checkForUpdates();
if (app.isPackaged) {
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);

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/auto-launch";
import "./autoupdater/check-for-updates";
import "./autoupdater/restart-and-install-update";
import "./autoupdater/continue-to-main-window";
ipcMain.handle("ping", () => "pong");
ipcMain.handle("getVersion", () => app.getVersion());

View File

@ -7,7 +7,7 @@ import { resolveDatabaseUpdates, WindowManager } from "@main/services";
import { dataSource } from "@main/data-source";
import * as resources from "@locales";
import { userPreferencesRepository } from "@main/repository";
import electronLog from "electron-log";
import electronLog, { MainLogger } from "electron-log";
const { autoUpdater } = updater;
autoUpdater.setFeedURL({
@ -17,7 +17,7 @@ autoUpdater.setFeedURL({
});
autoUpdater.logger = electronLog;
autoUpdater.logger.transports.file.level = "info";
(autoUpdater.logger as MainLogger).transports.file.level = "info";
const gotTheLock = app.requestSingleInstanceLock();
if (!gotTheLock) app.quit();
@ -67,18 +67,7 @@ app.whenReady().then(() => {
});
WindowManager.createSplashScreen();
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({
width: 400,
height: 400,
frame: true,
frame: false,
alwaysOnTop: false,
webPreferences: {
preload: path.join(__dirname, "../preload/index.mjs"),

View File

@ -115,6 +115,19 @@ contextBridge.exposeInMainWorld("electron", {
platform: process.platform,
/* Splash */
checkForUpdates: (cb: (value: AppUpdaterEvents) => void) =>
ipcRenderer.invoke("checkForUpdates", cb),
onAutoUpdaterEvent: (cb: (value: AppUpdaterEvents) => void) => {
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 {
AppUpdaterEvents,
CatalogueCategory,
CatalogueEntry,
Game,
@ -92,7 +93,12 @@ declare global {
platform: NodeJS.Platform;
/* 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 {

View File

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

View File

@ -14,5 +14,5 @@ export const main = 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 "../../app.css";
import { useEffect } from "react";
import { useEffect, useState } from "react";
import { AppUpdaterEvents } from "@types";
document.body.classList.add(themeClass);
export default function Splash() {
const [status, setStatus] = useState<AppUpdaterEvents | null>(null);
useEffect(() => {
window.electron.checkForUpdates((event) => {
console.log("-----------");
console.log(event);
});
console.log("subscribing");
const unsubscribe = window.electron.onAutoUpdaterEvent(
(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 (
<main className={styles.main}>
<img src={icon} className={styles.splashIcon} alt="" />
<p>Procurando atualizaçoes</p>
{renderSwitch()}
</main>
);
}

View File

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