diff --git a/package.json b/package.json index 457f2ff8..3eb7bae4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hydralauncher", - "version": "3.0.5", + "version": "3.0.8", "description": "Hydra", "main": "./out/main/index.js", "author": "Los Broxas", @@ -36,7 +36,6 @@ "@electron-toolkit/utils": "^3.0.0", "@fontsource/noto-sans": "^5.0.22", "@hookform/resolvers": "^3.9.0", - "@intercom/messenger-js-sdk": "^0.0.14", "@primer/octicons-react": "^19.9.0", "@reduxjs/toolkit": "^2.2.3", "@vanilla-extract/css": "^1.14.2", diff --git a/src/locales/bg/translation.json b/src/locales/bg/translation.json index f9999582..a1a5306f 100644 --- a/src/locales/bg/translation.json +++ b/src/locales/bg/translation.json @@ -29,7 +29,7 @@ "need_help": "Имате нужда от помощ??" }, "header": { - "search": "Търси игри", + "search": "Търсене", "home": "Начало", "catalogue": "Каталог", "downloads": "Изтегляния", @@ -65,7 +65,7 @@ "calculating_eta": "Калкулиране на оставащо време…", "downloading_metadata": "Изтегляне на метадата…", "filter": "Филтрирай repacks", - "requirements": "Състемни изисквания", + "requirements": "Системни изисквания", "minimum": "Минимални", "recommended": "Препоръчителни", "paused": "Паузирано", @@ -79,8 +79,8 @@ "add_to_library": "Добави в библиотеката", "remove_from_library": "Премахни от библиотеката", "no_downloads": "Няма налични изтегляния", - "play_time": "Играно {{amount}}", - "last_time_played": "Последно играно {{period}}", + "play_time": "Игрално време {{amount}}", + "last_time_played": "Последно пускане {{period}}", "not_played_yet": "Не сте играли {{title}} все още", "next_suggestion": "Следващо предложение", "play": "Пускане", @@ -110,7 +110,7 @@ "remove_from_library_description": "Това ще премахне {{game}} от Библиотеката", "options": "Опции", "executable_section_title": "Стартиращ файл", - "executable_section_description": "Пътят на файла, който ще се изпълни, когато се щракне върху \"Играй\"", + "executable_section_description": "Пътят на файла, който ще се изпълни, когато се щракне върху \"Пускане\"", "downloads_secion_title": "Свалени", "downloads_section_description": "Вижте актуализации или други версии на тази игра", "danger_zone_section_title": "Опасна зона", @@ -162,7 +162,7 @@ "no_download_option_info": "Няма налични данни", "backup_deletion_failed": "Неуспешно изтриване на резервно копие", "max_number_of_artifacts_reached": "Достигнат максимален брой резервни копия за тази игра", - "achievements_not_sync": "Постиженията ви не са синхронизирани", + "achievements_not_sync": "Постиженията не са синхронизирани", "manage_files_description": "Управлявайте кои файлове ще бъдат архивирани и възстановени", "select_folder": "Избери папка", "backup_from": "Резервно копие от {{date}}", @@ -198,7 +198,7 @@ "downloads_completed": "Приключени", "queued": "В опашка", "no_downloads_title": "Толкова е празно", - "no_downloads_description": "Все още не сте изтеглили нищо с Hydra, но никога не е късно да започнете..", + "no_downloads_description": "Все още не сте изтеглили нищо с Hydra, но никога не е късно да започнете...", "checking_files": "Проверка на файлове…" }, "settings": { @@ -331,7 +331,7 @@ "blocked_users": "Блокирани потребители", "unblock": "Отблокирай", "no_friends_added": "Не сте добавили приятели", - "pending": "Чакащо", + "pending": "Чакащи", "no_pending_invites": "Нямате чакащи покани", "no_blocked_users": "Нямате блокирани потребители", "friend_code_copied": "Приятелския код е копиран", diff --git a/src/locales/cs/translation.json b/src/locales/cs/translation.json index b5b602c5..d839fa46 100644 --- a/src/locales/cs/translation.json +++ b/src/locales/cs/translation.json @@ -6,7 +6,11 @@ "home": { "featured": "Doporučené", "surprise_me": "Překvap mě", - "no_results": "Výsledek nenalezen" + "no_results": "Výsledek nenalezen", + "start_typing": "Začni psát pro vyhledávání...", + "hot": "Teď populární", + "weekly": "📅 Nejlepší hry týdne", + "achievements": "🏆 Hry k překonání" }, "sidebar": { "catalogue": "Katalog", @@ -20,7 +24,9 @@ "home": "Domov", "queued": "{{title}} (V řadě)", "game_has_no_executable": "Hra nemá zvolen žádný spustitelný soubor", - "sign_in": "Přihlásit se" + "sign_in": "Přihlásit se", + "friends": "Přátelé", + "need_help": "Potřebujete pomoc?" }, "header": { "search": "Vyhledat hry", @@ -113,7 +119,54 @@ "download_paused": "Stahování pozastaveno", "last_downloaded_option": "Poslední stažená možnost", "create_shortcut_success": "Zástupce vytvořen úspěšně", - "create_shortcut_error": "Chyba při pokusu vytvořit zástupce" + "create_shortcut_error": "Chyba při pokusu vytvořit zástupce", + "nsfw_content_title": "Tahle hra obsahuje nevhodný obsah", + "nsfw_content_description": "{{title}} obsahuje obsah, který by nemusel být vhodný pro všechny věkové skupiny. Jste si jisti, že chcete pokračovat?", + "allow_nsfw_content": "Pokračovat", + "refuse_nsfw_content": "Jít zpět", + "stats": "Statistiky", + "download_count": "Stažení", + "player_count": "Aktivní hráči", + "download_error": "Tahle možnost stažení není dostupná", + "download": "Stáhnout", + "executable_path_in_use": "Spustitelný soubor již používá \"{{game}}\"", + "warning": "Varování", + "hydra_needs_to_remain_open": "Pro tohle stažení, musí Hydra zůstat otevřená až do konce stahování. Pokud Hydru zavřete dříve, postup stahování bude ztracen.", + "achievements": "Achievementy", + "achievements_count": "Achievementy {{unlockedCount}}/{{achievementsCount}}", + "cloud_save": "Uložení v cloudu", + "cloud_save_description": "Uložte si svůj postup v cloud a pokračujte v hraní na jakémkoliv zářízení", + "backups": "Zálohy", + "install_backup": "Nainstalovat", + "delete_backup": "Smazat", + "create_backup": "Vytvořit zálohu", + "last_backup_date": "Poslední záloha vytvořena {{date}}", + "no_backup_preview": "Žádné zálohy nebyly nalezeny pro tuhle hru", + "restoring_backup": "Obnovuji zálohu ({{progress}} hotovo)...", + "uploading_backup": "Nahrávání zálohy...", + "no_backups": "Nemáte zatím vytvořeny žádné zálohy pro tuto hru", + "backup_uploaded": "Záloha nahrána", + "backup_deleted": "Záloha odstraněna", + "backup_restored": "Záloha obnovena", + "see_all_achievements": "Zobrazit všechny achievementy", + "sign_in_to_see_achievements": "Musíte se přihlásit pro zobrazení achievementů", + "mapping_method_automatic": "Automaticky", + "mapping_method_manual": "Manuálně", + "mapping_method_label": "Metoda mapování", + "files_automatically_mapped": "Soubory automaticky zmapovány", + "no_backups_created": "Žádné zálohy nebyly vytvořeny pro tuto hru", + "manage_files": "Spravovat soubory", + "loading_save_preview": "Hledání uložených her...", + "wine_prefix": "Wine Prefix", + "wine_prefix_description": "Wine Prefix použit pro spuštění této hry", + "no_download_option_info": "Žádné informace nejsou dostupny", + "backup_deletion_failed": "Nepovedlo se odstranit zálohu", + "max_number_of_artifacts_reached": "Dosáhli jste maximálního počtu záloh pro tuto hru", + "achievements_not_sync": "Vaše achievementy nejsou synchronizovány", + "manage_files_description": "Spravovat, které soubory budou zálohovány a obnoveny", + "select_folder": "Vybrat složku", + "backup_from": "Zálohy z {{date}}", + "custom_backup_location_set": "Vlastní umístění záloh nastaveno" }, "activation": { "title": "Aktivovat hydru", @@ -189,7 +242,21 @@ "found_download_option_zero": "Nenalezena žádná možnost stahování", "found_download_option_one": "Nalezena {{countFormatted}} možnost stahování", "found_download_option_other": "Nalezeny {{countFormatted}} možnosti stahování", - "import": "Importovat" + "import": "Importovat", + "public": "Veřejné", + "private": "Soukromé", + "friends_only": "Pouze přátelé", + "privacy": "Soukromí", + "profile_visibility": "Viditelnost profilu", + "profile_visibility_description": "Vyberte si, kdo může vidět váš profil a knihovnu", + "required_field": "Toto pole je povinné", + "source_already_exists": "Tento zdroj byl již přidán", + "must_be_valid_url": "Zdroj musí být platký odkaz URL", + "blocked_users": "Zablokovaní uživatelé", + "user_unblocked": "Uživatel byl odblokován", + "enable_achievement_notifications": "Když je odemknut achievement", + "launch_minimized": "Spustit v minimalizovaném režimu", + "disable_nsfw_alert": "Deaktivovat upozornění na nevhodný obsah" }, "notifications": { "download_complete": "Stahování dokončeno", @@ -198,7 +265,9 @@ "repack_count_one": "{{count}} repack přidán", "repack_count_other": "{{count}} repacky přidány", "new_update_available": "Version {{version}} je dostupná", - "restart_to_install_update": "Restartuj Hydru pro aktualizaci" + "restart_to_install_update": "Restartuj Hydru pro aktualizaci", + "notification_achievement_unlocked_title": "Achievement pro {{game}} byl odemknut", + "notification_achievement_unlocked_body": "{{achievement}} a dalších {{count}} byly odemknuty" }, "system_tray": { "open": "Otevřít Hydru", @@ -266,6 +335,47 @@ "no_pending_invites": "Nemáte žádné příchozí žádosti", "no_blocked_users": "Nemáte nikoho zablokovaného", "friend_code_copied": "Kód přítele zkopírován", - "undo_friendship_modal_text": "Tímto zrušíte své přátelství s {{displayName}}" + "undo_friendship_modal_text": "Tímto zrušíte své přátelství s {{displayName}}", + "privacy_hint": "Pro změnu toho, kdo tohle může vidět, jděte do <0>Nastavení", + "locked_profile": "Tento profil je soukromý", + "image_process_failure": "Nastala chyba při zpracování obrázku", + "required_field": "Toto pole je povinné", + "displayname_min_length": "Uživatelské jméno musí být minimálně 3 znaky dlouhé", + "displayname_max_length": "Uživatelské jméno musí být maximálně 50 znaků dlouhé", + "report_profile": "Nahlásit profil", + "report_reason": "Proč nahlašujete tento profil?", + "report_description": "Přídavné informace", + "report_description_placeholder": "Přídavné informace", + "report": "Nahlásit", + "report_reason_hate": "Nenávistné projevy", + "report_reason_sexual_content": "Sexuální obsah", + "report_reason_violence": "Násilí", + "report_reason_spam": "Spam", + "report_reason_other": "Ostatní", + "profile_reported": "Profil nahlášen", + "your_friend_code": "Tvůj kód přítele:", + "upload_banner": "Nahrát banner profilu", + "uploading_banner": "Nahrávání banneru", + "background_image_updated": "Obrázek pozadí byl změněn" + }, + "achievement": { + "achievement_unlocked": "Achievement odemčen", + "user_achievements": "Achievementy uživatele {{displayName}}", + "your_achievements": "Vaše achievementy", + "unlocked_at": "Odemčeno:", + "subscription_needed": "Je vyžadováno předplatné Hydra Cloud pro zobrazení tohoto obsahu", + "new_achievements_unlocked": "Odemčeno {{achievementCount}} nových achievementů z {{gameCount}} her", + "achievement_progress": "{{unlockedCount}}/{{totalCount}} achievementů", + "achievements_unlocked_for_game": "Odemčeno {{achievementCount}} nových achievementů pro {{gameTitle}}" + }, + "tour": { + "subscription_tour_title": "Předplatné Hydra Cloud", + "subscribe_now": "Připojit se", + "cloud_saving": "Ukládání v cloudu", + "cloud_achievements": "Ukládejte vaše achievementy do cloudu", + "animated_profile_picture": "Animované profilové obrázky", + "premium_support": "Prémiová podpora", + "show_and_compare_achievements": "Zobraz a porovnej achievementy s ostatními uživateli", + "animated_profile_banner": "Animovaný banner na profilu" } } diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index fa47e507..940e3185 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -105,6 +105,7 @@ "open_folder": "Open folder", "open_download_location": "See downloaded files", "create_shortcut": "Create desktop shortcut", + "clear": "Clear", "remove_files": "Remove files", "remove_from_library_title": "Are you sure?", "remove_from_library_description": "This will remove {{game}} from your library", @@ -166,7 +167,8 @@ "manage_files_description": "Manage which files will be backed up and restored", "select_folder": "Select folder", "backup_from": "Backup from {{date}}", - "custom_backup_location_set": "Custom backup location set" + "custom_backup_location_set": "Custom backup location set", + "no_directory_selected": "No directory selected" }, "activation": { "title": "Activate Hydra", diff --git a/src/locales/es/translation.json b/src/locales/es/translation.json index 2830eb0c..ab34be1f 100644 --- a/src/locales/es/translation.json +++ b/src/locales/es/translation.json @@ -100,7 +100,7 @@ "open_screenshot": "Abrir captura {{number}}", "download_settings": "Ajustes de descarga", "downloader": "Método de descarga", - "select_executable": "Seleccionar ejecutable", + "select_executable": "Seleccionar", "no_executable_selected": "No se seleccionó un ejecutable", "open_folder": "Abrir carpeta", "open_download_location": "Ver archivos descargados", @@ -166,7 +166,9 @@ "manage_files_description": "Gestiona los archivos que serán respaldados y restaurados", "select_folder": "Seleccionar carpeta", "backup_from": "Copia de seguridad de {{date}}", - "custom_backup_location_set": "Se configuró la carpeta de copia de seguridad" + "custom_backup_location_set": "Se configuró la carpeta de copia de seguridad", + "clear": "Limpiar", + "no_directory_selected": "No se seleccionó un directório" }, "activation": { "title": "Activar Hydra", @@ -254,7 +256,9 @@ "must_be_valid_url": "La fuente debe ser una URL válida.", "blocked_users": "Usuarios bloqueados", "user_unblocked": "El usuario ha sido desbloqueado", - "enable_achievement_notifications": "Cuando un logro se desbloquea" + "enable_achievement_notifications": "Cuando un logro se desbloquea", + "launch_minimized": "Iniciar Hydra minimizado", + "disable_nsfw_alert": "Desactivar alerta NSFW" }, "notifications": { "download_complete": "Descarga completada", @@ -361,8 +365,10 @@ "user_achievements": "Logros de {{displayName}}", "your_achievements": "Tus Logros", "unlocked_at": "Desbloqueado el:", - "subscription_needed": "Se necesita una suscripción a Hydra Cloud se necesita para ver este contenido", - "new_achievements_unlocked": "Desbloqueados {{achievementCount}} nuevos logros de {{gameCount}} juegos" + "subscription_needed": "Se necesita una suscripción a Hydra Cloud necesita para ver este contenido", + "new_achievements_unlocked": "Desbloqueados {{achievementCount}} nuevos logros de {{gameCount}} juegos", + "achievement_progress": "{{unlockedCount}}/{{totalCount}} logros", + "achievements_unlocked_for_game": "Se han desbloqueado {{achievementCount}} nuevos logros de {{gameTitle}}" }, "tour": { "subscription_tour_title": "Suscripción Hydra Cloud", diff --git a/src/locales/pt-BR/translation.json b/src/locales/pt-BR/translation.json index 43c18a48..e724cdc3 100644 --- a/src/locales/pt-BR/translation.json +++ b/src/locales/pt-BR/translation.json @@ -162,7 +162,9 @@ "backup_from": "Backup de {{date}}", "custom_backup_location_set": "Localização customizada selecionada", "select_folder": "Selecione a pasta", - "manage_files_description": "Gerencie quais arquivos serão feitos backup" + "manage_files_description": "Gerencie quais arquivos serão feitos backup", + "clear": "Limpar", + "no_directory_selected": "Nenhum diretório selecionado" }, "activation": { "title": "Ativação", diff --git a/src/main/events/library/select-game-wine-prefix.ts b/src/main/events/library/select-game-wine-prefix.ts index a75a3cb0..d9f01c08 100644 --- a/src/main/events/library/select-game-wine-prefix.ts +++ b/src/main/events/library/select-game-wine-prefix.ts @@ -5,9 +5,9 @@ import { registerEvent } from "../register-event"; const selectGameWinePrefix = async ( _event: Electron.IpcMainInvokeEvent, id: number, - winePrefixPath: string + winePrefixPath: string | null ) => { - return gameRepository.update({ id }, { winePrefixPath }); + return gameRepository.update({ id }, { winePrefixPath: winePrefixPath }); }; registerEvent("selectGameWinePrefix", selectGameWinePrefix); diff --git a/src/main/events/library/update-executable-path.ts b/src/main/events/library/update-executable-path.ts index 9be36ab1..aee80771 100644 --- a/src/main/events/library/update-executable-path.ts +++ b/src/main/events/library/update-executable-path.ts @@ -6,14 +6,18 @@ import { parseExecutablePath } from "../helpers/parse-executable-path"; const updateExecutablePath = async ( _event: Electron.IpcMainInvokeEvent, id: number, - executablePath: string + executablePath: string | null ) => { + const parsedPath = executablePath + ? parseExecutablePath(executablePath) + : null; + return gameRepository.update( { id, }, { - executablePath: parseExecutablePath(executablePath), + executablePath: parsedPath, } ); }; diff --git a/src/main/services/download/python-instance.ts b/src/main/services/download/python-instance.ts index f59b20b8..146c6553 100644 --- a/src/main/services/download/python-instance.ts +++ b/src/main/services/download/python-instance.ts @@ -174,8 +174,10 @@ export class PythonInstance { .then((response) => response.data); } - private static async handleRpcError(_error: unknown) { - await this.rpc.get("/healthcheck").catch(() => { + private static async handleRpcError(error: unknown) { + logger.error(error); + + return this.rpc.get("/healthcheck").catch(() => { logger.error( "RPC healthcheck failed. Killing process and starting again" ); diff --git a/src/main/services/hydra-api.ts b/src/main/services/hydra-api.ts index f642f43b..bac1486a 100644 --- a/src/main/services/hydra-api.ts +++ b/src/main/services/hydra-api.ts @@ -153,21 +153,26 @@ export class HydraApi { (error) => { logger.error(" ---- RESPONSE ERROR -----"); const { config } = error; + const data = JSON.parse(config.data); + logger.error( config.method, config.baseURL, config.url, - config.headers, - config.data + omit(config.headers, ["accessToken", "refreshToken"]), + Array.isArray(data) + ? data + : omit(data, ["accessToken", "refreshToken"]) ); if (error.response) { logger.error( - "Response", + "Response error:", error.response.status, error.response.data ); } else if (error.request) { - logger.error("Request", error.request); + const errorData = error.toJSON(); + logger.error("Request error:", errorData.message); } else { logger.error("Error", error.message); } diff --git a/src/main/services/user/get-user-data.ts b/src/main/services/user/get-user-data.ts index fd4e5e1d..ff012881 100644 --- a/src/main/services/user/get-user-data.ts +++ b/src/main/services/user/get-user-data.ts @@ -44,7 +44,7 @@ export const getUserData = () => { if (err instanceof UserNotLoggedInError) { return null; } - logger.error("Failed to get logged user", err); + logger.error("Failed to get logged user"); const loggedUser = await userAuthRepository.findOne({ where: { id: 1 }, relations: { subscription: true }, diff --git a/src/main/services/window-manager.ts b/src/main/services/window-manager.ts index 4f65ef2a..426d7afe 100644 --- a/src/main/services/window-manager.ts +++ b/src/main/services/window-manager.ts @@ -85,7 +85,11 @@ export class WindowManager { return callback(details); } - if (details.url.includes("intercom.io")) { + if (details.url.includes("featurebase")) { + return callback(details); + } + + if (details.url.includes("chatwoot")) { return callback(details); } @@ -191,7 +195,7 @@ export class WindowManager { this.mainWindow?.focus(); } - public static createSystemTray(language: string) { + public static async createSystemTray(language: string) { let tray: Tray; if (process.platform === "darwin") { @@ -259,6 +263,7 @@ export class WindowManager { }, ]); + tray.setContextMenu(contextMenu); return contextMenu; }; @@ -270,6 +275,8 @@ export class WindowManager { tray.setToolTip("Hydra"); if (process.platform !== "darwin") { + await updateSystemTray(); + tray.addListener("click", () => { if (this.mainWindow) { if ( diff --git a/src/preload/index.ts b/src/preload/index.ts index 3f2f677a..f9d19644 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -87,9 +87,9 @@ contextBridge.exposeInMainWorld("electron", { ipcRenderer.invoke("addGameToLibrary", objectId, title, shop), createGameShortcut: (id: number) => ipcRenderer.invoke("createGameShortcut", id), - updateExecutablePath: (id: number, executablePath: string) => + updateExecutablePath: (id: number, executablePath: string | null) => ipcRenderer.invoke("updateExecutablePath", id, executablePath), - selectGameWinePrefix: (id: number, winePrefixPath: string) => + selectGameWinePrefix: (id: number, winePrefixPath: string | null) => ipcRenderer.invoke("selectGameWinePrefix", id, winePrefixPath), verifyExecutablePathInUse: (executablePath: string) => ipcRenderer.invoke("verifyExecutablePathInUse", executablePath), diff --git a/src/renderer/index.html b/src/renderer/index.html index 6290dfa4..5d62f4c5 100644 --- a/src/renderer/index.html +++ b/src/renderer/index.html @@ -6,7 +6,7 @@ Hydra diff --git a/src/renderer/src/app.tsx b/src/renderer/src/app.tsx index bb2f096a..1ec7507e 100644 --- a/src/renderer/src/app.tsx +++ b/src/renderer/src/app.tsx @@ -119,25 +119,13 @@ export function App() { if (response) { updateUserDetails(response); syncFriendRequests(); - - const $existingScript = document.getElementById("user-details"); - - const content = `window.userDetails = ${JSON.stringify(response)};`; - - if ($existingScript) { - $existingScript.textContent = content; - } else { - const $script = document.createElement("script"); - $script.id = "user-details"; - $script.type = "text/javascript"; - $script.textContent = content; - - document.head.appendChild($script); - } } }) .finally(() => { + if (document.getElementById("external-resources")) return; + const $script = document.createElement("script"); + $script.id = "external-resources"; $script.src = `${import.meta.env.RENDERER_VITE_EXTERNAL_RESOURCES_URL}?t=${Date.now()}`; document.head.appendChild($script); }); diff --git a/src/renderer/src/cookies.ts b/src/renderer/src/cookies.ts new file mode 100644 index 00000000..b769ed7f --- /dev/null +++ b/src/renderer/src/cookies.ts @@ -0,0 +1,46 @@ +export function addCookieInterceptor(isStaging: boolean) { + const cookieKey = isStaging ? "cookies-staging" : "cookies"; + + Object.defineProperty(document, "cookie", { + enumerable: true, + configurable: true, + get() { + return localStorage.getItem(cookieKey) || ""; + }, + set(cookieString) { + try { + const [cookieName, cookieValue] = cookieString.split(";")[0].split("="); + + const currentCookies = localStorage.getItem(cookieKey) || ""; + + const cookiesObject = parseCookieStringsToObjects(currentCookies); + cookiesObject[cookieName] = cookieValue; + + const newString = Object.entries(cookiesObject) + .map(([key, value]) => { + return key + "=" + value; + }) + .join("; "); + + localStorage.setItem(cookieKey, newString); + } catch (err) { + console.error(err); + } + }, + }); +} + +const parseCookieStringsToObjects = ( + cookieStrings: string +): { [key: string]: string } => { + const result = {}; + + if (cookieStrings === "") return result; + + cookieStrings.split(";").forEach((cookieString) => { + const [name, value] = cookieString.split("="); + result[name.trim()] = value.trim(); + }); + + return result; +}; diff --git a/src/renderer/src/declaration.d.ts b/src/renderer/src/declaration.d.ts index 2ffcfab7..93c423e0 100644 --- a/src/renderer/src/declaration.d.ts +++ b/src/renderer/src/declaration.d.ts @@ -80,8 +80,14 @@ declare global { shop: GameShop ) => Promise; createGameShortcut: (id: number) => Promise; - updateExecutablePath: (id: number, executablePath: string) => Promise; - selectGameWinePrefix: (id: number, winePrefixPath: string) => Promise; + updateExecutablePath: ( + id: number, + executablePath: string | null + ) => Promise; + selectGameWinePrefix: ( + id: number, + winePrefixPath: string | null + ) => Promise; verifyExecutablePathInUse: (executablePath: string) => Promise; getLibrary: () => Promise; openGameInstaller: (gameId: number) => Promise; diff --git a/src/renderer/src/hooks/use-user-details.ts b/src/renderer/src/hooks/use-user-details.ts index feca478c..3328c517 100644 --- a/src/renderer/src/hooks/use-user-details.ts +++ b/src/renderer/src/hooks/use-user-details.ts @@ -56,6 +56,8 @@ export function useUserDetails() { clearUserDetails(); } + window["userDetails"] = userDetails; + return userDetails; }); }, [clearUserDetails]); diff --git a/src/renderer/src/main.tsx b/src/renderer/src/main.tsx index 2d29f831..f2e326c3 100644 --- a/src/renderer/src/main.tsx +++ b/src/renderer/src/main.tsx @@ -20,6 +20,8 @@ import resources from "@locales"; import { RepacksContextProvider } from "./context"; import { SuspenseWrapper } from "./components"; +import { logger } from "./logger"; +import { addCookieInterceptor } from "./cookies"; const Home = React.lazy(() => import("./pages/home/home")); const GameDetails = React.lazy( @@ -34,6 +36,11 @@ const Achievements = React.lazy( () => import("./pages/achievements/achievements") ); +console.log = logger.log; + +const isStaging = await window.electron.isStaging(); +addCookieInterceptor(isStaging); + i18n .use(LanguageDetector) .use(initReactI18next) diff --git a/src/renderer/src/pages/game-details/modals/game-options-modal.tsx b/src/renderer/src/pages/game-details/modals/game-options-modal.tsx index 64346d52..e5c83ec4 100644 --- a/src/renderer/src/pages/game-details/modals/game-options-modal.tsx +++ b/src/renderer/src/pages/game-details/modals/game-options-modal.tsx @@ -95,6 +95,11 @@ export function GameOptionsModal({ await window.electron.openGameExecutablePath(game.id); }; + const handleClearExecutablePath = async () => { + await window.electron.updateExecutablePath(game.id, null); + updateGame(); + }; + const handleChangeWinePrefixPath = async () => { const { filePaths } = await window.electron.showOpenDialog({ properties: ["openDirectory"], @@ -106,6 +111,11 @@ export function GameOptionsModal({ } }; + const handleClearWinePrefixPath = async () => { + await window.electron.selectGameWinePrefix(game.id, null); + updateGame(); + }; + const shouldShowWinePrefixConfiguration = window.electron.platform === "linux"; @@ -145,14 +155,21 @@ export function GameOptionsModal({ disabled placeholder={t("no_executable_selected")} rightContent={ - + <> + + {game.executablePath && ( + + )} + } /> @@ -186,14 +203,24 @@ export function GameOptionsModal({ disabled placeholder={t("no_directory_selected")} rightContent={ - + <> + + {game.winePrefixPath && ( + + )} + } /> diff --git a/src/types/index.ts b/src/types/index.ts index c0269cd3..434a15e7 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -241,6 +241,7 @@ export interface Subscription { status: SubscriptionStatus; plan: { id: string; name: string }; expiresAt: string | null; + paymentMethod: "pix" | "paypal"; } export interface UserDetails { diff --git a/yarn.lock b/yarn.lock index 0220a873..b6b2d3b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1066,11 +1066,6 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== -"@intercom/messenger-js-sdk@^0.0.14": - version "0.0.14" - resolved "https://registry.yarnpkg.com/@intercom/messenger-js-sdk/-/messenger-js-sdk-0.0.14.tgz#a27999370cc0a82a2a57a779426df25a57891863" - integrity sha512-2dH4BDAh9EI90K7hUkAdZ76W79LM45Sd1OBX7t6Vzy8twpNiQ5X+7sH9G5hlJlkSGnf+vFWlFcy9TOYAyEs1hA== - "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz"