Skip to content

Commit 53b5833

Browse files
committed
Optimize File Icons in file-tree to Match Those in file-list
1 parent 9ebae4a commit 53b5833

File tree

2 files changed

+40
-43
lines changed

2 files changed

+40
-43
lines changed

services/repository/files/tree.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package files
66
import (
77
"context"
88
"fmt"
9+
"html/template"
910
"net/url"
1011
"path"
1112
"sort"
@@ -14,8 +15,10 @@ import (
1415
repo_model "code.gitea.io/gitea/models/repo"
1516
"code.gitea.io/gitea/modules/git"
1617
"code.gitea.io/gitea/modules/log"
18+
"code.gitea.io/gitea/modules/reqctx"
1719
"code.gitea.io/gitea/modules/setting"
1820
api "code.gitea.io/gitea/modules/structs"
21+
"code.gitea.io/gitea/modules/templates"
1922
"code.gitea.io/gitea/modules/util"
2023
)
2124

@@ -142,6 +145,7 @@ func entryModeString(entryMode git.EntryMode) string {
142145
type TreeViewNode struct {
143146
EntryName string `json:"entryName"`
144147
EntryMode string `json:"entryMode"`
148+
FileIcon template.HTML `json:"fileIcon"`
145149
FullPath string `json:"fullPath"`
146150
SubmoduleURL string `json:"submoduleUrl,omitempty"`
147151
Children []*TreeViewNode `json:"children,omitempty"`
@@ -155,6 +159,7 @@ func newTreeViewNodeFromEntry(ctx context.Context, commit *git.Commit, parentDir
155159
node := &TreeViewNode{
156160
EntryName: entry.Name(),
157161
EntryMode: entryModeString(entry.Mode()),
162+
FileIcon: templates.NewRenderUtils(reqctx.FromContext(ctx)).RenderFileIcon(entry),
158163
FullPath: path.Join(parentDir, entry.Name()),
159164
}
160165

web_src/js/components/ViewFileTreeItem.vue

Lines changed: 35 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<script lang="ts" setup>
22
import {SvgIcon} from '../svg.ts';
3-
import {ref} from 'vue';
3+
import {onMounted, ref} from 'vue';
44
55
type Item = {
66
entryName: string;
77
entryMode: string;
8+
fileIcon: string;
89
fullPath: string;
910
submoduleUrl?: string;
1011
children?: Item[];
@@ -17,9 +18,15 @@ const props = defineProps<{
1718
selectedItem?: string,
1819
}>();
1920
21+
const elRoot = ref<HTMLElement | null>(null);
2022
const isLoading = ref(false);
2123
const children = ref(props.item.children);
2224
const collapsed = ref(!props.item.children);
25+
const isDirectory = ref(!(
26+
props.item.entryMode === 'commit' ||
27+
props.item.entryMode === 'symlink' ||
28+
props.item.entryMode !== 'tree'
29+
));
2330
2431
const doLoadChildren = async () => {
2532
collapsed.value = !collapsed.value;
@@ -45,59 +52,40 @@ const doLoadFileContent = () => {
4552
const doGotoSubModule = () => {
4653
location.href = props.item.submoduleUrl;
4754
};
55+
56+
const doItemAction = () => {
57+
if (props.item.entryMode === 'symlink' || props.item.entryMode === 'tree') {
58+
doLoadFileContent();
59+
} else if (props.item.entryMode === 'commit') {
60+
doGotoSubModule();
61+
} else {
62+
doLoadDirContent();
63+
}
64+
};
65+
66+
onMounted(async () => {
67+
elRoot.value.querySelector('.item-icon svg')?.classList?.add('preview-square');
68+
});
4869
</script>
4970

5071
<!--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"-->
5172
<template>
5273
<div
53-
v-if="item.entryMode === 'commit'" class="tree-item type-submodule"
54-
:title="item.entryName"
55-
@click.stop="doGotoSubModule"
56-
>
57-
<!-- submodule -->
58-
<div class="item-content">
59-
<SvgIcon class="text primary" name="octicon-file-submodule"/>
60-
<span class="gt-ellipsis tw-flex-1">{{ item.entryName }}</span>
61-
</div>
62-
</div>
63-
<div
64-
v-else-if="item.entryMode === 'symlink'" class="tree-item type-symlink"
65-
:class="{'selected': selectedItem === item.fullPath}"
66-
:title="item.entryName"
67-
@click.stop="doLoadFileContent"
68-
>
69-
<!-- symlink -->
70-
<div class="item-content">
71-
<SvgIcon name="octicon-file-symlink-file"/>
72-
<span class="gt-ellipsis tw-flex-1">{{ item.entryName }}</span>
73-
</div>
74-
</div>
75-
<div
76-
v-else-if="item.entryMode !== 'tree'" class="tree-item type-file"
77-
:class="{'selected': selectedItem === item.fullPath}"
78-
:title="item.entryName"
79-
@click.stop="doLoadFileContent"
80-
>
81-
<!-- file -->
82-
<div class="item-content">
83-
<SvgIcon name="octicon-file"/>
84-
<span class="gt-ellipsis tw-flex-1">{{ item.entryName }}</span>
85-
</div>
86-
</div>
87-
<div
88-
v-else class="tree-item type-directory"
89-
:class="{'selected': selectedItem === item.fullPath}"
74+
ref="elRoot"
75+
class="tree-item"
76+
:class="{'selected': selectedItem === item.fullPath, 'type-directory': isDirectory}"
9077
:title="item.entryName"
91-
@click.stop="doLoadDirContent"
78+
@click.stop="doItemAction"
9279
>
93-
<!-- directory -->
94-
<div class="item-toggle">
80+
<div v-if="isDirectory" class="item-toggle">
81+
<!-- directory -->
9582
<SvgIcon v-if="isLoading" name="octicon-sync" class="job-status-rotate"/>
9683
<SvgIcon v-else :name="collapsed ? 'octicon-chevron-right' : 'octicon-chevron-down'" @click.stop="doLoadChildren"/>
9784
</div>
9885
<div class="item-content">
99-
<SvgIcon class="text primary" :name="collapsed ? 'octicon-file-directory-fill' : 'octicon-file-directory-open-fill'"/>
100-
<span class="gt-ellipsis">{{ item.entryName }}</span>
86+
<SvgIcon v-if="isDirectory" class="text primary" :name="collapsed ? 'octicon-file-directory-fill' : 'octicon-file-directory-open-fill'"/>
87+
<span v-else class="item-icon" v-html="item.fileIcon"/>
88+
<span class="gt-ellipsis tw-flex-1">{{ item.entryName }}</span>
10189
</div>
10290
</div>
10391

@@ -153,4 +141,8 @@ const doGotoSubModule = () => {
153141
text-overflow: ellipsis;
154142
min-width: 0;
155143
}
144+
145+
.item-content .item-icon {
146+
display: contents;
147+
}
156148
</style>

0 commit comments

Comments
 (0)