mirror of
https://github.com/usememos/memos.git
synced 2025-12-16 05:43:06 +08:00
Merge a284053831 into 5f57f48673
This commit is contained in:
commit
f028bcb001
4 changed files with 39 additions and 6 deletions
|
|
@ -1,6 +1,8 @@
|
|||
import { observer } from "mobx-react-lite";
|
||||
import { useState } from "react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { workspaceStore } from "@/store";
|
||||
import { loadTheme } from "@/utils/theme";
|
||||
import LocaleSelect from "./LocaleSelect";
|
||||
import ThemeSelect from "./ThemeSelect";
|
||||
|
||||
|
|
@ -9,10 +11,22 @@ interface Props {
|
|||
}
|
||||
|
||||
const AuthFooter = observer(({ className }: Props) => {
|
||||
// Local state for login page theme since we can't persist to server
|
||||
const [localTheme, setLocalTheme] = useState(workspaceStore.state.theme || "default");
|
||||
|
||||
const handleThemeChange = (theme: string) => {
|
||||
// Update local state
|
||||
setLocalTheme(theme);
|
||||
// Update workspace store for immediate UI feedback
|
||||
workspaceStore.state.setPartial({ theme });
|
||||
// Apply theme to DOM
|
||||
loadTheme(theme);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={cn("mt-4 flex flex-row items-center justify-center w-full gap-2", className)}>
|
||||
<LocaleSelect value={workspaceStore.state.locale} onChange={(locale) => workspaceStore.state.setPartial({ locale })} />
|
||||
<ThemeSelect value={workspaceStore.state.theme} onValueChange={(theme) => workspaceStore.state.setPartial({ theme })} />
|
||||
<ThemeSelect value={localTheme} onValueChange={handleThemeChange} />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -47,7 +47,10 @@ const PreferencesSection = observer(() => {
|
|||
</div>
|
||||
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<span>{t("setting.preference-section.theme")}</span>
|
||||
<div className="flex flex-col">
|
||||
<span>{t("setting.preference-section.theme")}</span>
|
||||
<span className="text-xs text-muted-foreground">Your personal theme preference (overrides default)</span>
|
||||
</div>
|
||||
<ThemeSelect value={setting.theme} onValueChange={handleThemeChange} />
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -81,7 +81,10 @@ const WorkspaceSection = observer(() => {
|
|||
<Separator />
|
||||
<p className="font-medium text-foreground">{t("setting.system-section.title")}</p>
|
||||
<div className="w-full flex flex-row justify-between items-center">
|
||||
<span>Theme</span>
|
||||
<div className="flex flex-col">
|
||||
<span>Default Theme</span>
|
||||
<span className="text-xs text-muted-foreground">Sets the default theme for all users</span>
|
||||
</div>
|
||||
<ThemeSelect
|
||||
value={workspaceGeneralSetting.theme || "default"}
|
||||
onValueChange={(value: string) => updatePartialSetting({ theme: value })}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
import { observer } from "mobx-react-lite";
|
||||
import { Moon, Palette, Sun, Wallpaper } from "lucide-react";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { workspaceStore } from "@/store";
|
||||
import { workspaceStore, userStore } from "@/store";
|
||||
import { THEME_OPTIONS } from "@/utils/theme";
|
||||
|
||||
interface ThemeSelectProps {
|
||||
value?: string;
|
||||
onValueChange?: (theme: string) => void;
|
||||
className?: string;
|
||||
showEffectiveTheme?: boolean;
|
||||
}
|
||||
|
||||
const THEME_ICONS: Record<string, JSX.Element> = {
|
||||
|
|
@ -16,8 +18,13 @@ const THEME_ICONS: Record<string, JSX.Element> = {
|
|||
whitewall: <Wallpaper className="w-4 h-4" />,
|
||||
};
|
||||
|
||||
const ThemeSelect = ({ value, onValueChange, className }: ThemeSelectProps = {}) => {
|
||||
const ThemeSelect = observer(({ value, onValueChange, className, showEffectiveTheme = false }: ThemeSelectProps = {}) => {
|
||||
const currentTheme = value || workspaceStore.state.theme || "default";
|
||||
|
||||
// Calculate effective theme (user preference overrides workspace default)
|
||||
const effectiveTheme = userStore.state.userGeneralSetting?.theme || workspaceStore.state.theme || "default";
|
||||
|
||||
const displayTheme = showEffectiveTheme ? effectiveTheme : currentTheme;
|
||||
|
||||
const handleThemeChange = (newTheme: Theme) => {
|
||||
if (onValueChange) {
|
||||
|
|
@ -32,6 +39,9 @@ const ThemeSelect = ({ value, onValueChange, className }: ThemeSelectProps = {})
|
|||
<SelectTrigger className={className}>
|
||||
<div className="flex items-center gap-2">
|
||||
<SelectValue placeholder="Select theme" />
|
||||
{showEffectiveTheme && effectiveTheme !== currentTheme && (
|
||||
<span className="text-xs text-muted-foreground">(effective: {effectiveTheme})</span>
|
||||
)}
|
||||
</div>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
|
|
@ -40,12 +50,15 @@ const ThemeSelect = ({ value, onValueChange, className }: ThemeSelectProps = {})
|
|||
<div className="flex items-center gap-2">
|
||||
{THEME_ICONS[option.value]}
|
||||
<span>{option.label}</span>
|
||||
{showEffectiveTheme && option.value === effectiveTheme && (
|
||||
<span className="text-xs text-green-600">✓</span>
|
||||
)}
|
||||
</div>
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default ThemeSelect;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue