18
18
*/
19
19
import { Box , Code , VStack , IconButton } from "@chakra-ui/react" ;
20
20
import { useVirtualizer } from "@tanstack/react-virtual" ;
21
- import { useLayoutEffect , useRef } from "react" ;
21
+ import { useLayoutEffect , useMemo , useRef } from "react" ;
22
22
import { useHotkeys } from "react-hotkeys-hook" ;
23
23
import { useTranslation } from "react-i18next" ;
24
24
import { FiChevronDown , FiChevronUp } from "react-icons/fi" ;
@@ -63,7 +63,7 @@ const ScrollToButton = ({
63
63
} }
64
64
aria-label = { translate ( `scroll.direction.${ direction } ` ) }
65
65
bg = "bg.panel"
66
- bottom = { direction === "bottom" ? 2 : 12 }
66
+ bottom = { direction === "bottom" ? 4 : 14 }
67
67
onClick = { onClick }
68
68
position = "absolute"
69
69
rounded = "full"
@@ -86,20 +86,27 @@ export const TaskLogContent = ({ error, isLoading, logError, parsedLogs, wrap }:
86
86
overscan : 10 ,
87
87
} ) ;
88
88
89
+ const showScrollButtons = useMemo ( ( ) => {
90
+ const contentHeight = rowVirtualizer . getTotalSize ( ) ;
91
+ const containerHeight = rowVirtualizer . scrollElement ?. clientHeight ?? 0 ;
92
+
93
+ return contentHeight > containerHeight ;
94
+ } , [ rowVirtualizer ] ) ;
95
+
89
96
useLayoutEffect ( ( ) => {
90
97
if ( location . hash && ! isLoading ) {
91
- rowVirtualizer . scrollToIndex ( Number ( hash ) ) ;
98
+ rowVirtualizer . scrollToIndex ( Math . min ( Number ( hash ) + 5 , parsedLogs . length - 1 ) ) ;
92
99
}
93
- } , [ isLoading , rowVirtualizer , hash ] ) ;
100
+ } , [ isLoading , rowVirtualizer , hash , parsedLogs ] ) ;
94
101
95
102
const handleScrollTo = ( to : "bottom" | "top" ) => {
96
103
if ( parsedLogs . length > 0 ) {
97
104
rowVirtualizer . scrollToIndex ( to === "bottom" ? parsedLogs . length - 1 : 0 ) ;
98
105
}
99
106
} ;
100
107
101
- useHotkeys ( "ArrowDown" , ( ) => handleScrollTo ( "bottom" ) , { enabled : ! isLoading } ) ;
102
- useHotkeys ( "ArrowUp" , ( ) => handleScrollTo ( "top" ) , { enabled : ! isLoading } ) ;
108
+ useHotkeys ( "mod+ ArrowDown" , ( ) => handleScrollTo ( "bottom" ) , { enabled : ! isLoading } ) ;
109
+ useHotkeys ( "mod+ ArrowUp" , ( ) => handleScrollTo ( "top" ) , { enabled : ! isLoading } ) ;
103
110
104
111
return (
105
112
< Box display = "flex" flexDirection = "column" flexGrow = { 1 } h = "100%" minHeight = { 0 } position = "relative" >
@@ -148,8 +155,12 @@ export const TaskLogContent = ({ error, isLoading, logError, parsedLogs, wrap }:
148
155
</ VStack >
149
156
</ Code >
150
157
151
- < ScrollToButton direction = "top" onClick = { ( ) => handleScrollTo ( "top" ) } />
152
- < ScrollToButton direction = "bottom" onClick = { ( ) => handleScrollTo ( "bottom" ) } />
158
+ { showScrollButtons ? (
159
+ < >
160
+ < ScrollToButton direction = "top" onClick = { ( ) => handleScrollTo ( "top" ) } />
161
+ < ScrollToButton direction = "bottom" onClick = { ( ) => handleScrollTo ( "bottom" ) } />
162
+ </ >
163
+ ) : undefined }
153
164
</ Box >
154
165
) ;
155
166
} ;
0 commit comments