@@ -25,6 +25,75 @@ const currentPage = ref(1)
2525const observer = ref <IntersectionObserver | null >(null )
2626const loadingTriggerRef = ref <HTMLElement | null >(null )
2727
28+ // 列宽度状态
29+ const columnWidths = ref ({
30+ hash: 80 ,
31+ message: 400 , // 给定初始宽度,不再使用 flex: 1
32+ stats: 140 ,
33+ author: 120 ,
34+ date: 160 ,
35+ })
36+
37+ // 拖拽状态
38+ const isDragging = ref (false )
39+ const currentColumn = ref (' ' )
40+ const startX = ref (0 )
41+ const startWidth = ref (0 )
42+
43+ function handleDragStart(e : MouseEvent , column : string ) {
44+ e .preventDefault ()
45+ e .stopPropagation ()
46+
47+ isDragging .value = true
48+ currentColumn .value = column
49+ startX .value = e .clientX
50+ startWidth .value = columnWidths .value [column ]
51+
52+ document .addEventListener (' mousemove' , handleDragging , { passive: false })
53+ document .addEventListener (' mouseup' , handleDragEnd , { once: true })
54+ document .addEventListener (' mouseleave' , handleDragEnd , { once: true })
55+ document .addEventListener (' keydown' , handleKeyDown )
56+
57+ document .body .style .userSelect = ' none'
58+ document .body .style .cursor = ' col-resize'
59+ }
60+
61+ function handleDragging(e : MouseEvent ) {
62+ if (! isDragging .value ) {
63+ handleDragEnd ()
64+ return
65+ }
66+
67+ e .preventDefault ()
68+ e .stopPropagation ()
69+
70+ const diff = e .clientX - startX .value
71+ const newWidth = Math .max (100 , startWidth .value + diff )
72+ columnWidths .value [currentColumn .value ] = newWidth
73+ }
74+
75+ function handleKeyDown(e : KeyboardEvent ) {
76+ if (e .key === ' Escape' ) {
77+ handleDragEnd ()
78+ }
79+ }
80+
81+ function handleDragEnd() {
82+ if (! isDragging .value )
83+ return
84+
85+ isDragging .value = false
86+ currentColumn .value = ' '
87+
88+ document .removeEventListener (' mousemove' , handleDragging )
89+ document .removeEventListener (' mouseup' , handleDragEnd )
90+ document .removeEventListener (' mouseleave' , handleDragEnd )
91+ document .removeEventListener (' keydown' , handleKeyDown )
92+
93+ document .body .style .userSelect = ' '
94+ document .body .style .cursor = ' '
95+ }
96+
2897function handleCommitClick(commit : Commit & { date: string }) {
2998 try {
3099 if (window .vscode ) {
@@ -93,18 +162,51 @@ onUnmounted(() => {
93162 if (observer .value ) {
94163 observer .value .disconnect ()
95164 }
165+ if (isDragging .value ) {
166+ handleDragEnd ()
167+ }
96168})
97169 </script >
98170
99171<template >
100172 <div class =" git-graph" >
101- <ul class =" commit-list" >
173+ <ul class =" commit-list" :class = " { dragging: isDragging } " >
102174 <li class =" commit-header" >
103- <span class =" hash-col" >CommitId</span >
104- <span class =" message-col" >Message</span >
105- <span class =" stats-col" >Changes</span >
106- <span class =" author" >Author</span >
107- <span class =" date" >Date</span >
175+ <span class =" hash-col column-header" :style =" { width: `${columnWidths.hash}px` }" >
176+ CommitId
177+ <div
178+ class =" resize-handle"
179+ :class =" { active: currentColumn === 'hash' }"
180+ @mousedown =" handleDragStart($event, 'hash')"
181+ />
182+ </span >
183+ <span class =" message-col column-header" :style =" { width: `${columnWidths.message}px` }" >
184+ Message
185+ <div
186+ class =" resize-handle"
187+ :class =" { active: currentColumn === 'message' }"
188+ @mousedown =" handleDragStart($event, 'message')"
189+ />
190+ </span >
191+ <span class =" stats-col column-header" :style =" { width: `${columnWidths.stats}px` }" >
192+ Changes
193+ <div
194+ class =" resize-handle"
195+ :class =" { active: currentColumn === 'stats' }"
196+ @mousedown =" handleDragStart($event, 'stats')"
197+ />
198+ </span >
199+ <span class =" author column-header" :style =" { width: `${columnWidths.author}px` }" >
200+ Author
201+ <div
202+ class =" resize-handle"
203+ :class =" { active: currentColumn === 'author' }"
204+ @mousedown =" handleDragStart($event, 'author')"
205+ />
206+ </span >
207+ <span class =" date column-header" >
208+ Date
209+ </span >
108210 </li >
109211 <li
110212 v-for =" commit in visibleCommits"
@@ -113,17 +215,17 @@ onUnmounted(() => {
113215 @click =" handleCommitClick(commit)"
114216 @dblclick =" handleDoubleClick"
115217 >
116- <span class =" hash-col" >{{ commit.hash.substring(0, 7) }}</span >
117- <span class =" message-col" >{{ commit.message }}</span >
118- <span class =" stats-col" >
218+ <span class =" hash-col" :style = " { width: `${columnWidths.hash}px` } " >{{ commit.hash.substring(0, 7) }}</span >
219+ <span class =" message-col" :style = " { width: `${columnWidths.message}px` } " >{{ commit.message }}</span >
220+ <span class =" stats-col" :style = " { width: `${columnWidths.stats}px` } " >
119221 <span v-if =" commit.stats" class =" commit-stats" >
120222 <span class =" files" >{{ commit.stats.files }} files</span >
121223 <span v-if =" commit.stats.additions" class =" additions" >+{{ commit.stats.additions }}</span >
122224 <span v-if =" commit.stats.deletions" class =" deletions" >-{{ commit.stats.deletions }}</span >
123225 </span >
124226 </span >
125- <span class =" author" >{{ commit.authorName }}</span >
126- <span class =" date" >{{ commit.date }}</span >
227+ <span class =" author" :style = " { width: `${columnWidths.author}px` } " >{{ commit.authorName }}</span >
228+ <span class =" date" :style = " { width: `${columnWidths.date}px` } " >{{ commit.date }}</span >
127229 </li >
128230 <li ref =" loadingTriggerRef" class =" loading-trigger" >
129231 <div v-if =" visibleCommits.length < graphData.length" class =" loading-text" >
@@ -148,80 +250,113 @@ onUnmounted(() => {
148250 list-style : none ;
149251 font-size : var (--vscode-font-size );
150252 color : var (--vscode-foreground );
253+ min-width : min-content ;
151254}
152255
153256.commit-header {
154257 position : sticky ;
155258 top : 0 ;
156259 display : flex ;
157260 align-items : center ;
158- padding : 8px ;
159261 background-color : var (--vscode-sideBar-background );
160262 border-bottom : 1px solid var (--vscode-panel-border );
161263 font-weight : bold ;
264+ width : 100% ;
265+ box-sizing : border-box ;
266+ padding : 8px ;
267+ z-index : 2 ;
162268}
163269
164270.commit-row {
165271 display : flex ;
166272 align-items : center ;
167- padding : 8px ;
168273 border-bottom : 1px solid var (--vscode-panel-border );
169274 cursor : pointer ;
170- gap : 5px ;
275+ width : 100% ;
276+ box-sizing : border-box ;
277+ padding : 8px ;
171278}
172279
173280.commit-row :hover {
174281 background-color : var (--vscode-list-hoverBackground );
175282}
176283
177- .hash-col {
178- width : 80px ;
179- padding-right : 8px ;
284+ .column-header ,
285+ .hash-col ,
286+ .message-col ,
287+ .stats-col ,
288+ .author ,
289+ .date {
290+ position : relative ;
291+ box-sizing : border-box ;
292+ padding : 0 8px ;
180293 white-space : nowrap ;
181294 overflow : hidden ;
182295 text-overflow : ellipsis ;
296+ display : flex ;
297+ align-items : center ;
183298}
184299
185- .commit-row .hash-col {
186- color : var ( --vscode-gitDecoration-addedResourceForeground ) ;
300+ .column-header {
301+ user-select : none ;
187302}
188303
189- .commit-row .hash-col :hover {
190- text-decoration : underline ;
304+ .hash-col {
305+ width : 80px ;
306+ color : var (--vscode-gitDecoration-addedResourceForeground );
191307}
192308
193309.message-col {
194- flex : 1 ;
195- padding-right : 8px ;
196- white-space : nowrap ;
197- overflow : hidden ;
198- text-overflow : ellipsis ;
310+ min-width : 100px ;
199311}
200312
201313.stats-col {
202314 width : 140px ;
203- padding-right : 8px ;
204- white-space : nowrap ;
205- overflow : hidden ;
206- text-overflow : ellipsis ;
207315}
208316
209317.author {
210318 width : 120px ;
211- padding-right : 8px ;
212- white-space : nowrap ;
213- overflow : hidden ;
214- text-overflow : ellipsis ;
215319}
216320
217321.date {
218322 width : 160px ;
219- white-space : nowrap ;
220- overflow : hidden ;
221- text-overflow : ellipsis ;
323+ padding-right : 16px ;
222324 color : var (--vscode-descriptionForeground );
223325}
224326
327+ .resize-handle {
328+ position : absolute ;
329+ right : 0 ;
330+ top : 0 ;
331+ bottom : 0 ;
332+ width : 3px ;
333+ cursor : col-resize ;
334+ background : var (--vscode-scrollbarSlider-hoverBackground );
335+ opacity : 0.6 ;
336+ z-index : 1 ;
337+ transition : background-color 0.1s ease ;
338+ }
339+
340+ .resize-handle :hover {
341+ background : var (--vscode-activityBar-activeBorder );
342+ opacity : 0.8 ;
343+ }
344+
345+ .resize-handle.active {
346+ background : var (--vscode-activityBar-activeBorder );
347+ opacity : 1 ;
348+ }
349+
350+ .commit-list.dragging {
351+ cursor : col-resize ;
352+ }
353+
354+ .commit-list.dragging .resize-handle.active {
355+ display : block ;
356+ background : var (--vscode-activityBar-activeBorder );
357+ opacity : 1 ;
358+ }
359+
225360.commit-stats {
226361 display : inline-flex ;
227362 gap : 8px ;
@@ -238,17 +373,12 @@ onUnmounted(() => {
238373}
239374
240375.loading-trigger {
241- text-align : center ;
242376 padding : 8px ;
377+ text-align : center ;
243378}
244379
245380.loading-text {
246381 font-size : 12px ;
247382 color : var (--vscode-descriptionForeground );
248383}
249-
250- /* Ensure the graph lines remain visible when hovering */
251- .commit-row :hover .commit-line {
252- opacity : 0.8 ;
253- }
254384 </style >
0 commit comments