Skip to content

Commit 40b61f3

Browse files
committed
clean up
1 parent 692c62a commit 40b61f3

File tree

6 files changed

+67
-96
lines changed

6 files changed

+67
-96
lines changed

Diff for: routers/web/web.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1176,7 +1176,7 @@ func registerRoutes(m *web.Router) {
11761176
m.Get("/tag/*", context.RepoRefByType(git.RefTypeTag), repo.TreeList)
11771177
m.Get("/commit/*", context.RepoRefByType(git.RefTypeCommit), repo.TreeList)
11781178
})
1179-
m.Group("/tree", func() {
1179+
m.Group("/tree-view", func() {
11801180
m.Get("/branch/*", context.RepoRefByType(git.RefTypeBranch), repo.TreeViewNodes)
11811181
m.Get("/tag/*", context.RepoRefByType(git.RefTypeTag), repo.TreeViewNodes)
11821182
m.Get("/commit/*", context.RepoRefByType(git.RefTypeCommit), repo.TreeViewNodes)

Diff for: templates/repo/view_file_tree_sidebar.tmpl

+2-4
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,8 @@
88
<!--// TODO: Dynamically move components such as refSelector and createPR here-->
99
<div class="view-file-tree-sidebar-bottom tw-overflow-auto">
1010
<div id="view-file-tree" class="is-loading"
11-
data-api-base-url="{{.RepoLink}}"
11+
data-repo-link="{{.RepoLink}}"
1212
data-tree-path="{{$.TreePath}}"
13-
data-current-ref-type="{{.RefFullName.RefType}}"
14-
data-current-ref-short-name="{{.RefFullName.ShortName}}"
15-
data-current-ref-type-name-sub-url="{{.RefTypeNameSubURL}}"
13+
data-current-ref-name-sub-url="{{.RefTypeNameSubURL}}"
1614
></div>
1715
</div>

Diff for: web_src/js/components/ViewFileTree.vue

+39-8
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,49 @@
11
<script lang="ts" setup>
22
import ViewFileTreeItem from './ViewFileTreeItem.vue';
3+
import {onMounted, ref} from 'vue';
4+
import {pathEscapeSegments} from '../utils/url.ts';
5+
import {GET} from '../modules/fetch.ts';
36
4-
defineProps<{
5-
files: any,
6-
selectedItem: any,
7-
loadChildren: any,
8-
loadContent: any;
9-
}>();
7+
const elRoot = ref<HTMLElement | null>(null);
8+
9+
const props = defineProps({
10+
repoLink: {type: String, required: true},
11+
treePath: {type: String, required: true},
12+
currentRefNameSubURL: {type: String, required: true},
13+
});
14+
15+
const files = ref([]);
16+
const selectedItem = ref('');
17+
18+
async function loadChildren(treePath: string, subPath: string = '') {
19+
const response = await GET(`${props.repoLink}/tree-view/${props.currentRefNameSubURL}/${pathEscapeSegments(treePath)}?sub_path=${encodeURIComponent(subPath)}`);
20+
const json = await response.json();
21+
return json.fileTreeNodes ?? null;
22+
}
23+
24+
async function loadViewContent(treePath: string) {
25+
// load content by path (content based on home_content.tmpl)
26+
window.history.pushState({treePath}, null, `${props.repoLink}/src/${props.currentRefNameSubURL}/${pathEscapeSegments(treePath)}`);
27+
const response = await GET(`${window.location.href}?only_content=true`);
28+
const contentEl = document.querySelector('.repo-view-content');
29+
contentEl.innerHTML = await response.text();
30+
}
31+
32+
onMounted(async () => {
33+
selectedItem.value = props.treePath;
34+
files.value = await loadChildren('', props.treePath);
35+
elRoot.value.closest('.is-loading')?.classList?.remove('is-loading');
36+
window.addEventListener('popstate', (e) => {
37+
selectedItem.value = e.state?.treePath || '';
38+
loadViewContent(selectedItem.value);
39+
});
40+
});
1041
</script>
1142

1243
<template>
13-
<div class="view-file-tree-items">
44+
<div class="view-file-tree-items" ref="elRoot">
1445
<!-- only render the tree if we're visible. in many cases this is something that doesn't change very often -->
15-
<ViewFileTreeItem v-for="item in files" :key="item.name" :item="item" :selected-item="selectedItem" :load-content="loadContent" :load-children="loadChildren"/>
46+
<ViewFileTreeItem v-for="item in files" :key="item.name" :item="item" :selected-item="selectedItem" :load-content="loadViewContent" :load-children="loadChildren"/>
1647
</div>
1748
</template>
1849

Diff for: web_src/js/components/ViewFileTreeItem.vue

+9-18
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ const doLoadChildren = async () => {
2626
if (!collapsed.value && props.loadChildren) {
2727
isLoading.value = true;
2828
try {
29-
const _children = await props.loadChildren(props.item.path);
30-
children.value = _children;
29+
children.value = await props.loadChildren(props.item.path);
3130
} finally {
3231
isLoading.value = false;
3332
}
@@ -51,7 +50,7 @@ const doGotoSubModule = () => {
5150
<template>
5251
<!--title instead of tooltip above as the tooltip needs too much work with the current methods, i.e. not being loaded or staying open for "too long"-->
5352
<div
54-
v-if="item.type === 'commit'" class="item-submodule"
53+
v-if="item.type === 'commit'" class="tree-item type-submodule"
5554
:title="item.name"
5655
@click.stop="doGotoSubModule"
5756
>
@@ -62,7 +61,7 @@ const doGotoSubModule = () => {
6261
</div>
6362
</div>
6463
<div
65-
v-else-if="item.type === 'symlink'" class="item-symlink"
64+
v-else-if="item.type === 'symlink'" class="tree-item type-symlink"
6665
:class="{'selected': selectedItem.value === item.path}"
6766
:title="item.name"
6867
@click.stop="doLoadFileContent"
@@ -74,7 +73,7 @@ const doGotoSubModule = () => {
7473
</div>
7574
</div>
7675
<div
77-
v-else-if="item.type !== 'tree'" class="item-file"
76+
v-else-if="item.type !== 'tree'" class="tree-item type-file"
7877
:class="{'selected': selectedItem.value === item.path}"
7978
:title="item.name"
8079
@click.stop="doLoadFileContent"
@@ -86,7 +85,7 @@ const doGotoSubModule = () => {
8685
</div>
8786
</div>
8887
<div
89-
v-else class="item-directory"
88+
v-else class="tree-item type-directory"
9089
:class="{'selected': selectedItem.value === item.path}"
9190
:title="item.name"
9291
@click.stop="doLoadDirContent"
@@ -115,33 +114,25 @@ const doGotoSubModule = () => {
115114
border-left: 1px solid var(--color-secondary);
116115
}
117116
118-
.item-directory.selected,
119-
.item-symlink.selected,
120-
.item-file.selected {
117+
.tree-item.selected {
121118
color: var(--color-text);
122119
background: var(--color-active);
123120
border-radius: 4px;
124121
}
125122
126-
.item-directory {
123+
.tree-item.type-directory {
127124
user-select: none;
128125
}
129126
130-
.item-file,
131-
.item-symlink,
132-
.item-submodule,
133-
.item-directory {
127+
.tree-item {
134128
display: grid;
135129
grid-template-columns: 16px 1fr;
136130
grid-template-areas: "toggle content";
137131
gap: 0.25em;
138132
padding: 6px;
139133
}
140134
141-
.item-file:hover,
142-
.item-symlink:hover,
143-
.item-submodule:hover,
144-
.item-directory:hover {
135+
.tree-item:hover {
145136
color: var(--color-text);
146137
background: var(--color-hover);
147138
border-radius: 4px;

Diff for: web_src/js/features/repo-view-file-tree-sidebar.ts

+16-61
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import {createApp, ref} from 'vue';
1+
import {createApp} from 'vue';
22
import {toggleElem} from '../utils/dom.ts';
3-
import {pathEscapeSegments, pathUnescapeSegments} from '../utils/url.ts';
4-
import {GET, POST} from '../modules/fetch.ts';
3+
import {POST} from '../modules/fetch.ts';
54
import ViewFileTree from '../components/ViewFileTree.vue';
65

76
const {appSubUrl} = window.config;
@@ -24,70 +23,26 @@ async function toggleSidebar(sidebarEl: HTMLElement, shouldShow: boolean) {
2423
codeViewShowFileTree: shouldShow,
2524
},
2625
});
27-
}
28-
29-
function childrenLoader(sidebarEl: HTMLElement) {
30-
return async (treePath: string, subPath: string = '') => {
31-
const fileTree = sidebarEl.querySelector('#view-file-tree');
32-
const baseUrl = fileTree.getAttribute('data-api-base-url');
33-
const refTypeNameSubURL = fileTree.getAttribute('data-current-ref-type-name-sub-url');
34-
const response = await GET(`${baseUrl}/tree/${refTypeNameSubURL}/${pathEscapeSegments(treePath)}?sub_path=${encodeURIComponent(subPath)}`);
35-
const json = await response.json();
36-
return json.fileTreeNodes ?? null;
37-
};
38-
}
3926

40-
async function loadContent(sidebarEl: HTMLElement) {
41-
// load content by path (content based on home_content.tmpl)
42-
const response = await GET(`${window.location.href}?only_content=true`);
43-
const contentEl = sidebarEl.parentElement.querySelector('.repo-view-content');
44-
contentEl.innerHTML = await response.text();
45-
reloadContentScript(sidebarEl, contentEl);
46-
}
47-
48-
function reloadContentScript(sidebarEl: HTMLElement, contentEl: Element) {
49-
contentEl.querySelector('.show-tree-sidebar-button')?.addEventListener('click', () => {
50-
toggleSidebar(sidebarEl, true);
51-
});
27+
// FIXME: add event listener for "show-tree-sidebar-button"
5228
}
5329

5430
export async function initViewFileTreeSidebar() {
55-
const sidebarEl = document.querySelector('.repo-view-file-tree-sidebar');
56-
if (!sidebarEl || !(sidebarEl instanceof HTMLElement)) return;
31+
const sidebar = document.querySelector<HTMLElement>('.repo-view-file-tree-sidebar');
32+
const repoViewContent = document.querySelector('.repo-view-content');
33+
if (!sidebar || !repoViewContent) return;
5734

58-
sidebarEl.querySelector('.hide-tree-sidebar-button').addEventListener('click', () => {
59-
toggleSidebar(sidebarEl, false);
35+
sidebar.querySelector('.hide-tree-sidebar-button').addEventListener('click', () => {
36+
toggleSidebar(sidebar, false);
6037
});
61-
sidebarEl.parentElement.querySelector('.repo-view-content .show-tree-sidebar-button').addEventListener('click', () => {
62-
toggleSidebar(sidebarEl, true);
38+
repoViewContent.querySelector('.show-tree-sidebar-button').addEventListener('click', () => {
39+
toggleSidebar(sidebar, true);
6340
});
6441

65-
const fileTree = sidebarEl.querySelector('#view-file-tree');
66-
const baseUrl = fileTree.getAttribute('data-api-base-url');
67-
const treePath = fileTree.getAttribute('data-tree-path');
68-
const refType = fileTree.getAttribute('data-current-ref-type');
69-
const refName = fileTree.getAttribute('data-current-ref-short-name');
70-
const refString = (refType ? (`/${refType}`) : '') + (refName ? (`/${refName}`) : '');
71-
72-
const selectedItem = ref(getSelectedPath(refString));
73-
74-
const files = await childrenLoader(sidebarEl)('', treePath);
75-
76-
fileTree.classList.remove('is-loading');
77-
const fileTreeView = createApp(ViewFileTree, {files, selectedItem, loadChildren: childrenLoader(sidebarEl), loadContent: (path: string) => {
78-
window.history.pushState(null, null, `${baseUrl}/src${refString}/${pathEscapeSegments(path)}`);
79-
selectedItem.value = path;
80-
loadContent(sidebarEl);
81-
}});
82-
fileTreeView.mount(fileTree);
83-
84-
window.addEventListener('popstate', () => {
85-
selectedItem.value = getSelectedPath(refString);
86-
loadContent(sidebarEl);
87-
});
88-
}
89-
90-
function getSelectedPath(ref: string) {
91-
const path = pathUnescapeSegments(new URL(window.location.href).pathname);
92-
return path.substring(path.indexOf(ref) + ref.length + 1);
42+
const fileTree = sidebar.querySelector('#view-file-tree');
43+
createApp(ViewFileTree, {
44+
repoLink: fileTree.getAttribute('data-repo-link'),
45+
treePath: fileTree.getAttribute('data-tree-path'),
46+
currentRefNameSubURL: fileTree.getAttribute('data-current-ref-name-sub-url'),
47+
}).mount(fileTree);
9348
}

Diff for: web_src/js/utils/url.ts

-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,6 @@ export function pathEscapeSegments(s: string): string {
22
return s.split('/').map(encodeURIComponent).join('/');
33
}
44

5-
export function pathUnescapeSegments(s: string): string {
6-
return s.split('/').map(decodeURIComponent).join('/');
7-
}
8-
95
function stripSlash(url: string): string {
106
return url.endsWith('/') ? url.slice(0, -1) : url;
117
}

0 commit comments

Comments
 (0)