From 6b125aff27b30b2e60f5defdef104508e143210a Mon Sep 17 00:00:00 2001 From: zxcsix-zxc <84792959+zxcsix-zxc@users.noreply.github.com> Date: Sun, 3 Nov 2024 00:50:29 +0200 Subject: [PATCH 01/21] Update translation.json Changed translation for "hot" --- src/locales/ru/translation.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/locales/ru/translation.json b/src/locales/ru/translation.json index c7299479..47bfe30c 100644 --- a/src/locales/ru/translation.json +++ b/src/locales/ru/translation.json @@ -7,7 +7,7 @@ "featured": "Рекомендованное", "surprise_me": "Удиви меня", "no_results": "Ничего не найдено", - "hot": "Сейчас жарко", + "hot": "Сейчас в топе", "start_typing": "Начинаю вводить текст для поиска...", "weekly": "📅 Лучшие игры недели" }, From dc93ef9134a0ec3accd4f712bfef6624788d2695 Mon Sep 17 00:00:00 2001 From: JackEnx Date: Tue, 5 Nov 2024 00:13:55 -0300 Subject: [PATCH 02/21] fix: linux deb download --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index a379f371..b8a15cdc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ libtorrent -cx_Freeze +cx_Freeze == 7.2.3 cx_Logging; sys_platform == 'win32' pywin32; sys_platform == 'win32' psutil From 0745f5b401fde07129d6c555f6e62095195f77a9 Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Tue, 5 Nov 2024 01:33:44 -0300 Subject: [PATCH 03/21] chore: bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index ab9a268a..b9d0d6bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hydralauncher", - "version": "3.0.4", + "version": "3.0.5", "description": "Hydra", "main": "./out/main/index.js", "author": "Los Broxas", From 42e0df29eef978ab01f63070421d76fb3bd3f8d1 Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Tue, 5 Nov 2024 12:32:54 -0300 Subject: [PATCH 04/21] fix: replace nbsp with space --- src/shared/index.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/shared/index.ts b/src/shared/index.ts index 1f17ac56..173867df 100644 --- a/src/shared/index.ts +++ b/src/shared/index.ts @@ -55,6 +55,9 @@ export const removeDuplicateSpaces = (name: string) => export const replaceDotsWithSpace = (name: string) => name.replace(/\./g, " "); +export const replaceNbspWithSpace = (name: string) => + name.replace(new RegExp(String.fromCharCode(160), "g"), " "); + export const replaceUnderscoreWithSpace = (name: string) => name.replace(/_/g, " "); @@ -69,6 +72,7 @@ export const formatName = pipe( removeSpecialEditionFromName, replaceUnderscoreWithSpace, replaceDotsWithSpace, + replaceNbspWithSpace, (str) => str.replace(/DIRECTOR'S CUT/g, ""), removeSymbolsFromName, removeDuplicateSpaces, From b82840df3b57d0b17f2f58600876c4ee5529b81a Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Tue, 5 Nov 2024 12:53:55 -0300 Subject: [PATCH 05/21] feat: add download analytics --- .../events/torrenting/start-game-download.ts | 3 ++ src/main/services/hydra-analytics.ts | 34 +++++++++++++++++++ src/main/vite-env.d.ts | 1 + 3 files changed, 38 insertions(+) create mode 100644 src/main/services/hydra-analytics.ts diff --git a/src/main/events/torrenting/start-game-download.ts b/src/main/events/torrenting/start-game-download.ts index deac1d2c..a8a250f6 100644 --- a/src/main/events/torrenting/start-game-download.ts +++ b/src/main/events/torrenting/start-game-download.ts @@ -9,6 +9,7 @@ import { createGame } from "@main/services/library-sync"; import { steamUrlBuilder } from "@shared"; import { dataSource } from "@main/data-source"; import { DownloadQueue, Game } from "@main/entity"; +import { HydraAnalytics } from "@main/services/hydra-analytics"; const startGameDownload = async ( _event: Electron.IpcMainInvokeEvent, @@ -90,6 +91,8 @@ const startGameDownload = async ( logger.error("Failed to create game download", err); }); + HydraAnalytics.postDownload(payload.uri).catch(() => {}); + await DownloadManager.cancelDownload(updatedGame!.id); await DownloadManager.startDownload(updatedGame!); diff --git a/src/main/services/hydra-analytics.ts b/src/main/services/hydra-analytics.ts new file mode 100644 index 00000000..f4a6b24c --- /dev/null +++ b/src/main/services/hydra-analytics.ts @@ -0,0 +1,34 @@ +import { userSubscriptionRepository } from "@main/repository"; +import axios from "axios"; +import { appVersion } from "@main/constants"; + +export class HydraAnalytics { + private static instance = axios.create({ + baseURL: import.meta.env.MAIN_VITE_ANALYTICS_API_URL, + headers: { "User-Agent": `Hydra Launcher v${appVersion}` }, + }); + + private static async hasActiveSubscription() { + const userSubscription = await userSubscriptionRepository.findOne({ + where: { id: 1 }, + }); + + return ( + userSubscription?.expiresAt && userSubscription.expiresAt > new Date() + ); + } + + static async postDownload(hash: string) { + const hasSubscription = await this.hasActiveSubscription(); + + return this.instance + .post("/track", { + event: "download", + attributes: { + hash, + hasSubscription, + }, + }) + .then((response) => response.data); + } +} diff --git a/src/main/vite-env.d.ts b/src/main/vite-env.d.ts index c070dcc7..86aa9d33 100644 --- a/src/main/vite-env.d.ts +++ b/src/main/vite-env.d.ts @@ -3,6 +3,7 @@ interface ImportMetaEnv { readonly MAIN_VITE_STEAMGRIDDB_API_KEY: string; readonly MAIN_VITE_API_URL: string; + readonly MAIN_VITE_ANALYTICS_API_URL: string; readonly MAIN_VITE_AUTH_URL: string; readonly MAIN_VITE_CHECKOUT_URL: string; } From e67d6059495cf90990bfb1c2849ae45c0fe57cd8 Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Tue, 5 Nov 2024 13:21:51 -0300 Subject: [PATCH 06/21] chore: add envs to gh action yml --- .github/workflows/build.yml | 2 ++ .github/workflows/release.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3ec889ad..9a560fcf 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -43,6 +43,7 @@ jobs: MAIN_VITE_API_URL: ${{ vars.MAIN_VITE_STAGING_API_URL }} MAIN_VITE_AUTH_URL: ${{ vars.MAIN_VITE_STAGING_AUTH_URL }} MAIN_VITE_CHECKOUT_URL: ${{ vars.MAIN_VITE_STAGING_CHECKOUT_URL }} + MAIN_VITE_ANALYTICS_API_URL: ${{ vars.MAIN_VITE_ANALYTICS_API_URL }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Build Windows @@ -52,6 +53,7 @@ jobs: MAIN_VITE_API_URL: ${{ vars.MAIN_VITE_STAGING_API_URL }} MAIN_VITE_AUTH_URL: ${{ vars.MAIN_VITE_STAGING_AUTH_URL }} MAIN_VITE_CHECKOUT_URL: ${{ vars.MAIN_VITE_STAGING_CHECKOUT_URL }} + MAIN_VITE_ANALYTICS_API_URL: ${{ vars.MAIN_VITE_ANALYTICS_API_URL }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create artifact diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 98a6cde4..834a73a1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -45,6 +45,7 @@ jobs: MAIN_VITE_API_URL: ${{ vars.MAIN_VITE_API_URL }} MAIN_VITE_AUTH_URL: ${{ vars.MAIN_VITE_AUTH_URL }} MAIN_VITE_CHECKOUT_URL: ${{ vars.MAIN_VITE_CHECKOUT_URL }} + MAIN_VITE_ANALYTICS_API_URL: ${{ vars.MAIN_VITE_ANALYTICS_API_URL }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Build Windows @@ -54,6 +55,7 @@ jobs: MAIN_VITE_API_URL: ${{ vars.MAIN_VITE_API_URL }} MAIN_VITE_AUTH_URL: ${{ vars.MAIN_VITE_AUTH_URL }} MAIN_VITE_CHECKOUT_URL: ${{ vars.MAIN_VITE_CHECKOUT_URL }} + MAIN_VITE_ANALYTICS_API_URL: ${{ vars.MAIN_VITE_ANALYTICS_API_URL }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Create artifact From 6d53aaa631af92d470a9f8300d0b4835eafae013 Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Tue, 5 Nov 2024 13:43:21 -0300 Subject: [PATCH 07/21] feat: parsing hash before post analytics --- src/main/events/torrenting/start-game-download.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/events/torrenting/start-game-download.ts b/src/main/events/torrenting/start-game-download.ts index a8a250f6..3fa1ce90 100644 --- a/src/main/events/torrenting/start-game-download.ts +++ b/src/main/events/torrenting/start-game-download.ts @@ -1,5 +1,5 @@ import { registerEvent } from "../register-event"; - +import parseTorrent from "parse-torrent"; import type { StartGameDownloadPayload } from "@types"; import { DownloadManager, HydraApi, logger } from "@main/services"; @@ -91,7 +91,10 @@ const startGameDownload = async ( logger.error("Failed to create game download", err); }); - HydraAnalytics.postDownload(payload.uri).catch(() => {}); + const { infoHash } = await parseTorrent(payload.uri); + if (infoHash) { + HydraAnalytics.postDownload(infoHash).catch(() => {}); + } await DownloadManager.cancelDownload(updatedGame!.id); await DownloadManager.startDownload(updatedGame!); From bdaf4d6d9bfd739aa0fcd80e81b5082ac6305c7a Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Tue, 5 Nov 2024 13:48:53 -0300 Subject: [PATCH 08/21] fix: use game iconUrl to show finish download notification --- package.json | 2 +- src/main/services/notifications/index.ts | 76 ++++++---------- yarn.lock | 109 ++++------------------- 3 files changed, 43 insertions(+), 144 deletions(-) diff --git a/package.json b/package.json index b9d0d6bc..1a29b564 100644 --- a/package.json +++ b/package.json @@ -53,10 +53,10 @@ "dexie": "^4.0.9", "electron-log": "^5.2.0", "electron-updater": "^6.3.9", + "file-type": "^19.6.0", "flexsearch": "^0.7.43", "i18next": "^23.11.2", "i18next-browser-languagedetector": "^7.2.1", - "icojs": "^0.19.4", "jsdom": "^24.0.0", "jsonwebtoken": "^9.0.2", "knex": "^3.1.0", diff --git a/src/main/services/notifications/index.ts b/src/main/services/notifications/index.ts index e4fb8f6e..f3e2541b 100644 --- a/src/main/services/notifications/index.ts +++ b/src/main/services/notifications/index.ts @@ -1,9 +1,8 @@ -import { Notification, app, nativeImage } from "electron"; +import { Notification, app } from "electron"; import { t } from "i18next"; -import { parseICO } from "icojs"; import trayIcon from "@resources/tray-icon.png?asset"; import { Game } from "@main/entity"; -import { gameRepository, userPreferencesRepository } from "@main/repository"; +import { userPreferencesRepository } from "@main/repository"; import fs from "node:fs"; import axios from "axios"; import path from "node:path"; @@ -11,37 +10,38 @@ import sound from "sound-play"; import { achievementSoundPath } from "@main/constants"; import icon from "@resources/icon.png?asset"; import { NotificationOptions, toXmlString } from "./xml"; +import { logger } from "../logger"; -const getGameIconNativeImage = async (gameId: number) => { - try { - const game = await gameRepository.findOne({ - where: { - id: gameId, - }, +async function downloadImage(url: string | null) { + if (!url) return undefined; + if (!url.startsWith("http")) return undefined; + + const fileName = url.split("/").pop()!; + const outputPath = path.join(app.getPath("temp"), fileName); + const writer = fs.createWriteStream(outputPath); + + const response = await axios.get(url, { + responseType: "stream", + }); + + response.data.pipe(writer); + + return new Promise((resolve) => { + writer.on("finish", () => { + resolve(outputPath); }); - - if (!game?.iconUrl) return undefined; - - const images = await parseICO( - Buffer.from(game.iconUrl.split("base64,")[1], "base64") - ); - - const highResIcon = images.find((image) => image.width >= 128); - if (!highResIcon) return undefined; - - return nativeImage.createFromBuffer(Buffer.from(highResIcon.buffer)); - } catch (err) { - return undefined; - } -}; + writer.on("error", () => { + logger.error("Failed to download image", { url }); + resolve(undefined); + }); + }); +} export const publishDownloadCompleteNotification = async (game: Game) => { const userPreferences = await userPreferencesRepository.findOne({ where: { id: 1 }, }); - const icon = await getGameIconNativeImage(game.id); - if (userPreferences?.downloadNotificationsEnabled) { new Notification({ title: t("download_complete", { @@ -51,7 +51,7 @@ export const publishDownloadCompleteNotification = async (game: Game) => { ns: "notifications", title: game.title, }), - icon, + icon: await downloadImage(game.iconUrl), }).show(); } }; @@ -73,28 +73,6 @@ export const publishNotificationUpdateReadyToInstall = async ( export const publishNewFriendRequestNotification = async () => {}; -async function downloadImage(url: string | null) { - if (!url) return null; - if (!url.startsWith("http")) return null; - - const fileName = url.split("/").pop()!; - const outputPath = path.join(app.getPath("temp"), fileName); - const writer = fs.createWriteStream(outputPath); - - const response = await axios.get(url, { - responseType: "stream", - }); - - response.data.pipe(writer); - - return new Promise((resolve, reject) => { - writer.on("finish", () => { - resolve(outputPath); - }); - writer.on("error", reject); - }); -} - export const publishCombinedNewAchievementNotification = async ( achievementCount, gameCount diff --git a/yarn.lock b/yarn.lock index d241181c..b6b2d3b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -480,11 +480,6 @@ resolved "https://registry.yarnpkg.com/@bufbuild/protobuf/-/protobuf-2.2.2.tgz#1a6d89603fb215dc4d4178052d05b30b83c75402" integrity sha512-UNtPCbrwrenpmrXuRwn9jYpPoweNXj8X5sMvYgsqYyaH8jQ6LfUJSk3dJLnBK+6sfYPrF4iAIo5sd5HQ+tg75A== -"@canvas/image-data@^1.0.0": - version "1.0.0" - resolved "https://registry.npmjs.org/@canvas/image-data/-/image-data-1.0.0.tgz" - integrity sha512-BxOqI5LgsIQP1odU5KMwV9yoijleOPzHL18/YvNqF9KFSGF2K/DLlYAbDQsWqd/1nbaFuSkYD/191dpMtNh4vw== - "@commitlint/cli@^19.5.0": version "19.5.0" resolved "https://registry.yarnpkg.com/@commitlint/cli/-/cli-19.5.0.tgz#a6e2f7f8397ddf9abd5ee5870e30a1bf51b7be2b" @@ -1090,21 +1085,6 @@ dependencies: minipass "^7.0.4" -"@jimp/bmp@^0.22.12": - version "0.22.12" - resolved "https://registry.yarnpkg.com/@jimp/bmp/-/bmp-0.22.12.tgz#0316044dc7b1a90274aef266d50349347fb864d4" - integrity sha512-aeI64HD0npropd+AR76MCcvvRaa+Qck6loCOS03CkkxGHN5/r336qTM5HPUdHKMDOGzqknuVPA8+kK1t03z12g== - dependencies: - "@jimp/utils" "^0.22.12" - bmp-js "^0.1.0" - -"@jimp/utils@^0.22.12": - version "0.22.12" - resolved "https://registry.npmjs.org/@jimp/utils/-/utils-0.22.12.tgz" - integrity sha512-yJ5cWUknGnilBq97ZXOyOS0HhsHOyAyjHwYfHxGbSyMTohgQI6sVyE8KPgDwH8HHW/nMKXk8TrSwAE71zt716Q== - dependencies: - regenerator-runtime "^0.13.3" - "@jridgewell/gen-mapping@^0.3.5": version "0.3.5" resolved "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz" @@ -1620,7 +1600,7 @@ "@tokenizer/token@^0.3.0": version "0.3.0" - resolved "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz" + resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== "@tootallnate/once@2": @@ -2523,11 +2503,6 @@ bluebird@^3.5.5: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -bmp-js@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" - integrity sha512-vHdS19CnY3hwiNdkaqk93DvjVLfbEcI8mys4UjuWrlX1haDmroo8o4xCzh4wD6DGV6HxRCyauwhHRqMTfERtjw== - boolean@^3.0.1: version "3.2.0" resolved "https://registry.yarnpkg.com/boolean/-/boolean-3.2.0.tgz#9e5294af4e98314494cbb17979fa54ca159f116b" @@ -3139,23 +3114,6 @@ decimal.js@^10.4.3: resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== -decode-bmp@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/decode-bmp/-/decode-bmp-0.2.1.tgz#cec3e0197ec3b6c60f02220f50e8757030ff2427" - integrity sha512-NiOaGe+GN0KJqi2STf24hfMkFitDUaIoUU3eKvP/wAbLe8o6FuW5n/x7MHPR0HKvBokp6MQY/j7w8lewEeVCIA== - dependencies: - "@canvas/image-data" "^1.0.0" - to-data-view "^1.1.0" - -decode-ico@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/decode-ico/-/decode-ico-0.4.1.tgz#e0f7373081532c7b8495bd51fb225d354e14de25" - integrity sha512-69NZfbKIzux1vBOd31al3XnMnH+2mqDhEgLdpygErm4d60N+UwA5Sq5WFjmEDQzumgB9fElojGwWG0vybVfFmA== - dependencies: - "@canvas/image-data" "^1.0.0" - decode-bmp "^0.2.0" - to-data-view "^1.1.0" - decompress-response@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" @@ -3967,13 +3925,13 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -file-type@^19.0.0: - version "19.5.0" - resolved "https://registry.yarnpkg.com/file-type/-/file-type-19.5.0.tgz#c13c5eca9c1c7270f6d5fbff70331b3c976f92b5" - integrity sha512-dMuq6WWnP6BpQY0zYJNpTtQWgeCImSMG0BTIzUBXvxbwc1HWP/E7AE4UWU9XSCOPGJuOHda0HpDnwM2FW+d90A== +file-type@^19.6.0: + version "19.6.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-19.6.0.tgz#b43d8870453363891884cf5e79bb3e4464f2efd3" + integrity sha512-VZR5I7k5wkD0HgFnMsq5hOsSc710MJMu5Nc5QYsbe38NN5iPV/XTObYLc/cpttRTf6lX538+5uO1ZQRhYibiZQ== dependencies: get-stream "^9.0.1" - strtok3 "^8.1.0" + strtok3 "^9.0.1" token-types "^6.0.0" uint8array-extras "^1.3.0" @@ -4529,18 +4487,6 @@ i18next@^23.11.2: dependencies: "@babel/runtime" "^7.23.2" -icojs@^0.19.4: - version "0.19.4" - resolved "https://registry.yarnpkg.com/icojs/-/icojs-0.19.4.tgz#fdbc9e61a0945ed1d331beb358d67f72cf7d78dc" - integrity sha512-86oNepPk2jAmbb96BPeucZI7HoSBobFlXDhhjIbwRb3wkQpvdBO5HO9KtMUNzMFT3qqQZsjLsfW+L0/9Rl9VqA== - dependencies: - "@jimp/bmp" "^0.22.12" - decode-ico "^0.4.1" - file-type "^19.0.0" - jpeg-js "^0.4.4" - pngjs "^7.0.0" - to-data-view "^2.0.0" - iconv-corefoundation@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz#31065e6ab2c9272154c8b0821151e2c88f1b002a" @@ -4955,11 +4901,6 @@ jiti@^1.19.1: resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268" integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w== -jpeg-js@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/jpeg-js/-/jpeg-js-0.4.4.tgz#a9f1c6f1f9f0fa80cdb3484ed9635054d28936aa" - integrity sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg== - "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" @@ -5961,10 +5902,10 @@ pe-library@^0.4.1: resolved "https://registry.yarnpkg.com/pe-library/-/pe-library-0.4.1.tgz#e269be0340dcb13aa6949d743da7d658c3e2fbea" integrity sha512-eRWB5LBz7PpDu4PUlwT0PhnQfTQJlDDdPa35urV4Osrm0t0AqQFGn+UIkU3klZvwJ8KPO3VbBFsXquA6p6kqZw== -peek-readable@^5.1.4: - version "5.2.0" - resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-5.2.0.tgz#7458f18126217c154938c32a185f5d05f3df3710" - integrity sha512-U94a+eXHzct7vAd19GH3UQ2dH4Satbng0MyYTMaQatL0pvYYL5CTPR25HBhKtecl+4bfu1/i3vC6k0hydO5Vcw== +peek-readable@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-5.3.1.tgz#9cc2c275cceda9f3d07a988f4f664c2080387dff" + integrity sha512-GVlENSDW6KHaXcd9zkZltB7tCLosKB/4Hg0fqBJkAoBgYG2Tn1xtMgXtSUuMU9AK/gCm/tTdT8mgAeF4YNeeqw== pend@~1.2.0: version "1.2.0" @@ -6011,11 +5952,6 @@ plist@^3.0.4, plist@^3.0.5, plist@^3.1.0: base64-js "^1.5.1" xmlbuilder "^15.1.1" -pngjs@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-7.0.0.tgz#a8b7446020ebbc6ac739db6c5415a65d17090e26" - integrity sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow== - possible-typed-array-names@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" @@ -6262,11 +6198,6 @@ reflect.getprototypeof@^1.0.4: globalthis "^1.0.3" which-builtin-type "^1.1.3" -regenerator-runtime@^0.13.3: - version "0.13.11" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" - integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== - regenerator-runtime@^0.14.0: version "0.14.1" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f" @@ -6971,13 +6902,13 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== -strtok3@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-8.1.0.tgz#9234a6f42ee03bf8569c7ae0788d5fd4e67e095b" - integrity sha512-ExzDvHYPj6F6QkSNe/JxSlBxTh3OrI6wrAIz53ulxo1c4hBJ1bT9C/JrAthEKHWG9riVH3Xzg7B03Oxty6S2Lw== +strtok3@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-9.0.1.tgz#7e3d7bbd2b829c9def6a7bb90d82e240abdd32be" + integrity sha512-ERPW+XkvX9W2A+ov07iy+ZFJpVdik04GhDA4eVogiG9hpC97Kem2iucyzhFxbFRvQ5o2UckFtKZdp1hkGvnrEw== dependencies: "@tokenizer/token" "^0.3.0" - peek-readable "^5.1.4" + peek-readable "^5.3.1" sudo-prompt@^9.2.1: version "9.2.1" @@ -7154,16 +7085,6 @@ tmp@^0.2.0: resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.3.tgz#eb783cc22bc1e8bebd0671476d46ea4eb32a79ae" integrity sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w== -to-data-view@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/to-data-view/-/to-data-view-1.1.0.tgz#08d6492b0b8deb9b29bdf1f61c23eadfa8994d00" - integrity sha512-1eAdufMg6mwgmlojAx3QeMnzB/BTVp7Tbndi3U7ftcT2zCZadjxkkmLmd97zmaxWi+sgGcgWrokmpEoy0Dn0vQ== - -to-data-view@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-data-view/-/to-data-view-2.0.0.tgz#4cc3f5c9eb59514a7436fc54c587c3c34c9b1d60" - integrity sha512-RGEM5KqlPHr+WVTPmGNAXNeFEmsBnlkxXaIfEpUYV0AST2Z5W1EGq9L/MENFrMMmL2WQr1wjkmZy/M92eKhjYA== - to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" From 9d75e3ad6fee034323c6859e69aca001143e92fd Mon Sep 17 00:00:00 2001 From: Chubby Granny Chaser Date: Tue, 5 Nov 2024 18:13:32 +0000 Subject: [PATCH 09/21] feat: adding intercom --- package.json | 1 + src/locales/en/translation.json | 3 +- src/locales/es/translation.json | 3 +- src/locales/pt-BR/translation.json | 3 +- src/locales/ru/translation.json | 3 +- src/main/services/window-manager.ts | 4 ++ src/renderer/index.html | 2 +- src/renderer/src/app.css.ts | 6 +++ src/renderer/src/app.tsx | 26 +++++++-- src/renderer/src/components/badge/badge.scss | 2 +- .../src/components/sidebar/sidebar.css.ts | 26 +++++++++ .../src/components/sidebar/sidebar.tsx | 33 +++++++++++- src/renderer/src/dexie.ts | 14 ++++- src/renderer/src/hooks/use-friendship.ts | 0 src/renderer/src/pages/home/home.tsx | 54 +++++++++++++++---- ...eat.types.ts => how-long-to-beat.types.ts} | 0 src/types/index.ts | 4 +- yarn.lock | 5 ++ 18 files changed, 165 insertions(+), 24 deletions(-) delete mode 100644 src/renderer/src/hooks/use-friendship.ts rename src/types/{howlongtobeat.types.ts => how-long-to-beat.types.ts} (100%) diff --git a/package.json b/package.json index ab9a268a..d40a2663 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "@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/en/translation.json b/src/locales/en/translation.json index abecb50d..e70eb519 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -25,7 +25,8 @@ "queued": "{{title}} (Queued)", "game_has_no_executable": "Game has no executable selected", "sign_in": "Sign in", - "friends": "Friends" + "friends": "Friends", + "need_help": "Need help?" }, "header": { "search": "Search games", diff --git a/src/locales/es/translation.json b/src/locales/es/translation.json index d155bcd6..2830eb0c 100644 --- a/src/locales/es/translation.json +++ b/src/locales/es/translation.json @@ -25,7 +25,8 @@ "queued": "{{title}} (En cola)", "game_has_no_executable": "El juego no tiene un ejecutable seleccionado", "sign_in": "Iniciar sesión", - "friends": "Amigos" + "friends": "Amigos", + "need_help": "¿Necesitas ayuda?" }, "header": { "search": "Buscar juegos", diff --git a/src/locales/pt-BR/translation.json b/src/locales/pt-BR/translation.json index 41e60338..b61a08be 100644 --- a/src/locales/pt-BR/translation.json +++ b/src/locales/pt-BR/translation.json @@ -25,7 +25,8 @@ "queued": "{{title}} (Na fila)", "game_has_no_executable": "Jogo não possui executável selecionado", "sign_in": "Login", - "friends": "Amigos" + "friends": "Amigos", + "need_help": "Precisa de ajuda?" }, "header": { "search": "Buscar jogos", diff --git a/src/locales/ru/translation.json b/src/locales/ru/translation.json index c7299479..1616bfd6 100644 --- a/src/locales/ru/translation.json +++ b/src/locales/ru/translation.json @@ -24,7 +24,8 @@ "queued": "{{title}} (В очереди)", "game_has_no_executable": "Файл запуска игры не выбран", "sign_in": "Войти", - "friends": "Друзья" + "friends": "Друзья", + "need_help": "Нужна помощь?" }, "header": { "search": "Поиск", diff --git a/src/main/services/window-manager.ts b/src/main/services/window-manager.ts index 8da2dd5e..4f65ef2a 100644 --- a/src/main/services/window-manager.ts +++ b/src/main/services/window-manager.ts @@ -85,6 +85,10 @@ export class WindowManager { return callback(details); } + if (details.url.includes("intercom.io")) { + return callback(details); + } + const headers = { "access-control-allow-origin": ["*"], "access-control-allow-methods": ["GET, POST, PUT, DELETE, OPTIONS"], diff --git a/src/renderer/index.html b/src/renderer/index.html index b53595ff..c1d8f50c 100644 --- a/src/renderer/index.html +++ b/src/renderer/index.html @@ -6,7 +6,7 @@ Hydra diff --git a/src/renderer/src/app.css.ts b/src/renderer/src/app.css.ts index a52d81f6..25c453c8 100644 --- a/src/renderer/src/app.css.ts +++ b/src/renderer/src/app.css.ts @@ -126,3 +126,9 @@ export const titleBar = style({ zIndex: "4", borderBottom: `1px solid ${vars.color.border}`, } as ComplexStyleRule); + +export const cloudText = style({ + background: "linear-gradient(270deg, #16B195 50%, #3E62C0 100%)", + backgroundClip: "text", + color: "transparent", +}); diff --git a/src/renderer/src/app.tsx b/src/renderer/src/app.tsx index 7c572a56..11522273 100644 --- a/src/renderer/src/app.tsx +++ b/src/renderer/src/app.tsx @@ -2,6 +2,8 @@ import { useCallback, useContext, useEffect, useRef } from "react"; import { Sidebar, BottomPanel, Header, Toast } from "@renderer/components"; +import Intercom from "@intercom/messenger-js-sdk"; + import { useAppDispatch, useAppSelector, @@ -34,6 +36,10 @@ export interface AppProps { children: React.ReactNode; } +Intercom({ + app_id: "pq96v8fh", +}); + export function App() { const contentRef = useRef(null); const { updateLibrary, library } = useLibrary(); @@ -54,8 +60,13 @@ export function App() { hideFriendsModal, } = useUserDetails(); - const { userDetails, fetchUserDetails, updateUserDetails, clearUserDetails } = - useUserDetails(); + const { + userDetails, + hasActiveSubscription, + fetchUserDetails, + updateUserDetails, + clearUserDetails, + } = useUserDetails(); const dispatch = useAppDispatch(); @@ -204,7 +215,9 @@ export function App() { useEffect(() => { new MutationObserver(() => { - const modal = document.body.querySelector("[role=dialog]"); + const modal = document.body.querySelector( + "[role=dialog]:not([data-intercom-frame='true'])" + ); dispatch(toggleDraggingDisabled(Boolean(modal))); }).observe(document.body, { @@ -270,7 +283,12 @@ export function App() { <> {window.electron.platform === "win32" && (
-

