Skip to content

Commit

Permalink
Merge branch 'feature/custom-themes' of github.com:hydralauncher/hydr…
Browse files Browse the repository at this point in the history
…a into feature/custom-themes
  • Loading branch information
thegrannychaseroperation committed Feb 16, 2025
2 parents c36aff8 + 3f6315f commit 9449d7c
Show file tree
Hide file tree
Showing 8 changed files with 181 additions and 35 deletions.
1 change: 1 addition & 0 deletions src/main/events/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ import "./themes/get-custom-theme-by-id";
import "./themes/get-active-custom-theme";
import "./themes/css-injector";
import "./themes/close-editor-window";
import "./themes/import-theme";
import { isPortableVersion } from "@main/helpers";

ipcMain.handle("ping", () => "pong");
Expand Down
64 changes: 32 additions & 32 deletions src/main/events/themes/deeplink.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,38 @@
import { themes } from "@main/level/sublevels/themes";
import { WindowManager } from "@main/services";
import { Theme } from "@types";
// import { themes } from "@main/level/sublevels/themes";
// import { WindowManager } from "@main/services";
// import { Theme } from "@types";

export const handleDeepLinkTheme = async (
themeName: string,
authorCode: string
) => {
const theme: Theme = {
id: crypto.randomUUID(),
name: themeName,
isActive: false,
author: authorCode,
authorName: "spectre",
code: `https://hydrathemes.shop/themes/${themeName}.css`,
createdAt: new Date(),
updatedAt: new Date(),
};
// export const handleDeepLinkTheme = async (
// themeName: string,
// authorCode: string
// ) => {
// const theme: Theme = {
// id: crypto.randomUUID(),
// name: themeName,
// isActive: false,
// author: authorCode,
// authorName: "spectre",
// code: `https://hydrathemes.shop/themes/${themeName}.css`,
// createdAt: new Date(),
// updatedAt: new Date(),
// };

await themes.put(theme.id, theme);
// await themes.put(theme.id, theme);

const allThemes = await themes.values().all();
const activeTheme = allThemes.find((theme: Theme) => theme.isActive);
// const allThemes = await themes.values().all();
// const activeTheme = allThemes.find((theme: Theme) => theme.isActive);

if (activeTheme) {
await themes.put(activeTheme.id, {
...activeTheme,
isActive: false,
});
}
// if (activeTheme) {
// await themes.put(activeTheme.id, {
// ...activeTheme,
// isActive: false,
// });
// }

WindowManager.mainWindow?.webContents.send("css-injected", theme.code);
// WindowManager.mainWindow?.webContents.send("css-injected", theme.code);

await themes.put(theme.id, {
...theme,
isActive: true,
});
};
// await themes.put(theme.id, {
// ...theme,
// isActive: true,
// });
// };
12 changes: 12 additions & 0 deletions src/main/events/themes/import-theme.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { registerEvent } from "../register-event";
import { WindowManager } from "@main/services";

const importTheme = async (
_event: Electron.IpcMainInvokeEvent,
theme: string,
author: string
) => {
WindowManager.mainWindow?.webContents.send("import-theme", theme, author);
};

registerEvent("importTheme", importTheme);
7 changes: 5 additions & 2 deletions src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { PythonRPC } from "./services/python-rpc";
import { Aria2 } from "./services/aria2";
import { db, levelKeys } from "./level";
import { loadState } from "./main";
import { handleDeepLinkTheme } from "./events/themes/deeplink";

const { autoUpdater } = updater;

