mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-09 03:37:45 +03:00
Merge branch 'main' into feature/cloud-sync-improvements
This commit is contained in:
commit
034e71b3ee
@ -25,6 +25,7 @@
|
|||||||
[![cs](https://img.shields.io/badge/lang-cs-purple)](./README.cs.md)
|
[![cs](https://img.shields.io/badge/lang-cs-purple)](./README.cs.md)
|
||||||
[![da](https://img.shields.io/badge/lang-da-red)](./README.da.md)
|
[![da](https://img.shields.io/badge/lang-da-red)](./README.da.md)
|
||||||
[![nb](https://img.shields.io/badge/lang-nb-blue)](./README.nb.md)
|
[![nb](https://img.shields.io/badge/lang-nb-blue)](./README.nb.md)
|
||||||
|
[![ee](https://img.shields.io/badge/lang-et-blue.svg)](./README.et.md)
|
||||||
|
|
||||||
![Hydra Catalogue](./docs/screenshot.png)
|
![Hydra Catalogue](./docs/screenshot.png)
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
||||||
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
||||||
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
||||||
|
[![et](https://img.shields.io/badge/lang-et-blue.svg)](README.et.md)
|
||||||
|
|
||||||
![Hydra Catalogue](./screenshot.png)
|
![Hydra Catalogue](./screenshot.png)
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
||||||
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
||||||
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
||||||
|
[![et](https://img.shields.io/badge/lang-et-blue.svg)](README.et.md)
|
||||||
|
|
||||||
![Hydra Katalog](./screenshot.png)
|
![Hydra Katalog](./screenshot.png)
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
[![ita](https://img.shields.io/badge/lang-it-red)](README.it.md)
|
[![ita](https://img.shields.io/badge/lang-it-red)](README.it.md)
|
||||||
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
||||||
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
||||||
|
[![et](https://img.shields.io/badge/lang-et-blue.svg)](README.et.md)
|
||||||
|
|
||||||
![Hydra Catalogue](./screenshot.png)
|
![Hydra Catalogue](./screenshot.png)
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
||||||
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
||||||
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
||||||
|
[![et](https://img.shields.io/badge/lang-et-blue.svg)](README.et.md)
|
||||||
|
|
||||||
![Hydra Katalog](./screenshot.png)
|
![Hydra Katalog](./screenshot.png)
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
||||||
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
||||||
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
||||||
|
[![et](https://img.shields.io/badge/lang-et-blue.svg)](README.et.md)
|
||||||
|
|
||||||
![Hydra Catalogue](./screenshot.png)
|
![Hydra Catalogue](./screenshot.png)
|
||||||
|
|
||||||
|
186
docs/README.et.md
Normal file
186
docs/README.et.md
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
<div align="center">
|
||||||
|
|
||||||
|
[<img src="../resources/icon.png" width="144"/>](https://hydralauncher.site)
|
||||||
|
|
||||||
|
<h1 align="center">Hydra Launcher</h1>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<strong>Hydra on mängulauncher oma sisseehitatud bittorrenti kliendiga.</strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
[![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)
|
||||||
|
[![es](https://img.shields.io/badge/lang-es-red)](./README.es.md)
|
||||||
|
[![fr](https://img.shields.io/badge/lang-fr-blue)](./README.fr.md)
|
||||||
|
[![de](https://img.shields.io/badge/lang-de-black)](./README.de.md)
|
||||||
|
[![ita](https://img.shields.io/badge/lang-it-red)](./README.it.md)
|
||||||
|
[![cs](https://img.shields.io/badge/lang-cs-purple)](./README.cs.md)
|
||||||
|
[![da](https://img.shields.io/badge/lang-da-red)](./README.da.md)
|
||||||
|
[![nb](https://img.shields.io/badge/lang-nb-blue)](./README.nb.md)
|
||||||
|
[![ee](https://img.shields.io/badge/lang-et-blue.svg)](./README.et.md)
|
||||||
|
|
||||||
|
![Hydra Kataloog](./screenshot.png)
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
## Sisukord
|
||||||
|
|
||||||
|
- [Sisukord](#sisukord)
|
||||||
|
- [Tutvustus](#tutvustus)
|
||||||
|
- [Funktsioonid](#funktsioonid)
|
||||||
|
- [Paigaldamine](#paigaldamine)
|
||||||
|
- [Panustamine](#panustamine)
|
||||||
|
- [Liitu meie Telegramiga](#liitu-meie-telegramiga)
|
||||||
|
- [Forki ja klooni oma repositoorium](#forki-ja-klooni-oma-repositoorium)
|
||||||
|
- [Viisid panustamiseks](#viisid-panustamiseks)
|
||||||
|
- [Projekti Struktuur](#projekti-struktuur)
|
||||||
|
- [Lähtekoodi kompileerimine](#lähtekoodi-kompileerimine)
|
||||||
|
- [Node.js paigaldamine](#nodejs-paigaldamine)
|
||||||
|
- [Yarn'i paigaldamine](#yarni-paigaldamine)
|
||||||
|
- [Node sõltuvuste paigaldamine](#node-sõltuvuste-paigaldamine)
|
||||||
|
- [Python 3.9 paigaldamine](#python-39-paigaldamine)
|
||||||
|
- [Python'i sõltuvuste paigaldamine](#pythoni-sõltuvuste-paigaldamine)
|
||||||
|
- [Keskkonna muutujad](#keskkonna-muutujad)
|
||||||
|
- [Käivitamine](#käivitamine)
|
||||||
|
- [Kompileerimine](#kompileerimine)
|
||||||
|
- [Bittorrenti kliendi kompileerimine](#bittorrenti-kliendi-kompileerimine)
|
||||||
|
- [Electron rakenduse kompileerimine](#electron-rakenduse-kompileerimine)
|
||||||
|
- [Panustajad](#panustajad)
|
||||||
|
- [Litsents](#litsents)
|
||||||
|
|
||||||
|
## Tutvustus
|
||||||
|
|
||||||
|
**Hydra** on **Mängulauncher** oma sisseehitatud **BitTorrent Kliendiga**.
|
||||||
|
<br>
|
||||||
|
Launcher on kirjutatud TypeScriptis (Electron) ja Pythonis, mis haldab torrentide süsteemi kasutades libtorrenti.
|
||||||
|
|
||||||
|
## Funktsioonid
|
||||||
|
|
||||||
|
- Sisseehitatud bittorrenti klient
|
||||||
|
- How Long To Beat (HLTB) integratsioon mängu lehel
|
||||||
|
- Allalaadimiste kausta kohandamine
|
||||||
|
- Windowsi ja Linuxi tugi
|
||||||
|
- Pidevad uuendused
|
||||||
|
- Ja palju muud ...
|
||||||
|
|
||||||
|
## Paigaldamine
|
||||||
|
|
||||||
|
Järgi paigaldamiseks järgmisi samme:
|
||||||
|
|
||||||
|
1. Lae alla Hydra uusim versioon [Releases](https://github.com/hydralauncher/hydra/releases/latest) lehelt.
|
||||||
|
- Lae alla ainult .exe fail, kui soovid paigaldada Hydrat Windowsile.
|
||||||
|
- Lae alla .deb või .rpm või .zip fail, kui soovid paigaldada Hydrat Linuxile. (sõltub sinu Linuxi distrost)
|
||||||
|
2. Käivita allalaaditud fail.
|
||||||
|
3. Naudi Hydrat!
|
||||||
|
|
||||||
|
## Panustamine
|
||||||
|
|
||||||
|
### Liitu meie Telegramiga
|
||||||
|
|
||||||
|
Me keskendume aruteludele meie [Telegrami](https://t.me/hydralauncher) kanalis.
|
||||||
|
|
||||||
|
### Forki ja klooni oma repositoorium
|
||||||
|
|
||||||
|
1. Forki repositoorium [(klõpsa siia forkimiseks)](https://github.com/hydralauncher/hydra/fork)
|
||||||
|
2. Klooni oma forkitud kood `git clone https://github.com/your_username/hydra`
|
||||||
|
3. Loo uus haru
|
||||||
|
4. Pushi oma commitid
|
||||||
|
5. Esita uus Pull Request
|
||||||
|
|
||||||
|
### Viisid panustamiseks
|
||||||
|
|
||||||
|
- Tõlkimine: Me soovime, et Hydra oleks kättesaadav võimalikult paljudele inimestele. Võid aidata tõlkida uutesse keeltesse või uuendada ja parandada juba olemasolevaid tõlkeid Hydras.
|
||||||
|
- Kood: Hydra on ehitatud kasutades TypeScripti, Electroni ja natuke Pythonit. Kui soovid panustada, liitu meie [Telegramiga](https://t.me/hydralauncher)!
|
||||||
|
|
||||||
|
### Projekti Struktuur
|
||||||
|
|
||||||
|
- torrent-client: Kasutame libtorrenti, Pythoni teeki, torrentide allalaadimiste haldamiseks
|
||||||
|
- src/renderer: rakenduse kasutajaliides
|
||||||
|
- src/main: kogu loogika asub siin.
|
||||||
|
|
||||||
|
## Lähtekoodi kompileerimine
|
||||||
|
|
||||||
|
### Node.js paigaldamine
|
||||||
|
|
||||||
|
Veendu, et Node.js on sinu arvutisse paigaldatud. Kui ei ole, lae alla ja paigalda see [nodejs.org](https://nodejs.org/) lehelt.
|
||||||
|
|
||||||
|
### Yarn'i paigaldamine
|
||||||
|
|
||||||
|
Yarn on Node.js paketihaldur. Kui sa pole Yarni veel paigaldanud, saad seda teha järgides juhiseid [yarnpkg.com](https://classic.yarnpkg.com/lang/en/docs/install/) lehel.
|
||||||
|
|
||||||
|
### Node sõltuvuste paigaldamine
|
||||||
|
|
||||||
|
Liigu projekti kausta ja paigalda Node sõltuvused kasutades Yarni:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd hydra
|
||||||
|
yarn
|
||||||
|
```
|
||||||
|
|
||||||
|
### Python 3.9 paigaldamine
|
||||||
|
|
||||||
|
Veendu, et Python 3.9 on sinu arvutisse paigaldatud. Saad selle alla laadida ja paigaldada [python.org](https://www.python.org/downloads/release/python-3913/) lehelt.
|
||||||
|
|
||||||
|
### Python'i sõltuvuste paigaldamine
|
||||||
|
|
||||||
|
Paigalda vajalikud Pythoni sõltuvused kasutades pip'i:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
## Keskkonna muutujad
|
||||||
|
|
||||||
|
Sul on vaja SteamGridDB API võtit, et laadida alla mängude ikoone paigaldamisel.
|
||||||
|
|
||||||
|
Kui sul on see olemas, saad kopeerida või ümber nimetada `.env.example` faili `.env` failiks ja lisada sinna `STEAMGRIDDB_API_KEY`.
|
||||||
|
|
||||||
|
## Käivitamine
|
||||||
|
|
||||||
|
Kui kõik on seadistatud, saad käivitada järgmise käsu, et käivitada nii Electroni protsess kui ka bittorrenti klient:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## Kompileerimine
|
||||||
|
|
||||||
|
### Bittorrenti kliendi kompileerimine
|
||||||
|
|
||||||
|
Kompileeri bittorrenti klient kasutades järgmist käsku:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python torrent-client/setup.py build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Electron rakenduse kompileerimine
|
||||||
|
|
||||||
|
Kompileeri Electron rakendus kasutades järgmist käsku:
|
||||||
|
|
||||||
|
Windowsil:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn build:win
|
||||||
|
```
|
||||||
|
|
||||||
|
Linuxil:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
yarn build:linux
|
||||||
|
```
|
||||||
|
|
||||||
|
## Panustajad
|
||||||
|
|
||||||
|
<a href="https://github.com/hydralauncher/hydra/graphs/contributors">
|
||||||
|
<img src="https://contrib.rocks/image?repo=hydralauncher/hydra" />
|
||||||
|
</a>
|
||||||
|
|
||||||
|
## Litsents
|
||||||
|
|
||||||
|
Hydra on litsentseeritud [MIT Litsentsi](LICENSE) all.
|
@ -25,6 +25,7 @@
|
|||||||
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
||||||
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
||||||
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
||||||
|
[![et](https://img.shields.io/badge/lang-et-blue.svg)](README.et.md)
|
||||||
|
|
||||||
![Catalogue Hydra](./screenshot.png)
|
![Catalogue Hydra](./screenshot.png)
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
||||||
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
||||||
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
||||||
|
[![et](https://img.shields.io/badge/lang-et-blue.svg)](README.et.md)
|
||||||
|
|
||||||
![Hydra Catalogue](./screenshot.png)
|
![Hydra Catalogue](./screenshot.png)
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
[![ita](https://img.shields.io/badge/lang-it-red)](README.it.md)
|
[![ita](https://img.shields.io/badge/lang-it-red)](README.it.md)
|
||||||
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
||||||
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
||||||
|
[![et](https://img.shields.io/badge/lang-et-blue.svg)](README.et.md)
|
||||||
|
|
||||||
![Hydra Catalogue](./screenshot.png)
|
![Hydra Catalogue](./screenshot.png)
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
||||||
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
||||||
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
||||||
|
[![et](https://img.shields.io/badge/lang-et-blue.svg)](README.et.md)
|
||||||
|
|
||||||
![Hydra Catalogue](./screenshot.png)
|
![Hydra Catalogue](./screenshot.png)
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
||||||
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
||||||
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
||||||
|
[![et](https://img.shields.io/badge/lang-et-blue.svg)](README.et.md)
|
||||||
|
|
||||||
![Hydra Catalogue](./screenshot.png)
|
![Hydra Catalogue](./screenshot.png)
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
||||||
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
||||||
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
||||||
|
[![et](https://img.shields.io/badge/lang-et-blue.svg)](README.et.md)
|
||||||
|
|
||||||
![Hydra Catalogue](./screenshot.png)
|
![Hydra Catalogue](./screenshot.png)
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
[![cs](https://img.shields.io/badge/lang-cs-purple)](README.cs.md)
|
||||||
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
[![da](https://img.shields.io/badge/lang-da-red)](README.da.md)
|
||||||
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
[![nb](https://img.shields.io/badge/lang-nb-blue)](README.nb.md)
|
||||||
|
[![et](https://img.shields.io/badge/lang-et-blue.svg)](README.et.md)
|
||||||
|
|
||||||
![Hydra Catalogue](./screenshot.png)
|
![Hydra Catalogue](./screenshot.png)
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
"bottom_panel": {
|
"bottom_panel": {
|
||||||
"no_downloads_in_progress": "No downloads in progress",
|
"no_downloads_in_progress": "No downloads in progress",
|
||||||
"downloading_metadata": "Downloading {{title}} metadata…",
|
"downloading_metadata": "Downloading {{title}} metadata…",
|
||||||
"downloading": "Downloading {{title}}… ({{percentage}} complete) - Conclusion {{eta}} - {{speed}}",
|
"downloading": "Downloading {{title}}… ({{percentage}} complete) - Completion {{eta}} - {{speed}}",
|
||||||
"calculating_eta": "Downloading {{title}}… ({{percentage}} complete) - Calculating remaining time…",
|
"calculating_eta": "Downloading {{title}}… ({{percentage}} complete) - Calculating remaining time…",
|
||||||
"checking_files": "Checking {{title}} files… ({{percentage}} complete)"
|
"checking_files": "Checking {{title}} files… ({{percentage}} complete)"
|
||||||
},
|
},
|
||||||
@ -358,7 +358,7 @@
|
|||||||
"user_achievements": "{{displayName}}'s Achievements",
|
"user_achievements": "{{displayName}}'s Achievements",
|
||||||
"your_achievements": "Your Achievements",
|
"your_achievements": "Your Achievements",
|
||||||
"unlocked_at": "Unlocked at:",
|
"unlocked_at": "Unlocked at:",
|
||||||
"subscription_needed": "A Hydra Cloud subscription is needed to see this content",
|
"subscription_needed": "A Hydra Cloud subscription is required to see this content",
|
||||||
"new_achievements_unlocked": "Unlocked {{achievementCount}} new achievements from {{gameCount}} games"
|
"new_achievements_unlocked": "Unlocked {{achievementCount}} new achievements from {{gameCount}} games"
|
||||||
},
|
},
|
||||||
"tour": {
|
"tour": {
|
||||||
|
459
src/locales/et/translation.json
Normal file
459
src/locales/et/translation.json
Normal file
@ -0,0 +1,459 @@
|
|||||||
|
{
|
||||||
|
"language_name": "Eesti",
|
||||||
|
"app": {
|
||||||
|
"successfully_signed_in": "Edukalt sisse logitud"
|
||||||
|
},
|
||||||
|
"home": {
|
||||||
|
"featured": "Esile toodud",
|
||||||
|
"trending": "Populaarne",
|
||||||
|
"surprise_me": "Üllata mind",
|
||||||
|
"no_results": "Tulemusi ei leitud",
|
||||||
|
"start_typing": "Alusta otsimiseks kirjutamist...",
|
||||||
|
"hot": "Praegu kuum",
|
||||||
|
"weekly": "📅 Nädala top mängud"
|
||||||
|
},
|
||||||
|
"sidebar": {
|
||||||
|
"catalogue": "Kataloog",
|
||||||
|
"downloads": "Allalaadimised",
|
||||||
|
"settings": "Seaded",
|
||||||
|
"my_library": "Minu kogu",
|
||||||
|
"downloading_metadata": "{{title}} (Metaandmete allalaadimine…)",
|
||||||
|
"paused": "{{title}} (Peatatud)",
|
||||||
|
"downloading": "{{title}} ({{percentage}} - Allalaadimine…)",
|
||||||
|
"filter": "Filtreeri kogu",
|
||||||
|
"home": "Avaleht",
|
||||||
|
"queued": "{{title}} (Järjekorras)",
|
||||||
|
"game_has_no_executable": "Mängul pole käivitusfaili valitud",
|
||||||
|
"sign_in": "Logi sisse",
|
||||||
|
"friends": "Sõbrad"
|
||||||
|
},
|
||||||
|
"header": {
|
||||||
|
"search": "Otsi mänge",
|
||||||
|
"home": "Avaleht",
|
||||||
|
"catalogue": "Kataloog",
|
||||||
|
"downloads": "Allalaadimised",
|
||||||
|
"search_results": "Otsingutulemused",
|
||||||
|
"settings": "Seaded",
|
||||||
|
"version_available_install": "Versioon {{version}} on saadaval. Klõpsa siia taaskäivitamiseks ja installimiseks.",
|
||||||
|
"version_available_download": "Versioon {{version}} on saadaval. Klõpsa siia allalaadimiseks."
|
||||||
|
},
|
||||||
|
"bottom_panel": {
|
||||||
|
"no_downloads_in_progress": "Allalaadimisi pole pooleli",
|
||||||
|
"downloading_metadata": "{{title}} metaandmete allalaadimine…",
|
||||||
|
"downloading": "{{title}} allalaadimine… ({{percentage}} valmis) - Lõpp {{eta}} - {{speed}}",
|
||||||
|
"calculating_eta": "{{title}} allalaadimine… ({{percentage}} valmis) - Järelejäänud aja arvutamine…",
|
||||||
|
"checking_files": "{{title}} failide kontrollimine… ({{percentage}} valmis)"
|
||||||
|
},
|
||||||
|
"catalogue": {
|
||||||
|
"next_page": "Järgmine leht",
|
||||||
|
"previous_page": "Eelmine leht"
|
||||||
|
},
|
||||||
|
"game_details": {
|
||||||
|
"open_download_options": "Ava allalaadimise valikud",
|
||||||
|
"download_options_zero": "Allalaadimise valikuid pole",
|
||||||
|
"download_options_one": "{{count}} allalaadimise valik",
|
||||||
|
"download_options_other": "{{count}} allalaadimise valikut",
|
||||||
|
"updated_at": "Uuendatud {{updated_at}}",
|
||||||
|
"install": "Installi",
|
||||||
|
"resume": "Jätka",
|
||||||
|
"pause": "Peata",
|
||||||
|
"cancel": "Tühista",
|
||||||
|
"remove": "Eemalda",
|
||||||
|
"space_left_on_disk": "{{space}} kettaruumi järel",
|
||||||
|
"eta": "Lõpp {{eta}}",
|
||||||
|
"calculating_eta": "Järelejäänud aja arvutamine…",
|
||||||
|
"downloading_metadata": "Metaandmete allalaadimine…",
|
||||||
|
"filter": "Filtreeri repacke",
|
||||||
|
"requirements": "Süsteeminõuded",
|
||||||
|
"minimum": "Miinimum",
|
||||||
|
"recommended": "Soovitatav",
|
||||||
|
"paused": "Peatatud",
|
||||||
|
"release_date": "Välja antud {{date}}",
|
||||||
|
"publisher": "Avaldaja {{publisher}}",
|
||||||
|
"hours": "tundi",
|
||||||
|
"minutes": "minutit",
|
||||||
|
"amount_hours": "{{amount}} tundi",
|
||||||
|
"amount_minutes": "{{amount}} minutit",
|
||||||
|
"accuracy": "{{accuracy}}% täpsus",
|
||||||
|
"add_to_library": "Lisa kogusse",
|
||||||
|
"remove_from_library": "Eemalda kogust",
|
||||||
|
"no_downloads": "Allalaadimisi pole saadaval",
|
||||||
|
"play_time": "Mängitud {{amount}}",
|
||||||
|
"last_time_played": "Viimati mängitud {{period}}",
|
||||||
|
"not_played_yet": "Sa pole veel {{title}} mänginud",
|
||||||
|
"next_suggestion": "Järgmine soovitus",
|
||||||
|
"play": "Mängi",
|
||||||
|
"deleting": "Installeri kustutamine…",
|
||||||
|
"close": "Sulge",
|
||||||
|
"playing_now": "Mängib praegu",
|
||||||
|
"change": "Muuda",
|
||||||
|
"repacks_modal_description": "Vali repack, mida soovid alla laadida",
|
||||||
|
"select_folder_hint": "Vaikimisi kausta muutmiseks mine <0>Seadetesse</0>",
|
||||||
|
"download_now": "Laadi alla kohe",
|
||||||
|
"no_shop_details": "Poe andmeid ei õnnestunud laadida.",
|
||||||
|
"download_options": "Allalaadimise valikud",
|
||||||
|
"download_path": "Allalaadimise tee",
|
||||||
|
"previous_screenshot": "Eelmine kuvatõmmis",
|
||||||
|
"next_screenshot": "Järgmine kuvatõmmis",
|
||||||
|
"screenshot": "Kuvatõmmis {{number}}",
|
||||||
|
"open_screenshot": "Ava kuvatõmmis {{number}}",
|
||||||
|
"download_settings": "Allalaadimise seaded",
|
||||||
|
"downloader": "Allalaadija",
|
||||||
|
"select_executable": "Vali",
|
||||||
|
"no_executable_selected": "Käivitusfaili pole valitud",
|
||||||
|
"open_folder": "Ava kaust",
|
||||||
|
"open_download_location": "Vaata allalaaditud faile",
|
||||||
|
"create_shortcut": "Loo töölaua otsetee",
|
||||||
|
"remove_files": "Eemalda failid",
|
||||||
|
"remove_from_library_title": "Oled sa kindel?",
|
||||||
|
"remove_from_library_description": "See eemaldab {{game}} sinu kogust",
|
||||||
|
"options": "Valikud",
|
||||||
|
"executable_section_title": "Käivitusfail",
|
||||||
|
"executable_section_description": "Faili tee, mida käivitatakse \"Mängi\" nupule vajutades",
|
||||||
|
"downloads_secion_title": "Allalaadimised",
|
||||||
|
"downloads_section_description": "Vaata uuendusi või selle mängu teisi versioone",
|
||||||
|
"danger_zone_section_title": "Ohutsoon",
|
||||||
|
"danger_zone_section_description": "Eemalda see mäng oma kogust või Hydra poolt allalaaditud failid",
|
||||||
|
"download_in_progress": "Allalaadimine käimas",
|
||||||
|
"download_paused": "Allalaadimine peatatud",
|
||||||
|
"last_downloaded_option": "Viimane allalaaditud variant",
|
||||||
|
"create_shortcut_success": "Otsetee edukalt loodud",
|
||||||
|
"create_shortcut_error": "Viga otsetee loomisel",
|
||||||
|
"nsfw_content_title": "See mäng sisaldab sobimatut sisu",
|
||||||
|
"nsfw_content_description": "{{title}} sisaldab sisu, mis ei pruugi sobida kõigile vanusegruppidele. Kas soovid kindlasti jätkata?",
|
||||||
|
"allow_nsfw_content": "Jätka",
|
||||||
|
"refuse_nsfw_content": "Mine tagasi",
|
||||||
|
"stats": "Statistika",
|
||||||
|
"download_count": "Allalaadimised",
|
||||||
|
"player_count": "Aktiivsed mängijad",
|
||||||
|
"download_error": "See allalaadimise valik pole saadaval",
|
||||||
|
"download": "Laadi alla",
|
||||||
|
"executable_path_in_use": "Käivitusfail on juba kasutusel mängus \"{{game}}\"",
|
||||||
|
"warning": "Hoiatus:",
|
||||||
|
"hydra_needs_to_remain_open": "selle allalaadimise jaoks peab Hydra jääma avatuks kuni lõpuni. Kui Hydra sulgub enne lõppu, kaotad oma progressi.",
|
||||||
|
"achievements": "Saavutused",
|
||||||
|
"achievements_count": "Saavutused {{unlockedCount}}/{{achievementsCount}}",
|
||||||
|
"cloud_save": "Pilvesalvestus",
|
||||||
|
"cloud_save_description": "Salvesta oma progress pilve ja jätka mängimist mistahes seadmes",
|
||||||
|
"backups": "Varundused",
|
||||||
|
"install_backup": "Installi",
|
||||||
|
"delete_backup": "Kustuta",
|
||||||
|
"create_backup": "Uus varundus",
|
||||||
|
"last_backup_date": "Viimane varundus {{date}}",
|
||||||
|
"no_backup_preview": "Selle mängu jaoks ei leitud salvestusi",
|
||||||
|
"restoring_backup": "Varunduse taastamine ({{progress}} valmis)…",
|
||||||
|
"uploading_backup": "Varunduse üleslaadimine…",
|
||||||
|
"no_backups": "Sa pole veel selle mängu jaoks varundusi loonud",
|
||||||
|
"backup_uploaded": "Varundus üles laaditud",
|
||||||
|
"backup_deleted": "Varundus kustutatud",
|
||||||
|
"backup_restored": "Varundus taastatud",
|
||||||
|
"see_all_achievements": "Vaata kõiki saavutusi",
|
||||||
|
"sign_in_to_see_achievements": "Logi sisse, et näha saavutusi",
|
||||||
|
"mapping_method_automatic": "Automaatne",
|
||||||
|
"mapping_method_manual": "Käsitsi",
|
||||||
|
"mapping_method_label": "Kaardistamise meetod",
|
||||||
|
"files_automatically_mapped": "Failid automaatselt kaardistatud",
|
||||||
|
"no_backups_created": "Selle mängu jaoks pole varundusi loodud",
|
||||||
|
"manage_files": "Halda faile",
|
||||||
|
"loading_save_preview": "Salvestuste otsimine…",
|
||||||
|
"wine_prefix": "Wine Prefix",
|
||||||
|
"wine_prefix_description": "Wine prefix, mida kasutatakse selle mängu käivitamiseks",
|
||||||
|
"no_download_option_info": "Info pole saadaval",
|
||||||
|
"backup_deletion_failed": "Varunduse kustutamine ebaõnnestus",
|
||||||
|
"max_number_of_artifacts_reached": "Selle mängu varunduste maksimaalne arv on saavutatud",
|
||||||
|
"achievements_not_sync": "Sinu saavutused pole sünkroniseeritud"
|
||||||
|
},
|
||||||
|
"activation": {
|
||||||
|
"title": "Aktiveeri Hydra",
|
||||||
|
"installation_id": "Installatsiooni ID:",
|
||||||
|
"enter_activation_code": "Sisesta oma aktiveerimiskood",
|
||||||
|
"message": "Kui sa ei tea, kust seda küsida, siis sa ei peaks seda omama.",
|
||||||
|
"activate": "Aktiveeri",
|
||||||
|
"loading": "Laadimine…"
|
||||||
|
},
|
||||||
|
"downloads": {
|
||||||
|
"resume": "Jätka",
|
||||||
|
"pause": "Peata",
|
||||||
|
"eta": "Lõpp {{eta}}",
|
||||||
|
"paused": "Peatatud",
|
||||||
|
"verifying": "Kontrollimine…",
|
||||||
|
"completed": "Lõpetatud",
|
||||||
|
"removed": "Pole alla laaditud",
|
||||||
|
"cancel": "Tühista",
|
||||||
|
"filter": "Filtreeri allalaaditud mänge",
|
||||||
|
"remove": "Eemalda",
|
||||||
|
"downloading_metadata": "Metaandmete allalaadimine…",
|
||||||
|
"deleting": "Installeri kustutamine…",
|
||||||
|
"delete": "Eemalda installer",
|
||||||
|
"delete_modal_title": "Oled sa kindel?",
|
||||||
|
"delete_modal_description": "See eemaldab kõik installifailid sinu arvutist",
|
||||||
|
"install": "Installi",
|
||||||
|
"download_in_progress": "Töös",
|
||||||
|
"queued_downloads": "Järjekorras allalaadimised",
|
||||||
|
"downloads_completed": "Lõpetatud",
|
||||||
|
"queued": "Järjekorras",
|
||||||
|
"no_downloads_title": "Nii tühi",
|
||||||
|
"no_downloads_description": "Sa pole veel Hydraga midagi alla laadinud, aga pole kunagi hilja alustada.",
|
||||||
|
"checking_files": "Failide kontrollimine…"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"downloads_path": "Allalaadimiste tee",
|
||||||
|
"change": "Uuenda",
|
||||||
|
"notifications": "Teavitused",
|
||||||
|
"enable_download_notifications": "Kui allalaadimine on lõpetatud",
|
||||||
|
"enable_repack_list_notifications": "Kui uus repack on lisatud",
|
||||||
|
"real_debrid_api_token_label": "Real-Debrid API võti",
|
||||||
|
"quit_app_instead_hiding": "Ära peida Hydrat sulgemisel",
|
||||||
|
"launch_with_system": "Käivita Hydra süsteemi käivitamisel",
|
||||||
|
"general": "Üldine",
|
||||||
|
"behavior": "Käitumine",
|
||||||
|
"download_sources": "Allalaadimise allikad",
|
||||||
|
"language": "Keel",
|
||||||
|
"real_debrid_api_token": "API Võti",
|
||||||
|
"enable_real_debrid": "Luba Real-Debrid",
|
||||||
|
"real_debrid_description": "Real-Debrid on piiranguteta allalaadija, mis võimaldab sul faile alla laadida koheselt ja sinu internetiühenduse parima kiirusega.",
|
||||||
|
"real_debrid_invalid_token": "Vigane API võti",
|
||||||
|
"real_debrid_api_token_hint": "Sa saad oma API võtme <0>siit</0>",
|
||||||
|
"real_debrid_free_account_error": "Konto \"{{username}}\" on tasuta konto. Palun telli Real-Debrid",
|
||||||
|
"real_debrid_linked_message": "Konto \"{{username}}\" ühendatud",
|
||||||
|
"save_changes": "Salvesta muudatused",
|
||||||
|
"changes_saved": "Muudatused edukalt salvestatud",
|
||||||
|
"download_sources_description": "Hydra laeb allalaadimise lingid nendest allikatest. Allika URL peab olema otsene link .json failile, mis sisaldab allalaadimise linke.",
|
||||||
|
"validate_download_source": "Valideeri",
|
||||||
|
"remove_download_source": "Eemalda",
|
||||||
|
"add_download_source": "Lisa allikas",
|
||||||
|
"download_count_zero": "Allalaadimise valikuid pole",
|
||||||
|
"download_count_one": "{{countFormatted}} allalaadimise valik",
|
||||||
|
"download_count_other": "{{countFormatted}} allalaadimise valikut",
|
||||||
|
"download_source_url": "Allalaadimise allika URL",
|
||||||
|
"add_download_source_description": "Sisesta URL, mis sisaldab .json faili",
|
||||||
|
"download_source_up_to_date": "Ajakohane",
|
||||||
|
"download_source_errored": "Vigane",
|
||||||
|
"sync_download_sources": "Sünkroniseeri allikad",
|
||||||
|
"removed_download_source": "Allalaadimise allikas eemaldatud",
|
||||||
|
"added_download_source": "Allalaadimise allikas lisatud",
|
||||||
|
"download_sources_synced": "Kõik allalaadimise allikad on sünkroniseeritud",
|
||||||
|
"insert_valid_json_url": "Sisesta kehtiv JSON url",
|
||||||
|
"found_download_option_zero": "Allalaadimise valikuid ei leitud",
|
||||||
|
"found_download_option_one": "Leitud {{countFormatted}} allalaadimise valik",
|
||||||
|
"found_download_option_other": "Leitud {{countFormatted}} allalaadimise valikut",
|
||||||
|
"import": "Impordi",
|
||||||
|
"public": "Avalik",
|
||||||
|
"private": "Privaatne",
|
||||||
|
"friends_only": "Ainult sõpradele",
|
||||||
|
"privacy": "Privaatsus",
|
||||||
|
"profile_visibility": "Profiili nähtavus",
|
||||||
|
"profile_visibility_description": "Vali, kes saavad näha sinu profiili ja kogu",
|
||||||
|
"required_field": "See väli on kohustuslik",
|
||||||
|
"source_already_exists": "See allikas on juba lisatud",
|
||||||
|
"must_be_valid_url": "Allikas peab olema kehtiv URL",
|
||||||
|
"blocked_users": "Blokeeritud kasutajad",
|
||||||
|
"user_unblocked": "Kasutaja blokeering on eemaldatud",
|
||||||
|
"enable_achievement_notifications": "Kui saavutus avatakse"
|
||||||
|
},
|
||||||
|
"activation": {
|
||||||
|
"title": "Aktiveeri Hydra",
|
||||||
|
"installation_id": "Installatsiooni ID:",
|
||||||
|
"enter_activation_code": "Sisesta oma aktiveerimiskood",
|
||||||
|
"message": "Kui sa ei tea, kust seda küsida, siis sa ei peaks seda omama.",
|
||||||
|
"activate": "Aktiveeri",
|
||||||
|
"loading": "Laadimine…"
|
||||||
|
},
|
||||||
|
"downloads": {
|
||||||
|
"resume": "Jätka",
|
||||||
|
"pause": "Peata",
|
||||||
|
"eta": "Lõpp {{eta}}",
|
||||||
|
"paused": "Peatatud",
|
||||||
|
"verifying": "Kontrollimine…",
|
||||||
|
"completed": "Lõpetatud",
|
||||||
|
"removed": "Pole alla laaditud",
|
||||||
|
"cancel": "Tühista",
|
||||||
|
"filter": "Filtreeri allalaaditud mänge",
|
||||||
|
"remove": "Eemalda",
|
||||||
|
"downloading_metadata": "Metaandmete allalaadimine…",
|
||||||
|
"deleting": "Installeri kustutamine…",
|
||||||
|
"delete": "Eemalda installer",
|
||||||
|
"delete_modal_title": "Oled sa kindel?",
|
||||||
|
"delete_modal_description": "See eemaldab kõik installifailid sinu arvutist",
|
||||||
|
"install": "Installi",
|
||||||
|
"download_in_progress": "Töös",
|
||||||
|
"queued_downloads": "Järjekorras allalaadimised",
|
||||||
|
"downloads_completed": "Lõpetatud",
|
||||||
|
"queued": "Järjekorras",
|
||||||
|
"no_downloads_title": "Nii tühi",
|
||||||
|
"no_downloads_description": "Sa pole veel Hydraga midagi alla laadinud, aga pole kunagi hilja alustada.",
|
||||||
|
"checking_files": "Failide kontrollimine…"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"downloads_path": "Allalaadimiste tee",
|
||||||
|
"change": "Uuenda",
|
||||||
|
"notifications": "Teavitused",
|
||||||
|
"enable_download_notifications": "Kui allalaadimine on lõpetatud",
|
||||||
|
"enable_repack_list_notifications": "Kui uus repack on lisatud",
|
||||||
|
"real_debrid_api_token_label": "Real-Debrid API võti",
|
||||||
|
"quit_app_instead_hiding": "Ära peida Hydrat sulgemisel",
|
||||||
|
"launch_with_system": "Käivita Hydra süsteemi käivitamisel",
|
||||||
|
"general": "Üldine",
|
||||||
|
"behavior": "Käitumine",
|
||||||
|
"download_sources": "Allalaadimise allikad",
|
||||||
|
"language": "Keel",
|
||||||
|
"real_debrid_api_token": "API Võti",
|
||||||
|
"enable_real_debrid": "Luba Real-Debrid",
|
||||||
|
"real_debrid_description": "Real-Debrid on piiranguteta allalaadija, mis võimaldab sul faile alla laadida koheselt ja sinu internetiühenduse parima kiirusega.",
|
||||||
|
"real_debrid_invalid_token": "Vigane API võti",
|
||||||
|
"real_debrid_api_token_hint": "Sa saad oma API võtme <0>siit</0>",
|
||||||
|
"real_debrid_free_account_error": "Konto \"{{username}}\" on tasuta konto. Palun telli Real-Debrid",
|
||||||
|
"real_debrid_linked_message": "Konto \"{{username}}\" ühendatud",
|
||||||
|
"save_changes": "Salvesta muudatused",
|
||||||
|
"changes_saved": "Muudatused edukalt salvestatud",
|
||||||
|
"download_sources_description": "Hydra laeb allalaadimise lingid nendest allikatest. Allika URL peab olema otsene link .json failile, mis sisaldab allalaadimise linke.",
|
||||||
|
"validate_download_source": "Valideeri",
|
||||||
|
"remove_download_source": "Eemalda",
|
||||||
|
"add_download_source": "Lisa allikas",
|
||||||
|
"download_count_zero": "Allalaadimise valikuid pole",
|
||||||
|
"download_count_one": "{{countFormatted}} allalaadimise valik",
|
||||||
|
"download_count_other": "{{countFormatted}} allalaadimise valikut",
|
||||||
|
"download_source_url": "Allalaadimise allika URL",
|
||||||
|
"add_download_source_description": "Sisesta URL, mis sisaldab .json faili",
|
||||||
|
"download_source_up_to_date": "Ajakohane",
|
||||||
|
"download_source_errored": "Vigane",
|
||||||
|
"sync_download_sources": "Sünkroniseeri allikad",
|
||||||
|
"removed_download_source": "Allalaadimise allikas eemaldatud",
|
||||||
|
"added_download_source": "Allalaadimise allikas lisatud",
|
||||||
|
"download_sources_synced": "Kõik allalaadimise allikad on sünkroniseeritud",
|
||||||
|
"insert_valid_json_url": "Sisesta kehtiv JSON url",
|
||||||
|
"found_download_option_zero": "Allalaadimise valikuid ei leitud",
|
||||||
|
"found_download_option_one": "Leitud {{countFormatted}} allalaadimise valik",
|
||||||
|
"found_download_option_other": "Leitud {{countFormatted}} allalaadimise valikut",
|
||||||
|
"import": "Impordi",
|
||||||
|
"public": "Avalik",
|
||||||
|
"private": "Privaatne",
|
||||||
|
"friends_only": "Ainult sõpradele",
|
||||||
|
"privacy": "Privaatsus",
|
||||||
|
"profile_visibility": "Profiili nähtavus",
|
||||||
|
"profile_visibility_description": "Vali, kes saavad näha sinu profiili ja kogu",
|
||||||
|
"required_field": "See väli on kohustuslik",
|
||||||
|
"source_already_exists": "See allikas on juba lisatud",
|
||||||
|
"must_be_valid_url": "Allikas peab olema kehtiv URL",
|
||||||
|
"blocked_users": "Blokeeritud kasutajad",
|
||||||
|
"user_unblocked": "Kasutaja blokeering on eemaldatud",
|
||||||
|
"enable_achievement_notifications": "Kui saavutus avatakse"
|
||||||
|
},
|
||||||
|
"notifications": {
|
||||||
|
"download_complete": "Allalaadimine lõpetatud",
|
||||||
|
"game_ready_to_install": "{{title}} on valmis installimiseks",
|
||||||
|
"repack_list_updated": "Repackide nimekiri uuendatud",
|
||||||
|
"repack_count_one": "{{count}} repack lisatud",
|
||||||
|
"repack_count_other": "{{count}} repacki lisatud",
|
||||||
|
"new_update_available": "Versioon {{version}} saadaval",
|
||||||
|
"restart_to_install_update": "Taaskäivita Hydra uuenduse installimiseks",
|
||||||
|
"notification_achievement_unlocked_title": "Saavutus avatud mängus {{game}}",
|
||||||
|
"notification_achievement_unlocked_body": "{{achievement}} ja veel {{count}} avati"
|
||||||
|
},
|
||||||
|
"system_tray": {
|
||||||
|
"open": "Ava Hydra",
|
||||||
|
"quit": "Välju"
|
||||||
|
},
|
||||||
|
"game_card": {
|
||||||
|
"no_downloads": "Allalaadimisi pole saadaval"
|
||||||
|
},
|
||||||
|
"binary_not_found_modal": {
|
||||||
|
"title": "Programmid pole installitud",
|
||||||
|
"description": "Wine või Lutrise käivitusfaile ei leitud sinu süsteemist",
|
||||||
|
"instructions": "Kontrolli õiget viisi nende installimiseks oma Linuxi distrol, et mäng saaks normaalselt töötada"
|
||||||
|
},
|
||||||
|
"modal": {
|
||||||
|
"close": "Sulgemise nupp"
|
||||||
|
},
|
||||||
|
"forms": {
|
||||||
|
"toggle_password_visibility": "Lülita parooli nähtavust"
|
||||||
|
},
|
||||||
|
"user_profile": {
|
||||||
|
"amount_hours": "{{amount}} tundi",
|
||||||
|
"amount_minutes": "{{amount}} minutit",
|
||||||
|
"last_time_played": "Viimati mängitud {{period}}",
|
||||||
|
"activity": "Hiljutine aktiivsus",
|
||||||
|
"library": "Kogu",
|
||||||
|
"total_play_time": "Kogu mängitud aeg: {{amount}}",
|
||||||
|
"no_recent_activity_title": "Hmmm… siin pole midagi",
|
||||||
|
"no_recent_activity_description": "Sa pole hiljuti ühtegi mängu mänginud. On aeg seda muuta!",
|
||||||
|
"display_name": "Kuvatav nimi",
|
||||||
|
"saving": "Salvestamine",
|
||||||
|
"save": "Salvesta",
|
||||||
|
"edit_profile": "Muuda profiili",
|
||||||
|
"saved_successfully": "Edukalt salvestatud",
|
||||||
|
"try_again": "Palun proovi uuesti",
|
||||||
|
"sign_out_modal_title": "Oled sa kindel?",
|
||||||
|
"cancel": "Tühista",
|
||||||
|
"successfully_signed_out": "Edukalt välja logitud",
|
||||||
|
"sign_out": "Logi välja",
|
||||||
|
"playing_for": "Mängib {{amount}}",
|
||||||
|
"sign_out_modal_text": "Sinu kogu on seotud sinu praeguse kontoga. Välja logides pole sinu kogu enam nähtav ja edasist progressi ei salvestata. Jätkata väljalogimisega?",
|
||||||
|
"add_friends": "Lisa sõpru",
|
||||||
|
"add": "Lisa",
|
||||||
|
"friend_code": "Sõbrakood",
|
||||||
|
"see_profile": "Vaata profiili",
|
||||||
|
"sending": "Saatmine",
|
||||||
|
"friend_request_sent": "Sõbrakutse saadetud",
|
||||||
|
"friends": "Sõbrad",
|
||||||
|
"friends_list": "Sõbrade nimekiri",
|
||||||
|
"user_not_found": "Kasutajat ei leitud",
|
||||||
|
"block_user": "Blokeeri kasutaja",
|
||||||
|
"add_friend": "Lisa sõbraks",
|
||||||
|
"request_sent": "Kutse saadetud",
|
||||||
|
"request_received": "Kutse saadud",
|
||||||
|
"accept_request": "Võta kutse vastu",
|
||||||
|
"ignore_request": "Ignoreeri kutset",
|
||||||
|
"cancel_request": "Tühista kutse",
|
||||||
|
"undo_friendship": "Tühista sõprus",
|
||||||
|
"request_accepted": "Kutse vastu võetud",
|
||||||
|
"user_blocked_successfully": "Kasutaja edukalt blokeeritud",
|
||||||
|
"user_block_modal_text": "See blokeerib kasutaja {{displayName}}",
|
||||||
|
"blocked_users": "Blokeeritud kasutajad",
|
||||||
|
"unblock": "Eemalda blokeering",
|
||||||
|
"no_friends_added": "Sul pole veel lisatud sõpru",
|
||||||
|
"pending": "Ootel",
|
||||||
|
"no_pending_invites": "Sul pole ootel kutseid",
|
||||||
|
"no_blocked_users": "Sul pole blokeeritud kasutajaid",
|
||||||
|
"friend_code_copied": "Sõbrakood kopeeritud",
|
||||||
|
"undo_friendship_modal_text": "See tühistab sinu sõpruse kasutajaga {{displayName}}",
|
||||||
|
"privacy_hint": "Et muuta, kes seda näevad, mine <0>Seadetesse</0>",
|
||||||
|
"locked_profile": "See profiil on privaatne",
|
||||||
|
"image_process_failure": "Viga pildi töötlemisel",
|
||||||
|
"required_field": "See väli on kohustuslik",
|
||||||
|
"displayname_min_length": "Kuvatav nimi peab olema vähemalt 3 tähemärki pikk",
|
||||||
|
"displayname_max_length": "Kuvatav nimi võib olla maksimaalselt 50 tähemärki pikk",
|
||||||
|
"report_profile": "Teata sellest profiilist",
|
||||||
|
"report_reason": "Miks sa sellest profiilist teatad?",
|
||||||
|
"report_description": "Lisainfo",
|
||||||
|
"report_description_placeholder": "Lisainfo",
|
||||||
|
"report": "Teata",
|
||||||
|
"report_reason_hate": "Vaenukõne",
|
||||||
|
"report_reason_sexual_content": "Seksuaalne sisu",
|
||||||
|
"report_reason_violence": "Vägivald",
|
||||||
|
"report_reason_spam": "Rämpspost",
|
||||||
|
"report_reason_other": "Muu",
|
||||||
|
"profile_reported": "Profiilist teatatud",
|
||||||
|
"your_friend_code": "Sinu sõbrakood:",
|
||||||
|
"upload_banner": "Lae üles bänner",
|
||||||
|
"uploading_banner": "Bänneri üleslaadimine…"
|
||||||
|
},
|
||||||
|
"achievement": {
|
||||||
|
"achievement_unlocked": "Saavutus avatud",
|
||||||
|
"user_achievements": "{{displayName}} saavutused",
|
||||||
|
"your_achievements": "Sinu saavutused",
|
||||||
|
"unlocked_at": "Avatud:",
|
||||||
|
"subscription_needed": "Selle sisu nägemiseks on vaja Hydra Cloud tellimust",
|
||||||
|
"new_achievements_unlocked": "Avatud {{achievementCount}} uut saavutust {{gameCount}} mängust"
|
||||||
|
},
|
||||||
|
"tour": {
|
||||||
|
"subscription_tour_title": "Hydra Cloud Tellimus",
|
||||||
|
"subscribe_now": "Telli kohe",
|
||||||
|
"cloud_saving": "Pilvesalvestus (kuni {{gameCount}} mängu)",
|
||||||
|
"cloud_achievements": "Salvesta oma saavutused pilve",
|
||||||
|
"animated_profile_picture": "Animeeritud profiilipildid",
|
||||||
|
"premium_support": "Premium tugi",
|
||||||
|
"show_and_compare_achievements": "Näita ja võrdle oma saavutusi teiste kasutajatega",
|
||||||
|
"animated_profile_banner": "Animeeritud profiilibänner"
|
||||||
|
}
|
||||||
|
}
|
@ -23,6 +23,7 @@ import ca from "./ca/translation.json";
|
|||||||
import kk from "./kk/translation.json";
|
import kk from "./kk/translation.json";
|
||||||
import cs from "./cs/translation.json";
|
import cs from "./cs/translation.json";
|
||||||
import nb from "./nb/translation.json";
|
import nb from "./nb/translation.json";
|
||||||
|
import et from "./et/translation.json";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
"pt-BR": ptBR,
|
"pt-BR": ptBR,
|
||||||
@ -50,4 +51,5 @@ export default {
|
|||||||
kk,
|
kk,
|
||||||
cs,
|
cs,
|
||||||
nb,
|
nb,
|
||||||
|
et,
|
||||||
};
|
};
|
||||||
|
@ -367,6 +367,7 @@
|
|||||||
"animated_profile_picture": "Fotos de perfil animadas",
|
"animated_profile_picture": "Fotos de perfil animadas",
|
||||||
"premium_support": "Suporte Premium",
|
"premium_support": "Suporte Premium",
|
||||||
"show_and_compare_achievements": "Exiba e compare suas conquistas com outros usuários",
|
"show_and_compare_achievements": "Exiba e compare suas conquistas com outros usuários",
|
||||||
"animated_profile_banner": "Banner animado no perfil"
|
"animated_profile_banner": "Banner animado no perfil",
|
||||||
|
"cloud_saving": "Saves na Cloud (até {{gameCount}} jogos)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import {
|
|||||||
gamesPlaytime,
|
gamesPlaytime,
|
||||||
} from "@main/services";
|
} from "@main/services";
|
||||||
import { dataSource } from "@main/data-source";
|
import { dataSource } from "@main/data-source";
|
||||||
import { DownloadQueue, Game, UserAuth } from "@main/entity";
|
import { DownloadQueue, Game, UserAuth, UserSubscription } from "@main/entity";
|
||||||
|
|
||||||
const signOut = async (_event: Electron.IpcMainInvokeEvent) => {
|
const signOut = async (_event: Electron.IpcMainInvokeEvent) => {
|
||||||
const databaseOperations = dataSource
|
const databaseOperations = dataSource
|
||||||
@ -19,6 +19,10 @@ const signOut = async (_event: Electron.IpcMainInvokeEvent) => {
|
|||||||
await transactionalEntityManager
|
await transactionalEntityManager
|
||||||
.getRepository(UserAuth)
|
.getRepository(UserAuth)
|
||||||
.delete({ id: 1 });
|
.delete({ id: 1 });
|
||||||
|
|
||||||
|
await transactionalEntityManager
|
||||||
|
.getRepository(UserSubscription)
|
||||||
|
.delete({ id: 1 });
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
/* Removes all games being played */
|
/* Removes all games being played */
|
||||||
|
@ -1,43 +1,11 @@
|
|||||||
import { registerEvent } from "../register-event";
|
import { registerEvent } from "../register-event";
|
||||||
import { logger } from "@main/services";
|
import type { UserDetails } from "@types";
|
||||||
import type { ProfileVisibility, UserDetails } from "@types";
|
|
||||||
import { userAuthRepository } from "@main/repository";
|
|
||||||
import { UserNotLoggedInError } from "@shared";
|
|
||||||
import { getUserData } from "@main/services/user/get-user-data";
|
import { getUserData } from "@main/services/user/get-user-data";
|
||||||
|
|
||||||
const getMe = async (
|
const getMe = async (
|
||||||
_event: Electron.IpcMainInvokeEvent
|
_event: Electron.IpcMainInvokeEvent
|
||||||
): Promise<UserDetails | null> => {
|
): Promise<UserDetails | null> => {
|
||||||
return getUserData().catch(async (err) => {
|
return getUserData();
|
||||||
if (err instanceof UserNotLoggedInError) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
logger.error("Failed to get logged user", err);
|
|
||||||
const loggedUser = await userAuthRepository.findOne({ where: { id: 1 } });
|
|
||||||
|
|
||||||
if (loggedUser) {
|
|
||||||
return {
|
|
||||||
...loggedUser,
|
|
||||||
id: loggedUser.userId,
|
|
||||||
username: "",
|
|
||||||
bio: "",
|
|
||||||
profileVisibility: "PUBLIC" as ProfileVisibility,
|
|
||||||
subscription: loggedUser.subscription
|
|
||||||
? {
|
|
||||||
id: loggedUser.subscription.subscriptionId,
|
|
||||||
status: loggedUser.subscription.status,
|
|
||||||
plan: {
|
|
||||||
id: loggedUser.subscription.planId,
|
|
||||||
name: loggedUser.subscription.planName,
|
|
||||||
},
|
|
||||||
expiresAt: loggedUser.subscription.expiresAt,
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
registerEvent("getMe", getMe);
|
registerEvent("getMe", getMe);
|
||||||
|
@ -12,7 +12,6 @@ import { UserPreferences } from "./entity";
|
|||||||
import { RealDebridClient } from "./services/real-debrid";
|
import { RealDebridClient } from "./services/real-debrid";
|
||||||
import { HydraApi } from "./services/hydra-api";
|
import { HydraApi } from "./services/hydra-api";
|
||||||
import { uploadGamesBatch } from "./services/library-sync";
|
import { uploadGamesBatch } from "./services/library-sync";
|
||||||
import { getUserData } from "./services/user/get-user-data";
|
|
||||||
|
|
||||||
const loadState = async (userPreferences: UserPreferences | null) => {
|
const loadState = async (userPreferences: UserPreferences | null) => {
|
||||||
import("./events");
|
import("./events");
|
||||||
@ -23,8 +22,7 @@ const loadState = async (userPreferences: UserPreferences | null) => {
|
|||||||
|
|
||||||
Ludusavi.addManifestToLudusaviConfig();
|
Ludusavi.addManifestToLudusaviConfig();
|
||||||
|
|
||||||
await HydraApi.setupApi().then(async () => {
|
HydraApi.setupApi().then(() => {
|
||||||
await getUserData().catch(() => {});
|
|
||||||
uploadGamesBatch();
|
uploadGamesBatch();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -71,6 +71,7 @@ const crackers = [
|
|||||||
Cracker.smartSteamEmu,
|
Cracker.smartSteamEmu,
|
||||||
Cracker.empress,
|
Cracker.empress,
|
||||||
Cracker.flt,
|
Cracker.flt,
|
||||||
|
Cracker.razor1911,
|
||||||
];
|
];
|
||||||
|
|
||||||
const getPathFromCracker = (cracker: Cracker) => {
|
const getPathFromCracker = (cracker: Cracker) => {
|
||||||
@ -221,6 +222,15 @@ const getPathFromCracker = (cracker: Cracker) => {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cracker == Cracker.razor1911) {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
folderPath: path.join(appData, ".1911"),
|
||||||
|
fileLocation: ["achievement"],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
achievementsLogger.error(`Cracker ${cracker} not implemented`);
|
achievementsLogger.error(`Cracker ${cracker} not implemented`);
|
||||||
throw new Error(`Cracker ${cracker} not implemented`);
|
throw new Error(`Cracker ${cracker} not implemented`);
|
||||||
};
|
};
|
||||||
|
@ -125,7 +125,7 @@ export const mergeAchievements = async (
|
|||||||
id: game.remoteId,
|
id: game.remoteId,
|
||||||
achievements: mergedLocalAchievements,
|
achievements: mergedLocalAchievements,
|
||||||
},
|
},
|
||||||
{ needsCloud: true }
|
{ needsSubscription: true }
|
||||||
)
|
)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
return saveAchievementsOnLocal(
|
return saveAchievementsOnLocal(
|
||||||
|
@ -65,6 +65,10 @@ export const parseAchievementFile = (
|
|||||||
return processCreamAPI(parsed);
|
return processCreamAPI(parsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type === Cracker.razor1911) {
|
||||||
|
return processRazor1911(filePath);
|
||||||
|
}
|
||||||
|
|
||||||
achievementsLogger.log(
|
achievementsLogger.log(
|
||||||
`Unprocessed ${type} achievements found on ${filePath}`
|
`Unprocessed ${type} achievements found on ${filePath}`
|
||||||
);
|
);
|
||||||
@ -111,6 +115,35 @@ const jsonParse = (filePath: string) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const processRazor1911 = (filePath: string): UnlockedAchievement[] => {
|
||||||
|
try {
|
||||||
|
const fileContent = readFileSync(filePath, "utf-8");
|
||||||
|
achievementsLogger.log("processing file", filePath, fileContent);
|
||||||
|
const lines =
|
||||||
|
fileContent.charCodeAt(0) === 0xfeff
|
||||||
|
? fileContent.slice(1).split(/[\r\n]+/)
|
||||||
|
: fileContent.split(/[\r\n]+/);
|
||||||
|
|
||||||
|
const achievements: UnlockedAchievement[] = [];
|
||||||
|
for (const line of lines) {
|
||||||
|
if (!line.length) continue;
|
||||||
|
|
||||||
|
const [name, unlocked, unlockTime] = line.split(" ");
|
||||||
|
if (unlocked === "1") {
|
||||||
|
achievements.push({
|
||||||
|
name,
|
||||||
|
unlockTime: Number(unlockTime) * 1000,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
achievementsLogger.log("processing file", achievements);
|
||||||
|
return achievements;
|
||||||
|
} catch (err) {
|
||||||
|
achievementsLogger.error(`Error processing ${filePath}`, err);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const processOnlineFix = (unlockedAchievements: any): UnlockedAchievement[] => {
|
const processOnlineFix = (unlockedAchievements: any): UnlockedAchievement[] => {
|
||||||
const parsedUnlockedAchievements: UnlockedAchievement[] = [];
|
const parsedUnlockedAchievements: UnlockedAchievement[] = [];
|
||||||
|
|
||||||
|
@ -11,10 +11,18 @@ import { logger } from "./logger";
|
|||||||
import { UserNotLoggedInError, SubscriptionRequiredError } from "@shared";
|
import { UserNotLoggedInError, SubscriptionRequiredError } from "@shared";
|
||||||
import { omit } from "lodash-es";
|
import { omit } from "lodash-es";
|
||||||
import { appVersion } from "@main/constants";
|
import { appVersion } from "@main/constants";
|
||||||
|
import { getUserData } from "./user/get-user-data";
|
||||||
|
|
||||||
interface HydraApiOptions {
|
interface HydraApiOptions {
|
||||||
needsAuth?: boolean;
|
needsAuth?: boolean;
|
||||||
needsCloud?: boolean;
|
needsSubscription?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface HydraApiUserAuth {
|
||||||
|
authToken: string;
|
||||||
|
refreshToken: string;
|
||||||
|
expirationTimestamp: number;
|
||||||
|
subscription: { expiresAt: Date | null } | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class HydraApi {
|
export class HydraApi {
|
||||||
@ -25,27 +33,22 @@ export class HydraApi {
|
|||||||
|
|
||||||
private static secondsToMilliseconds = (seconds: number) => seconds * 1000;
|
private static secondsToMilliseconds = (seconds: number) => seconds * 1000;
|
||||||
|
|
||||||
private static userAuth = {
|
private static userAuth: HydraApiUserAuth = {
|
||||||
authToken: "",
|
authToken: "",
|
||||||
refreshToken: "",
|
refreshToken: "",
|
||||||
expirationTimestamp: 0,
|
expirationTimestamp: 0,
|
||||||
|
subscription: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
private static isLoggedIn() {
|
private static isLoggedIn() {
|
||||||
return this.userAuth.authToken !== "";
|
return this.userAuth.authToken !== "";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async hasCloudSubscription() {
|
private static hasCloudSubscription() {
|
||||||
return userSubscriptionRepository
|
|
||||||
.findOne({ where: { id: 1 } })
|
|
||||||
.then((userSubscription) => {
|
|
||||||
if (!userSubscription) return false;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
!userSubscription.expiresAt ||
|
this.userAuth.subscription?.expiresAt &&
|
||||||
userSubscription!.expiresAt > new Date()
|
this.userAuth.subscription.expiresAt > new Date()
|
||||||
);
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static async handleExternalAuth(uri: string) {
|
static async handleExternalAuth(uri: string) {
|
||||||
@ -67,6 +70,7 @@ export class HydraApi {
|
|||||||
authToken: accessToken,
|
authToken: accessToken,
|
||||||
refreshToken: refreshToken,
|
refreshToken: refreshToken,
|
||||||
expirationTimestamp: tokenExpirationTimestamp,
|
expirationTimestamp: tokenExpirationTimestamp,
|
||||||
|
subscription: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
logger.log(
|
logger.log(
|
||||||
@ -84,6 +88,16 @@ export class HydraApi {
|
|||||||
["id"]
|
["id"]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await getUserData().then((userDetails) => {
|
||||||
|
if (userDetails?.subscription) {
|
||||||
|
this.userAuth.subscription = {
|
||||||
|
expiresAt: userDetails.subscription.expiresAt
|
||||||
|
? new Date(userDetails.subscription.expiresAt)
|
||||||
|
: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
if (WindowManager.mainWindow) {
|
if (WindowManager.mainWindow) {
|
||||||
WindowManager.mainWindow.webContents.send("on-signin");
|
WindowManager.mainWindow.webContents.send("on-signin");
|
||||||
await clearGamesRemoteIds();
|
await clearGamesRemoteIds();
|
||||||
@ -96,6 +110,7 @@ export class HydraApi {
|
|||||||
authToken: "",
|
authToken: "",
|
||||||
refreshToken: "",
|
refreshToken: "",
|
||||||
expirationTimestamp: 0,
|
expirationTimestamp: 0,
|
||||||
|
subscription: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,14 +176,20 @@ export class HydraApi {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await getUserData();
|
||||||
|
|
||||||
const userAuth = await userAuthRepository.findOne({
|
const userAuth = await userAuthRepository.findOne({
|
||||||
where: { id: 1 },
|
where: { id: 1 },
|
||||||
|
relations: { subscription: true },
|
||||||
});
|
});
|
||||||
|
|
||||||
this.userAuth = {
|
this.userAuth = {
|
||||||
authToken: userAuth?.accessToken ?? "",
|
authToken: userAuth?.accessToken ?? "",
|
||||||
refreshToken: userAuth?.refreshToken ?? "",
|
refreshToken: userAuth?.refreshToken ?? "",
|
||||||
expirationTimestamp: userAuth?.tokenExpirationTimestamp ?? 0,
|
expirationTimestamp: userAuth?.tokenExpirationTimestamp ?? 0,
|
||||||
|
subscription: userAuth?.subscription
|
||||||
|
? { expiresAt: userAuth.subscription?.expiresAt }
|
||||||
|
: null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,9 +257,11 @@ export class HydraApi {
|
|||||||
authToken: "",
|
authToken: "",
|
||||||
expirationTimestamp: 0,
|
expirationTimestamp: 0,
|
||||||
refreshToken: "",
|
refreshToken: "",
|
||||||
|
subscription: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
userAuthRepository.delete({ id: 1 });
|
userAuthRepository.delete({ id: 1 });
|
||||||
|
userSubscriptionRepository.delete({ id: 1 });
|
||||||
|
|
||||||
this.sendSignOutEvent();
|
this.sendSignOutEvent();
|
||||||
}
|
}
|
||||||
@ -248,14 +271,14 @@ export class HydraApi {
|
|||||||
|
|
||||||
private static async validateOptions(options?: HydraApiOptions) {
|
private static async validateOptions(options?: HydraApiOptions) {
|
||||||
const needsAuth = options?.needsAuth == undefined || options.needsAuth;
|
const needsAuth = options?.needsAuth == undefined || options.needsAuth;
|
||||||
const needsCloud = options?.needsCloud === true;
|
const needsSubscription = options?.needsSubscription === true;
|
||||||
|
|
||||||
if (needsAuth) {
|
if (needsAuth) {
|
||||||
if (!this.isLoggedIn()) throw new UserNotLoggedInError();
|
if (!this.isLoggedIn()) throw new UserNotLoggedInError();
|
||||||
await this.revalidateAccessTokenIfExpired();
|
await this.revalidateAccessTokenIfExpired();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needsCloud) {
|
if (needsSubscription) {
|
||||||
if (!(await this.hasCloudSubscription())) {
|
if (!(await this.hasCloudSubscription())) {
|
||||||
throw new SubscriptionRequiredError();
|
throw new SubscriptionRequiredError();
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,16 @@
|
|||||||
import type { UserDetails } from "@types";
|
import type { ProfileVisibility, UserDetails } from "@types";
|
||||||
import { HydraApi } from "../hydra-api";
|
import { HydraApi } from "../hydra-api";
|
||||||
import {
|
import {
|
||||||
userAuthRepository,
|
userAuthRepository,
|
||||||
userSubscriptionRepository,
|
userSubscriptionRepository,
|
||||||
} from "@main/repository";
|
} from "@main/repository";
|
||||||
import * as Sentry from "@sentry/electron/main";
|
import * as Sentry from "@sentry/electron/main";
|
||||||
|
import { UserNotLoggedInError } from "@shared";
|
||||||
|
import { logger } from "../logger";
|
||||||
|
|
||||||
export const getUserData = () => {
|
export const getUserData = () => {
|
||||||
return HydraApi.get<UserDetails>(`/profile/me`).then(async (me) => {
|
return HydraApi.get<UserDetails>(`/profile/me`)
|
||||||
|
.then(async (me) => {
|
||||||
userAuthRepository.upsert(
|
userAuthRepository.upsert(
|
||||||
{
|
{
|
||||||
id: 1,
|
id: 1,
|
||||||
@ -39,5 +42,38 @@ export const getUserData = () => {
|
|||||||
Sentry.setUser({ id: me.id, username: me.username });
|
Sentry.setUser({ id: me.id, username: me.username });
|
||||||
|
|
||||||
return me;
|
return me;
|
||||||
|
})
|
||||||
|
.catch(async (err) => {
|
||||||
|
if (err instanceof UserNotLoggedInError) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
logger.error("Failed to get logged user", err);
|
||||||
|
const loggedUser = await userAuthRepository.findOne({
|
||||||
|
where: { id: 1 },
|
||||||
|
relations: { subscription: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (loggedUser) {
|
||||||
|
return {
|
||||||
|
...loggedUser,
|
||||||
|
id: loggedUser.userId,
|
||||||
|
username: "",
|
||||||
|
bio: "",
|
||||||
|
profileVisibility: "PUBLIC" as ProfileVisibility,
|
||||||
|
subscription: loggedUser.subscription
|
||||||
|
? {
|
||||||
|
id: loggedUser.subscription.subscriptionId,
|
||||||
|
status: loggedUser.subscription.status,
|
||||||
|
plan: {
|
||||||
|
id: loggedUser.subscription.planId,
|
||||||
|
name: loggedUser.subscription.planName,
|
||||||
|
},
|
||||||
|
expiresAt: loggedUser.subscription.expiresAt,
|
||||||
|
}
|
||||||
|
: null,
|
||||||
|
} as UserDetails;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -42,6 +42,7 @@ interface AchievementSummaryProps {
|
|||||||
function AchievementSummary({ user, isComparison }: AchievementSummaryProps) {
|
function AchievementSummary({ user, isComparison }: AchievementSummaryProps) {
|
||||||
const { t } = useTranslation("achievement");
|
const { t } = useTranslation("achievement");
|
||||||
const { userDetails, hasActiveSubscription } = useUserDetails();
|
const { userDetails, hasActiveSubscription } = useUserDetails();
|
||||||
|
const { handleClickOpenCheckout } = useContext(gameDetailsContext);
|
||||||
|
|
||||||
const getProfileImage = (
|
const getProfileImage = (
|
||||||
user: Pick<UserInfo, "profileImageUrl" | "displayName">
|
user: Pick<UserInfo, "profileImageUrl" | "displayName">
|
||||||
@ -90,7 +91,12 @@ function AchievementSummary({ user, isComparison }: AchievementSummaryProps) {
|
|||||||
>
|
>
|
||||||
<LockIcon size={24} />
|
<LockIcon size={24} />
|
||||||
<h3>
|
<h3>
|
||||||
<Link to={""}>{t("subscription_needed")}</Link>
|
<button
|
||||||
|
className={styles.subscriptionRequiredButton}
|
||||||
|
onClick={handleClickOpenCheckout}
|
||||||
|
>
|
||||||
|
{t("subscription_needed")}
|
||||||
|
</button>
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -207,3 +207,16 @@ export const profileAvatarSmall = style({
|
|||||||
position: "relative",
|
position: "relative",
|
||||||
objectFit: "cover",
|
objectFit: "cover",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const subscriptionRequiredButton = style({
|
||||||
|
textDecoration: "none",
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
width: "100%",
|
||||||
|
gap: `${SPACING_UNIT / 2}px`,
|
||||||
|
color: vars.color.body,
|
||||||
|
cursor: "pointer",
|
||||||
|
":hover": {
|
||||||
|
textDecoration: "underline",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import { useCallback, useEffect, useRef, useState } from "react";
|
||||||
import achievementSound from "@renderer/assets/audio/achievement.wav";
|
import achievementSound from "@renderer/assets/audio/achievement.wav";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import * as styles from "./achievement-notification.css";
|
import * as styles from "./achievement-notification.css";
|
||||||
@ -24,11 +24,10 @@ export function AchievementNotification() {
|
|||||||
const closingAnimation = useRef(-1);
|
const closingAnimation = useRef(-1);
|
||||||
const visibleAnimation = useRef(-1);
|
const visibleAnimation = useRef(-1);
|
||||||
|
|
||||||
const audio = useMemo(() => {
|
const playAudio = useCallback(() => {
|
||||||
const audio = new Audio(achievementSound);
|
const audio = new Audio(achievementSound);
|
||||||
audio.volume = 0.2;
|
audio.volume = 0.2;
|
||||||
audio.preload = "auto";
|
audio.play();
|
||||||
return audio;
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -47,14 +46,14 @@ export function AchievementNotification() {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
audio.play();
|
playAudio();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unsubscribe();
|
unsubscribe();
|
||||||
};
|
};
|
||||||
}, [audio]);
|
}, [playAudio]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const unsubscribe = window.electron.onAchievementUnlocked(
|
const unsubscribe = window.electron.onAchievementUnlocked(
|
||||||
@ -63,14 +62,14 @@ export function AchievementNotification() {
|
|||||||
|
|
||||||
setAchievements((ach) => ach.concat(achievements));
|
setAchievements((ach) => ach.concat(achievements));
|
||||||
|
|
||||||
audio.play();
|
playAudio();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unsubscribe();
|
unsubscribe();
|
||||||
};
|
};
|
||||||
}, [audio]);
|
}, [playAudio]);
|
||||||
|
|
||||||
const hasAchievementsPending = achievements.length > 0;
|
const hasAchievementsPending = achievements.length > 0;
|
||||||
|
|
||||||
|
@ -39,4 +39,5 @@ export enum Cracker {
|
|||||||
_3dm = "3dm",
|
_3dm = "3dm",
|
||||||
flt = "FLT",
|
flt = "FLT",
|
||||||
rle = "RLE",
|
rle = "RLE",
|
||||||
|
razor1911 = "RAZOR1911",
|
||||||
}
|
}
|
||||||
|
@ -238,7 +238,7 @@ export interface Subscription {
|
|||||||
id: string;
|
id: string;
|
||||||
status: SubscriptionStatus;
|
status: SubscriptionStatus;
|
||||||
plan: { id: string; name: string };
|
plan: { id: string; name: string };
|
||||||
expiresAt: Date | null;
|
expiresAt: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UserDetails {
|
export interface UserDetails {
|
||||||
|
Loading…
Reference in New Issue
Block a user