From 811878e36410f0abf051f4bcbef962c19fd9cd64 Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Sun, 19 May 2024 14:15:07 -0300 Subject: [PATCH] feat: events working --- .../events/autoupdater/check-for-updates.ts | 85 +++++++++++++------ .../autoupdater/continue-to-main-window.ts | 9 ++ .../autoupdater/restart-and-install-update.ts | 17 ++++ src/main/events/index.ts | 2 + src/main/index.ts | 15 +--- src/main/services/window-manager.ts | 2 +- src/preload/index.ts | 17 +++- src/renderer/src/declaration.d.ts | 8 +- src/renderer/src/main.tsx | 4 +- src/renderer/src/pages/splash/splash.css.ts | 2 +- src/renderer/src/pages/splash/splash.tsx | 63 ++++++++++++-- src/types/index.ts | 40 ++------- 12 files changed, 182 insertions(+), 82 deletions(-) create mode 100644 src/main/events/autoupdater/continue-to-main-window.ts create mode 100644 src/main/events/autoupdater/restart-and-install-update.ts diff --git a/src/main/events/autoupdater/check-for-updates.ts b/src/main/events/autoupdater/check-for-updates.ts index cdffb260..76bac878 100644 --- a/src/main/events/autoupdater/check-for-updates.ts +++ b/src/main/events/autoupdater/check-for-updates.ts @@ -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); diff --git a/src/main/events/autoupdater/continue-to-main-window.ts b/src/main/events/autoupdater/continue-to-main-window.ts new file mode 100644 index 00000000..f8b2bb2c --- /dev/null +++ b/src/main/events/autoupdater/continue-to-main-window.ts @@ -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); diff --git a/src/main/events/autoupdater/restart-and-install-update.ts b/src/main/events/autoupdater/restart-and-install-update.ts new file mode 100644 index 00000000..f54c2b0b --- /dev/null +++ b/src/main/events/autoupdater/restart-and-install-update.ts @@ -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); diff --git a/src/main/events/index.ts b/src/main/events/index.ts index 3d749d0c..debca0e4 100644 --- a/src/main/events/index.ts +++ b/src/main/events/index.ts @@ -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()); diff --git a/src/main/index.ts b/src/main/index.ts index 7b6af0df..89a6147c 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -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(); - }); - }); }); }); diff --git a/src/main/services/window-manager.ts b/src/main/services/window-manager.ts index e2128a0c..35b58151 100644 --- a/src/main/services/window-manager.ts +++ b/src/main/services/window-manager.ts @@ -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"), diff --git a/src/preload/index.ts b/src/preload/index.ts index 0a12218f..4ddf5009 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -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"), }); diff --git a/src/renderer/src/declaration.d.ts b/src/renderer/src/declaration.d.ts index 1f3a3a9e..608f21a0 100644 --- a/src/renderer/src/declaration.d.ts +++ b/src/renderer/src/declaration.d.ts @@ -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; + onAutoUpdaterEvent: ( + cb: (event: AppUpdaterEvents) => void + ) => () => Electron.IpcRenderer; + checkForUpdates: () => Promise; + restartAndInstallUpdate: () => Promise; + continueToMainWindow: () => Promise; } interface Window { diff --git a/src/renderer/src/main.tsx b/src/renderer/src/main.tsx index 19456ff9..3608af8d 100644 --- a/src/renderer/src/main.tsx +++ b/src/renderer/src/main.tsx @@ -48,9 +48,9 @@ ReactDOM.createRoot(document.getElementById("root")!).render( - + }> - + diff --git a/src/renderer/src/pages/splash/splash.css.ts b/src/renderer/src/pages/splash/splash.css.ts index 4a7761b4..cae94a51 100644 --- a/src/renderer/src/pages/splash/splash.css.ts +++ b/src/renderer/src/pages/splash/splash.css.ts @@ -14,5 +14,5 @@ export const main = style({ }); export const splashIcon = style({ - width: "300px", + width: "250px", }); diff --git a/src/renderer/src/pages/splash/splash.tsx b/src/renderer/src/pages/splash/splash.tsx index 90ce8c67..b777270f 100644 --- a/src/renderer/src/pages/splash/splash.tsx +++ b/src/renderer/src/pages/splash/splash.tsx @@ -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(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 ( + <> +

Baixando

+

{status.info.percent}

+ + ); + case "checking-for-updates": + return

Buscando atualizações

; + case "update-available": + return

Atualização encontrada

; + default: + return <>; + } + }; + return (
-

Procurando atualizaçoes

+ {renderSwitch()}
); } diff --git a/src/types/index.ts b/src/types/index.ts index 9518ce3e..be8ebbd8 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -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 };