diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 31d5bf08c6..309ff99c43 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -490,6 +490,7 @@ form.name_chars_not_allowed = User name '%s' contains invalid characters. [settings] profile = Profile account = Account +appearance = Appearance password = Password security = Security avatar = Avatar @@ -514,7 +515,9 @@ website = Website location = Location update_theme = Update Theme update_profile = Update Profile +update_language = Update Language update_language_not_found = Language '%s' is not available. +update_language_success = Language has been updated. update_profile_success = Your profile has been updated. change_username = Your username has been changed. change_username_prompt = Note: username changes also change your account URL. diff --git a/routers/web/user/setting/account.go b/routers/web/user/setting/account.go index 249793578a..47014dc814 100644 --- a/routers/web/user/setting/account.go +++ b/routers/web/user/setting/account.go @@ -257,34 +257,6 @@ func DeleteAccount(ctx *context.Context) { } } -// UpdateUIThemePost is used to update users' specific theme -func UpdateUIThemePost(ctx *context.Context) { - form := web.GetForm(ctx).(*forms.UpdateThemeForm) - ctx.Data["Title"] = ctx.Tr("settings") - ctx.Data["PageIsSettingsAccount"] = true - - if ctx.HasError() { - ctx.Redirect(setting.AppSubURL + "/user/settings/account") - return - } - - if !form.IsThemeExists() { - ctx.Flash.Error(ctx.Tr("settings.theme_update_error")) - ctx.Redirect(setting.AppSubURL + "/user/settings/account") - return - } - - if err := ctx.User.UpdateTheme(form.Theme); err != nil { - ctx.Flash.Error(ctx.Tr("settings.theme_update_error")) - ctx.Redirect(setting.AppSubURL + "/user/settings/account") - return - } - - log.Trace("Update user theme: %s", ctx.User.Name) - ctx.Flash.Success(ctx.Tr("settings.theme_update_success")) - ctx.Redirect(setting.AppSubURL + "/user/settings/account") -} - func loadAccountData(ctx *context.Context) { emlist, err := models.GetEmailAddresses(ctx.User.ID) if err != nil { diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go index d75149b8fc..d181ae1720 100644 --- a/routers/web/user/setting/profile.go +++ b/routers/web/user/setting/profile.go @@ -32,6 +32,7 @@ import ( const ( tplSettingsProfile base.TplName = "user/settings/profile" + tplSettingsAppearance base.TplName = "user/settings/appearance" tplSettingsOrganization base.TplName = "user/settings/organization" tplSettingsRepositories base.TplName = "user/settings/repos" ) @@ -115,14 +116,6 @@ func ProfilePost(ctx *context.Context) { ctx.User.KeepEmailPrivate = form.KeepEmailPrivate ctx.User.Website = form.Website ctx.User.Location = form.Location - if len(form.Language) != 0 { - if !util.IsStringInSlice(form.Language, setting.Langs) { - ctx.Flash.Error(ctx.Tr("settings.update_language_not_found", form.Language)) - ctx.Redirect(setting.AppSubURL + "/user/settings") - return - } - ctx.User.Language = form.Language - } ctx.User.Description = form.Description ctx.User.KeepActivityPrivate = form.KeepActivityPrivate ctx.User.Visibility = form.Visibility @@ -329,3 +322,68 @@ func Repos(ctx *context.Context) { ctx.Data["Page"] = pager ctx.HTML(http.StatusOK, tplSettingsRepositories) } + +// Appearance render user's appearance settings +func Appearance(ctx *context.Context) { + ctx.Data["Title"] = ctx.Tr("settings") + ctx.Data["PageIsSettingsAppearance"] = true + + ctx.HTML(http.StatusOK, tplSettingsAppearance) +} + +// UpdateUIThemePost is used to update users' specific theme +func UpdateUIThemePost(ctx *context.Context) { + form := web.GetForm(ctx).(*forms.UpdateThemeForm) + ctx.Data["Title"] = ctx.Tr("settings") + ctx.Data["PageIsSettingsAppearance"] = true + + if ctx.HasError() { + ctx.Redirect(setting.AppSubURL + "/user/settings/appearance") + return + } + + if !form.IsThemeExists() { + ctx.Flash.Error(ctx.Tr("settings.theme_update_error")) + ctx.Redirect(setting.AppSubURL + "/user/settings/appearance") + return + } + + if err := ctx.User.UpdateTheme(form.Theme); err != nil { + ctx.Flash.Error(ctx.Tr("settings.theme_update_error")) + ctx.Redirect(setting.AppSubURL + "/user/settings/appearance") + return + } + + log.Trace("Update user theme: %s", ctx.User.Name) + ctx.Flash.Success(ctx.Tr("settings.theme_update_success")) + ctx.Redirect(setting.AppSubURL + "/user/settings/appearance") +} + +// UpdateUserLang update a user's language +func UpdateUserLang(ctx *context.Context) { + form := web.GetForm(ctx).(*forms.UpdateLanguageForm) + ctx.Data["Title"] = ctx.Tr("settings") + ctx.Data["PageIsSettingsAppearance"] = true + + if len(form.Language) != 0 { + if !util.IsStringInSlice(form.Language, setting.Langs) { + ctx.Flash.Error(ctx.Tr("settings.update_language_not_found", form.Language)) + ctx.Redirect(setting.AppSubURL + "/user/settings/appearance") + return + } + ctx.User.Language = form.Language + } + + if err := models.UpdateUserSetting(ctx.User); err != nil { + ctx.ServerError("UpdateUserSetting", err) + return + } + + // Update the language to the one we just set + middleware.SetLocaleCookie(ctx.Resp, ctx.User.Language, 0) + + log.Trace("User settings updated: %s", ctx.User.Name) + ctx.Flash.Success(i18n.Tr(ctx.User.Language, "settings.update_language_success")) + ctx.Redirect(setting.AppSubURL + "/user/settings/appearance") + +} diff --git a/routers/web/web.go b/routers/web/web.go index 88565d6d85..c0bb74da2e 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -317,6 +317,10 @@ func RegisterRoutes(m *web.Route) { m.Post("/email", bindIgnErr(forms.AddEmailForm{}), userSetting.EmailPost) m.Post("/email/delete", userSetting.DeleteEmail) m.Post("/delete", userSetting.DeleteAccount) + }) + m.Group("/appearance", func() { + m.Get("", userSetting.Appearance) + m.Post("/language", bindIgnErr(forms.UpdateLanguageForm{}), userSetting.UpdateUserLang) m.Post("/theme", bindIgnErr(forms.UpdateThemeForm{}), userSetting.UpdateUIThemePost) }) m.Group("/security", func() { diff --git a/services/forms/user_form.go b/services/forms/user_form.go index 241ebdc0d9..9f86bf6166 100644 --- a/services/forms/user_form.go +++ b/services/forms/user_form.go @@ -240,7 +240,6 @@ type UpdateProfileForm struct { KeepEmailPrivate bool Website string `binding:"ValidSiteUrl;MaxSize(255)"` Location string `binding:"MaxSize(50)"` - Language string Description string `binding:"MaxSize(255)"` Visibility structs.VisibleType KeepActivityPrivate bool @@ -252,6 +251,17 @@ func (f *UpdateProfileForm) Validate(req *http.Request, errs binding.Errors) bin return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } +// UpdateLanguageForm form for updating profile +type UpdateLanguageForm struct { + Language string +} + +// Validate validates the fields +func (f *UpdateLanguageForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { + ctx := context.GetContext(req) + return middleware.Validate(errs, ctx.Data, f, ctx.Locale) +} + // Avatar types const ( AvatarLocal string = "local" diff --git a/templates/user/settings/account.tmpl b/templates/user/settings/account.tmpl index 9ed5d3a6dd..3753a77cec 100644 --- a/templates/user/settings/account.tmpl +++ b/templates/user/settings/account.tmpl @@ -130,44 +130,6 @@ -