From 5e6190b181c68acdbf24a08de359e824d973a95b Mon Sep 17 00:00:00 2001 From: steven Date: Tue, 5 Sep 2023 23:59:24 +0800 Subject: [PATCH] feat: add color theme selector --- api/v2/user_setting_service.go | 34 ++++++++++++++++ .../components/setting/PreferenceSection.tsx | 40 ++++++++++++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/api/v2/user_setting_service.go b/api/v2/user_setting_service.go index 19b0ebd..185c1c5 100644 --- a/api/v2/user_setting_service.go +++ b/api/v2/user_setting_service.go @@ -51,6 +51,16 @@ func (s *UserSettingService) UpdateUserSetting(ctx context.Context, request *api }); err != nil { 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 { 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 { if setting.Key == storepb.UserSettingKey_USER_SETTING_LOCALE { userSetting.Locale = convertUserSettingLocaleFromStore(setting.GetLocale()) + } else if setting.Key == storepb.UserSettingKey_USER_SETTING_COLOR_THEME { + userSetting.ColorTheme = convertUserSettingColorThemeFromStore(setting.GetColorTheme()) } } return userSetting, nil @@ -106,3 +118,25 @@ func convertUserSettingLocaleFromStore(locale storepb.LocaleUserSetting) apiv2pb 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 + } +} diff --git a/frontend/web/src/components/setting/PreferenceSection.tsx b/frontend/web/src/components/setting/PreferenceSection.tsx index 7232ddb..cdd2dc2 100644 --- a/frontend/web/src/components/setting/PreferenceSection.tsx +++ b/frontend/web/src/components/setting/PreferenceSection.tsx @@ -1,6 +1,6 @@ import { Option, Select } from "@mui/joy"; 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"; const PreferenceSection: React.FC = () => { @@ -8,6 +8,7 @@ const PreferenceSection: React.FC = () => { const userStore = useUserStore(); const userSetting = userStore.getCurrentUserSetting(); const language = userSetting.locale || UserSetting_Locale.EN; + const colorTheme = userSetting.colorTheme; 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) => { if (!locale) { 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 ( <>
@@ -50,6 +76,18 @@ const PreferenceSection: React.FC = () => { })}
+
+ Color Theme + +
);