Hydra

+

+ Hydra + {hasActiveSubscription && ( + Cloud + )} +

)} diff --git a/src/renderer/src/components/badge/badge.scss b/src/renderer/src/components/badge/badge.scss index f1ed89e9..f32c398f 100644 --- a/src/renderer/src/components/badge/badge.scss +++ b/src/renderer/src/components/badge/badge.scss @@ -4,7 +4,7 @@ color: globals.$muted-color; font-size: 10px; padding: calc(globals.$spacing-unit / 2) globals.$spacing-unit; - border: solid 1px globals.$border-color; + border: solid 1px globals.$muted-color; border-radius: 4px; display: flex; align-items: center; diff --git a/src/renderer/src/components/sidebar/sidebar.css.ts b/src/renderer/src/components/sidebar/sidebar.css.ts index bfdb4eea..9b061d68 100644 --- a/src/renderer/src/components/sidebar/sidebar.css.ts +++ b/src/renderer/src/components/sidebar/sidebar.css.ts @@ -124,3 +124,29 @@ export const section = style({ flexDirection: "column", paddingBottom: `${SPACING_UNIT}px`, }); + +export const helpButton = style({ + color: vars.color.muted, + padding: `${SPACING_UNIT}px ${SPACING_UNIT * 2}px`, + gap: "9px", + display: "flex", + alignItems: "center", + cursor: "pointer", + boxShadow: "0px 0px 15px 0px rgba(0, 0, 0, 0.6)", + borderTop: `solid 1px ${vars.color.border}`, + transition: "background-color ease 0.1s", + ":hover": { + backgroundColor: "rgba(255, 255, 255, 0.15)", + }, +}); + +export const helpButtonIcon = style({ + background: "linear-gradient(0deg, #16B195 50%, #3E62C0 100%)", + width: "24px", + height: "24px", + display: "flex", + alignItems: "center", + justifyContent: "center", + color: "#fff", + borderRadius: "50%", +}); diff --git a/src/renderer/src/components/sidebar/sidebar.tsx b/src/renderer/src/components/sidebar/sidebar.tsx index 3159ecac..d529e942 100644 --- a/src/renderer/src/components/sidebar/sidebar.tsx +++ b/src/renderer/src/components/sidebar/sidebar.tsx @@ -5,7 +5,12 @@ import { useLocation, useNavigate } from "react-router-dom"; import type { LibraryGame } from "@types"; import { TextField } from "@renderer/components"; -import { useDownload, useLibrary, useToast } from "@renderer/hooks"; +import { + useDownload, + useLibrary, + useToast, + useUserDetails, +} from "@renderer/hooks"; import { routes } from "./routes"; @@ -15,6 +20,9 @@ import { buildGameDetailsPath } from "@renderer/helpers"; import SteamLogo from "@renderer/assets/steam-logo.svg?react"; import { SidebarProfile } from "./sidebar-profile"; import { sortBy } from "lodash-es"; +import { CommentDiscussionIcon } from "@primer/octicons-react"; + +import { show, update } from "@intercom/messenger-js-sdk"; const SIDEBAR_MIN_WIDTH = 200; const SIDEBAR_INITIAL_WIDTH = 250; @@ -42,6 +50,20 @@ export function Sidebar() { return sortBy(library, (game) => game.title); }, [library]); + const { userDetails, hasActiveSubscription } = useUserDetails(); + + useEffect(() => { + if (userDetails) { + update({ + name: userDetails.displayName, + Username: userDetails.username, + Email: userDetails.email, + "Subscription expiration date": userDetails?.subscription?.expiresAt, + "Payment status": userDetails?.subscription?.status, + }); + } + }, [userDetails, hasActiveSubscription]); + const { lastPacket, progress } = useDownload(); const { showWarningToast } = useToast(); @@ -237,6 +259,15 @@ export function Sidebar() { + {hasActiveSubscription && ( + + )} + - - ))} - - + + + ))} + + -
- {t("my_library")} +
+ {t("my_library")} - + -
    - {filteredLibrary.map((game) => ( -
  • - -
  • - ))} -
-
+ + {getGameTitle(game)} + + + + ))} + +
+ {hasActiveSubscription && ( From 9418c4acf7b891406b7b27bd987ba7dadfb7c6f6 Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Tue, 5 Nov 2024 17:09:46 -0300 Subject: [PATCH 16/21] fix: achievement filter --- src/main/services/achievements/merge-achievements.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/services/achievements/merge-achievements.ts b/src/main/services/achievements/merge-achievements.ts index fc13c56b..50780e95 100644 --- a/src/main/services/achievements/merge-achievements.ts +++ b/src/main/services/achievements/merge-achievements.ts @@ -102,7 +102,7 @@ export const mergeAchievements = async ( ); }); }) - .filter((achievement) => achievement) + .filter((achievement) => Boolean(achievement)) .map((achievement) => { return { displayName: achievement!.displayName, From b09e91a1cf58b8fd5f8c292b72e570b9c718dbcb Mon Sep 17 00:00:00 2001 From: Chubby Granny Chaser Date: Tue, 5 Nov 2024 20:29:44 +0000 Subject: [PATCH 17/21] fix: fixing analytics for ddl --- src/main/events/torrenting/start-game-download.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/events/torrenting/start-game-download.ts b/src/main/events/torrenting/start-game-download.ts index 3fa1ce90..17099450 100644 --- a/src/main/events/torrenting/start-game-download.ts +++ b/src/main/events/torrenting/start-game-download.ts @@ -91,9 +91,15 @@ const startGameDownload = async ( logger.error("Failed to create game download", err); }); - const { infoHash } = await parseTorrent(payload.uri); - if (infoHash) { - HydraAnalytics.postDownload(infoHash).catch(() => {}); + if (uri.startsWith("magnet:")) { + try { + const { infoHash } = await parseTorrent(payload.uri); + if (infoHash) { + HydraAnalytics.postDownload(infoHash).catch(() => {}); + } + } catch (err) { + logger.error("Failed to parse torrent", err); + } } await DownloadManager.cancelDownload(updatedGame!.id); From 2f8fe67f9fcacb3c55a8cbebe1227902ec17e6cb Mon Sep 17 00:00:00 2001 From: Hachi-R Date: Wed, 6 Nov 2024 02:57:52 -0300 Subject: [PATCH 18/21] feat: add option to disable NSFW warning --- src/main/entity/user-preferences.entity.ts | 3 +++ src/main/knex-client.ts | 2 ++ ...41106053733_add_disable_nsfw_popup_column.ts | 17 +++++++++++++++++ .../game-details/game-details.context.tsx | 2 +- .../src/pages/settings/settings-behavior.tsx | 10 ++++++++++ src/types/index.ts | 1 + 6 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 src/main/migrations/20241106053733_add_disable_nsfw_popup_column.ts diff --git a/src/main/entity/user-preferences.entity.ts b/src/main/entity/user-preferences.entity.ts index b43d463e..97adfd18 100644 --- a/src/main/entity/user-preferences.entity.ts +++ b/src/main/entity/user-preferences.entity.ts @@ -38,6 +38,9 @@ export class UserPreferences { @Column("boolean", { default: false }) startMinimized: boolean; + @Column("boolean", { default: false }) + disableNsfwPopup: boolean; + @CreateDateColumn() createdAt: Date; diff --git a/src/main/knex-client.ts b/src/main/knex-client.ts index eec5b054..e1d13b58 100644 --- a/src/main/knex-client.ts +++ b/src/main/knex-client.ts @@ -12,6 +12,7 @@ import { CreateUserSubscription } from "./migrations/20241015235142_create_user_ import { AddBackgroundImageUrl } from "./migrations/20241016100249_add_background_image_url"; import { AddWinePrefixToGame } from "./migrations/20241019081648_add_wine_prefix_to_game"; import { AddStartMinimizedColumn } from "./migrations/20241030171454_add_start_minimized_column"; +import { AddDisableNsfwPopupColumn } from "./migrations/20241106053733_add_disable_nsfw_popup_column"; export type HydraMigration = Knex.Migration & { name: string }; class MigrationSource implements Knex.MigrationSource { @@ -28,6 +29,7 @@ class MigrationSource implements Knex.MigrationSource { AddBackgroundImageUrl, AddWinePrefixToGame, AddStartMinimizedColumn, + AddDisableNsfwPopupColumn, ]); } getMigrationName(migration: HydraMigration): string { diff --git a/src/main/migrations/20241106053733_add_disable_nsfw_popup_column.ts b/src/main/migrations/20241106053733_add_disable_nsfw_popup_column.ts new file mode 100644 index 00000000..8fa41930 --- /dev/null +++ b/src/main/migrations/20241106053733_add_disable_nsfw_popup_column.ts @@ -0,0 +1,17 @@ +import type { HydraMigration } from "@main/knex-client"; +import type { Knex } from "knex"; + +export const AddDisableNsfwPopupColumn: HydraMigration = { + name: "AddDisableNsfwPopupColumn", + up: (knex: Knex) => { + return knex.schema.alterTable("user_preferences", (table) => { + return table.boolean("disableNsfwPopup").notNullable().defaultTo(0); + }); + }, + + down: async (knex: Knex) => { + return knex.schema.alterTable("user_preferences", (table) => { + return table.dropColumn("disableNsfwPopup"); + }); + }, +}; diff --git a/src/renderer/src/context/game-details/game-details.context.tsx b/src/renderer/src/context/game-details/game-details.context.tsx index 77aaab5d..b432ae26 100644 --- a/src/renderer/src/context/game-details/game-details.context.tsx +++ b/src/renderer/src/context/game-details/game-details.context.tsx @@ -147,7 +147,7 @@ export function GameDetailsContextProvider({ if ( result?.content_descriptors.ids.includes( SteamContentDescriptor.AdultOnlySexualContent - ) + ) && !userPreferences?.disableNsfwPopup ) { setHasNSFWContentBlocked(true); } diff --git a/src/renderer/src/pages/settings/settings-behavior.tsx b/src/renderer/src/pages/settings/settings-behavior.tsx index 4e3ef2f3..8e90b3c2 100644 --- a/src/renderer/src/pages/settings/settings-behavior.tsx +++ b/src/renderer/src/pages/settings/settings-behavior.tsx @@ -18,6 +18,7 @@ export function SettingsBehavior() { preferQuitInsteadOfHiding: false, runAtStartup: false, startMinimized: false, + disableNsfwPopup: false, }); const { t } = useTranslation("settings"); @@ -28,6 +29,7 @@ export function SettingsBehavior() { preferQuitInsteadOfHiding: userPreferences.preferQuitInsteadOfHiding, runAtStartup: userPreferences.runAtStartup, startMinimized: userPreferences.startMinimized, + disableNsfwPopup: userPreferences.disableNsfwPopup, }); } }, [userPreferences]); @@ -86,6 +88,14 @@ export function SettingsBehavior() { /> )} + + + handleChange({ disableNsfwPopup: !form.disableNsfwPopup }) + } + /> ); } diff --git a/src/types/index.ts b/src/types/index.ts index 58e5beb7..7b6321fe 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -161,6 +161,7 @@ export interface UserPreferences { preferQuitInsteadOfHiding: boolean; runAtStartup: boolean; startMinimized: boolean; + disableNsfwPopup: boolean; } export interface Steam250Game { From 56b15bf52a30a9b09c59cdaa20978895de8e3b16 Mon Sep 17 00:00:00 2001 From: Hachi-R Date: Wed, 6 Nov 2024 02:58:10 -0300 Subject: [PATCH 19/21] lint --- src/renderer/src/context/game-details/game-details.context.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/renderer/src/context/game-details/game-details.context.tsx b/src/renderer/src/context/game-details/game-details.context.tsx index b432ae26..c1f4d068 100644 --- a/src/renderer/src/context/game-details/game-details.context.tsx +++ b/src/renderer/src/context/game-details/game-details.context.tsx @@ -147,7 +147,8 @@ export function GameDetailsContextProvider({ if ( result?.content_descriptors.ids.includes( SteamContentDescriptor.AdultOnlySexualContent - ) && !userPreferences?.disableNsfwPopup + ) && + !userPreferences?.disableNsfwPopup ) { setHasNSFWContentBlocked(true); } From e7acce2dfc1d290f7be60987e1815e9f31f0012e Mon Sep 17 00:00:00 2001 From: Hachi-R Date: Wed, 6 Nov 2024 03:01:28 -0300 Subject: [PATCH 20/21] feat: add localization strings --- src/locales/en/translation.json | 3 ++- src/locales/pt-BR/translation.json | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index e70eb519..9d080d8d 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -255,7 +255,8 @@ "blocked_users": "Blocked users", "user_unblocked": "User has been unblocked", "enable_achievement_notifications": "When an achievement is unlocked", - "launch_minimized": "Launch Hydra minimized" + "launch_minimized": "Launch Hydra minimized", + "disable_nsfw_popup": "Disable NSFW warning popup" }, "notifications": { "download_complete": "Download complete", diff --git a/src/locales/pt-BR/translation.json b/src/locales/pt-BR/translation.json index b61a08be..4a1edffb 100644 --- a/src/locales/pt-BR/translation.json +++ b/src/locales/pt-BR/translation.json @@ -251,7 +251,8 @@ "blocked_users": "Usuários bloqueados", "user_unblocked": "Usuário desbloqueado", "enable_achievement_notifications": "Quando uma conquista é desbloqueada", - "launch_minimized": "Iniciar o Hydra minimizado" + "launch_minimized": "Iniciar o Hydra minimizado", + "disable_nsfw_popup": "Desativar popup de conteúdo impróprio" }, "notifications": { "download_complete": "Download concluído", From aaee27732d56786e28709c8e3d2e3e6712ba7576 Mon Sep 17 00:00:00 2001 From: Hachi-R Date: Wed, 6 Nov 2024 20:44:56 -0300 Subject: [PATCH 21/21] refactor: rename all "popup" strings to "alert" --- src/locales/en/translation.json | 2 +- src/locales/pt-BR/translation.json | 2 +- src/main/entity/user-preferences.entity.ts | 2 +- src/main/knex-client.ts | 4 ++-- ...=> 20241106053733_add_disable_nsfw_alert_column.ts} | 8 ++++---- .../src/context/game-details/game-details.context.tsx | 2 +- src/renderer/src/pages/settings/settings-behavior.tsx | 10 +++++----- src/types/index.ts | 2 +- 8 files changed, 16 insertions(+), 16 deletions(-) rename src/main/migrations/{20241106053733_add_disable_nsfw_popup_column.ts => 20241106053733_add_disable_nsfw_alert_column.ts} (60%) diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 9d080d8d..fa47e507 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -256,7 +256,7 @@ "user_unblocked": "User has been unblocked", "enable_achievement_notifications": "When an achievement is unlocked", "launch_minimized": "Launch Hydra minimized", - "disable_nsfw_popup": "Disable NSFW warning popup" + "disable_nsfw_alert": "Disable NSFW alert" }, "notifications": { "download_complete": "Download complete", diff --git a/src/locales/pt-BR/translation.json b/src/locales/pt-BR/translation.json index 4a1edffb..43c18a48 100644 --- a/src/locales/pt-BR/translation.json +++ b/src/locales/pt-BR/translation.json @@ -252,7 +252,7 @@ "user_unblocked": "Usuário desbloqueado", "enable_achievement_notifications": "Quando uma conquista é desbloqueada", "launch_minimized": "Iniciar o Hydra minimizado", - "disable_nsfw_popup": "Desativar popup de conteúdo impróprio" + "disable_nsfw_alert": "Desativar alerta de conteúdo inapropriado" }, "notifications": { "download_complete": "Download concluído", diff --git a/src/main/entity/user-preferences.entity.ts b/src/main/entity/user-preferences.entity.ts index 97adfd18..357dfb50 100644 --- a/src/main/entity/user-preferences.entity.ts +++ b/src/main/entity/user-preferences.entity.ts @@ -39,7 +39,7 @@ export class UserPreferences { startMinimized: boolean; @Column("boolean", { default: false }) - disableNsfwPopup: boolean; + disableNsfwAlert: boolean; @CreateDateColumn() createdAt: Date; diff --git a/src/main/knex-client.ts b/src/main/knex-client.ts index e1d13b58..988d42da 100644 --- a/src/main/knex-client.ts +++ b/src/main/knex-client.ts @@ -12,7 +12,7 @@ import { CreateUserSubscription } from "./migrations/20241015235142_create_user_ import { AddBackgroundImageUrl } from "./migrations/20241016100249_add_background_image_url"; import { AddWinePrefixToGame } from "./migrations/20241019081648_add_wine_prefix_to_game"; import { AddStartMinimizedColumn } from "./migrations/20241030171454_add_start_minimized_column"; -import { AddDisableNsfwPopupColumn } from "./migrations/20241106053733_add_disable_nsfw_popup_column"; +import { AddDisableNsfwAlertColumn } from "./migrations/20241106053733_add_disable_nsfw_alert_column"; export type HydraMigration = Knex.Migration & { name: string }; class MigrationSource implements Knex.MigrationSource { @@ -29,7 +29,7 @@ class MigrationSource implements Knex.MigrationSource { AddBackgroundImageUrl, AddWinePrefixToGame, AddStartMinimizedColumn, - AddDisableNsfwPopupColumn, + AddDisableNsfwAlertColumn, ]); } getMigrationName(migration: HydraMigration): string { diff --git a/src/main/migrations/20241106053733_add_disable_nsfw_popup_column.ts b/src/main/migrations/20241106053733_add_disable_nsfw_alert_column.ts similarity index 60% rename from src/main/migrations/20241106053733_add_disable_nsfw_popup_column.ts rename to src/main/migrations/20241106053733_add_disable_nsfw_alert_column.ts index 8fa41930..a248dd2b 100644 --- a/src/main/migrations/20241106053733_add_disable_nsfw_popup_column.ts +++ b/src/main/migrations/20241106053733_add_disable_nsfw_alert_column.ts @@ -1,17 +1,17 @@ import type { HydraMigration } from "@main/knex-client"; import type { Knex } from "knex"; -export const AddDisableNsfwPopupColumn: HydraMigration = { - name: "AddDisableNsfwPopupColumn", +export const AddDisableNsfwAlertColumn: HydraMigration = { + name: "AddDisableNsfwAlertColumn", up: (knex: Knex) => { return knex.schema.alterTable("user_preferences", (table) => { - return table.boolean("disableNsfwPopup").notNullable().defaultTo(0); + return table.boolean("disableNsfwAlert").notNullable().defaultTo(0); }); }, down: async (knex: Knex) => { return knex.schema.alterTable("user_preferences", (table) => { - return table.dropColumn("disableNsfwPopup"); + return table.dropColumn("disableNsfwAlert"); }); }, }; diff --git a/src/renderer/src/context/game-details/game-details.context.tsx b/src/renderer/src/context/game-details/game-details.context.tsx index c1f4d068..398d6c27 100644 --- a/src/renderer/src/context/game-details/game-details.context.tsx +++ b/src/renderer/src/context/game-details/game-details.context.tsx @@ -148,7 +148,7 @@ export function GameDetailsContextProvider({ result?.content_descriptors.ids.includes( SteamContentDescriptor.AdultOnlySexualContent ) && - !userPreferences?.disableNsfwPopup + !userPreferences?.disableNsfwAlert ) { setHasNSFWContentBlocked(true); } diff --git a/src/renderer/src/pages/settings/settings-behavior.tsx b/src/renderer/src/pages/settings/settings-behavior.tsx index 8e90b3c2..b4b91dd2 100644 --- a/src/renderer/src/pages/settings/settings-behavior.tsx +++ b/src/renderer/src/pages/settings/settings-behavior.tsx @@ -18,7 +18,7 @@ export function SettingsBehavior() { preferQuitInsteadOfHiding: false, runAtStartup: false, startMinimized: false, - disableNsfwPopup: false, + disableNsfwAlert: false, }); const { t } = useTranslation("settings"); @@ -29,7 +29,7 @@ export function SettingsBehavior() { preferQuitInsteadOfHiding: userPreferences.preferQuitInsteadOfHiding, runAtStartup: userPreferences.runAtStartup, startMinimized: userPreferences.startMinimized, - disableNsfwPopup: userPreferences.disableNsfwPopup, + disableNsfwAlert: userPreferences.disableNsfwAlert, }); } }, [userPreferences]); @@ -90,10 +90,10 @@ export function SettingsBehavior() { )} - handleChange({ disableNsfwPopup: !form.disableNsfwPopup }) + handleChange({ disableNsfwAlert: !form.disableNsfwAlert }) } /> diff --git a/src/types/index.ts b/src/types/index.ts index 7b6321fe..c0269cd3 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -161,7 +161,7 @@ export interface UserPreferences { preferQuitInsteadOfHiding: boolean; runAtStartup: boolean; startMinimized: boolean; - disableNsfwPopup: boolean; + disableNsfwAlert: boolean; } export interface Steam250Game {