diff --git a/web/src/i18n/locales/en.ts b/web/src/i18n/locales/en.ts index d776aa6..03b4290 100644 --- a/web/src/i18n/locales/en.ts +++ b/web/src/i18n/locales/en.ts @@ -47,6 +47,7 @@ const en = { finishBtn: 'Finished' }, screen: { + title: 'Screen', video: 'Video Mode', resolution: 'Resolution', auto: 'Automatic', @@ -65,6 +66,7 @@ const en = { resetHdmi: 'Reset HDMI' }, keyboard: { + title: 'Keyboard', paste: 'Paste', tips: 'Only standard keyboard letters and symbols are supported', placeholder: 'Please input', @@ -73,6 +75,7 @@ const en = { ctrlaltdel: 'Ctrl+Alt+Del' }, mouse: { + title: 'Mouse', default: 'Default cursor', pointer: 'Pointer cursor', cell: 'Cell cursor', @@ -86,7 +89,7 @@ const en = { resetHid: 'Reset HID' }, image: { - title: 'Image', + title: 'Images', loading: 'Loading...', empty: 'Nothing Found', cdrom: 'Mount the image in CD-ROM mode', @@ -110,7 +113,7 @@ const en = { } }, script: { - title: 'Script', + title: 'Scripts', upload: 'Upload', run: 'Run', runBackground: 'Run Background', @@ -139,7 +142,7 @@ const en = { ok: 'Ok' }, download: { - title: 'Download Image', + title: 'Image Downloader', input: 'Please enter a remote image URL', ok: 'Ok', disabled: '/data partition is RO, so we cannot download the image' @@ -257,8 +260,15 @@ const en = { } }, error: { - title: "We've ran into an issue", - refresh: 'Refresh' + title: 'We\'ve ran into an issue', + refresh: 'Refresh', + }, + fullscreen: { + toggle: 'Toggle Fullscreen', + }, + menu: { + collapse: 'Collapse Menu', + expand: 'Expand Menu', } } }; diff --git a/web/src/pages/desktop/menu/download.tsx b/web/src/pages/desktop/menu/download.tsx index 194000b..ec4494b 100644 --- a/web/src/pages/desktop/menu/download.tsx +++ b/web/src/pages/desktop/menu/download.tsx @@ -1,5 +1,5 @@ import { ChangeEvent, useEffect, useRef, useState } from 'react'; -import { Button, Divider, Input, Popover } from 'antd'; +import { Button, Divider, Input, Popover, Tooltip } from 'antd'; import type { InputRef } from 'antd'; import clsx from 'clsx'; import { useSetAtom } from 'jotai'; @@ -21,6 +21,9 @@ export const DownloadImage = () => { const [diskEnabled, setDiskEnabled] = useState(false); const [popoverKey, setPopoverKey] = useState(0); + const tooltip = t('download.title'); + const [tooltipValue, setTooltipValue] = useState(tooltip); + const inputRef = useRef(null); const intervalId = useRef(undefined); @@ -165,11 +168,16 @@ export const DownloadImage = () => { trigger="click" arrow={false} open={isPopoverOpen} - onOpenChange={handleOpenChange} + onOpenChange={(visible) => { + handleOpenChange(visible); + setTooltipValue(visible ? '' : tooltip); + }} > -
- -
+ +
+ +
+
); }; diff --git a/web/src/pages/desktop/menu/fullscreen/index.tsx b/web/src/pages/desktop/menu/fullscreen/index.tsx index defd237..da81b34 100644 --- a/web/src/pages/desktop/menu/fullscreen/index.tsx +++ b/web/src/pages/desktop/menu/fullscreen/index.tsx @@ -1,8 +1,12 @@ import { useEffect, useState } from 'react'; import { MaximizeIcon, MinimizeIcon } from 'lucide-react'; +import { useTranslation } from 'react-i18next'; +import { Tooltip } from 'antd'; export const Fullscreen = () => { + const { t } = useTranslation(); const [isFullscreen, setIsFullscreen] = useState(false); + const [tooltipValue, setTooltipValue] = useState(t('fullscreen.toggle')); useEffect(() => { function onFullscreenChange() { @@ -27,11 +31,13 @@ export const Fullscreen = () => { } return ( -
- {isFullscreen ? : } -
+ +
+ {isFullscreen ? : } +
+
); }; diff --git a/web/src/pages/desktop/menu/image/index.tsx b/web/src/pages/desktop/menu/image/index.tsx index d93da94..f918905 100644 --- a/web/src/pages/desktop/menu/image/index.tsx +++ b/web/src/pages/desktop/menu/image/index.tsx @@ -18,6 +18,9 @@ export const Image = () => { const [isMounted, setIsMounted] = useState(false); const [cdrom, setCdrom] = useState(false); + const tooltip = t('image.title'); + const [tooltipValue, setTooltipValue] = useState(tooltip); + useEffect(() => { getMountedImage().then((rsp) => { if (rsp.code !== 0) return; @@ -60,16 +63,21 @@ export const Image = () => { trigger="click" arrow={false} open={isPopoverOpen} - onOpenChange={setIsPopoverOpen} + onOpenChange={(visible) => { + setIsPopoverOpen(visible); + setTooltipValue(visible ? '' : tooltip); + }} > -
- -
+ +
+ +
+
); }; diff --git a/web/src/pages/desktop/menu/index.tsx b/web/src/pages/desktop/menu/index.tsx index fd8830f..6d21e93 100644 --- a/web/src/pages/desktop/menu/index.tsx +++ b/web/src/pages/desktop/menu/index.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { Divider } from 'antd'; +import { Divider, Tooltip } from 'antd'; import clsx from 'clsx'; import { useAtom } from 'jotai'; import { MenuIcon, XIcon } from 'lucide-react'; @@ -18,6 +18,7 @@ import { Script } from './script'; import { Settings } from './settings'; import { Terminal } from './terminal'; import { Wol } from './wol'; +import { t } from 'i18next'; export const Menu = () => { const [menuDisabledItems, setMenuDisabledItems] = useAtom(menuDisabledItemsAtom); @@ -67,21 +68,25 @@ export const Menu = () => { -
setIsMenuOpen((o) => !o)} - > - -
+ +
setIsMenuOpen((o) => !o)} + > + +
+
{!isMenuOpen && ( -
setIsMenuOpen((o) => !o)} - > - -
+ +
setIsMenuOpen((o) => !o)} + > + +
+
)} diff --git a/web/src/pages/desktop/menu/keyboard/index.tsx b/web/src/pages/desktop/menu/keyboard/index.tsx index e96f8d7..f29c2fe 100644 --- a/web/src/pages/desktop/menu/keyboard/index.tsx +++ b/web/src/pages/desktop/menu/keyboard/index.tsx @@ -1,14 +1,19 @@ import { useState } from 'react'; -import { Popover } from 'antd'; +import { Popover, Tooltip } from 'antd'; import { KeyboardIcon } from 'lucide-react'; +import { t } from 'i18next'; import { Paste } from './paste.tsx'; import { VirtualKeyboard } from './virtual-keyboard.tsx'; import { CtrlAltDel } from './ctrl-alt-del.tsx'; + export const Keyboard = () => { const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const tooltip = t('keyboard.title') + const [tooltipValue, setTooltipValue] = useState(tooltip); + const content = ( <> @@ -24,11 +29,16 @@ export const Keyboard = () => { trigger="click" arrow={false} open={isPopoverOpen} - onOpenChange={setIsPopoverOpen} + onOpenChange={(visible) => { + setIsPopoverOpen(visible); + setTooltipValue(visible ? "" : tooltip); + }} > -
- -
+ +
+ +
+
); }; diff --git a/web/src/pages/desktop/menu/mouse/index.tsx b/web/src/pages/desktop/menu/mouse/index.tsx index a46397a..ed2e199 100644 --- a/web/src/pages/desktop/menu/mouse/index.tsx +++ b/web/src/pages/desktop/menu/mouse/index.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { Divider, Popover } from 'antd'; +import { Divider, Popover, Tooltip } from 'antd'; import clsx from 'clsx'; import { useAtom } from 'jotai'; import { @@ -27,6 +27,9 @@ export const Mouse = () => { const [isPopoverOpen, setIsPopoverOpen] = useState(false); const [isResetting, setIsResetting] = useState(false); + const tooltip = t('mouse.title'); + const [tooltipValue, setTooltipValue] = useState(tooltip); + const mouseStyles = [ { name: t('mouse.default'), icon: , value: 'cursor-default' }, { name: t('mouse.grab'), icon: , value: 'cursor-grab' }, @@ -154,11 +157,16 @@ export const Mouse = () => { trigger="click" arrow={false} open={isPopoverOpen} - onOpenChange={setIsPopoverOpen} + onOpenChange={(visible) => { + setIsPopoverOpen(visible); + setTooltipValue(visible ? "" : tooltip); + }} > -
- -
+ +
+ +
+
); }; diff --git a/web/src/pages/desktop/menu/power/index.tsx b/web/src/pages/desktop/menu/power/index.tsx index 460ba71..b5d42ae 100644 --- a/web/src/pages/desktop/menu/power/index.tsx +++ b/web/src/pages/desktop/menu/power/index.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { Popover, Slider } from 'antd'; +import { Popover, Slider, Tooltip } from 'antd'; import clsx from 'clsx'; import { CirclePowerIcon, LoaderCircleIcon, PowerIcon, RotateCcwIcon } from 'lucide-react'; import { useTranslation } from 'react-i18next'; @@ -13,6 +13,9 @@ export const Power = () => { const [isLoading, setIsLoading] = useState(false); const [powerDuration, setPowerDuration] = useState(8); + const tooltip = t('power.title'); + const [tooltipValue, setTooltipValue] = useState(tooltip); + useEffect(() => { getLed(); const interval = setInterval(getLed, 5000); @@ -95,19 +98,24 @@ export const Power = () => { trigger="click" arrow={false} open={isPopoverOpen} - onOpenChange={setIsPopoverOpen} + onOpenChange={(visible) => { + setIsPopoverOpen(visible); + setTooltipValue(visible ? '' : tooltip); + }} > -
-
- {isLoading ? ( - - ) : ( - - )} + +
+
+ {isLoading ? ( + + ) : ( + + )} +
-
+ ); }; diff --git a/web/src/pages/desktop/menu/screen/index.tsx b/web/src/pages/desktop/menu/screen/index.tsx index 12b70e2..9b291bb 100644 --- a/web/src/pages/desktop/menu/screen/index.tsx +++ b/web/src/pages/desktop/menu/screen/index.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { Popover } from 'antd'; +import { Popover, Tooltip } from 'antd'; import { useAtomValue } from 'jotai'; import { MonitorIcon } from 'lucide-react'; @@ -14,6 +14,7 @@ import { Quality } from './quality'; import { Reset } from './reset.tsx'; import { Resolution } from './resolution'; import { VideoMode } from './video-mode.tsx'; +import { t } from 'i18next'; export const Screen = () => { const videoMode = useAtomValue(videoModeAtom); @@ -21,10 +22,12 @@ export const Screen = () => { const [fps, setFps] = useState(30); const [quality, setQuality] = useState(2); + const tooltip = t('screen.title'); + const [tooltipValue, setTooltipValue] = useState(tooltip); + useEffect(() => { updateScreen('type', videoMode === 'mjpeg' ? 0 : 1); updateScreen('resolution', resolution!.height); - updateQuality(); updateFps(); }, []); @@ -69,10 +72,13 @@ export const Screen = () => { placement="bottomLeft" trigger="click" arrow={false} + onOpenChange={(visible) => setTooltipValue(visible ? '' : tooltip)} > -
- -
+ +
+ +
+
); }; diff --git a/web/src/pages/desktop/menu/script/index.tsx b/web/src/pages/desktop/menu/script/index.tsx index b079a83..00e6a16 100644 --- a/web/src/pages/desktop/menu/script/index.tsx +++ b/web/src/pages/desktop/menu/script/index.tsx @@ -1,6 +1,6 @@ import { ChangeEvent, useRef, useState } from 'react'; import { UploadOutlined } from '@ant-design/icons'; -import { Button, Divider, Popconfirm, Popover } from 'antd'; +import { Button, Divider, Popconfirm, Popover, Tooltip } from 'antd'; import clsx from 'clsx'; import { ChevronRightIcon, FileJsonIcon } from 'lucide-react'; import { useTranslation } from 'react-i18next'; @@ -22,6 +22,9 @@ export const Script = () => { const [isUploading, setIsUploading] = useState(false); const inputRef = useRef(null); + const tooltip = t('script.title'); + const [tooltipValue, setTooltipValue] = useState(tooltip); + function handleOpenChange(open: boolean) { if (open) { getScripts(); @@ -194,11 +197,16 @@ export const Script = () => { trigger="click" arrow={false} open={isPopoverOpen} - onOpenChange={handleOpenChange} + onOpenChange={(visible) => { + handleOpenChange(visible); + setTooltipValue(visible ? '' : tooltip); + }} > -
- -
+ +
+ +
+
{isRunning && } diff --git a/web/src/pages/desktop/menu/settings/index.tsx b/web/src/pages/desktop/menu/settings/index.tsx index 9d15bf9..294c83a 100644 --- a/web/src/pages/desktop/menu/settings/index.tsx +++ b/web/src/pages/desktop/menu/settings/index.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react'; -import { Badge, Modal } from 'antd'; +import { Badge, Modal, Tooltip } from 'antd'; import clsx from 'clsx'; import { BadgeInfoIcon, @@ -32,6 +32,9 @@ export const Settings = () => { const [isUpdateAvailable, setIsUpdateAvailable] = useState(false); + const tooltip = t('settings.title'); + const [tooltipValue, setTooltipValue] = useState(tooltip); + const tabs = [ { id: 'about', icon: , component: }, { id: 'appearance', icon: , component: }, @@ -92,16 +95,18 @@ export const Settings = () => { return ( <> -
setIsModalOpen(true)} - > - -
- -
-
-
+ +
setIsModalOpen(true)} + > + +
+ +
+
+
+
{ destroyOnClose={true} styles={{ content: { padding: 0 } }} onCancel={closeModal} + afterOpenChange={(visible) => setTooltipValue(visible ? '' : tooltip)} >
diff --git a/web/src/pages/desktop/menu/terminal/index.tsx b/web/src/pages/desktop/menu/terminal/index.tsx index 7f65584..82e525d 100644 --- a/web/src/pages/desktop/menu/terminal/index.tsx +++ b/web/src/pages/desktop/menu/terminal/index.tsx @@ -1,5 +1,5 @@ import { useState } from 'react'; -import { Divider, Popover } from 'antd'; +import { Divider, Popover, Tooltip } from 'antd'; import { SquareTerminalIcon } from 'lucide-react'; import { useTranslation } from 'react-i18next'; @@ -10,6 +10,9 @@ export const Terminal = () => { const { t } = useTranslation(); const [isPopoverOpen, setIsPopoverOpen] = useState(false); + const tooltip = t('terminal.title'); + const [tooltipValue, setTooltipValue] = useState(tooltip); + const content = (
@@ -30,11 +33,16 @@ export const Terminal = () => { trigger="click" arrow={false} open={isPopoverOpen} - onOpenChange={setIsPopoverOpen} + onOpenChange={(visible) => { + setIsPopoverOpen(visible); + setTooltipValue(visible ? '' : tooltip); + }} > -
- -
+ +
+ +
+
); }; diff --git a/web/src/pages/desktop/menu/wol/index.tsx b/web/src/pages/desktop/menu/wol/index.tsx index ca58d08..9d0a13d 100644 --- a/web/src/pages/desktop/menu/wol/index.tsx +++ b/web/src/pages/desktop/menu/wol/index.tsx @@ -1,5 +1,5 @@ import { ChangeEvent, useRef, useState } from 'react'; -import { Button, Divider, Input, List, Popover } from 'antd'; +import { Button, Divider, Input, List, Popover, Tooltip } from 'antd'; import type { InputRef } from 'antd'; import clsx from 'clsx'; import { useSetAtom } from 'jotai'; @@ -22,6 +22,9 @@ export const Wol = () => { const [status, setStatus] = useState(''); const [log, setLog] = useState(''); + const tooltip = t('wol.title'); + const [tooltipValue, setTooltipValue] = useState(tooltip); + const [macList, setMacList] = useState([]); const inputRef = useRef(null); @@ -153,11 +156,16 @@ export const Wol = () => { trigger="click" arrow={false} open={isPopoverOpen} - onOpenChange={handleOpenChange} + onOpenChange={(visible) => { + handleOpenChange(visible); + setTooltipValue(visible ? '' : tooltip); + }} > -
- -
+ +
+ +
+
); };