From faa13f58e0bf51dd63d70053ab68cc685b25017c Mon Sep 17 00:00:00 2001 From: jialin Date: Fri, 17 Jan 2025 21:21:21 +0800 Subject: [PATCH] fix: catalog form meta data update --- src/components/logs-viewer/index.tsx | 4 +- src/components/logs-viewer/logs-list.tsx | 4 +- src/config/global.d.ts | 4 ++ src/hooks/use-body-scroll.ts | 60 +++++++++++++++++++ src/hooks/use-overlay-scroller.ts | 16 +++-- src/layouts/index.tsx | 7 ++- src/locales/zh-CN/common.ts | 2 +- .../llmodels/components/advance-config.tsx | 14 ++++- src/pages/llmodels/index.tsx | 37 ++++++++++++ 9 files changed, 138 insertions(+), 10 deletions(-) create mode 100644 src/hooks/use-body-scroll.ts diff --git a/src/components/logs-viewer/index.tsx b/src/components/logs-viewer/index.tsx index d8894591..abc42d69 100644 --- a/src/components/logs-viewer/index.tsx +++ b/src/components/logs-viewer/index.tsx @@ -24,7 +24,9 @@ const LogsViewer: React.FC = (props) => { instance, initialized } = useOverlayScroller({ - theme: 'os-theme-light' + options: { + theme: 'os-theme-light' + } }); const { isClean, parseAnsi } = useParseAnsi(); const { setChunkFetch } = useSetChunkFetch(); diff --git a/src/components/logs-viewer/logs-list.tsx b/src/components/logs-viewer/logs-list.tsx index 0b9d200a..4449cf17 100644 --- a/src/components/logs-viewer/logs-list.tsx +++ b/src/components/logs-viewer/logs-list.tsx @@ -30,7 +30,9 @@ const LogsList: React.FC = forwardRef((props, ref) => { instance, initialized } = useOverlayScroller({ - theme: 'os-theme-light' + options: { + theme: 'os-theme-light' + } }); const viewportHeight = window.innerHeight; const viewHeight = viewportHeight - diffHeight; diff --git a/src/config/global.d.ts b/src/config/global.d.ts index 14086252..4af3812c 100644 --- a/src/config/global.d.ts +++ b/src/config/global.d.ts @@ -43,3 +43,7 @@ declare namespace Global { type SearchParams = Pagination & { search?: string }; } + +interface Window { + __GPUSTACK_BODY_SCROLLER__?: any; +} diff --git a/src/hooks/use-body-scroll.ts b/src/hooks/use-body-scroll.ts new file mode 100644 index 00000000..b1ddddf6 --- /dev/null +++ b/src/hooks/use-body-scroll.ts @@ -0,0 +1,60 @@ +import React from 'react'; + +export default function useBodyScroll() { + const scrollHeight = React.useRef(0); + const scrollerState = React.useRef({}); + + const bodyScroller = React.useRef(null); + + const instanceRef = React.useRef(null); + + const int = () => { + bodyScroller.current = + window.__GPUSTACK_BODY_SCROLLER__?.elements()?.scrollEventElement; + + instanceRef.current = window.__GPUSTACK_BODY_SCROLLER__; + }; + + const saveScrollHeight = React.useCallback(() => { + scrollerState.current = instanceRef.current?.state(); + + console.log('saveScrollHeight', scrollerState.current?.overflowAmount?.y); + + const scrollTop = scrollerState.current?.overflowAmount?.y; + scrollHeight.current = scrollTop; + instanceRef.current?.options?.({ + overflow: { + x: 'hidden', + y: 'visible' + } + }); + }, []); + + const restoreScrollHeight = React.useCallback(() => { + console.log('saveScrollHeight++++++++++', scrollHeight.current); + + bodyScroller.current?.scrollTo?.({ + top: scrollHeight.current, + behavior: 'smooth' + }); + + instanceRef.current?.options?.({ + overflow: { + x: 'hidden', + y: 'scroll' + } + }); + + instanceRef.current?.update?.(); + }, []); + + React.useEffect(() => { + int(); + return () => { + bodyScroller.current = null; + instanceRef.current = null; + }; + }, []); + + return { saveScrollHeight, restoreScrollHeight }; +} diff --git a/src/hooks/use-overlay-scroller.ts b/src/hooks/use-overlay-scroller.ts index bb4bb9d1..22a6a130 100644 --- a/src/hooks/use-overlay-scroller.ts +++ b/src/hooks/use-overlay-scroller.ts @@ -23,7 +23,12 @@ export const overlaySollerOptions: UseOverlayScrollbarsParams = { defer: true }; -export default function useOverlayScroller(options?: any) { +export default function useOverlayScroller(data?: { + options?: any; + events?: any; + defer?: boolean; +}) { + const { options, events, defer = true } = data || {}; const scrollEventElement = React.useRef(null); const instanceRef = React.useRef(null); const initialized = React.useRef(false); @@ -42,8 +47,10 @@ export default function useOverlayScroller(options?: any) { clickScroll: 'instant' } }, - - defer: true + events: { + ...events + }, + defer: defer }); instanceRef.current = instance?.(); @@ -99,7 +106,7 @@ export default function useOverlayScroller(options?: any) { const createInstance = React.useCallback( (el: any) => { if (instanceRef.current) { - return; + return instanceRef.current; } if (el) { initialize(el); @@ -108,6 +115,7 @@ export default function useOverlayScroller(options?: any) { scrollEventElement.current = instanceRef.current?.elements()?.scrollEventElement; } + return instanceRef.current; }, [initialize, instance] ); diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index 32622300..86ec2b12 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -94,7 +94,9 @@ const mapRoutes = (routes: IRoute[], role: string) => { }; export default (props: any) => { - const { initialize: initialize } = useOverlayScroller(); + const { initialize: initialize } = useOverlayScroller({ + defer: false + }); const { initialize: initializeMenu } = useOverlayScroller(); const [userInfo] = useAtom(userAtom); const [routeCache] = useAtom(routeCacheAtom); @@ -209,7 +211,8 @@ export default (props: any) => { useEffect(() => { const body = document.querySelector('body'); if (body) { - initialize(body); + const ins = initialize(body); + window.__GPUSTACK_BODY_SCROLLER__ = ins; } }, [initialize]); diff --git a/src/locales/zh-CN/common.ts b/src/locales/zh-CN/common.ts index c3c969d2..a1d44a64 100644 --- a/src/locales/zh-CN/common.ts +++ b/src/locales/zh-CN/common.ts @@ -210,7 +210,7 @@ export default { 'common.text.new': '新', 'common.text.changelog': '更新日志', 'common.button.recreate': '重新创建', - 'common.button.delrecreate': '删除(重建)', + 'common.button.delrecreate': '删除(重建)', 'common.options.all': '全部', 'common.options.none': '无', 'common.options.auto': '自动' diff --git a/src/pages/llmodels/components/advance-config.tsx b/src/pages/llmodels/components/advance-config.tsx index 192e426b..25ec1918 100644 --- a/src/pages/llmodels/components/advance-config.tsx +++ b/src/pages/llmodels/components/advance-config.tsx @@ -44,6 +44,12 @@ const AdvanceConfig: React.FC = (props) => { const wokerSelector = Form.useWatch('worker_selector', form); const scheduleType = Form.useWatch('scheduleType', form); const backend = Form.useWatch('backend', form); + const backend_parameters = Form.useWatch('backend_parameters', form); + const categories = Form.useWatch('categories', form); + const backend_version = Form.useWatch('backend_version', form); + const placement_strategy = Form.useWatch('placement_strategy', form); + const gpuSelectorIds = Form.useWatch('gpu_selector.gpu_ids', form); + const worker_selector = Form.useWatch('worker_selector', form); const placementStrategyTips = [ { @@ -371,7 +377,13 @@ const AdvanceConfig: React.FC = (props) => { scheduleType, wokerSelector, backend, - isGGUF + backend_parameters, + isGGUF, + categories, + backend_version, + placement_strategy, + gpuSelectorIds, + worker_selector ]); return ( diff --git a/src/pages/llmodels/index.tsx b/src/pages/llmodels/index.tsx index 97fd5601..54955a0f 100644 --- a/src/pages/llmodels/index.tsx +++ b/src/pages/llmodels/index.tsx @@ -29,6 +29,7 @@ const Models: React.FC = () => { loading: false, total: 0 }); + const [pageHidden, setPageHidden] = useState(false); const [gpuDeviceList, setGpuDeviceList] = useState([]); const [workerList, setWorkerList] = useState([]); const [firstLoad, setFirstLoad] = useState(true); @@ -122,6 +123,10 @@ const Models: React.FC = () => { const updateInstanceHandler = (list: any) => { setModelInstances(list); + window.postMessage( + { type: 'modelInstance', data: list }, + window.location.origin + ); }; const createModelsChunkRequest = useCallback(async () => { @@ -242,6 +247,38 @@ const Models: React.FC = () => { }; }, [fetchData, createModelsChunkRequest, createModelsInstanceChunkRequest]); + useEffect(() => { + const handleOnWindowMessage = (event: any) => { + const data = event.data; + console.log( + 'event.origin=======', + event.origin !== window.location.origin || + data.type !== 'modelInstance', + data, + event.origin, + window.location.origin + ); + + if ( + event.origin !== window.location.origin || + data.type !== 'modelInstance' + ) { + return; + } + + if (document.visibilityState === 'hidden') { + console.log('isPageHidden=======', document.visibilityState, data.data); + + setModelInstances(data.data); + } + }; + + window.addEventListener('message', handleOnWindowMessage); + return () => { + window.removeEventListener('message', handleOnWindowMessage); + }; + }, []); + return (