Skip to content

Commit 7307659

Browse files
committed
fix
1 parent 9a73a1f commit 7307659

29 files changed

+230
-53
lines changed

modules/svg/svg.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ func MockIcon(icon string) func() {
5858

5959
// RenderHTML renders icons - arguments icon name (string), size (int), class (string)
6060
func RenderHTML(icon string, others ...any) template.HTML {
61+
if icon == "" {
62+
return ""
63+
}
6164
size, class := gitea_html.ParseSizeAndClass(defaultSize, "", others...)
6265
if svgStr, ok := svgIcons[icon]; ok {
6366
// the code is somewhat hacky, but it just works, because the SVG contents are all normalized

modules/templates/helper.go

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import (
1212
"strings"
1313
"time"
1414

15-
user_model "code.gitea.io/gitea/models/user"
1615
"code.gitea.io/gitea/modules/base"
1716
"code.gitea.io/gitea/modules/htmlutil"
1817
"code.gitea.io/gitea/modules/markup"
@@ -21,7 +20,6 @@ import (
2120
"code.gitea.io/gitea/modules/templates/eval"
2221
"code.gitea.io/gitea/modules/util"
2322
"code.gitea.io/gitea/services/gitdiff"
24-
"code.gitea.io/gitea/services/webtheme"
2523
)
2624

2725
// NewFuncMap returns functions for injecting to templates
@@ -130,7 +128,6 @@ func NewFuncMap() template.FuncMap {
130128
"DisableWebhooks": func() bool {
131129
return setting.DisableWebhooks
132130
},
133-
"UserThemeName": userThemeName,
134131
"NotificationSettings": func() map[string]any {
135132
return map[string]any{
136133
"MinTimeout": int(setting.UI.Notification.MinTimeout / time.Millisecond),
@@ -217,16 +214,6 @@ func evalTokens(tokens ...any) (any, error) {
217214
return n.Value, err
218215
}
219216

220-
func userThemeName(user *user_model.User) string {
221-
if user == nil || user.Theme == "" {
222-
return setting.UI.DefaultTheme
223-
}
224-
if webtheme.IsThemeAvailable(user.Theme) {
225-
return user.Theme
226-
}
227-
return setting.UI.DefaultTheme
228-
}
229-
230217
func isQueryParamEmpty(v any) bool {
231218
return v == nil || v == false || v == 0 || v == int64(0) || v == ""
232219
}

modules/templates/util_render.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ import (
2323
"code.gitea.io/gitea/modules/markup/markdown"
2424
"code.gitea.io/gitea/modules/reqctx"
2525
"code.gitea.io/gitea/modules/setting"
26+
"code.gitea.io/gitea/modules/svg"
2627
"code.gitea.io/gitea/modules/translation"
2728
"code.gitea.io/gitea/modules/util"
29+
"code.gitea.io/gitea/services/webtheme"
2830
)
2931

3032
type RenderUtils struct {
@@ -259,3 +261,18 @@ func (ut *RenderUtils) RenderLabels(labels []*issues_model.Label, repoLink strin
259261
htmlCode += "</span>"
260262
return template.HTML(htmlCode)
261263
}
264+
265+
func (ut *RenderUtils) RenderThemeItem(info *webtheme.ThemeMetaInfo, iconSize int) template.HTML {
266+
svgName := "octicon-paintbrush"
267+
switch info.ColorScheme {
268+
case "dark":
269+
svgName = "octicon-moon"
270+
case "light":
271+
svgName = "octicon-sun"
272+
case "auto":
273+
svgName = "gitea-eclipse"
274+
}
275+
icon := svg.RenderHTML(svgName, iconSize)
276+
extraIcon := svg.RenderHTML(info.GetExtraIconName(), iconSize)
277+
return htmlutil.HTMLFormat(`<div class="theme-menu-item" data-tooltip-content="%s">%s %s %s</div>`, info.GetDescription(), icon, info.DisplayName, extraIcon)
278+
}

public/assets/img/svg/gitea-colorblind-redgreen.svg

Lines changed: 1 addition & 0 deletions
Loading

public/assets/img/svg/gitea-eclipse.svg

Lines changed: 1 addition & 0 deletions
Loading

routers/common/errpage.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func RenderPanicErrorPage(w http.ResponseWriter, req *http.Request, err any) {
3535
httpcache.SetCacheControlInHeader(w.Header(), &httpcache.CacheControlOptions{NoTransform: true})
3636
w.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)
3737

38-
tmplCtx := context.TemplateContext{}
38+
tmplCtx := context.NewTemplateContext(req.Context(), req)
3939
tmplCtx["Locale"] = middleware.Locale(w, req)
4040
ctxData := middleware.GetContextData(req.Context())
4141

routers/common/qos.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ func renderServiceUnavailable(w http.ResponseWriter, req *http.Request) {
133133
return
134134
}
135135

136-
tmplCtx := giteacontext.TemplateContext{}
136+
tmplCtx := giteacontext.NewTemplateContext(req.Context(), req)
137137
tmplCtx["Locale"] = middleware.Locale(w, req)
138138
ctxData := middleware.GetContextData(req.Context())
139139
err := templates.HTMLRenderer().HTML(w, http.StatusServiceUnavailable, tplStatus503, ctxData, tmplCtx)

routers/web/misc/webtheme.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// Copyright 2025 The Gitea Authors. All rights reserved.
2+
// SPDX-License-Identifier: MIT
3+
4+
package misc
5+
6+
import (
7+
"net/http"
8+
9+
"code.gitea.io/gitea/modules/optional"
10+
"code.gitea.io/gitea/modules/templates"
11+
"code.gitea.io/gitea/modules/util"
12+
"code.gitea.io/gitea/modules/web/middleware"
13+
"code.gitea.io/gitea/services/context"
14+
user_service "code.gitea.io/gitea/services/user"
15+
"code.gitea.io/gitea/services/webtheme"
16+
)
17+
18+
func WebThemeList(ctx *context.Context) {
19+
curWebTheme := ctx.TemplateContext.CurrentWebTheme()
20+
renderUtils := templates.NewRenderUtils(ctx)
21+
allThemes := webtheme.GetAvailableThemes()
22+
23+
var results []map[string]any
24+
for _, theme := range allThemes {
25+
results = append(results, map[string]any{
26+
"name": renderUtils.RenderThemeItem(theme, 14),
27+
"value": theme.InternalName,
28+
"class": "item js-aria-clickable" + util.Iif(theme.InternalName == curWebTheme.InternalName, " selected", ""),
29+
})
30+
}
31+
ctx.JSON(http.StatusOK, map[string]any{"results": results})
32+
}
33+
34+
func WebThemeApply(ctx *context.Context) {
35+
themeName := ctx.FormString("theme")
36+
middleware.SetSiteCookie(ctx.Resp, "gitea_theme", themeName, 0)
37+
if ctx.Doer != nil {
38+
opts := &user_service.UpdateOptions{Theme: optional.Some(themeName)}
39+
_ = user_service.UpdateUser(ctx, ctx.Doer, opts)
40+
}
41+
}

routers/web/user/setting/profile.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ func UpdateUIThemePost(ctx *context.Context) {
369369
return
370370
}
371371

372-
if !webtheme.IsThemeAvailable(form.Theme) {
372+
if webtheme.GetThemeMetaInfo(form.Theme) == nil {
373373
ctx.Flash.Error(ctx.Tr("settings.theme_update_error"))
374374
ctx.Redirect(setting.AppSubURL + "/user/settings/appearance")
375375
return

routers/web/web.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,9 @@ func registerWebRoutes(m *web.Router) {
497497

498498
m.Post("/-/markup", reqSignIn, web.Bind(structs.MarkupOption{}), misc.Markup)
499499

500+
m.Get("/-/web-theme/list", misc.WebThemeList)
501+
m.Post("/-/web-theme/apply", optSignInIgnoreCsrf, misc.WebThemeApply)
502+
500503
m.Group("/explore", func() {
501504
m.Get("", func(ctx *context.Context) {
502505
ctx.Redirect(setting.AppSubURL + "/explore/repos")

0 commit comments

Comments
 (0)