diff --git a/src/hooks/use-actions.ts b/src/hooks/use-actions.ts deleted file mode 100644 index 7ea80d5b..00000000 --- a/src/hooks/use-actions.ts +++ /dev/null @@ -1,10 +0,0 @@ -export default function useActions(actions: Global.ActionItem[], ctx: T) { - return actions - .filter((action) => { - return action.visible ? action.visible(ctx) : true; - }) - .map((action) => ({ - ...action, - disabled: action.disabled?.(ctx) - })); -} diff --git a/src/hooks/use-app-utils.ts b/src/hooks/use-app-utils.ts deleted file mode 100644 index 8a59a47a..00000000 --- a/src/hooks/use-app-utils.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { useIntl } from '@umijs/max'; -import { message } from 'antd'; - -type MessageType = 'input' | 'select'; - -const useAppUtils = () => { - const intl = useIntl(); - const [messageApi, contextHolder] = message.useMessage(); - - /** - * - * @param type Array<'input' | 'select'> - * @param name - * @param locale boolean - * @returns - */ - const getRuleMessage = ( - type: MessageType | MessageType[], - name: string, - locale = true - ) => { - const nameStr = locale ? intl.formatMessage({ id: name }) : name; - // transform type to array - const typeList = Array.isArray(type) ? type : [type]; - - if (typeList.includes('select') && typeList.includes('input')) { - return intl.formatMessage( - { id: 'common.form.rule.selectInput' }, - { name: nameStr } - ); - } - - if (typeList.includes('input')) { - return intl.formatMessage( - { id: 'common.form.rule.input' }, - { name: nameStr } - ); - } - - return intl.formatMessage( - { id: 'common.form.rule.select' }, - { name: nameStr } - ); - }; - - const showSuccess = (msg?: string) => { - messageApi.success( - msg || intl.formatMessage({ id: 'common.message.success' }) - ); - }; - - return { - getRuleMessage, - showSuccess - }; -}; - -export default useAppUtils; diff --git a/src/hooks/use-broadcast.ts b/src/hooks/use-broadcast.ts deleted file mode 100644 index 892682c1..00000000 --- a/src/hooks/use-broadcast.ts +++ /dev/null @@ -1,18 +0,0 @@ -// broadcast channel hook - -import { useEffect, useRef } from 'react'; - -export const useBroadcast = () => { - const broadcastChannel = useRef(null); - - useEffect(() => { - broadcastChannel.current = new BroadcastChannel('broadcast_channel'); - - return () => { - broadcastChannel.current?.close(); - console.log('broadcast channel closed'); - }; - }, []); - - return { broadcastChannel }; -}; diff --git a/src/hooks/use-container-scorll.ts b/src/hooks/use-container-scorll.ts deleted file mode 100644 index 58ae0efe..00000000 --- a/src/hooks/use-container-scorll.ts +++ /dev/null @@ -1,56 +0,0 @@ -import _ from 'lodash'; -import { useRef } from 'react'; - -export default function useContainerScroll( - container: any, - options?: { toBottom?: boolean } -) { - const isWheeled = useRef(false); - const scroller = useRef(container); - const optionsRef = useRef(options); - const toBottomFlag = useRef(options?.toBottom); - const timerRef = useRef(null); - - const debunceResetWheeled = _.debounce(() => { - isWheeled.current = false; - }, 5000); - - const handleContentWheel = (e: any) => { - isWheeled.current = true; - debunceResetWheeled.cancel?.(); - debunceResetWheeled(); - }; - - const scrollerRun = () => { - const scrollerContainer = scroller.current?.current || {}; - const { scrollHeight, clientHeight, scrollTop } = scrollerContainer; - if ( - optionsRef.current?.toBottom && - toBottomFlag.current && - scrollHeight > clientHeight + scrollTop - ) { - scroller.current.current.scrollTop = scrollHeight; - // toBottomFlag.current = false; - isWheeled.current = false; - } else if ( - !isWheeled.current && - scrollHeight > clientHeight + scrollTop && - scroller.current?.current - ) { - scroller.current.current.scrollTop += 10; - window.requestAnimationFrame(scrollerRun); - } - }; - - const updateScrollerPosition = () => { - if (!isWheeled.current) { - window.requestAnimationFrame(scrollerRun); - } - }; - - return { - handleContentWheel, - updateScrollerPosition, - scroller - }; -} diff --git a/src/hooks/use-copy-to-clipboard.ts b/src/hooks/use-copy-to-clipboard.ts deleted file mode 100644 index a690f0b6..00000000 --- a/src/hooks/use-copy-to-clipboard.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { useCallback, useState } from 'react'; - -const useCopyToClipboard = () => { - const [copied, setCopied] = useState(false); - - const copyToClipboard = useCallback(async (text: string) => { - try { - if (navigator.clipboard) { - await navigator.clipboard.writeText(text); - setCopied(true); - setTimeout(() => { - setCopied(false); - }, 3000); - } - } catch (error) { - setCopied(false); - } - }, []); - - return { copied, copyToClipboard }; -}; - -export default useCopyToClipboard; diff --git a/src/hooks/use-download-logs.tsx b/src/hooks/use-download-logs.tsx deleted file mode 100644 index ba2db93b..00000000 --- a/src/hooks/use-download-logs.tsx +++ /dev/null @@ -1,71 +0,0 @@ -import { HandlerOptions } from '@/hooks/use-chunk-fetch'; -import { useDownloadStream } from '@gpustack/core-ui'; -import { useIntl } from '@umijs/max'; -import { Progress, notification } from 'antd'; -import dayjs from 'dayjs'; - -const renderMessage = (title: string) => { - return ( -
- {title} -
- ); -}; - -const createFileName = (name: string) => { - const timestamp = dayjs().format('YYYY-MM-DD_HH-mm-ss'); - const fileName = `${name}_${timestamp}.txt`; - return fileName; -}; - -const useDownloadLogs = () => { - const { downloadStream } = useDownloadStream(); - const intl = useIntl(); - const [api, contextHolder] = notification.useNotification({ - stack: { threshold: 1 } - }); - - const downloadNotification = ( - data: HandlerOptions & { - filename: string; - duration?: number; - chunkRequestRef: any; - } - ) => { - api.open({ - duration: data.duration, - message: renderMessage(data.filename), - key: data.filename, - closeIcon: ( - {intl.formatMessage({ id: 'common.button.cancel' })} - ), - description: , - onClose() { - data.chunkRequestRef?.current?.abort(); - notification.destroy?.(data.filename); - } - }); - }; - - const handleDownloadLog = async (params: { url: string; name: string }) => { - downloadStream({ - url: params.url, - filename: createFileName(params.name), - downloadNotification - }); - }; - - return { - onDownloadLog: handleDownloadLog, - contextHolder - }; -}; - -export default useDownloadLogs; diff --git a/src/hooks/use-download-stream.ts b/src/hooks/use-download-stream.ts deleted file mode 100644 index e10b19f2..00000000 --- a/src/hooks/use-download-stream.ts +++ /dev/null @@ -1,136 +0,0 @@ -import useSetChunkFetch, { HandlerOptions } from '@/hooks/use-chunk-fetch'; -import { message } from 'antd'; -import { useEffect, useRef } from 'react'; - -export default function useDownloadStream() { - const chunkRequestRef = useRef(null); - const logParseWorker = useRef(null); - const clearScreen = useRef(false); - const filename = useRef('log'); - const downloadNotificationRef = useRef(null); - - const { setChunkFetch } = useSetChunkFetch(); - - const downloadFile = (content: string) => { - const blob = new Blob([content], { type: 'text/plain' }); - const url = URL.createObjectURL(blob); - - const a = document.createElement('a'); - a.href = url; - a.download = filename.current; - document.body.appendChild(a); - a.click(); - document.body.removeChild(a); - - URL.revokeObjectURL(url); - }; - - const updateContent = (data: string, options?: HandlerOptions) => { - const { isComplete, percent } = options || {}; - - logParseWorker.current?.postMessage({ - inputStr: data, - reset: clearScreen.current, - isComplete: isComplete, - percent: percent, - chunked: false - }); - clearScreen.current = false; - }; - - const handleError = (error: any) => { - const errorMsg = error?.message || error; - const msg = - typeof errorMsg === 'string' ? errorMsg : JSON.stringify(errorMsg); - message.error(msg); - downloadNotificationRef.current?.({ - duration: 1, - percent: 0, - filename: filename.current - }); - }; - - const downloadStream = async (props: { - data?: any; - url: string; - params?: any; - signal?: AbortSignal; - method?: string; - headers?: any; - filename?: string; - downloadNotification?: (data: any) => void; - }) => { - try { - clearScreen.current = true; - filename.current = props.filename || 'log'; - downloadNotificationRef.current = props.downloadNotification; - const { params, url } = props; - - chunkRequestRef.current?.current?.abort?.(); - - chunkRequestRef.current = setChunkFetch({ - url, - params, - watch: false, - contentType: 'text', - errorHandler: handleError, - handler: updateContent - }); - downloadNotificationRef.current?.({ - filename: filename.current, - duration: null, - chunkRequestRef: chunkRequestRef.current - }); - } catch (error) { - // - downloadNotificationRef.current?.({ - duration: 1, - percent: 0, - filename: filename.current - }); - } - }; - - useEffect(() => { - logParseWorker.current?.terminate?.(); - - logParseWorker.current = new Worker( - // @ts-ignore - new URL('@/components/logs-viewer/parse-worker.ts', import.meta.url), - { - type: 'module' - } - ); - - logParseWorker.current.onmessage = (event: any) => { - const { result, isComplete, percent } = event.data; - - const isAborted = chunkRequestRef.current?.current?.signal?.aborted; - if (!isComplete && !isAborted) { - downloadNotificationRef.current?.({ - percent: percent, - duration: null, - filename: filename.current, - chunkRequestRef: chunkRequestRef.current - }); - } else if (isComplete && !isAborted) { - downloadNotificationRef.current?.({ - duration: 1, - percent: 100, - filename: filename.current - }); - downloadFile(result); - } - }; - - return () => { - if (logParseWorker.current) { - logParseWorker.current.terminate(); - } - }; - }, []); - - return { - downloadStream - }; -} diff --git a/src/hooks/use-esc-hint.tsx b/src/hooks/use-esc-hint.tsx deleted file mode 100644 index 158ae002..00000000 --- a/src/hooks/use-esc-hint.tsx +++ /dev/null @@ -1,106 +0,0 @@ -import HotKeys from '@/config/hotkeys'; -import { useIntl } from '@umijs/max'; -import { createStyles } from 'antd-style'; -import { throttle } from 'lodash'; -import { useEffect, useMemo, useRef, useState } from 'react'; -import { useHotkeys } from 'react-hotkeys-hook'; - -const useStyles = createStyles(({ css, token }) => ({ - hintOverlay: css` - position: fixed; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - background: var(--color-esc-hint-bg); - color: ${token.colorTextLightSolid}; - padding: 16px 24px; - border-radius: 4px; - z-index: 2000; - font-size: 14px; - pointer-events: none; - animation: fadeInOut 2s ease-in-out; - @keyframes fadeInOut { - 0% { - opacity: 0; - } - 10% { - opacity: 1; - } - 90% { - opacity: 1; - } - 100% { - opacity: 0; - } - } - ` -})); - -export function useEscHint(options?: { - enabled?: boolean; - message?: string; - throttleDelay?: number; -}) { - const { enabled = true, message, throttleDelay = 3000 } = options || {}; - const intl = useIntl(); - const { styles } = useStyles(); - const [visible, setVisible] = useState(false); - const timeoutRef = useRef(null); - const isHintActiveRef = useRef(false); - - const showHintThrottled = useMemo( - () => - throttle( - () => { - if (isHintActiveRef.current) return; - - isHintActiveRef.current = true; - - setVisible(true); - - if (timeoutRef.current) { - clearTimeout(timeoutRef.current); - } - - timeoutRef.current = setTimeout(() => { - setVisible(false); - isHintActiveRef.current = false; - }, 2000); - }, - throttleDelay, - { - leading: true, - trailing: false - } - ), - [throttleDelay] - ); - - useHotkeys( - HotKeys.ESC, - () => { - if (!enabled) return; - showHintThrottled(); - }, - { - enabled: enabled - } - ); - - useEffect(() => { - return () => { - if (timeoutRef.current) { - clearTimeout(timeoutRef.current); - } - showHintThrottled.cancel(); - }; - }, [showHintThrottled]); - - const EscHint = visible ? ( -
- {message || intl.formatMessage({ id: 'common.tips.escape.disable' })} -
- ) : null; - - return { EscHint }; -} diff --git a/src/hooks/use-event-source.ts b/src/hooks/use-event-source.ts deleted file mode 100644 index cd543d18..00000000 --- a/src/hooks/use-event-source.ts +++ /dev/null @@ -1,72 +0,0 @@ -import qs from 'query-string'; -import { useEffect, useRef } from 'react'; - -export const createEventSourceURL = (url: string) => { - const { host, protocol } = window.location; - return `${protocol}://${host}${url}`; -}; - -/* -0: connecting -1: connect successfully -2: closed -*/ - -export default function useEventSource() { - const eventSourceRef = useRef(null); - - const createEventSourceConnection = (query: { - url: string; - params: any; - onmessage?: (data: any) => void; - }) => { - eventSourceRef.current?.close?.(); - - const { url, params, onmessage = () => {} } = query; - - const sseurl = createEventSourceURL(url); - - eventSourceRef.current = new EventSource( - `${url}?${qs.stringify({ - ...params - })}`, - { - withCredentials: true - } - ); - - eventSourceRef.current.onmessage = (res: any) => { - try { - console.log('event source message: ', { res, resData: res }); - const data = JSON.parse(res.data); - onmessage(data); - } catch (error) { - // error - console.log('event source error: ', error); - } - }; - - eventSourceRef.current.onclose = () => { - console.log('event source closed...'); - }; - - eventSourceRef.current.onopen = () => { - console.log('event source connected...'); - }; - - eventSourceRef.current.onerror = (error: any) => { - console.log('event source error: ', error); - }; - }; - - useEffect(() => { - return () => { - eventSourceRef.current?.close?.(); - }; - }, []); - - return { - eventSourceRef: eventSourceRef, - createEventSourceConnection - }; -} diff --git a/src/hooks/use-overlay-scroller.ts b/src/hooks/use-overlay-scroller.ts deleted file mode 100644 index 051948a4..00000000 --- a/src/hooks/use-overlay-scroller.ts +++ /dev/null @@ -1,280 +0,0 @@ -import { useMemoizedFn } from 'ahooks'; -import { throttle } from 'lodash'; -import { - UseOverlayScrollbarsParams, - useOverlayScrollbars -} from 'overlayscrollbars-react'; -import React, { useEffect } from 'react'; -import useUserSettings from './use-user-settings'; - -type OverflowBehavior = - | 'hidden' - | 'scroll' - | 'visible' - | 'visible-hidden' - | 'visible-scroll'; -export interface OverlayScrollerOptions { - oppositeTheme?: boolean; - overflow?: { - x?: OverflowBehavior; - y?: OverflowBehavior; - }; - scrollbars?: { - theme?: 'os-theme-light' | 'os-theme-dark'; - autoHide?: 'never' | 'scroll' | 'leave' | 'move'; - autoHideDelay?: number; - clickScroll?: boolean | 'instant'; - }; -} - -export const overlaySollerOptions: UseOverlayScrollbarsParams = { - options: { - update: { - debounce: 0 - }, - overflow: { - x: 'hidden' - }, - scrollbars: { - theme: 'os-theme-light', - autoHide: 'scroll', - autoHideDelay: 600, - clickScroll: 'instant' - } - }, - defer: true -}; - -const RESETSCROLLDELAY = 5000; - -/** - * - * @param options.theme: if set theme, it will fix the theme - * @returns - */ -export default function useOverlayScroller(data?: { - options?: OverlayScrollerOptions; - events?: any; - defer?: boolean; -}) { - const { userSettings } = useUserSettings(); - const { options, events, defer = true } = data || {}; - const { scrollbars, overflow, oppositeTheme } = options || {}; - const scrollEventElement = React.useRef(null); - const instanceRef = React.useRef(null); - const initialized = React.useRef(false); - const scrollElementRef = React.useRef(null); - const stopUpdatePosition = React.useRef(false); - const timerRef = React.useRef(null); - const [initialize, instance] = useOverlayScrollbars({ - options: { - update: { - debounce: 0 - }, - overflow: { - x: 'hidden', - ...overflow - }, - scrollbars: { - autoHide: 'scroll', - autoHideDelay: 600, - clickScroll: 'instant', - ...scrollbars, - theme: - scrollbars?.theme || - (userSettings.theme === 'light' || !userSettings.theme - ? 'os-theme-dark' - : 'os-theme-light') - } - }, - events: { - ...events - }, - defer: defer - }); - - instanceRef.current = instance?.(); - scrollEventElement.current = - instanceRef.current?.elements()?.scrollEventElement; - - const handleOnScroll = () => { - const scrollTop = scrollEventElement.current?.scrollTop; - const scrollHeight = scrollEventElement.current?.scrollHeight; - const clientHeight = scrollEventElement.current?.clientHeight; - - const isBottom = scrollTop + clientHeight + 20 >= scrollHeight; - - if (isBottom) { - stopUpdatePosition.current = false; - } else { - stopUpdatePosition.current = true; - } - }; - - const throttledScroll = useMemoizedFn( - throttle(() => { - scrollEventElement.current?.scrollTo?.({ - top: scrollEventElement.current?.scrollHeight, - behavior: 'smooth' - }); - instanceRef.current?.update?.(); - }, 100) - ); - - const scrollauto = useMemoizedFn(() => { - scrollEventElement.current?.scrollTo?.({ - top: scrollEventElement.current.scrollHeight, - behavior: 'auto' - }); - instanceRef.current?.update?.(); - }); - - // scroll to bottom - const throttledUpdateScrollerPosition = useMemoizedFn((delay?: number) => { - if (stopUpdatePosition.current) { - return; - } - if (delay === 0) { - scrollauto(); - } else { - throttledScroll(); - } - }); - - // scroll to top - const updateScrollerPositionToTop = useMemoizedFn(() => { - scrollEventElement.current?.scrollTo?.({ - top: 0, - behavior: 'auto' - }); - instanceRef.current?.update?.(); - }); - - const generateInstance = () => { - instanceRef.current = instance?.(); - scrollEventElement.current = - instanceRef.current?.elements()?.scrollEventElement; - }; - - const handleWheelCallback = useMemoizedFn((e: any) => { - handleOnScroll(); - if (timerRef.current) { - clearTimeout(timerRef.current); - } - timerRef.current = setTimeout(() => { - stopUpdatePosition.current = false; - }, RESETSCROLLDELAY); - }); - - // add wheel event - const handleWheelEvent = () => { - scrollElementRef.current?.addEventListener?.('wheel', handleWheelCallback, { - passive: true - }); - }; - - // remove wheel event - const removeWheelEvent = () => { - scrollElementRef.current?.removeEventListener?.( - 'wheel', - handleWheelCallback, - { passive: true } - ); - }; - - const createInstance = useMemoizedFn((el: any) => { - if (instanceRef.current) { - return instanceRef.current; - } - if (el) { - initialize(el); - scrollElementRef.current = el; - initialized.current = true; - instanceRef.current = instance?.(); - scrollEventElement.current = - instanceRef.current?.elements()?.scrollEventElement; - handleWheelEvent(); - } - return instanceRef.current; - }); - - const destroyInstance = () => { - instanceRef.current?.destroy?.(); - removeWheelEvent(); - instanceRef.current = null; - }; - - const scrollToTarget = (target: any, offset = 100) => { - if (!target) return; - if (!instanceRef.current || !scrollEventElement.current) { - instanceRef.current = instance?.(); - scrollEventElement.current = - instanceRef.current?.elements()?.scrollEventElement; - } - - const viewport = instanceRef.current?.elements().viewport; - const containerRect = viewport.getBoundingClientRect(); - const targetRect = target.getBoundingClientRect(); - - const scrollerState = instanceRef.current?.state(); - - const currentScroll = scrollerState.current?.overflowAmount?.y; - - // const currentScroll = instanceRef.current?.scroll().position.y; - const targetPos = targetRect.top - containerRect.top + currentScroll; - - scrollEventElement.current.scroll({ - y: targetPos - offset, - behavior: 'smooth' - }); - instanceRef.current?.update?.(); - }; - - const getScrollElementScrollableHeight = () => { - if (!instanceRef.current || !scrollEventElement.current) { - instanceRef.current = instance?.(); - scrollEventElement.current = - instanceRef.current?.elements()?.scrollEventElement; - } - - const scrollOffsetElement = instanceRef.current?.elements().viewport; - - return { - scrollTop: scrollOffsetElement?.scrollTop, - scrollHeight: - scrollOffsetElement?.scrollHeight - scrollOffsetElement?.clientHeight - }; - }; - - const getScrollElement = () => { - if (!instanceRef.current || !scrollEventElement.current) { - instanceRef.current = instance?.(); - scrollEventElement.current = - instanceRef.current?.elements()?.scrollEventElement; - } - return scrollEventElement; - }; - - useEffect(() => { - return () => { - instanceRef.current?.destroy?.(); - removeWheelEvent(); - }; - }, [instance]); - - return { - initialize: createInstance, - instance: instanceRef, - scrollEventElement: scrollEventElement, - initialized: initialized.current, - getScrollElementScrollableHeight, - getScrollElement, - generateInstance, - destroyInstance: destroyInstance, - updateScrollerPosition: throttledUpdateScrollerPosition, - updateScrollerPositionToTop: updateScrollerPositionToTop, - scrollToBottom: scrollauto, - scrollToTop: updateScrollerPositionToTop, - scrollToTarget - }; -}