diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4eee0aad..cd91c635 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,4 +1,4 @@ -name: Build +name: Release on: push: diff --git a/README.be.md b/README.be.md index d74e3291..c5848f79 100644 --- a/README.be.md +++ b/README.be.md @@ -119,7 +119,7 @@ yarn ### Усталёўка Python 3.9 -Упэўніцеся, што ў вас усталяваны Python 3.9 на вашым кампутары. Вы можаце загрузіць і ўсталяваць яго з [python.org](https://www.python.org/downloads/release/python-3919/). +Упэўніцеся, што ў вас усталяваны Python 3.9 на вашым кампутары. Вы можаце загрузіць і ўсталяваць яго з [python.org](https://www.python.org/downloads/release/python-3913/). ### Усталёўка залежнасцяў Python diff --git a/README.md b/README.md index 2162b75b..ab608f37 100644 --- a/README.md +++ b/README.md @@ -13,11 +13,11 @@ [![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions) [![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases) +[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md) +[![pl](https://img.shields.io/badge/lang-pl-white)](README.pl.md) [![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md) -[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md) [![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md) [![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md) -[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md) ![Hydra Catalogue](./docs/screenshot.png) @@ -119,7 +119,7 @@ yarn ### Install Python 3.9 -Ensure you have Python 3.9 installed on your machine. You can download and install it from [python.org](https://www.python.org/downloads/release/python-3919/). +Ensure you have Python 3.9 installed on your machine. You can download and install it from [python.org](https://www.python.org/downloads/release/python-3913/). ### Install Python Dependencies diff --git a/README.pl.md b/README.pl.md new file mode 100644 index 00000000..4fa7449e --- /dev/null +++ b/README.pl.md @@ -0,0 +1,185 @@ +
+ +
+ +[](https://hydralauncher.site) + +

Hydra Launcher

+ +

+ Hydra - to program uruchamiający gry z własnym wbudowanym klientem bittorrent i samodzielnie zarządzanym repackagerem.. +

+ +[![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions) +[![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases) + +[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md) +[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md) +[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md) +[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md) +[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md) + +![Hydra Catalogue](./docs/screenshot.png) + +
+ +## Zawartość. + +- [O nas](#o-nas) +- [Cechy.](#cechy) +- [Instalacja](#instalacja) +- [Dokonaj wpłaty](#dokonaj-wpłaty) + - [Dołącz do naszego kanału Telegram](#dołącz-do-naszego-kanału-telegram) + - [Rozwidlenie i sklonowanie repozytorium](#rozwidlenie-i-sklonowanie-repozytorium) + - [Jak możesz wnieść swój wkład](#jak-możesz-pomóc) + - [Struktura projektu](#struktura-projektu) +- [Utwórz kompilację z kodu źródłowego](#utwórz-kompilację-z-kodu-źródłowego) + - [Instalacja Node.js](#zainstaluj-nodejs) + - [Instalacja Yarn](#zainstaluj-yarn) + - [Instalacja Node zależności](#zainstaluj-zależności-node) + - [Instalacja Python 3.9](#zainstaluj-python-39) + - [Instalacja Python zależności](#zainstaluj-zależności-pythona) +- [Zmienne środowiskowe](#zmienne-środowiskowe) +- [Uruchomienie](#utwórz-kompilację-z-kodu-źródłowego) +- [Tworzenie kompilacji](#tworzenie-kompilacji) + - [Tworzenie klienta bittorrent](#zbuduj-klienta-bittorrent) + - [Tworzenie kompilacji aplikacji Electron](#tworzenie-aplikacji-electron) +- [Współtwórcy](#współtwórcy) + +## O nas + +**Hydra** - jest **programem uruchamiającym gry** z wbudowanym **klientem BitTorrent** i **samozarządzającym się repackagerem**. +
+Ten launcher jest napisany w TypeScript (Electron) i Pythonie, który współpracuje z systemem torrent przy użyciu libtorrent. + +## Cechy + +- Samodzielnie zarządzany repackager wśród wszystkich najbardziej zaufanych stron na [Megathread]("https://www.reddit.com/r/Piracy/wiki/megathread/"). +- Własny wbudowany klient bittorrent +- Integracja funkcji How Long To Beat (HLTB) na stronie gry +- Personalizacja folderu pobierania +- Powiadomienia o aktualizacjach listy repacków +- Wsparcie dla systemów Windows i Linux +- Stała aktualizacja +- I nie tylko ... + +## Instalacja + +Aby zainstalować, wykonaj poniższe czynności: + +1. Pobierz najnowszą wersję programu Hydra ze strony [Wydania](https://github.com/hydralauncher/hydra/releases/latest). + - Pobierz .exe tylko, jeśli chcesz zainstalować Hydrę w systemie Windows. + - Pobierz .deb lub .rpm lub .zip, jeśli chcesz zainstalować Hydrę w systemie Linux (zależy od dystrybucji systemu Linux). +2. Uruchom pobrany plik. +3. Ciesz się Hydrą! + +## Dokonaj wpłaty + +### Dołącz do naszego kanału Telegram + +Skupiamy nasze dyskusje na naszym kanale [Telegram](https://t.me/hydralauncher). + +1. Dołącz do naszego kanału +2. Przejdź do kanału ról i wybierz rolę Pracownik. +3. Wejdź na kanał dev, komunikuj się z nami i dziel się swoimi pomysłami. + +### Rozwidlenie i sklonowanie repozytorium + +1. Rozwidlenie repozytorium [(kliknij tutaj, aby rozwidlić teraz)](https://github.com/hydralauncher/hydra/fork) +2. Sklonuj swój rozwidlony kod `git clone https://github.com/your_username/hydra`. +3. Utwórz nowy brunch +4. Wypchnij swoje zatwierdzenia +5. Wyślij nowy Pull Request + +### Jak możesz pomóc + +- Tłumaczenie: Chcemy, aby Hydra była dostępna dla jak największej liczby osób. Zachęcamy do pomocy w tłumaczeniu na nowe języki lub aktualizowaniu i ulepszaniu tych, które są już dostępne na Hydrze. +- Kod: Hydra jest zbudowana przy użyciu Typescript, Electron i odrobiny Pythona. Jeśli chcesz wnieść swój wkład, dołącz do naszego kanału Telegram! + +### Struktura projektu + +- Klient torrent: Używamy libtorrent, biblioteki Pythona, do zarządzania pobieraniem torrentów. +- src/renderer: interfejs aplikacji +- src/main: cała logika jest tutaj. + +## Utwórz kompilację z kodu źródłowego + +### Zainstaluj Node.js + +Upewnij się, że masz zainstalowany Node.js na swoim komputerze. Jeśli nie, pobierz i zainstaluj go ze strony [nodejs.org](https://nodejs.org/). + +### Zainstaluj Yarn + +Yarn to menedżer pakietów dla Node.js. Jeśli jeszcze nie zainstalowałeś Yarn, możesz to zrobić, postępując zgodnie z instrukcjami na stronie [yarnpkg.com](https://classic.yarnpkg.com/lang/en/docs/install/). + +### Zainstaluj zależności Node + +Przejdź do katalogu projektu i zainstaluj zależności Node za pomocą Yarn: + +```bash +cd hydra +yarn +``` + +### Zainstaluj Python 3.9 + +Upewnij się, że masz zainstalowany Python 3.9 na swoim komputerze. Można go pobrać i zainstalować ze strony [python.org](https://www.python.org/downloads/release/python-3913/). + +### Zainstaluj zależności Pythona + +Zainstaluj niezbędne zależności Pythona za pomocą pip: + +```bash +pip install -r requirements.txt +``` + +## Zmienne środowiskowe + +Będziesz potrzebował klucza API SteamGridDB, aby uzyskać ikony gier podczas instalacji. +Jeśli chcesz użyć onlinefix jako repackagera, musisz dodać swoje dane uwierzytelniające do .env + +Po jego uzyskaniu można skopiować plik lub zmienić jego nazwę `.env.example` na `.env` i umieść go na`STEAMGRIDDB_API_KEY`, `ONLINEFIX_USERNAME`, `ONLINEFIX_PASSWORD`. + +## Run + +Po skonfigurowaniu wszystkiego można uruchomić następujące polecenie, aby uruchomić zarówno proces Electron, jak i klienta bittorrent: + +```bash +yarn dev +``` + +## Tworzenie kompilacji + +### Zbuduj klienta bittorrent + +Zbuduj klienta bittorrent za pomocą tego poleceniaи: + +```bash +python torrent-client/setup.py build +``` + +### Tworzenie aplikacji Electron + +Zbuduj aplikację Electron za pomocą tego polecenia: + +W systemie Windows: + +```bash +yarn build:win +``` + +W systemie Linux: + +```bash +yarn build:linux +``` + +## Współtwórcy + + + + + +## License + +Hydra posiada licencję [MIT License](LICENSE). diff --git a/README.pt-BR.md b/README.pt-BR.md index 5d04e48b..07c89e96 100644 --- a/README.pt-BR.md +++ b/README.pt-BR.md @@ -13,12 +13,11 @@ [![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions) [![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases) -[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md) +[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md) [![en](https://img.shields.io/badge/lang-en-red.svg)](README.md) +[![pl](https://img.shields.io/badge/lang-pl-white)](README.pl.md) [![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md) [![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md) -[![be](https://img.shields.io/badge/lang-be-orange)](README.be.md) - ![Hydra Catalogue](./docs/screenshot.png) @@ -119,7 +118,7 @@ yarn ### Instale Python 3.9 -Certifique-se de ter o Python 3.9 instalado em sua máquina. Você pode baixá-lo e instalá-lo em [python.org](https://www.python.org/downloads/release/python-3919/). +Certifique-se de ter o Python 3.9 instalado em sua máquina. Você pode baixá-lo e instalá-lo em [python.org](https://www.python.org/downloads/release/python-3913/). ### Instale Python Dependencies diff --git a/README.ru.md b/README.ru.md index 03ecf379..704a8c90 100644 --- a/README.ru.md +++ b/README.ru.md @@ -13,11 +13,11 @@ [![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions) [![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases) -[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md) -[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md) -[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md) -[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md) [![be](https://img.shields.io/badge/lang-be-orange)](README.be.md) +[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md) +[![pl](https://img.shields.io/badge/lang-pl-white)](README.pl.md) +[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md) +[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md) ![Hydra Catalogue](./docs/screenshot.png) @@ -119,7 +119,7 @@ yarn ### Установка Python 3.9 -Убедитесь, что у вас установлен Python 3.9 на вашем компьютере. Вы можете загрузить и установить его с [python.org](https://www.python.org/downloads/release/python-3919/). +Убедитесь, что у вас установлен Python 3.9 на вашем компьютере. Вы можете загрузить и установить его с [python.org](https://www.python.org/downloads/release/python-3913/). ### Установка зависимостей Python diff --git a/README.uk-UA.md b/README.uk-UA.md index 99b5ca3c..c8451bc2 100644 --- a/README.uk-UA.md +++ b/README.uk-UA.md @@ -13,11 +13,11 @@ [![build](https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml)](https://github.com/hydralauncher/hydra/actions) [![release](https://img.shields.io/github/package-json/v/hydralauncher/hydra)](https://github.com/hydralauncher/hydra/releases) -[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md) -[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md) -[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md) -[![uk-UA](https://img.shields.io/badge/lang-uk--UA-blue)](README.uk-UA.md) [![be](https://img.shields.io/badge/lang-be-orange)](README.be.md) +[![en](https://img.shields.io/badge/lang-en-red.svg)](README.md) +[![pl](https://img.shields.io/badge/lang-pl-white)](README.pl.md) +[![pt-BR](https://img.shields.io/badge/lang-pt--BR-green.svg)](README.pt-BR.md) +[![ru](https://img.shields.io/badge/lang-ru-yellow.svg)](README.ru.md) ![Hydra Catalogue](./docs/screenshot.png) @@ -123,7 +123,7 @@ yarn ### Встановіть Python 3.9 -Переконайтеся, що на вашому комп'ютері встановлено Python 3.9. Ви можете завантажити та встановити його з [python.org](https://www.python.org/downloads/release/python-3919/). +Переконайтеся, що на вашому комп'ютері встановлено Python 3.9. Ви можете завантажити та встановити його з [python.org](https://www.python.org/downloads/release/python-3913/). ### Встановіть Python залежності diff --git a/package.json b/package.json index 97944d50..3c787f4d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { - "name": "hydra", - "version": "1.2.2", + "name": "hydralauncher", + "version": "1.2.3", "description": "Hydra", "main": "./out/main/index.js", "author": "Los Broxas", diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index ac695bca..ee9fb16b 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -176,5 +176,11 @@ }, "modal": { "close": "Close button" + }, + "splash": { + "downloading_version": "Downloading version {{version}}", + "searching_updates": "Searching for updates", + "update_found": "Update {{version}} found", + "restarting_and_applying": "Restarting and applying update" } } diff --git a/src/locales/pt/translation.json b/src/locales/pt/translation.json index bc3190db..d5f92a9f 100644 --- a/src/locales/pt/translation.json +++ b/src/locales/pt/translation.json @@ -176,5 +176,11 @@ }, "modal": { "close": "Botão de fechar" + }, + "splash": { + "downloading_version": "Baixando versão {{version}}", + "searching_updates": "Buscando atualizações", + "update_found": "Versão {{version}} encontrada", + "restarting_and_applying": "Reiniciando e aplicando atualização" } } diff --git a/src/main/constants.ts b/src/main/constants.ts index 4d43518b..17eea7ca 100644 --- a/src/main/constants.ts +++ b/src/main/constants.ts @@ -22,7 +22,7 @@ export const defaultDownloadsPath = app.getPath("downloads"); export const databasePath = path.join( app.getPath("appData"), - app.getName(), + "hydra", "hydra.db" ); diff --git a/src/main/events/autoupdater/check-for-updates.ts b/src/main/events/autoupdater/check-for-updates.ts new file mode 100644 index 00000000..aa63575f --- /dev/null +++ b/src/main/events/autoupdater/check-for-updates.ts @@ -0,0 +1,48 @@ +import { AppUpdaterEvents } from "@types"; +import { registerEvent } from "../register-event"; +import updater, { ProgressInfo, UpdateInfo } from "electron-updater"; +import { WindowManager } from "@main/services"; +import { app } from "electron"; + +const { autoUpdater } = updater; + +const sendEvent = (event: AppUpdaterEvents) => { + WindowManager.splashWindow?.webContents.send("autoUpdaterEvent", event); +}; + +const mockValuesForDebug = async () => { + sendEvent({ type: "update-downloaded" }); +}; + +const checkForUpdates = async (_event: Electron.IpcMainInvokeEvent) => { + autoUpdater + .addListener("error", () => { + sendEvent({ type: "error" }); + }) + .addListener("checking-for-update", () => { + sendEvent({ type: "checking-for-updates" }); + }) + .addListener("update-not-available", () => { + sendEvent({ type: "update-not-available" }); + }) + .addListener("update-available", (info: UpdateInfo) => { + sendEvent({ type: "update-available", info }); + }) + .addListener("update-downloaded", () => { + sendEvent({ type: "update-downloaded" }); + }) + .addListener("download-progress", (info: ProgressInfo) => { + sendEvent({ type: "download-progress", info }); + }) + .addListener("update-cancelled", () => { + sendEvent({ type: "update-cancelled" }); + }); + + if (app.isPackaged) { + autoUpdater.checkForUpdates(); + } else { + await mockValuesForDebug(); + } +}; + +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..6a8965f9 --- /dev/null +++ b/src/main/events/autoupdater/continue-to-main-window.ts @@ -0,0 +1,12 @@ +import { WindowManager } from "@main/services"; +import { registerEvent } from "../register-event"; +import updater from "electron-updater"; + +const { autoUpdater } = updater; + +const continueToMainWindow = async (_event: Electron.IpcMainInvokeEvent) => { + autoUpdater.removeAllListeners(); + WindowManager.prepareMainWindowAndCloseSplash(); +}; + +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..be301c18 --- /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(true, true); + } else { + autoUpdater.removeAllListeners(); + WindowManager.prepareMainWindowAndCloseSplash(); + } +}; + +registerEvent("restartAndInstallUpdate", restartAndInstallUpdate); diff --git a/src/main/events/index.ts b/src/main/events/index.ts index 5d721c62..debca0e4 100644 --- a/src/main/events/index.ts +++ b/src/main/events/index.ts @@ -27,6 +27,9 @@ import "./torrenting/start-game-download"; 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 dabdeb4e..22c13388 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -3,11 +3,10 @@ import updater from "electron-updater"; import i18n from "i18next"; import path from "node:path"; import { electronApp, optimizer } from "@electron-toolkit/utils"; -import { resolveDatabaseUpdates, WindowManager } from "@main/services"; +import { logger, resolveDatabaseUpdates, WindowManager } from "@main/services"; import { dataSource } from "@main/data-source"; import * as resources from "@locales"; import { userPreferencesRepository } from "@main/repository"; - const { autoUpdater } = updater; autoUpdater.setFeedURL({ @@ -16,6 +15,8 @@ autoUpdater.setFeedURL({ repo: "hydra", }); +autoUpdater.logger = logger; + const gotTheLock = app.requestSingleInstanceLock(); if (!gotTheLock) app.quit(); @@ -63,12 +64,8 @@ app.whenReady().then(() => { where: { id: 1 }, }); - WindowManager.createMainWindow(); + WindowManager.createSplashScreen(); WindowManager.createSystemTray(userPreferences?.language || "en"); - - WindowManager.mainWindow?.on("ready-to-show", () => { - autoUpdater.checkForUpdatesAndNotify(); - }); }); }); diff --git a/src/main/services/repack-tracker/online-fix.ts b/src/main/services/repack-tracker/online-fix.ts index 38864a8b..265f6b70 100644 --- a/src/main/services/repack-tracker/online-fix.ts +++ b/src/main/services/repack-tracker/online-fix.ts @@ -148,9 +148,10 @@ export const getNewRepacksFromOnlineFix = async ( ); if (!newRepacks.length) return; - if (page === totalPages) return; await savePage(newRepacks); + if (page === totalPages) return; + return getNewRepacksFromOnlineFix(existingRepacks, page + 1, cookieJar); }; diff --git a/src/main/services/repack-tracker/xatab.ts b/src/main/services/repack-tracker/xatab.ts index 34ebfa4c..e765bebf 100644 --- a/src/main/services/repack-tracker/xatab.ts +++ b/src/main/services/repack-tracker/xatab.ts @@ -111,9 +111,10 @@ export const getNewRepacksFromXatab = async ( ); if (!newRepacks.length) return; - if (page === totalPages) return; await savePage(newRepacks); + if (page === totalPages) return; + return getNewRepacksFromXatab(existingRepacks, page + 1); }; diff --git a/src/main/services/window-manager.ts b/src/main/services/window-manager.ts index 973a0c64..e435ddb2 100644 --- a/src/main/services/window-manager.ts +++ b/src/main/services/window-manager.ts @@ -17,6 +17,8 @@ import { IsNull, Not } from "typeorm"; export class WindowManager { public static mainWindow: Electron.BrowserWindow | null = null; + public static splashWindow: Electron.BrowserWindow | null = null; + public static isReadyToShowMainWindow = false; private static loadURL(hash = "") { // HMR for renderer base on electron-vite cli. @@ -35,13 +37,51 @@ export class WindowManager { } } + private static loadSplashURL() { + // HMR for renderer base on electron-vite cli. + // Load the remote URL for development or the local html file for production. + if (is.dev && process.env["ELECTRON_RENDERER_URL"]) { + this.splashWindow?.loadURL( + `${process.env["ELECTRON_RENDERER_URL"]}#/splash` + ); + } else { + this.splashWindow?.loadFile( + path.join(__dirname, "../renderer/index.html"), + { + hash: "splash", + } + ); + } + } + + public static createSplashScreen() { + if (this.splashWindow) return; + + this.splashWindow = new BrowserWindow({ + width: 380, + height: 380, + frame: false, + resizable: false, + backgroundColor: "#1c1c1c", + webPreferences: { + preload: path.join(__dirname, "../preload/index.mjs"), + sandbox: false, + }, + }); + + this.loadSplashURL(); + this.splashWindow.removeMenu(); + } + public static createMainWindow() { - // Create the browser window. + if (this.mainWindow || !this.isReadyToShowMainWindow) return; + this.mainWindow = new BrowserWindow({ width: 1200, height: 720, minWidth: 1024, minHeight: 540, + backgroundColor: "#1c1c1c", titleBarStyle: "hidden", ...(process.platform === "linux" ? { icon } : {}), trafficLightPosition: { x: 16, y: 16 }, @@ -75,6 +115,12 @@ export class WindowManager { }); } + public static prepareMainWindowAndCloseSplash() { + this.isReadyToShowMainWindow = true; + this.splashWindow?.close(); + this.createMainWindow(); + } + public static redirect(hash: string) { if (!this.mainWindow) this.createMainWindow(); this.loadURL(hash); diff --git a/src/preload/index.ts b/src/preload/index.ts index 0e397a4a..c808d8fc 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -7,6 +7,7 @@ import type { GameShop, DownloadProgress, UserPreferences, + AppUpdaterEvents, } from "@types"; contextBridge.exposeInMainWorld("electron", { @@ -112,4 +113,21 @@ contextBridge.exposeInMainWorld("electron", { showOpenDialog: (options: Electron.OpenDialogOptions) => ipcRenderer.invoke("showOpenDialog", options), platform: process.platform, + + /* Splash */ + 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/app.tsx b/src/renderer/src/app.tsx index adb2a613..3a10b98c 100644 --- a/src/renderer/src/app.tsx +++ b/src/renderer/src/app.tsx @@ -12,7 +12,7 @@ import { import * as styles from "./app.css"; import { themeClass } from "./theme.css"; -import { useLocation, useNavigate } from "react-router-dom"; +import { Outlet, useLocation, useNavigate } from "react-router-dom"; import { setSearch, clearSearch, @@ -26,7 +26,7 @@ export interface AppProps { children: React.ReactNode; } -export function App({ children }: AppProps) { +export function App() { const contentRef = useRef(null); const { updateLibrary } = useLibrary(); @@ -127,7 +127,7 @@ export function App({ children }: AppProps) { />
- {children} +
diff --git a/src/renderer/src/assets/icon.png b/src/renderer/src/assets/icon.png new file mode 100644 index 00000000..9254a8fb Binary files /dev/null and b/src/renderer/src/assets/icon.png differ diff --git a/src/renderer/src/components/toast/toast.css.ts b/src/renderer/src/components/toast/toast.css.ts index 9035c8e8..bc8d5377 100644 --- a/src/renderer/src/components/toast/toast.css.ts +++ b/src/renderer/src/components/toast/toast.css.ts @@ -3,7 +3,7 @@ import { keyframes, style } from "@vanilla-extract/css"; import { SPACING_UNIT, vars } from "../../theme.css"; import { recipe } from "@vanilla-extract/recipes"; -const TOAST_HEIGHT = 60; +const TOAST_HEIGHT = 55; export const slideIn = keyframes({ "0%": { transform: `translateY(${TOAST_HEIGHT + SPACING_UNIT * 2}px)` }, diff --git a/src/renderer/src/components/toast/toast.tsx b/src/renderer/src/components/toast/toast.tsx index 8ae9f934..1228653e 100644 --- a/src/renderer/src/components/toast/toast.tsx +++ b/src/renderer/src/components/toast/toast.tsx @@ -85,6 +85,7 @@ export function Toast({ visible, message, type, onClose }: ToastProps) { type="button" className={styles.closeButton} onClick={startAnimateClosing} + aria-label="Close toast" > diff --git a/src/renderer/src/declaration.d.ts b/src/renderer/src/declaration.d.ts index 508a56b3..8a4e1c93 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, @@ -90,6 +91,14 @@ declare global { options: Electron.OpenDialogOptions ) => Promise; platform: NodeJS.Platform; + + /* Splash */ + 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 f44653cb..3608af8d 100644 --- a/src/renderer/src/main.tsx +++ b/src/renderer/src/main.tsx @@ -27,6 +27,7 @@ import { import { store } from "./store"; import * as resources from "@locales"; +import Splash from "./pages/splash/splash"; i18n .use(LanguageDetector) @@ -46,16 +47,17 @@ ReactDOM.createRoot(document.getElementById("root")!).render( - - + + + }> - - + + diff --git a/src/renderer/src/pages/game-details/gallery-slider.tsx b/src/renderer/src/pages/game-details/gallery-slider.tsx index 486f56f8..75502df8 100644 --- a/src/renderer/src/pages/game-details/gallery-slider.tsx +++ b/src/renderer/src/pages/game-details/gallery-slider.tsx @@ -57,9 +57,7 @@ export function GallerySlider() { if (hasMovies && mediaContainerRef.current) { mediaContainerRef.current.childNodes.forEach((node, index) => { if (node instanceof HTMLVideoElement) { - if (index == mediaIndex) { - node.play(); - } else { + if (index !== mediaIndex) { node.pause(); } } diff --git a/src/renderer/src/pages/game-details/modals/select-folder-modal.css.tsx b/src/renderer/src/pages/game-details/modals/select-folder-modal.css.tsx index fe369301..e63603c2 100644 --- a/src/renderer/src/pages/game-details/modals/select-folder-modal.css.tsx +++ b/src/renderer/src/pages/game-details/modals/select-folder-modal.css.tsx @@ -17,3 +17,12 @@ export const hintText = style({ fontSize: "12px", color: vars.color.bodyText, }); + +export const downloaders = style({ + display: "flex", + gap: `${SPACING_UNIT}px`, +}); + +export const downloaderOption = style({ + flex: "1", +}); diff --git a/src/renderer/src/pages/game-details/modals/select-folder-modal.tsx b/src/renderer/src/pages/game-details/modals/select-folder-modal.tsx index 9c1d18e1..4b43c74d 100644 --- a/src/renderer/src/pages/game-details/modals/select-folder-modal.tsx +++ b/src/renderer/src/pages/game-details/modals/select-folder-modal.tsx @@ -80,8 +80,24 @@ export function SelectFolderModal({ onClose={onClose} >
+
+ + +
+ + +
+
+
- +
+

+