mirror of
https://github.com/sipeed/NanoKVM.git
synced 2026-09-11 00:22:56 -05:00
fix: stop HDMI capture when logged out (#841)
* fix: stop HDMI capture when logged out * feat: stop HDMI capture when viewers are idle * fix: keep HDMI capture active for consumers
This commit is contained in:
@@ -85,6 +85,11 @@ export function setHdmiState(enabled: boolean) {
|
||||
return disableHdmi();
|
||||
}
|
||||
|
||||
// set HDMI idle timeout in minutes
|
||||
export function setHdmiIdleTimeout(minutes: number) {
|
||||
return http.post('/api/vm/hdmi/timeout', { minutes });
|
||||
}
|
||||
|
||||
// get SSH state
|
||||
export function getSSHState() {
|
||||
return http.get('/api/vm/ssh');
|
||||
|
||||
@@ -369,7 +369,10 @@ const ca = {
|
||||
tip: 'Desactiva-ho si no és necessari'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'Activa la sortida HDMI'
|
||||
description: 'Activa la sortida HDMI',
|
||||
idleTimeoutTitle: "Temps d'espera d'inactivitat de captura",
|
||||
idleTimeoutDescription: "Atura la captura HDMI després de no detectar espectadors actius durant",
|
||||
minutes: 'min'
|
||||
},
|
||||
autostart: {
|
||||
title: "Configuració dels scripts d'inici automàtic",
|
||||
|
||||
@@ -372,7 +372,10 @@ const cz = {
|
||||
tip: 'Vypnutí, pokud to není potřeba'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'Povolit výstup HDMI/monitor'
|
||||
description: 'Povolit výstup HDMI/monitor',
|
||||
idleTimeoutTitle: 'Časový limit nečinnosti snímání',
|
||||
idleTimeoutDescription: 'Zastavit snímání HDMI po době bez aktivních diváků',
|
||||
minutes: 'min'
|
||||
},
|
||||
autostart: {
|
||||
title: 'Nastavení automatického spuštění skriptů',
|
||||
|
||||
@@ -369,7 +369,10 @@ const da = {
|
||||
tip: 'Slukker den, hvis den ikke er nødvendig'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'Aktiver HDMI/monitor output'
|
||||
description: 'Aktiver HDMI/monitor output',
|
||||
idleTimeoutTitle: 'Timeout for inaktiv optagelse',
|
||||
idleTimeoutDescription: 'Stop HDMI-optagelse efter en periode uden aktive seere på',
|
||||
minutes: 'min'
|
||||
},
|
||||
autostart: {
|
||||
title: 'Indstillinger for autostart scripts',
|
||||
|
||||
@@ -375,7 +375,10 @@ const de = {
|
||||
tip: 'Deaktivieren Sie den Dienst, wenn Sie ihn nicht benötigen'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'HDMI/Monitor-Ausgabe aktivieren'
|
||||
description: 'HDMI/Monitor-Ausgabe aktivieren',
|
||||
idleTimeoutTitle: 'Zeitlimit für inaktive Aufnahme',
|
||||
idleTimeoutDescription: 'HDMI-Aufnahme stoppen, wenn keine aktiven Zuschauer vorhanden sind für',
|
||||
minutes: 'Min.'
|
||||
},
|
||||
autostart: {
|
||||
title: 'Autostart-Skripteinstellungen',
|
||||
|
||||
@@ -368,7 +368,10 @@ const en = {
|
||||
tip: "Turning it off if it's not needed"
|
||||
},
|
||||
hdmi: {
|
||||
description: 'Enable HDMI/monitor output'
|
||||
description: 'Enable HDMI/monitor output',
|
||||
idleTimeoutTitle: 'Capture idle timeout',
|
||||
idleTimeoutDescription: 'Stop HDMI capture after there are no active viewers for',
|
||||
minutes: 'min'
|
||||
},
|
||||
autostart: {
|
||||
title: 'Autostart Scripts Settings',
|
||||
|
||||
@@ -372,7 +372,10 @@ const es = {
|
||||
tip: 'Desactívalo si no es necesario'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'Habilitar salida HDMI/monitor'
|
||||
description: 'Habilitar salida HDMI/monitor',
|
||||
idleTimeoutTitle: 'Tiempo de espera de captura inactiva',
|
||||
idleTimeoutDescription: 'Detener la captura HDMI después de no haber espectadores activos durante',
|
||||
minutes: 'min'
|
||||
},
|
||||
autostart: {
|
||||
title: 'Configuración de scripts de inicio automático',
|
||||
|
||||
@@ -374,7 +374,10 @@ const fr = {
|
||||
tip: "L'éteindre si ce n'est pas nécessaire"
|
||||
},
|
||||
hdmi: {
|
||||
description: 'Activer HDMI/sortie moniteur'
|
||||
description: 'Activer HDMI/sortie moniteur',
|
||||
idleTimeoutTitle: "Délai d'inactivité de la capture",
|
||||
idleTimeoutDescription: "Arrêter la capture HDMI lorsqu'il n'y a aucun spectateur actif pendant",
|
||||
minutes: 'min'
|
||||
},
|
||||
autostart: {
|
||||
title: 'Paramètres des scripts de démarrage automatique',
|
||||
|
||||
@@ -373,7 +373,10 @@ const hu = {
|
||||
tip: 'Kikapcsolás, ha nincs rá szükség'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'HDMI/monitor kimenet engedélyezése'
|
||||
description: 'HDMI/monitor kimenet engedélyezése',
|
||||
idleTimeoutTitle: 'Inaktív rögzítés időkorlátja',
|
||||
idleTimeoutDescription: 'A HDMI-rögzítés leállítása, ha nincs aktív néző ennyi ideig:',
|
||||
minutes: 'perc'
|
||||
},
|
||||
autostart: {
|
||||
title: 'Automatikus indítási parancsfájlok beállításai',
|
||||
|
||||
@@ -371,7 +371,10 @@ const id = {
|
||||
tip: 'Mematikan jika tidak diperlukan'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'Aktifkan keluaran HDMI/monitor'
|
||||
description: 'Aktifkan keluaran HDMI/monitor',
|
||||
idleTimeoutTitle: 'Batas waktu tangkapan tidak aktif',
|
||||
idleTimeoutDescription: 'Hentikan tangkapan HDMI setelah tidak ada penonton aktif selama',
|
||||
minutes: 'mnt'
|
||||
},
|
||||
autostart: {
|
||||
title: 'Pengaturan Skrip Mulai Otomatis',
|
||||
|
||||
@@ -373,7 +373,10 @@ const it = {
|
||||
tip: 'Spegnerlo se non è necessario'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'Abilita HDMI/monitora uscita'
|
||||
description: 'Abilita HDMI/monitora uscita',
|
||||
idleTimeoutTitle: 'Timeout cattura inattiva',
|
||||
idleTimeoutDescription: 'Interrompi la cattura HDMI dopo che non ci sono visualizzatori attivi per',
|
||||
minutes: 'min'
|
||||
},
|
||||
autostart: {
|
||||
title: 'Impostazioni script di avvio automatico',
|
||||
|
||||
@@ -372,7 +372,10 @@ const ja = {
|
||||
tip: 'この機能を使用していない場合は、オフにすることをお勧めします'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'HDMI/モニター 出力機能を有効にする'
|
||||
description: 'HDMI/モニター 出力機能を有効にする',
|
||||
idleTimeoutTitle: 'キャプチャのアイドルタイムアウト',
|
||||
idleTimeoutDescription: 'アクティブな閲覧者がいない状態が次の時間続いたら HDMI キャプチャを停止',
|
||||
minutes: '分'
|
||||
},
|
||||
autostart: {
|
||||
title: '自動起動スクリプト設定',
|
||||
|
||||
@@ -367,7 +367,10 @@ const ko = {
|
||||
tip: '사용하지 않는 경우 끄는 것이 좋습니다'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'HDMI/모니터 출력 활성화'
|
||||
description: 'HDMI/모니터 출력 활성화',
|
||||
idleTimeoutTitle: '캡처 유휴 시간 제한',
|
||||
idleTimeoutDescription: '활성 시청자가 없는 상태가 다음 시간 동안 지속되면 HDMI 캡처 중지',
|
||||
minutes: '분'
|
||||
},
|
||||
autostart: {
|
||||
title: '자동 시작 스크립트 설정',
|
||||
|
||||
@@ -370,7 +370,10 @@ const nb = {
|
||||
tip: 'Slå den av hvis den ikke er nødvendig'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'Aktiver HDMI/skjermutgang'
|
||||
description: 'Aktiver HDMI/skjermutgang',
|
||||
idleTimeoutTitle: 'Tidsavbrudd for inaktivt opptak',
|
||||
idleTimeoutDescription: 'Stopp HDMI-opptak etter at det ikke har vært aktive seere i',
|
||||
minutes: 'min'
|
||||
},
|
||||
autostart: {
|
||||
title: 'Autostart skriptinnstillinger',
|
||||
|
||||
@@ -373,7 +373,10 @@ const nl = {
|
||||
tip: 'Schakel het uit als het niet nodig is'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'Schakel HDMI/monitoruitgang in'
|
||||
description: 'Schakel HDMI/monitoruitgang in',
|
||||
idleTimeoutTitle: 'Time-out voor inactieve opname',
|
||||
idleTimeoutDescription: 'HDMI-opname stoppen nadat er gedurende deze tijd geen actieve kijkers zijn:',
|
||||
minutes: 'min'
|
||||
},
|
||||
autostart: {
|
||||
title: 'Instellingen voor automatisch starten van scripts',
|
||||
|
||||
@@ -372,7 +372,10 @@ const pl = {
|
||||
tip: 'Wyłączanie, jeśli nie jest potrzebne'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'Włącz HDMI/wyjście monitora'
|
||||
description: 'Włącz HDMI/wyjście monitora',
|
||||
idleTimeoutTitle: 'Limit czasu bezczynności przechwytywania',
|
||||
idleTimeoutDescription: 'Zatrzymaj przechwytywanie HDMI po czasie bez aktywnych widzów:',
|
||||
minutes: 'min'
|
||||
},
|
||||
autostart: {
|
||||
title: 'Ustawienia skryptów autostartu',
|
||||
|
||||
@@ -371,7 +371,10 @@ const pt_br = {
|
||||
tip: 'Desligue se não for necessário'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'Habilitar saída HDMI/monitor'
|
||||
description: 'Habilitar saída HDMI/monitor',
|
||||
idleTimeoutTitle: 'Tempo limite de captura inativa',
|
||||
idleTimeoutDescription: 'Parar a captura HDMI após não haver visualizadores ativos por',
|
||||
minutes: 'min'
|
||||
},
|
||||
autostart: {
|
||||
title: 'Configurações de scripts de inicialização automática',
|
||||
|
||||
@@ -372,7 +372,10 @@ const ru = {
|
||||
tip: 'Выключите, если нет необходимости'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'Включить HDMI/выход монитора'
|
||||
description: 'Включить HDMI/выход монитора',
|
||||
idleTimeoutTitle: 'Тайм-аут неактивного захвата',
|
||||
idleTimeoutDescription: 'Остановить захват HDMI, если активных зрителей нет в течение',
|
||||
minutes: 'мин'
|
||||
},
|
||||
autostart: {
|
||||
title: 'Настройки сценариев автозапуска',
|
||||
|
||||
@@ -368,7 +368,10 @@ const se = {
|
||||
tip: 'Stäng av om det inte behövs'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'Aktivera HDMI/monitorutgång'
|
||||
description: 'Aktivera HDMI/monitorutgång',
|
||||
idleTimeoutTitle: 'Tidsgräns för inaktiv inspelning',
|
||||
idleTimeoutDescription: 'Stoppa HDMI-inspelning efter att det inte har funnits aktiva tittare i',
|
||||
minutes: 'min'
|
||||
},
|
||||
autostart: {
|
||||
title: 'Autostart skriptinställningar',
|
||||
|
||||
@@ -364,7 +364,10 @@ const th = {
|
||||
tip: 'ปิดเครื่องหากไม่จำเป็น'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'เปิดใช้งาน HDMI/เอาต์พุตมอนิเตอร์'
|
||||
description: 'เปิดใช้งาน HDMI/เอาต์พุตมอนิเตอร์',
|
||||
idleTimeoutTitle: 'หมดเวลาการจับภาพเมื่อไม่มีการใช้งาน',
|
||||
idleTimeoutDescription: 'หยุดการจับภาพ HDMI เมื่อไม่มีผู้ชมที่ใช้งานอยู่เป็นเวลา',
|
||||
minutes: 'นาที'
|
||||
},
|
||||
autostart: {
|
||||
title: 'การตั้งค่าสคริปต์เริ่มอัตโนมัติ',
|
||||
|
||||
@@ -370,7 +370,10 @@ const tr = {
|
||||
tip: 'Kullanmıyorsanız devre dışı bırakabilirsiniz'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'HDMI/Momitör çıktısını aktifleştir'
|
||||
description: 'HDMI/Momitör çıktısını aktifleştir',
|
||||
idleTimeoutTitle: 'Etkin olmayan yakalama zaman aşımı',
|
||||
idleTimeoutDescription: 'Etkin görüntüleyici olmadığında HDMI yakalamayı şu süre sonunda durdur:',
|
||||
minutes: 'dk'
|
||||
},
|
||||
autostart: {
|
||||
title: 'Otomatik Başlatılan Komut Dosyaları Ayarları',
|
||||
|
||||
@@ -371,7 +371,10 @@ const uk = {
|
||||
tip: 'Вимкнути, якщо це не потрібно'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'Увімкнути вихід HDMI/monitor'
|
||||
description: 'Увімкнути вихід HDMI/monitor',
|
||||
idleTimeoutTitle: 'Час очікування неактивного захоплення',
|
||||
idleTimeoutDescription: 'Зупинити захоплення HDMI, якщо активних глядачів немає протягом',
|
||||
minutes: 'хв'
|
||||
},
|
||||
autostart: {
|
||||
title: 'Налаштування сценаріїв автозапуску',
|
||||
|
||||
@@ -368,7 +368,10 @@ const vi = {
|
||||
tip: 'Tắt đi nếu không cần thiết'
|
||||
},
|
||||
hdmi: {
|
||||
description: 'Kích hoạt HDMI/đầu ra màn hình'
|
||||
description: 'Kích hoạt HDMI/đầu ra màn hình',
|
||||
idleTimeoutTitle: 'Thời gian chờ khi không hoạt động',
|
||||
idleTimeoutDescription: 'Dừng việc ghi hình HDMI sau khi không có người xem hoạt động trong',
|
||||
minutes: 'phút'
|
||||
},
|
||||
autostart: {
|
||||
title: 'Cài đặt tập lệnh tự khởi động',
|
||||
|
||||
@@ -359,7 +359,10 @@ const zh = {
|
||||
tip: '如果您未使用此功能,建议将其关闭'
|
||||
},
|
||||
hdmi: {
|
||||
description: '启用 HDMI/显示器 输出功能'
|
||||
description: '启用 HDMI/显示器 输出功能',
|
||||
idleTimeoutTitle: '无观看者自动停止采集',
|
||||
idleTimeoutDescription: '没有活跃观看者后停止 HDMI 采集,0 表示永不停止',
|
||||
minutes: '分钟'
|
||||
},
|
||||
autostart: {
|
||||
title: '自动启动脚本设置',
|
||||
|
||||
@@ -359,7 +359,10 @@ const zh_tw = {
|
||||
tip: '若無需求,建議關閉此功能'
|
||||
},
|
||||
hdmi: {
|
||||
description: '啟用 HDMI/螢幕 輸出'
|
||||
description: '啟用 HDMI/螢幕 輸出',
|
||||
idleTimeoutTitle: '擷取閒置逾時',
|
||||
idleTimeoutDescription: '沒有活躍觀看者時,在指定時間後停止 HDMI 擷取',
|
||||
minutes: '分鐘'
|
||||
},
|
||||
autostart: {
|
||||
title: '啟動時指令碼設定',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Switch } from 'antd';
|
||||
import { InputNumber, Switch } from 'antd';
|
||||
import { useAtom } from 'jotai';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -13,6 +13,9 @@ export const Hdmi = () => {
|
||||
|
||||
const [isPcie, setIsPcie] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [idleTimeout, setIdleTimeout] = useState(0);
|
||||
const [idleTimeoutInput, setIdleTimeoutInput] = useState<number | null>(0);
|
||||
const [isIdleTimeoutLoading, setIsIdleTimeoutLoading] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
getHardware();
|
||||
@@ -34,11 +37,40 @@ export const Hdmi = () => {
|
||||
const rsp = await api.getHdmiState();
|
||||
if (rsp.code === 0) {
|
||||
setIsHdmiEnabled(rsp.data.enabled);
|
||||
const timeout = rsp.data.idleTimeout ?? 0;
|
||||
setIdleTimeout(timeout);
|
||||
setIdleTimeoutInput(timeout);
|
||||
}
|
||||
|
||||
setIsLoading(false);
|
||||
}
|
||||
|
||||
function updateIdleTimeout() {
|
||||
if (
|
||||
isIdleTimeoutLoading ||
|
||||
idleTimeoutInput === null ||
|
||||
idleTimeoutInput < 0 ||
|
||||
idleTimeoutInput === idleTimeout
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsIdleTimeoutLoading(true);
|
||||
api
|
||||
.setHdmiIdleTimeout(idleTimeoutInput)
|
||||
.then((rsp) => {
|
||||
if (rsp.code !== 0) {
|
||||
setIdleTimeoutInput(idleTimeout);
|
||||
return;
|
||||
}
|
||||
|
||||
setIdleTimeout(idleTimeoutInput);
|
||||
})
|
||||
.finally(() => {
|
||||
setIsIdleTimeoutLoading(false);
|
||||
});
|
||||
}
|
||||
|
||||
async function setHdmiState() {
|
||||
if (isLoading) return;
|
||||
setIsLoading(true);
|
||||
@@ -60,16 +92,40 @@ export const Hdmi = () => {
|
||||
return (
|
||||
<>
|
||||
{isPcie && (
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex flex-col space-y-1">
|
||||
<span>HDMI</span>
|
||||
<div className="flex flex-col space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex flex-col space-y-1">
|
||||
<span>HDMI</span>
|
||||
|
||||
<span className="text-xs text-neutral-500">
|
||||
{t('settings.device.hdmi.description')}
|
||||
</span>
|
||||
<span className="text-xs text-neutral-500">
|
||||
{t('settings.device.hdmi.description')}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<Switch checked={isHdmiEnabled} loading={isLoading} onChange={setHdmiState} />
|
||||
</div>
|
||||
|
||||
<Switch checked={isHdmiEnabled} loading={isLoading} onChange={setHdmiState} />
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex flex-col space-y-1">
|
||||
<span>{t('settings.device.hdmi.idleTimeoutTitle')}</span>
|
||||
<span className="text-xs text-neutral-500">
|
||||
{t('settings.device.hdmi.idleTimeoutDescription')}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<InputNumber
|
||||
style={{ width: 150 }}
|
||||
min={0}
|
||||
max={10080}
|
||||
precision={0}
|
||||
value={idleTimeoutInput}
|
||||
addonAfter={t('settings.device.hdmi.minutes')}
|
||||
disabled={isIdleTimeoutLoading}
|
||||
onChange={setIdleTimeoutInput}
|
||||
onBlur={updateIdleTimeout}
|
||||
onPressEnter={updateIdleTimeout}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -135,12 +135,16 @@ export function createPicoclawSidebarSessionActions(options: PicoclawSidebarSess
|
||||
}
|
||||
]);
|
||||
|
||||
const sent = sendChatMessage(content, {
|
||||
const task = sendChatMessage(content, {
|
||||
id,
|
||||
maxSteps: config.maxSteps,
|
||||
maxRuntimeMs: config.maxRuntimeMs
|
||||
});
|
||||
return sent !== null;
|
||||
if (task === null) {
|
||||
setMessages((current) => current.filter((message) => message.id !== id));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
async function handleReconnectGateway() {
|
||||
|
||||
Reference in New Issue
Block a user