mirror of
https://github.com/hydralauncher/hydra.git
synced 2025-02-13 03:32:13 +00:00
feat: implement custom theme management
This commit is contained in:
parent
6bf049d136
commit
58f63cab44
12 changed files with 95 additions and 0 deletions
|
@ -74,6 +74,10 @@ import "./cloud-save/upload-save-game";
|
||||||
import "./cloud-save/delete-game-artifact";
|
import "./cloud-save/delete-game-artifact";
|
||||||
import "./cloud-save/select-game-backup-path";
|
import "./cloud-save/select-game-backup-path";
|
||||||
import "./notifications/publish-new-repacks-notification";
|
import "./notifications/publish-new-repacks-notification";
|
||||||
|
import "./themes/add-custom-theme";
|
||||||
|
import "./themes/delete-custom-theme";
|
||||||
|
import "./themes/get-all-custom-themes";
|
||||||
|
import "./themes/delete-all-custom-themes";
|
||||||
import { isPortableVersion } from "@main/helpers";
|
import { isPortableVersion } from "@main/helpers";
|
||||||
|
|
||||||
ipcMain.handle("ping", () => "pong");
|
ipcMain.handle("ping", () => "pong");
|
||||||
|
|
12
src/main/events/themes/add-custom-theme.ts
Normal file
12
src/main/events/themes/add-custom-theme.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
import { Theme } from "@types";
|
||||||
|
import { themes } from "@main/level/sublevels/themes";
|
||||||
|
import { registerEvent } from "../register-event";
|
||||||
|
|
||||||
|
const addCustomTheme = async (
|
||||||
|
_event: Electron.IpcMainInvokeEvent,
|
||||||
|
theme: Theme
|
||||||
|
) => {
|
||||||
|
await themes.put(theme.id, theme);
|
||||||
|
};
|
||||||
|
|
||||||
|
registerEvent("addCustomTheme", addCustomTheme);
|
9
src/main/events/themes/delete-all-custom-themes.ts
Normal file
9
src/main/events/themes/delete-all-custom-themes.ts
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
import { themes } from "@main/level/sublevels/themes";
|
||||||
|
import { registerEvent } from "../register-event";
|
||||||
|
|
||||||
|
const deleteAllCustomThemes = async (_event: Electron.IpcMainInvokeEvent) => {
|
||||||
|
console.log("sexo2");
|
||||||
|
await themes.clear();
|
||||||
|
};
|
||||||
|
|
||||||
|
registerEvent("deleteAllCustomThemes", deleteAllCustomThemes);
|
11
src/main/events/themes/delete-custom-theme.ts
Normal file
11
src/main/events/themes/delete-custom-theme.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { themes } from "@main/level/sublevels/themes";
|
||||||
|
import { registerEvent } from "../register-event";
|
||||||
|
|
||||||
|
const deleteCustomTheme = async (
|
||||||
|
_event: Electron.IpcMainInvokeEvent,
|
||||||
|
themeId: string
|
||||||
|
) => {
|
||||||
|
await themes.del(themeId);
|
||||||
|
};
|
||||||
|
|
||||||
|
registerEvent("deleteCustomTheme", deleteCustomTheme);
|
8
src/main/events/themes/get-all-custom-themes.ts
Normal file
8
src/main/events/themes/get-all-custom-themes.ts
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import { themes } from "@main/level/sublevels/themes";
|
||||||
|
import { registerEvent } from "../register-event";
|
||||||
|
|
||||||
|
const getAllCustomThemes = async (_event: Electron.IpcMainInvokeEvent) => {
|
||||||
|
return await themes.values().all();
|
||||||
|
};
|
||||||
|
|
||||||
|
registerEvent("getAllCustomThemes", getAllCustomThemes);
|
|
@ -32,3 +32,8 @@ export const isPortableVersion = () => {
|
||||||
|
|
||||||
export const normalizePath = (str: string) =>
|
export const normalizePath = (str: string) =>
|
||||||
path.posix.normalize(str).replace(/\\/g, "/");
|
path.posix.normalize(str).replace(/\\/g, "/");
|
||||||
|
|
||||||
|
export const isValidHexColor = (color: string): boolean => {
|
||||||
|
const hexColorRegex = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
|
||||||
|
return hexColorRegex.test(color);
|
||||||
|
};
|
||||||
|
|
|
@ -5,6 +5,7 @@ export const levelKeys = {
|
||||||
game: (shop: GameShop, objectId: string) => `${shop}:${objectId}`,
|
game: (shop: GameShop, objectId: string) => `${shop}:${objectId}`,
|
||||||
user: "user",
|
user: "user",
|
||||||
auth: "auth",
|
auth: "auth",
|
||||||
|
themes: "themes",
|
||||||
gameShopCache: "gameShopCache",
|
gameShopCache: "gameShopCache",
|
||||||
gameShopCacheItem: (shop: GameShop, objectId: string, language: string) =>
|
gameShopCacheItem: (shop: GameShop, objectId: string, language: string) =>
|
||||||
`${shop}:${objectId}:${language}`,
|
`${shop}:${objectId}:${language}`,
|
||||||
|
|
7
src/main/level/sublevels/themes.ts
Normal file
7
src/main/level/sublevels/themes.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import type { Theme } from "@types";
|
||||||
|
import { db } from "../level";
|
||||||
|
import { levelKeys } from "./keys";
|
||||||
|
|
||||||
|
export const themes = db.sublevel<string, Theme>(levelKeys.themes, {
|
||||||
|
valueEncoding: "json",
|
||||||
|
});
|
|
@ -14,6 +14,7 @@ import type {
|
||||||
CatalogueSearchPayload,
|
CatalogueSearchPayload,
|
||||||
SeedingStatus,
|
SeedingStatus,
|
||||||
GameAchievement,
|
GameAchievement,
|
||||||
|
Theme,
|
||||||
} from "@types";
|
} from "@types";
|
||||||
import type { AuthPage, CatalogueCategory } from "@shared";
|
import type { AuthPage, CatalogueCategory } from "@shared";
|
||||||
import type { AxiosProgressEvent } from "axios";
|
import type { AxiosProgressEvent } from "axios";
|
||||||
|
@ -334,4 +335,11 @@ contextBridge.exposeInMainWorld("electron", {
|
||||||
/* Notifications */
|
/* Notifications */
|
||||||
publishNewRepacksNotification: (newRepacksCount: number) =>
|
publishNewRepacksNotification: (newRepacksCount: number) =>
|
||||||
ipcRenderer.invoke("publishNewRepacksNotification", newRepacksCount),
|
ipcRenderer.invoke("publishNewRepacksNotification", newRepacksCount),
|
||||||
|
|
||||||
|
/* Themes */
|
||||||
|
addCustomTheme: (theme: Theme) => ipcRenderer.invoke("addCustomTheme", theme),
|
||||||
|
getAllCustomThemes: () => ipcRenderer.invoke("getAllCustomThemes"),
|
||||||
|
deleteAllCustomThemes: () => ipcRenderer.invoke("deleteAllCustomThemes"),
|
||||||
|
deleteCustomTheme: (themeId: string) =>
|
||||||
|
ipcRenderer.invoke("deleteCustomTheme", themeId),
|
||||||
});
|
});
|
||||||
|
|
6
src/renderer/src/declaration.d.ts
vendored
6
src/renderer/src/declaration.d.ts
vendored
|
@ -269,6 +269,12 @@ declare global {
|
||||||
|
|
||||||
/* Notifications */
|
/* Notifications */
|
||||||
publishNewRepacksNotification: (newRepacksCount: number) => Promise<void>;
|
publishNewRepacksNotification: (newRepacksCount: number) => Promise<void>;
|
||||||
|
|
||||||
|
/* Themes */
|
||||||
|
addCustomTheme: (theme: Theme) => Promise<void>;
|
||||||
|
getAllCustomThemes: () => Promise<Theme[]>;
|
||||||
|
deleteAllCustomThemes: () => Promise<void>;
|
||||||
|
deleteCustomTheme: (themeId: string) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Window {
|
interface Window {
|
||||||
|
|
|
@ -294,3 +294,4 @@ export * from "./download.types";
|
||||||
export * from "./ludusavi.types";
|
export * from "./ludusavi.types";
|
||||||
export * from "./how-long-to-beat.types";
|
export * from "./how-long-to-beat.types";
|
||||||
export * from "./level.types";
|
export * from "./level.types";
|
||||||
|
export * from "./theme.types";
|
||||||
|
|
23
src/types/theme.types.ts
Normal file
23
src/types/theme.types.ts
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
import { isValidHexColor } from "@main/helpers";
|
||||||
|
import { z } from "zod";
|
||||||
|
|
||||||
|
const hexColorSchema = z.string().refine(isValidHexColor);
|
||||||
|
type HexColorType = z.infer<typeof hexColorSchema>;
|
||||||
|
|
||||||
|
export interface Theme {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
colors: {
|
||||||
|
accent: HexColorType;
|
||||||
|
background: HexColorType;
|
||||||
|
surface: HexColorType;
|
||||||
|
optional1?: HexColorType;
|
||||||
|
optional2?: HexColorType;
|
||||||
|
};
|
||||||
|
description?: string;
|
||||||
|
author: number;
|
||||||
|
isActive: boolean;
|
||||||
|
code: string;
|
||||||
|
createdAt: Date;
|
||||||
|
updatedAt: Date;
|
||||||
|
}
|
Loading…
Reference in a new issue