mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 19:06:18 +01:00 
			
		
		
		
	Use git diff-tree for DiffFileTree on diff pages (#33514)
				
					
				
			Modify Diff View FileTree to show all files ## Changes * removes Show Status button on diff * uses `git diff-tree` to generate the file tree for the diff * doesn't reload the diff tree each time we load more files in the preview * selecting and unloaded file will keep loading until that file is loaded * removes `DiffFileList.vue` and "Show Stats" in diff options ## Open Questions * selecting and unloaded file will keep loading until that file is loaded. Is this behaviour okay? It matches what github does. ### Demo In this demo I set `git.MAX_GIT_DIFF_FILES=1` in my `app.ini` to demonstrate a worst case example. In most cases the behaviour isn't nearly as jarring as we load a bunch of files at a time. https://github.com/user-attachments/assets/72f29663-d6fc-472d-94fa-7fb5950c2836 --------- Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
		| @@ -2,21 +2,7 @@ | ||||
| import {SvgIcon, type SvgName} from '../svg.ts'; | ||||
| import {diffTreeStore} from '../modules/stores.ts'; | ||||
| import {ref} from 'vue'; | ||||
|  | ||||
| type File = { | ||||
|   Name: string; | ||||
|   NameHash: string; | ||||
|   Type: number; | ||||
|   IsViewed: boolean; | ||||
|   IsSubmodule: boolean; | ||||
| } | ||||
|  | ||||
| export type Item = { | ||||
|   name: string; | ||||
|   isFile: boolean; | ||||
|   file?: File; | ||||
|   children?: Item[]; | ||||
| }; | ||||
| import type {Item, File, FileStatus} from '../utils/filetree.ts'; | ||||
|  | ||||
| defineProps<{ | ||||
|   item: Item, | ||||
| @@ -25,15 +11,16 @@ defineProps<{ | ||||
| const store = diffTreeStore(); | ||||
| const collapsed = ref(false); | ||||
|  | ||||
| function getIconForDiffType(pType: number) { | ||||
|   const diffTypes: Record<string, {name: SvgName, classes: Array<string>}> = { | ||||
|     '1': {name: 'octicon-diff-added', classes: ['text', 'green']}, | ||||
|     '2': {name: 'octicon-diff-modified', classes: ['text', 'yellow']}, | ||||
|     '3': {name: 'octicon-diff-removed', classes: ['text', 'red']}, | ||||
|     '4': {name: 'octicon-diff-renamed', classes: ['text', 'teal']}, | ||||
|     '5': {name: 'octicon-diff-renamed', classes: ['text', 'green']}, // there is no octicon for copied, so renamed should be ok | ||||
| function getIconForDiffStatus(pType: FileStatus) { | ||||
|   const diffTypes: Record<FileStatus, { name: SvgName, classes: Array<string> }> = { | ||||
|     'added': {name: 'octicon-diff-added', classes: ['text', 'green']}, | ||||
|     'modified': {name: 'octicon-diff-modified', classes: ['text', 'yellow']}, | ||||
|     'deleted': {name: 'octicon-diff-removed', classes: ['text', 'red']}, | ||||
|     'renamed': {name: 'octicon-diff-renamed', classes: ['text', 'teal']}, | ||||
|     'copied': {name: 'octicon-diff-renamed', classes: ['text', 'green']}, | ||||
|     'typechange': {name: 'octicon-diff-modified', classes: ['text', 'green']}, // there is no octicon for copied, so renamed should be ok | ||||
|   }; | ||||
|   return diffTypes[String(pType)]; | ||||
|   return diffTypes[pType]; | ||||
| } | ||||
|  | ||||
| function fileIcon(file: File) { | ||||
| @@ -48,27 +35,37 @@ function fileIcon(file: File) { | ||||
|   <!--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"--> | ||||
|   <a | ||||
|     v-if="item.isFile" class="item-file" | ||||
|     :class="{'selected': store.selectedItem === '#diff-' + item.file.NameHash, 'viewed': item.file.IsViewed}" | ||||
|     :class="{ 'selected': store.selectedItem === '#diff-' + item.file.NameHash, 'viewed': item.file.IsViewed }" | ||||
|     :title="item.name" :href="'#diff-' + item.file.NameHash" | ||||
|   > | ||||
|     <!-- file --> | ||||
|     <SvgIcon :name="fileIcon(item.file)"/> | ||||
|     <span class="gt-ellipsis tw-flex-1">{{ item.name }}</span> | ||||
|     <SvgIcon :name="getIconForDiffType(item.file.Type).name" :class="getIconForDiffType(item.file.Type).classes"/> | ||||
|     <SvgIcon | ||||
|       :name="getIconForDiffStatus(item.file.Status).name" | ||||
|       :class="getIconForDiffStatus(item.file.Status).classes" | ||||
|     /> | ||||
|   </a> | ||||
|   <div v-else class="item-directory" :title="item.name" @click.stop="collapsed = !collapsed"> | ||||
|     <!-- directory --> | ||||
|     <SvgIcon :name="collapsed ? 'octicon-chevron-right' : 'octicon-chevron-down'"/> | ||||
|     <SvgIcon class="text primary" :name="collapsed ? 'octicon-file-directory-fill' : 'octicon-file-directory-open-fill'"/> | ||||
|     <span class="gt-ellipsis">{{ item.name }}</span> | ||||
|   </div> | ||||
|  | ||||
|   <div v-if="item.children?.length" v-show="!collapsed" class="sub-items"> | ||||
|     <DiffFileTreeItem v-for="childItem in item.children" :key="childItem.name" :item="childItem"/> | ||||
|   </div> | ||||
|   <template v-else-if="item.isFile === false"> | ||||
|     <div class="item-directory" :title="item.name" @click.stop="collapsed = !collapsed"> | ||||
|       <!-- directory --> | ||||
|       <SvgIcon :name="collapsed ? 'octicon-chevron-right' : 'octicon-chevron-down'"/> | ||||
|       <SvgIcon | ||||
|         class="text primary" | ||||
|         :name="collapsed ? 'octicon-file-directory-fill' : 'octicon-file-directory-open-fill'" | ||||
|       /> | ||||
|       <span class="gt-ellipsis">{{ item.name }}</span> | ||||
|     </div> | ||||
|  | ||||
|     <div v-show="!collapsed" class="sub-items"> | ||||
|       <DiffFileTreeItem v-for="childItem in item.children" :key="childItem.name" :item="childItem"/> | ||||
|     </div> | ||||
|   </template> | ||||
| </template> | ||||
| <style scoped> | ||||
| a, a:hover { | ||||
| a, | ||||
| a:hover { | ||||
|   text-decoration: none; | ||||
|   color: var(--color-text); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user