Expand Down Expand Up @@ -93,7 +92,11 @@ const handleDeepLinkPath = (uri?: string) => {
const authorCode = url.searchParams.get("author");

if (themeName && authorCode) {
handleDeepLinkTheme(themeName, authorCode);
WindowManager.mainWindow?.webContents.send(
"import-theme",
themeName,
authorCode
);
}
}
} catch (error) {
Expand Down
9 changes: 9 additions & 0 deletions src/preload/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,15 @@ contextBridge.exposeInMainWorld("electron", {
getCustomThemeById: (themeId: string) =>
ipcRenderer.invoke("getCustomThemeById", themeId),
getActiveCustomTheme: () => ipcRenderer.invoke("getActiveCustomTheme"),
onImportTheme: (cb: (theme: string, author: string) => void) => {
const listener = (
_event: Electron.IpcRendererEvent,
theme: string,
author: string
) => cb(theme, author);
ipcRenderer.on("import-theme", listener);
return () => ipcRenderer.removeListener("import-theme", listener);
},

/* Editor */
openEditorWindow: (themeId: string) =>
Expand Down
28 changes: 27 additions & 1 deletion src/renderer/src/app.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useCallback, useEffect, useRef } from "react";
import { useCallback, useEffect, useRef, useState } from "react";
import achievementSound from "@renderer/assets/audio/achievement.wav";
import { Sidebar, BottomPanel, Header, Toast } from "@renderer/components";

Expand Down Expand Up @@ -30,6 +30,7 @@ import { HydraCloudModal } from "./pages/shared-modals/hydra-cloud/hydra-cloud-m

import { injectCustomCss } from "./helpers";
import "./app.scss";
import { ImportThemeModal } from "./pages/settings/aparence/modals/import-theme-modal";

export interface AppProps {
children: React.ReactNode;
Expand All @@ -38,6 +39,12 @@ export interface AppProps {
export function App() {
const contentRef = useRef<HTMLDivElement>(null);
const { updateLibrary, library } = useLibrary();
const [isImportThemeModalVisible, setIsImportThemeModalVisible] =
useState(false);
const [importTheme, setImportTheme] = useState<{
theme: string;
author: string;
} | null>(null);

const { t } = useTranslation("app");

Expand Down Expand Up @@ -271,6 +278,15 @@ export function App() {
return () => unsubscribe();
}, []);

useEffect(() => {
const unsubscribe = window.electron.onImportTheme((theme, author) => {
setImportTheme({ theme, author });
setIsImportThemeModalVisible(true);
});

return () => unsubscribe();
}, []);

const handleToastClose = useCallback(() => {
dispatch(closeToast());
}, [dispatch]);
Expand Down Expand Up @@ -312,6 +328,16 @@ export function App() {
/>
)}

{importTheme && (
<ImportThemeModal
visible={isImportThemeModalVisible}
onClose={() => setIsImportThemeModalVisible(false)}
onThemeImported={() => setIsImportThemeModalVisible(false)}
themeName={importTheme.theme}
authorCode={importTheme.author}
/>
)}

<main>
<Sidebar />

Expand Down
3 changes: 3 additions & 0 deletions src/renderer/src/declaration.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,9 @@ declare global {
updateCustomTheme: (themeId: string, theme: Theme) => Promise<void>;
getCustomThemeById: (themeId: string) => Promise<Theme | null>;
getActiveCustomTheme: () => Promise<Theme | null>;
onImportTheme: (
cb: (theme: string, author: string) => void
) => () => Electron.IpcRenderer;

/* Editor */
openEditorWindow: (themeId: string) => Promise<void>;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { Button } from "@renderer/components/button/button";
import { Modal } from "@renderer/components/modal/modal";
import { useTranslation } from "react-i18next";
import "./modals.scss";
import { Theme } from "@types";
import { injectCustomCss, removeCustomCss } from "@renderer/helpers";
import { useToast } from "@renderer/hooks";

interface ImportThemeModalProps {
visible: boolean;
onClose: () => void;
onThemeImported: () => void;
themeName: string;
authorCode: string;
}

export const ImportThemeModal = ({
visible,
onClose,
onThemeImported,
themeName,
authorCode,
}: ImportThemeModalProps) => {
const { t } = useTranslation("settings");
const { showSuccessToast, showErrorToast } = useToast();

const handleImportTheme = async () => {
const theme: Theme = {
id: crypto.randomUUID(),
name: themeName,
isActive: false,
author: authorCode,
authorName: "spectre",
code: `https://hydrathemes.shop/themes/${themeName}.css`,
createdAt: new Date(),
updatedAt: new Date(),
};

try {
await window.electron.addCustomTheme(theme);

const currentTheme = await window.electron.getCustomThemeById(theme.id);

if (!currentTheme) return;

const activeTheme = await window.electron.getActiveCustomTheme();

if (activeTheme) {
removeCustomCss();
await window.electron.updateCustomTheme(activeTheme.id, {
...activeTheme,
isActive: false,
});
}

if (currentTheme.code) {
injectCustomCss(currentTheme.code);
}

await window.electron.updateCustomTheme(currentTheme.id, {
...currentTheme,
isActive: true,
});
onThemeImported();
showSuccessToast(t("theme_imported"));
onClose();
} catch (error) {
console.error(error);
showErrorToast(t("error_importing_theme"));
onClose();
}
};

return (
<Modal
visible={visible}
title={t("import_theme")}
description={t("import_theme_description")}
onClose={onClose}
>
<div className="delete-all-themes-modal__container">
<Button theme="outline" onClick={handleImportTheme}>
{t("import_theme")}
</Button>

<Button theme="primary" onClick={onClose}>
{t("cancel")}
</Button>
</div>
</Modal>
);
};

0 comments on commit 9449d7c

Please sign in to comment.