diff options
author | wxiaoguang <wxiaoguang@gmail.com> | 2024-02-24 21:12:17 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-24 13:12:17 +0000 |
commit | 29a26d9d8c573c9fb7e79a66ac3d578e8b20dcae (patch) | |
tree | 2d51372c6d14b0f1c96c35d1a2cf4ff8f6fb050b /routers/web | |
parent | c42083a33950be6ee9f822c6d0de3c3a79d1f51b (diff) | |
download | gitea-29a26d9d8c573c9fb7e79a66ac3d578e8b20dcae.tar.gz gitea-29a26d9d8c573c9fb7e79a66ac3d578e8b20dcae.zip |
Customizable "Open with" applications for repository clone (#29320)
Users could customize the "clone" menu with their own application URLs on the admin panel.
Replace #22378
Close #21121
Close #22149
Diffstat (limited to 'routers/web')
-rw-r--r-- | routers/web/admin/config.go | 67 | ||||
-rw-r--r-- | routers/web/repo/view.go | 29 | ||||
-rw-r--r-- | routers/web/web.go | 1 |
3 files changed, 87 insertions, 10 deletions
diff --git a/routers/web/admin/config.go b/routers/web/admin/config.go index c827f2a4f5..47f9201504 100644 --- a/routers/web/admin/config.go +++ b/routers/web/admin/config.go @@ -7,11 +7,11 @@ package admin import ( "net/http" "net/url" + "strconv" "strings" system_model "code.gitea.io/gitea/models/system" "code.gitea.io/gitea/modules/base" - "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/json" @@ -24,7 +24,10 @@ import ( "gitea.com/go-chi/session" ) -const tplConfig base.TplName = "admin/config" +const ( + tplConfig base.TplName = "admin/config" + tplConfigSettings base.TplName = "admin/config_settings" +) // SendTestMail send test mail to confirm mail service is OK func SendTestMail(ctx *context.Context) { @@ -98,8 +101,9 @@ func shadowPassword(provider, cfgItem string) string { // Config show admin config page func Config(ctx *context.Context) { - ctx.Data["Title"] = ctx.Tr("admin.config") + ctx.Data["Title"] = ctx.Tr("admin.config_summary") ctx.Data["PageIsAdminConfig"] = true + ctx.Data["PageIsAdminConfigSummary"] = true ctx.Data["CustomConf"] = setting.CustomConf ctx.Data["AppUrl"] = setting.AppURL @@ -161,23 +165,70 @@ func Config(ctx *context.Context) { ctx.Data["Loggers"] = log.GetManager().DumpLoggers() config.GetDynGetter().InvalidateCache() - ctx.Data["SystemConfig"] = setting.Config() prepareDeprecatedWarningsAlert(ctx) ctx.HTML(http.StatusOK, tplConfig) } +func ConfigSettings(ctx *context.Context) { + ctx.Data["Title"] = ctx.Tr("admin.config_settings") + ctx.Data["PageIsAdminConfig"] = true + ctx.Data["PageIsAdminConfigSettings"] = true + ctx.Data["DefaultOpenWithEditorAppsString"] = setting.DefaultOpenWithEditorApps().ToTextareaString() + ctx.HTML(http.StatusOK, tplConfigSettings) +} + func ChangeConfig(ctx *context.Context) { key := strings.TrimSpace(ctx.FormString("key")) value := ctx.FormString("value") cfg := setting.Config() - allowedKeys := container.SetOf(cfg.Picture.DisableGravatar.DynKey(), cfg.Picture.EnableFederatedAvatar.DynKey()) - if !allowedKeys.Contains(key) { + + marshalBool := func(v string) (string, error) { + if b, _ := strconv.ParseBool(v); b { + return "true", nil + } + return "false", nil + } + marshalOpenWithApps := func(value string) (string, error) { + lines := strings.Split(value, "\n") + var openWithEditorApps setting.OpenWithEditorAppsType + for _, line := range lines { + line = strings.TrimSpace(line) + if line == "" { + continue + } + displayName, openURL, ok := strings.Cut(line, "=") + displayName, openURL = strings.TrimSpace(displayName), strings.TrimSpace(openURL) + if !ok || displayName == "" || openURL == "" { + continue + } + openWithEditorApps = append(openWithEditorApps, setting.OpenWithEditorApp{ + DisplayName: strings.TrimSpace(displayName), + OpenURL: strings.TrimSpace(openURL), + }) + } + b, err := json.Marshal(openWithEditorApps) + if err != nil { + return "", err + } + return string(b), nil + } + marshallers := map[string]func(string) (string, error){ + cfg.Picture.DisableGravatar.DynKey(): marshalBool, + cfg.Picture.EnableFederatedAvatar.DynKey(): marshalBool, + cfg.Repository.OpenWithEditorApps.DynKey(): marshalOpenWithApps, + } + marshaller, hasMarshaller := marshallers[key] + if !hasMarshaller { + ctx.JSONError(ctx.Tr("admin.config.set_setting_failed", key)) + return + } + marshaledValue, err := marshaller(value) + if err != nil { ctx.JSONError(ctx.Tr("admin.config.set_setting_failed", key)) return } - if err := system_model.SetSettings(ctx, map[string]string{key: value}); err != nil { - log.Error("set setting failed: %v", err) + if err = system_model.SetSettings(ctx, map[string]string{key: marshaledValue}); err != nil { ctx.JSONError(ctx.Tr("admin.config.set_setting_failed", key)) return } diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index 15f22237a8..33a5941d36 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -45,6 +45,7 @@ import ( repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/svg" "code.gitea.io/gitea/modules/typesniffer" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/routers/web/feed" @@ -792,7 +793,7 @@ func Home(ctx *context.Context) { return } - renderCode(ctx) + renderHomeCode(ctx) } // LastCommit returns lastCommit data for the provided branch/tag/commit and directory (in url) and filenames in body @@ -919,9 +920,33 @@ func renderRepoTopics(ctx *context.Context) { ctx.Data["Topics"] = topics } -func renderCode(ctx *context.Context) { +func prepareOpenWithEditorApps(ctx *context.Context) { + var tmplApps []map[string]any + apps := setting.Config().Repository.OpenWithEditorApps.Value(ctx) + if len(apps) == 0 { + apps = setting.DefaultOpenWithEditorApps() + } + for _, app := range apps { + schema, _, _ := strings.Cut(app.OpenURL, ":") + var iconHTML template.HTML + if schema == "vscode" || schema == "vscodium" || schema == "jetbrains" { + iconHTML = svg.RenderHTML(fmt.Sprintf("gitea-open-with-%s", schema), 16, "gt-mr-3") + } else { + iconHTML = svg.RenderHTML("gitea-git", 16, "gt-mr-3") // TODO: it could support user's customized icon in the future + } + tmplApps = append(tmplApps, map[string]any{ + "DisplayName": app.DisplayName, + "OpenURL": app.OpenURL, + "IconHTML": iconHTML, + }) + } + ctx.Data["OpenWithEditorApps"] = tmplApps +} + +func renderHomeCode(ctx *context.Context) { ctx.Data["PageIsViewCode"] = true ctx.Data["RepositoryUploadEnabled"] = setting.Repository.Upload.Enabled + prepareOpenWithEditorApps(ctx) if ctx.Repo.Commit == nil || ctx.Repo.Repository.IsEmpty || ctx.Repo.Repository.IsBroken() { showEmpty := true diff --git a/routers/web/web.go b/routers/web/web.go index 8505417c88..b1fa5cf355 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -686,6 +686,7 @@ func registerRoutes(m *web.Route) { m.Get("", admin.Config) m.Post("", admin.ChangeConfig) m.Post("/test_mail", admin.SendTestMail) + m.Get("/settings", admin.ConfigSettings) }) m.Group("/monitor", func() { |