@Summary Update user appearance settings @ID update-user-appearance-settings @Security CoderSessionToken @Accept json @Produce json @Tags Users @Param user path string true "User ID, name, or me" @Param request body codersdk.UpdateUserAppearanceSettingsRequest true "New appearance settings" @Success
(rw http.ResponseWriter, r *http.Request)
| 1170 | // @Success 200 {object} codersdk.UserAppearanceSettings |
| 1171 | // @Router /api/v2/users/{user}/appearance [put] |
| 1172 | func (api *API) putUserAppearanceSettings(rw http.ResponseWriter, r *http.Request) { |
| 1173 | var ( |
| 1174 | ctx = r.Context() |
| 1175 | user = httpmw.UserParam(r) |
| 1176 | ) |
| 1177 | |
| 1178 | var params codersdk.UpdateUserAppearanceSettingsRequest |
| 1179 | if !httpapi.Read(ctx, rw, r, ¶ms) { |
| 1180 | return |
| 1181 | } |
| 1182 | |
| 1183 | if !isValidFontName(params.TerminalFont) { |
| 1184 | httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ |
| 1185 | Message: "Unsupported font family.", |
| 1186 | }) |
| 1187 | return |
| 1188 | } |
| 1189 | |
| 1190 | // theme_mode is optional for backward compatibility. Older CLI |
| 1191 | // clients do not know about theme_mode or the sync slots, so an |
| 1192 | // omitted mode must leave those fields untouched instead of replacing |
| 1193 | // them with single-mode defaults. Legacy auto values are the exception: |
| 1194 | // the old UI used them to mean sync-with-system, so clearing theme_mode |
| 1195 | // lets modern clients migrate them on read. |
| 1196 | themeModeProvided := params.ThemeMode != codersdk.ThemeModeUnset |
| 1197 | updateThemeMode := themeModeProvided |
| 1198 | isSyncMode := params.ThemeMode == codersdk.ThemeModeSync |
| 1199 | isSingleMode := params.ThemeMode == codersdk.ThemeModeSingle |
| 1200 | updateThemeLight := isSyncMode || (isSingleMode && params.ThemeLight != "") |
| 1201 | updateThemeDark := isSyncMode || (isSingleMode && params.ThemeDark != "") |
| 1202 | themeMode := params.ThemeMode |
| 1203 | if !updateThemeMode && isLegacyAutoThemePreference(params.ThemePreference) { |
| 1204 | updateThemeMode = true |
| 1205 | themeMode = codersdk.ThemeModeUnset |
| 1206 | } |
| 1207 | |
| 1208 | var updatedSettings database.GetUserAppearanceSettingsRow |
| 1209 | |
| 1210 | err := api.Database.InTx(func(tx database.Store) error { |
| 1211 | _, err := tx.UpdateUserThemePreference(ctx, database.UpdateUserThemePreferenceParams{ |
| 1212 | UserID: user.ID, |
| 1213 | ThemePreference: params.ThemePreference, |
| 1214 | }) |
| 1215 | if err != nil { |
| 1216 | return xerrors.Errorf("update user theme preference: %w", err) |
| 1217 | } |
| 1218 | |
| 1219 | if updateThemeMode { |
| 1220 | _, err = tx.UpdateUserThemeMode(ctx, database.UpdateUserThemeModeParams{ |
| 1221 | UserID: user.ID, |
| 1222 | ThemeMode: string(themeMode), |
| 1223 | }) |
| 1224 | if err != nil { |
| 1225 | return xerrors.Errorf("update user theme mode: %w", err) |
| 1226 | } |
| 1227 | } |
| 1228 | |
| 1229 | if updateThemeLight { |
nothing calls this directly
no test coverage detected