1- import React , { useState , useEffect , useLayoutEffect , useRef , useCallback , useMemo } from 'react' ;
1+ import React , { useState , useEffect , useRef , useCallback , useMemo } from 'react' ;
22import { Icons } from './Icons' ;
33import { FileIcon } from './FileIcon' ;
44import './ChangesPanel.css' ;
@@ -57,51 +57,6 @@ const areChangedFileEqual = (prev: ChangedFile, next: ChangedFile): boolean => (
5757 && ( prev . removed ?? 0 ) === ( next . removed ?? 0 )
5858) ;
5959
60- const areChangedFileStructureEqual = ( prev : ChangedFile , next : ChangedFile ) : boolean => (
61- prev . path === next . path
62- && prev . status === next . status
63- && ! ! prev . staged === ! ! next . staged
64- && ! ! prev . unstaged === ! ! next . unstaged
65- && ! ! prev . conflicted === ! ! next . conflicted
66- ) ;
67-
68- const updateStatsElement = (
69- element : HTMLSpanElement | undefined ,
70- added : number ,
71- removed : number ,
72- ) => {
73- if ( ! element ) {
74- return ;
75- }
76-
77- element . style . display = added > 0 || removed > 0 ? '' : 'none' ;
78-
79- const addedElement = element . querySelector < HTMLElement > ( '[data-stat="added"]' ) ;
80- if ( addedElement ) {
81- addedElement . textContent = added > 0 ? `+${ added } ` : '' ;
82- addedElement . style . display = added > 0 ? '' : 'none' ;
83- }
84-
85- const removedElement = element . querySelector < HTMLElement > ( '[data-stat="removed"]' ) ;
86- if ( removedElement ) {
87- removedElement . textContent = removed > 0 ? `-${ removed } ` : '' ;
88- removedElement . style . display = removed > 0 ? '' : 'none' ;
89- }
90- } ;
91-
92- const statsElementsByPath = new Map < string , Set < HTMLSpanElement > > ( ) ;
93-
94- export const updateChangesFileStats = ( path : string , added : number , removed : number ) => {
95- const elements = statsElementsByPath . get ( path ) ;
96- if ( ! elements ) {
97- return ;
98- }
99-
100- for ( const element of elements ) {
101- updateStatsElement ( element , added , removed ) ;
102- }
103- } ;
104-
10560interface ChangesPanelItemProps {
10661 rowId : string ;
10762 file : ChangedFile ;
@@ -114,23 +69,21 @@ interface ChangesPanelItemProps {
11469 onStage : ( path : string ) => void ;
11570 onUnstage : ( path : string ) => void ;
11671 setItemRef : ( rowId : string , element : HTMLDivElement | null ) => void ;
117- setStatsRef : ( path : string , element : HTMLSpanElement | null ) => void ;
11872}
11973
12074interface ChangesFileStatsProps {
121- path : string ;
122- setStatsRef : ( path : string , element : HTMLSpanElement | null ) => void ;
75+ added : number ;
76+ removed : number ;
12377}
12478
125- const ChangesFileStats = React . memo ( ( { path, setStatsRef } : ChangesFileStatsProps ) => {
126- const refCallback = useCallback ( ( element : HTMLSpanElement | null ) => {
127- setStatsRef ( path , element ) ;
128- } , [ path , setStatsRef ] ) ;
129-
79+ const ChangesFileStats = React . memo ( ( { added, removed } : ChangesFileStatsProps ) => {
80+ if ( added === 0 && removed === 0 ) {
81+ return null ;
82+ }
13083 return (
131- < span className = "changes-file-stats" ref = { refCallback } style = { { display : 'none' } } >
132- < span className = "changes-stat-added" data-stat = " added" />
133- < span className = "changes-stat-removed" data-stat = " removed" />
84+ < span className = "changes-file-stats" >
85+ { added > 0 && < span className = "changes-stat-added" > + { added } </ span > }
86+ { removed > 0 && < span className = "changes-stat-removed" > - { removed } </ span > }
13487 </ span >
13588 ) ;
13689} ) ;
@@ -148,7 +101,6 @@ const ChangesPanelItemImpl: React.FC<ChangesPanelItemProps> = ({
148101 onStage,
149102 onUnstage,
150103 setItemRef,
151- setStatsRef,
152104} ) => {
153105 const handleRevert = useCallback ( ( e : React . MouseEvent ) => {
154106 e . stopPropagation ( ) ;
@@ -213,7 +165,7 @@ const ChangesPanelItemImpl: React.FC<ChangesPanelItemProps> = ({
213165 { stageButtonLabel }
214166 </ button >
215167 </ div >
216- < ChangesFileStats path = { file . path } setStatsRef = { setStatsRef } />
168+ < ChangesFileStats added = { file . added ?? 0 } removed = { file . removed ?? 0 } />
217169 </ div >
218170 </ div >
219171 ) ;
@@ -233,8 +185,7 @@ const areChangesPanelItemsEqual = (
233185 && prev . onStage === next . onStage
234186 && prev . onUnstage === next . onUnstage
235187 && prev . setItemRef === next . setItemRef
236- && prev . setStatsRef === next . setStatsRef
237- && areChangedFileStructureEqual ( prev . file , next . file )
188+ && areChangedFileEqual ( prev . file , next . file )
238189) ;
239190
240191const ChangesPanelItem = React . memo ( ChangesPanelItemImpl , areChangesPanelItemsEqual ) ;
@@ -274,30 +225,6 @@ const ChangesPanelImpl: React.FC<ChangesPanelProps> = ({
274225 itemRefs . current . delete ( rowId ) ;
275226 } , [ ] ) ;
276227
277- const setStatsRef = useCallback ( ( path : string , element : HTMLSpanElement | null ) => {
278- const elements = statsElementsByPath . get ( path ) ;
279- if ( ! element ) {
280- elements ?. forEach ( ( existingElement ) => {
281- if ( ! existingElement . isConnected ) {
282- elements . delete ( existingElement ) ;
283- }
284- } ) ;
285- if ( elements ?. size === 0 ) {
286- statsElementsByPath . delete ( path ) ;
287- }
288- return ;
289- }
290-
291- if ( ! elements ) {
292- statsElementsByPath . set ( path , new Set ( [ element ] ) ) ;
293- return ;
294- }
295-
296- if ( element ) {
297- elements . add ( element ) ;
298- }
299- } , [ ] ) ;
300-
301228 const conflictingFiles = useMemo (
302229 ( ) => files . filter ( ( file ) => file . conflicted || file . status === 'conflict' ) ,
303230 [ files ] ,
@@ -330,16 +257,6 @@ const ChangesPanelImpl: React.FC<ChangesPanelProps> = ({
330257 const stagedStats = useMemo ( ( ) => countGroupStats ( stagedFiles ) , [ countGroupStats , stagedFiles ] ) ;
331258 const changedStats = useMemo ( ( ) => countGroupStats ( changedFiles ) , [ changedFiles , countGroupStats ] ) ;
332259
333- useLayoutEffect ( ( ) => {
334- for ( const row of displayedRows ) {
335- updateChangesFileStats (
336- row . file . path ,
337- row . file . added ?? 0 ,
338- row . file . removed ?? 0 ,
339- ) ;
340- }
341- } , [ displayedRows ] ) ;
342-
343260 useEffect ( ( ) => {
344261 if ( typeof window === 'undefined' ) return ;
345262 if ( message ) {
@@ -532,10 +449,9 @@ const ChangesPanelImpl: React.FC<ChangesPanelProps> = ({
532449 onStage = { onStage }
533450 onUnstage = { onUnstage }
534451 setItemRef = { setItemRef }
535- setStatsRef = { setStatsRef }
536452 />
537453 ) )
538- ) , [ activeFilePath , handleItemClick , onRevert , onStage , onUnstage , selectedRowId , setItemRef , setStatsRef , fileIconsStyle ] ) ;
454+ ) , [ activeFilePath , handleItemClick , onRevert , onStage , onUnstage , selectedRowId , setItemRef , fileIconsStyle ] ) ;
539455
540456 return (
541457 < div className = "changes-panel" >
0 commit comments