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 f1e47fc + 5a6f66a commit 777f857
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 32 deletions.
6 changes: 5 additions & 1 deletion src/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -328,7 +328,11 @@
"torbox_description": "TorBox is your premium seedbox service rivaling even the best servers on the market.",
"torbox_account_linked": "TorBox account linked",
"real_debrid_account_linked": "Real-Debrid account linked",
"name_min_length": "Theme name must be at least 3 characters long"
"name_min_length": "Theme name must be at least 3 characters long",
"import_theme": "Import theme",
"import_theme_description": "You will import {{theme}} from the theme store",
"error_importing_theme": "Error importing theme",
"theme_imported": "Theme imported successfully"
},
"notifications": {
"download_complete": "Download complete",
Expand Down
7 changes: 4 additions & 3 deletions src/main/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,12 @@ const handleDeepLinkPath = (uri?: string) => {

if (url.host === "install-theme") {
const themeName = url.searchParams.get("theme");
const authorCode = url.searchParams.get("author");
const authorId = url.searchParams.get("authorId");
const authorName = url.searchParams.get("authorName");

if (themeName && authorCode) {
if (themeName && authorId && authorName) {
WindowManager.redirect(
`settings?theme=${themeName}&author=${authorCode}`
`settings?theme=${themeName}&authorId=${authorId}&authorName=${authorName}`
);
}
}
Expand Down
34 changes: 26 additions & 8 deletions src/renderer/src/context/settings/settings.context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ export interface SettingsContext {
blockedUsers: UserBlocks["blocks"];
fetchBlockedUsers: () => Promise<void>;
appearanceTheme: string | null;
appearanceAuthor: string | null;
appearanceAuthorId: string | null;
appearanceAuthorName: string | null;
}

export const settingsContext = createContext<SettingsContext>({
Expand All @@ -26,7 +27,8 @@ export const settingsContext = createContext<SettingsContext>({
blockedUsers: [],
fetchBlockedUsers: async () => {},
appearanceTheme: null,
appearanceAuthor: null,
appearanceAuthorId: null,
appearanceAuthorName: null,
});

const { Provider } = settingsContext;
Expand All @@ -42,15 +44,21 @@ export function SettingsContextProvider({
const dispatch = useAppDispatch();
const [sourceUrl, setSourceUrl] = useState<string | null>(null);
const [appearanceTheme, setAppearanceTheme] = useState<string | null>(null);
const [appearanceAuthor, setAppearanceAuthor] = useState<string | null>(null);
const [appearanceAuthorId, setAppearanceAuthorId] = useState<string | null>(
null
);
const [appearanceAuthorName, setAppearanceAuthorName] = useState<
string | null
>(null);
const [currentCategoryIndex, setCurrentCategoryIndex] = useState(0);

const [blockedUsers, setBlockedUsers] = useState<UserBlocks["blocks"]>([]);

const [searchParams] = useSearchParams();
const defaultSourceUrl = searchParams.get("urls");
const defaultAppearanceTheme = searchParams.get("theme");
const defaultAppearanceAuthor = searchParams.get("author");
const defaultAppearanceAuthorId = searchParams.get("authorId");
const defaultAppearanceAuthorName = searchParams.get("authorName");

useEffect(() => {
if (sourceUrl) setCurrentCategoryIndex(2);
Expand All @@ -67,11 +75,20 @@ export function SettingsContextProvider({
}, [appearanceTheme]);

useEffect(() => {
if (defaultAppearanceTheme && defaultAppearanceAuthor) {
if (
defaultAppearanceTheme &&
defaultAppearanceAuthorId &&
defaultAppearanceAuthorName
) {
setAppearanceTheme(defaultAppearanceTheme);
setAppearanceAuthor(defaultAppearanceAuthor);
setAppearanceAuthorId(defaultAppearanceAuthorId);
setAppearanceAuthorName(defaultAppearanceAuthorName);
}
}, [defaultAppearanceTheme, defaultAppearanceAuthor]);
}, [
defaultAppearanceTheme,
defaultAppearanceAuthorId,
defaultAppearanceAuthorName,
]);

const fetchBlockedUsers = useCallback(async () => {
const blockedUsers = await window.electron.getBlockedUsers(12, 0);
Expand Down Expand Up @@ -102,7 +119,8 @@ export function SettingsContextProvider({
sourceUrl,
blockedUsers,
appearanceTheme,
appearanceAuthor,
appearanceAuthorId,
appearanceAuthorName,
}}
>
{children}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Button } from "@renderer/components/button/button";
import { Modal } from "@renderer/components/modal/modal";
import { useTranslation } from "react-i18next";
import "./modals.scss";
import { Theme, UserProfile } from "@types";
import { Theme } from "@types";
import { injectCustomCss, removeCustomCss } from "@renderer/helpers";
import { useToast } from "@renderer/hooks";
import { THEME_WEB_STORE_URL } from "@renderer/constants";
Expand All @@ -13,31 +13,28 @@ interface ImportThemeModalProps {
onClose: () => void;
onThemeImported: () => void;
themeName: string;
authorCode: string;
authorId: string;
authorName: string;
}

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

let author: UserProfile | null = null;
window.electron.getUser(authorCode).then((user) => {
author = user;
});

const handleImportTheme = async () => {
const theme: Theme = {
id: crypto.randomUUID(),
name: themeName,
isActive: false,
author: author?.id,
authorName: author?.displayName,
author: authorId,
authorName: authorName,
code: `${THEME_WEB_STORE_URL}/themes/${themeName.toLowerCase()}/theme.css`,
createdAt: new Date(),
updatedAt: new Date(),
Expand Down
19 changes: 12 additions & 7 deletions src/renderer/src/pages/settings/aparence/settings-appearance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,22 @@ import { ImportThemeModal } from "./modals/import-theme-modal";

interface SettingsAppearanceProps {
appearanceTheme: string | null;
appearanceAuthor: string | null;
appearanceAuthorId: string | null;
appearanceAuthorName: string | null;
}

export const SettingsAppearance = ({
appearanceTheme,
appearanceAuthor,
appearanceAuthorId,
appearanceAuthorName,
}: SettingsAppearanceProps) => {
const [themes, setThemes] = useState<Theme[]>([]);
const [isImportThemeModalVisible, setIsImportThemeModalVisible] =
useState(false);
const [importTheme, setImportTheme] = useState<{
theme: string;
author: string;
authorId: string;
authorName: string;
} | null>(null);

const loadThemes = async () => {
Expand All @@ -39,14 +42,15 @@ export const SettingsAppearance = ({
}, []);

useEffect(() => {
if (appearanceTheme && appearanceAuthor) {
if (appearanceTheme && appearanceAuthorId && appearanceAuthorName) {
setIsImportThemeModalVisible(true);
setImportTheme({
theme: appearanceTheme,
author: appearanceAuthor,
authorId: appearanceAuthorId,
authorName: appearanceAuthorName,
});
}
}, [appearanceTheme, appearanceAuthor]);
}, [appearanceTheme, appearanceAuthorId, appearanceAuthorName]);

return (
<div className="settings-appearance">
Expand Down Expand Up @@ -81,7 +85,8 @@ export const SettingsAppearance = ({
loadThemes();
}}
themeName={importTheme.theme}
authorCode={importTheme.author}
authorId={importTheme.authorId}
authorName={importTheme.authorName}
/>
)}
</div>
Expand Down
12 changes: 9 additions & 3 deletions src/renderer/src/pages/settings/settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ export default function Settings() {
{
tabLabel: (
<>
<img src={torBoxLogo} alt="TorBox" style={{ width: 13 }} />
<img
src={torBoxLogo}
alt="TorBox"
style={{ width: 13, height: 13 }}
/>{" "}
Torbox
</>
),
Expand All @@ -65,7 +69,8 @@ export default function Settings() {
currentCategoryIndex,
setCurrentCategoryIndex,
appearanceTheme,
appearanceAuthor,
appearanceAuthorId,
appearanceAuthorName,
}) => {
const renderCategory = () => {
if (currentCategoryIndex === 0) {
Expand All @@ -84,7 +89,8 @@ export default function Settings() {
return (
<SettingsAppearance
appearanceTheme={appearanceTheme}
appearanceAuthor={appearanceAuthor}
appearanceAuthorId={appearanceAuthorId}
appearanceAuthorName={appearanceAuthorName}
/>
);
}
Expand Down

0 comments on commit 777f857

Please sign in to comment.