mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-02 16:23:48 +03:00
chore: pulling from remote
This commit is contained in:
commit
9e648fed28
34
README.md
34
README.md
@ -240,10 +240,10 @@ yarn build:linux
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/jps14">
|
||||
<img src="https://avatars.githubusercontent.com/u/168477146?v=4" width="100;" alt="jps14"/>
|
||||
<a href="https://github.com/Hachi-R">
|
||||
<img src="https://avatars.githubusercontent.com/u/58823742?v=4" width="100;" alt="Hachi-R"/>
|
||||
<br />
|
||||
<sub><b>José Luís</b></sub>
|
||||
<sub><b>Hachi</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
@ -282,13 +282,6 @@ yarn build:linux
|
||||
<sub><b>Netflixy</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Hachi-R">
|
||||
<img src="https://avatars.githubusercontent.com/u/58823742?v=4" width="100;" alt="Hachi-R"/>
|
||||
<br />
|
||||
<sub><b>Hachi</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/FerNikoMF">
|
||||
<img src="https://avatars.githubusercontent.com/u/76095334?v=4" width="100;" alt="FerNikoMF"/>
|
||||
@ -296,19 +289,26 @@ yarn build:linux
|
||||
<sub><b>Firdavs</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/userMacieG">
|
||||
<img src="https://avatars.githubusercontent.com/u/24211405?v=4" width="100;" alt="userMacieG"/>
|
||||
<br />
|
||||
<sub><b>Maciej Ratyński</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Tunchichi">
|
||||
<img src="https://avatars.githubusercontent.com/u/118926729?v=4" width="100;" alt="Tunchichi"/>
|
||||
<br />
|
||||
<sub><b>Ruslan</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Chr1s0Blood">
|
||||
<img src="https://avatars.githubusercontent.com/u/166660500?v=4" width="100;" alt="Chr1s0Blood"/>
|
||||
<br />
|
||||
<sub><b>Cristian S.</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/userMacieG">
|
||||
<img src="https://avatars.githubusercontent.com/u/24211405?v=4" width="100;" alt="userMacieG"/>
|
||||
<br />
|
||||
<sub><b>Maciej Ratyński</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
</table>
|
||||
<!-- readme: contributors -end -->
|
||||
|
314
README.ru.md
Normal file
314
README.ru.md
Normal file
@ -0,0 +1,314 @@
|
||||
<br>
|
||||
|
||||
<div align="center">
|
||||
<a href="https://hydralauncher.site">
|
||||
<img src="./resources/icon.png" width="144"/>
|
||||
</a>
|
||||
<h1 align="center">Hydra Launcher</h1>
|
||||
<p align="center">
|
||||
<strong>Hydra-это игровой лаунчер со своим собственным встроенным клиентом BitTorrent и самоуправляемым скребком репаков.</strong>
|
||||
</p>
|
||||
<p>
|
||||
<a href="https://discord.gg/hydralauncher">
|
||||
<img src ="https://img.shields.io/discord/1220692017311645737?style=flat&logo=discord&label=Hydra&labelColor=%231c1c1c"/>
|
||||
</a>
|
||||
<a href="https://github.com/hydralauncher/hydra">
|
||||
<img src="https://img.shields.io/github/actions/workflow/status/hydralauncher/hydra/build.yml" />
|
||||
</a>
|
||||
<a href="https://github.com/hydralauncher/hydra">
|
||||
<img src="https://img.shields.io/github/package-json/v/hydralauncher/hydra" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
![Hydra Catalogue](./docs/screenshot.png)
|
||||
|
||||
</div>
|
||||
|
||||
<br>
|
||||
|
||||
### Язык
|
||||
[![ru](https://img.shields.io/badge/lang-ru-red)](https://github.com/hydralauncher/hydra/blob/main/README.ru.md)
|
||||
|
||||
## Содержание
|
||||
|
||||
- [О нас](#о-нас)
|
||||
- [Функции](#функции)
|
||||
- [Установка](#установка)
|
||||
- [Сотрудничество](#сотрудничество)
|
||||
- [Присоединяйтесь к нашему Discord](#присоединяйтесь-к-нашему-discord)
|
||||
- [Ответвлить и клонировать свой репозиторий](#ответвлить-и-клонировать-свой-репозиторий)
|
||||
- [Способы внести свой вклад](#способы-внести-свой-вклад)
|
||||
- [Структура проекта](#структура-проекта)
|
||||
- [Создать из источника](#создать-из-источника)
|
||||
- [Установите Node.js](#установите-nodejs)
|
||||
- [Установите Yarn](#установите-yarn)
|
||||
- [Установите зависимости Node](#установите-зависимости-node)
|
||||
- [Установите Python 3.9](#установите-python-39)
|
||||
- [Установите зависимости Python](#установите-зависимости-python)
|
||||
- [Переменные среды](#переменные-среды)
|
||||
- [Запуск](#запуск)
|
||||
- [Создание](#создание)
|
||||
- [Создайте клиент BitTorrent](#создайте-клиент-bittorrent)
|
||||
- [Создайте приложение Electron](#создайте-приложение-electron)
|
||||
- [Участники](#участники)
|
||||
|
||||
## О нас
|
||||
|
||||
**Hydra**-это **Игровой Лаунчер** со своим собственным встроенным **BitTorrent Client** и **самоуправляемым скребком репаков**.
|
||||
<br>
|
||||
Лаунчер написан на TypeScript (Electron) и Python, который обрабатывает систему торрента с использованием LibTorrent.
|
||||
|
||||
## Функции
|
||||
|
||||
- Самоуправляемый скребок репаков среди всех самых надежных веб-сайтов на [Megathread]("https://www.reddit.com/r/Piracy/wiki/megathread/")
|
||||
- Собственный встроенный клиент BitTorrent
|
||||
- Как долго пробиться (HLTB) интеграция на странице игры
|
||||
- Загрузка настройки пути
|
||||
- Уведомления об обновлении списка репаков
|
||||
- Поддержка Windows и Linux
|
||||
- Постоянно обновляется
|
||||
- И более ...
|
||||
|
||||
## Установка
|
||||
|
||||
Следуйте приведенным ниже шагам, чтобы установить:
|
||||
|
||||
1. Загрузите последнюю версию Hydra из [Выпуски](https://github.com/hydralauncher/hydra/releases/latest).
|
||||
- Загрузите только .exe, если вы хотите установить Hydra в Windows.
|
||||
- Скачать .deb или .rpm или .zip, если вы хотите установить Hydra на Linux.(Зависит от вашего дистрибутива Linux)
|
||||
2. Запустите загруженный файл.
|
||||
3. Наслаждаться Hydra!
|
||||
|
||||
## Сотрудничество
|
||||
|
||||
### Присоединяйтесь к нашему Discord
|
||||
|
||||
Мы концентрируем наши обсуждения на нашем [Discord](https://discord.gg/hydralauncher) сервере.
|
||||
|
||||
1. Присоединяйтесь к нашему серверу
|
||||
2. Перейдите на роли канала и возьмите роль сотрудничества
|
||||
3. Зайдите на канал Dev, поговорите с нами и поделитесь своими идеями.
|
||||
|
||||
### Ответвлить и клонировать свой репозиторий
|
||||
|
||||
1. Ответвление репозитория [(Нажмите здесь, чтобы сейчас ответвлить)](https://github.com/hydralauncher/hydra/fork)
|
||||
2. Клонировать свой ответвленный код `git clone https://github.com/your_username/hydra`
|
||||
3. Создать новую ветку
|
||||
4. Подтолкнуть свои коммиты
|
||||
5. Отправить новый запрос на привлечение
|
||||
|
||||
### Способы внести свой вклад
|
||||
|
||||
- Перевод: Мы хотим, чтобы Hydra была доступна как можно большему количеству людей. Не стесняйтесь переводить на новые языки или обновить и улучшить те, которые уже доступны на Hydra.
|
||||
- Код: Hydra построена на TypeScript, Electron и немного Python.Если вы хотите внести свой вклад, присоединяйтесь к нашему серверу Discord!
|
||||
|
||||
### Структура проекта
|
||||
|
||||
- torrent-client: Мы используем LibTorrent, библиотеку Python, чтобы управлять загрузками торрента
|
||||
- src/renderer: пользовательский интерфейс приложения
|
||||
- src/main: Вся логика отдыхает здесь.
|
||||
|
||||
## Создать из источника
|
||||
|
||||
### Установите Node.js
|
||||
|
||||
Убедитесь, что у вас установлен Node.js на вашем компьютере.Если нет, загрузите и установите из [nodejs.org](https://nodejs.org/).
|
||||
|
||||
### Установите Yarn
|
||||
|
||||
Yarn является менеджером пакетов для node.js. Если вы еще не установили Yarn, вы можете сделать это, следуя инструкциям на [yarnpkg.com](https://classic.yarnpkg.com/lang/en/docs/install/).
|
||||
|
||||
### Установите зависимости Node
|
||||
|
||||
Перейдите к каталогу проекта и установите Node зависимости с использованием Yarn:
|
||||
|
||||
```bash
|
||||
cd hydra
|
||||
yarn
|
||||
```
|
||||
|
||||
### Установите Python 3.9
|
||||
|
||||
Убедитесь, что на вашем компьютере установлен Python 3.9. Вы можете скачать и установить его из [python.org](https://www.python.org/downloads/release/python-3919/).
|
||||
|
||||
### Установите зависимости Python
|
||||
|
||||
Установите необходимые зависимости Python, используя pip:
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
## Переменные среды
|
||||
|
||||
Вам понадобится ключ API SteamGridDB, чтобы принести значки игры при установке.
|
||||
Если вы хотите получить онлайн -фикс в качестве репака, вам нужно добавить свои учетные данные в .env
|
||||
|
||||
Как только он у вас есть, вы можете скопировать или переименовать `.env.example` файл в `.env`и заполнить это`STEAMGRIDDB_API_KEY`, `ONLINEFIX_USERNAME`, `ONLINEFIX_PASSWORD`.
|
||||
|
||||
## Запуск
|
||||
|
||||
После того, как у вас все настроено, вы можете запустить следующую команду, чтобы запустить приложение Electron и клиент BitTorrent:
|
||||
|
||||
```bash
|
||||
yarn dev
|
||||
```
|
||||
|
||||
## Создание
|
||||
|
||||
### Создайте клиент BitTorrent
|
||||
|
||||
Создайте клиент BitTorrent, используя эту команду:
|
||||
|
||||
```bash
|
||||
python torrent-client/setup.py build
|
||||
```
|
||||
|
||||
### Создайте приложение Electron
|
||||
|
||||
Создайте приложение Electron с помощью этой команды:
|
||||
|
||||
В Windows:
|
||||
|
||||
```bash
|
||||
yarn build:win
|
||||
```
|
||||
|
||||
В Linux:
|
||||
|
||||
```bash
|
||||
yarn build:linux
|
||||
```
|
||||
|
||||
## Участники
|
||||
|
||||
<!-- readme: contributors -start -->
|
||||
<table>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/hydralauncher">
|
||||
<img src="https://avatars.githubusercontent.com/u/164102380?v=4" width="100;" alt="hydralauncher"/>
|
||||
<br />
|
||||
<sub><b>Hydra</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/zamitto">
|
||||
<img src="https://avatars.githubusercontent.com/u/167933696?v=4" width="100;" alt="zamitto"/>
|
||||
<br />
|
||||
<sub><b>Null</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/fzanutto">
|
||||
<img src="https://avatars.githubusercontent.com/u/15229294?v=4" width="100;" alt="fzanutto"/>
|
||||
<br />
|
||||
<sub><b>Null</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/JackEnx">
|
||||
<img src="https://avatars.githubusercontent.com/u/167036558?v=4" width="100;" alt="JackEnx"/>
|
||||
<br />
|
||||
<sub><b>Null</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Magrid0">
|
||||
<img src="https://avatars.githubusercontent.com/u/73496008?v=4" width="100;" alt="Magrid0"/>
|
||||
<br />
|
||||
<sub><b>Magrid</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/fhilipecrash">
|
||||
<img src="https://avatars.githubusercontent.com/u/36455575?v=4" width="100;" alt="fhilipecrash"/>
|
||||
<br />
|
||||
<sub><b>Fhilipe Coelho</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/jps14">
|
||||
<img src="https://avatars.githubusercontent.com/u/168477146?v=4" width="100;" alt="jps14"/>
|
||||
<br />
|
||||
<sub><b>José Luís</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/shadowtosser">
|
||||
<img src="https://avatars.githubusercontent.com/u/168544958?v=4" width="100;" alt="shadowtosser"/>
|
||||
<br />
|
||||
<sub><b>Null</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/pmenta">
|
||||
<img src="https://avatars.githubusercontent.com/u/71457671?v=4" width="100;" alt="pmenta"/>
|
||||
<br />
|
||||
<sub><b>João Martins</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/ferivoq">
|
||||
<img src="https://avatars.githubusercontent.com/u/36544651?v=4" width="100;" alt="ferivoq"/>
|
||||
<br />
|
||||
<sub><b>FeriVOQ</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/xbozo">
|
||||
<img src="https://avatars.githubusercontent.com/u/119091492?v=4" width="100;" alt="xbozo"/>
|
||||
<br />
|
||||
<sub><b>Guilherme Viana</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/eltociear">
|
||||
<img src="https://avatars.githubusercontent.com/u/22633385?v=4" width="100;" alt="eltociear"/>
|
||||
<br />
|
||||
<sub><b>Ikko Eltociear Ashimine</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Netflixyapp">
|
||||
<img src="https://avatars.githubusercontent.com/u/91623880?v=4" width="100;" alt="Netflixyapp"/>
|
||||
<br />
|
||||
<sub><b>Netflixy</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Hachi-R">
|
||||
<img src="https://avatars.githubusercontent.com/u/58823742?v=4" width="100;" alt="Hachi-R"/>
|
||||
<br />
|
||||
<sub><b>Hachi</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/FerNikoMF">
|
||||
<img src="https://avatars.githubusercontent.com/u/76095334?v=4" width="100;" alt="FerNikoMF"/>
|
||||
<br />
|
||||
<sub><b>Firdavs</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/userMacieG">
|
||||
<img src="https://avatars.githubusercontent.com/u/24211405?v=4" width="100;" alt="userMacieG"/>
|
||||
<br />
|
||||
<sub><b>Maciej Ratyński</b></sub>
|
||||
</a>
|
||||
</td>
|
||||
<td align="center">
|
||||
<a href="https://github.com/Tunchichi">
|
||||
<img src="https://avatars.githubusercontent.com/u/118926729?v=4" width="100;" alt="Tunchichi"/>
|
||||
<br />
|
||||
<sub><b>Ruslan</b></sub>
|
||||
</a>
|
||||
</td></tr>
|
||||
</table>
|
||||
<!-- readme: contributors -end -->
|
||||
|
||||
## License
|
||||
|
||||
Hydra лицензирована в соответствии с лицензией [MIT License](LICENSE).
|
12433
package-lock.json
generated
Normal file
12433
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
@ -37,6 +37,7 @@
|
||||
"@sentry/vite-plugin": "^2.16.1",
|
||||
"@vanilla-extract/css": "^1.14.2",
|
||||
"@vanilla-extract/recipes": "^0.5.2",
|
||||
"auto-launch": "^5.0.6",
|
||||
"axios": "^1.6.8",
|
||||
"better-sqlite3": "^9.5.0",
|
||||
"check-disk-space": "^3.4.0",
|
||||
@ -68,6 +69,7 @@
|
||||
"@electron-toolkit/eslint-config-ts": "^1.0.1",
|
||||
"@electron-toolkit/tsconfig": "^1.0.1",
|
||||
"@swc/core": "^1.4.16",
|
||||
"@types/auto-launch": "^5.0.5",
|
||||
"@types/jsdom": "^21.1.6",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^20.12.7",
|
||||
|
@ -139,7 +139,8 @@
|
||||
"telemetry_description": "Enable anonymous usage statistics",
|
||||
"real_debrid_api_token_description": "(Optional) Real Debrid API token",
|
||||
"behavior": "Behavior",
|
||||
"quit_app_instead_hiding": "Close app instead of minimizing to tray"
|
||||
"quit_app_instead_hiding": "Close app instead of minimizing to tray",
|
||||
"launch_with_system": "Launch app on system start-up"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Download complete",
|
||||
|
@ -135,7 +135,8 @@
|
||||
"telemetry_description": "Habilitar estatísticas de uso anônimas",
|
||||
"real_debrid_api_token_description": "(Opcional) Real Debrid API token",
|
||||
"behavior": "Comportamento",
|
||||
"quit_app_instead_hiding": "Fechar o aplicativo em vez de minimizá-lo"
|
||||
"quit_app_instead_hiding": "Fechar o aplicativo em vez de minimizá-lo",
|
||||
"launch_with_system": "Iniciar aplicativo na inicialização do sistema"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Download concluído",
|
||||
|
@ -139,6 +139,7 @@
|
||||
"telemetry_description": "Включить анонимную статистику использования",
|
||||
"behavior": "Поведение",
|
||||
"quit_app_instead_hiding": "Закрывать приложение вместо того, чтобы сворачивать его в трей"
|
||||
"launch_with_system": "Запуск приложения при запуске системы"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Загрузка завершена",
|
||||
|
@ -32,6 +32,9 @@ export class UserPreferences {
|
||||
@Column("boolean", { default: false })
|
||||
preferQuitInsteadOfHiding: boolean;
|
||||
|
||||
@Column("boolean", { default: false })
|
||||
runAtStartup: boolean;
|
||||
|
||||
@CreateDateColumn()
|
||||
createdAt: Date;
|
||||
|
||||
|
@ -26,6 +26,7 @@ import "./torrenting/resume-game-download";
|
||||
import "./torrenting/start-game-download";
|
||||
import "./user-preferences/get-user-preferences";
|
||||
import "./user-preferences/update-user-preferences";
|
||||
import "./user-preferences/auto-launch";
|
||||
|
||||
ipcMain.handle("ping", () => "pong");
|
||||
ipcMain.handle("getVersion", () => app.getVersion());
|
||||
|
21
src/main/events/user-preferences/auto-launch.ts
Normal file
21
src/main/events/user-preferences/auto-launch.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { registerEvent } from "../register-event";
|
||||
import AutoLaunch from "auto-launch";
|
||||
import { app } from "electron";
|
||||
|
||||
const autoLaunch = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
enabled: boolean
|
||||
) => {
|
||||
const appLauncher = new AutoLaunch({
|
||||
name: app.getName(),
|
||||
});
|
||||
if (enabled) {
|
||||
appLauncher.enable().catch();
|
||||
} else {
|
||||
appLauncher.disable().catch();
|
||||
}
|
||||
};
|
||||
|
||||
registerEvent(autoLaunch, {
|
||||
name: "autoLaunch",
|
||||
});
|
@ -26,7 +26,7 @@ export class WindowManager {
|
||||
}
|
||||
}
|
||||
|
||||
public static async createMainWindow() {
|
||||
public static createMainWindow() {
|
||||
// Create the browser window.
|
||||
this.mainWindow = new BrowserWindow({
|
||||
width: 1200,
|
||||
|
1
src/preload/index.d.ts
vendored
1
src/preload/index.d.ts
vendored
@ -48,6 +48,7 @@ contextBridge.exposeInMainWorld("electron", {
|
||||
getUserPreferences: () => ipcRenderer.invoke("getUserPreferences"),
|
||||
updateUserPreferences: (preferences: UserPreferences) =>
|
||||
ipcRenderer.invoke("updateUserPreferences", preferences),
|
||||
autoLaunch: (enabled: boolean) => ipcRenderer.invoke("autoLaunch", enabled),
|
||||
|
||||
/* Library */
|
||||
addGameToLibrary: (
|
||||
|
@ -57,6 +57,7 @@ contextBridge.exposeInMainWorld("electron", {
|
||||
getUserPreferences: () => ipcRenderer.invoke("getUserPreferences"),
|
||||
updateUserPreferences: (preferences: UserPreferences) =>
|
||||
ipcRenderer.invoke("updateUserPreferences", preferences),
|
||||
autoLaunch: (enabled: boolean) => ipcRenderer.invoke("autoLaunch", enabled),
|
||||
|
||||
/* Library */
|
||||
addGameToLibrary: (
|
||||
|
@ -6,7 +6,7 @@
|
||||
<title>Hydra</title>
|
||||
<meta
|
||||
http-equiv="Content-Security-Policy"
|
||||
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://steamcdn-a.akamaihd.net https://cdn.cloudflare.steamstatic.com https://cdn2.steamgriddb.com https://cdn.akamai.steamstatic.com;"
|
||||
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https://steamcdn-a.akamaihd.net https://cdn.cloudflare.steamstatic.com https://cdn2.steamgriddb.com https://cdn.akamai.steamstatic.com; media-src 'self' data: https://steamcdn-a.akamaihd.net https://cdn.cloudflare.steamstatic.com https://cdn2.steamgriddb.com https://cdn.akamai.steamstatic.com;"
|
||||
/>
|
||||
</head>
|
||||
<body style="background-color: #1c1c1c">
|
||||
|
1
src/renderer/src/declaration.d.ts
vendored
1
src/renderer/src/declaration.d.ts
vendored
@ -74,6 +74,7 @@ declare global {
|
||||
updateUserPreferences: (
|
||||
preferences: Partial<UserPreferences>
|
||||
) => Promise<void>;
|
||||
autoLaunch: (enabled: boolean) => Promise<void>;
|
||||
|
||||
/* Hardware */
|
||||
getDiskFreeSpace: (path: string) => Promise<DiskSpace>;
|
||||
|
132
src/renderer/src/pages/game-details/gallery-slider.tsx
Normal file
132
src/renderer/src/pages/game-details/gallery-slider.tsx
Normal file
@ -0,0 +1,132 @@
|
||||
import { RefObject, useEffect, useRef, useState } from "react";
|
||||
import { ShopDetails, SteamMovies, SteamScreenshot } from "@types";
|
||||
import { ChevronRightIcon, ChevronLeftIcon } from "@primer/octicons-react";
|
||||
import * as styles from "./game-details.css";
|
||||
|
||||
export interface GallerySliderProps {
|
||||
gameDetails: ShopDetails | null;
|
||||
}
|
||||
|
||||
export function GallerySlider({ gameDetails }: GallerySliderProps) {
|
||||
const scrollContainerRef: RefObject<HTMLDivElement> =
|
||||
useRef<HTMLDivElement>(null);
|
||||
const [mediaCount] = useState<number>(() => {
|
||||
if (gameDetails) {
|
||||
if (gameDetails.screenshots && gameDetails.movies) {
|
||||
return gameDetails.screenshots.length + gameDetails.movies.length;
|
||||
} else if (gameDetails.movies) {
|
||||
return gameDetails.movies.length;
|
||||
} else if (gameDetails.screenshots) {
|
||||
return gameDetails.screenshots.length;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
const [mediaIndex, setMediaIndex] = useState<number>(0);
|
||||
const [arrowShow, setArrowShow] = useState(false);
|
||||
|
||||
const scrollHorizontallyToPercentage = () => {
|
||||
if (scrollContainerRef.current) {
|
||||
const container = scrollContainerRef.current;
|
||||
const totalWidth = container.scrollWidth - container.clientWidth;
|
||||
const itemWidth = totalWidth / (mediaCount - 1);
|
||||
const scrollLeft = mediaIndex * itemWidth;
|
||||
container.scrollLeft = scrollLeft;
|
||||
}
|
||||
};
|
||||
|
||||
const showNextImage = () => {
|
||||
setMediaIndex((index: number) => {
|
||||
if (index === mediaCount - 1) return 0;
|
||||
|
||||
return index + 1;
|
||||
});
|
||||
};
|
||||
const showPrevImage = () => {
|
||||
setMediaIndex((index: number) => {
|
||||
if (index === 0) return mediaCount - 1;
|
||||
|
||||
return index - 1;
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
scrollHorizontallyToPercentage();
|
||||
}, [mediaIndex]);
|
||||
return (
|
||||
<>
|
||||
{gameDetails?.screenshots && (
|
||||
<div className={styles.gallerySliderContainer}>
|
||||
<div
|
||||
onMouseEnter={() => setArrowShow(true)}
|
||||
onMouseLeave={() => setArrowShow(false)}
|
||||
className={styles.gallerySliderAnimationContainer}
|
||||
>
|
||||
{gameDetails.movies &&
|
||||
gameDetails.movies.map((video: SteamMovies) => (
|
||||
<video
|
||||
controls
|
||||
className={styles.gallerySliderMedia}
|
||||
poster={video.thumbnail}
|
||||
style={{ translate: `${-100 * mediaIndex}%` }}
|
||||
>
|
||||
<source src={video.webm.max.replace("http", "https")} />
|
||||
</video>
|
||||
))}
|
||||
{gameDetails.screenshots &&
|
||||
gameDetails.screenshots.map((image: SteamScreenshot) => (
|
||||
<img
|
||||
className={styles.gallerySliderMedia}
|
||||
src={image.path_full}
|
||||
style={{ translate: `${-100 * mediaIndex}%` }}
|
||||
/>
|
||||
))}
|
||||
{arrowShow && (
|
||||
<>
|
||||
<button
|
||||
onClick={showPrevImage}
|
||||
className={styles.gallerySliderButton}
|
||||
style={{ left: 0 }}
|
||||
>
|
||||
<ChevronLeftIcon className={styles.gallerySliderIcons} />
|
||||
</button>
|
||||
<button
|
||||
onClick={showNextImage}
|
||||
className={styles.gallerySliderButton}
|
||||
style={{ right: 0 }}
|
||||
>
|
||||
<ChevronRightIcon className={styles.gallerySliderIcons} />
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={styles.gallerySliderPreview} ref={scrollContainerRef}>
|
||||
{gameDetails.movies &&
|
||||
gameDetails.movies.map((video: SteamMovies, i: number) => (
|
||||
<img
|
||||
onClick={() => setMediaIndex(i)}
|
||||
src={video.thumbnail}
|
||||
className={`${styles.gallerySliderMediaPreview} ${mediaIndex === i ? styles.gallerySliderMediaPreviewActive : ""}`}
|
||||
/>
|
||||
))}
|
||||
{gameDetails.screenshots &&
|
||||
gameDetails.screenshots.map(
|
||||
(image: SteamScreenshot, i: number) => (
|
||||
<img
|
||||
onClick={() =>
|
||||
setMediaIndex(
|
||||
i + (gameDetails.movies ? gameDetails.movies.length : 0)
|
||||
)
|
||||
}
|
||||
className={`${styles.gallerySliderMediaPreview} ${mediaIndex === i + (gameDetails.movies ? gameDetails.movies.length : 0) ? styles.gallerySliderMediaPreviewActive : ""}`}
|
||||
src={image.path_full}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
@ -79,6 +79,94 @@ export const descriptionContent = style({
|
||||
height: "100%",
|
||||
});
|
||||
|
||||
export const gallerySliderContainer = style({
|
||||
padding: `${SPACING_UNIT * 3}px ${SPACING_UNIT * 2}px`,
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
});
|
||||
|
||||
export const gallerySliderMedia = style({
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
display: "block",
|
||||
flexShrink: 0,
|
||||
flexGrow: 0,
|
||||
transition: "translate 300ms ease-in-out",
|
||||
});
|
||||
|
||||
export const gallerySliderAnimationContainer = style({
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
position: "relative",
|
||||
overflow: "hidden",
|
||||
"@media": {
|
||||
"(min-width: 1280px)": {
|
||||
width: "60%",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const gallerySliderPreview = style({
|
||||
width: "100%",
|
||||
paddingTop: "0.5rem",
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
position: "relative",
|
||||
overflowX: "auto",
|
||||
overflowY: "hidden",
|
||||
"@media": {
|
||||
"(min-width: 1280px)": {
|
||||
width: "60%",
|
||||
},
|
||||
},
|
||||
"::-webkit-scrollbar-thumb": {
|
||||
width: "20%"
|
||||
}
|
||||
});
|
||||
|
||||
export const gallerySliderMediaPreview = style({
|
||||
cursor: "pointer",
|
||||
width: "20%",
|
||||
height: "20%",
|
||||
display: "block",
|
||||
flexShrink: 0,
|
||||
flexGrow: 0,
|
||||
opacity: 0.3,
|
||||
paddingRight: "5px",
|
||||
transition: "translate 300ms ease-in-out",
|
||||
":hover": {
|
||||
opacity: 1,
|
||||
},
|
||||
});
|
||||
|
||||
export const gallerySliderMediaPreviewActive = style({
|
||||
opacity: 1,
|
||||
});
|
||||
|
||||
export const gallerySliderButton = style({
|
||||
all: "unset",
|
||||
display: "block",
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
padding: "1rem",
|
||||
cursor: "pointer",
|
||||
transition: "background-color 100ms ease-in-out",
|
||||
":hover": {
|
||||
backgroundColor: "rgb(0,0,0, 0.2)",
|
||||
},
|
||||
});
|
||||
|
||||
export const gallerySliderIcons = style({
|
||||
stroke: "white",
|
||||
fill: "black",
|
||||
width: "2rem",
|
||||
height: "2rem",
|
||||
});
|
||||
|
||||
export const contentSidebar = style({
|
||||
borderLeft: `solid 1px ${vars.color.border};`,
|
||||
width: "100%",
|
||||
|
@ -36,6 +36,7 @@ import {
|
||||
DONT_SHOW_ONLINE_FIX_INSTRUCTIONS_KEY,
|
||||
OnlineFixInstallationGuide,
|
||||
} from "./installation-guides";
|
||||
import { GallerySlider } from "./gallery-slider";
|
||||
|
||||
export function GameDetails() {
|
||||
const { objectID, shop } = useParams();
|
||||
@ -89,7 +90,6 @@ export function GameDetails() {
|
||||
useEffect(() => {
|
||||
getGame();
|
||||
}, [getGame, gameDownloading?.id]);
|
||||
|
||||
useEffect(() => {
|
||||
setGame(null);
|
||||
setIsLoading(true);
|
||||
@ -249,6 +249,8 @@ export function GameDetails() {
|
||||
<div className={styles.descriptionContent}>
|
||||
<DescriptionHeader gameDetails={gameDetails} />
|
||||
|
||||
<GallerySlider gameDetails={gameDetails} />
|
||||
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: gameDetails?.about_the_game ?? "",
|
||||
|
@ -13,6 +13,7 @@ export function Settings() {
|
||||
telemetryEnabled: false,
|
||||
realDebridApiToken: null as string | null,
|
||||
preferQuitInsteadOfHiding: false,
|
||||
runAtStartup: false,
|
||||
});
|
||||
|
||||
const { t } = useTranslation("settings");
|
||||
@ -32,6 +33,7 @@ export function Settings() {
|
||||
realDebridApiToken: userPreferences?.realDebridApiToken ?? null,
|
||||
preferQuitInsteadOfHiding:
|
||||
userPreferences?.preferQuitInsteadOfHiding ?? false,
|
||||
runAtStartup: userPreferences?.runAtStartup ?? false,
|
||||
});
|
||||
});
|
||||
}, []);
|
||||
@ -134,6 +136,15 @@ export function Settings() {
|
||||
updateUserPreferences("realDebridApiToken", event.target.value);
|
||||
}}
|
||||
/>
|
||||
|
||||
<CheckboxField
|
||||
label={t("launch_with_system")}
|
||||
onChange={() => {
|
||||
updateUserPreferences("runAtStartup", !form.runAtStartup);
|
||||
window.electron.autoLaunch(!form.runAtStartup);
|
||||
}}
|
||||
checked={form.runAtStartup}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
@ -14,6 +14,20 @@ export interface SteamScreenshot {
|
||||
path_full: string;
|
||||
}
|
||||
|
||||
export interface SteamVideoSource {
|
||||
max: string;
|
||||
'480': string;
|
||||
}
|
||||
|
||||
export interface SteamMovies {
|
||||
id: number;
|
||||
mp4: SteamVideoSource;
|
||||
webm: SteamVideoSource;
|
||||
thumbnail: string;
|
||||
name: string;
|
||||
highlight: boolean;
|
||||
}
|
||||
|
||||
export interface SteamAppDetails {
|
||||
name: string;
|
||||
detailed_description: string;
|
||||
@ -21,6 +35,7 @@ export interface SteamAppDetails {
|
||||
short_description: string;
|
||||
publishers: string[];
|
||||
genres: SteamGenre[];
|
||||
movies: SteamMovies[];
|
||||
screenshots: SteamScreenshot[];
|
||||
pc_requirements: {
|
||||
minimum: string;
|
||||
@ -30,7 +45,7 @@ export interface SteamAppDetails {
|
||||
minimum: string;
|
||||
recommended: string;
|
||||
};
|
||||
linux_requirmenets: {
|
||||
linux_requirements: {
|
||||
minimum: string;
|
||||
recommended: string;
|
||||
};
|
||||
@ -111,6 +126,7 @@ export interface UserPreferences {
|
||||
telemetryEnabled: boolean;
|
||||
realDebridApiToken: string | null;
|
||||
preferQuitInsteadOfHiding: boolean;
|
||||
runAtStartup: boolean;
|
||||
}
|
||||
|
||||
export interface HowLongToBeatCategory {
|
||||
|
41
yarn.lock
41
yarn.lock
@ -1316,6 +1316,11 @@
|
||||
resolved "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz"
|
||||
integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
|
||||
|
||||
"@types/auto-launch@^5.0.5":
|
||||
version "5.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/auto-launch/-/auto-launch-5.0.5.tgz#439ed36aaaea501e2e2cfbddd8a20c366c34863b"
|
||||
integrity sha512-/nGvQZSzM/pvCMCh4Gt2kIeiUmOP/cKGJbjlInI+A+5MoV/7XmT56DJ6EU8bqc3+ItxEe4UC2GVspmPzcCc8cg==
|
||||
|
||||
"@types/babel__core@^7.20.5":
|
||||
version "7.20.5"
|
||||
resolved "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz"
|
||||
@ -1822,6 +1827,14 @@ app-root-path@^3.1.0:
|
||||
resolved "https://registry.npmjs.org/app-root-path/-/app-root-path-3.1.0.tgz"
|
||||
integrity sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==
|
||||
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
applescript@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/applescript/-/applescript-1.0.0.tgz#bb87af568cad034a4e48c4bdaf6067a3a2701317"
|
||||
integrity sha512-yvtNHdWvtbYEiIazXAdp/NY+BBb65/DAseqlNiJQjOx9DynuzOYDbVLBJvuc0ve0VL9x6B3OHF6eH52y9hCBtQ==
|
||||
|
||||
>>>>>>> 53e5d2938c050ead27fdc8883d58f75920d63923
|
||||
argparse@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz"
|
||||
@ -1949,6 +1962,17 @@ at-least-node@^1.0.0:
|
||||
resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz"
|
||||
integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
|
||||
|
||||
auto-launch@^5.0.6:
|
||||
version "5.0.6"
|
||||
resolved "https://registry.yarnpkg.com/auto-launch/-/auto-launch-5.0.6.tgz#ccc238ddc07b2fa84e96a1bc2fd11b581a20cb2d"
|
||||
integrity sha512-OgxiAm4q9EBf9EeXdPBiVNENaWE3jUZofwrhAkWjHDYGezu1k3FRZHU8V2FBxGuSJOHzKmTJEd0G7L7/0xDGFA==
|
||||
dependencies:
|
||||
applescript "^1.0.0"
|
||||
mkdirp "^0.5.1"
|
||||
path-is-absolute "^1.0.0"
|
||||
untildify "^3.0.2"
|
||||
winreg "1.2.4"
|
||||
|
||||
available-typed-arrays@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz"
|
||||
@ -4394,6 +4418,13 @@ mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3:
|
||||
resolved "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz"
|
||||
integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==
|
||||
|
||||
mkdirp@^0.5.1:
|
||||
version "0.5.6"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6"
|
||||
integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==
|
||||
dependencies:
|
||||
minimist "^1.2.6"
|
||||
|
||||
mkdirp@^1.0.3:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz"
|
||||
@ -5776,6 +5807,11 @@ unplugin@1.0.1:
|
||||
webpack-sources "^3.2.3"
|
||||
webpack-virtual-modules "^0.5.0"
|
||||
|
||||
untildify@^3.0.2:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.3.tgz#1e7b42b140bcfd922b22e70ca1265bfe3634c7c9"
|
||||
integrity sha512-iSk/J8efr8uPT/Z4eSUywnqyrQU7DSdMfdqK4iWEaUVVmcP5JcnpRqmVMwcwcnmI1ATFNgC5V90u09tBynNFKA==
|
||||
|
||||
update-browserslist-db@^1.0.13:
|
||||
version "1.0.14"
|
||||
resolved "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.14.tgz"
|
||||
@ -5988,6 +6024,11 @@ which@^2.0.1, which@^2.0.2:
|
||||
dependencies:
|
||||
isexe "^2.0.0"
|
||||
|
||||
winreg@1.2.4:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/winreg/-/winreg-1.2.4.tgz#ba065629b7a925130e15779108cf540990e98d1b"
|
||||
integrity sha512-IHpzORub7kYlb8A43Iig3reOvlcBJGX9gZ0WycHhghHtA65X0LYnMRuJs+aH1abVnMJztQkvQNlltnbPi5aGIA==
|
||||
|
||||
winston-transport@^4.7.0:
|
||||
version "4.7.0"
|
||||
resolved "https://registry.npmjs.org/winston-transport/-/winston-transport-4.7.0.tgz"
|
||||
|
Loading…
Reference in New Issue
Block a user