mirror of
https://github.com/aykhans/slash-e.git
synced 2025-04-20 22:07:15 +00:00
feat: add color theme selector
This commit is contained in:
parent
b50e809125
commit
5e6190b181
@ -51,6 +51,16 @@ func (s *UserSettingService) UpdateUserSetting(ctx context.Context, request *api
|
|||||||
}); err != nil {
|
}); err != nil {
|
||||||
return nil, status.Errorf(codes.Internal, "failed to update user setting: %v", err)
|
return nil, status.Errorf(codes.Internal, "failed to update user setting: %v", err)
|
||||||
}
|
}
|
||||||
|
} else if path == "color_theme" {
|
||||||
|
if _, err := s.Store.UpsertUserSetting(ctx, &storepb.UserSetting{
|
||||||
|
UserId: userID,
|
||||||
|
Key: storepb.UserSettingKey_USER_SETTING_COLOR_THEME,
|
||||||
|
Value: &storepb.UserSetting_ColorTheme{
|
||||||
|
ColorTheme: convertUserSettingColorThemeToStore(request.UserSetting.ColorTheme),
|
||||||
|
},
|
||||||
|
}); err != nil {
|
||||||
|
return nil, status.Errorf(codes.Internal, "failed to update user setting: %v", err)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return nil, status.Errorf(codes.InvalidArgument, "invalid path: %s", path)
|
return nil, status.Errorf(codes.InvalidArgument, "invalid path: %s", path)
|
||||||
}
|
}
|
||||||
@ -80,6 +90,8 @@ func getUserSetting(ctx context.Context, s *store.Store, userID int32) (*apiv2pb
|
|||||||
for _, setting := range userSettings {
|
for _, setting := range userSettings {
|
||||||
if setting.Key == storepb.UserSettingKey_USER_SETTING_LOCALE {
|
if setting.Key == storepb.UserSettingKey_USER_SETTING_LOCALE {
|
||||||
userSetting.Locale = convertUserSettingLocaleFromStore(setting.GetLocale())
|
userSetting.Locale = convertUserSettingLocaleFromStore(setting.GetLocale())
|
||||||
|
} else if setting.Key == storepb.UserSettingKey_USER_SETTING_COLOR_THEME {
|
||||||
|
userSetting.ColorTheme = convertUserSettingColorThemeFromStore(setting.GetColorTheme())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return userSetting, nil
|
return userSetting, nil
|
||||||
@ -106,3 +118,25 @@ func convertUserSettingLocaleFromStore(locale storepb.LocaleUserSetting) apiv2pb
|
|||||||
return apiv2pb.UserSetting_LOCALE_UNSPECIFIED
|
return apiv2pb.UserSetting_LOCALE_UNSPECIFIED
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func convertUserSettingColorThemeToStore(colorTheme apiv2pb.UserSetting_ColorTheme) storepb.ColorThemeUserSetting {
|
||||||
|
switch colorTheme {
|
||||||
|
case apiv2pb.UserSetting_COLOR_THEME_LIGHT:
|
||||||
|
return storepb.ColorThemeUserSetting_COLOR_THEME_USER_SETTING_LIGHT
|
||||||
|
case apiv2pb.UserSetting_COLOR_THEME_DARK:
|
||||||
|
return storepb.ColorThemeUserSetting_COLOR_THEME_USER_SETTING_DARK
|
||||||
|
default:
|
||||||
|
return storepb.ColorThemeUserSetting_COLOR_THEME_USER_SETTING_UNSPECIFIED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertUserSettingColorThemeFromStore(colorTheme storepb.ColorThemeUserSetting) apiv2pb.UserSetting_ColorTheme {
|
||||||
|
switch colorTheme {
|
||||||
|
case storepb.ColorThemeUserSetting_COLOR_THEME_USER_SETTING_LIGHT:
|
||||||
|
return apiv2pb.UserSetting_COLOR_THEME_LIGHT
|
||||||
|
case storepb.ColorThemeUserSetting_COLOR_THEME_USER_SETTING_DARK:
|
||||||
|
return apiv2pb.UserSetting_COLOR_THEME_DARK
|
||||||
|
default:
|
||||||
|
return apiv2pb.UserSetting_COLOR_THEME_UNSPECIFIED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Option, Select } from "@mui/joy";
|
import { Option, Select } from "@mui/joy";
|
||||||
import { useTranslation } from "react-i18next";
|
import { useTranslation } from "react-i18next";
|
||||||
import { UserSetting, UserSetting_Locale } from "@/types/proto/api/v2/user_setting_service_pb";
|
import { UserSetting, UserSetting_ColorTheme, UserSetting_Locale } from "@/types/proto/api/v2/user_setting_service_pb";
|
||||||
import useUserStore from "../../stores/v1/user";
|
import useUserStore from "../../stores/v1/user";
|
||||||
|
|
||||||
const PreferenceSection: React.FC = () => {
|
const PreferenceSection: React.FC = () => {
|
||||||
@ -8,6 +8,7 @@ const PreferenceSection: React.FC = () => {
|
|||||||
const userStore = useUserStore();
|
const userStore = useUserStore();
|
||||||
const userSetting = userStore.getCurrentUserSetting();
|
const userSetting = userStore.getCurrentUserSetting();
|
||||||
const language = userSetting.locale || UserSetting_Locale.EN;
|
const language = userSetting.locale || UserSetting_Locale.EN;
|
||||||
|
const colorTheme = userSetting.colorTheme;
|
||||||
|
|
||||||
const languageOptions = [
|
const languageOptions = [
|
||||||
{
|
{
|
||||||
@ -20,6 +21,21 @@ const PreferenceSection: React.FC = () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const colorThemeOptions = [
|
||||||
|
{
|
||||||
|
value: "COLOR_THEME_UNSPECIFIED",
|
||||||
|
label: "Auto",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "COLOR_THEME_LIGHT",
|
||||||
|
label: "Light",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: "COLOR_THEME_DARK",
|
||||||
|
label: "Dark",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
const handleSelectLanguage = async (locale: UserSetting_Locale) => {
|
const handleSelectLanguage = async (locale: UserSetting_Locale) => {
|
||||||
if (!locale) {
|
if (!locale) {
|
||||||
return;
|
return;
|
||||||
@ -34,6 +50,16 @@ const PreferenceSection: React.FC = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSelectColorTheme = async (colorTheme: UserSetting_ColorTheme) => {
|
||||||
|
await userStore.updateUserSetting(
|
||||||
|
{
|
||||||
|
...userSetting,
|
||||||
|
colorTheme: colorTheme,
|
||||||
|
} as UserSetting,
|
||||||
|
["color_theme"]
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="w-full flex flex-col justify-start items-start gap-y-2">
|
<div className="w-full flex flex-col justify-start items-start gap-y-2">
|
||||||
@ -50,6 +76,18 @@ const PreferenceSection: React.FC = () => {
|
|||||||
})}
|
})}
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="w-full flex flex-row justify-between items-center">
|
||||||
|
<span>Color Theme</span>
|
||||||
|
<Select defaultValue={colorTheme} onChange={(_, value) => handleSelectColorTheme(value as UserSetting_ColorTheme)}>
|
||||||
|
{colorThemeOptions.map((option) => {
|
||||||
|
return (
|
||||||
|
<Option key={option.value} value={option.value}>
|
||||||
|
{option.label}
|
||||||
|
</Option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user