From f9906bfe9571d39bb4f1b66f7478e08c9c2e0a9e Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Sun, 15 Sep 2024 01:00:44 -0300 Subject: [PATCH 01/12] fix: message and migration --- src/main/knex-client.ts | 8 +++++++- .../20240915035339_ensure_repack_uris.ts | 17 +++++++++++++++++ .../modals/download-settings-modal.tsx | 15 +++++++++------ 3 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 src/main/migrations/20240915035339_ensure_repack_uris.ts diff --git a/src/main/knex-client.ts b/src/main/knex-client.ts index 9d045e3a..fe72a3de 100644 --- a/src/main/knex-client.ts +++ b/src/main/knex-client.ts @@ -3,12 +3,18 @@ import { databasePath } from "./constants"; import { Hydra2_0_3 } from "./migrations/20240830143811_Hydra_2_0_3"; import { RepackUris } from "./migrations/20240830143906_RepackUris"; import { UpdateUserLanguage } from "./migrations/20240913213944_update_user_language"; +import { EnsureRepackUris } from "./migrations/20240915035339_ensure_repack_uris"; export type HydraMigration = Knex.Migration & { name: string }; class MigrationSource implements Knex.MigrationSource { getMigrations(): Promise { - return Promise.resolve([Hydra2_0_3, RepackUris, UpdateUserLanguage]); + return Promise.resolve([ + Hydra2_0_3, + RepackUris, + UpdateUserLanguage, + EnsureRepackUris, + ]); } getMigrationName(migration: HydraMigration): string { return migration.name; diff --git a/src/main/migrations/20240915035339_ensure_repack_uris.ts b/src/main/migrations/20240915035339_ensure_repack_uris.ts new file mode 100644 index 00000000..64fbcd2e --- /dev/null +++ b/src/main/migrations/20240915035339_ensure_repack_uris.ts @@ -0,0 +1,17 @@ +import type { HydraMigration } from "@main/knex-client"; +import type { Knex } from "knex"; + +export const EnsureRepackUris: HydraMigration = { + name: "EnsureRepackUris", + up: async (knex: Knex) => { + await knex.schema.hasColumn("repack", "uris").then(async (exists) => { + if (!exists) { + await knex.schema.table("repack", (table) => { + table.text("uris").notNullable().defaultTo("[]"); + }); + } + }); + }, + + down: async (_knex: Knex) => {}, +}; diff --git a/src/renderer/src/pages/game-details/modals/download-settings-modal.tsx b/src/renderer/src/pages/game-details/modals/download-settings-modal.tsx index a301110a..35982b19 100644 --- a/src/renderer/src/pages/game-details/modals/download-settings-modal.tsx +++ b/src/renderer/src/pages/game-details/modals/download-settings-modal.tsx @@ -160,12 +160,15 @@ export function DownloadSettingsModal({ ))} - {selectedDownloader && selectedDownloader !== Downloader.Torrent && ( -

- {t("warning")}{" "} - {t("hydra_needs_to_remain_open")} -

- )} + {selectedDownloader != null && + selectedDownloader !== Downloader.Torrent && ( +

+ + {t("warning")} + {" "} + {t("hydra_needs_to_remain_open")} +

+ )}
Date: Sun, 15 Sep 2024 01:07:46 -0300 Subject: [PATCH 02/12] chore: version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7122e3df..dbe71a38 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hydralauncher", - "version": "2.1.1", + "version": "2.1.2", "description": "Hydra", "main": "./out/main/index.js", "author": "Los Broxas", From 214e39adda1f03cae9f7dca07f44769f0054d682 Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Sun, 15 Sep 2024 01:07:46 -0300 Subject: [PATCH 03/12] chore: version --- .../20240915035339_ensure_repack_uris.ts | 55 ++++++++++++++++--- .../components/sidebar/sidebar-profile.tsx | 1 + .../src/components/sidebar/sidebar.css.ts | 2 +- 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/src/main/migrations/20240915035339_ensure_repack_uris.ts b/src/main/migrations/20240915035339_ensure_repack_uris.ts index 64fbcd2e..48fcbdbd 100644 --- a/src/main/migrations/20240915035339_ensure_repack_uris.ts +++ b/src/main/migrations/20240915035339_ensure_repack_uris.ts @@ -4,14 +4,55 @@ import type { Knex } from "knex"; export const EnsureRepackUris: HydraMigration = { name: "EnsureRepackUris", up: async (knex: Knex) => { - await knex.schema.hasColumn("repack", "uris").then(async (exists) => { - if (!exists) { - await knex.schema.table("repack", (table) => { - table.text("uris").notNullable().defaultTo("[]"); - }); - } + await knex.schema.createTable("temporary_repack", (table) => { + const timestamp = new Date().getTime(); + table.increments("id").primary(); + table + .text("title") + .notNullable() + .unique({ indexName: "repack_title_unique_" + timestamp }); + table + .text("magnet") + .notNullable() + .unique({ indexName: "repack_magnet_unique_" + timestamp }); + table.text("repacker").notNullable(); + table.text("fileSize").notNullable(); + table.datetime("uploadDate").notNullable(); + table.datetime("createdAt").notNullable().defaultTo(knex.fn.now()); + table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now()); + table + .integer("downloadSourceId") + .references("download_source.id") + .onDelete("CASCADE"); + table.text("uris").notNullable().defaultTo("[]"); }); + await knex.raw( + `INSERT INTO "temporary_repack"("id", "title", "magnet", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId") SELECT "id", "title", "magnet", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId" FROM "repack"` + ); + await knex.schema.dropTable("repack"); + await knex.schema.renameTable("temporary_repack", "repack"); }, - down: async (_knex: Knex) => {}, + down: async (knex: Knex) => { + await knex.schema.renameTable("repack", "temporary_repack"); + await knex.schema.createTable("repack", (table) => { + table.increments("id").primary(); + table.text("title").notNullable().unique(); + table.text("magnet").notNullable().unique(); + table.integer("page"); + table.text("repacker").notNullable(); + table.text("fileSize").notNullable(); + table.datetime("uploadDate").notNullable(); + table.datetime("createdAt").notNullable().defaultTo(knex.fn.now()); + table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now()); + table + .integer("downloadSourceId") + .references("download_source.id") + .onDelete("CASCADE"); + }); + await knex.raw( + `INSERT INTO "repack"("id", "title", "magnet", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId") SELECT "id", "title", "magnet", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId" FROM "temporary_repack"` + ); + await knex.schema.dropTable("temporary_repack"); + }, }; diff --git a/src/renderer/src/components/sidebar/sidebar-profile.tsx b/src/renderer/src/components/sidebar/sidebar-profile.tsx index f9cd1b43..d688459f 100644 --- a/src/renderer/src/components/sidebar/sidebar-profile.tsx +++ b/src/renderer/src/components/sidebar/sidebar-profile.tsx @@ -100,6 +100,7 @@ export function SidebarProfile() { textOverflow: "ellipsis", whiteSpace: "nowrap", width: "100%", + textAlign: "left", }} > {gameRunning.title} diff --git a/src/renderer/src/components/sidebar/sidebar.css.ts b/src/renderer/src/components/sidebar/sidebar.css.ts index 10faf795..bfdb4eea 100644 --- a/src/renderer/src/components/sidebar/sidebar.css.ts +++ b/src/renderer/src/components/sidebar/sidebar.css.ts @@ -26,7 +26,7 @@ export const sidebar = recipe({ paddingTop: `${SPACING_UNIT * 6}px`, }, false: { - paddingTop: `${SPACING_UNIT * 2}px`, + paddingTop: `${SPACING_UNIT}px`, }, }, }, From c21ebe1ce2da9a75480f8c8e000f7ea28ba7a4a7 Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Sun, 15 Sep 2024 12:09:51 -0300 Subject: [PATCH 04/12] fix: database migration --- package.json | 2 +- src/main/knex-client.ts | 2 + .../migrations/20240830143906_RepackUris.ts | 46 +--------------- .../20240915035339_ensure_repack_uris.ts | 55 +++---------------- 4 files changed, 13 insertions(+), 92 deletions(-) diff --git a/package.json b/package.json index dbe71a38..2e084ec1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hydralauncher", - "version": "2.1.2", + "version": "2.1.3 ", "description": "Hydra", "main": "./out/main/index.js", "author": "Los Broxas", diff --git a/src/main/knex-client.ts b/src/main/knex-client.ts index fe72a3de..d7206677 100644 --- a/src/main/knex-client.ts +++ b/src/main/knex-client.ts @@ -4,6 +4,7 @@ import { Hydra2_0_3 } from "./migrations/20240830143811_Hydra_2_0_3"; import { RepackUris } from "./migrations/20240830143906_RepackUris"; import { UpdateUserLanguage } from "./migrations/20240913213944_update_user_language"; import { EnsureRepackUris } from "./migrations/20240915035339_ensure_repack_uris"; +import { app } from "electron"; export type HydraMigration = Knex.Migration & { name: string }; @@ -25,6 +26,7 @@ class MigrationSource implements Knex.MigrationSource { } export const knexClient = knex({ + debug: !app.isPackaged, client: "better-sqlite3", connection: { filename: databasePath, diff --git a/src/main/migrations/20240830143906_RepackUris.ts b/src/main/migrations/20240830143906_RepackUris.ts index 0785d50d..18bb9a59 100644 --- a/src/main/migrations/20240830143906_RepackUris.ts +++ b/src/main/migrations/20240830143906_RepackUris.ts @@ -4,55 +4,15 @@ import type { Knex } from "knex"; export const RepackUris: HydraMigration = { name: "RepackUris", up: async (knex: Knex) => { - await knex.schema.createTable("temporary_repack", (table) => { - const timestamp = new Date().getTime(); - table.increments("id").primary(); - table - .text("title") - .notNullable() - .unique({ indexName: "repack_title_unique_" + timestamp }); - table - .text("magnet") - .notNullable() - .unique({ indexName: "repack_magnet_unique_" + timestamp }); - table.text("repacker").notNullable(); - table.text("fileSize").notNullable(); - table.datetime("uploadDate").notNullable(); - table.datetime("createdAt").notNullable().defaultTo(knex.fn.now()); - table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now()); - table - .integer("downloadSourceId") - .references("download_source.id") - .onDelete("CASCADE"); + await knex.schema.alterTable("repack", (table) => { table.text("uris").notNullable().defaultTo("[]"); }); - await knex.raw( - `INSERT INTO "temporary_repack"("id", "title", "magnet", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId") SELECT "id", "title", "magnet", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId" FROM "repack"` - ); - await knex.schema.dropTable("repack"); - await knex.schema.renameTable("temporary_repack", "repack"); }, down: async (knex: Knex) => { - await knex.schema.renameTable("repack", "temporary_repack"); - await knex.schema.createTable("repack", (table) => { - table.increments("id").primary(); - table.text("title").notNullable().unique(); - table.text("magnet").notNullable().unique(); + await knex.schema.alterTable("repack", (table) => { table.integer("page"); - table.text("repacker").notNullable(); - table.text("fileSize").notNullable(); - table.datetime("uploadDate").notNullable(); - table.datetime("createdAt").notNullable().defaultTo(knex.fn.now()); - table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now()); - table - .integer("downloadSourceId") - .references("download_source.id") - .onDelete("CASCADE"); + table.dropColumn("uris"); }); - await knex.raw( - `INSERT INTO "repack"("id", "title", "magnet", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId") SELECT "id", "title", "magnet", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId" FROM "temporary_repack"` - ); - await knex.schema.dropTable("temporary_repack"); }, }; diff --git a/src/main/migrations/20240915035339_ensure_repack_uris.ts b/src/main/migrations/20240915035339_ensure_repack_uris.ts index 48fcbdbd..64fbcd2e 100644 --- a/src/main/migrations/20240915035339_ensure_repack_uris.ts +++ b/src/main/migrations/20240915035339_ensure_repack_uris.ts @@ -4,55 +4,14 @@ import type { Knex } from "knex"; export const EnsureRepackUris: HydraMigration = { name: "EnsureRepackUris", up: async (knex: Knex) => { - await knex.schema.createTable("temporary_repack", (table) => { - const timestamp = new Date().getTime(); - table.increments("id").primary(); - table - .text("title") - .notNullable() - .unique({ indexName: "repack_title_unique_" + timestamp }); - table - .text("magnet") - .notNullable() - .unique({ indexName: "repack_magnet_unique_" + timestamp }); - table.text("repacker").notNullable(); - table.text("fileSize").notNullable(); - table.datetime("uploadDate").notNullable(); - table.datetime("createdAt").notNullable().defaultTo(knex.fn.now()); - table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now()); - table - .integer("downloadSourceId") - .references("download_source.id") - .onDelete("CASCADE"); - table.text("uris").notNullable().defaultTo("[]"); + await knex.schema.hasColumn("repack", "uris").then(async (exists) => { + if (!exists) { + await knex.schema.table("repack", (table) => { + table.text("uris").notNullable().defaultTo("[]"); + }); + } }); - await knex.raw( - `INSERT INTO "temporary_repack"("id", "title", "magnet", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId") SELECT "id", "title", "magnet", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId" FROM "repack"` - ); - await knex.schema.dropTable("repack"); - await knex.schema.renameTable("temporary_repack", "repack"); }, - down: async (knex: Knex) => { - await knex.schema.renameTable("repack", "temporary_repack"); - await knex.schema.createTable("repack", (table) => { - table.increments("id").primary(); - table.text("title").notNullable().unique(); - table.text("magnet").notNullable().unique(); - table.integer("page"); - table.text("repacker").notNullable(); - table.text("fileSize").notNullable(); - table.datetime("uploadDate").notNullable(); - table.datetime("createdAt").notNullable().defaultTo(knex.fn.now()); - table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now()); - table - .integer("downloadSourceId") - .references("download_source.id") - .onDelete("CASCADE"); - }); - await knex.raw( - `INSERT INTO "repack"("id", "title", "magnet", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId") SELECT "id", "title", "magnet", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId" FROM "temporary_repack"` - ); - await knex.schema.dropTable("temporary_repack"); - }, + down: async (_knex: Knex) => {}, }; From ee02811aea7a9e17cb7f3ee82742c1516bb770b9 Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Sun, 15 Sep 2024 12:21:41 -0300 Subject: [PATCH 05/12] chore: remove space in version string --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2e084ec1..fb794294 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hydralauncher", - "version": "2.1.3 ", + "version": "2.1.3", "description": "Hydra", "main": "./out/main/index.js", "author": "Los Broxas", From 1de3a9836c188944293ca416eb7125c40379ff0e Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Mon, 16 Sep 2024 11:22:26 -0300 Subject: [PATCH 06/12] feat: update typing to match get me endpoint --- src/main/events/profile/get-me.ts | 47 +++++-------------- src/renderer/src/declaration.d.ts | 3 +- .../src/features/user-details-slice.ts | 6 +-- src/renderer/src/hooks/use-user-details.ts | 9 ++-- .../pages/game-details/sidebar/sidebar.tsx | 33 +++++++------ src/types/index.ts | 17 +++++-- 6 files changed, 53 insertions(+), 62 deletions(-) diff --git a/src/main/events/profile/get-me.ts b/src/main/events/profile/get-me.ts index 5154da8d..1eeecbf9 100644 --- a/src/main/events/profile/get-me.ts +++ b/src/main/events/profile/get-me.ts @@ -1,32 +1,14 @@ import { registerEvent } from "../register-event"; import * as Sentry from "@sentry/electron/main"; -import { HydraApi, logger } from "@main/services"; -import { UserProfile } from "@types"; +import { HydraApi } from "@main/services"; +import { ProfileVisibility, UserDetails } from "@types"; import { userAuthRepository } from "@main/repository"; -import { steamUrlBuilder, UserNotLoggedInError } from "@shared"; -import { steamGamesWorker } from "@main/workers"; - -const getSteamGame = async (objectId: string) => { - try { - const steamGame = await steamGamesWorker.run(Number(objectId), { - name: "getById", - }); - - return { - title: steamGame.name, - iconUrl: steamUrlBuilder.icon(objectId, steamGame.clientIcon), - }; - } catch (err) { - logger.error("Failed to get Steam game", err); - - return null; - } -}; +import { UserNotLoggedInError } from "@shared"; const getMe = async ( _event: Electron.IpcMainInvokeEvent -): Promise => { - return HydraApi.get(`/profile/me`) +): Promise => { + return HydraApi.get(`/profile/me`) .then(async (me) => { userAuthRepository.upsert( { @@ -38,17 +20,6 @@ const getMe = async ( ["id"] ); - if (me.currentGame) { - const steamGame = await getSteamGame(me.currentGame.objectId); - - if (steamGame) { - me.currentGame = { - ...me.currentGame, - ...steamGame, - }; - } - } - Sentry.setUser({ id: me.id, username: me.username }); return me; @@ -61,7 +32,13 @@ const getMe = async ( const loggedUser = await userAuthRepository.findOne({ where: { id: 1 } }); if (loggedUser) { - return { ...loggedUser, id: loggedUser.userId }; + return { + ...loggedUser, + id: loggedUser.userId, + username: "", + bio: "", + profileVisibility: "PUBLIC" as ProfileVisibility, + }; } return null; diff --git a/src/renderer/src/declaration.d.ts b/src/renderer/src/declaration.d.ts index 8e341ed8..26169d67 100644 --- a/src/renderer/src/declaration.d.ts +++ b/src/renderer/src/declaration.d.ts @@ -23,6 +23,7 @@ import type { GameStats, TrendingGame, UserStats, + UserDetails, } from "@types"; import type { DiskSpace } from "check-disk-space"; @@ -153,7 +154,7 @@ declare global { ) => Promise; /* Profile */ - getMe: () => Promise; + getMe: () => Promise; undoFriendship: (userId: string) => Promise; updateProfile: ( updateProfile: UpdateProfileRequest diff --git a/src/renderer/src/features/user-details-slice.ts b/src/renderer/src/features/user-details-slice.ts index 00542020..d559de09 100644 --- a/src/renderer/src/features/user-details-slice.ts +++ b/src/renderer/src/features/user-details-slice.ts @@ -1,9 +1,9 @@ import { PayloadAction, createSlice } from "@reduxjs/toolkit"; import { UserFriendModalTab } from "@renderer/pages/shared-modals/user-friend-modal"; -import type { FriendRequest, UserProfile } from "@types"; +import type { FriendRequest, UserDetails } from "@types"; export interface UserDetailsState { - userDetails: UserProfile | null; + userDetails: UserDetails | null; profileBackground: null | string; friendRequests: FriendRequest[]; isFriendsModalVisible: boolean; @@ -24,7 +24,7 @@ export const userDetailsSlice = createSlice({ name: "user-details", initialState, reducers: { - setUserDetails: (state, action: PayloadAction) => { + setUserDetails: (state, action: PayloadAction) => { state.userDetails = action.payload; }, setProfileBackground: (state, action: PayloadAction) => { diff --git a/src/renderer/src/hooks/use-user-details.ts b/src/renderer/src/hooks/use-user-details.ts index a826b008..0ae196dc 100644 --- a/src/renderer/src/hooks/use-user-details.ts +++ b/src/renderer/src/hooks/use-user-details.ts @@ -10,7 +10,7 @@ import { import type { FriendRequestAction, UpdateProfileRequest, - UserProfile, + UserDetails, } from "@types"; import { UserFriendModalTab } from "@renderer/pages/shared-modals/user-friend-modal"; @@ -40,7 +40,7 @@ export function useUserDetails() { }, [clearUserDetails]); const updateUserDetails = useCallback( - async (userDetails: UserProfile) => { + async (userDetails: UserDetails) => { dispatch(setUserDetails(userDetails)); if (userDetails.profileImageUrl) { @@ -83,7 +83,10 @@ export function useUserDetails() { const patchUser = useCallback( async (values: UpdateProfileRequest) => { const response = await window.electron.updateProfile(values); - return updateUserDetails(response); + return updateUserDetails({ + ...response, + username: userDetails?.username || "", + }); }, [updateUserDetails] ); diff --git a/src/renderer/src/pages/game-details/sidebar/sidebar.tsx b/src/renderer/src/pages/game-details/sidebar/sidebar.tsx index 1922403c..e56f0764 100644 --- a/src/renderer/src/pages/game-details/sidebar/sidebar.tsx +++ b/src/renderer/src/pages/game-details/sidebar/sidebar.tsx @@ -1,4 +1,4 @@ -import { useContext, useEffect, useState } from "react"; +import { useContext, useState } from "react"; import type { HowLongToBeatCategory, SteamAppDetails } from "@types"; import { useTranslation } from "react-i18next"; import { Button } from "@renderer/components"; @@ -9,7 +9,7 @@ import { useFormat } from "@renderer/hooks"; import { DownloadIcon, PeopleIcon } from "@primer/octicons-react"; export function Sidebar() { - const [_howLongToBeat, setHowLongToBeat] = useState<{ + const [_howLongToBeat, _setHowLongToBeat] = useState<{ isLoading: boolean; data: HowLongToBeatCategory[] | null; }>({ isLoading: true, data: null }); @@ -17,27 +17,26 @@ export function Sidebar() { const [activeRequirement, setActiveRequirement] = useState("minimum"); - const { gameTitle, shopDetails, objectID, stats } = - useContext(gameDetailsContext); + const { gameTitle, shopDetails, stats } = useContext(gameDetailsContext); const { t } = useTranslation("game_details"); const { numberFormatter } = useFormat(); - useEffect(() => { - if (objectID) { - setHowLongToBeat({ isLoading: true, data: null }); + // useEffect(() => { + // if (objectID) { + // setHowLongToBeat({ isLoading: true, data: null }); - window.electron - .getHowLongToBeat(objectID, "steam", gameTitle) - .then((howLongToBeat) => { - setHowLongToBeat({ isLoading: false, data: howLongToBeat }); - }) - .catch(() => { - setHowLongToBeat({ isLoading: false, data: null }); - }); - } - }, [objectID, gameTitle]); + // window.electron + // .getHowLongToBeat(objectID, "steam", gameTitle) + // .then((howLongToBeat) => { + // setHowLongToBeat({ isLoading: false, data: howLongToBeat }); + // }) + // .catch(() => { + // setHowLongToBeat({ isLoading: false, data: null }); + // }); + // } + // }, [objectID, gameTitle]); return (