From 1542b346af0299c47069e1ded41011ce04d3be9d Mon Sep 17 00:00:00 2001 From: Antecess <59663394+xxDRV@users.noreply.github.com> Date: Fri, 23 Aug 2024 01:22:28 +0500 Subject: [PATCH 01/12] Updated RU to fit new features --- src/locales/ru/translation.json | 37 +++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/locales/ru/translation.json b/src/locales/ru/translation.json index f6f18d11..89d16b28 100644 --- a/src/locales/ru/translation.json +++ b/src/locales/ru/translation.json @@ -177,9 +177,6 @@ "download_count_zero": "В списке нет загрузок", "download_count_one": "{{countFormatted}} загрузка в списке", "download_count_other": "{{countFormatted}} загрузок в списке", - "download_options_zero": "Нет доступных загрузок", - "download_options_one": "{{countFormatted}} вариант загрузки доступен", - "download_options_other": "{{countFormatted}} вариантов загрузки доступно", "download_source_url": "Ссылка на источник", "add_download_source_description": "Вставьте ссылку на .json-файл", "download_source_up_to_date": "Обновлён", @@ -241,6 +238,38 @@ "successfully_signed_out": "Успешный выход из аккаунта", "sign_out": "Выйти", "playing_for": "Сыграно {{amount}}", - "sign_out_modal_text": "Ваша библиотека связана с текущей учетной записью. При выходе из системы ваша библиотека станет недоступна, и прогресс не будет сохранен. Выйти?" + "sign_out_modal_text": "Ваша библиотека связана с текущей учетной записью. При выходе из системы ваша библиотека станет недоступна, и прогресс не будет сохранен. Выйти?", + "add_friends": "Добавить друзей", + "add": "Добавить", + "friend_code": "Код друга", + "see_profile": "Просмотреть профиль", + "sending": "Отправка", + "friend_request_sent": "Запрос в друзья отправлен", + "friends": "Друзья", + "friends_list": "Список друзей", + "user_not_found": "Пользователь не найден", + "block_user": "Заблокировать пользователя", + "add_friend": "Добавить друга", + "request_sent": "Запрос отправлен", + "request_received": "Запрос получен", + "accept_request": "Принять запрос", + "ignore_request": "Игнорировать запрос", + "cancel_request": "Отменить запрос", + "undo_friendship": "Удалить друга", + "request_accepted": "Запрос принят", + "user_blocked_successfully": "Пользователь успешно заблокирован", + "user_block_modal_text": "{{displayName}} будет заблокирован", + "settings": "Настройки", + "public": "Публичный", + "private": "Приватный", + "friends_only": "Только друзья", + "privacy": "Приватность", + "blocked_users": "Заблокированные пользователи", + "unblock": "Разблокировать", + "no_friends_added": "Вы ещё не добавили ни одного друга", + "pending": "Ожидание", + "no_pending_invites": "У вас нет запросов ожидающих ответа", + "no_blocked_users": "Вы не заблокировали ни одного пользователя", + "friend_code_copied": "Код друга скопирован" } } From 81aa25fa5293d2d17e67b8c65012ccf50823a605 Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Thu, 22 Aug 2024 23:50:35 -0300 Subject: [PATCH 02/12] feat: write migrations --- .prettierignore | 1 - package.json | 6 +- src/main/data-source.ts | 4 +- src/main/entity/repack.entity.ts | 6 - src/main/index.ts | 17 ++- src/main/knex.ts | 14 +++ .../migrations/1724081695967-Hydra_2_0_3.ts | 50 -------- .../1724081984535-DowloadsRefactor.ts | 20 ---- src/main/migrations/1_Hydra_2_0_3.ts | 110 ++++++++++++++++++ src/main/migrations/2_DowloadsRefactor.ts | 47 ++++++++ src/main/migrations/index.ts | 2 - yarn.lock | 86 ++++++++++++-- 12 files changed, 270 insertions(+), 93 deletions(-) create mode 100644 src/main/knex.ts delete mode 100644 src/main/migrations/1724081695967-Hydra_2_0_3.ts delete mode 100644 src/main/migrations/1724081984535-DowloadsRefactor.ts create mode 100644 src/main/migrations/1_Hydra_2_0_3.ts create mode 100644 src/main/migrations/2_DowloadsRefactor.ts delete mode 100644 src/main/migrations/index.ts diff --git a/.prettierignore b/.prettierignore index 9b6e9df6..05d298a1 100644 --- a/.prettierignore +++ b/.prettierignore @@ -5,4 +5,3 @@ pnpm-lock.yaml LICENSE.md tsconfig.json tsconfig.*.json -src/main/migrations diff --git a/package.json b/package.json index aa77084e..113b2e20 100644 --- a/package.json +++ b/package.json @@ -28,8 +28,7 @@ "build:win": "electron-vite build && electron-builder --win", "build:mac": "electron-vite build && electron-builder --mac", "build:linux": "electron-vite build && electron-builder --linux", - "prepare": "husky", - "typeorm:migration-create": "yarn typeorm migration:create" + "prepare": "husky" }, "dependencies": { "@electron-toolkit/preload": "^3.0.0", @@ -43,7 +42,7 @@ "@vanilla-extract/recipes": "^0.5.2", "auto-launch": "^5.0.6", "axios": "^1.6.8", - "better-sqlite3": "^9.5.0", + "better-sqlite3": "^11.2.1", "check-disk-space": "^3.4.0", "classnames": "^2.5.1", "color": "^4.2.3", @@ -61,6 +60,7 @@ "iso-639-1": "3.1.2", "jsdom": "^24.0.0", "jsonwebtoken": "^9.0.2", + "knex": "^3.1.0", "lodash-es": "^4.17.21", "lottie-react": "^2.4.0", "parse-torrent": "^11.0.16", diff --git a/src/main/data-source.ts b/src/main/data-source.ts index 446ccbdc..29c72f8c 100644 --- a/src/main/data-source.ts +++ b/src/main/data-source.ts @@ -10,7 +10,6 @@ import { } from "@main/entity"; import { databasePath } from "./constants"; -import * as migrations from "./migrations"; export const dataSource = new DataSource({ type: "better-sqlite3", @@ -23,7 +22,6 @@ export const dataSource = new DataSource({ DownloadQueue, UserAuth, ], - synchronize: true, + synchronize: false, database: databasePath, - migrations, }); diff --git a/src/main/entity/repack.entity.ts b/src/main/entity/repack.entity.ts index ff3f16cb..36de2a7c 100644 --- a/src/main/entity/repack.entity.ts +++ b/src/main/entity/repack.entity.ts @@ -22,12 +22,6 @@ export class Repack { @Column("text", { unique: true }) magnet: string; - /** - * @deprecated Direct scraping capability has been removed - */ - @Column("int", { nullable: true }) - page: number; - @Column("text") repacker: string; diff --git a/src/main/index.ts b/src/main/index.ts index e288302b..3e14a1ba 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -9,6 +9,7 @@ import { logger, PythonInstance, WindowManager } from "@main/services"; import { dataSource } from "@main/data-source"; import * as resources from "@locales"; import { userPreferencesRepository } from "@main/repository"; +import { knexClient, migrationConfig } from "./knex"; const { autoUpdater } = updater; @@ -63,8 +64,22 @@ app.whenReady().then(async () => { return net.fetch(url.pathToFileURL(decodeURI(filePath)).toString()); }); + await knexClient.migrate.list(migrationConfig).then((result) => { + console.log("Migrations to run:", result[1]); + }); + + await knexClient.migrate + .latest(migrationConfig) + .then(() => { + console.log("Migrations executed successfully"); + }) + .catch((err) => { + console.log("Migrations failed to run:", err); + }); + + await knexClient.destroy(); + await dataSource.initialize(); - await dataSource.runMigrations(); await import("./main"); diff --git a/src/main/knex.ts b/src/main/knex.ts new file mode 100644 index 00000000..2e5cc27e --- /dev/null +++ b/src/main/knex.ts @@ -0,0 +1,14 @@ +import knex, { Knex } from "knex"; +import { databasePath } from "./constants"; +import path from "node:path"; + +export const knexClient = knex({ + client: "better-sqlite3", + connection: { + filename: databasePath, + }, +}); + +export const migrationConfig: Knex.MigratorConfig = { + directory: path.resolve(__dirname, "migrations"), +}; diff --git a/src/main/migrations/1724081695967-Hydra_2_0_3.ts b/src/main/migrations/1724081695967-Hydra_2_0_3.ts deleted file mode 100644 index 5ab18acb..00000000 --- a/src/main/migrations/1724081695967-Hydra_2_0_3.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; - -export class Hydra2031724081695967 implements MigrationInterface { - name = 'Hydra2031724081695967' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE IF NOT EXISTS "game" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "objectID" text NOT NULL, "remoteId" text, "title" text NOT NULL, "iconUrl" text, "folderName" text, "downloadPath" text, "executablePath" text, "playTimeInMilliseconds" integer NOT NULL DEFAULT (0), "shop" text NOT NULL, "status" text, "downloader" integer NOT NULL DEFAULT (1), "progress" float NOT NULL DEFAULT (0), "bytesDownloaded" integer NOT NULL DEFAULT (0), "lastTimePlayed" datetime, "fileSize" float NOT NULL DEFAULT (0), "uri" text, "isDeleted" boolean NOT NULL DEFAULT (0), "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "repackId" integer, CONSTRAINT "UQ_04293f46e8db3deaec8dfb69264" UNIQUE ("objectID"), CONSTRAINT "UQ_6dac8c3148e141251a4864e94d4" UNIQUE ("remoteId"), CONSTRAINT "REL_0c1d6445ad047d9bbd256f961f" UNIQUE ("repackId"))`); - await queryRunner.query(`CREATE TABLE IF NOT EXISTS "download_source" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "url" text, "name" text NOT NULL, "etag" text, "downloadCount" integer NOT NULL DEFAULT (0), "status" text NOT NULL DEFAULT (0), "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), CONSTRAINT "UQ_aec2879321a87e9bb2ed477981a" UNIQUE ("url"))`); - await queryRunner.query(`CREATE TABLE IF NOT EXISTS "repack" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "title" text NOT NULL, "magnet" text NOT NULL, "page" integer, "repacker" text NOT NULL, "fileSize" text NOT NULL, "uploadDate" datetime NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "downloadSourceId" integer, CONSTRAINT "UQ_a46a68496754a4d429ddf9d48ec" UNIQUE ("title"), CONSTRAINT "UQ_5e8d57798643e693bced32095d2" UNIQUE ("magnet"))`); - await queryRunner.query(`CREATE TABLE IF NOT EXISTS "user_preferences" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "downloadsPath" text, "language" text NOT NULL DEFAULT ('en'), "realDebridApiToken" text, "downloadNotificationsEnabled" boolean NOT NULL DEFAULT (0), "repackUpdatesNotificationsEnabled" boolean NOT NULL DEFAULT (0), "preferQuitInsteadOfHiding" boolean NOT NULL DEFAULT (0), "runAtStartup" boolean NOT NULL DEFAULT (0), "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')))`); - await queryRunner.query(`CREATE TABLE IF NOT EXISTS "game_shop_cache" ("objectID" text PRIMARY KEY NOT NULL, "shop" text NOT NULL, "serializedData" text, "howLongToBeatSerializedData" text, "language" text, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')))`); - await queryRunner.query(`CREATE TABLE IF NOT EXISTS "download_queue" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "gameId" integer, CONSTRAINT "REL_aed852c94d9ded617a7a07f541" UNIQUE ("gameId"))`); - await queryRunner.query(`CREATE TABLE IF NOT EXISTS "user_auth" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "userId" text NOT NULL DEFAULT (''), "displayName" text NOT NULL DEFAULT (''), "profileImageUrl" text, "accessToken" text NOT NULL DEFAULT (''), "refreshToken" text NOT NULL DEFAULT (''), "tokenExpirationTimestamp" integer NOT NULL DEFAULT (0), "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')))`); - await queryRunner.query(`CREATE TABLE IF NOT EXISTS "temporary_game" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "objectID" text NOT NULL, "remoteId" text, "title" text NOT NULL, "iconUrl" text, "folderName" text, "downloadPath" text, "executablePath" text, "playTimeInMilliseconds" integer NOT NULL DEFAULT (0), "shop" text NOT NULL, "status" text, "downloader" integer NOT NULL DEFAULT (1), "progress" float NOT NULL DEFAULT (0), "bytesDownloaded" integer NOT NULL DEFAULT (0), "lastTimePlayed" datetime, "fileSize" float NOT NULL DEFAULT (0), "uri" text, "isDeleted" boolean NOT NULL DEFAULT (0), "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "repackId" integer, CONSTRAINT "UQ_04293f46e8db3deaec8dfb69264" UNIQUE ("objectID"), CONSTRAINT "UQ_6dac8c3148e141251a4864e94d4" UNIQUE ("remoteId"), CONSTRAINT "REL_0c1d6445ad047d9bbd256f961f" UNIQUE ("repackId"), CONSTRAINT "FK_0c1d6445ad047d9bbd256f961f6" FOREIGN KEY ("repackId") REFERENCES "repack" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`); - await queryRunner.query(`INSERT INTO "temporary_game"("id", "objectID", "remoteId", "title", "iconUrl", "folderName", "downloadPath", "executablePath", "playTimeInMilliseconds", "shop", "status", "downloader", "progress", "bytesDownloaded", "lastTimePlayed", "fileSize", "uri", "isDeleted", "createdAt", "updatedAt", "repackId") SELECT "id", "objectID", "remoteId", "title", "iconUrl", "folderName", "downloadPath", "executablePath", "playTimeInMilliseconds", "shop", "status", "downloader", "progress", "bytesDownloaded", "lastTimePlayed", "fileSize", "uri", "isDeleted", "createdAt", "updatedAt", "repackId" FROM "game"`); - await queryRunner.query(`DROP TABLE "game"`); - await queryRunner.query(`ALTER TABLE "temporary_game" RENAME TO "game"`); - await queryRunner.query(`CREATE TABLE IF NOT EXISTS "temporary_repack" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "title" text NOT NULL, "magnet" text NOT NULL, "page" integer, "repacker" text NOT NULL, "fileSize" text NOT NULL, "uploadDate" datetime NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "downloadSourceId" integer, CONSTRAINT "UQ_a46a68496754a4d429ddf9d48ec" UNIQUE ("title"), CONSTRAINT "UQ_5e8d57798643e693bced32095d2" UNIQUE ("magnet"), CONSTRAINT "FK_13f131029be1dd361fd3cd9c2a6" FOREIGN KEY ("downloadSourceId") REFERENCES "download_source" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`); - await queryRunner.query(`INSERT INTO "temporary_repack"("id", "title", "magnet", "page", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId") SELECT "id", "title", "magnet", "page", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId" FROM "repack"`); - await queryRunner.query(`DROP TABLE "repack"`); - await queryRunner.query(`ALTER TABLE "temporary_repack" RENAME TO "repack"`); - await queryRunner.query(`CREATE TABLE IF NOT EXISTS "temporary_download_queue" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "gameId" integer, CONSTRAINT "REL_aed852c94d9ded617a7a07f541" UNIQUE ("gameId"), CONSTRAINT "FK_aed852c94d9ded617a7a07f5415" FOREIGN KEY ("gameId") REFERENCES "game" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`); - await queryRunner.query(`INSERT INTO "temporary_download_queue"("id", "createdAt", "updatedAt", "gameId") SELECT "id", "createdAt", "updatedAt", "gameId" FROM "download_queue"`); - await queryRunner.query(`DROP TABLE "download_queue"`); - await queryRunner.query(`ALTER TABLE "temporary_download_queue" RENAME TO "download_queue"`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "download_queue" RENAME TO "temporary_download_queue"`); - await queryRunner.query(`CREATE TABLE IF NOT EXISTS "download_queue" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "gameId" integer, CONSTRAINT "REL_aed852c94d9ded617a7a07f541" UNIQUE ("gameId"))`); - await queryRunner.query(`INSERT INTO "download_queue"("id", "createdAt", "updatedAt", "gameId") SELECT "id", "createdAt", "updatedAt", "gameId" FROM "temporary_download_queue"`); - await queryRunner.query(`DROP TABLE "temporary_download_queue"`); - await queryRunner.query(`ALTER TABLE "repack" RENAME TO "temporary_repack"`); - await queryRunner.query(`CREATE TABLE IF NOT EXISTS "repack" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "title" text NOT NULL, "magnet" text NOT NULL, "page" integer, "repacker" text NOT NULL, "fileSize" text NOT NULL, "uploadDate" datetime NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "downloadSourceId" integer, CONSTRAINT "UQ_a46a68496754a4d429ddf9d48ec" UNIQUE ("title"), CONSTRAINT "UQ_5e8d57798643e693bced32095d2" UNIQUE ("magnet"))`); - await queryRunner.query(`INSERT INTO "repack"("id", "title", "magnet", "page", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId") SELECT "id", "title", "magnet", "page", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId" FROM "temporary_repack"`); - await queryRunner.query(`DROP TABLE "temporary_repack"`); - await queryRunner.query(`ALTER TABLE "game" RENAME TO "temporary_game"`); - await queryRunner.query(`CREATE TABLE IF NOT EXISTS "game" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "objectID" text NOT NULL, "remoteId" text, "title" text NOT NULL, "iconUrl" text, "folderName" text, "downloadPath" text, "executablePath" text, "playTimeInMilliseconds" integer NOT NULL DEFAULT (0), "shop" text NOT NULL, "status" text, "downloader" integer NOT NULL DEFAULT (1), "progress" float NOT NULL DEFAULT (0), "bytesDownloaded" integer NOT NULL DEFAULT (0), "lastTimePlayed" datetime, "fileSize" float NOT NULL DEFAULT (0), "uri" text, "isDeleted" boolean NOT NULL DEFAULT (0), "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "repackId" integer, CONSTRAINT "UQ_04293f46e8db3deaec8dfb69264" UNIQUE ("objectID"), CONSTRAINT "UQ_6dac8c3148e141251a4864e94d4" UNIQUE ("remoteId"), CONSTRAINT "REL_0c1d6445ad047d9bbd256f961f" UNIQUE ("repackId"))`); - await queryRunner.query(`INSERT INTO "game"("id", "objectID", "remoteId", "title", "iconUrl", "folderName", "downloadPath", "executablePath", "playTimeInMilliseconds", "shop", "status", "downloader", "progress", "bytesDownloaded", "lastTimePlayed", "fileSize", "uri", "isDeleted", "createdAt", "updatedAt", "repackId") SELECT "id", "objectID", "remoteId", "title", "iconUrl", "folderName", "downloadPath", "executablePath", "playTimeInMilliseconds", "shop", "status", "downloader", "progress", "bytesDownloaded", "lastTimePlayed", "fileSize", "uri", "isDeleted", "createdAt", "updatedAt", "repackId" FROM "temporary_game"`); - await queryRunner.query(`DROP TABLE "temporary_game"`); - await queryRunner.query(`DROP TABLE "user_auth"`); - await queryRunner.query(`DROP TABLE "download_queue"`); - await queryRunner.query(`DROP TABLE "game_shop_cache"`); - await queryRunner.query(`DROP TABLE "user_preferences"`); - await queryRunner.query(`DROP TABLE "repack"`); - await queryRunner.query(`DROP TABLE "download_source"`); - await queryRunner.query(`DROP TABLE "game"`); - } - -} diff --git a/src/main/migrations/1724081984535-DowloadsRefactor.ts b/src/main/migrations/1724081984535-DowloadsRefactor.ts deleted file mode 100644 index 3afc8444..00000000 --- a/src/main/migrations/1724081984535-DowloadsRefactor.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { MigrationInterface, QueryRunner } from "typeorm"; - -export class DowloadsRefactor1724081984535 implements MigrationInterface { - name = 'DowloadsRefactor1724081984535' - - public async up(queryRunner: QueryRunner): Promise { - await queryRunner.query(`CREATE TABLE "temporary_repack" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "title" text NOT NULL, "magnet" text NOT NULL, "page" integer, "repacker" text NOT NULL, "fileSize" text NOT NULL, "uploadDate" datetime NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "downloadSourceId" integer, "uris" text NOT NULL DEFAULT ('[]'), CONSTRAINT "UQ_5e8d57798643e693bced32095d2" UNIQUE ("magnet"), CONSTRAINT "UQ_a46a68496754a4d429ddf9d48ec" UNIQUE ("title"), CONSTRAINT "FK_13f131029be1dd361fd3cd9c2a6" FOREIGN KEY ("downloadSourceId") REFERENCES "download_source" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`); - await queryRunner.query(`INSERT INTO "temporary_repack"("id", "title", "magnet", "page", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId") SELECT "id", "title", "magnet", "page", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId" FROM "repack"`); - await queryRunner.query(`DROP TABLE "repack"`); - await queryRunner.query(`ALTER TABLE "temporary_repack" RENAME TO "repack"`); - } - - public async down(queryRunner: QueryRunner): Promise { - await queryRunner.query(`ALTER TABLE "repack" RENAME TO "temporary_repack"`); - await queryRunner.query(`CREATE TABLE "repack" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "title" text NOT NULL, "magnet" text NOT NULL, "page" integer, "repacker" text NOT NULL, "fileSize" text NOT NULL, "uploadDate" datetime NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "downloadSourceId" integer, CONSTRAINT "UQ_5e8d57798643e693bced32095d2" UNIQUE ("magnet"), CONSTRAINT "UQ_a46a68496754a4d429ddf9d48ec" UNIQUE ("title"), CONSTRAINT "FK_13f131029be1dd361fd3cd9c2a6" FOREIGN KEY ("downloadSourceId") REFERENCES "download_source" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`); - await queryRunner.query(`INSERT INTO "repack"("id", "title", "magnet", "page", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId") SELECT "id", "title", "magnet", "page", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId" FROM "temporary_repack"`); - await queryRunner.query(`DROP TABLE "temporary_repack"`); - } - -} diff --git a/src/main/migrations/1_Hydra_2_0_3.ts b/src/main/migrations/1_Hydra_2_0_3.ts new file mode 100644 index 00000000..3d7dac78 --- /dev/null +++ b/src/main/migrations/1_Hydra_2_0_3.ts @@ -0,0 +1,110 @@ +import { Knex } from "knex"; + +export const up = async (knex: Knex) => { + await knex.schema.dropTableIfExists("migrations"); + await knex.schema.createTableIfNotExists("download_source", (table) => { + table.increments("id").primary(); + table.text("url").unique(); + table.text("name").notNullable(); + table.text("etag"); + table.integer("downloadCount").notNullable().defaultTo(0); + table.text("status").notNullable().defaultTo(0); + table.datetime("createdAt").notNullable().defaultTo(knex.fn.now()); + table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now()); + }); + + await knex.schema.createTableIfNotExists("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.schema.createTableIfNotExists("game", (table) => { + table.increments("id").primary(); + table.text("objectID").notNullable().unique(); + table.text("remoteId").unique(); + table.text("title").notNullable(); + table.text("iconUrl"); + table.text("folderName"); + table.text("downloadPath"); + table.text("executablePath"); + table.integer("playTimeInMilliseconds").notNullable().defaultTo(0); + table.text("shop").notNullable(); + table.text("status"); + table.integer("downloader").notNullable().defaultTo(1); + table.float("progress").notNullable().defaultTo(0); + table.integer("bytesDownloaded").notNullable().defaultTo(0); + table.datetime("lastTimePlayed"); + table.float("fileSize").notNullable().defaultTo(0); + table.text("uri"); + table.boolean("isDeleted").notNullable().defaultTo(0); + table.datetime("createdAt").notNullable().defaultTo(knex.fn.now()); + table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now()); + table.integer("repackId").references("repack.id").unique(); + }); + + await knex.schema.createTableIfNotExists("user_preferences", (table) => { + table.increments("id").primary(); + table.text("downloadsPath"); + table.text("language").notNullable().defaultTo("en"); + table.text("realDebridApiToken"); + table.boolean("downloadNotificationsEnabled").notNullable().defaultTo(0); + table + .boolean("repackUpdatesNotificationsEnabled") + .notNullable() + .defaultTo(0); + table.boolean("preferQuitInsteadOfHiding").notNullable().defaultTo(0); + table.boolean("runAtStartup").notNullable().defaultTo(0); + table.datetime("createdAt").notNullable().defaultTo(knex.fn.now()); + table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now()); + }); + + await knex.schema.createTableIfNotExists("game_shop_cache", (table) => { + table.text("objectID").primary().notNullable(); + table.text("shop").notNullable(); + table.text("serializedData"); + table.text("howLongToBeatSerializedData"); + table.text("language"); + table.datetime("createdAt").notNullable().defaultTo(knex.fn.now()); + table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now()); + }); + + await knex.schema.createTableIfNotExists("download_queue", (table) => { + table.increments("id").primary(); + table.integer("gameId").references("game.id").unique(); + table.datetime("createdAt").notNullable().defaultTo(knex.fn.now()); + table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now()); + }); + + await knex.schema.createTableIfNotExists("user_auth", (table) => { + table.increments("id").primary(); + table.text("userId").notNullable().defaultTo(""); + table.text("displayName").notNullable().defaultTo(""); + table.text("profileImageUrl"); + table.text("accessToken").notNullable().defaultTo(""); + table.text("refreshToken").notNullable().defaultTo(""); + table.integer("tokenExpirationTimestamp").notNullable().defaultTo(0); + table.datetime("createdAt").notNullable().defaultTo(knex.fn.now()); + table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now()); + }); +}; + +export const down = async (knex: Knex) => { + await knex.schema.dropTableIfExists("game"); + await knex.schema.dropTableIfExists("repack"); + await knex.schema.dropTableIfExists("download_queue"); + await knex.schema.dropTableIfExists("user_auth"); + await knex.schema.dropTableIfExists("game_shop_cache"); + await knex.schema.dropTableIfExists("user_preferences"); + await knex.schema.dropTableIfExists("download_source"); +}; diff --git a/src/main/migrations/2_DowloadsRefactor.ts b/src/main/migrations/2_DowloadsRefactor.ts new file mode 100644 index 00000000..7a2bf5e6 --- /dev/null +++ b/src/main/migrations/2_DowloadsRefactor.ts @@ -0,0 +1,47 @@ +import { Knex } from "knex"; + +export const up = async (knex: Knex) => { + await knex.schema.createTableIfNotExists("temporary_repack", (table) => { + table.increments("id").primary(); + table.text("title").notNullable().unique(); + table.text("magnet").notNullable().unique(); + 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"); +}; + +export const down = async (knex: Knex) => { + await knex.schema.renameTable("repack", "temporary_repack"); + await knex.schema.createTableIfNotExists("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/main/migrations/index.ts b/src/main/migrations/index.ts deleted file mode 100644 index 5546bce0..00000000 --- a/src/main/migrations/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./1724081695967-Hydra_2_0_3"; -export * from "./1724081984535-DowloadsRefactor"; diff --git a/yarn.lock b/yarn.lock index 74b9a8a1..9ffbf746 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2870,10 +2870,10 @@ bep53-range@^2.0.0: resolved "https://registry.npmjs.org/bep53-range/-/bep53-range-2.0.0.tgz" integrity sha512-sMm2sV5PRs0YOVk0LTKtjuIprVzxgTQUsrGX/7Yph2Rm4FO2Fqqtq7hNjsOB5xezM4v4+5rljCgK++UeQJZguA== -better-sqlite3@^9.5.0: - version "9.6.0" - resolved "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-9.6.0.tgz" - integrity sha512-yR5HATnqeYNVnkaUTf4bOP2dJSnyhP4puJN/QPRyx4YkBEEUxib422n2XzPqDEHjQQqazoYoADdAm5vE15+dAQ== +better-sqlite3@^11.2.1: + version "11.2.1" + resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-11.2.1.tgz#3c6b8a8e2e12444d380e811796b59c8aba012e03" + integrity sha512-Xbt1d68wQnUuFIEVsbt6V+RG30zwgbtCGQ4QOcXVrOH0FE4eHk64FWZ9NUfRHS4/x1PXqwz/+KOrnXD7f0WieA== dependencies: bindings "^1.5.0" prebuild-install "^7.1.1" @@ -3245,6 +3245,11 @@ color@^4.2.3: color-convert "^2.0.1" color-string "^1.9.0" +colorette@2.0.19: + version "2.0.19" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" + integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== + combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" @@ -3252,6 +3257,11 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" +commander@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + commander@^5.0.0: version "5.1.0" resolved "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz" @@ -3462,7 +3472,7 @@ dayjs@^1.11.9: resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz" integrity sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg== -debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: +debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -4101,6 +4111,11 @@ eslint@^8.56.0: strip-ansi "^6.0.1" text-table "^0.2.0" +esm@^3.2.25: + version "3.2.25" + resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" + integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== + espree@^9.6.0, espree@^9.6.1: version "9.6.1" resolved "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz" @@ -4463,6 +4478,11 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@ has-symbols "^1.0.3" hasown "^2.0.0" +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + get-stdin@^9.0.0: version "9.0.0" resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz" @@ -4489,6 +4509,11 @@ get-symbol-description@^1.0.2: es-errors "^1.3.0" get-intrinsic "^1.2.4" +getopts@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.3.0.tgz#71e5593284807e03e2427449d4f6712a268666f4" + integrity sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA== + git-raw-commits@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz" @@ -4909,6 +4934,11 @@ internal-slot@^1.0.7: hasown "^2.0.0" side-channel "^1.0.4" +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + is-array-buffer@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz" @@ -5350,6 +5380,26 @@ keyv@^4.0.0, keyv@^4.5.3: dependencies: json-buffer "3.0.1" +knex@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/knex/-/knex-3.1.0.tgz#b6ddd5b5ad26a6315234a5b09ec38dc4a370bd8c" + integrity sha512-GLoII6hR0c4ti243gMs5/1Rb3B+AjwMOfjYm97pu0FOQa7JH56hgBxYf5WK2525ceSbBY1cjeZ9yk99GPMB6Kw== + dependencies: + colorette "2.0.19" + commander "^10.0.0" + debug "4.3.4" + escalade "^3.1.1" + esm "^3.2.25" + get-package-type "^0.1.0" + getopts "2.3.0" + interpret "^2.2.0" + lodash "^4.17.21" + pg-connection-string "2.6.2" + rechoir "^0.8.0" + resolve-from "^5.0.0" + tarn "^3.0.2" + tildify "2.0.0" + language-subtag-registry@^0.3.20: version "0.3.22" resolved "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz" @@ -5489,7 +5539,7 @@ lodash.upperfirst@^4.3.1: resolved "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz" integrity sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg== -lodash@^4.17.15: +lodash@^4.17.15, lodash@^4.17.21: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -6114,6 +6164,11 @@ pend@~1.2.0: resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz" integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== +pg-connection-string@2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.6.2.tgz#713d82053de4e2bd166fab70cd4f26ad36aab475" + integrity sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA== + pg-int8@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" @@ -6457,6 +6512,13 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +rechoir@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" + integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== + dependencies: + resolve "^1.20.0" + redux-thunk@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz" @@ -6554,7 +6616,7 @@ resolve-from@^5.0.0: resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve@^1.22.1: +resolve@^1.20.0, resolve@^1.22.1: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -7083,6 +7145,11 @@ tar@^6.1.12: mkdirp "^1.0.3" yallist "^4.0.0" +tarn@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/tarn/-/tarn-3.0.2.tgz#73b6140fbb881b71559c4f8bfde3d9a4b3d27693" + integrity sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ== + temp-file@^3.4.0: version "3.4.0" resolved "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz" @@ -7120,6 +7187,11 @@ thenify-all@^1.0.0: resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== +tildify@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/tildify/-/tildify-2.0.0.tgz#f205f3674d677ce698b7067a99e949ce03b4754a" + integrity sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw== + tiny-typed-emitter@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz" From 5fcca9888d8f329adb7ecf2d15c893df247a96c9 Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Fri, 23 Aug 2024 00:07:50 -0300 Subject: [PATCH 03/12] Revert "feat: write migrations" This reverts commit 81aa25fa5293d2d17e67b8c65012ccf50823a605. --- .prettierignore | 1 + package.json | 6 +- src/main/data-source.ts | 4 +- src/main/entity/repack.entity.ts | 6 + src/main/index.ts | 17 +-- src/main/knex.ts | 14 --- .../migrations/1724081695967-Hydra_2_0_3.ts | 50 ++++++++ .../1724081984535-DowloadsRefactor.ts | 20 ++++ src/main/migrations/1_Hydra_2_0_3.ts | 110 ------------------ src/main/migrations/2_DowloadsRefactor.ts | 47 -------- src/main/migrations/index.ts | 2 + yarn.lock | 86 ++------------ 12 files changed, 93 insertions(+), 270 deletions(-) delete mode 100644 src/main/knex.ts create mode 100644 src/main/migrations/1724081695967-Hydra_2_0_3.ts create mode 100644 src/main/migrations/1724081984535-DowloadsRefactor.ts delete mode 100644 src/main/migrations/1_Hydra_2_0_3.ts delete mode 100644 src/main/migrations/2_DowloadsRefactor.ts create mode 100644 src/main/migrations/index.ts diff --git a/.prettierignore b/.prettierignore index 05d298a1..9b6e9df6 100644 --- a/.prettierignore +++ b/.prettierignore @@ -5,3 +5,4 @@ pnpm-lock.yaml LICENSE.md tsconfig.json tsconfig.*.json +src/main/migrations diff --git a/package.json b/package.json index 113b2e20..aa77084e 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ "build:win": "electron-vite build && electron-builder --win", "build:mac": "electron-vite build && electron-builder --mac", "build:linux": "electron-vite build && electron-builder --linux", - "prepare": "husky" + "prepare": "husky", + "typeorm:migration-create": "yarn typeorm migration:create" }, "dependencies": { "@electron-toolkit/preload": "^3.0.0", @@ -42,7 +43,7 @@ "@vanilla-extract/recipes": "^0.5.2", "auto-launch": "^5.0.6", "axios": "^1.6.8", - "better-sqlite3": "^11.2.1", + "better-sqlite3": "^9.5.0", "check-disk-space": "^3.4.0", "classnames": "^2.5.1", "color": "^4.2.3", @@ -60,7 +61,6 @@ "iso-639-1": "3.1.2", "jsdom": "^24.0.0", "jsonwebtoken": "^9.0.2", - "knex": "^3.1.0", "lodash-es": "^4.17.21", "lottie-react": "^2.4.0", "parse-torrent": "^11.0.16", diff --git a/src/main/data-source.ts b/src/main/data-source.ts index 29c72f8c..446ccbdc 100644 --- a/src/main/data-source.ts +++ b/src/main/data-source.ts @@ -10,6 +10,7 @@ import { } from "@main/entity"; import { databasePath } from "./constants"; +import * as migrations from "./migrations"; export const dataSource = new DataSource({ type: "better-sqlite3", @@ -22,6 +23,7 @@ export const dataSource = new DataSource({ DownloadQueue, UserAuth, ], - synchronize: false, + synchronize: true, database: databasePath, + migrations, }); diff --git a/src/main/entity/repack.entity.ts b/src/main/entity/repack.entity.ts index 36de2a7c..ff3f16cb 100644 --- a/src/main/entity/repack.entity.ts +++ b/src/main/entity/repack.entity.ts @@ -22,6 +22,12 @@ export class Repack { @Column("text", { unique: true }) magnet: string; + /** + * @deprecated Direct scraping capability has been removed + */ + @Column("int", { nullable: true }) + page: number; + @Column("text") repacker: string; diff --git a/src/main/index.ts b/src/main/index.ts index 3e14a1ba..e288302b 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -9,7 +9,6 @@ import { logger, PythonInstance, WindowManager } from "@main/services"; import { dataSource } from "@main/data-source"; import * as resources from "@locales"; import { userPreferencesRepository } from "@main/repository"; -import { knexClient, migrationConfig } from "./knex"; const { autoUpdater } = updater; @@ -64,22 +63,8 @@ app.whenReady().then(async () => { return net.fetch(url.pathToFileURL(decodeURI(filePath)).toString()); }); - await knexClient.migrate.list(migrationConfig).then((result) => { - console.log("Migrations to run:", result[1]); - }); - - await knexClient.migrate - .latest(migrationConfig) - .then(() => { - console.log("Migrations executed successfully"); - }) - .catch((err) => { - console.log("Migrations failed to run:", err); - }); - - await knexClient.destroy(); - await dataSource.initialize(); + await dataSource.runMigrations(); await import("./main"); diff --git a/src/main/knex.ts b/src/main/knex.ts deleted file mode 100644 index 2e5cc27e..00000000 --- a/src/main/knex.ts +++ /dev/null @@ -1,14 +0,0 @@ -import knex, { Knex } from "knex"; -import { databasePath } from "./constants"; -import path from "node:path"; - -export const knexClient = knex({ - client: "better-sqlite3", - connection: { - filename: databasePath, - }, -}); - -export const migrationConfig: Knex.MigratorConfig = { - directory: path.resolve(__dirname, "migrations"), -}; diff --git a/src/main/migrations/1724081695967-Hydra_2_0_3.ts b/src/main/migrations/1724081695967-Hydra_2_0_3.ts new file mode 100644 index 00000000..5ab18acb --- /dev/null +++ b/src/main/migrations/1724081695967-Hydra_2_0_3.ts @@ -0,0 +1,50 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class Hydra2031724081695967 implements MigrationInterface { + name = 'Hydra2031724081695967' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TABLE IF NOT EXISTS "game" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "objectID" text NOT NULL, "remoteId" text, "title" text NOT NULL, "iconUrl" text, "folderName" text, "downloadPath" text, "executablePath" text, "playTimeInMilliseconds" integer NOT NULL DEFAULT (0), "shop" text NOT NULL, "status" text, "downloader" integer NOT NULL DEFAULT (1), "progress" float NOT NULL DEFAULT (0), "bytesDownloaded" integer NOT NULL DEFAULT (0), "lastTimePlayed" datetime, "fileSize" float NOT NULL DEFAULT (0), "uri" text, "isDeleted" boolean NOT NULL DEFAULT (0), "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "repackId" integer, CONSTRAINT "UQ_04293f46e8db3deaec8dfb69264" UNIQUE ("objectID"), CONSTRAINT "UQ_6dac8c3148e141251a4864e94d4" UNIQUE ("remoteId"), CONSTRAINT "REL_0c1d6445ad047d9bbd256f961f" UNIQUE ("repackId"))`); + await queryRunner.query(`CREATE TABLE IF NOT EXISTS "download_source" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "url" text, "name" text NOT NULL, "etag" text, "downloadCount" integer NOT NULL DEFAULT (0), "status" text NOT NULL DEFAULT (0), "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), CONSTRAINT "UQ_aec2879321a87e9bb2ed477981a" UNIQUE ("url"))`); + await queryRunner.query(`CREATE TABLE IF NOT EXISTS "repack" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "title" text NOT NULL, "magnet" text NOT NULL, "page" integer, "repacker" text NOT NULL, "fileSize" text NOT NULL, "uploadDate" datetime NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "downloadSourceId" integer, CONSTRAINT "UQ_a46a68496754a4d429ddf9d48ec" UNIQUE ("title"), CONSTRAINT "UQ_5e8d57798643e693bced32095d2" UNIQUE ("magnet"))`); + await queryRunner.query(`CREATE TABLE IF NOT EXISTS "user_preferences" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "downloadsPath" text, "language" text NOT NULL DEFAULT ('en'), "realDebridApiToken" text, "downloadNotificationsEnabled" boolean NOT NULL DEFAULT (0), "repackUpdatesNotificationsEnabled" boolean NOT NULL DEFAULT (0), "preferQuitInsteadOfHiding" boolean NOT NULL DEFAULT (0), "runAtStartup" boolean NOT NULL DEFAULT (0), "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')))`); + await queryRunner.query(`CREATE TABLE IF NOT EXISTS "game_shop_cache" ("objectID" text PRIMARY KEY NOT NULL, "shop" text NOT NULL, "serializedData" text, "howLongToBeatSerializedData" text, "language" text, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')))`); + await queryRunner.query(`CREATE TABLE IF NOT EXISTS "download_queue" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "gameId" integer, CONSTRAINT "REL_aed852c94d9ded617a7a07f541" UNIQUE ("gameId"))`); + await queryRunner.query(`CREATE TABLE IF NOT EXISTS "user_auth" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "userId" text NOT NULL DEFAULT (''), "displayName" text NOT NULL DEFAULT (''), "profileImageUrl" text, "accessToken" text NOT NULL DEFAULT (''), "refreshToken" text NOT NULL DEFAULT (''), "tokenExpirationTimestamp" integer NOT NULL DEFAULT (0), "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')))`); + await queryRunner.query(`CREATE TABLE IF NOT EXISTS "temporary_game" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "objectID" text NOT NULL, "remoteId" text, "title" text NOT NULL, "iconUrl" text, "folderName" text, "downloadPath" text, "executablePath" text, "playTimeInMilliseconds" integer NOT NULL DEFAULT (0), "shop" text NOT NULL, "status" text, "downloader" integer NOT NULL DEFAULT (1), "progress" float NOT NULL DEFAULT (0), "bytesDownloaded" integer NOT NULL DEFAULT (0), "lastTimePlayed" datetime, "fileSize" float NOT NULL DEFAULT (0), "uri" text, "isDeleted" boolean NOT NULL DEFAULT (0), "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "repackId" integer, CONSTRAINT "UQ_04293f46e8db3deaec8dfb69264" UNIQUE ("objectID"), CONSTRAINT "UQ_6dac8c3148e141251a4864e94d4" UNIQUE ("remoteId"), CONSTRAINT "REL_0c1d6445ad047d9bbd256f961f" UNIQUE ("repackId"), CONSTRAINT "FK_0c1d6445ad047d9bbd256f961f6" FOREIGN KEY ("repackId") REFERENCES "repack" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`); + await queryRunner.query(`INSERT INTO "temporary_game"("id", "objectID", "remoteId", "title", "iconUrl", "folderName", "downloadPath", "executablePath", "playTimeInMilliseconds", "shop", "status", "downloader", "progress", "bytesDownloaded", "lastTimePlayed", "fileSize", "uri", "isDeleted", "createdAt", "updatedAt", "repackId") SELECT "id", "objectID", "remoteId", "title", "iconUrl", "folderName", "downloadPath", "executablePath", "playTimeInMilliseconds", "shop", "status", "downloader", "progress", "bytesDownloaded", "lastTimePlayed", "fileSize", "uri", "isDeleted", "createdAt", "updatedAt", "repackId" FROM "game"`); + await queryRunner.query(`DROP TABLE "game"`); + await queryRunner.query(`ALTER TABLE "temporary_game" RENAME TO "game"`); + await queryRunner.query(`CREATE TABLE IF NOT EXISTS "temporary_repack" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "title" text NOT NULL, "magnet" text NOT NULL, "page" integer, "repacker" text NOT NULL, "fileSize" text NOT NULL, "uploadDate" datetime NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "downloadSourceId" integer, CONSTRAINT "UQ_a46a68496754a4d429ddf9d48ec" UNIQUE ("title"), CONSTRAINT "UQ_5e8d57798643e693bced32095d2" UNIQUE ("magnet"), CONSTRAINT "FK_13f131029be1dd361fd3cd9c2a6" FOREIGN KEY ("downloadSourceId") REFERENCES "download_source" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`); + await queryRunner.query(`INSERT INTO "temporary_repack"("id", "title", "magnet", "page", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId") SELECT "id", "title", "magnet", "page", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId" FROM "repack"`); + await queryRunner.query(`DROP TABLE "repack"`); + await queryRunner.query(`ALTER TABLE "temporary_repack" RENAME TO "repack"`); + await queryRunner.query(`CREATE TABLE IF NOT EXISTS "temporary_download_queue" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "gameId" integer, CONSTRAINT "REL_aed852c94d9ded617a7a07f541" UNIQUE ("gameId"), CONSTRAINT "FK_aed852c94d9ded617a7a07f5415" FOREIGN KEY ("gameId") REFERENCES "game" ("id") ON DELETE NO ACTION ON UPDATE NO ACTION)`); + await queryRunner.query(`INSERT INTO "temporary_download_queue"("id", "createdAt", "updatedAt", "gameId") SELECT "id", "createdAt", "updatedAt", "gameId" FROM "download_queue"`); + await queryRunner.query(`DROP TABLE "download_queue"`); + await queryRunner.query(`ALTER TABLE "temporary_download_queue" RENAME TO "download_queue"`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "download_queue" RENAME TO "temporary_download_queue"`); + await queryRunner.query(`CREATE TABLE IF NOT EXISTS "download_queue" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "gameId" integer, CONSTRAINT "REL_aed852c94d9ded617a7a07f541" UNIQUE ("gameId"))`); + await queryRunner.query(`INSERT INTO "download_queue"("id", "createdAt", "updatedAt", "gameId") SELECT "id", "createdAt", "updatedAt", "gameId" FROM "temporary_download_queue"`); + await queryRunner.query(`DROP TABLE "temporary_download_queue"`); + await queryRunner.query(`ALTER TABLE "repack" RENAME TO "temporary_repack"`); + await queryRunner.query(`CREATE TABLE IF NOT EXISTS "repack" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "title" text NOT NULL, "magnet" text NOT NULL, "page" integer, "repacker" text NOT NULL, "fileSize" text NOT NULL, "uploadDate" datetime NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "downloadSourceId" integer, CONSTRAINT "UQ_a46a68496754a4d429ddf9d48ec" UNIQUE ("title"), CONSTRAINT "UQ_5e8d57798643e693bced32095d2" UNIQUE ("magnet"))`); + await queryRunner.query(`INSERT INTO "repack"("id", "title", "magnet", "page", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId") SELECT "id", "title", "magnet", "page", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId" FROM "temporary_repack"`); + await queryRunner.query(`DROP TABLE "temporary_repack"`); + await queryRunner.query(`ALTER TABLE "game" RENAME TO "temporary_game"`); + await queryRunner.query(`CREATE TABLE IF NOT EXISTS "game" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "objectID" text NOT NULL, "remoteId" text, "title" text NOT NULL, "iconUrl" text, "folderName" text, "downloadPath" text, "executablePath" text, "playTimeInMilliseconds" integer NOT NULL DEFAULT (0), "shop" text NOT NULL, "status" text, "downloader" integer NOT NULL DEFAULT (1), "progress" float NOT NULL DEFAULT (0), "bytesDownloaded" integer NOT NULL DEFAULT (0), "lastTimePlayed" datetime, "fileSize" float NOT NULL DEFAULT (0), "uri" text, "isDeleted" boolean NOT NULL DEFAULT (0), "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "repackId" integer, CONSTRAINT "UQ_04293f46e8db3deaec8dfb69264" UNIQUE ("objectID"), CONSTRAINT "UQ_6dac8c3148e141251a4864e94d4" UNIQUE ("remoteId"), CONSTRAINT "REL_0c1d6445ad047d9bbd256f961f" UNIQUE ("repackId"))`); + await queryRunner.query(`INSERT INTO "game"("id", "objectID", "remoteId", "title", "iconUrl", "folderName", "downloadPath", "executablePath", "playTimeInMilliseconds", "shop", "status", "downloader", "progress", "bytesDownloaded", "lastTimePlayed", "fileSize", "uri", "isDeleted", "createdAt", "updatedAt", "repackId") SELECT "id", "objectID", "remoteId", "title", "iconUrl", "folderName", "downloadPath", "executablePath", "playTimeInMilliseconds", "shop", "status", "downloader", "progress", "bytesDownloaded", "lastTimePlayed", "fileSize", "uri", "isDeleted", "createdAt", "updatedAt", "repackId" FROM "temporary_game"`); + await queryRunner.query(`DROP TABLE "temporary_game"`); + await queryRunner.query(`DROP TABLE "user_auth"`); + await queryRunner.query(`DROP TABLE "download_queue"`); + await queryRunner.query(`DROP TABLE "game_shop_cache"`); + await queryRunner.query(`DROP TABLE "user_preferences"`); + await queryRunner.query(`DROP TABLE "repack"`); + await queryRunner.query(`DROP TABLE "download_source"`); + await queryRunner.query(`DROP TABLE "game"`); + } + +} diff --git a/src/main/migrations/1724081984535-DowloadsRefactor.ts b/src/main/migrations/1724081984535-DowloadsRefactor.ts new file mode 100644 index 00000000..3afc8444 --- /dev/null +++ b/src/main/migrations/1724081984535-DowloadsRefactor.ts @@ -0,0 +1,20 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class DowloadsRefactor1724081984535 implements MigrationInterface { + name = 'DowloadsRefactor1724081984535' + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE TABLE "temporary_repack" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "title" text NOT NULL, "magnet" text NOT NULL, "page" integer, "repacker" text NOT NULL, "fileSize" text NOT NULL, "uploadDate" datetime NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "downloadSourceId" integer, "uris" text NOT NULL DEFAULT ('[]'), CONSTRAINT "UQ_5e8d57798643e693bced32095d2" UNIQUE ("magnet"), CONSTRAINT "UQ_a46a68496754a4d429ddf9d48ec" UNIQUE ("title"), CONSTRAINT "FK_13f131029be1dd361fd3cd9c2a6" FOREIGN KEY ("downloadSourceId") REFERENCES "download_source" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`); + await queryRunner.query(`INSERT INTO "temporary_repack"("id", "title", "magnet", "page", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId") SELECT "id", "title", "magnet", "page", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId" FROM "repack"`); + await queryRunner.query(`DROP TABLE "repack"`); + await queryRunner.query(`ALTER TABLE "temporary_repack" RENAME TO "repack"`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`ALTER TABLE "repack" RENAME TO "temporary_repack"`); + await queryRunner.query(`CREATE TABLE "repack" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "title" text NOT NULL, "magnet" text NOT NULL, "page" integer, "repacker" text NOT NULL, "fileSize" text NOT NULL, "uploadDate" datetime NOT NULL, "createdAt" datetime NOT NULL DEFAULT (datetime('now')), "updatedAt" datetime NOT NULL DEFAULT (datetime('now')), "downloadSourceId" integer, CONSTRAINT "UQ_5e8d57798643e693bced32095d2" UNIQUE ("magnet"), CONSTRAINT "UQ_a46a68496754a4d429ddf9d48ec" UNIQUE ("title"), CONSTRAINT "FK_13f131029be1dd361fd3cd9c2a6" FOREIGN KEY ("downloadSourceId") REFERENCES "download_source" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`); + await queryRunner.query(`INSERT INTO "repack"("id", "title", "magnet", "page", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId") SELECT "id", "title", "magnet", "page", "repacker", "fileSize", "uploadDate", "createdAt", "updatedAt", "downloadSourceId" FROM "temporary_repack"`); + await queryRunner.query(`DROP TABLE "temporary_repack"`); + } + +} diff --git a/src/main/migrations/1_Hydra_2_0_3.ts b/src/main/migrations/1_Hydra_2_0_3.ts deleted file mode 100644 index 3d7dac78..00000000 --- a/src/main/migrations/1_Hydra_2_0_3.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { Knex } from "knex"; - -export const up = async (knex: Knex) => { - await knex.schema.dropTableIfExists("migrations"); - await knex.schema.createTableIfNotExists("download_source", (table) => { - table.increments("id").primary(); - table.text("url").unique(); - table.text("name").notNullable(); - table.text("etag"); - table.integer("downloadCount").notNullable().defaultTo(0); - table.text("status").notNullable().defaultTo(0); - table.datetime("createdAt").notNullable().defaultTo(knex.fn.now()); - table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now()); - }); - - await knex.schema.createTableIfNotExists("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.schema.createTableIfNotExists("game", (table) => { - table.increments("id").primary(); - table.text("objectID").notNullable().unique(); - table.text("remoteId").unique(); - table.text("title").notNullable(); - table.text("iconUrl"); - table.text("folderName"); - table.text("downloadPath"); - table.text("executablePath"); - table.integer("playTimeInMilliseconds").notNullable().defaultTo(0); - table.text("shop").notNullable(); - table.text("status"); - table.integer("downloader").notNullable().defaultTo(1); - table.float("progress").notNullable().defaultTo(0); - table.integer("bytesDownloaded").notNullable().defaultTo(0); - table.datetime("lastTimePlayed"); - table.float("fileSize").notNullable().defaultTo(0); - table.text("uri"); - table.boolean("isDeleted").notNullable().defaultTo(0); - table.datetime("createdAt").notNullable().defaultTo(knex.fn.now()); - table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now()); - table.integer("repackId").references("repack.id").unique(); - }); - - await knex.schema.createTableIfNotExists("user_preferences", (table) => { - table.increments("id").primary(); - table.text("downloadsPath"); - table.text("language").notNullable().defaultTo("en"); - table.text("realDebridApiToken"); - table.boolean("downloadNotificationsEnabled").notNullable().defaultTo(0); - table - .boolean("repackUpdatesNotificationsEnabled") - .notNullable() - .defaultTo(0); - table.boolean("preferQuitInsteadOfHiding").notNullable().defaultTo(0); - table.boolean("runAtStartup").notNullable().defaultTo(0); - table.datetime("createdAt").notNullable().defaultTo(knex.fn.now()); - table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now()); - }); - - await knex.schema.createTableIfNotExists("game_shop_cache", (table) => { - table.text("objectID").primary().notNullable(); - table.text("shop").notNullable(); - table.text("serializedData"); - table.text("howLongToBeatSerializedData"); - table.text("language"); - table.datetime("createdAt").notNullable().defaultTo(knex.fn.now()); - table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now()); - }); - - await knex.schema.createTableIfNotExists("download_queue", (table) => { - table.increments("id").primary(); - table.integer("gameId").references("game.id").unique(); - table.datetime("createdAt").notNullable().defaultTo(knex.fn.now()); - table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now()); - }); - - await knex.schema.createTableIfNotExists("user_auth", (table) => { - table.increments("id").primary(); - table.text("userId").notNullable().defaultTo(""); - table.text("displayName").notNullable().defaultTo(""); - table.text("profileImageUrl"); - table.text("accessToken").notNullable().defaultTo(""); - table.text("refreshToken").notNullable().defaultTo(""); - table.integer("tokenExpirationTimestamp").notNullable().defaultTo(0); - table.datetime("createdAt").notNullable().defaultTo(knex.fn.now()); - table.datetime("updatedAt").notNullable().defaultTo(knex.fn.now()); - }); -}; - -export const down = async (knex: Knex) => { - await knex.schema.dropTableIfExists("game"); - await knex.schema.dropTableIfExists("repack"); - await knex.schema.dropTableIfExists("download_queue"); - await knex.schema.dropTableIfExists("user_auth"); - await knex.schema.dropTableIfExists("game_shop_cache"); - await knex.schema.dropTableIfExists("user_preferences"); - await knex.schema.dropTableIfExists("download_source"); -}; diff --git a/src/main/migrations/2_DowloadsRefactor.ts b/src/main/migrations/2_DowloadsRefactor.ts deleted file mode 100644 index 7a2bf5e6..00000000 --- a/src/main/migrations/2_DowloadsRefactor.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Knex } from "knex"; - -export const up = async (knex: Knex) => { - await knex.schema.createTableIfNotExists("temporary_repack", (table) => { - table.increments("id").primary(); - table.text("title").notNullable().unique(); - table.text("magnet").notNullable().unique(); - 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"); -}; - -export const down = async (knex: Knex) => { - await knex.schema.renameTable("repack", "temporary_repack"); - await knex.schema.createTableIfNotExists("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/main/migrations/index.ts b/src/main/migrations/index.ts new file mode 100644 index 00000000..5546bce0 --- /dev/null +++ b/src/main/migrations/index.ts @@ -0,0 +1,2 @@ +export * from "./1724081695967-Hydra_2_0_3"; +export * from "./1724081984535-DowloadsRefactor"; diff --git a/yarn.lock b/yarn.lock index 9ffbf746..74b9a8a1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2870,10 +2870,10 @@ bep53-range@^2.0.0: resolved "https://registry.npmjs.org/bep53-range/-/bep53-range-2.0.0.tgz" integrity sha512-sMm2sV5PRs0YOVk0LTKtjuIprVzxgTQUsrGX/7Yph2Rm4FO2Fqqtq7hNjsOB5xezM4v4+5rljCgK++UeQJZguA== -better-sqlite3@^11.2.1: - version "11.2.1" - resolved "https://registry.yarnpkg.com/better-sqlite3/-/better-sqlite3-11.2.1.tgz#3c6b8a8e2e12444d380e811796b59c8aba012e03" - integrity sha512-Xbt1d68wQnUuFIEVsbt6V+RG30zwgbtCGQ4QOcXVrOH0FE4eHk64FWZ9NUfRHS4/x1PXqwz/+KOrnXD7f0WieA== +better-sqlite3@^9.5.0: + version "9.6.0" + resolved "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-9.6.0.tgz" + integrity sha512-yR5HATnqeYNVnkaUTf4bOP2dJSnyhP4puJN/QPRyx4YkBEEUxib422n2XzPqDEHjQQqazoYoADdAm5vE15+dAQ== dependencies: bindings "^1.5.0" prebuild-install "^7.1.1" @@ -3245,11 +3245,6 @@ color@^4.2.3: color-convert "^2.0.1" color-string "^1.9.0" -colorette@2.0.19: - version "2.0.19" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" - integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== - combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" @@ -3257,11 +3252,6 @@ combined-stream@^1.0.8: dependencies: delayed-stream "~1.0.0" -commander@^10.0.0: - version "10.0.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" - integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== - commander@^5.0.0: version "5.1.0" resolved "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz" @@ -3472,7 +3462,7 @@ dayjs@^1.11.9: resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz" integrity sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg== -debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -4111,11 +4101,6 @@ eslint@^8.56.0: strip-ansi "^6.0.1" text-table "^0.2.0" -esm@^3.2.25: - version "3.2.25" - resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" - integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== - espree@^9.6.0, espree@^9.6.1: version "9.6.1" resolved "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz" @@ -4478,11 +4463,6 @@ get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.3, get-intrinsic@ has-symbols "^1.0.3" hasown "^2.0.0" -get-package-type@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" - integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== - get-stdin@^9.0.0: version "9.0.0" resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz" @@ -4509,11 +4489,6 @@ get-symbol-description@^1.0.2: es-errors "^1.3.0" get-intrinsic "^1.2.4" -getopts@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.3.0.tgz#71e5593284807e03e2427449d4f6712a268666f4" - integrity sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA== - git-raw-commits@^4.0.0: version "4.0.0" resolved "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz" @@ -4934,11 +4909,6 @@ internal-slot@^1.0.7: hasown "^2.0.0" side-channel "^1.0.4" -interpret@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" - integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== - is-array-buffer@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz" @@ -5380,26 +5350,6 @@ keyv@^4.0.0, keyv@^4.5.3: dependencies: json-buffer "3.0.1" -knex@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/knex/-/knex-3.1.0.tgz#b6ddd5b5ad26a6315234a5b09ec38dc4a370bd8c" - integrity sha512-GLoII6hR0c4ti243gMs5/1Rb3B+AjwMOfjYm97pu0FOQa7JH56hgBxYf5WK2525ceSbBY1cjeZ9yk99GPMB6Kw== - dependencies: - colorette "2.0.19" - commander "^10.0.0" - debug "4.3.4" - escalade "^3.1.1" - esm "^3.2.25" - get-package-type "^0.1.0" - getopts "2.3.0" - interpret "^2.2.0" - lodash "^4.17.21" - pg-connection-string "2.6.2" - rechoir "^0.8.0" - resolve-from "^5.0.0" - tarn "^3.0.2" - tildify "2.0.0" - language-subtag-registry@^0.3.20: version "0.3.22" resolved "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz" @@ -5539,7 +5489,7 @@ lodash.upperfirst@^4.3.1: resolved "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz" integrity sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg== -lodash@^4.17.15, lodash@^4.17.21: +lodash@^4.17.15: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -6164,11 +6114,6 @@ pend@~1.2.0: resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz" integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== -pg-connection-string@2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.6.2.tgz#713d82053de4e2bd166fab70cd4f26ad36aab475" - integrity sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA== - pg-int8@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" @@ -6512,13 +6457,6 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" -rechoir@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" - integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== - dependencies: - resolve "^1.20.0" - redux-thunk@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz" @@ -6616,7 +6554,7 @@ resolve-from@^5.0.0: resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== -resolve@^1.20.0, resolve@^1.22.1: +resolve@^1.22.1: version "1.22.8" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== @@ -7145,11 +7083,6 @@ tar@^6.1.12: mkdirp "^1.0.3" yallist "^4.0.0" -tarn@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/tarn/-/tarn-3.0.2.tgz#73b6140fbb881b71559c4f8bfde3d9a4b3d27693" - integrity sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ== - temp-file@^3.4.0: version "3.4.0" resolved "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz" @@ -7187,11 +7120,6 @@ thenify-all@^1.0.0: resolved "https://registry.npmjs.org/through/-/through-2.3.8.tgz" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== -tildify@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/tildify/-/tildify-2.0.0.tgz#f205f3674d677ce698b7067a99e949ce03b4754a" - integrity sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw== - tiny-typed-emitter@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz" From f9979a38da9fe687c243bd9657c3d706bcb9d3ef Mon Sep 17 00:00:00 2001 From: Lianela <140931995+Lianela@users.noreply.github.com> Date: Sun, 25 Aug 2024 16:58:48 -0600 Subject: [PATCH 04/12] removed strings / added new translations (es) --- src/locales/es/translation.json | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/locales/es/translation.json b/src/locales/es/translation.json index 0800b0c9..9cc7af9d 100644 --- a/src/locales/es/translation.json +++ b/src/locales/es/translation.json @@ -177,9 +177,6 @@ "download_count_zero": "No hay descargas en la lista", "download_count_one": "{{countFormatted}} descarga en la lista", "download_count_other": "{{countFormatted}} descargas en la lista", - "download_options_zero": "No hay descargas disponibles", - "download_options_one": "{{countFormatted}} descarga disponible", - "download_options_other": "{{countFormatted}} descargas disponibles", "download_source_url": "Descargar URL de origen", "add_download_source_description": "Introduce la URL con el archivo .json", "download_source_up_to_date": "Al día", @@ -261,6 +258,18 @@ "undo_friendship": "Eliminar amistad", "request_accepted": "Solicitud aceptada", "user_blocked_successfully": "Usuario bloqueado exitosamente", - "user_block_modal_text": "Esto va a bloquear a {{displayName}}" + "user_block_modal_text": "Esto va a bloquear a {{displayName}}", + "settings": "Ajustes", + "public": "Público", + "private": "Privado", + "friends_only": "Solo Amigos", + "privacy": "Privacidad", + "blocked_users": "Usuarios bloqueados", + "unblock": "Desbloquear", + "no_friends_added": "Todavía no tienes amigos añadidos", + "pending": "Pendiente", + "no_pending_invites": "No tienes invitaciones pendientes", + "no_blocked_users": "No has bloqueado a ningún usuario", + "friend_code_copied": "Código de amigo copiado" } } From fb60c91c8399ef0b556da22892f14d12f3fc3b6e Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Mon, 26 Aug 2024 12:23:32 -0300 Subject: [PATCH 05/12] feat: add undo friendship confirm modal --- src/locales/en/translation.json | 3 +- src/locales/pt/translation.json | 3 +- .../user-confirm-undo-friendship-modal.tsx | 42 +++++++++++++++++++ src/renderer/src/pages/user/user-content.tsx | 16 ++++--- 4 files changed, 56 insertions(+), 8 deletions(-) create mode 100644 src/renderer/src/pages/user/user-confirm-undo-friendship-modal.tsx diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index e2726b79..08c9fda2 100644 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -270,6 +270,7 @@ "pending": "Pending", "no_pending_invites": "You have no pending invites", "no_blocked_users": "You have no blocked users", - "friend_code_copied": "Friend code copied" + "friend_code_copied": "Friend code copied", + "undo_friendship_modal_text": "This will undo your friendship with {{displayName}}" } } diff --git a/src/locales/pt/translation.json b/src/locales/pt/translation.json index 36d38c96..a97a81cf 100644 --- a/src/locales/pt/translation.json +++ b/src/locales/pt/translation.json @@ -273,6 +273,7 @@ "pending": "Pendentes", "no_pending_invites": "Você não possui convites de amizade pendentes", "no_blocked_users": "Você não tem nenhum usuário bloqueado", - "friend_code_copied": "Código de amigo copiado" + "friend_code_copied": "Código de amigo copiado", + "undo_friendship_modal_text": "Isso irá remover sua amizade com {{displayName}}" } } diff --git a/src/renderer/src/pages/user/user-confirm-undo-friendship-modal.tsx b/src/renderer/src/pages/user/user-confirm-undo-friendship-modal.tsx new file mode 100644 index 00000000..cf2a0415 --- /dev/null +++ b/src/renderer/src/pages/user/user-confirm-undo-friendship-modal.tsx @@ -0,0 +1,42 @@ +import { Button, Modal } from "@renderer/components"; +import * as styles from "./user.css"; +import { useTranslation } from "react-i18next"; + +export interface UserConfirmUndoFriendshipModalProps { + visible: boolean; + displayName: string; + onConfirm: () => void; + onClose: () => void; +} + +export const UserConfirmUndoFriendshipModal = ({ + visible, + displayName, + onConfirm, + onClose, +}: UserConfirmUndoFriendshipModalProps) => { + const { t } = useTranslation("user_profile"); + + return ( + <> + +
+

{t("undo_friendship_modal_text", { displayName })}

+
+ + + +
+
+
+ + ); +}; diff --git a/src/renderer/src/pages/user/user-content.tsx b/src/renderer/src/pages/user/user-content.tsx index c334389e..fb092d06 100644 --- a/src/renderer/src/pages/user/user-content.tsx +++ b/src/renderer/src/pages/user/user-content.tsx @@ -34,6 +34,7 @@ import { UserProfileSettingsModal } from "./user-profile-settings-modal"; import { UserSignOutModal } from "./user-sign-out-modal"; import { UserFriendModalTab } from "../shared-modals/user-friend-modal"; import { UserBlockModal } from "./user-block-modal"; +import { UserConfirmUndoFriendshipModal } from "./user-confirm-undo-friendship-modal"; const MAX_MINUTES_TO_SHOW_IN_PLAYTIME = 120; @@ -68,6 +69,7 @@ export function UserContent({ useState(false); const [showSignOutModal, setShowSignOutModal] = useState(false); const [showUserBlockModal, setShowUserBlockModal] = useState(false); + const [showUndoFriendshipModal, setShowUndoFriendshipModal] = useState(false); const [currentGame, setCurrentGame] = useState(null); const { gameRunning } = useAppSelector((state) => state.gameRunning); @@ -213,17 +215,12 @@ export function UserContent({ } if (userProfile.relation.status === "ACCEPTED") { - const userId = - userProfile.relation.AId === userDetails?.id - ? userProfile.relation.BId - : userProfile.relation.AId; - return ( <> @@ -291,6 +288,13 @@ export function UserContent({ displayName={userProfile.displayName} /> + setShowUndoFriendshipModal(false)} + onConfirm={() => handleFriendAction(userProfile.id, "UNDO")} + displayName={userProfile.displayName} + /> +
Date: Mon, 26 Aug 2024 12:45:27 -0300 Subject: [PATCH 06/12] fix: profile display name --- src/renderer/src/pages/user/user-content.tsx | 4 +++- .../user-profile-settings-modal/user-edit-profile.tsx | 1 + src/renderer/src/pages/user/user.css.ts | 9 +++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/renderer/src/pages/user/user-content.tsx b/src/renderer/src/pages/user/user-content.tsx index fb092d06..f4a46ccd 100644 --- a/src/renderer/src/pages/user/user-content.tsx +++ b/src/renderer/src/pages/user/user-content.tsx @@ -332,7 +332,9 @@ export function UserContent({
-

{userProfile.displayName}

+

+ {userProfile.displayName} +

{currentGame && (
setForm({ ...form, displayName: e.target.value })} /> diff --git a/src/renderer/src/pages/user/user.css.ts b/src/renderer/src/pages/user/user.css.ts index 4e1c2139..6bcb30b0 100644 --- a/src/renderer/src/pages/user/user.css.ts +++ b/src/renderer/src/pages/user/user.css.ts @@ -23,6 +23,7 @@ export const profileContentBox = style({ export const profileAvatarContainer = style({ width: "96px", + minWidth: "96px", height: "96px", borderRadius: "50%", display: "flex", @@ -100,6 +101,14 @@ export const profileInformation = style({ alignItems: "flex-start", color: "#c0c1c7", zIndex: 1, + overflow: "hidden", +}); + +export const profileDisplayName = style({ + fontWeight: "bold", + overflow: "hidden", + textOverflow: "ellipsis", + width: "100%", }); export const profileContent = style({ From 3293320926e74a867a39188231604840c0f0c3aa Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Mon, 26 Aug 2024 13:21:21 -0300 Subject: [PATCH 07/12] fix: sidebar profile layout --- .../components/sidebar/sidebar-profile.css.ts | 20 +++++--------- .../components/sidebar/sidebar-profile.tsx | 27 ++++++++++--------- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/src/renderer/src/components/sidebar/sidebar-profile.css.ts b/src/renderer/src/components/sidebar/sidebar-profile.css.ts index ba29c850..d97b0c44 100644 --- a/src/renderer/src/components/sidebar/sidebar-profile.css.ts +++ b/src/renderer/src/components/sidebar/sidebar-profile.css.ts @@ -7,22 +7,24 @@ export const profileContainerBackground = createVar(); export const profileContainer = style({ background: profileContainerBackground, position: "relative", + display: "flex", + gap: `${SPACING_UNIT}px`, cursor: "pointer", ":hover": { backgroundColor: "rgba(255, 255, 255, 0.15)", }, + borderBottom: `solid 1px ${vars.color.border}`, + boxShadow: "0px 0px 15px 0px rgb(0 0 0 / 70%)", + padding: `${SPACING_UNIT * 2}px ${SPACING_UNIT * 2}px`, }); export const profileButton = style({ display: "flex", cursor: "pointer", transition: "all ease 0.1s", - padding: `${SPACING_UNIT * 2}px ${SPACING_UNIT * 2}px`, color: vars.color.muted, - borderBottom: `solid 1px ${vars.color.border}`, - boxShadow: "0px 0px 15px 0px rgb(0 0 0 / 70%)", width: "100%", - zIndex: "10", + overflow: "hidden", }); export const profileButtonContent = style({ @@ -75,16 +77,6 @@ export const profileButtonTitle = style({ whiteSpace: "nowrap", }); -export const friendRequestContainer = style({ - position: "absolute", - padding: "8px", - right: `${SPACING_UNIT}px`, - display: "flex", - top: 0, - bottom: 0, - alignItems: "center", -}); - export const friendRequestButton = style({ color: vars.color.success, cursor: "pointer", diff --git a/src/renderer/src/components/sidebar/sidebar-profile.tsx b/src/renderer/src/components/sidebar/sidebar-profile.tsx index 069831cb..e41d7da2 100644 --- a/src/renderer/src/components/sidebar/sidebar-profile.tsx +++ b/src/renderer/src/components/sidebar/sidebar-profile.tsx @@ -41,6 +41,9 @@ export function SidebarProfile() { return undefined; }, [profileBackground]); + const showPendingRequests = + userDetails && receivedRequests.length > -1 && !gameRunning; + return (
- {userDetails && receivedRequests.length > 0 && !gameRunning && ( -
- -
+ {showPendingRequests && ( + )}
); From 0bedb7c9b7e237e3bf872b1754f21782c624e4ce Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Mon, 26 Aug 2024 14:12:42 -0300 Subject: [PATCH 08/12] fix: header overflow text --- src/renderer/src/components/header/header.css.ts | 5 +++++ src/renderer/src/components/header/header.tsx | 2 +- src/renderer/src/components/sidebar/sidebar-profile.tsx | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/renderer/src/components/header/header.css.ts b/src/renderer/src/components/header/header.css.ts index 0e82aaef..12855986 100644 --- a/src/renderer/src/components/header/header.css.ts +++ b/src/renderer/src/components/header/header.css.ts @@ -104,6 +104,7 @@ export const section = style({ alignItems: "center", gap: `${SPACING_UNIT * 2}px`, height: "100%", + overflow: "hidden", }); export const backButton = recipe({ @@ -136,11 +137,15 @@ export const backButton = recipe({ export const title = recipe({ base: { transition: "all ease 0.2s", + overflow: "hidden", + textOverflow: "ellipsis", + width: "100%", }, variants: { hasBackButton: { true: { transform: "translateX(28px)", + width: "calc(100% - 28px)", }, }, }, diff --git a/src/renderer/src/components/header/header.tsx b/src/renderer/src/components/header/header.tsx index d3315098..c37e4b44 100644 --- a/src/renderer/src/components/header/header.tsx +++ b/src/renderer/src/components/header/header.tsx @@ -72,7 +72,7 @@ export function Header({ onSearch, onClear, search }: HeaderProps) { isWindows: window.electron.platform === "win32", })} > -
+
+ +
+

{t("undo_friendship_modal_text", { displayName })}

+
+ - -
+
-
- +
+ ); }; From d4d94dfc4cf3ff401a846596d40a843fe32ff8e5 Mon Sep 17 00:00:00 2001 From: Zamitto <167933696+zamitto@users.noreply.github.com> Date: Fri, 30 Aug 2024 10:13:18 -0300 Subject: [PATCH 12/12] feat: use function expression for component --- .../src/pages/user/user-confirm-undo-friendship-modal.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/renderer/src/pages/user/user-confirm-undo-friendship-modal.tsx b/src/renderer/src/pages/user/user-confirm-undo-friendship-modal.tsx index ad83bc00..cfdb5d06 100644 --- a/src/renderer/src/pages/user/user-confirm-undo-friendship-modal.tsx +++ b/src/renderer/src/pages/user/user-confirm-undo-friendship-modal.tsx @@ -9,12 +9,12 @@ export interface UserConfirmUndoFriendshipModalProps { onClose: () => void; } -export const UserConfirmUndoFriendshipModal = ({ +export function UserConfirmUndoFriendshipModal({ visible, displayName, onConfirm, onClose, -}: UserConfirmUndoFriendshipModalProps) => { +}: UserConfirmUndoFriendshipModalProps) { const { t } = useTranslation("user_profile"); return ( @@ -37,4 +37,4 @@ export const UserConfirmUndoFriendshipModal = ({
); -}; +}