fix: logs viewer do not scroll after opened

This commit is contained in:
jialin
2024-10-22 15:36:53 +08:00
parent a0a1b8b3e8
commit 902bb06353
7 changed files with 80 additions and 18 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ import { IApi } from '@umijs/max';
export default (api: IApi) => { export default (api: IApi) => {
api.modifyHTML(($) => { api.modifyHTML(($) => {
const info = JSON.parse(process.env.VERSION || '{}'); const info = JSON.parse(process.env.VERSION || '{}');
const env = info.version ? 'production' : 'development'; const env = process.env.NODE_ENV;
$('html').attr('data-env', env); $('html').attr('data-env', env);
+29 -8
View File
@@ -15,8 +15,14 @@ interface LogsViewerProps {
} }
const LogsViewer: React.FC<LogsViewerProps> = (props) => { const LogsViewer: React.FC<LogsViewerProps> = (props) => {
const { height, url } = props; const { height, url } = props;
const { initialize, updateScrollerPosition, scrollEventElement } = const {
useOverlayScroller({ initialize,
updateScrollerPosition,
generateInstance,
scrollEventElement,
instance,
initialized
} = useOverlayScroller({
theme: 'os-theme-light' theme: 'os-theme-light'
}); });
const { isClean, parseAnsi } = useParseAnsi(); const { isClean, parseAnsi } = useParseAnsi();
@@ -62,11 +68,12 @@ const LogsViewer: React.FC<LogsViewerProps> = (props) => {
const debounceResetStopScroll = _.debounce(() => { const debounceResetStopScroll = _.debounce(() => {
stopScroll.current = false; stopScroll.current = false;
}, 30000); }, 30000);
const handleOnWheel = useCallback( const handleOnWheel = useCallback(
(e: any) => { (e: any) => {
const scrollTop = scrollEventElement.scrollTop; const scrollTop = scrollEventElement?.scrollTop;
const scrollHeight = scrollEventElement.scrollHeight; const scrollHeight = scrollEventElement?.scrollHeight;
const clientHeight = scrollEventElement.clientHeight; const clientHeight = scrollEventElement?.clientHeight;
if (scrollTop + clientHeight >= scrollHeight) { if (scrollTop + clientHeight >= scrollHeight) {
stopScroll.current = false; stopScroll.current = false;
} else { } else {
@@ -74,9 +81,14 @@ const LogsViewer: React.FC<LogsViewerProps> = (props) => {
} }
debounceResetStopScroll(); debounceResetStopScroll();
}, },
[debounceResetStopScroll] [debounceResetStopScroll, scrollEventElement]
); );
const debounceUpdateScrollerPosition = _.debounce(() => {
generateInstance();
updateScrollerPosition(0);
}, 200);
useEffect(() => { useEffect(() => {
createChunkConnection(); createChunkConnection();
return () => { return () => {
@@ -91,10 +103,19 @@ const LogsViewer: React.FC<LogsViewerProps> = (props) => {
}, [scroller.current, initialize]); }, [scroller.current, initialize]);
useEffect(() => { useEffect(() => {
if (logs.length && !stopScroll.current) { if (logs.length && !stopScroll.current && instance) {
updateScrollerPosition(0);
} else if (logs.length && !stopScroll.current && scroller.current) {
if (!initialized) {
initialize(scroller.current);
}
if (!instance) {
debounceUpdateScrollerPosition();
} else {
updateScrollerPosition(0); updateScrollerPosition(0);
} }
}, [logs, stopScroll.current]); }
}, [logs, stopScroll.current, instance, scroller.current]);
return ( return (
<div className="logs-viewer-wrap-w2"> <div className="logs-viewer-wrap-w2">
+4 -3
View File
@@ -10,8 +10,7 @@ const VersionInfo: React.FC<{ intl: any }> = ({ intl }) => {
const latestVersion = getAtomStorage(UpdateCheckAtom).latest_version; const latestVersion = getAtomStorage(UpdateCheckAtom).latest_version;
const currentVersion = getAtomStorage(GPUStackVersionAtom)?.version; const currentVersion = getAtomStorage(GPUStackVersionAtom)?.version;
const isProd = const isProd = currentVersion !== '0.0.0';
document.documentElement.getAttribute('data-env') === 'production';
const uiVersion = document.documentElement.getAttribute('data-version'); const uiVersion = document.documentElement.getAttribute('data-version');
@@ -51,7 +50,9 @@ const VersionInfo: React.FC<{ intl: any }> = ({ intl }) => {
{getAtomStorage(userAtom)?.is_admin && ( {getAtomStorage(userAtom)?.is_admin && (
<div className="upgrade"> <div className="upgrade">
<span className="m-l-5"> <span className="m-l-5">
{latestVersion && latestVersion !== currentVersion {latestVersion &&
latestVersion !== currentVersion &&
latestVersion !== '0.0.0'
? intl.formatMessage( ? intl.formatMessage(
{ id: 'users.version.update' }, { id: 'users.version.update' },
{ version: latestVersion } { version: latestVersion }
+22
View File
@@ -509,6 +509,28 @@ body {
border-radius: 8px; border-radius: 8px;
} }
.ant-modal-centered.ant-modal-wrap {
&::-webkit-scrollbar {
width: var(--scrollbar-size);
}
&::-webkit-scrollbar-thumb {
background-color: transparent;
border-radius: 4px;
}
&::-webkit-scrollbar-track {
background-color: transparent;
}
&:hover {
&::-webkit-scrollbar-thumb {
background-color: var(--scrollbar-handle-bg);
border-radius: 4px;
}
}
}
.custome-scrollbar { .custome-scrollbar {
&::-webkit-scrollbar { &::-webkit-scrollbar {
width: var(--scrollbar-size); width: var(--scrollbar-size);
+20 -2
View File
@@ -1,7 +1,7 @@
import { throttle } from 'lodash'; import { throttle } from 'lodash';
import { import {
useOverlayScrollbars, UseOverlayScrollbarsParams,
UseOverlayScrollbarsParams useOverlayScrollbars
} from 'overlayscrollbars-react'; } from 'overlayscrollbars-react';
import React from 'react'; import React from 'react';
@@ -26,6 +26,7 @@ export const overlaySollerOptions: UseOverlayScrollbarsParams = {
export default function useOverlayScroller(options?: any) { export default function useOverlayScroller(options?: any) {
const scrollEventElement = React.useRef<any>(null); const scrollEventElement = React.useRef<any>(null);
const instanceRef = React.useRef<any>(null); const instanceRef = React.useRef<any>(null);
const initialized = React.useRef(false);
const [initialize, instance] = useOverlayScrollbars({ const [initialize, instance] = useOverlayScrollbars({
options: { options: {
update: { update: {
@@ -43,6 +44,7 @@ export default function useOverlayScroller(options?: any) {
}, },
defer: true defer: true
}); });
instanceRef.current = instance?.(); instanceRef.current = instance?.();
scrollEventElement.current = scrollEventElement.current =
instanceRef.current?.elements()?.scrollEventElement; instanceRef.current?.elements()?.scrollEventElement;
@@ -78,6 +80,12 @@ export default function useOverlayScroller(options?: any) {
[throttledScroll, scrollauto] [throttledScroll, scrollauto]
); );
const generateInstance = () => {
instanceRef.current = instance?.();
scrollEventElement.current =
instanceRef.current?.elements()?.scrollEventElement;
};
const createInstance = React.useCallback( const createInstance = React.useCallback(
(el: any) => { (el: any) => {
if (instanceRef.current) { if (instanceRef.current) {
@@ -85,6 +93,14 @@ export default function useOverlayScroller(options?: any) {
} }
if (el) { if (el) {
initialize(el); initialize(el);
initialized.current = true;
console.log(
'createInstance===2',
initialized.current,
instanceRef.current,
instance?.(),
instance
);
instanceRef.current = instance?.(); instanceRef.current = instance?.();
scrollEventElement.current = scrollEventElement.current =
instanceRef.current?.elements()?.scrollEventElement; instanceRef.current?.elements()?.scrollEventElement;
@@ -97,6 +113,8 @@ export default function useOverlayScroller(options?: any) {
initialize: createInstance, initialize: createInstance,
instance: instanceRef.current, instance: instanceRef.current,
scrollEventElement: scrollEventElement.current, scrollEventElement: scrollEventElement.current,
initialized: initialized.current,
generateInstance,
updateScrollerPosition: throttledUpdateScrollerPosition updateScrollerPosition: throttledUpdateScrollerPosition
}; };
} }
+1 -1
View File
@@ -26,6 +26,6 @@ export default {
'users.password.confirm.empty': 'Please confirm the new password.', 'users.password.confirm.empty': 'Please confirm the new password.',
'users.password.confirm.error': 'The two passwords entered do not match.', 'users.password.confirm.error': 'The two passwords entered do not match.',
'users.login.title': 'Log in to {name}', 'users.login.title': 'Log in to {name}',
'users.version.islatest': '{version} is the latest version', 'users.version.islatest': 'GPUStack {version} is the latest version',
'users.version.update': 'GPUStack {version} is available' 'users.version.update': 'GPUStack {version} is available'
}; };
+1 -1
View File
@@ -25,6 +25,6 @@ export default {
'users.password.confirm.empty': '请确认新密码', 'users.password.confirm.empty': '请确认新密码',
'users.password.confirm.error': '两次输入的密码不一致', 'users.password.confirm.error': '两次输入的密码不一致',
'users.login.title': '登录 {name}', 'users.login.title': '登录 {name}',
'users.version.islatest': '{version} 已是最新版本', 'users.version.islatest': 'GPUStack {version} 已是最新版本',
'users.version.update': 'GPUStack {version} 版本可供更新' 'users.version.update': 'GPUStack {version} 版本可供更新'
}; };