theme v1
This commit is contained in:
@@ -9,6 +9,7 @@ import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
@@ -22,6 +23,7 @@ import (
|
||||
"github.com/tamakyi/TamaBox/internal/i18n"
|
||||
"github.com/tamakyi/TamaBox/internal/imagecheck"
|
||||
"github.com/tamakyi/TamaBox/internal/storage"
|
||||
"github.com/tamakyi/TamaBox/internal/theme"
|
||||
)
|
||||
|
||||
// Profile 账号设置页。按面板分区:
|
||||
@@ -39,6 +41,14 @@ func Profile(ctx context.Context) {
|
||||
ctx.Data["StrictnessLocked"] = true
|
||||
}
|
||||
ctx.Data["TagLimits"] = tagLimits()
|
||||
// 主题:可选清单(顺序同 [theme] available)+ 当前选择。
|
||||
// 当前值取原始存储值,非法/已下线主题归零为「跟随站点默认」,避免单选一个都不选中。
|
||||
ctx.Data["Themes"] = theme.List()
|
||||
if theme.IsAvailable(ctx.User.Theme) {
|
||||
ctx.Data["CurrentTheme"] = strings.ToLower(strings.TrimSpace(ctx.User.Theme))
|
||||
} else {
|
||||
ctx.Data["CurrentTheme"] = ""
|
||||
}
|
||||
ctx.Data["ChatLimits"] = chatLimits()
|
||||
InjectFeatureViews(ctx)
|
||||
ctx.Success("user/profile")
|
||||
@@ -64,6 +74,34 @@ func chatLimits() map[string]int {
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateTheme 保存箱主选择的主题。只写 users.theme 一列,
|
||||
// 与背景图/颜色等个性化设置互不影响(各自独立的表单入口)。
|
||||
func UpdateTheme(ctx context.Context, f form.UpdateProfileTheme) {
|
||||
if ctx.HasError() {
|
||||
ctx.Success("user/profile")
|
||||
return
|
||||
}
|
||||
|
||||
slug := strings.ToLower(strings.TrimSpace(f.Theme))
|
||||
// 白名单校验:既挡住拼写错误,也挡住把任意字符串拼进 <link href> 的路径穿越尝试。
|
||||
// 用 flash + 重定向而不是原地渲染:本页数据由 Profile() 装配(可选主题清单等),
|
||||
// 直接 Success 会渲染出缺数据的页面。
|
||||
if slug != "" && !theme.IsAvailable(slug) {
|
||||
ctx.SetErrorFlash(i18n.T(ctx.Lang(), "profile.theme.invalid"))
|
||||
ctx.Redirect("/user/profile")
|
||||
return
|
||||
}
|
||||
|
||||
if err := db.Users.UpdateTheme(ctx.Request().Context(), ctx.User.ID, slug); err != nil {
|
||||
logrus.WithContext(ctx.Request().Context()).WithError(err).Error("Failed to update theme")
|
||||
ctx.SetInternalErrorFlash()
|
||||
ctx.Redirect("/user/profile")
|
||||
return
|
||||
}
|
||||
ctx.SetSuccessFlash(i18n.T(ctx.Lang(), "profile.theme.saved"))
|
||||
ctx.Redirect("/user/profile")
|
||||
}
|
||||
|
||||
func ProfileAPI(ctx context.Context) error {
|
||||
return ctx.JSON(ctx.User)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user