From 6f83b756c2dfc8d17c59875641e2a192a5297e4c Mon Sep 17 00:00:00 2001 From: polyzium Date: Thu, 5 Sep 2024 19:53:40 +0300 Subject: [PATCH] Implement fit to window Implements the feature as per #20 (https://github.com/sipeed/NanoKVM/issues/20#issue-2486746749) --- web/src/i18n/locales/en.ts | 3 ++- web/src/i18n/locales/fr.ts | 3 ++- web/src/i18n/locales/ko.ts | 3 ++- web/src/i18n/locales/ru.ts | 3 ++- web/src/i18n/locales/zh.ts | 3 ++- web/src/jotai/scaling.ts | 4 ++++ web/src/pages/desktop/menu/screen/index.tsx | 19 +++++++++++++++++-- web/src/pages/desktop/mouse/absolute.tsx | 4 ++-- web/src/pages/desktop/screen/index.tsx | 16 +++++++++++----- 9 files changed, 44 insertions(+), 14 deletions(-) create mode 100644 web/src/jotai/scaling.ts diff --git a/web/src/i18n/locales/en.ts b/web/src/i18n/locales/en.ts index 69a9d73..4838316 100644 --- a/web/src/i18n/locales/en.ts +++ b/web/src/i18n/locales/en.ts @@ -52,7 +52,8 @@ const en = { quality: 'Quality', frameDetect: 'Frame Detect', frameDetectTip: - "Calculate the difference between frames. Stop transmitting video stream when no changes are detected on the remote host's screen." + "Calculate the difference between frames. Stop transmitting video stream when no changes are detected on the remote host's screen.", + fitInWindow: "Fit in window", }, cursor: { default: 'Default cursor', diff --git a/web/src/i18n/locales/fr.ts b/web/src/i18n/locales/fr.ts index 4ddae2e..5a04b41 100644 --- a/web/src/i18n/locales/fr.ts +++ b/web/src/i18n/locales/fr.ts @@ -55,7 +55,8 @@ const fr = { quality: 'Qualité', frameDetect: 'Frame Detect', frameDetectTip: - "Calcule la différence entre les images. Arrête la transmission du flux vidéo lorsqu'aucun changement n'est détecté sur l'écran de l'hôte distant" + "Calcule la différence entre les images. Arrête la transmission du flux vidéo lorsqu'aucun changement n'est détecté sur l'écran de l'hôte distant", + fitInWindow: "Ajuster à la fenêtre" }, cursor: { default: 'Curseur par défaut', diff --git a/web/src/i18n/locales/ko.ts b/web/src/i18n/locales/ko.ts index 73e14f5..4f0ba88 100644 --- a/web/src/i18n/locales/ko.ts +++ b/web/src/i18n/locales/ko.ts @@ -52,7 +52,8 @@ const ko = { quality: '품질', frameDetect: '프레임 탐지', frameDetectTip: - "프레임 간의 차이를 계산합니다. 원격 호스트 화면에 변경 사항이 감지되지 않으면 비디오 스트림 전송을 중지합니다." + "프레임 간의 차이를 계산합니다. 원격 호스트 화면에 변경 사항이 감지되지 않으면 비디오 스트림 전송을 중지합니다.", + fitInWindow: "창에 맞추기" }, cursor: { default: '기본 커서', diff --git a/web/src/i18n/locales/ru.ts b/web/src/i18n/locales/ru.ts index 8df4a54..66a7201 100644 --- a/web/src/i18n/locales/ru.ts +++ b/web/src/i18n/locales/ru.ts @@ -57,7 +57,8 @@ const ru = { quality: 'Качество', frameDetect: 'Экономия трафика', frameDetectTip: - 'Вычисляет разницу между кадрами и прекращает передачу видеопотока, если на экране удаленного узла не обнаружено никаких изменений.' + 'Вычисляет разницу между кадрами и прекращает передачу видеопотока, если на экране удаленного узла не обнаружено никаких изменений.', + fitInWindow: "Вписать в окно", }, cursor: { default: 'Курсор по умолчанию', diff --git a/web/src/i18n/locales/zh.ts b/web/src/i18n/locales/zh.ts index 7eb0541..f5d42a6 100644 --- a/web/src/i18n/locales/zh.ts +++ b/web/src/i18n/locales/zh.ts @@ -51,7 +51,8 @@ const zh = { customizeFps: '自定义', quality: '图像质量', frameDetect: '帧差检测', - frameDetectTip: '计算帧之间的差异,当检测到远程主机画面不变时,停止传输视频流' + frameDetectTip: '计算帧之间的差异,当检测到远程主机画面不变时,停止传输视频流', + fitInWindow: '适应窗口' }, cursor: { default: '默认指针', diff --git a/web/src/jotai/scaling.ts b/web/src/jotai/scaling.ts new file mode 100644 index 0000000..6a92fe2 --- /dev/null +++ b/web/src/jotai/scaling.ts @@ -0,0 +1,4 @@ +import { atom } from 'jotai'; + +// Should the feed fit in the browser window? +export const fitInWindowAtom = atom(false); diff --git a/web/src/pages/desktop/menu/screen/index.tsx b/web/src/pages/desktop/menu/screen/index.tsx index 7444035..f973523 100644 --- a/web/src/pages/desktop/menu/screen/index.tsx +++ b/web/src/pages/desktop/menu/screen/index.tsx @@ -1,6 +1,6 @@ import { useEffect, useState } from 'react'; -import { Popover } from 'antd'; -import { useAtomValue } from 'jotai'; +import { Divider, Popover, Switch } from 'antd'; +import { useAtom, useAtomValue } from 'jotai'; import { MonitorIcon } from 'lucide-react'; import { updateScreen } from '@/api/vm'; @@ -11,11 +11,16 @@ import { Fps } from './fps'; import { FrameDetect } from './frame-detect'; import { Quality } from './quality'; import { Resolution } from './resolution'; +import { useTranslation } from 'react-i18next'; +import { fitInWindowAtom } from '@/jotai/scaling'; export const Screen = () => { + const { t } = useTranslation(); + const resolution = useAtomValue(resolutionAtom); const [fps, setFps] = useState(30); const [quality, setQuality] = useState(80); + const [fitInWindow, setFitInWindow] = useAtom(fitInWindowAtom); useEffect(() => { updateScreen('resolution', resolution!.height); @@ -47,6 +52,16 @@ export const Screen = () => { + + + +
setFitInWindow(!fitInWindow)} + > +
{t('screen.fitInWindow')}
+ +
} placement="bottomLeft" diff --git a/web/src/pages/desktop/mouse/absolute.tsx b/web/src/pages/desktop/mouse/absolute.tsx index bd56fdb..b3abc16 100644 --- a/web/src/pages/desktop/mouse/absolute.tsx +++ b/web/src/pages/desktop/mouse/absolute.tsx @@ -58,8 +58,8 @@ export const Absolute = () => { disableEvent(event); const rect = canvas!.getBoundingClientRect(); - const x = (event.clientX - rect.left) / resolution!.width; - const y = (event.clientY - rect.top) / resolution!.height; + const x = (event.clientX - rect.left) / rect.width; + const y = (event.clientY - rect.top) / rect.height; const hexX = x < 0 ? 0x0001 : Math.floor(0x7fff * x) + 0x0001; const hexY = y < 0 ? 0x0001 : Math.floor(0x7fff * y) + 0x0001; diff --git a/web/src/pages/desktop/screen/index.tsx b/web/src/pages/desktop/screen/index.tsx index bc871c2..ed1f5f9 100644 --- a/web/src/pages/desktop/screen/index.tsx +++ b/web/src/pages/desktop/screen/index.tsx @@ -8,10 +8,12 @@ import { stopFrameDetect } from '@/api/stream.ts'; import { getBaseUrl } from '@/lib/service.ts'; import { mouseStyleAtom } from '@/jotai/mouse.ts'; import { resolutionAtom } from '@/jotai/resolution.ts'; +import { fitInWindowAtom } from '@/jotai/scaling.ts'; export const Screen = () => { const resolution = useAtomValue(resolutionAtom); const mouseStyle = useAtomValue(mouseStyleAtom); + const fitInWindow = useAtomValue(fitInWindowAtom); useEffect(() => { // stop frame detect for a while @@ -20,18 +22,22 @@ export const Screen = () => { return (