fix: update theme logic

This commit is contained in:
Aaryan Khandelwal 2024-04-30 12:09:21 +05:30
parent c389c6b440
commit 9134d704e5
9 changed files with 79 additions and 76 deletions

View File

@ -48,7 +48,7 @@ export type TUserProfile = {
palette: string | undefined;
primary: string | undefined;
background: string | undefined;
darkPalette: string | undefined;
darkPalette: boolean | undefined;
sidebarText: string | undefined;
sidebarBackground: string | undefined;
};

View File

@ -1,11 +1,14 @@
import React, { FC, useEffect, useState } from "react";
import { FC, useEffect, useState } from "react";
import { Command } from "cmdk";
import { observer } from "mobx-react";
import { useTheme } from "next-themes";
// icons
import { Settings } from "lucide-react";
// ui
import { TOAST_TYPE, setToast } from "@plane/ui";
// constants
import { THEME_OPTIONS } from "@/constants/themes";
// hooks
import { useUserProfile } from "@/hooks/store";
type Props = {
closePalette: () => void;
@ -15,18 +18,20 @@ export const CommandPaletteThemeActions: FC<Props> = observer((props) => {
const { closePalette } = props;
// states
const [mounted, setMounted] = useState(false);
// hooks
// store hooks
const { updateCurrentUserTheme } = useUserProfile();
// next-themes
const { setTheme } = useTheme();
const updateUserTheme = async (newTheme: string) => {
setTheme(newTheme);
// return updateUserProfile({ theme: newTheme }).catch(() => {
// setToast({
// type: TOAST_TYPE.ERROR,
// title: "Failed to save user theme settings!",
// });
// });
return updateCurrentUserTheme(newTheme).catch(() => {
setToast({
type: TOAST_TYPE.ERROR,
title: "Failed to save user theme settings!",
});
});
};
// useEffect only runs on the client, so now we can safely show the UI

View File

@ -26,7 +26,7 @@ const inputRules = {
export const CustomThemeSelector: React.FC = observer(() => {
const {
profile: { data: userProfile },
profile: { data: userProfile, updateUserProfile },
} = useUser();
const userTheme: any = userProfile?.theme;
@ -64,9 +64,9 @@ export const CustomThemeSelector: React.FC = observer(() => {
setTheme("custom");
console.log(payload);
// return updateUserProfile({ theme: payload });
return updateUserProfile({
theme: payload,
});
};
const handleValueChange = (val: string | undefined, onChange: any) => {

View File

@ -33,3 +33,4 @@ export * from "./use-instance";
export * from "./use-app-theme";
export * from "./use-command-palette";
export * from "./use-app-router";
export * from "./use-app-theme";

View File

@ -2,7 +2,7 @@ import { FC, ReactNode } from "react";
// layout
import { SidebarHamburgerToggle } from "@/components/core/sidebar/sidebar-menu-hamburger-toggle";
import { PreferencesMobileHeader } from "@/components/profile/preferences/preferences-mobile-header";
import { useApplication } from "@/hooks/store";
import { useAppTheme } from "@/hooks/store";
import { ProfileSettingsLayout } from "@/layouts/settings-layout";
// local components
import { ProfilePreferenceSettingsSidebar } from "./sidebar";
@ -14,13 +14,14 @@ interface IProfilePreferenceSettingsLayout {
export const ProfilePreferenceSettingsLayout: FC<IProfilePreferenceSettingsLayout> = (props) => {
const { children, header } = props;
const { theme: themeStore } = useApplication();
// store hooks
const { toggleSidebar } = useAppTheme();
return (
<ProfileSettingsLayout
header={
<div className="md:hidden flex flex-shrink-0 gap-4 items-center justify-start border-b border-custom-border-200 p-4">
<SidebarHamburgerToggle onClick={() => themeStore.toggleSidebar()} />
<SidebarHamburgerToggle onClick={toggleSidebar} />
</div>
}
>

View File

@ -43,11 +43,19 @@ const StoreWrapper: FC<TStoreWrapper> = observer((props) => {
if (!userProfile) return;
if (window) setDom(window.document?.querySelector<HTMLElement>("[data-theme='custom']") || undefined);
setTheme(userProfile?.theme?.theme || "system");
if (userProfile?.theme?.theme === "custom" && userProfile?.theme?.palette && dom)
applyTheme(userProfile?.theme?.palette, false);
else unsetCustomCssVariables();
}, [userProfile, setTheme, dom]);
const themeData = userProfile.theme;
console.log("userProfile", userProfile.theme.theme);
setTheme(themeData?.theme || "system");
if (themeData?.theme === "custom" && themeData?.palette && dom) {
console.log("Setting...");
applyTheme(themeData?.palette, false);
} else {
console.log("Unsetting...");
unsetCustomCssVariables();
}
}, [dom, setTheme, userProfile]);
useEffect(() => {
if (!router.query) return;

View File

@ -2,10 +2,7 @@ import { useEffect, useState, ReactElement } from "react";
import { observer } from "mobx-react";
import { useTheme } from "next-themes";
// ui
import {
Spinner,
// setPromiseToast
} from "@plane/ui";
import { Spinner, setPromiseToast } from "@plane/ui";
// components
import { CustomThemeSelector, ThemeSwitch, PageHead } from "@/components/core";
// constants
@ -23,7 +20,7 @@ const ProfilePreferencesThemePage: NextPageWithLayout = observer(() => {
// store hooks
const {
data: currentUser,
profile: { data: userProfile },
profile: { data: userProfile, updateCurrentUserTheme },
} = useUser();
// computed
const userTheme = userProfile?.theme;
@ -41,24 +38,24 @@ const ProfilePreferencesThemePage: NextPageWithLayout = observer(() => {
const handleThemeChange = (themeOption: I_THEME_OPTION) => {
setTheme(themeOption.value);
// const updateCurrentUserThemePromise = updateCurrentUserTheme(themeOption.value);
const updateCurrentUserThemePromise = updateCurrentUserTheme(themeOption.value);
// setPromiseToast(updateCurrentUserThemePromise, {
// loading: "Updating theme...",
// success: {
// title: "Success!",
// message: () => "Theme updated successfully!",
// },
// error: {
// title: "Error!",
// message: () => "Failed to Update the theme",
// },
// });
setPromiseToast(updateCurrentUserThemePromise, {
loading: "Updating theme...",
success: {
title: "Success!",
message: () => "Theme updated successfully!",
},
error: {
title: "Error!",
message: () => "Failed to Update the theme",
},
});
};
return (
<>
<PageHead title="Profile - Theme Prefrence" />
<PageHead title="Profile - Theme Preference" />
{currentUser ? (
<div className="mx-auto mt-10 h-full w-full overflow-y-auto md:px-6 px-4 pb-8 md:mt-14 lg:px-20 vertical-scrollbar scrollbar-md">
<div className="flex items-center border-b border-custom-border-100 pb-3.5">

View File

@ -1,18 +1,13 @@
// mobx
import { action, observable, makeObservable } from "mobx";
// helper
import { applyTheme, unsetCustomCssVariables } from "@/helpers/theme.helper";
export interface IThemeStore {
// observables
theme: string | null;
sidebarCollapsed: boolean | undefined;
profileSidebarCollapsed: boolean | undefined;
workspaceAnalyticsSidebarCollapsed: boolean | undefined;
issueDetailSidebarCollapsed: boolean | undefined;
// actions
toggleSidebar: (collapsed?: boolean) => void;
setTheme: (theme: any) => void;
toggleProfileSidebar: (collapsed?: boolean) => void;
toggleWorkspaceAnalyticsSidebar: (collapsed?: boolean) => void;
toggleIssueDetailSidebar: (collapsed?: boolean) => void;
@ -21,7 +16,6 @@ export interface IThemeStore {
export class ThemeStore implements IThemeStore {
// observables
sidebarCollapsed: boolean | undefined = undefined;
theme: string | null = null;
profileSidebarCollapsed: boolean | undefined = undefined;
workspaceAnalyticsSidebarCollapsed: boolean | undefined = undefined;
issueDetailSidebarCollapsed: boolean | undefined = undefined;
@ -32,13 +26,11 @@ export class ThemeStore implements IThemeStore {
makeObservable(this, {
// observable
sidebarCollapsed: observable.ref,
theme: observable.ref,
profileSidebarCollapsed: observable.ref,
workspaceAnalyticsSidebarCollapsed: observable.ref,
issueDetailSidebarCollapsed: observable.ref,
// action
toggleSidebar: action,
setTheme: action,
toggleProfileSidebar: action,
toggleWorkspaceAnalyticsSidebar: action,
toggleIssueDetailSidebar: action,
@ -95,30 +87,4 @@ export class ThemeStore implements IThemeStore {
}
localStorage.setItem("issue_detail_sidebar_collapsed", this.issueDetailSidebarCollapsed.toString());
};
/**
* Sets the user theme and applies it to the platform
* @param _theme
*/
setTheme = async (_theme: { theme: any }) => {
try {
const currentTheme: string = _theme?.theme?.theme?.toString();
// updating the local storage theme value
localStorage.setItem("theme", currentTheme);
// updating the mobx theme value
this.theme = currentTheme;
// applying the theme to platform if the selected theme is custom
if (currentTheme === "custom") {
const themeSettings = this.rootStore.user.currentUserSettings || null;
applyTheme(
themeSettings?.theme?.palette !== ",,,,"
? themeSettings?.theme?.palette
: "#0d101b,#c5c5c5,#3f76ff,#0d101b,#c5c5c5",
themeSettings?.theme?.darkPalette
);
} else unsetCustomCssVariables();
} catch (error) {
console.error("setting user theme error", error);
}
};
}

View File

@ -1,8 +1,9 @@
import set from "lodash/set";
import { action, makeObservable, observable, runInAction } from "mobx";
// services
import { UserService } from "services/user.service";
// types
import { TUserProfile } from "@plane/types";
// services
import { UserService } from "@/services/user.service";
type TError = {
status: string;
@ -19,6 +20,7 @@ export interface IProfileStore {
updateUserProfile: (data: Partial<TUserProfile>) => Promise<void>;
updateUserOnBoard: () => Promise<void>;
updateTourCompleted: () => Promise<void>;
updateCurrentUserTheme: (theme: string) => Promise<void>;
}
export class ProfileStore implements IProfileStore {
@ -68,6 +70,7 @@ export class ProfileStore implements IProfileStore {
updateUserProfile: action,
updateUserOnBoard: action,
updateTourCompleted: action,
updateCurrentUserTheme: action,
});
// services
this.userService = new UserService();
@ -164,4 +167,26 @@ export class ProfileStore implements IProfileStore {
throw error;
}
};
/**
* Updates the current user theme
* @param theme
* @returns Promise<void>
*/
updateCurrentUserTheme = async (theme: string) => {
const originalTheme = this.data?.theme?.theme;
try {
set(this.data, "theme.theme", theme);
const response = await this.updateUserProfile({
theme: {
...this.data?.theme,
theme,
},
});
return response;
} catch (error) {
set(this.data, "theme.theme", originalTheme);
throw error;
}
};
}