diff --git a/routers/web/repo/blame.go b/routers/web/repo/blame.go index e304633f95238..7e104db9ed2fb 100644 --- a/routers/web/repo/blame.go +++ b/routers/web/repo/blame.go @@ -74,7 +74,7 @@ func RefBlame(ctx *context.Context) { tplName := tplRepoViewContent if !ctx.FormBool("only_content") { - prepareHomeTreeSideBarSwitch(ctx) + prepareTreeSideBarSwitch(ctx) tplName = tplRepoView } diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go index 2a5ac102824d9..47e560f06a4e6 100644 --- a/routers/web/repo/editor.go +++ b/routers/web/repo/editor.go @@ -280,6 +280,8 @@ func EditFile(ctx *context.Context) { return } + prepareTreeSideBarSwitch(ctx) + // on the "New File" page, we should add an empty path field to make end users could input a new name prepareTreePathFieldsAndPaths(ctx, util.Iif(isNewFile, ctx.Repo.TreePath+"/", ctx.Repo.TreePath)) @@ -320,6 +322,7 @@ func EditFile(ctx *context.Context) { } } + ctx.Data["PageIsEdit"] = true ctx.Data["EditorconfigJson"] = getContextRepoEditorConfig(ctx, ctx.Repo.TreePath) ctx.HTML(http.StatusOK, tplEditFile) } @@ -376,6 +379,8 @@ func EditFilePost(ctx *context.Context) { // DeleteFile render delete file page func DeleteFile(ctx *context.Context) { + prepareTreePathFieldsAndPaths(ctx, ctx.Repo.TreePath) + prepareTreeSideBarSwitch(ctx) prepareEditorCommitFormOptions(ctx, "_delete") if ctx.Written() { return diff --git a/routers/web/repo/editor_apply_patch.go b/routers/web/repo/editor_apply_patch.go index bd2811cc5f01d..98ef2e5327505 100644 --- a/routers/web/repo/editor_apply_patch.go +++ b/routers/web/repo/editor_apply_patch.go @@ -14,6 +14,7 @@ import ( ) func NewDiffPatch(ctx *context.Context) { + prepareTreeSideBarSwitch(ctx) prepareEditorCommitFormOptions(ctx, "_diffpatch") if ctx.Written() { return diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index e47bc56d081a6..7892cb0ed6d78 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -13,6 +13,7 @@ import ( "net/http" "net/url" "path" + "strconv" "strings" "time" @@ -257,6 +258,19 @@ func LastCommit(ctx *context.Context) { ctx.HTML(http.StatusOK, tplRepoViewList) } +func prepareTreeSideBarSwitch(ctx *context.Context) { + showFileTree := true + if ctx.Doer != nil { + v, err := user_model.GetUserSetting(ctx, ctx.Doer.ID, user_model.SettingsKeyCodeViewShowFileTree, "true") + if err != nil { + log.Error("GetUserSetting: %v", err) + } else { + showFileTree, _ = strconv.ParseBool(v) + } + } + ctx.Data["UserSettingCodeViewShowFileTree"] = showFileTree +} + func prepareDirectoryFileIcons(ctx *context.Context, files []git.CommitInfo) { renderedIconPool := fileicon.NewRenderedIconPool() fileIcons := map[string]template.HTML{} diff --git a/routers/web/repo/view_home.go b/routers/web/repo/view_home.go index f475e93f60489..1b59d217fefe8 100644 --- a/routers/web/repo/view_home.go +++ b/routers/web/repo/view_home.go @@ -9,7 +9,6 @@ import ( "html/template" "net/http" "path" - "strconv" "strings" "time" @@ -17,7 +16,6 @@ import ( git_model "code.gitea.io/gitea/models/git" repo_model "code.gitea.io/gitea/models/repo" unit_model "code.gitea.io/gitea/models/unit" - user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/htmlutil" @@ -318,19 +316,6 @@ func handleRepoHomeFeed(ctx *context.Context) bool { return true } -func prepareHomeTreeSideBarSwitch(ctx *context.Context) { - showFileTree := true - if ctx.Doer != nil { - v, err := user_model.GetUserSetting(ctx, ctx.Doer.ID, user_model.SettingsKeyCodeViewShowFileTree, "true") - if err != nil { - log.Error("GetUserSetting: %v", err) - } else { - showFileTree, _ = strconv.ParseBool(v) - } - } - ctx.Data["UserSettingCodeViewShowFileTree"] = showFileTree -} - func redirectSrcToRaw(ctx *context.Context) bool { // GitHub redirects a tree path with "?raw=1" to the raw path // It is useful to embed some raw contents into Markdown files, @@ -386,7 +371,7 @@ func Home(ctx *context.Context) { return } - prepareHomeTreeSideBarSwitch(ctx) + prepareTreeSideBarSwitch(ctx) // get the current git entry which doer user is currently looking at. entry, err := ctx.Repo.Commit.GetTreeEntryByPath(ctx.Repo.TreePath) diff --git a/templates/repo/editor/common_breadcrumb.tmpl b/templates/repo/editor/common_breadcrumb.tmpl index 8cfbe09d3eef5..ff4efd8ab513d 100644 --- a/templates/repo/editor/common_breadcrumb.tmpl +++ b/templates/repo/editor/common_breadcrumb.tmpl @@ -5,7 +5,9 @@ {{range $i, $v := .TreeNames}} {{if eq $i $l}} - + {{svg "octicon-info"}} {{else}} {{$v}} diff --git a/templates/repo/editor/delete.tmpl b/templates/repo/editor/delete.tmpl index bf6143f1cb91a..bb260c6e5e4da 100644 --- a/templates/repo/editor/delete.tmpl +++ b/templates/repo/editor/delete.tmpl @@ -1,13 +1,28 @@ {{template "base/head" .}}
{{template "repo/header" .}} -
+
{{template "base/alert" .}} -
- {{.CsrfTokenHtml}} - {{template "repo/editor/common_top" .}} - {{template "repo/editor/commit_form" .}} -
+ {{template "repo/editor/common_top" .}} +
+
+ {{template "repo/view_file_tree" .}} +
+
+
+
+ {{template "repo/editor/file_tree_toggle" .}} + {{template "repo/editor/common_breadcrumb" .}} +
+
+
+
+ {{.CsrfTokenHtml}} + {{template "repo/editor/commit_form" .}} +
+
+
+
{{template "base/footer" .}} diff --git a/templates/repo/editor/edit.tmpl b/templates/repo/editor/edit.tmpl index 0911d02e1f423..e70de3391b4d0 100644 --- a/templates/repo/editor/edit.tmpl +++ b/templates/repo/editor/edit.tmpl @@ -1,53 +1,73 @@ {{template "base/head" .}}
{{template "repo/header" .}} -
+
{{template "base/alert" .}} -
- {{.CsrfTokenHtml}} - {{template "repo/editor/common_top" .}} -
- {{template "repo/editor/common_breadcrumb" .}} + {{template "repo/editor/common_top" .}} +
+
+ {{template "repo/view_file_tree" .}}
- {{if not .NotEditableReason}} -
-
- +
+ + {{.CsrfTokenHtml}} +
+ {{template "repo/editor/file_tree_toggle" .}} + {{template "repo/editor/common_breadcrumb" .}}
-
-
- -
-
-
- {{ctx.Locale.Tr "loading"}} + {{if not .NotEditableReason}} + -
-
+ {{else}} +
+
+

{{.NotEditableReason}}

+

{{ctx.Locale.Tr "repo.editor.file_not_editable_hint"}}

+
-
-
- {{else}} -
-
-

{{.NotEditableReason}}

-

{{ctx.Locale.Tr "repo.editor.file_not_editable_hint"}}

-
-
- {{end}} - {{template "repo/editor/commit_form" .}} - + {{end}} + {{template "repo/editor/commit_form" .}} + +
+
{{template "base/footer" .}} diff --git a/templates/repo/editor/file_tree_toggle.tmpl b/templates/repo/editor/file_tree_toggle.tmpl new file mode 100644 index 0000000000000..e8e01bdae83f7 --- /dev/null +++ b/templates/repo/editor/file_tree_toggle.tmpl @@ -0,0 +1,6 @@ + diff --git a/templates/repo/editor/fork.tmpl b/templates/repo/editor/fork.tmpl index e28b2ba7a26c7..db774d6170c47 100644 --- a/templates/repo/editor/fork.tmpl +++ b/templates/repo/editor/fork.tmpl @@ -1,18 +1,29 @@ {{template "base/head" .}}
{{template "repo/header" .}} -
+
{{template "base/alert" .}} -
- {{.CsrfTokenHtml}} -
-
-

{{ctx.Locale.Tr "repo.editor.fork_create"}}

-

{{ctx.Locale.Tr "repo.editor.fork_create_description"}}

-
- +
+
+ {{template "repo/view_file_tree" .}}
- +
+
+ {{.CsrfTokenHtml}} +
+ {{template "repo/editor/file_tree_toggle" .}} + {{template "repo/editor/common_breadcrumb" .}} +
+
+
+

{{ctx.Locale.Tr "repo.editor.fork_create"}}

+

{{ctx.Locale.Tr "repo.editor.fork_create_description"}}

+
+ +
+
+
+
{{template "base/footer" .}} diff --git a/templates/repo/view_file_tree.tmpl b/templates/repo/view_file_tree.tmpl index 8aed05f346940..74b0a5555fef3 100644 --- a/templates/repo/view_file_tree.tmpl +++ b/templates/repo/view_file_tree.tmpl @@ -12,4 +12,5 @@ data-repo-link="{{.RepoLink}}" data-tree-path="{{$.TreePath}}" data-current-ref-name-sub-url="{{.RefTypeNameSubURL}}" + data-page-is-edit="{{or .PageIsEdit .PageIsDelete}}" >
diff --git a/web_src/css/editor/fileeditor.css b/web_src/css/editor/fileeditor.css index 698efffc9925e..df1b387ac689d 100644 --- a/web_src/css/editor/fileeditor.css +++ b/web_src/css/editor/fileeditor.css @@ -14,8 +14,9 @@ .repo-editor-header { display: flex; - margin: 1rem 0; + margin: 4px 0; padding: 3px 0; + gap: 0.5rem } .editor-toolbar { diff --git a/web_src/css/repo.css b/web_src/css/repo.css index 9f4fa518819a7..32630de219195 100644 --- a/web_src/css/repo.css +++ b/web_src/css/repo.css @@ -150,34 +150,34 @@ td .commit-summary { } } -.repository.file.list .non-diff-file-content .header .icon { +.repository .non-diff-file-content .header .icon { font-size: 1em; } -.repository.file.list .non-diff-file-content .header .small.icon { +.repository .non-diff-file-content .header .small.icon { font-size: 0.75em; } -.repository.file.list .non-diff-file-content .header .tiny.icon { +.repository .non-diff-file-content .header .tiny.icon { font-size: 0.5em; } -.repository.file.list .non-diff-file-content .header .file-actions .btn-octicon { +.repository .non-diff-file-content .header .file-actions .btn-octicon { line-height: var(--line-height-default); padding: 8px; vertical-align: middle; color: var(--color-text); } -.repository.file.list .non-diff-file-content .header .file-actions .btn-octicon:hover { +.repository .non-diff-file-content .header .file-actions .btn-octicon:hover { color: var(--color-primary); } -.repository.file.list .non-diff-file-content .header .file-actions .btn-octicon-danger:hover { +.repository .non-diff-file-content .header .file-actions .btn-octicon-danger:hover { color: var(--color-red); } -.repository.file.list .non-diff-file-content .header .file-actions .btn-octicon.disabled { +.repository .non-diff-file-content .header .file-actions .btn-octicon.disabled { color: inherit; opacity: var(--opacity-disabled); cursor: default; diff --git a/web_src/js/components/ViewFileTree.vue b/web_src/js/components/ViewFileTree.vue index 1f90f9258670c..eabd64476cea4 100644 --- a/web_src/js/components/ViewFileTree.vue +++ b/web_src/js/components/ViewFileTree.vue @@ -9,6 +9,7 @@ const props = defineProps({ repoLink: {type: String, required: true}, treePath: {type: String, required: true}, currentRefNameSubURL: {type: String, required: true}, + pageIsEdit: {type: Boolean, required: true}, }); const store = createViewFileTreeStore(props); diff --git a/web_src/js/components/ViewFileTreeItem.vue b/web_src/js/components/ViewFileTreeItem.vue index 5173c7eb46c19..4fde8ed876368 100644 --- a/web_src/js/components/ViewFileTreeItem.vue +++ b/web_src/js/components/ViewFileTreeItem.vue @@ -37,9 +37,10 @@ const doLoadChildren = async () => { }; const onItemClick = (e: MouseEvent) => { - // only handle the click event with page partial reloading if the user didn't press any special key - // let browsers handle special keys like "Ctrl+Click" - if (!isPlainClick(e)) return; + // only handle the click event with partial page reloading if either + // - the user didn't press any special key let browsers handle special keys like "Ctrl+Click" + // - the user doesn't edit the file (a full page reload shows a confirmation dialog if the editor or commit dialog have unsaved changes) + if (!isPlainClick(e) || props.store.pageIsEdit) return; e.preventDefault(); if (props.item.entryMode === 'tree') doLoadChildren(); store.navigateTreeView(props.item.fullPath); diff --git a/web_src/js/components/ViewFileTreeStore.ts b/web_src/js/components/ViewFileTreeStore.ts index e2155bd58a26f..f1a1b59bad68b 100644 --- a/web_src/js/components/ViewFileTreeStore.ts +++ b/web_src/js/components/ViewFileTreeStore.ts @@ -4,10 +4,11 @@ import {pathEscapeSegments} from '../utils/url.ts'; import {createElementFromHTML} from '../utils/dom.ts'; import {html} from '../utils/html.ts'; -export function createViewFileTreeStore(props: { repoLink: string, treePath: string, currentRefNameSubURL: string}) { +export function createViewFileTreeStore(props: { repoLink: string, treePath: string, currentRefNameSubURL: string, pageIsEdit: boolean }) { const store = reactive({ rootFiles: [], selectedItem: props.treePath, + pageIsEdit: props.pageIsEdit, async loadChildren(treePath: string, subPath: string = '') { const response = await GET(`${props.repoLink}/tree-view/${props.currentRefNameSubURL}/${pathEscapeSegments(treePath)}?sub_path=${encodeURIComponent(subPath)}`); diff --git a/web_src/js/features/repo-view-file-tree.ts b/web_src/js/features/repo-view-file-tree.ts index f52b64cc51d19..34cc5e650b8b6 100644 --- a/web_src/js/features/repo-view-file-tree.ts +++ b/web_src/js/features/repo-view-file-tree.ts @@ -33,5 +33,6 @@ export async function initRepoViewFileTree() { repoLink: fileTree.getAttribute('data-repo-link'), treePath: fileTree.getAttribute('data-tree-path'), currentRefNameSubURL: fileTree.getAttribute('data-current-ref-name-sub-url'), + pageIsEdit: fileTree.getAttribute('data-page-is-edit') === 'true', }).mount(fileTree); }