mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-02 16:23:48 +03:00
feat: adding bypass for region blocks
This commit is contained in:
parent
a2790190e6
commit
1c7911c531
@ -2,7 +2,7 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
[<img src="./resources/icon.png" width="144"/>](https://hydralauncher.site)
|
||||
[<img src="./resources/icon.png" width="144"/>](https://hydralauncher.site)
|
||||
|
||||
<h1 align="center">Hydra Launcher</h1>
|
||||
|
||||
@ -10,15 +10,15 @@
|
||||
<strong>Hydra é um Launcher de Jogos com seu próprio cliente de bittorrent integrado e um wrapper autogerenciado para busca de repacks.</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)
|
||||
[![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)
|
||||
[![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)
|
||||
|
||||
![Hydra Catalogue](./docs/screenshot.png)
|
||||
![Hydra Catalogue](./docs/screenshot.png)
|
||||
|
||||
</div>
|
||||
|
||||
|
20
README.ru.md
20
README.ru.md
@ -2,7 +2,7 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
[<img src="./resources/icon.png" width="144"/>](https://hydralauncher.site)
|
||||
[<img src="./resources/icon.png" width="144"/>](https://hydralauncher.site)
|
||||
|
||||
<h1 align="center">Hydra Launcher</h1>
|
||||
|
||||
@ -10,15 +10,15 @@
|
||||
<strong>Hydra - это игровой лаунчер с собственным встроенным клиентом BitTorrent и самостоятельным scraper`ом для репаков.</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)
|
||||
[![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)
|
||||
[![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)
|
||||
|
||||
![Hydra Catalogue](./docs/screenshot.png)
|
||||
![Hydra Catalogue](./docs/screenshot.png)
|
||||
|
||||
</div>
|
||||
|
||||
@ -67,8 +67,8 @@
|
||||
Чтобы установить, выполните следующие шаги:
|
||||
|
||||
1. Скачайте последнюю версию Hydra с [страницы релизов](https://github.com/hydralauncher/hydra/releases/latest).
|
||||
- Загрузите только .exe, если хотите установить Hydra на Windows.
|
||||
- Загрузите .deb или .rpm или .zip, если хотите установить Hydra на Linux (в зависимости от вашего дистрибутива Linux).
|
||||
- Загрузите только .exe, если хотите установить Hydra на Windows.
|
||||
- Загрузите .deb или .rpm или .zip, если хотите установить Hydra на Linux (в зависимости от вашего дистрибутива Linux).
|
||||
2. Запустите скачанный файл.
|
||||
3. Наслаждайтесь Hydra!
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<div align="center">
|
||||
|
||||
[<img src="./resources/icon.png" width="144"/>](https://hydralauncher.site)
|
||||
[<img src="./resources/icon.png" width="144"/>](https://hydralauncher.site)
|
||||
|
||||
<h1 align="center">Hydra Launcher</h1>
|
||||
|
||||
@ -10,15 +10,15 @@
|
||||
<strong>Hydra - це ігровий лаунчер з власним вбудованим bittorrent-клієнтом і самокерованим збирачем репаків.</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)
|
||||
[![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)
|
||||
[![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)
|
||||
|
||||
![Hydra Catalogue](./docs/screenshot.png)
|
||||
![Hydra Catalogue](./docs/screenshot.png)
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -96,7 +96,8 @@
|
||||
"dont_show_it_again": "Don't show it again",
|
||||
"copy_to_clipboard": "Copy",
|
||||
"copied_to_clipboard": "Copied",
|
||||
"got_it": "Got it"
|
||||
"got_it": "Got it",
|
||||
"no_shop_details": "Could not retrieve shop details."
|
||||
},
|
||||
"activation": {
|
||||
"title": "Activate Hydra",
|
||||
|
@ -1,175 +1,174 @@
|
||||
{
|
||||
"home": {
|
||||
"featured": "Uitgelicht",
|
||||
"recently_added": "Recent Toegevoegd",
|
||||
"trending": "Trending",
|
||||
"surprise_me": "Verrasing",
|
||||
"no_results": "Geen resultaten gevonden"
|
||||
},
|
||||
"sidebar": {
|
||||
"catalogue": "catalogus",
|
||||
"downloads": "Downloads",
|
||||
"settings": "Instellingen",
|
||||
"my_library": "Mijn Bibliotheek",
|
||||
"downloading_metadata": "{{title}} (Downloading metadata…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Folders checken…)",
|
||||
"paused": "{{title}} (Gepauzeerd)",
|
||||
"downloading": "{{title}} ({{percentage}} - Downloading…)",
|
||||
"filter": "Filter Bibliotheek",
|
||||
"follow_us": "volg ons",
|
||||
"home": "Home",
|
||||
"discord": "Volg onze Discord",
|
||||
"telegram": "Volg onze Telegram",
|
||||
"x": "Volg ons op X",
|
||||
"github": "Contribute op GitHub"
|
||||
},
|
||||
"header": {
|
||||
"search": "Zoek spellen",
|
||||
"home": "Home",
|
||||
"catalogue": "Bibliotheek",
|
||||
"downloads": "Downloads",
|
||||
"search_results": "Zoek resultaten",
|
||||
"settings": "Instellingen"
|
||||
},
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "Geen Downloads bezig",
|
||||
"downloading_metadata": "Downloading {{title}} metadata…",
|
||||
"checking_files": "Checking {{title}} files… ({{percentage}} complete)",
|
||||
"downloading": "Downloading {{title}}… ({{percentage}} complete) - Conclusion {{eta}} - {{speed}}"
|
||||
},
|
||||
"catalogue": {
|
||||
"next_page": "Volgende Pagina",
|
||||
"previous_page": "Vorige Pagina"
|
||||
},
|
||||
"game_details": {
|
||||
"open_download_options": "Open download Instellingen",
|
||||
"download_options_zero": "Geen download Instellingen",
|
||||
"download_options_one": "{{count}} download Instellingen",
|
||||
"download_options_other": "{{count}} download Instellingen",
|
||||
"updated_at": "Geupdate {{updated_at}}",
|
||||
"install": "Instaleer",
|
||||
"resume": "Verder gaan",
|
||||
"pause": "Pauze",
|
||||
"cancel": "Stoppen",
|
||||
"remove": "Verwijderen",
|
||||
"remove_from_list": "Verwijdere van lijst",
|
||||
"space_left_on_disk": "{{space}} Over op schijf",
|
||||
"eta": "Conclusie {{eta}}",
|
||||
"downloading_metadata": "Downloading metadata…",
|
||||
"checking_files": "Files nakijken…",
|
||||
"filter": "Filter repacks",
|
||||
"requirements": "Systeem vereisten",
|
||||
"minimum": "Minimaal",
|
||||
"recommended": "Aanbevolen",
|
||||
"no_minimum_requirements": "{{title}} biedt geen informatie over de minimale vereisten",
|
||||
"no_recommended_requirements": "{{title}} biedt geen informatie over aanbevolen vereisten",
|
||||
"paused_progress": "{{progress}} (Paused)",
|
||||
"release_date": "Uitgebracht op {{date}}",
|
||||
"publisher": "Gepubliceerd door {{publisher}}",
|
||||
"copy_link_to_clipboard": "Kopieer link",
|
||||
"copied_link_to_clipboard": "Link Gekopieerd",
|
||||
"hours": "uren",
|
||||
"minutes": "minuten",
|
||||
"amount_hours": "{{amount}} uren",
|
||||
"amount_minutes": "{{amount}} minuten",
|
||||
"accuracy": "{{accuracy}}% nauwkeurigheid",
|
||||
"add_to_library": "Toevoegen aan bibliotheek",
|
||||
"remove_from_library": "Verwijderen uit bibliotheek",
|
||||
"no_downloads": "Geen downloads beschikbaar",
|
||||
"play_time": "Voor gespeeld {{amount}}",
|
||||
"last_time_played": "Laatst gespeeld {{period}}",
|
||||
"not_played_yet": "Je hebt nog niet gespeeld {{title}}",
|
||||
"next_suggestion": "Volgende suggestie",
|
||||
"play": "Speel",
|
||||
"deleting": "Installatieprogramma verwijderen…",
|
||||
"close": "Sluiten",
|
||||
"playing_now": "Speel nu",
|
||||
"change": "Verander",
|
||||
"repacks_modal_description": "Kies de herverpakking die u wilt downloaden",
|
||||
"downloads_path": "Downloads path",
|
||||
"select_folder_hint": "Om de standaardmap te wijzigen, gaat u naar <0>instellingen</0>",
|
||||
"download_now": "Download nu",
|
||||
"installation_instructions": "Installatie instructies",
|
||||
"installation_instructions_description": "Er zijn extra stappen vereist om deze game te installeren",
|
||||
"online_fix_instruction": "OnlineFix-spellen vereisen dat een wachtwoord wordt uitgepakt. Gebruik indien nodig het volgende wachtwoord:",
|
||||
"dodi_installation_instruction": "Wanneer u het DODI-installatieprogramma opent, drukt u op de toets omhoog <0 /> op uw toetsenbord om het installatieproces te starten:",
|
||||
"dont_show_it_again": "Laat het niet meer zien",
|
||||
"copy_to_clipboard": "Kopiëren",
|
||||
"copied_to_clipboard": "Gekopieerd",
|
||||
"got_it": "Begrepen"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Activeer Hydra",
|
||||
"installation_id": "Installatie-ID:",
|
||||
"enter_activation_code": "Voer uw activatiecode in",
|
||||
"message": "Als je niet weet waar je dit moet vragen, dan moet je dit niet hebben.",
|
||||
"activate": "Activeren",
|
||||
"loading": "Bezig met laden…"
|
||||
},
|
||||
"downloads": {
|
||||
"resume": "Hervatten",
|
||||
"pause": "Pauze",
|
||||
"eta": "Conclusie{{eta}}",
|
||||
"paused": "Gepauzeerd",
|
||||
"verifying": "Verifiëren…",
|
||||
"completed_at": "Voltooid binnen {{date}}",
|
||||
"completed": "Voltooid",
|
||||
"cancelled": "Geannuleerd",
|
||||
"download_again": "Opnieuw downloaden",
|
||||
"cancel": "Annuleren",
|
||||
"filter": "Filter gedownloade games",
|
||||
"remove": "Verwijderen",
|
||||
"downloading_metadata": "Metagegevens downloaden",
|
||||
"checking_files": "Bestanden controleren",
|
||||
"starting_download": "download starten",
|
||||
"deleting": "Installatieprogramma verwijderen…",
|
||||
"delete": "Installatieprogramma verwijderen",
|
||||
"remove_from_list": "Verwijderen",
|
||||
"delete_modal_title": "Weet je het zeker?",
|
||||
"delete_modal_description": "Hiermee worden alle installatiebestanden van uw computer verwijderd",
|
||||
"install": "Installeren",
|
||||
"real_debrid": "Real Debrid",
|
||||
"torrent": "Torrent"
|
||||
},
|
||||
"settings": {
|
||||
"downloads_path": "Downloadpad",
|
||||
"change": "Update",
|
||||
"notifications": "Meldingen",
|
||||
"enable_download_notifications": "Wanneer een download voltooid is",
|
||||
"enable_repack_list_notifications": "Wanneer een nieuwe herverpakking wordt toegevoegd",
|
||||
"telemetry": "Telemetrie",
|
||||
"telemetry_description": "Schakel anonieme gebruiksstatistieken in",
|
||||
"real_debrid_api_token_description": "Real Debrid API token",
|
||||
"quit_app_instead_hiding": "Sluit Hydra af in plaats van te minimaliseren naar de lade",
|
||||
"launch_with_system": "Start Hydra bij het opstarten van het systeem",
|
||||
"general": "Algemeen",
|
||||
"behavior": "Gedrag",
|
||||
"enable_real_debrid": "Enable Real Debrid",
|
||||
"real_debrid": "Real Debrid",
|
||||
"real_debrid_api_token_hint": "U kunt uw API-sleutel <0>hier</0> verkrijgen.",
|
||||
"save_changes": "Wijzigingen opslaan"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Download compleet",
|
||||
"game_ready_to_install": "{{title}} is klaar om te installeren",
|
||||
"repack_list_updated": "Herpaklijst bijgewerkt",
|
||||
"repack_count_one": "{{count}} herverpakking toegevoegd",
|
||||
"repack_count_other": "{{count}} herverpakkingen toegevoegd"
|
||||
},
|
||||
"system_tray": {
|
||||
"open": "Open Hydra",
|
||||
"quit": "Verlaten"
|
||||
},
|
||||
"game_card": {
|
||||
"no_downloads": "Geen downloads beschikbaar"
|
||||
},
|
||||
"binary_not_found_modal": {
|
||||
"title": "Programma's niet geïnstalleerd",
|
||||
"description": "Er zijn geen uitvoerbare bestanden van Wine of Lutris gevonden op uw systeem",
|
||||
"instructions": "Controleer de juiste manier om ze op je Linux-distro te installeren, zodat de game normaal kan werken"
|
||||
},
|
||||
"modal": {
|
||||
"close": "Knop Sluiten"
|
||||
}
|
||||
"home": {
|
||||
"featured": "Uitgelicht",
|
||||
"recently_added": "Recent Toegevoegd",
|
||||
"trending": "Trending",
|
||||
"surprise_me": "Verrasing",
|
||||
"no_results": "Geen resultaten gevonden"
|
||||
},
|
||||
"sidebar": {
|
||||
"catalogue": "catalogus",
|
||||
"downloads": "Downloads",
|
||||
"settings": "Instellingen",
|
||||
"my_library": "Mijn Bibliotheek",
|
||||
"downloading_metadata": "{{title}} (Downloading metadata…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Folders checken…)",
|
||||
"paused": "{{title}} (Gepauzeerd)",
|
||||
"downloading": "{{title}} ({{percentage}} - Downloading…)",
|
||||
"filter": "Filter Bibliotheek",
|
||||
"follow_us": "volg ons",
|
||||
"home": "Home",
|
||||
"discord": "Volg onze Discord",
|
||||
"telegram": "Volg onze Telegram",
|
||||
"x": "Volg ons op X",
|
||||
"github": "Contribute op GitHub"
|
||||
},
|
||||
"header": {
|
||||
"search": "Zoek spellen",
|
||||
"home": "Home",
|
||||
"catalogue": "Bibliotheek",
|
||||
"downloads": "Downloads",
|
||||
"search_results": "Zoek resultaten",
|
||||
"settings": "Instellingen"
|
||||
},
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "Geen Downloads bezig",
|
||||
"downloading_metadata": "Downloading {{title}} metadata…",
|
||||
"checking_files": "Checking {{title}} files… ({{percentage}} complete)",
|
||||
"downloading": "Downloading {{title}}… ({{percentage}} complete) - Conclusion {{eta}} - {{speed}}"
|
||||
},
|
||||
"catalogue": {
|
||||
"next_page": "Volgende Pagina",
|
||||
"previous_page": "Vorige Pagina"
|
||||
},
|
||||
"game_details": {
|
||||
"open_download_options": "Open download Instellingen",
|
||||
"download_options_zero": "Geen download Instellingen",
|
||||
"download_options_one": "{{count}} download Instellingen",
|
||||
"download_options_other": "{{count}} download Instellingen",
|
||||
"updated_at": "Geupdate {{updated_at}}",
|
||||
"install": "Instaleer",
|
||||
"resume": "Verder gaan",
|
||||
"pause": "Pauze",
|
||||
"cancel": "Stoppen",
|
||||
"remove": "Verwijderen",
|
||||
"remove_from_list": "Verwijdere van lijst",
|
||||
"space_left_on_disk": "{{space}} Over op schijf",
|
||||
"eta": "Conclusie {{eta}}",
|
||||
"downloading_metadata": "Downloading metadata…",
|
||||
"checking_files": "Files nakijken…",
|
||||
"filter": "Filter repacks",
|
||||
"requirements": "Systeem vereisten",
|
||||
"minimum": "Minimaal",
|
||||
"recommended": "Aanbevolen",
|
||||
"no_minimum_requirements": "{{title}} biedt geen informatie over de minimale vereisten",
|
||||
"no_recommended_requirements": "{{title}} biedt geen informatie over aanbevolen vereisten",
|
||||
"paused_progress": "{{progress}} (Paused)",
|
||||
"release_date": "Uitgebracht op {{date}}",
|
||||
"publisher": "Gepubliceerd door {{publisher}}",
|
||||
"copy_link_to_clipboard": "Kopieer link",
|
||||
"copied_link_to_clipboard": "Link Gekopieerd",
|
||||
"hours": "uren",
|
||||
"minutes": "minuten",
|
||||
"amount_hours": "{{amount}} uren",
|
||||
"amount_minutes": "{{amount}} minuten",
|
||||
"accuracy": "{{accuracy}}% nauwkeurigheid",
|
||||
"add_to_library": "Toevoegen aan bibliotheek",
|
||||
"remove_from_library": "Verwijderen uit bibliotheek",
|
||||
"no_downloads": "Geen downloads beschikbaar",
|
||||
"play_time": "Voor gespeeld {{amount}}",
|
||||
"last_time_played": "Laatst gespeeld {{period}}",
|
||||
"not_played_yet": "Je hebt nog niet gespeeld {{title}}",
|
||||
"next_suggestion": "Volgende suggestie",
|
||||
"play": "Speel",
|
||||
"deleting": "Installatieprogramma verwijderen…",
|
||||
"close": "Sluiten",
|
||||
"playing_now": "Speel nu",
|
||||
"change": "Verander",
|
||||
"repacks_modal_description": "Kies de herverpakking die u wilt downloaden",
|
||||
"downloads_path": "Downloads path",
|
||||
"select_folder_hint": "Om de standaardmap te wijzigen, gaat u naar <0>instellingen</0>",
|
||||
"download_now": "Download nu",
|
||||
"installation_instructions": "Installatie instructies",
|
||||
"installation_instructions_description": "Er zijn extra stappen vereist om deze game te installeren",
|
||||
"online_fix_instruction": "OnlineFix-spellen vereisen dat een wachtwoord wordt uitgepakt. Gebruik indien nodig het volgende wachtwoord:",
|
||||
"dodi_installation_instruction": "Wanneer u het DODI-installatieprogramma opent, drukt u op de toets omhoog <0 /> op uw toetsenbord om het installatieproces te starten:",
|
||||
"dont_show_it_again": "Laat het niet meer zien",
|
||||
"copy_to_clipboard": "Kopiëren",
|
||||
"copied_to_clipboard": "Gekopieerd",
|
||||
"got_it": "Begrepen"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Activeer Hydra",
|
||||
"installation_id": "Installatie-ID:",
|
||||
"enter_activation_code": "Voer uw activatiecode in",
|
||||
"message": "Als je niet weet waar je dit moet vragen, dan moet je dit niet hebben.",
|
||||
"activate": "Activeren",
|
||||
"loading": "Bezig met laden…"
|
||||
},
|
||||
"downloads": {
|
||||
"resume": "Hervatten",
|
||||
"pause": "Pauze",
|
||||
"eta": "Conclusie{{eta}}",
|
||||
"paused": "Gepauzeerd",
|
||||
"verifying": "Verifiëren…",
|
||||
"completed_at": "Voltooid binnen {{date}}",
|
||||
"completed": "Voltooid",
|
||||
"cancelled": "Geannuleerd",
|
||||
"download_again": "Opnieuw downloaden",
|
||||
"cancel": "Annuleren",
|
||||
"filter": "Filter gedownloade games",
|
||||
"remove": "Verwijderen",
|
||||
"downloading_metadata": "Metagegevens downloaden",
|
||||
"checking_files": "Bestanden controleren",
|
||||
"starting_download": "download starten",
|
||||
"deleting": "Installatieprogramma verwijderen…",
|
||||
"delete": "Installatieprogramma verwijderen",
|
||||
"remove_from_list": "Verwijderen",
|
||||
"delete_modal_title": "Weet je het zeker?",
|
||||
"delete_modal_description": "Hiermee worden alle installatiebestanden van uw computer verwijderd",
|
||||
"install": "Installeren",
|
||||
"real_debrid": "Real Debrid",
|
||||
"torrent": "Torrent"
|
||||
},
|
||||
"settings": {
|
||||
"downloads_path": "Downloadpad",
|
||||
"change": "Update",
|
||||
"notifications": "Meldingen",
|
||||
"enable_download_notifications": "Wanneer een download voltooid is",
|
||||
"enable_repack_list_notifications": "Wanneer een nieuwe herverpakking wordt toegevoegd",
|
||||
"telemetry": "Telemetrie",
|
||||
"telemetry_description": "Schakel anonieme gebruiksstatistieken in",
|
||||
"real_debrid_api_token_description": "Real Debrid API token",
|
||||
"quit_app_instead_hiding": "Sluit Hydra af in plaats van te minimaliseren naar de lade",
|
||||
"launch_with_system": "Start Hydra bij het opstarten van het systeem",
|
||||
"general": "Algemeen",
|
||||
"behavior": "Gedrag",
|
||||
"enable_real_debrid": "Enable Real Debrid",
|
||||
"real_debrid": "Real Debrid",
|
||||
"real_debrid_api_token_hint": "U kunt uw API-sleutel <0>hier</0> verkrijgen.",
|
||||
"save_changes": "Wijzigingen opslaan"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Download compleet",
|
||||
"game_ready_to_install": "{{title}} is klaar om te installeren",
|
||||
"repack_list_updated": "Herpaklijst bijgewerkt",
|
||||
"repack_count_one": "{{count}} herverpakking toegevoegd",
|
||||
"repack_count_other": "{{count}} herverpakkingen toegevoegd"
|
||||
},
|
||||
"system_tray": {
|
||||
"open": "Open Hydra",
|
||||
"quit": "Verlaten"
|
||||
},
|
||||
"game_card": {
|
||||
"no_downloads": "Geen downloads beschikbaar"
|
||||
},
|
||||
"binary_not_found_modal": {
|
||||
"title": "Programma's niet geïnstalleerd",
|
||||
"description": "Er zijn geen uitvoerbare bestanden van Wine of Lutris gevonden op uw systeem",
|
||||
"instructions": "Controleer de juiste manier om ze op je Linux-distro te installeren, zodat de game normaal kan werken"
|
||||
},
|
||||
"modal": {
|
||||
"close": "Knop Sluiten"
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,165 +1,164 @@
|
||||
{
|
||||
"home": {
|
||||
"featured": "Öne çıkan",
|
||||
"recently_added": "Son eklenen",
|
||||
"trending": "Popüler",
|
||||
"surprise_me": "Şaşırt beni",
|
||||
"no_results": "Sonuç bulunamadı"
|
||||
},
|
||||
"sidebar": {
|
||||
"catalogue": "Katalog",
|
||||
"downloads": "İndirmeler",
|
||||
"settings": "Ayarlar",
|
||||
"my_library": "Kütüphane",
|
||||
"downloading_metadata": "{{title}} (Metadata indiriliyor…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Dosyalar kontrol ediliyor…)",
|
||||
"paused": "{{title}} (Duraklatıldı)",
|
||||
"downloading": "{{title}} ({{percentage}} - İndiriliyor…)",
|
||||
"filter": "Kütüphaneyi filtrele",
|
||||
"follow_us": "Bizi takip et",
|
||||
"home": "Ana menü",
|
||||
"discord": "Discord'umuza katıl",
|
||||
"telegram": "Telegram'umuza katıl",
|
||||
"x": "X'te bizi takip et",
|
||||
"github": "GitHub'da bize katkı yap"
|
||||
},
|
||||
"header": {
|
||||
"search": "Ara",
|
||||
"home": "Ana menü",
|
||||
"catalogue": "Katalog",
|
||||
"downloads": "İndirmeler",
|
||||
"search_results": "Arama sonuçları",
|
||||
"settings": "Ayarlar"
|
||||
},
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "İndirilen bir şey yok",
|
||||
"downloading_metadata": "{{title}} metadatası indiriliyor…",
|
||||
"checking_files": "{{title}} dosyaları kontrol ediliyor… ({{percentage}} tamamlandı)",
|
||||
"downloading": "{{title}} indiriliyor… ({{percentage}} tamamlandı) - Bitiş {{eta}} - {{speed}}"
|
||||
},
|
||||
"catalogue": {
|
||||
"next_page": "Sonraki sayfa",
|
||||
"previous_page": "Önceki sayfa"
|
||||
},
|
||||
"game_details": {
|
||||
"open_download_options": "İndirme seçeneklerini aç",
|
||||
"download_options_zero": "İndirme seçeneği yok",
|
||||
"download_options_one": "{{count}} indirme seçeneği",
|
||||
"download_options_other": "{{count}} indirme seçeneği",
|
||||
"updated_at": "{{updated_at}} güncellendi",
|
||||
"install": "İndir",
|
||||
"resume": "Devam et",
|
||||
"pause": "Duraklat",
|
||||
"cancel": "İptal et",
|
||||
"remove": "Sil",
|
||||
"remove_from_list": "Sil",
|
||||
"space_left_on_disk": "Diskte {{space}} yer kaldı",
|
||||
"eta": "Bitiş {{eta}}",
|
||||
"downloading_metadata": "Metadata indiriliyor…",
|
||||
"checking_files": "Dosyalar kontrol ediliyor…",
|
||||
"filter": "Repackleri filtrele",
|
||||
"requirements": "Sistem gereksinimleri",
|
||||
"minimum": "Minimum",
|
||||
"recommended": "Önerilen",
|
||||
"no_minimum_requirements": "{{title}} minimum sistem gereksinim bilgilerini karşılamıyor",
|
||||
"no_recommended_requirements": "{{title}} önerilen sistem gereksinim bilgilerini karşılamıyor",
|
||||
"paused_progress": "{{progress}} (Duraklatıldı)",
|
||||
"release_date": "{{date}} tarihinde çıktı",
|
||||
"publisher": "{{publisher}} tarihinde yayınlandı",
|
||||
"copy_link_to_clipboard": "Link'i kopyala",
|
||||
"copied_link_to_clipboard": "Link kopyalandı",
|
||||
"hours": "saatler",
|
||||
"minutes": "dakikalar",
|
||||
"amount_hours": "{{amount}} saat",
|
||||
"amount_minutes": "{{amount}} dakika",
|
||||
"accuracy": "%{{accuracy}} doğruluk",
|
||||
"add_to_library": "Kütüphaneye ekle",
|
||||
"remove_from_library": "Kütüphaneden kaldır",
|
||||
"no_downloads": "İndirme yok",
|
||||
"play_time": "{{amount}} oynandı",
|
||||
"last_time_played": "Son oynanan {{period}}",
|
||||
"not_played_yet": "Bu {{title}} hiç oynanmadı",
|
||||
"next_suggestion": "Sıradaki öneri",
|
||||
"play": "Oyna",
|
||||
"deleting": "Installer siliniyor…",
|
||||
"close": "Kapat",
|
||||
"playing_now": "Şimdi oynanıyor",
|
||||
"change": "Değiştir",
|
||||
"repacks_modal_description": "İndirmek istediğiiniz repacki seçin",
|
||||
"downloads_path": "İndirme yolu",
|
||||
"select_folder_hint": "Varsayılan klasörü değiştirmek için ulaşmanız gereken ayar",
|
||||
"settings": "Ayarlar",
|
||||
"download_now": "Şimdi",
|
||||
"installation_instructions": "Kurulum",
|
||||
"installation_instructions_description": "Bu oyunu kurmak için ek adımlar gerekiyor",
|
||||
"online_fix_instruction": "OnlineFix oyunlarını ayıklamak için parola gerekiyor. Gerekli olduğunda bu parolayı kullanın:",
|
||||
"dodi_installation_instruction": "Dodi installerını açtığınızda, kurulumu başlatmak için bu tuşa basın <0 />:",
|
||||
"dont_show_it_again": "Tekrar gösterme",
|
||||
"copy_to_clipboard": "Kopyala",
|
||||
"copied_to_clipboard": "Kopyalandı",
|
||||
"got_it": "Tamam"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Hydra'yı aktif et",
|
||||
"installation_id": "Kurulum ID'si:",
|
||||
"enter_activation_code": "Aktifleştirme kodunuzu girin",
|
||||
"message": "Bunu nerede soracağınızı bilmiyorsanız, buna sahip olmamanız gerekiyor.",
|
||||
"activate": "Aktif et",
|
||||
"loading": "Yükleniyor…"
|
||||
},
|
||||
"downloads": {
|
||||
"resume": "Devam et",
|
||||
"pause": "Duraklat",
|
||||
"eta": "Bitiş {{eta}}",
|
||||
"paused": "Duraklatıldı",
|
||||
"verifying": "Doğrulanıyor…",
|
||||
"completed_at": "{{date}} tarihinde tamamlanacak",
|
||||
"completed": "Tamamlandı",
|
||||
"cancelled": "İptal edildi",
|
||||
"download_again": "Tekrar indir",
|
||||
"cancel": "İptal et",
|
||||
"filter": "Yüklü oyunları filtrele",
|
||||
"remove": "Kaldır",
|
||||
"downloading_metadata": "Metadata indiriliyor…",
|
||||
"checking_files": "Dosyalar kontrol ediliyor…",
|
||||
"starting_download": "İndirme başlatılıyor…",
|
||||
"deleting": "Installer siliniyor…",
|
||||
"delete": "Installer'ı sil",
|
||||
"remove_from_list": "Kaldır",
|
||||
"delete_modal_title": "Emin misiniz?",
|
||||
"delete_modal_description": "Bu bilgisayarınızdan tüm kurulum dosyalarını silecek",
|
||||
"install": "Kur"
|
||||
},
|
||||
"settings": {
|
||||
"downloads_path": "İndirme yolu",
|
||||
"change": "Güncelle",
|
||||
"notifications": "Bildirimler",
|
||||
"enable_download_notifications": "Bir indirme bittiğinde",
|
||||
"enable_repack_list_notifications": "Yeni bir repack eklendiğinde",
|
||||
"telemetry": "Telemetri",
|
||||
"telemetry_description": "Anonim kullanım istatistiklerini aktifleştir"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "İndirme tamamlandı",
|
||||
"game_ready_to_install": "{{title}} kuruluma hazır",
|
||||
"repack_list_updated": "Repack listesi güncellendi",
|
||||
"repack_count_one": "{{count}} yeni repack eklendi",
|
||||
"repack_count_other": "{{count}} yeni repack eklendi"
|
||||
},
|
||||
"system_tray": {
|
||||
"open": "Hydra'yı aç",
|
||||
"quit": "Çık"
|
||||
},
|
||||
"game_card": {
|
||||
"no_downloads": "İndirme mevcut değil"
|
||||
},
|
||||
"binary_not_found_modal": {
|
||||
"title": "Programlar yüklü değil",
|
||||
"description": "Sisteminizde Wine veya Lutris çalıştırılabiliri bulunamadı",
|
||||
"instructions": "Oyunları düzgün şekilde çalıştırmak için Linux distronuza bunlardan birini nasıl yükleyebileceğinize bakın"
|
||||
},
|
||||
"modal": {
|
||||
"close": "Kapat tuşu"
|
||||
}
|
||||
"home": {
|
||||
"featured": "Öne çıkan",
|
||||
"recently_added": "Son eklenen",
|
||||
"trending": "Popüler",
|
||||
"surprise_me": "Şaşırt beni",
|
||||
"no_results": "Sonuç bulunamadı"
|
||||
},
|
||||
"sidebar": {
|
||||
"catalogue": "Katalog",
|
||||
"downloads": "İndirmeler",
|
||||
"settings": "Ayarlar",
|
||||
"my_library": "Kütüphane",
|
||||
"downloading_metadata": "{{title}} (Metadata indiriliyor…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Dosyalar kontrol ediliyor…)",
|
||||
"paused": "{{title}} (Duraklatıldı)",
|
||||
"downloading": "{{title}} ({{percentage}} - İndiriliyor…)",
|
||||
"filter": "Kütüphaneyi filtrele",
|
||||
"follow_us": "Bizi takip et",
|
||||
"home": "Ana menü",
|
||||
"discord": "Discord'umuza katıl",
|
||||
"telegram": "Telegram'umuza katıl",
|
||||
"x": "X'te bizi takip et",
|
||||
"github": "GitHub'da bize katkı yap"
|
||||
},
|
||||
"header": {
|
||||
"search": "Ara",
|
||||
"home": "Ana menü",
|
||||
"catalogue": "Katalog",
|
||||
"downloads": "İndirmeler",
|
||||
"search_results": "Arama sonuçları",
|
||||
"settings": "Ayarlar"
|
||||
},
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "İndirilen bir şey yok",
|
||||
"downloading_metadata": "{{title}} metadatası indiriliyor…",
|
||||
"checking_files": "{{title}} dosyaları kontrol ediliyor… ({{percentage}} tamamlandı)",
|
||||
"downloading": "{{title}} indiriliyor… ({{percentage}} tamamlandı) - Bitiş {{eta}} - {{speed}}"
|
||||
},
|
||||
"catalogue": {
|
||||
"next_page": "Sonraki sayfa",
|
||||
"previous_page": "Önceki sayfa"
|
||||
},
|
||||
"game_details": {
|
||||
"open_download_options": "İndirme seçeneklerini aç",
|
||||
"download_options_zero": "İndirme seçeneği yok",
|
||||
"download_options_one": "{{count}} indirme seçeneği",
|
||||
"download_options_other": "{{count}} indirme seçeneği",
|
||||
"updated_at": "{{updated_at}} güncellendi",
|
||||
"install": "İndir",
|
||||
"resume": "Devam et",
|
||||
"pause": "Duraklat",
|
||||
"cancel": "İptal et",
|
||||
"remove": "Sil",
|
||||
"remove_from_list": "Sil",
|
||||
"space_left_on_disk": "Diskte {{space}} yer kaldı",
|
||||
"eta": "Bitiş {{eta}}",
|
||||
"downloading_metadata": "Metadata indiriliyor…",
|
||||
"checking_files": "Dosyalar kontrol ediliyor…",
|
||||
"filter": "Repackleri filtrele",
|
||||
"requirements": "Sistem gereksinimleri",
|
||||
"minimum": "Minimum",
|
||||
"recommended": "Önerilen",
|
||||
"no_minimum_requirements": "{{title}} minimum sistem gereksinim bilgilerini karşılamıyor",
|
||||
"no_recommended_requirements": "{{title}} önerilen sistem gereksinim bilgilerini karşılamıyor",
|
||||
"paused_progress": "{{progress}} (Duraklatıldı)",
|
||||
"release_date": "{{date}} tarihinde çıktı",
|
||||
"publisher": "{{publisher}} tarihinde yayınlandı",
|
||||
"copy_link_to_clipboard": "Link'i kopyala",
|
||||
"copied_link_to_clipboard": "Link kopyalandı",
|
||||
"hours": "saatler",
|
||||
"minutes": "dakikalar",
|
||||
"amount_hours": "{{amount}} saat",
|
||||
"amount_minutes": "{{amount}} dakika",
|
||||
"accuracy": "%{{accuracy}} doğruluk",
|
||||
"add_to_library": "Kütüphaneye ekle",
|
||||
"remove_from_library": "Kütüphaneden kaldır",
|
||||
"no_downloads": "İndirme yok",
|
||||
"play_time": "{{amount}} oynandı",
|
||||
"last_time_played": "Son oynanan {{period}}",
|
||||
"not_played_yet": "Bu {{title}} hiç oynanmadı",
|
||||
"next_suggestion": "Sıradaki öneri",
|
||||
"play": "Oyna",
|
||||
"deleting": "Installer siliniyor…",
|
||||
"close": "Kapat",
|
||||
"playing_now": "Şimdi oynanıyor",
|
||||
"change": "Değiştir",
|
||||
"repacks_modal_description": "İndirmek istediğiiniz repacki seçin",
|
||||
"downloads_path": "İndirme yolu",
|
||||
"select_folder_hint": "Varsayılan klasörü değiştirmek için ulaşmanız gereken ayar",
|
||||
"settings": "Ayarlar",
|
||||
"download_now": "Şimdi",
|
||||
"installation_instructions": "Kurulum",
|
||||
"installation_instructions_description": "Bu oyunu kurmak için ek adımlar gerekiyor",
|
||||
"online_fix_instruction": "OnlineFix oyunlarını ayıklamak için parola gerekiyor. Gerekli olduğunda bu parolayı kullanın:",
|
||||
"dodi_installation_instruction": "Dodi installerını açtığınızda, kurulumu başlatmak için bu tuşa basın <0 />:",
|
||||
"dont_show_it_again": "Tekrar gösterme",
|
||||
"copy_to_clipboard": "Kopyala",
|
||||
"copied_to_clipboard": "Kopyalandı",
|
||||
"got_it": "Tamam"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Hydra'yı aktif et",
|
||||
"installation_id": "Kurulum ID'si:",
|
||||
"enter_activation_code": "Aktifleştirme kodunuzu girin",
|
||||
"message": "Bunu nerede soracağınızı bilmiyorsanız, buna sahip olmamanız gerekiyor.",
|
||||
"activate": "Aktif et",
|
||||
"loading": "Yükleniyor…"
|
||||
},
|
||||
"downloads": {
|
||||
"resume": "Devam et",
|
||||
"pause": "Duraklat",
|
||||
"eta": "Bitiş {{eta}}",
|
||||
"paused": "Duraklatıldı",
|
||||
"verifying": "Doğrulanıyor…",
|
||||
"completed_at": "{{date}} tarihinde tamamlanacak",
|
||||
"completed": "Tamamlandı",
|
||||
"cancelled": "İptal edildi",
|
||||
"download_again": "Tekrar indir",
|
||||
"cancel": "İptal et",
|
||||
"filter": "Yüklü oyunları filtrele",
|
||||
"remove": "Kaldır",
|
||||
"downloading_metadata": "Metadata indiriliyor…",
|
||||
"checking_files": "Dosyalar kontrol ediliyor…",
|
||||
"starting_download": "İndirme başlatılıyor…",
|
||||
"deleting": "Installer siliniyor…",
|
||||
"delete": "Installer'ı sil",
|
||||
"remove_from_list": "Kaldır",
|
||||
"delete_modal_title": "Emin misiniz?",
|
||||
"delete_modal_description": "Bu bilgisayarınızdan tüm kurulum dosyalarını silecek",
|
||||
"install": "Kur"
|
||||
},
|
||||
"settings": {
|
||||
"downloads_path": "İndirme yolu",
|
||||
"change": "Güncelle",
|
||||
"notifications": "Bildirimler",
|
||||
"enable_download_notifications": "Bir indirme bittiğinde",
|
||||
"enable_repack_list_notifications": "Yeni bir repack eklendiğinde",
|
||||
"telemetry": "Telemetri",
|
||||
"telemetry_description": "Anonim kullanım istatistiklerini aktifleştir"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "İndirme tamamlandı",
|
||||
"game_ready_to_install": "{{title}} kuruluma hazır",
|
||||
"repack_list_updated": "Repack listesi güncellendi",
|
||||
"repack_count_one": "{{count}} yeni repack eklendi",
|
||||
"repack_count_other": "{{count}} yeni repack eklendi"
|
||||
},
|
||||
"system_tray": {
|
||||
"open": "Hydra'yı aç",
|
||||
"quit": "Çık"
|
||||
},
|
||||
"game_card": {
|
||||
"no_downloads": "İndirme mevcut değil"
|
||||
},
|
||||
"binary_not_found_modal": {
|
||||
"title": "Programlar yüklü değil",
|
||||
"description": "Sisteminizde Wine veya Lutris çalıştırılabiliri bulunamadı",
|
||||
"instructions": "Oyunları düzgün şekilde çalıştırmak için Linux distronuza bunlardan birini nasıl yükleyebileceğinize bakın"
|
||||
},
|
||||
"modal": {
|
||||
"close": "Kapat tuşu"
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,167 +1,167 @@
|
||||
{
|
||||
"home": {
|
||||
"featured": "Рекомендоване",
|
||||
"recently_added": "Нове",
|
||||
"trending": "У тренді",
|
||||
"surprise_me": "Здивуй мене",
|
||||
"no_results": "Результатів не знайдено"
|
||||
},
|
||||
"sidebar": {
|
||||
"catalogue": "Каталог",
|
||||
"downloads": "Завантаження",
|
||||
"settings": "Налаштування",
|
||||
"my_library": "Бібліотека",
|
||||
"downloading_metadata": "{{title}} (Завантаження метаданих…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Перевірка файлів…)",
|
||||
"paused": "{{title}} (Призупинено)",
|
||||
"downloading": "{{title}} ({{percentage}} - Завантаження…)",
|
||||
"filter": "Фільтр бібліотеки",
|
||||
"follow_us": "Підписуйтесь на нас",
|
||||
"home": "Головна",
|
||||
"discord": "Приєднуйтесь до Discord",
|
||||
"telegram": "Приєднуйтесь до Telegram",
|
||||
"x": "Підписуйтесь на X",
|
||||
"github": "Зробіть свій внесок на GitHub"
|
||||
},
|
||||
"header": {
|
||||
"search": "Пошук",
|
||||
"home": "Головна",
|
||||
"catalogue": "Каталог",
|
||||
"downloads": "Завантаження",
|
||||
"search_results": "Результати пошуку",
|
||||
"settings": "Налаштування"
|
||||
},
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "Немає активних завантажень",
|
||||
"downloading_metadata": "Завантаження метаданих {{title}}…",
|
||||
"checking_files": "Перевірка файлів {{title}}… ({{percentage}} завершено)",
|
||||
"downloading": "Завантаження {{title}}… ({{percentage}} завершено) - Закінчення {{eta}} - {{speed}}"
|
||||
},
|
||||
"catalogue": {
|
||||
"next_page": "Наступна сторінка",
|
||||
"previous_page": "Попередня сторінка"
|
||||
},
|
||||
"game_details": {
|
||||
"open_download_options": "Відкрити варіанти завантаження",
|
||||
"download_options_zero": "Немає варіантів завантаження",
|
||||
"download_options_one": "{{count}} варіант завантаження",
|
||||
"download_options_other": "{{count}} варіантів завантаження",
|
||||
"updated_at": "Оновлено {{updated_at}}",
|
||||
"install": "Встановити",
|
||||
"resume": "Відновити",
|
||||
"pause": "Призупинити",
|
||||
"cancel": "Скасувати",
|
||||
"remove": "Видалити",
|
||||
"remove_from_list": "Видалити",
|
||||
"space_left_on_disk": "{{space}} вільно на диску",
|
||||
"eta": "Закінчення {{eta}}",
|
||||
"downloading_metadata": "Завантаження метаданих…",
|
||||
"checking_files": "Перевірка файлів…",
|
||||
"filter": "Фільтр репаків",
|
||||
"requirements": "Системні вимоги",
|
||||
"minimum": "Мінімальні",
|
||||
"recommended": "Рекомендовані",
|
||||
"no_minimum_requirements": "Для {{title}} не вказані мінімальні вимоги",
|
||||
"no_recommended_requirements": "Для {{title}} не вказані рекомендовані вимоги",
|
||||
"paused_progress": "{{progress}} (Призупинено)",
|
||||
"release_date": "Випущено {{date}}",
|
||||
"publisher": "Видавець {{publisher}}",
|
||||
"copy_link_to_clipboard": "Скопіювати посилання",
|
||||
"copied_link_to_clipboard": "Посилання скопійовано",
|
||||
"hours": "годин",
|
||||
"minutes": "хвилин",
|
||||
"amount_hours": "{{amount}} годин",
|
||||
"amount_minutes": "{{amount}} хвилин",
|
||||
"accuracy": "{{accuracy}}% точність",
|
||||
"add_to_library": "Додати до бібліотеки",
|
||||
"remove_from_library": "Видалити з бібліотеки",
|
||||
"no_downloads": "Немає доступних завантажень",
|
||||
"play_time": "Час гри: {{amount}}",
|
||||
"last_time_played": "Востаннє зіграно: {{period}}",
|
||||
"not_played_yet": "Ви ще не грали в {{title}}",
|
||||
"next_suggestion": "Наступна пропозиція",
|
||||
"play": "Грати",
|
||||
"deleting": "Видалення інсталятора…",
|
||||
"close": "Закрити",
|
||||
"playing_now": "Поточна гра",
|
||||
"change": "Змінити",
|
||||
"repacks_modal_description": "Виберіть репак, який хочете завантажити",
|
||||
"downloads_path": "Шлях завантажень",
|
||||
"select_folder_hint": "Щоб змінити теку за замовчуванням, відкрийте",
|
||||
"settings": "Налаштування Hydra",
|
||||
"download_now": "Завантажити зараз",
|
||||
"installation_instructions": "Інструкція зі встановлення",
|
||||
"installation_instructions_description": "Для встановлення цієї гри потрібні додаткові кроки",
|
||||
"online_fix_instruction": "В іграх з OnlineFix потрібно ввести пароль для вилучення. За необхідності використовуйте наступний пароль:",
|
||||
"dodi_installation_instruction": "Коли ви відкриєте інсталятор DODI, натисніть на клавіатурі клавішу 'вгору' <0 />, щоб почати процес встановлення:",
|
||||
"dont_show_it_again": "Не показувати це знову",
|
||||
"copy_to_clipboard": "Копіювати",
|
||||
"copied_to_clipboard": "Скопійовано",
|
||||
"got_it": "Зрозуміло"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Активувати Hydra",
|
||||
"installation_id": "ID установки:",
|
||||
"enter_activation_code": "Введіть ваш активаційний код",
|
||||
"message": "Якщо ви не знаєте, де його запросити, то не повинні мати цього.",
|
||||
"activate": "Активувати",
|
||||
"loading": "Завантаження…"
|
||||
},
|
||||
"downloads": {
|
||||
"resume": "Продовжити",
|
||||
"pause": "Призупинити",
|
||||
"eta": "Закінчення {{eta}}",
|
||||
"paused": "Призупинено",
|
||||
"verifying": "Перевірка…",
|
||||
"completed_at": "Завершено в {{date}}",
|
||||
"completed": "Завершено",
|
||||
"cancelled": "Скасовано",
|
||||
"download_again": "Завантажити знову",
|
||||
"cancel": "Скасувати",
|
||||
"filter": "Фільтр завантажених ігор",
|
||||
"remove": "Видалити",
|
||||
"downloading_metadata": "Завантаження метаданих…",
|
||||
"checking_files": "Перевірка файлів…",
|
||||
"starting_download": "Початок завантаження…",
|
||||
"deleting": "Видалення інсталятора…",
|
||||
"delete": "Видалити інсталятор",
|
||||
"remove_from_list": "Видалити",
|
||||
"delete_modal_title": "Ви впевнені?",
|
||||
"delete_modal_description": "Це видалить усі інсталяційні файли з вашого комп'ютера",
|
||||
"install": "Встановити"
|
||||
},
|
||||
"settings": {
|
||||
"downloads_path": "Тека завантажень",
|
||||
"change": "Змінити",
|
||||
"notifications": "Повідомлення",
|
||||
"enable_download_notifications": "Після завершення завантаження",
|
||||
"enable_repack_list_notifications": "Коли додається новий репак",
|
||||
"telemetry": "Телеметрія",
|
||||
"telemetry_description": "Відправляти анонімну статистику використання",
|
||||
"behavior": "Поведінка",
|
||||
"quit_app_instead_hiding": "Закривати програму замість того, щоб згортати її в трей",
|
||||
"launch_with_system": "Запускати програми із запуском комп'ютера"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Завантаження завершено",
|
||||
"game_ready_to_install": "{{title}} готова до встановлення",
|
||||
"repack_list_updated": "Список репаків оновлено",
|
||||
"repack_count_one": "{{count}} репак додано",
|
||||
"repack_count_other": "{{count}} репаків додано"
|
||||
},
|
||||
"system_tray": {
|
||||
"open": "Відкрити Hydra",
|
||||
"quit": "Вийти"
|
||||
},
|
||||
"game_card": {
|
||||
"no_downloads": "Немає доступних завантажень"
|
||||
},
|
||||
"binary_not_found_modal": {
|
||||
"title": "Програми не встановлені",
|
||||
"description": "Виконувані файли Wine або Lutris не знайдено у вашій системі",
|
||||
"instructions": "Дізнайтеся правильний спосіб встановити будь-який з них на ваш дистрибутив Linux, щоб гра могла нормально працювати"
|
||||
},
|
||||
"modal": {
|
||||
"close": "Закрити"
|
||||
}
|
||||
}
|
||||
"home": {
|
||||
"featured": "Рекомендоване",
|
||||
"recently_added": "Нове",
|
||||
"trending": "У тренді",
|
||||
"surprise_me": "Здивуй мене",
|
||||
"no_results": "Результатів не знайдено"
|
||||
},
|
||||
"sidebar": {
|
||||
"catalogue": "Каталог",
|
||||
"downloads": "Завантаження",
|
||||
"settings": "Налаштування",
|
||||
"my_library": "Бібліотека",
|
||||
"downloading_metadata": "{{title}} (Завантаження метаданих…)",
|
||||
"checking_files": "{{title}} ({{percentage}} - Перевірка файлів…)",
|
||||
"paused": "{{title}} (Призупинено)",
|
||||
"downloading": "{{title}} ({{percentage}} - Завантаження…)",
|
||||
"filter": "Фільтр бібліотеки",
|
||||
"follow_us": "Підписуйтесь на нас",
|
||||
"home": "Головна",
|
||||
"discord": "Приєднуйтесь до Discord",
|
||||
"telegram": "Приєднуйтесь до Telegram",
|
||||
"x": "Підписуйтесь на X",
|
||||
"github": "Зробіть свій внесок на GitHub"
|
||||
},
|
||||
"header": {
|
||||
"search": "Пошук",
|
||||
"home": "Головна",
|
||||
"catalogue": "Каталог",
|
||||
"downloads": "Завантаження",
|
||||
"search_results": "Результати пошуку",
|
||||
"settings": "Налаштування"
|
||||
},
|
||||
"bottom_panel": {
|
||||
"no_downloads_in_progress": "Немає активних завантажень",
|
||||
"downloading_metadata": "Завантаження метаданих {{title}}…",
|
||||
"checking_files": "Перевірка файлів {{title}}… ({{percentage}} завершено)",
|
||||
"downloading": "Завантаження {{title}}… ({{percentage}} завершено) - Закінчення {{eta}} - {{speed}}"
|
||||
},
|
||||
"catalogue": {
|
||||
"next_page": "Наступна сторінка",
|
||||
"previous_page": "Попередня сторінка"
|
||||
},
|
||||
"game_details": {
|
||||
"open_download_options": "Відкрити варіанти завантаження",
|
||||
"download_options_zero": "Немає варіантів завантаження",
|
||||
"download_options_one": "{{count}} варіант завантаження",
|
||||
"download_options_other": "{{count}} варіантів завантаження",
|
||||
"updated_at": "Оновлено {{updated_at}}",
|
||||
"install": "Встановити",
|
||||
"resume": "Відновити",
|
||||
"pause": "Призупинити",
|
||||
"cancel": "Скасувати",
|
||||
"remove": "Видалити",
|
||||
"remove_from_list": "Видалити",
|
||||
"space_left_on_disk": "{{space}} вільно на диску",
|
||||
"eta": "Закінчення {{eta}}",
|
||||
"downloading_metadata": "Завантаження метаданих…",
|
||||
"checking_files": "Перевірка файлів…",
|
||||
"filter": "Фільтр репаків",
|
||||
"requirements": "Системні вимоги",
|
||||
"minimum": "Мінімальні",
|
||||
"recommended": "Рекомендовані",
|
||||
"no_minimum_requirements": "Для {{title}} не вказані мінімальні вимоги",
|
||||
"no_recommended_requirements": "Для {{title}} не вказані рекомендовані вимоги",
|
||||
"paused_progress": "{{progress}} (Призупинено)",
|
||||
"release_date": "Випущено {{date}}",
|
||||
"publisher": "Видавець {{publisher}}",
|
||||
"copy_link_to_clipboard": "Скопіювати посилання",
|
||||
"copied_link_to_clipboard": "Посилання скопійовано",
|
||||
"hours": "годин",
|
||||
"minutes": "хвилин",
|
||||
"amount_hours": "{{amount}} годин",
|
||||
"amount_minutes": "{{amount}} хвилин",
|
||||
"accuracy": "{{accuracy}}% точність",
|
||||
"add_to_library": "Додати до бібліотеки",
|
||||
"remove_from_library": "Видалити з бібліотеки",
|
||||
"no_downloads": "Немає доступних завантажень",
|
||||
"play_time": "Час гри: {{amount}}",
|
||||
"last_time_played": "Востаннє зіграно: {{period}}",
|
||||
"not_played_yet": "Ви ще не грали в {{title}}",
|
||||
"next_suggestion": "Наступна пропозиція",
|
||||
"play": "Грати",
|
||||
"deleting": "Видалення інсталятора…",
|
||||
"close": "Закрити",
|
||||
"playing_now": "Поточна гра",
|
||||
"change": "Змінити",
|
||||
"repacks_modal_description": "Виберіть репак, який хочете завантажити",
|
||||
"downloads_path": "Шлях завантажень",
|
||||
"select_folder_hint": "Щоб змінити теку за замовчуванням, відкрийте",
|
||||
"settings": "Налаштування Hydra",
|
||||
"download_now": "Завантажити зараз",
|
||||
"installation_instructions": "Інструкція зі встановлення",
|
||||
"installation_instructions_description": "Для встановлення цієї гри потрібні додаткові кроки",
|
||||
"online_fix_instruction": "В іграх з OnlineFix потрібно ввести пароль для вилучення. За необхідності використовуйте наступний пароль:",
|
||||
"dodi_installation_instruction": "Коли ви відкриєте інсталятор DODI, натисніть на клавіатурі клавішу 'вгору' <0 />, щоб почати процес встановлення:",
|
||||
"dont_show_it_again": "Не показувати це знову",
|
||||
"copy_to_clipboard": "Копіювати",
|
||||
"copied_to_clipboard": "Скопійовано",
|
||||
"got_it": "Зрозуміло"
|
||||
},
|
||||
"activation": {
|
||||
"title": "Активувати Hydra",
|
||||
"installation_id": "ID установки:",
|
||||
"enter_activation_code": "Введіть ваш активаційний код",
|
||||
"message": "Якщо ви не знаєте, де його запросити, то не повинні мати цього.",
|
||||
"activate": "Активувати",
|
||||
"loading": "Завантаження…"
|
||||
},
|
||||
"downloads": {
|
||||
"resume": "Продовжити",
|
||||
"pause": "Призупинити",
|
||||
"eta": "Закінчення {{eta}}",
|
||||
"paused": "Призупинено",
|
||||
"verifying": "Перевірка…",
|
||||
"completed_at": "Завершено в {{date}}",
|
||||
"completed": "Завершено",
|
||||
"cancelled": "Скасовано",
|
||||
"download_again": "Завантажити знову",
|
||||
"cancel": "Скасувати",
|
||||
"filter": "Фільтр завантажених ігор",
|
||||
"remove": "Видалити",
|
||||
"downloading_metadata": "Завантаження метаданих…",
|
||||
"checking_files": "Перевірка файлів…",
|
||||
"starting_download": "Початок завантаження…",
|
||||
"deleting": "Видалення інсталятора…",
|
||||
"delete": "Видалити інсталятор",
|
||||
"remove_from_list": "Видалити",
|
||||
"delete_modal_title": "Ви впевнені?",
|
||||
"delete_modal_description": "Це видалить усі інсталяційні файли з вашого комп'ютера",
|
||||
"install": "Встановити"
|
||||
},
|
||||
"settings": {
|
||||
"downloads_path": "Тека завантажень",
|
||||
"change": "Змінити",
|
||||
"notifications": "Повідомлення",
|
||||
"enable_download_notifications": "Після завершення завантаження",
|
||||
"enable_repack_list_notifications": "Коли додається новий репак",
|
||||
"telemetry": "Телеметрія",
|
||||
"telemetry_description": "Відправляти анонімну статистику використання",
|
||||
"behavior": "Поведінка",
|
||||
"quit_app_instead_hiding": "Закривати програму замість того, щоб згортати її в трей",
|
||||
"launch_with_system": "Запускати програми із запуском комп'ютера"
|
||||
},
|
||||
"notifications": {
|
||||
"download_complete": "Завантаження завершено",
|
||||
"game_ready_to_install": "{{title}} готова до встановлення",
|
||||
"repack_list_updated": "Список репаків оновлено",
|
||||
"repack_count_one": "{{count}} репак додано",
|
||||
"repack_count_other": "{{count}} репаків додано"
|
||||
},
|
||||
"system_tray": {
|
||||
"open": "Відкрити Hydra",
|
||||
"quit": "Вийти"
|
||||
},
|
||||
"game_card": {
|
||||
"no_downloads": "Немає доступних завантажень"
|
||||
},
|
||||
"binary_not_found_modal": {
|
||||
"title": "Програми не встановлені",
|
||||
"description": "Виконувані файли Wine або Lutris не знайдено у вашій системі",
|
||||
"instructions": "Дізнайтеся правильний спосіб встановити будь-який з них на ваш дистрибутив Linux, щоб гра могла нормально працювати"
|
||||
},
|
||||
"modal": {
|
||||
"close": "Закрити"
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,29 @@ import { getSteamAppDetails } from "@main/services";
|
||||
import type { ShopDetails, GameShop, SteamAppDetails } from "@types";
|
||||
|
||||
import { registerEvent } from "../register-event";
|
||||
import { searchRepacks } from "../helpers/search-games";
|
||||
|
||||
const getLocalizedSteamAppDetails = (
|
||||
objectID: string,
|
||||
language: string
|
||||
): Promise<ShopDetails | null> => {
|
||||
const englishAppDetails = getSteamAppDetails(objectID, "english");
|
||||
|
||||
if (language === "english") return englishAppDetails;
|
||||
|
||||
return Promise.all([
|
||||
englishAppDetails,
|
||||
getSteamAppDetails(objectID, language),
|
||||
]).then(([appDetails, localizedAppDetails]) => {
|
||||
if (appDetails && localizedAppDetails) {
|
||||
return {
|
||||
...localizedAppDetails,
|
||||
name: appDetails.name,
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
});
|
||||
};
|
||||
|
||||
const getGameShopDetails = async (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
@ -17,27 +39,21 @@ const getGameShopDetails = async (
|
||||
where: { objectID, language },
|
||||
});
|
||||
|
||||
const result = Promise.all([
|
||||
getSteamAppDetails(objectID, "english"),
|
||||
getSteamAppDetails(objectID, language),
|
||||
]).then(([appDetails, localizedAppDetails]) => {
|
||||
if (appDetails && localizedAppDetails) {
|
||||
const appDetails = getLocalizedSteamAppDetails(objectID, language).then(
|
||||
(result) => {
|
||||
gameShopCacheRepository.upsert(
|
||||
{
|
||||
objectID,
|
||||
shop: "steam",
|
||||
language,
|
||||
serializedData: JSON.stringify({
|
||||
...localizedAppDetails,
|
||||
name: appDetails.name,
|
||||
}),
|
||||
serializedData: JSON.stringify(result),
|
||||
},
|
||||
["objectID"]
|
||||
);
|
||||
}
|
||||
|
||||
return [appDetails, localizedAppDetails];
|
||||
});
|
||||
return result;
|
||||
}
|
||||
);
|
||||
|
||||
const cachedGame = cachedData?.serializedData
|
||||
? (JSON.parse(cachedData?.serializedData) as SteamAppDetails)
|
||||
@ -46,21 +62,11 @@ const getGameShopDetails = async (
|
||||
if (cachedGame) {
|
||||
return {
|
||||
...cachedGame,
|
||||
repacks: searchRepacks(cachedGame.name),
|
||||
objectID,
|
||||
} as ShopDetails;
|
||||
}
|
||||
|
||||
return result.then(([appDetails, localizedAppDetails]) => {
|
||||
if (!appDetails || !localizedAppDetails) return null;
|
||||
|
||||
return {
|
||||
...localizedAppDetails,
|
||||
name: appDetails.name,
|
||||
repacks: searchRepacks(appDetails.name),
|
||||
objectID,
|
||||
} as ShopDetails;
|
||||
});
|
||||
return Promise.resolve(appDetails);
|
||||
}
|
||||
|
||||
throw new Error("Not implemented");
|
||||
|
14
src/main/events/catalogue/search-game-repacks.ts
Normal file
14
src/main/events/catalogue/search-game-repacks.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { searchRepacks } from "../helpers/search-games";
|
||||
import { registerEvent } from "../register-event";
|
||||
|
||||
const searchGameRepacks = (
|
||||
_event: Electron.IpcMainInvokeEvent,
|
||||
query: string
|
||||
) => {
|
||||
return searchRepacks(query);
|
||||
};
|
||||
|
||||
registerEvent(searchGameRepacks, {
|
||||
name: "searchGameRepacks",
|
||||
memoize: true,
|
||||
});
|
@ -7,6 +7,7 @@ import "./catalogue/get-games";
|
||||
import "./catalogue/get-how-long-to-beat";
|
||||
import "./catalogue/get-random-game";
|
||||
import "./catalogue/search-games";
|
||||
import "./catalogue/search-game-repacks";
|
||||
import "./hardware/get-disk-free-space";
|
||||
import "./library/add-game-to-library";
|
||||
import "./library/close-game";
|
||||
|
@ -12,8 +12,7 @@ export class RealDebridClient {
|
||||
private static instance: AxiosInstance;
|
||||
|
||||
static async addMagnet(magnet: string) {
|
||||
const searchParams = new URLSearchParams();
|
||||
searchParams.append("magnet", magnet);
|
||||
const searchParams = new URLSearchParams({ magnet });
|
||||
|
||||
const response = await this.instance.post<RealDebridAddMagnet>(
|
||||
"/torrents/addMagnet",
|
||||
@ -31,8 +30,7 @@ export class RealDebridClient {
|
||||
}
|
||||
|
||||
static async selectAllFiles(id: string) {
|
||||
const searchParams = new URLSearchParams();
|
||||
searchParams.append("files", "all");
|
||||
const searchParams = new URLSearchParams({ files: "all" });
|
||||
|
||||
await this.instance.post(
|
||||
`/torrents/selectFiles/${id}`,
|
||||
@ -41,8 +39,7 @@ export class RealDebridClient {
|
||||
}
|
||||
|
||||
static async unrestrictLink(link: string) {
|
||||
const searchParams = new URLSearchParams();
|
||||
searchParams.append("link", link);
|
||||
const searchParams = new URLSearchParams({ link });
|
||||
|
||||
const response = await this.instance.post<RealDebridUnrestrictLink>(
|
||||
"/unrestrict/link",
|
||||
|
105
src/preload/index.d.ts
vendored
105
src/preload/index.d.ts
vendored
@ -1,105 +0,0 @@
|
||||
// See the Electron documentation for details on how to use preload scripts:
|
||||
// https://www.electronjs.org/docs/latest/tutorial/process-model#preload-scripts
|
||||
import { contextBridge, ipcRenderer } from "electron";
|
||||
|
||||
import type {
|
||||
CatalogueCategory,
|
||||
GameShop,
|
||||
TorrentProgress,
|
||||
UserPreferences,
|
||||
} from "@types";
|
||||
|
||||
contextBridge.exposeInMainWorld("electron", {
|
||||
/* Torrenting */
|
||||
startGameDownload: (
|
||||
repackId: number,
|
||||
objectID: string,
|
||||
title: string,
|
||||
shop: GameShop
|
||||
) => ipcRenderer.invoke("startGameDownload", repackId, objectID, title, shop),
|
||||
cancelGameDownload: (gameId: number) =>
|
||||
ipcRenderer.invoke("cancelGameDownload", gameId),
|
||||
pauseGameDownload: (gameId: number) =>
|
||||
ipcRenderer.invoke("pauseGameDownload", gameId),
|
||||
resumeGameDownload: (gameId: number) =>
|
||||
ipcRenderer.invoke("resumeGameDownload", gameId),
|
||||
onDownloadProgress: (cb: (value: TorrentProgress) => void) => {
|
||||
const listener = (
|
||||
_event: Electron.IpcRendererEvent,
|
||||
value: TorrentProgress
|
||||
) => cb(value);
|
||||
ipcRenderer.on("on-download-progress", listener);
|
||||
return () => ipcRenderer.removeListener("on-download-progress", listener);
|
||||
},
|
||||
|
||||
/* Catalogue */
|
||||
searchGames: (query: string) => ipcRenderer.invoke("searchGames", query),
|
||||
getCatalogue: (category: CatalogueCategory) =>
|
||||
ipcRenderer.invoke("getCatalogue", category),
|
||||
getGameShopDetails: (objectID: string, shop: GameShop, language: string) =>
|
||||
ipcRenderer.invoke("getGameShopDetails", objectID, shop, language),
|
||||
getRandomGame: () => ipcRenderer.invoke("getRandomGame"),
|
||||
getHowLongToBeat: (objectID: string, shop: GameShop, title: string) =>
|
||||
ipcRenderer.invoke("getHowLongToBeat", objectID, shop, title),
|
||||
getGames: (take?: number, prevCursor?: number) =>
|
||||
ipcRenderer.invoke("getGames", take, prevCursor),
|
||||
|
||||
/* User preferences */
|
||||
getUserPreferences: () => ipcRenderer.invoke("getUserPreferences"),
|
||||
updateUserPreferences: (preferences: UserPreferences) =>
|
||||
ipcRenderer.invoke("updateUserPreferences", preferences),
|
||||
autoLaunch: (enabled: boolean) => ipcRenderer.invoke("autoLaunch", enabled),
|
||||
|
||||
/* Library */
|
||||
addGameToLibrary: (
|
||||
objectID: string,
|
||||
title: string,
|
||||
shop: GameShop,
|
||||
executablePath: string
|
||||
) =>
|
||||
ipcRenderer.invoke(
|
||||
"addGameToLibrary",
|
||||
objectID,
|
||||
title,
|
||||
shop,
|
||||
executablePath
|
||||
),
|
||||
getLibrary: () => ipcRenderer.invoke("getLibrary"),
|
||||
getRepackersFriendlyNames: () =>
|
||||
ipcRenderer.invoke("getRepackersFriendlyNames"),
|
||||
openGameInstaller: (gameId: number) =>
|
||||
ipcRenderer.invoke("openGameInstaller", gameId),
|
||||
openGame: (gameId: number, executablePath: string) =>
|
||||
ipcRenderer.invoke("openGame", gameId, executablePath),
|
||||
closeGame: (gameId: number) => ipcRenderer.invoke("closeGame", gameId),
|
||||
removeGameFromLibrary: (gameId: number) =>
|
||||
ipcRenderer.invoke("removeGameFromLibrary", gameId),
|
||||
deleteGameFolder: (gameId: number) =>
|
||||
ipcRenderer.invoke("deleteGameFolder", gameId),
|
||||
getGameByObjectID: (objectID: string) =>
|
||||
ipcRenderer.invoke("getGameByObjectID", objectID),
|
||||
onPlaytime: (cb: (gameId: number) => void) => {
|
||||
const listener = (_event: Electron.IpcRendererEvent, gameId: number) =>
|
||||
cb(gameId);
|
||||
ipcRenderer.on("on-playtime", listener);
|
||||
return () => ipcRenderer.removeListener("on-playtime", listener);
|
||||
},
|
||||
onGameClose: (cb: (gameId: number) => void) => {
|
||||
const listener = (_event: Electron.IpcRendererEvent, gameId: number) =>
|
||||
cb(gameId);
|
||||
ipcRenderer.on("on-game-close", listener);
|
||||
return () => ipcRenderer.removeListener("on-game-close", listener);
|
||||
},
|
||||
|
||||
/* Hardware */
|
||||
getDiskFreeSpace: () => ipcRenderer.invoke("getDiskFreeSpace"),
|
||||
|
||||
/* Misc */
|
||||
ping: () => ipcRenderer.invoke("ping"),
|
||||
getVersion: () => ipcRenderer.invoke("getVersion"),
|
||||
getDefaultDownloadsPath: () => ipcRenderer.invoke("getDefaultDownloadsPath"),
|
||||
openExternal: (src: string) => ipcRenderer.invoke("openExternal", src),
|
||||
showOpenDialog: (options: Electron.OpenDialogOptions) =>
|
||||
ipcRenderer.invoke("showOpenDialog", options),
|
||||
platform: process.platform,
|
||||
});
|
@ -52,6 +52,8 @@ contextBridge.exposeInMainWorld("electron", {
|
||||
ipcRenderer.invoke("getHowLongToBeat", objectID, shop, title),
|
||||
getGames: (take?: number, prevCursor?: number) =>
|
||||
ipcRenderer.invoke("getGames", take, prevCursor),
|
||||
searchGameRepacks: (query: string) =>
|
||||
ipcRenderer.invoke("searchGameRepacks", query),
|
||||
|
||||
/* User preferences */
|
||||
getUserPreferences: () => ipcRenderer.invoke("getUserPreferences"),
|
||||
|
@ -1,31 +1,18 @@
|
||||
import { style } from "@vanilla-extract/css";
|
||||
import { recipe } from "@vanilla-extract/recipes";
|
||||
import { SPACING_UNIT, vars } from "../../theme.css";
|
||||
|
||||
export const card = recipe({
|
||||
base: {
|
||||
width: "100%",
|
||||
height: "180px",
|
||||
boxShadow: "0px 0px 15px 0px #000000",
|
||||
overflow: "hidden",
|
||||
borderRadius: "4px",
|
||||
transition: "all ease 0.2s",
|
||||
border: `solid 1px ${vars.color.border}`,
|
||||
cursor: "pointer",
|
||||
zIndex: "1",
|
||||
":active": {
|
||||
opacity: vars.opacity.active,
|
||||
},
|
||||
},
|
||||
variants: {
|
||||
disabled: {
|
||||
true: {
|
||||
pointerEvents: "none",
|
||||
boxShadow: "none",
|
||||
opacity: vars.opacity.disabled,
|
||||
filter: "grayscale(50%)",
|
||||
},
|
||||
},
|
||||
export const card = style({
|
||||
width: "100%",
|
||||
height: "180px",
|
||||
boxShadow: "0px 0px 15px 0px #000000",
|
||||
overflow: "hidden",
|
||||
borderRadius: "4px",
|
||||
transition: "all ease 0.2s",
|
||||
border: `solid 1px ${vars.color.border}`,
|
||||
cursor: "pointer",
|
||||
zIndex: "1",
|
||||
":active": {
|
||||
opacity: vars.opacity.active,
|
||||
},
|
||||
});
|
||||
|
||||
@ -48,7 +35,7 @@ export const cover = style({
|
||||
zIndex: "-1",
|
||||
transition: "all ease 0.2s",
|
||||
selectors: {
|
||||
[`${card({})}:hover &`]: {
|
||||
[`${card}:hover &`]: {
|
||||
transform: "scale(1.05)",
|
||||
},
|
||||
},
|
||||
@ -64,7 +51,7 @@ export const content = style({
|
||||
transition: "all ease 0.2s",
|
||||
transform: "translateY(24px)",
|
||||
selectors: {
|
||||
[`${card({})}:hover &`]: {
|
||||
[`${card}:hover &`]: {
|
||||
transform: "translateY(0px)",
|
||||
},
|
||||
},
|
||||
|
@ -14,7 +14,6 @@ export interface GameCardProps
|
||||
HTMLButtonElement
|
||||
> {
|
||||
game: CatalogueEntry;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
||||
const shopIcon = {
|
||||
@ -22,7 +21,7 @@ const shopIcon = {
|
||||
steam: <SteamLogo className={styles.shopIcon} />,
|
||||
};
|
||||
|
||||
export function GameCard({ game, disabled, ...props }: GameCardProps) {
|
||||
export function GameCard({ game, ...props }: GameCardProps) {
|
||||
const { t } = useTranslation("game_card");
|
||||
|
||||
const repackersFriendlyNames = useAppSelector(
|
||||
@ -34,12 +33,7 @@ export function GameCard({ game, disabled, ...props }: GameCardProps) {
|
||||
);
|
||||
|
||||
return (
|
||||
<button
|
||||
{...props}
|
||||
type="button"
|
||||
className={styles.card({ disabled })}
|
||||
disabled={disabled}
|
||||
>
|
||||
<button {...props} type="button" className={styles.card}>
|
||||
<div className={styles.backdrop}>
|
||||
<img src={game.cover} alt={game.title} className={styles.cover} />
|
||||
|
||||
|
@ -6,7 +6,7 @@ export const hero = style({
|
||||
height: "280px",
|
||||
minHeight: "280px",
|
||||
maxHeight: "280px",
|
||||
borderRadius: "8px",
|
||||
borderRadius: "4px",
|
||||
color: "#DADBE1",
|
||||
overflow: "hidden",
|
||||
boxShadow: "0px 0px 15px 0px #000000",
|
||||
@ -45,6 +45,7 @@ export const description = style({
|
||||
textAlign: "left",
|
||||
fontFamily: "'Fira Sans', sans-serif",
|
||||
lineHeight: "20px",
|
||||
marginTop: `${SPACING_UNIT * 2}px`,
|
||||
});
|
||||
|
||||
export const content = style({
|
||||
|
@ -2,20 +2,28 @@ import { useNavigate } from "react-router-dom";
|
||||
import * as styles from "./hero.css";
|
||||
import { useEffect, useState } from "react";
|
||||
import { ShopDetails } from "@types";
|
||||
import { getSteamLanguage, steamUrlBuilder } from "@renderer/helpers";
|
||||
import {
|
||||
buildGameDetailsPath,
|
||||
getSteamLanguage,
|
||||
steamUrlBuilder,
|
||||
} from "@renderer/helpers";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const FEATURED_GAME_TITLE = "Horizon Forbidden West™ Complete Edition";
|
||||
const FEATURED_GAME_ID = "2420110";
|
||||
|
||||
export function Hero() {
|
||||
const [featuredGameDetails, setFeaturedGameDetails] =
|
||||
useState<ShopDetails | null>(null);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const { i18n } = useTranslation();
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoading(true);
|
||||
|
||||
window.electron
|
||||
.getGameShopDetails(
|
||||
FEATURED_GAME_ID,
|
||||
@ -24,19 +32,30 @@ export function Hero() {
|
||||
)
|
||||
.then((result) => {
|
||||
setFeaturedGameDetails(result);
|
||||
})
|
||||
.finally(() => {
|
||||
setIsLoading(false);
|
||||
});
|
||||
}, [i18n.language]);
|
||||
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => navigate(`/game/steam/${FEATURED_GAME_ID}`)}
|
||||
onClick={() =>
|
||||
navigate(
|
||||
buildGameDetailsPath({
|
||||
title: FEATURED_GAME_TITLE,
|
||||
objectID: FEATURED_GAME_ID,
|
||||
shop: "steam",
|
||||
})
|
||||
)
|
||||
}
|
||||
className={styles.hero}
|
||||
>
|
||||
<div className={styles.backdrop}>
|
||||
<img
|
||||
src="https://cdn2.steamgriddb.com/hero/4ef10445b952a8b3c93a9379d581146a.jpg"
|
||||
alt={featuredGameDetails?.name}
|
||||
alt={FEATURED_GAME_TITLE}
|
||||
className={styles.heroMedia}
|
||||
/>
|
||||
|
||||
@ -44,13 +63,14 @@ export function Hero() {
|
||||
<img
|
||||
src={steamUrlBuilder.logo(FEATURED_GAME_ID)}
|
||||
width="250px"
|
||||
alt={featuredGameDetails?.name}
|
||||
style={{ marginBottom: 16 }}
|
||||
alt={FEATURED_GAME_TITLE}
|
||||
/>
|
||||
|
||||
<p className={styles.description}>
|
||||
{featuredGameDetails?.short_description}
|
||||
</p>
|
||||
{!isLoading && featuredGameDetails && (
|
||||
<p className={styles.description}>
|
||||
{featuredGameDetails?.short_description}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
|
@ -15,6 +15,7 @@ import XLogo from "@renderer/assets/x-icon.svg?react";
|
||||
|
||||
import * as styles from "./sidebar.css";
|
||||
import { GameStatus, GameStatusHelper } from "@shared";
|
||||
import { buildGameDetailsPath } from "@renderer/helpers";
|
||||
|
||||
const SIDEBAR_MIN_WIDTH = 200;
|
||||
const SIDEBAR_INITIAL_WIDTH = 250;
|
||||
@ -209,9 +210,7 @@ export function Sidebar() {
|
||||
type="button"
|
||||
className={styles.menuItemButton}
|
||||
onClick={() =>
|
||||
handleSidebarItemClick(
|
||||
`/game/${game.shop}/${game.objectID}`
|
||||
)
|
||||
handleSidebarItemClick(buildGameDetailsPath(game))
|
||||
}
|
||||
>
|
||||
<img
|
||||
|
2
src/renderer/src/declaration.d.ts
vendored
2
src/renderer/src/declaration.d.ts
vendored
@ -2,6 +2,7 @@ import type {
|
||||
CatalogueCategory,
|
||||
CatalogueEntry,
|
||||
Game,
|
||||
GameRepack,
|
||||
GameShop,
|
||||
HowLongToBeatCategory,
|
||||
ShopDetails,
|
||||
@ -50,6 +51,7 @@ declare global {
|
||||
take?: number,
|
||||
prevCursor?: number
|
||||
) => Promise<{ results: CatalogueEntry[]; cursor: number }>;
|
||||
searchGameRepacks: (query: string) => Promise<GameRepack[]>;
|
||||
|
||||
/* Library */
|
||||
addGameToLibrary: (
|
||||
|
@ -1,3 +1,5 @@
|
||||
import type { CatalogueEntry } from "@types";
|
||||
|
||||
export const steamUrlBuilder = {
|
||||
library: (objectID: string) =>
|
||||
`https://steamcdn-a.akamaihd.net/steam/apps/${objectID}/header.jpg`,
|
||||
@ -28,3 +30,11 @@ export const getSteamLanguage = (language: string) => {
|
||||
|
||||
return "english";
|
||||
};
|
||||
|
||||
export const buildGameDetailsPath = (
|
||||
game: Pick<CatalogueEntry, "title" | "shop" | "objectID">,
|
||||
params: Record<string, string> = {}
|
||||
) => {
|
||||
const searchParams = new URLSearchParams({ title: game.title, ...params });
|
||||
return `/game/${game.shop}/${game.objectID}?${searchParams.toString()}`;
|
||||
};
|
||||
|
@ -11,6 +11,7 @@ import { useEffect, useRef, useState } from "react";
|
||||
import { useNavigate, useSearchParams } from "react-router-dom";
|
||||
import * as styles from "../home/home.css";
|
||||
import { ArrowLeftIcon, ArrowRightIcon } from "@primer/octicons-react";
|
||||
import { buildGameDetailsPath } from "@renderer/helpers";
|
||||
|
||||
export function Catalogue() {
|
||||
const dispatch = useAppDispatch();
|
||||
@ -31,7 +32,7 @@ export function Catalogue() {
|
||||
|
||||
const handleGameClick = (game: CatalogueEntry) => {
|
||||
dispatch(clearSearch());
|
||||
navigate(`/game/${game.shop}/${game.objectID}`);
|
||||
navigate(buildGameDetailsPath(game));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -11,7 +11,7 @@ import * as styles from "./game-details.css";
|
||||
const OPEN_HYDRA_URL = "https://open.hydralauncher.site";
|
||||
|
||||
export interface DescriptionHeaderProps {
|
||||
gameDetails: ShopDetails | null;
|
||||
gameDetails: ShopDetails;
|
||||
}
|
||||
|
||||
export function DescriptionHeader({ gameDetails }: DescriptionHeaderProps) {
|
||||
@ -64,7 +64,7 @@ export function DescriptionHeader({ gameDetails }: DescriptionHeaderProps) {
|
||||
date: gameDetails?.release_date.date,
|
||||
})}
|
||||
</p>
|
||||
<p>{t("publisher", { publisher: gameDetails?.publishers[0] })}</p>
|
||||
<p>{t("publisher", { publisher: gameDetails.publishers[0] })}</p>
|
||||
</section>
|
||||
|
||||
<Button
|
||||
|
@ -4,21 +4,19 @@ import { ChevronRightIcon, ChevronLeftIcon } from "@primer/octicons-react";
|
||||
import * as styles from "./gallery-slider.css";
|
||||
|
||||
export interface GallerySliderProps {
|
||||
gameDetails: ShopDetails | null;
|
||||
gameDetails: ShopDetails;
|
||||
}
|
||||
|
||||
export function GallerySlider({ gameDetails }: GallerySliderProps) {
|
||||
const scrollContainerRef = 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;
|
||||
}
|
||||
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;
|
||||
@ -57,8 +55,8 @@ export function GallerySlider({ gameDetails }: GallerySliderProps) {
|
||||
}
|
||||
}, [gameDetails, mediaIndex, mediaCount]);
|
||||
|
||||
const hasScreenshots = gameDetails && gameDetails.screenshots.length;
|
||||
const hasMovies = gameDetails && gameDetails.movies?.length;
|
||||
const hasScreenshots = gameDetails.screenshots.length;
|
||||
const hasMovies = gameDetails.movies?.length;
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -84,7 +82,7 @@ export function GallerySlider({ gameDetails }: GallerySliderProps) {
|
||||
<source src={video.webm.max.replace("http", "https")} />
|
||||
</video>
|
||||
))}
|
||||
{gameDetails.screenshots &&
|
||||
{hasScreenshots &&
|
||||
gameDetails.screenshots.map(
|
||||
(image: SteamScreenshot, i: number) => (
|
||||
<img
|
||||
@ -128,7 +126,8 @@ export function GallerySlider({ gameDetails }: GallerySliderProps) {
|
||||
className={`${styles.gallerySliderMediaPreview} ${mediaIndex === i ? styles.gallerySliderMediaPreviewActive : ""}`}
|
||||
/>
|
||||
))}
|
||||
{gameDetails.screenshots &&
|
||||
|
||||
{hasScreenshots &&
|
||||
gameDetails.screenshots.map(
|
||||
(image: SteamScreenshot, i: number) => (
|
||||
<img
|
||||
|
@ -1,7 +1,10 @@
|
||||
import Skeleton from "react-loading-skeleton";
|
||||
|
||||
import { Button } from "@renderer/components";
|
||||
|
||||
import * as styles from "./game-details.css";
|
||||
import * as sidebarStyles from "./sidebar/sidebar.css";
|
||||
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { ShareAndroidIcon } from "@primer/octicons-react";
|
||||
|
||||
@ -43,41 +46,41 @@ export function GameDetailsSkeleton() {
|
||||
<Skeleton />
|
||||
</div>
|
||||
</div>
|
||||
<div className={styles.contentSidebar}>
|
||||
<div className={styles.contentSidebarTitle}>
|
||||
<div className={sidebarStyles.contentSidebar}>
|
||||
<div className={sidebarStyles.contentSidebarTitle}>
|
||||
<h3>HowLongToBeat</h3>
|
||||
</div>
|
||||
<ul className={styles.howLongToBeatCategoriesList}>
|
||||
<ul className={sidebarStyles.howLongToBeatCategoriesList}>
|
||||
{Array.from({ length: 3 }).map((_, index) => (
|
||||
<Skeleton
|
||||
key={index}
|
||||
className={styles.howLongToBeatCategorySkeleton}
|
||||
className={sidebarStyles.howLongToBeatCategorySkeleton}
|
||||
/>
|
||||
))}
|
||||
</ul>
|
||||
<div
|
||||
className={styles.contentSidebarTitle}
|
||||
className={sidebarStyles.contentSidebarTitle}
|
||||
style={{ border: "none" }}
|
||||
>
|
||||
<h3>{t("requirements")}</h3>
|
||||
</div>
|
||||
<div className={styles.requirementButtonContainer}>
|
||||
<div className={sidebarStyles.requirementButtonContainer}>
|
||||
<Button
|
||||
className={styles.requirementButton}
|
||||
className={sidebarStyles.requirementButton}
|
||||
theme="primary"
|
||||
disabled
|
||||
>
|
||||
{t("minimum")}
|
||||
</Button>
|
||||
<Button
|
||||
className={styles.requirementButton}
|
||||
className={sidebarStyles.requirementButton}
|
||||
theme="outline"
|
||||
disabled
|
||||
>
|
||||
{t("recommended")}
|
||||
</Button>
|
||||
</div>
|
||||
<div className={styles.requirementsDetailsSkeleton}>
|
||||
<div className={sidebarStyles.requirementsDetailsSkeleton}>
|
||||
{Array.from({ length: 6 }).map((_, index) => (
|
||||
<Skeleton key={index} height={20} />
|
||||
))}
|
||||
|
@ -79,62 +79,6 @@ export const descriptionContent = style({
|
||||
height: "100%",
|
||||
});
|
||||
|
||||
export const contentSidebar = style({
|
||||
borderLeft: `solid 1px ${vars.color.border};`,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
"@media": {
|
||||
"(min-width: 768px)": {
|
||||
width: "100%",
|
||||
maxWidth: "200px",
|
||||
},
|
||||
"(min-width: 1024px)": {
|
||||
maxWidth: "300px",
|
||||
width: "100%",
|
||||
},
|
||||
"(min-width: 1280px)": {
|
||||
width: "100%",
|
||||
maxWidth: "400px",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const contentSidebarTitle = style({
|
||||
height: "72px",
|
||||
padding: `${SPACING_UNIT * 2}px ${SPACING_UNIT * 2}px`,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
backgroundColor: vars.color.background,
|
||||
});
|
||||
|
||||
export const requirementButtonContainer = style({
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
});
|
||||
|
||||
export const requirementButton = style({
|
||||
border: `solid 1px ${vars.color.border};`,
|
||||
borderLeft: "none",
|
||||
borderRight: "none",
|
||||
borderRadius: "0",
|
||||
width: "100%",
|
||||
});
|
||||
|
||||
export const requirementsDetails = style({
|
||||
padding: `${SPACING_UNIT * 2}px`,
|
||||
lineHeight: "22px",
|
||||
fontFamily: "'Fira Sans', sans-serif",
|
||||
fontSize: "16px",
|
||||
});
|
||||
|
||||
export const requirementsDetailsSkeleton = style({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "8px",
|
||||
padding: `${SPACING_UNIT * 2}px`,
|
||||
fontSize: "16px",
|
||||
});
|
||||
|
||||
export const description = style({
|
||||
userSelect: "text",
|
||||
lineHeight: "22px",
|
||||
@ -183,34 +127,6 @@ export const descriptionHeaderInfo = style({
|
||||
flexDirection: "column",
|
||||
});
|
||||
|
||||
export const howLongToBeatCategoriesList = style({
|
||||
margin: "0",
|
||||
padding: "16px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "16px",
|
||||
});
|
||||
|
||||
export const howLongToBeatCategory = style({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "4px",
|
||||
backgroundColor: vars.color.background,
|
||||
borderRadius: "8px",
|
||||
padding: `8px 16px`,
|
||||
border: `solid 1px ${vars.color.border}`,
|
||||
});
|
||||
|
||||
export const howLongToBeatCategoryLabel = style({
|
||||
color: vars.color.muted,
|
||||
});
|
||||
|
||||
export const howLongToBeatCategorySkeleton = style({
|
||||
border: `solid 1px ${vars.color.border}`,
|
||||
borderRadius: "8px",
|
||||
height: "76px",
|
||||
});
|
||||
|
||||
export const randomizerButton = style({
|
||||
animationName: slideIn,
|
||||
animationDuration: "0.2s",
|
||||
@ -260,8 +176,3 @@ globalStyle(`${description} img`, {
|
||||
globalStyle(`${description} a`, {
|
||||
color: vars.color.bodyText,
|
||||
});
|
||||
|
||||
globalStyle(`${requirementsDetails} a`, {
|
||||
display: "flex",
|
||||
color: vars.color.bodyText,
|
||||
});
|
||||
|
@ -3,14 +3,7 @@ import { average } from "color.js";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { useNavigate, useParams, useSearchParams } from "react-router-dom";
|
||||
|
||||
import type {
|
||||
Game,
|
||||
GameRepack,
|
||||
GameShop,
|
||||
HowLongToBeatCategory,
|
||||
ShopDetails,
|
||||
SteamAppDetails,
|
||||
} from "@types";
|
||||
import type { Game, GameRepack, GameShop, ShopDetails } from "@types";
|
||||
|
||||
import { Button } from "@renderer/components";
|
||||
import { setHeaderTitle } from "@renderer/features";
|
||||
@ -26,7 +19,6 @@ import { DescriptionHeader } from "./description-header";
|
||||
import { GameDetailsSkeleton } from "./game-details-skeleton";
|
||||
import * as styles from "./game-details.css";
|
||||
import { HeroPanel } from "./hero";
|
||||
import { HowLongToBeatSection } from "./how-long-to-beat-section";
|
||||
import { RepacksModal } from "./repacks-modal";
|
||||
|
||||
import { vars } from "../../theme.css";
|
||||
@ -37,6 +29,7 @@ import {
|
||||
OnlineFixInstallationGuide,
|
||||
} from "./installation-guides";
|
||||
import { GallerySlider } from "./gallery-slider";
|
||||
import { Sidebar } from "./sidebar/sidebar";
|
||||
|
||||
export function GameDetails() {
|
||||
const { objectID, shop } = useParams();
|
||||
@ -45,10 +38,7 @@ export function GameDetails() {
|
||||
const [isLoadingRandomGame, setIsLoadingRandomGame] = useState(false);
|
||||
const [color, setColor] = useState({ dark: "", light: "" });
|
||||
const [gameDetails, setGameDetails] = useState<ShopDetails | null>(null);
|
||||
const [howLongToBeat, setHowLongToBeat] = useState<{
|
||||
isLoading: boolean;
|
||||
data: HowLongToBeatCategory[] | null;
|
||||
}>({ isLoading: true, data: null });
|
||||
const [repacks, setRepacks] = useState<GameRepack[]>([]);
|
||||
|
||||
const [game, setGame] = useState<Game | null>(null);
|
||||
const [isGamePlaying, setIsGamePlaying] = useState(false);
|
||||
@ -56,12 +46,12 @@ export function GameDetails() {
|
||||
null | "onlinefix" | "DODI"
|
||||
>(null);
|
||||
|
||||
const [activeRequirement, setActiveRequirement] =
|
||||
useState<keyof SteamAppDetails["pc_requirements"]>("minimum");
|
||||
|
||||
const navigate = useNavigate();
|
||||
const [searchParams] = useSearchParams();
|
||||
|
||||
const fromRandomizer = searchParams.get("fromRandomizer");
|
||||
const title = searchParams.get("title")!;
|
||||
|
||||
const { t, i18n } = useTranslation("game_details");
|
||||
|
||||
const [showRepacksModal, setShowRepacksModal] = useState(false);
|
||||
@ -90,28 +80,24 @@ export function GameDetails() {
|
||||
useEffect(() => {
|
||||
getGame();
|
||||
}, [getGame, gameDownloading?.id]);
|
||||
|
||||
useEffect(() => {
|
||||
setGame(null);
|
||||
setIsLoading(true);
|
||||
setIsGamePlaying(false);
|
||||
dispatch(setHeaderTitle(""));
|
||||
dispatch(setHeaderTitle(title));
|
||||
|
||||
window.electron
|
||||
.getGameShopDetails(objectID!, "steam", getSteamLanguage(i18n.language))
|
||||
.then((result) => {
|
||||
if (!result) {
|
||||
navigate(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
window.electron
|
||||
.getHowLongToBeat(objectID!, "steam", result.name)
|
||||
.then((data) => {
|
||||
setHowLongToBeat({ isLoading: false, data });
|
||||
});
|
||||
|
||||
setGameDetails(result);
|
||||
dispatch(setHeaderTitle(result.name));
|
||||
Promise.all([
|
||||
window.electron.getGameShopDetails(
|
||||
objectID!,
|
||||
"steam",
|
||||
getSteamLanguage(i18n.language)
|
||||
),
|
||||
window.electron.searchGameRepacks(title),
|
||||
])
|
||||
.then(([appDetails, repacks]) => {
|
||||
if (appDetails) setGameDetails(appDetails);
|
||||
setRepacks(repacks);
|
||||
setIsLoadingRandomGame(false);
|
||||
})
|
||||
.finally(() => {
|
||||
@ -119,8 +105,7 @@ export function GameDetails() {
|
||||
});
|
||||
|
||||
getGame();
|
||||
setHowLongToBeat({ isLoading: true, data: null });
|
||||
}, [getGame, dispatch, navigate, objectID, i18n.language]);
|
||||
}, [getGame, dispatch, navigate, title, objectID, i18n.language]);
|
||||
|
||||
const isGameDownloading = gameDownloading?.id === game?.id;
|
||||
|
||||
@ -154,30 +139,28 @@ export function GameDetails() {
|
||||
repack: GameRepack,
|
||||
downloadPath: string
|
||||
) => {
|
||||
if (gameDetails) {
|
||||
return startDownload(
|
||||
repack.id,
|
||||
gameDetails.objectID,
|
||||
gameDetails.name,
|
||||
shop as GameShop,
|
||||
downloadPath
|
||||
).then(() => {
|
||||
getGame();
|
||||
setShowRepacksModal(false);
|
||||
return startDownload(
|
||||
repack.id,
|
||||
objectID!,
|
||||
title,
|
||||
shop as GameShop,
|
||||
downloadPath
|
||||
).then(() => {
|
||||
getGame();
|
||||
setShowRepacksModal(false);
|
||||
|
||||
if (
|
||||
repack.repacker === "onlinefix" &&
|
||||
!window.localStorage.getItem(DONT_SHOW_ONLINE_FIX_INSTRUCTIONS_KEY)
|
||||
) {
|
||||
setShowInstructionsModal("onlinefix");
|
||||
} else if (
|
||||
repack.repacker === "DODI" &&
|
||||
!window.localStorage.getItem(DONT_SHOW_DODI_INSTRUCTIONS_KEY)
|
||||
) {
|
||||
setShowInstructionsModal("DODI");
|
||||
}
|
||||
});
|
||||
}
|
||||
if (
|
||||
repack.repacker === "onlinefix" &&
|
||||
!window.localStorage.getItem(DONT_SHOW_ONLINE_FIX_INSTRUCTIONS_KEY)
|
||||
) {
|
||||
setShowInstructionsModal("onlinefix");
|
||||
} else if (
|
||||
repack.repacker === "DODI" &&
|
||||
!window.localStorage.getItem(DONT_SHOW_DODI_INSTRUCTIONS_KEY)
|
||||
) {
|
||||
setShowInstructionsModal("DODI");
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const handleRandomizerClick = async () => {
|
||||
@ -191,18 +174,14 @@ export function GameDetails() {
|
||||
navigate(`/game/steam/${randomGameObjectID}?${searchParams.toString()}`);
|
||||
};
|
||||
|
||||
const fromRandomizer = searchParams.get("fromRandomizer");
|
||||
|
||||
return (
|
||||
<SkeletonTheme baseColor={vars.color.background} highlightColor="#444">
|
||||
{gameDetails && (
|
||||
<RepacksModal
|
||||
visible={showRepacksModal}
|
||||
gameDetails={gameDetails}
|
||||
startDownload={handleStartDownload}
|
||||
onClose={() => setShowRepacksModal(false)}
|
||||
/>
|
||||
)}
|
||||
<RepacksModal
|
||||
visible={showRepacksModal}
|
||||
repacks={repacks}
|
||||
startDownload={handleStartDownload}
|
||||
onClose={() => setShowRepacksModal(false)}
|
||||
/>
|
||||
|
||||
<OnlineFixInstallationGuide
|
||||
visible={showInstructionsModal === "onlinefix"}
|
||||
@ -239,7 +218,9 @@ export function GameDetails() {
|
||||
<HeroPanel
|
||||
game={game}
|
||||
color={color.dark}
|
||||
gameDetails={gameDetails}
|
||||
objectID={objectID!}
|
||||
title={title}
|
||||
repacks={repacks}
|
||||
openRepacksModal={() => setShowRepacksModal(true)}
|
||||
getGame={getGame}
|
||||
isGamePlaying={isGamePlaying}
|
||||
@ -247,63 +228,22 @@ export function GameDetails() {
|
||||
|
||||
<div className={styles.descriptionContainer}>
|
||||
<div className={styles.descriptionContent}>
|
||||
<DescriptionHeader gameDetails={gameDetails} />
|
||||
|
||||
<GallerySlider gameDetails={gameDetails} />
|
||||
{gameDetails && <DescriptionHeader gameDetails={gameDetails} />}
|
||||
{gameDetails && <GallerySlider gameDetails={gameDetails} />}
|
||||
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: gameDetails?.about_the_game ?? "",
|
||||
__html: gameDetails?.about_the_game ?? t("no_shop_details"),
|
||||
}}
|
||||
className={styles.description}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className={styles.contentSidebar}>
|
||||
<HowLongToBeatSection
|
||||
howLongToBeatData={howLongToBeat.data}
|
||||
isLoading={howLongToBeat.isLoading}
|
||||
/>
|
||||
|
||||
<div
|
||||
className={styles.contentSidebarTitle}
|
||||
style={{ border: "none" }}
|
||||
>
|
||||
<h3>{t("requirements")}</h3>
|
||||
</div>
|
||||
|
||||
<div className={styles.requirementButtonContainer}>
|
||||
<Button
|
||||
className={styles.requirementButton}
|
||||
onClick={() => setActiveRequirement("minimum")}
|
||||
theme={
|
||||
activeRequirement === "minimum" ? "primary" : "outline"
|
||||
}
|
||||
>
|
||||
{t("minimum")}
|
||||
</Button>
|
||||
<Button
|
||||
className={styles.requirementButton}
|
||||
onClick={() => setActiveRequirement("recommended")}
|
||||
theme={
|
||||
activeRequirement === "recommended" ? "primary" : "outline"
|
||||
}
|
||||
>
|
||||
{t("recommended")}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={styles.requirementsDetails}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html:
|
||||
gameDetails?.pc_requirements?.[activeRequirement] ??
|
||||
t(`no_${activeRequirement}_requirements`, {
|
||||
title: gameDetails?.name,
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<Sidebar
|
||||
objectID={objectID!}
|
||||
title={title}
|
||||
gameDetails={gameDetails}
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
)}
|
||||
|
@ -3,7 +3,7 @@ import { NoEntryIcon, PlusCircleIcon } from "@primer/octicons-react";
|
||||
|
||||
import { Button } from "@renderer/components";
|
||||
import { useDownload, useLibrary } from "@renderer/hooks";
|
||||
import type { Game, ShopDetails } from "@types";
|
||||
import type { Game, GameRepack } from "@types";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
@ -11,9 +11,11 @@ import * as styles from "./hero-panel-actions.css";
|
||||
|
||||
export interface HeroPanelActionsProps {
|
||||
game: Game | null;
|
||||
gameDetails: ShopDetails | null;
|
||||
repacks: GameRepack[];
|
||||
isGamePlaying: boolean;
|
||||
isGameDownloading: boolean;
|
||||
objectID: string;
|
||||
title: string;
|
||||
openRepacksModal: () => void;
|
||||
openBinaryNotFoundModal: () => void;
|
||||
getGame: () => void;
|
||||
@ -21,9 +23,11 @@ export interface HeroPanelActionsProps {
|
||||
|
||||
export function HeroPanelActions({
|
||||
game,
|
||||
gameDetails,
|
||||
isGamePlaying,
|
||||
isGameDownloading,
|
||||
repacks,
|
||||
objectID,
|
||||
title,
|
||||
openRepacksModal,
|
||||
openBinaryNotFoundModal,
|
||||
getGame,
|
||||
@ -69,12 +73,12 @@ export function HeroPanelActions({
|
||||
try {
|
||||
if (game) {
|
||||
await removeGameFromLibrary(game.id);
|
||||
} else if (gameDetails) {
|
||||
} else {
|
||||
const gameExecutablePath = await selectGameExecutable();
|
||||
|
||||
await window.electron.addGameToLibrary(
|
||||
gameDetails.objectID,
|
||||
gameDetails.name,
|
||||
objectID,
|
||||
title,
|
||||
"steam",
|
||||
gameExecutablePath
|
||||
);
|
||||
@ -123,7 +127,7 @@ export function HeroPanelActions({
|
||||
const toggleGameOnLibraryButton = (
|
||||
<Button
|
||||
theme="outline"
|
||||
disabled={!gameDetails || toggleLibraryGameDisabled}
|
||||
disabled={toggleLibraryGameDisabled}
|
||||
onClick={toggleGameOnLibrary}
|
||||
className={styles.heroPanelAction}
|
||||
>
|
||||
@ -239,7 +243,7 @@ export function HeroPanelActions({
|
||||
);
|
||||
}
|
||||
|
||||
if (gameDetails && gameDetails.repacks.length) {
|
||||
if (repacks.length) {
|
||||
return (
|
||||
<>
|
||||
{toggleGameOnLibraryButton}
|
||||
|
@ -4,13 +4,13 @@ import { SPACING_UNIT, vars } from "../../../theme.css";
|
||||
export const panel = style({
|
||||
width: "100%",
|
||||
height: "72px",
|
||||
minHeight: "72px",
|
||||
padding: `${SPACING_UNIT * 2}px ${SPACING_UNIT * 3}px`,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
transition: "all ease 0.2s",
|
||||
borderBottom: `solid 1px ${vars.color.border}`,
|
||||
boxShadow: "0px 0px 15px 0px #000000",
|
||||
});
|
||||
|
||||
export const content = style({
|
||||
|
@ -3,7 +3,7 @@ import { useMemo, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { useDownload } from "@renderer/hooks";
|
||||
import type { Game, ShopDetails } from "@types";
|
||||
import type { Game, GameRepack } from "@types";
|
||||
|
||||
import { formatDownloadProgress } from "@renderer/helpers";
|
||||
import { HeroPanelActions } from "./hero-panel-actions";
|
||||
@ -15,20 +15,24 @@ import { HeroPanelPlaytime } from "./hero-panel-playtime";
|
||||
|
||||
export interface HeroPanelProps {
|
||||
game: Game | null;
|
||||
gameDetails: ShopDetails | null;
|
||||
color: string;
|
||||
isGamePlaying: boolean;
|
||||
objectID: string;
|
||||
title: string;
|
||||
repacks: GameRepack[];
|
||||
openRepacksModal: () => void;
|
||||
getGame: () => void;
|
||||
}
|
||||
|
||||
export function HeroPanel({
|
||||
game,
|
||||
gameDetails,
|
||||
color,
|
||||
repacks,
|
||||
objectID,
|
||||
title,
|
||||
isGamePlaying,
|
||||
openRepacksModal,
|
||||
getGame,
|
||||
isGamePlaying,
|
||||
}: HeroPanelProps) {
|
||||
const { t } = useTranslation("game_details");
|
||||
|
||||
@ -58,7 +62,7 @@ export function HeroPanel({
|
||||
}, [game, isGameDownloading, gameDownloading]);
|
||||
|
||||
const getInfo = () => {
|
||||
if (!gameDetails) return null;
|
||||
if (!repacks.length) return null;
|
||||
|
||||
if (isGameDeleting(game?.id ?? -1)) {
|
||||
return <p>{t("deleting")}</p>;
|
||||
@ -110,11 +114,11 @@ export function HeroPanel({
|
||||
return <HeroPanelPlaytime game={game} isGamePlaying={isGamePlaying} />;
|
||||
}
|
||||
|
||||
const [latestRepack] = gameDetails.repacks;
|
||||
const [latestRepack] = repacks;
|
||||
|
||||
if (latestRepack) {
|
||||
const lastUpdate = format(latestRepack.uploadDate!, "dd/MM/yyyy");
|
||||
const repacksCount = gameDetails.repacks.length;
|
||||
const repacksCount = repacks.length;
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -139,7 +143,9 @@ export function HeroPanel({
|
||||
<div className={styles.actions}>
|
||||
<HeroPanelActions
|
||||
game={game}
|
||||
gameDetails={gameDetails}
|
||||
repacks={repacks}
|
||||
objectID={objectID}
|
||||
title={title}
|
||||
getGame={getGame}
|
||||
openRepacksModal={openRepacksModal}
|
||||
openBinaryNotFoundModal={() => setShowBinaryNotFoundModal(true)}
|
||||
|
@ -2,7 +2,7 @@ import { useEffect, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
import { Button, Modal, TextField } from "@renderer/components";
|
||||
import type { GameRepack, ShopDetails } from "@types";
|
||||
import type { GameRepack } from "@types";
|
||||
|
||||
import * as styles from "./repacks-modal.css";
|
||||
|
||||
@ -13,14 +13,14 @@ import { SelectFolderModal } from "./select-folder-modal";
|
||||
|
||||
export interface RepacksModalProps {
|
||||
visible: boolean;
|
||||
gameDetails: ShopDetails;
|
||||
repacks: GameRepack[];
|
||||
startDownload: (repack: GameRepack, downloadPath: string) => Promise<void>;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
export function RepacksModal({
|
||||
visible,
|
||||
gameDetails,
|
||||
repacks,
|
||||
startDownload,
|
||||
onClose,
|
||||
}: RepacksModalProps) {
|
||||
@ -35,8 +35,8 @@ export function RepacksModal({
|
||||
const { t } = useTranslation("game_details");
|
||||
|
||||
useEffect(() => {
|
||||
setFilteredRepacks(gameDetails.repacks);
|
||||
}, [gameDetails.repacks, visible]);
|
||||
setFilteredRepacks(repacks);
|
||||
}, [repacks, visible]);
|
||||
|
||||
const handleRepackClick = (repack: GameRepack) => {
|
||||
setRepack(repack);
|
||||
@ -47,7 +47,7 @@ export function RepacksModal({
|
||||
const term = event.target.value.toLocaleLowerCase();
|
||||
|
||||
setFilteredRepacks(
|
||||
gameDetails.repacks.filter((repack) => {
|
||||
repacks.filter((repack) => {
|
||||
const lowerCaseTitle = repack.title.toLowerCase();
|
||||
const lowerCaseRepacker = repack.repacker.toLowerCase();
|
||||
|
||||
@ -63,14 +63,13 @@ export function RepacksModal({
|
||||
<SelectFolderModal
|
||||
visible={showSelectFolderModal}
|
||||
onClose={() => setShowSelectFolderModal(false)}
|
||||
gameDetails={gameDetails}
|
||||
startDownload={startDownload}
|
||||
repack={repack}
|
||||
/>
|
||||
|
||||
<Modal
|
||||
visible={visible}
|
||||
title={`${gameDetails.name} Repacks`}
|
||||
title={`Download options`}
|
||||
description={t("repacks_modal_description")}
|
||||
onClose={onClose}
|
||||
>
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Button, Link, Modal, TextField } from "@renderer/components";
|
||||
import { GameRepack, ShopDetails } from "@types";
|
||||
import type { GameRepack } from "@types";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Trans, useTranslation } from "react-i18next";
|
||||
|
||||
@ -10,7 +10,6 @@ import { formatBytes } from "@shared";
|
||||
|
||||
export interface SelectFolderModalProps {
|
||||
visible: boolean;
|
||||
gameDetails: ShopDetails;
|
||||
onClose: () => void;
|
||||
startDownload: (repack: GameRepack, downloadPath: string) => Promise<void>;
|
||||
repack: GameRepack | null;
|
||||
@ -18,7 +17,6 @@ export interface SelectFolderModalProps {
|
||||
|
||||
export function SelectFolderModal({
|
||||
visible,
|
||||
gameDetails,
|
||||
onClose,
|
||||
startDownload,
|
||||
repack,
|
||||
@ -74,7 +72,7 @@ export function SelectFolderModal({
|
||||
return (
|
||||
<Modal
|
||||
visible={visible}
|
||||
title={t("installation_folder", { name: gameDetails.name })}
|
||||
title={t("installation_folder")}
|
||||
description={t("space_left_on_disk", {
|
||||
space: formatBytes(diskFreeSpace?.free ?? 0),
|
||||
})}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import Skeleton, { SkeletonTheme } from "react-loading-skeleton";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import type { HowLongToBeatCategory } from "@types";
|
||||
import { vars } from "../../theme.css";
|
||||
import * as styles from "./game-details.css";
|
||||
import { vars } from "../../../theme.css";
|
||||
import * as styles from "./sidebar.css";
|
||||
|
||||
const durationTranslation: Record<string, string> = {
|
||||
Hours: "hours",
|
92
src/renderer/src/pages/game-details/sidebar/sidebar.css.ts
Normal file
92
src/renderer/src/pages/game-details/sidebar/sidebar.css.ts
Normal file
@ -0,0 +1,92 @@
|
||||
import { globalStyle, style } from "@vanilla-extract/css";
|
||||
|
||||
import { SPACING_UNIT, vars } from "../../../theme.css";
|
||||
|
||||
export const contentSidebar = style({
|
||||
borderLeft: `solid 1px ${vars.color.border};`,
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
"@media": {
|
||||
"(min-width: 768px)": {
|
||||
width: "100%",
|
||||
maxWidth: "200px",
|
||||
},
|
||||
"(min-width: 1024px)": {
|
||||
maxWidth: "300px",
|
||||
width: "100%",
|
||||
},
|
||||
"(min-width: 1280px)": {
|
||||
width: "100%",
|
||||
maxWidth: "400px",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export const contentSidebarTitle = style({
|
||||
height: "72px",
|
||||
padding: `${SPACING_UNIT * 2}px ${SPACING_UNIT * 2}px`,
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
backgroundColor: vars.color.background,
|
||||
});
|
||||
|
||||
export const requirementButtonContainer = style({
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
});
|
||||
|
||||
export const requirementButton = style({
|
||||
border: `solid 1px ${vars.color.border};`,
|
||||
borderLeft: "none",
|
||||
borderRight: "none",
|
||||
borderRadius: "0",
|
||||
width: "100%",
|
||||
});
|
||||
|
||||
export const requirementsDetails = style({
|
||||
padding: `${SPACING_UNIT * 2}px`,
|
||||
lineHeight: "22px",
|
||||
fontFamily: "'Fira Sans', sans-serif",
|
||||
fontSize: "16px",
|
||||
});
|
||||
|
||||
export const requirementsDetailsSkeleton = style({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "8px",
|
||||
padding: `${SPACING_UNIT * 2}px`,
|
||||
fontSize: "16px",
|
||||
});
|
||||
|
||||
export const howLongToBeatCategoriesList = style({
|
||||
margin: "0",
|
||||
padding: "16px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "16px",
|
||||
});
|
||||
|
||||
export const howLongToBeatCategory = style({
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "4px",
|
||||
backgroundColor: vars.color.background,
|
||||
borderRadius: "8px",
|
||||
padding: `8px 16px`,
|
||||
border: `solid 1px ${vars.color.border}`,
|
||||
});
|
||||
|
||||
export const howLongToBeatCategoryLabel = style({
|
||||
color: vars.color.muted,
|
||||
});
|
||||
|
||||
export const howLongToBeatCategorySkeleton = style({
|
||||
border: `solid 1px ${vars.color.border}`,
|
||||
borderRadius: "8px",
|
||||
height: "76px",
|
||||
});
|
||||
|
||||
globalStyle(`${requirementsDetails} a`, {
|
||||
display: "flex",
|
||||
color: vars.color.bodyText,
|
||||
});
|
84
src/renderer/src/pages/game-details/sidebar/sidebar.tsx
Normal file
84
src/renderer/src/pages/game-details/sidebar/sidebar.tsx
Normal file
@ -0,0 +1,84 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { HowLongToBeatSection } from "./how-long-to-beat-section";
|
||||
import type {
|
||||
HowLongToBeatCategory,
|
||||
ShopDetails,
|
||||
SteamAppDetails,
|
||||
} from "@types";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Button } from "@renderer/components";
|
||||
|
||||
import * as styles from "./sidebar.css";
|
||||
|
||||
export interface SidebarProps {
|
||||
objectID: string;
|
||||
title: string;
|
||||
gameDetails: ShopDetails | null;
|
||||
}
|
||||
|
||||
export function Sidebar({ objectID, title, gameDetails }: SidebarProps) {
|
||||
const [howLongToBeat, setHowLongToBeat] = useState<{
|
||||
isLoading: boolean;
|
||||
data: HowLongToBeatCategory[] | null;
|
||||
}>({ isLoading: true, data: null });
|
||||
|
||||
const [activeRequirement, setActiveRequirement] =
|
||||
useState<keyof SteamAppDetails["pc_requirements"]>("minimum");
|
||||
|
||||
const { t } = useTranslation("game_details");
|
||||
|
||||
useEffect(() => {
|
||||
setHowLongToBeat({ isLoading: true, data: null });
|
||||
|
||||
window.electron
|
||||
.getHowLongToBeat(objectID, "steam", title)
|
||||
.then((howLongToBeat) => {
|
||||
setHowLongToBeat({ isLoading: false, data: howLongToBeat });
|
||||
})
|
||||
.catch(() => {
|
||||
setHowLongToBeat({ isLoading: false, data: null });
|
||||
});
|
||||
}, [objectID, title]);
|
||||
|
||||
return (
|
||||
<aside className={styles.contentSidebar}>
|
||||
<HowLongToBeatSection
|
||||
howLongToBeatData={howLongToBeat.data}
|
||||
isLoading={howLongToBeat.isLoading}
|
||||
/>
|
||||
|
||||
<div className={styles.contentSidebarTitle} style={{ border: "none" }}>
|
||||
<h3>{t("requirements")}</h3>
|
||||
</div>
|
||||
|
||||
<div className={styles.requirementButtonContainer}>
|
||||
<Button
|
||||
className={styles.requirementButton}
|
||||
onClick={() => setActiveRequirement("minimum")}
|
||||
theme={activeRequirement === "minimum" ? "primary" : "outline"}
|
||||
>
|
||||
{t("minimum")}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
className={styles.requirementButton}
|
||||
onClick={() => setActiveRequirement("recommended")}
|
||||
theme={activeRequirement === "recommended" ? "primary" : "outline"}
|
||||
>
|
||||
{t("recommended")}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={styles.requirementsDetails}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html:
|
||||
gameDetails?.pc_requirements?.[activeRequirement] ??
|
||||
t(`no_${activeRequirement}_requirements`, {
|
||||
title,
|
||||
}),
|
||||
}}
|
||||
/>
|
||||
</aside>
|
||||
);
|
||||
}
|
@ -12,6 +12,7 @@ import starsAnimation from "@renderer/assets/lottie/stars.json";
|
||||
import * as styles from "./home.css";
|
||||
import { vars } from "../../theme.css";
|
||||
import Lottie from "lottie-react";
|
||||
import { buildGameDetailsPath } from "@renderer/helpers";
|
||||
|
||||
const categories: CatalogueCategory[] = ["trending", "recently_added"];
|
||||
|
||||
@ -129,9 +130,7 @@ export function Home() {
|
||||
<GameCard
|
||||
key={result.objectID}
|
||||
game={result}
|
||||
onClick={() =>
|
||||
navigate(`/game/${result.shop}/${result.objectID}`)
|
||||
}
|
||||
onClick={() => navigate(buildGameDetailsPath(result))}
|
||||
/>
|
||||
))}
|
||||
</section>
|
||||
|
@ -14,6 +14,7 @@ import { useEffect, useRef, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useNavigate, useSearchParams } from "react-router-dom";
|
||||
import * as styles from "./home.css";
|
||||
import { buildGameDetailsPath } from "@renderer/helpers";
|
||||
|
||||
export function SearchResults() {
|
||||
const dispatch = useAppDispatch();
|
||||
@ -30,7 +31,7 @@ export function SearchResults() {
|
||||
|
||||
const handleGameClick = (game: CatalogueEntry) => {
|
||||
dispatch(clearSearch());
|
||||
navigate(`/game/${game.shop}/${game.objectID}`);
|
||||
navigate(buildGameDetailsPath(game));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
|
@ -69,7 +69,6 @@ export interface GameRepack {
|
||||
|
||||
export type ShopDetails = SteamAppDetails & {
|
||||
objectID: string;
|
||||
repacks: GameRepack[];
|
||||
};
|
||||
|
||||
export interface TorrentFile {
|
||||
|
Loading…
Reference in New Issue
Block a user