mirror of
https://github.com/sipeed/NanoKVM.git
synced 2026-11-10 01:49:00 -06:00
Merge branch 'main' of https://github.com/sipeed/NanoKVM
This commit is contained in:
@@ -1,6 +1,9 @@
|
||||
export const languages = [
|
||||
{ key: 'de', name: 'Deutsch' },
|
||||
{ key: 'en', name: 'English' },
|
||||
{ key: 'fr', name: 'Français' },
|
||||
{ key: 'it', name: 'Italian' },
|
||||
{ key: 'pl', name: 'Polski' },
|
||||
{ key: 'ru', name: 'Русский' },
|
||||
{ key: 'ko', name: '한국어' },
|
||||
{ key: 'zh', name: '中文' }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const en = {
|
||||
const de = {
|
||||
translation: {
|
||||
language: 'Sprache',
|
||||
changePassword: 'Passwort ändern',
|
||||
@@ -12,7 +12,8 @@ const en = {
|
||||
powerLong: 'Einschalten (Langes Drücken)',
|
||||
hddLed: 'Festplatten-LED',
|
||||
checkLibFailed: 'Überprüfung der Laufzeitbibliothek fehlgeschlagen, bitte erneut versuchen.',
|
||||
updateLibFailed: 'Aktualisierung der Laufzeitbibliothek fehlgeschlagen, bitte erneut versuchen.',
|
||||
updateLibFailed:
|
||||
'Aktualisierung der Laufzeitbibliothek fehlgeschlagen, bitte erneut versuchen.',
|
||||
updatingLib: 'Aktualiserung der Laufzeitbibliothek. Bitte nach dem Update die Seite neu laden.',
|
||||
checkForUpdate: 'Nach Update suchen',
|
||||
head: {
|
||||
@@ -25,11 +26,12 @@ const en = {
|
||||
login: 'Einloggen',
|
||||
placeholderUsername: 'Bitte den Benutzernamen eingeben',
|
||||
placeholderPassword: 'Bitte das Passwort eingeben',
|
||||
placeholderPassword2: 'Bitte das Passwort erneut eingeben',
|
||||
placeholderPassword2: 'Passwort wiederholen',
|
||||
noEmptyUsername: 'Der Benutzername darf nicht leer sein',
|
||||
noEmptyPassword: 'Das Passwort darf nicht leer sein',
|
||||
noAccount: 'Fehler beim Auslsen der Benutzerinformation, bitte die Seite neu laden oder das Passwort zurücksetzen',
|
||||
invalidUser: 'Ungültiger Username oder ungültiges Passwort',
|
||||
noAccount:
|
||||
'Fehler beim Auslsen der Benutzerinformation, bitte die Seite neu laden oder das Passwort zurücksetzen',
|
||||
invalidUser: 'Falscher Benutzername oder falsches Passwort',
|
||||
error: 'Unerwarteter Fehler',
|
||||
changePassword: 'Passwort ändern',
|
||||
differentPassword: 'Passwörter stimmt nicht überein',
|
||||
@@ -37,7 +39,8 @@ const en = {
|
||||
illegalPassword: 'Passwort beinhaltet ungültige Zeichen',
|
||||
forgetPassword: 'Passwort vergessen',
|
||||
resetPassword: 'Password zurücksetzen',
|
||||
reset1: 'Falls sie das Passwort vergessen haben, führen sie folgende Schritte durch um dieses zurückzusetzen:',
|
||||
reset1:
|
||||
'Falls sie das Passwort vergessen haben, führen sie folgende Schritte durch um dieses zurückzusetzen:',
|
||||
reset2: '1. In das NanoKVM via SSH einloggen;',
|
||||
reset3: '2. Die Datei auf dem Gerät löschen: ',
|
||||
reset4: '3. Den Standardaccount zum Einloggen benutzen: ',
|
||||
@@ -48,13 +51,13 @@ const en = {
|
||||
resolution: 'Auflösung',
|
||||
auto: 'Automatisch',
|
||||
autoTips:
|
||||
"Falls es bei bestimmten Auflösungen zu Screen-Tearing oder einem Offset des Mauszeigers kommen sollte, bitte die Auflösung des Remote Hosts anpassen oder den automatischen Modus ausschalten.",
|
||||
'Falls es bei bestimmten Auflösungen zu Screen-Tearing oder einem Offset des Mauszeigers kommen sollte, bitte die Auflösung des Remote Hosts anpassen oder den automatischen Modus ausschalten.',
|
||||
fps: 'FPS',
|
||||
customizeFps: 'Anpassen',
|
||||
quality: 'Qualität',
|
||||
frameDetect: 'Frame Detect',
|
||||
frameDetectTip:
|
||||
"Berechnet den Unterschied zwischen den Einzelbildern. Beendet die Liveübertragung des Videostreams wenn keine Änderungen auf dem Bildschirm des Hosts festgestellt werden kann."
|
||||
'Berechnet den Unterschied zwischen den Einzelbildern. Beendet die Liveübertragung des Videostreams wenn keine Änderungen auf dem Bildschirm des Hosts festgestellt werden kann.'
|
||||
},
|
||||
keyboard: {
|
||||
paste: 'Einfügen',
|
||||
@@ -73,18 +76,22 @@ const en = {
|
||||
mode: 'Maus Modus',
|
||||
absolute: 'Absoluter Modus',
|
||||
relative: 'Relativer Modus',
|
||||
requestPointer: 'Der Relative Modus wird benutzt. Bitte auf den Desktop klicken um einen Mauszeiger anzuzeigen.',
|
||||
requestPointer:
|
||||
'Der Relative Modus wird benutzt. Bitte auf den Desktop klicken um einen Mauszeiger anzuzeigen.',
|
||||
resetHid: 'Eingeabegeräte zurücksetzen'
|
||||
},
|
||||
image: {
|
||||
title: 'ISO oder Festplatten Abbilder',
|
||||
loading: 'Laden...',
|
||||
empty: 'Nichts gefunden',
|
||||
mountFailed: 'Mounten fehlgeschlagen',
|
||||
mountDesc:
|
||||
'Bei einigen Systemen muss die virtuelle Festplatte auf dem Remote-Host ausgeworfen werden, bevor das Image gemountet werden kann.',
|
||||
tips: {
|
||||
title: 'Wie man Abbilder hochlädt',
|
||||
usb1: 'Den NanoKVM via USB mit dem Computer verbinden.',
|
||||
usb2: 'Stellen sie sicher, das das Virtuelle USB-Gerät eingebunden ist. (Einstellungen - Virtuelles USB-Gerät).',
|
||||
usb3: 'Öffnen sie die virtuelle USB-Disk auf ihrem Computer und kopieren sie die Abbilddatei in das root-Verzeichnis des USB-Geräts.',
|
||||
usb2: 'Stellen sie sicher, das das Virtuelle Festplatte eingebunden ist. (Einstellungen - Virtuelle Festplatte).',
|
||||
usb3: 'Öffnen sie die Virtuelle Festplatte auf ihrem Computer und kopieren sie die Abbilddatei in das root-Verzeichnis des USB-Geräts.',
|
||||
scp1: 'Stellen sie sicher, das sich der NanoKVM und ihr Computer im gleichen lokalen Netzwerk befinden.',
|
||||
scp2: 'Öffnen sie ein Terminal auf ihrem Computer und benutzen sie den SCP-Befehl um die Abbilddatei in das /data Verzeichnis des NanoKVM zu kopieren.',
|
||||
scp3: 'Beispiel: scp ihr-abbild-verzeichnis root@ihre-nanokvm-ip:/data',
|
||||
@@ -114,7 +121,7 @@ const en = {
|
||||
nanokvm: 'NanoKVM Terminal',
|
||||
serial: 'Terminal über den Seriellen Port',
|
||||
serialPort: 'Serieller Port',
|
||||
serialPortPlaceholder: 'Bitte die Nummer des seriellen Ports angeben',
|
||||
serialPortPlaceholder: 'Serielle Portnummer eingeben',
|
||||
baudrate: 'Baudrate',
|
||||
confirm: 'Ok'
|
||||
},
|
||||
@@ -140,14 +147,15 @@ const en = {
|
||||
queryFailed: 'Versionsnummer konnte nicht erkannt werden',
|
||||
updateFailed: 'Update gescheitert. Bitte versuchen sie es erneut.',
|
||||
isLatest: 'Die aktuelle Version ist bereits installiert.',
|
||||
available: 'Ein Update ist verfügbar. Sind sie sicher, dass sie diese Version aktualisieren möchten?',
|
||||
available:
|
||||
'Ein Update ist verfügbar. Sind sie sicher, dass sie diese Version aktualisieren möchten?',
|
||||
updating: 'Update wird gestartet. Bitte warten...',
|
||||
confirm: 'Bestätigen',
|
||||
cancel: 'Abbrechen'
|
||||
},
|
||||
virtualDevice: {
|
||||
network: 'Virtuelles Netzwerk',
|
||||
usb: 'Virtuelles USB Gerät'
|
||||
disk: 'Virtuelle Festplatte'
|
||||
},
|
||||
tailscale: {
|
||||
loading: 'Lade...',
|
||||
@@ -155,7 +163,8 @@ const en = {
|
||||
install: 'Installieren',
|
||||
installing: 'Installation wird durchgeführt',
|
||||
failed: 'Installation gescheitert',
|
||||
retry: 'Bitte neu laden und noch einmal versuchen. Oder versuchen sie Tailscale manuell zu installieren',
|
||||
retry:
|
||||
'Bitte neu laden und noch einmal versuchen. Oder versuchen sie Tailscale manuell zu installieren',
|
||||
download: 'Laden sie das',
|
||||
package: 'Installationspaket',
|
||||
unzip: 'und entpacken sie es manuell',
|
||||
@@ -168,7 +177,7 @@ const en = {
|
||||
login: 'Einloggen',
|
||||
loginSuccess: 'Das Einloggen war erfolgreich',
|
||||
enable: 'Tailscale aktivieren',
|
||||
deviceName: 'Gerätename',
|
||||
deviceName: 'Name des Geräts',
|
||||
deviceIP: 'Geräte-IP',
|
||||
account: 'Benutzerkonto',
|
||||
logout: 'Ausloggen',
|
||||
|
||||
@@ -80,11 +80,14 @@ const en = {
|
||||
title: 'Images',
|
||||
loading: 'Loading...',
|
||||
empty: 'Nothing Found',
|
||||
mountFailed: 'Mount Failed',
|
||||
mountDesc:
|
||||
"In some systems, it's necessary to eject the virtual disk on the remote host before mounting the image.",
|
||||
tips: {
|
||||
title: 'How to upload',
|
||||
usb1: 'Connect the NanoKVM to your computer via USB.',
|
||||
usb2: 'Ensure that the Virtual USB is mounted (Settings - Virtual USB).',
|
||||
usb3: 'Open the virtual usb disk on your computer and copy the image file to the root directory of the usb disk.',
|
||||
usb2: 'Ensure that the virtual disk is mounted (Settings - Virtual Disk).',
|
||||
usb3: 'Open the virtual disk on your computer and copy the image file to the root directory of the virtual disk.',
|
||||
scp1: 'Make sure the NanoKVM and your computer are on the same local network.',
|
||||
scp2: 'Open a terminal on your computer and use the SCP command to upload the image file to the /data directory on the NanoKVM.',
|
||||
scp3: 'Example: scp your-image-path root@your-nanokvm-ip:/data',
|
||||
@@ -147,7 +150,7 @@ const en = {
|
||||
},
|
||||
virtualDevice: {
|
||||
network: 'Virtual Network',
|
||||
usb: 'Virtual USB'
|
||||
disk: 'Virtual Disk'
|
||||
},
|
||||
tailscale: {
|
||||
loading: 'Loading...',
|
||||
|
||||
@@ -84,11 +84,14 @@ const fr = {
|
||||
title: 'Images',
|
||||
loading: 'Chargement',
|
||||
empty: 'Vide',
|
||||
mountFailed: "Échec du montage de l'image.",
|
||||
mountDesc:
|
||||
"Dans certains systèmes, il est nécessaire de déséjecter le disque virtuel sur l'hôte distant avant de monter l'image.",
|
||||
tips: {
|
||||
title: 'Comment télécharger',
|
||||
usb1: 'Connectez le NanoKVM à votre ordinateur via USB.',
|
||||
usb2: 'Assurez-vous que le disque virtuel est monté (Paramètres - Disque virtuel).',
|
||||
usb3: 'Ouvrez le disque virtuel sur votre ordinateur et copiez le fichier image dans le répertoire racine du disque.',
|
||||
usb3: 'Ouvrez le disque virtuel sur votre ordinateur et copiez le fichier image dans le répertoire racine du disque virtuel.',
|
||||
scp1: 'Assurez-vous que le NanoKVM et votre ordinateur sont sur le même réseau local.',
|
||||
scp2: 'Ouvrez un terminal sur votre ordinateur et utilisez la commande SCP pour télécharger le fichier image dans le répertoire /data du NanoKVM.',
|
||||
scp3: 'Exemple : scp chemin-de-votre-image root@ip-de-votre-nanokvm:/data',
|
||||
@@ -150,8 +153,8 @@ const fr = {
|
||||
cancel: 'Annuler'
|
||||
},
|
||||
virtualDevice: {
|
||||
network: 'Réseau virtuel',
|
||||
usb: 'USB virtuel'
|
||||
network: 'carte réseau virtuelle',
|
||||
disk: 'disque virtuel'
|
||||
},
|
||||
tailscale: {
|
||||
loading: 'Chargement...',
|
||||
|
||||
185
web/src/i18n/locales/it.ts
Normal file
185
web/src/i18n/locales/it.ts
Normal file
@@ -0,0 +1,185 @@
|
||||
const it = {
|
||||
translation: {
|
||||
language: 'Lingua',
|
||||
changePassword: 'Cambia Password',
|
||||
logout: 'Disconnetti',
|
||||
settings: 'Impostazioni',
|
||||
showMouse: 'Mostra mouse',
|
||||
hideMouse: 'Nascondi mouse',
|
||||
power: 'Accensione',
|
||||
reset: 'Reimposta',
|
||||
powerShort: 'Accensione (clic breve)',
|
||||
powerLong: 'Accensione (clic lungo)',
|
||||
hddLed: 'LED HDD',
|
||||
checkLibFailed: 'Impossibile verificare la libreria runtime, riprova',
|
||||
updateLibFailed: 'Impossibile aggiornare la libreria runtime, riprova',
|
||||
updatingLib: "Aggiornamento libreria runtime. Aggiorna la pagina dopo l'aggiornamento.",
|
||||
checkForUpdate: 'Controlla Aggiornamenti',
|
||||
head: {
|
||||
desktop: 'Desktop Remoto',
|
||||
login: 'Accesso',
|
||||
changePassword: 'Cambia Password',
|
||||
terminal: 'Terminale'
|
||||
},
|
||||
auth: {
|
||||
login: 'Accesso',
|
||||
placeholderUsername: 'Inserisci il nome utente',
|
||||
placeholderPassword: 'Inserisci la password',
|
||||
placeholderPassword2: 'Inserisci nuovamente la password',
|
||||
noEmptyUsername: 'Il nome utente non può essere vuoto',
|
||||
noEmptyPassword: 'La password non può essere vuota',
|
||||
noAccount:
|
||||
'Impossibile ottenere informazioni utente, aggiorna la pagina o reimposta la password',
|
||||
invalidUser: 'Nome utente o password non validi',
|
||||
error: 'Errore imprevisto',
|
||||
changePassword: 'Cambia Password',
|
||||
differentPassword: 'Le password non corrispondono',
|
||||
illegalUsername: 'Il nome utente contiene caratteri non validi',
|
||||
illegalPassword: 'La password contiene caratteri non validi',
|
||||
forgetPassword: 'Hai dimenticato la password',
|
||||
resetPassword: 'Reimposta Password',
|
||||
reset1: 'Se hai dimenticato la password, segui questi passaggi per reimpostarla:',
|
||||
reset2: '1. Accedi al dispositivo NanoKVM tramite SSH;',
|
||||
reset3: '2. Elimina il file nel dispositivo: ',
|
||||
reset4: "3. Usa l'account predefinito per accedere: ",
|
||||
ok: 'Ok',
|
||||
cancel: 'Annulla'
|
||||
},
|
||||
screen: {
|
||||
resolution: 'Risoluzione',
|
||||
auto: 'Automatico',
|
||||
autoTips:
|
||||
'Potrebbero verificarsi tearing dello schermo o spostamento del mouse a risoluzioni specifiche. Considera di regolare la risoluzione del dispositivo remoto o disabilitare la modalità automatica.',
|
||||
fps: 'FPS',
|
||||
customizeFps: 'Personalizza',
|
||||
quality: 'Qualità',
|
||||
frameDetect: 'Rilevamento Frame',
|
||||
frameDetectTip:
|
||||
'Calcola la differenza tra i frame. Interrompe la trasmissione del flusso video quando non vengono rilevate modifiche sullo schermo del dispositivo remoto.'
|
||||
},
|
||||
keyboard: {
|
||||
paste: 'Incolla',
|
||||
tips: 'Sono supportati solo lettere e simboli standard della tastiera',
|
||||
placeholder: 'Inserisci testo',
|
||||
submit: 'Invia',
|
||||
virtual: 'Tastiera'
|
||||
},
|
||||
mouse: {
|
||||
default: 'Cursore predefinito',
|
||||
pointer: 'Cursore a puntatore',
|
||||
cell: 'Cursore a cella',
|
||||
text: 'Cursore testo',
|
||||
grab: 'Cursore di presa',
|
||||
hide: 'Nascondi cursore',
|
||||
mode: 'Modalità mouse',
|
||||
absolute: 'Modalità assoluta',
|
||||
relative: 'Modalità relativa',
|
||||
requestPointer:
|
||||
'Usando la modalità relativa. Clicca sul desktop per ottenere il puntatore del mouse.',
|
||||
resetHid: 'Reimposta HID'
|
||||
},
|
||||
image: {
|
||||
title: 'Immagini',
|
||||
loading: 'Caricamento...',
|
||||
empty: 'Nessun risultato',
|
||||
mountFailed: 'Montaggio immagine fallito',
|
||||
mountDesc:
|
||||
"In alcuni sistemi, è necessario espellere il disco virtuale sull'host remoto prima di montare l'immagine.",
|
||||
tips: {
|
||||
title: 'Come caricare',
|
||||
usb1: 'Collega il NanoKVM al tuo computer tramite USB.',
|
||||
usb2: 'Assicurati che la Virtual Disk sia montata (Impostazioni - Virtual Disk).',
|
||||
usb3: 'Apri il disk virtuale sul tuo computer e copia il file immagine nella directory principale del disk.',
|
||||
scp1: 'Assicurati che il NanoKVM e il tuo computer siano sulla stessa rete locale.',
|
||||
scp2: 'Apri un terminale sul tuo computer e usa il comando SCP per caricare il file immagine nella directory /data del NanoKVM.',
|
||||
scp3: 'Esempio: scp il-tuo-percorso-immagine root@il-tuo-ip-nanokvm:/data',
|
||||
tfCard: 'Scheda TF',
|
||||
tf1: 'Questo metodo è supportato su sistemi Linux',
|
||||
tf2: 'Recupera la scheda TF dal NanoKVM (per la versione FULL, smonta prima il case).',
|
||||
tf3: 'Inserisci la scheda TF in un lettore di schede e collegala al tuo computer.',
|
||||
tf4: 'Copia il file immagine nella directory /data sulla scheda TF.',
|
||||
tf5: 'Inserisci la scheda TF nel NanoKVM.'
|
||||
}
|
||||
},
|
||||
script: {
|
||||
title: 'Script',
|
||||
upload: 'Carica',
|
||||
run: 'Esegui',
|
||||
runBackground: 'Esegui in Background',
|
||||
runFailed: 'Esecuzione fallita',
|
||||
attention: 'Attenzione',
|
||||
delDesc: 'Sei sicuro di voler eliminare questo file?',
|
||||
confirm: 'Sì',
|
||||
cancel: 'No',
|
||||
delete: 'Elimina',
|
||||
close: 'Chiudi'
|
||||
},
|
||||
terminal: {
|
||||
title: 'Terminale',
|
||||
nanokvm: 'Terminale NanoKVM',
|
||||
serial: 'Terminale Porta Seriale',
|
||||
serialPort: 'Porta Seriale',
|
||||
serialPortPlaceholder: 'Inserisci la porta seriale',
|
||||
baudrate: 'Baud rate',
|
||||
confirm: 'Ok'
|
||||
},
|
||||
wol: {
|
||||
sending: 'Invio comando...',
|
||||
sent: 'Comando inviato',
|
||||
input: 'Inserisci il MAC',
|
||||
ok: 'Ok'
|
||||
},
|
||||
about: {
|
||||
title: 'Informazioni su NanoKVM',
|
||||
information: 'Informazioni',
|
||||
ip: 'IP',
|
||||
mdns: 'mDNS',
|
||||
firmware: 'Versione Applicazione',
|
||||
image: 'Versione Immagine',
|
||||
deviceKey: 'Chiave Dispositivo',
|
||||
queryFailed: 'Query fallita',
|
||||
community: 'Comunità'
|
||||
},
|
||||
update: {
|
||||
title: 'Controlla Aggiornamenti',
|
||||
queryFailed: 'Impossibile ottenere la versione',
|
||||
updateFailed: 'Aggiornamento fallito. Riprova.',
|
||||
isLatest: 'Hai già la versione più recente.',
|
||||
available: 'Un aggiornamento è disponibile. Sei sicuro di voler aggiornare?',
|
||||
updating: 'Aggiornamento avviato. Attendere prego...',
|
||||
confirm: 'Conferma',
|
||||
cancel: 'Annulla'
|
||||
},
|
||||
virtualDevice: {
|
||||
network: 'Rete Virtuale',
|
||||
usb: 'Disk Virtuale'
|
||||
},
|
||||
tailscale: {
|
||||
loading: 'Caricamento...',
|
||||
notInstall: 'Tailscale non trovato! Per favore, installa.',
|
||||
install: 'Installa',
|
||||
installing: 'Installazione in corso',
|
||||
failed: 'Installazione fallita',
|
||||
retry: 'Riprova aggiornando la pagina o installa manualmente',
|
||||
download: 'Scarica il',
|
||||
package: 'pacchetto di installazione',
|
||||
unzip: 'e decomprimilo',
|
||||
upTailscale: 'Carica tailscale nella directory /usr/bin/ del NanoKVM',
|
||||
upTailscaled: 'Carica tailscaled nella directory /usr/sbin/ del NanoKVM',
|
||||
refresh: 'Aggiorna la pagina corrente',
|
||||
notLogin:
|
||||
'Il dispositivo non è ancora stato associato. Effettua il login e associa questo dispositivo al tuo account.',
|
||||
urlPeriod: 'Questo URL è valido per 10 minuti',
|
||||
login: 'Accedi',
|
||||
loginSuccess: 'Accesso riuscito',
|
||||
enable: 'Abilita Tailscale',
|
||||
deviceName: 'Nome Dispositivo',
|
||||
deviceIP: 'IP Dispositivo',
|
||||
account: 'Account',
|
||||
logout: 'Disconnetti',
|
||||
logout2: 'Sei sicuro di voler uscire?'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default it;
|
||||
@@ -81,11 +81,14 @@ const ko = {
|
||||
title: '이미지',
|
||||
loading: 'Loading...',
|
||||
empty: '아무것도 없습니다.',
|
||||
mountFailed: '이미지 마운트 실패',
|
||||
mountDesc:
|
||||
'일부 시스템에서는 이미지를 마운트하기 전에 원격 호스트에서 가상 디스크를 제거해야 합니다.',
|
||||
tips: {
|
||||
title: '업로드 방법',
|
||||
usb1: 'USB를 통해 NanoKVM을 컴퓨터에 연결하세요.',
|
||||
usb2: '가상 USB가 마운트되어 있는지 확인하세요(설정 - 가상 USB).',
|
||||
usb3: '컴퓨터에서 가상 USB 디스크를 열고 이미지 파일을 USB 디스크의 루트 디렉터리에 복사하세요.',
|
||||
usb2: '가상 디스크가 마운트되었는지 확인하세요. (설정 - 가상 디스크).',
|
||||
usb3: '컴퓨터에서 가상 디스크를 열고 이미지 파일을 가상 디스크의 루트 디렉토리로 복사하세요.',
|
||||
scp1: 'NanoKVM과 컴퓨터가 동일한 로컬 네트워크에 있는지 확인하세요.',
|
||||
scp2: '컴퓨터에서 터미널을 열고 SCP 명령을 사용하여 이미지 파일을 NanoKVM의 /data 디렉터리에 업로드하세요.',
|
||||
scp3: '예: scp your-image-path root@your-nanokvm-ip:/data',
|
||||
@@ -147,8 +150,8 @@ const ko = {
|
||||
cancel: '취소'
|
||||
},
|
||||
virtualDevice: {
|
||||
network: '가상 네트워크',
|
||||
usb: '가상 USB'
|
||||
network: '가상 네트워크 카드',
|
||||
disk: '가상 디스크'
|
||||
},
|
||||
tailscale: {
|
||||
loading: 'Loading...',
|
||||
|
||||
184
web/src/i18n/locales/pl.ts
Normal file
184
web/src/i18n/locales/pl.ts
Normal file
@@ -0,0 +1,184 @@
|
||||
const pl = {
|
||||
translation: {
|
||||
language: 'Język',
|
||||
changePassword: 'Zmień hasło',
|
||||
logout: 'Wyloguj',
|
||||
settings: 'Ustawienia',
|
||||
showMouse: 'Pokaż myszkę',
|
||||
hideMouse: 'Ukryj myszkę',
|
||||
power: 'Zasilanie',
|
||||
reset: 'Reset',
|
||||
powerShort: 'Zasilanie (krótkie kliknięcie)',
|
||||
powerLong: 'Zasilanie (długie kliknięcie)',
|
||||
hddLed: 'HDD LED',
|
||||
checkLibFailed: 'Nie udało się sprawdzić biblioteki uruchomieniowej, spróbuj ponownie',
|
||||
updateLibFailed: 'Nie udało się zaktualizować biblioteki uruchomieniowej, spróbuj ponownie',
|
||||
updatingLib: 'Aktualizowanie biblioteki uruchomieniowej. Odśwież stronę po aktualizacji.',
|
||||
checkForUpdate: 'Aktualizacja systemu',
|
||||
head: {
|
||||
desktop: 'Zdalny pulpit',
|
||||
login: 'Login',
|
||||
changePassword: 'Zmień Hasło',
|
||||
terminal: 'Terminal'
|
||||
},
|
||||
auth: {
|
||||
login: 'Login',
|
||||
placeholderUsername: 'Wprowadź nazwę użykownika',
|
||||
placeholderPassword: 'wprowadź hasło',
|
||||
placeholderPassword2: 'wprowadź hasło ponownie',
|
||||
noEmptyUsername: 'nazwa użykownika nie może być pusta',
|
||||
noEmptyPassword: 'hasło nie może być puste',
|
||||
noAccount:
|
||||
'Nie udało się uzyskać informacji o użytkowniku, odśwież stronę lub zresetuj hasło',
|
||||
invalidUser: 'Błędne hasło lub nazwa użykownika',
|
||||
error: 'niespodziewany błąd',
|
||||
changePassword: 'Zmień Hasło',
|
||||
differentPassword: 'hasła nie zgadzają się',
|
||||
illegalUsername: 'nazwa użytkownika zawiera niedozwolone znaki',
|
||||
illegalPassword: 'hasło zawiera niedozwolone znaki',
|
||||
forgetPassword: 'Zapomiałeś hasła?',
|
||||
resetPassword: 'Zmień hasło',
|
||||
reset1: 'Jeśli zapomniałeś hasła, postępuj zgodnie z instrukcjami, aby je zresetować:',
|
||||
reset2: '1. Zaloguj się do urządzenia NanoKVM przez SSH:',
|
||||
reset3: '2. Usuń ten plik z urządzenia: ',
|
||||
reset4: '3. Użyj domyślnego login aby zalogować: ',
|
||||
ok: 'Ok',
|
||||
cancel: 'Anuluj'
|
||||
},
|
||||
screen: {
|
||||
resolution: 'Rozdzielczość',
|
||||
auto: 'Automatyczny',
|
||||
autoTips:
|
||||
'W określonych rozdzielczościach może wystąpić rozrywanie ekranu lub przesunięcie myszy. Rozważ dostosowanie rozdzielczości zdalnego hosta lub wyłącz tryb automatyczny.',
|
||||
fps: 'FPS',
|
||||
customizeFps: 'Personalizuj',
|
||||
quality: 'Jakość',
|
||||
frameDetect: 'Wykrywanie klatek',
|
||||
frameDetectTip:
|
||||
'Obliczanie różnicy między klatkami. Zatrzymaj transmisję strumienia wideo, gdy na ekranie zdalnego hosta nie zostaną wykryte żadne zmiany.'
|
||||
},
|
||||
keyboard: {
|
||||
paste: 'Wklej',
|
||||
tips: 'Tylko standardowe klawiaturowe znaki i symbole są obsługiwane.',
|
||||
placeholder: 'Proszę wprowadzić coś',
|
||||
submit: 'Prześlij',
|
||||
virtual: 'Klawiatura'
|
||||
},
|
||||
mouse: {
|
||||
default: 'Domyślny kursor',
|
||||
pointer: 'Wskazujący kursor',
|
||||
cell: 'Kursor komórki',
|
||||
text: 'Kursor tekstowy',
|
||||
grab: 'Kursor chwytania',
|
||||
hide: 'Ukruj kursor',
|
||||
mode: 'Tryb myszki',
|
||||
absolute: 'Tryb bezwzględny',
|
||||
relative: 'Tryb względny',
|
||||
requestPointer: 'Korzystanie z trybu względnego. Kliknij pulpit, aby uzyskać wskaźnik myszy.',
|
||||
resetHid: 'Zresetuj HID'
|
||||
},
|
||||
image: {
|
||||
title: 'Obrazy',
|
||||
loading: 'Ładowanie...',
|
||||
empty: 'Nic nie znaleziono',
|
||||
mountFailed: 'Nie udało się zamontować obrazu',
|
||||
mountDesc:
|
||||
'W niektórych systemach wymagane jest wyjęcie dysku wirtualnego na zdalnym hoście przed zamontowaniem obrazu.',
|
||||
tips: {
|
||||
title: 'Jak przesłać obrazy',
|
||||
usb1: 'Podłącz urządzenie NanoKVM do komputera przez USB.',
|
||||
usb2: 'Upewnij się, że dysk wirtualny jest zamontowany (Ustawienia - Dysk wirtualny).',
|
||||
usb3: 'Otwórz dysk wirtualny na swoim komputerze i skopiuj plik obrazu do katalogu głównego dysku wirtualnego.',
|
||||
scp1: 'Upewnij się że NanoKVM i twój komputer są na tej samej sieci lokalnej.',
|
||||
scp2: 'Otwórz terminal na komputerze i użyj komendę SCP aby przesłać obraz do katalogu /data na NanoKVM.',
|
||||
scp3: 'Przykład: scp lokalizacja-zrodlowego-obrazu root@ip-twojego-nanokvm:/data',
|
||||
tfCard: 'Karta SD',
|
||||
tf1: 'Ta metoda jest obsługiwana w systemie Linux',
|
||||
tf2: 'Usuń kartę SD od NanoKVM (dla wersji FULL, rozbierz obudowę najpierw).',
|
||||
tf3: 'Włóż kartę SD do czytnika kart i podłącz do twojego komputera.',
|
||||
tf4: 'Kopjuj obraz do katalogu /data na karcie SD.',
|
||||
tf5: 'Włóż kartę SD do NanoKVM.'
|
||||
}
|
||||
},
|
||||
script: {
|
||||
title: 'Skrypty',
|
||||
upload: 'Prześlij',
|
||||
run: 'Uruchom',
|
||||
runBackground: 'Uruchomiony w tle',
|
||||
runFailed: 'Uruchomienie nie powiodło się',
|
||||
attention: 'Uwaga',
|
||||
delDesc: 'Czy na pewno chcesz usunąć ten plik?',
|
||||
confirm: 'Tak',
|
||||
cancel: 'Nie',
|
||||
delete: 'Usuń',
|
||||
close: 'Zamknij'
|
||||
},
|
||||
terminal: {
|
||||
title: 'Terminal',
|
||||
nanokvm: 'Terminal NanoKVM',
|
||||
serial: 'Terminal portu szeregowego',
|
||||
serialPort: 'Port szeregowy',
|
||||
serialPortPlaceholder: 'Wprowadź port szeregowy',
|
||||
baudrate: 'Szybkość transmisji',
|
||||
confirm: 'Ok'
|
||||
},
|
||||
wol: {
|
||||
sending: 'Wysyłanie komendy...',
|
||||
sent: 'Komenda wysłana',
|
||||
input: 'Wprowadź numer adresu MAC',
|
||||
ok: 'Ok'
|
||||
},
|
||||
about: {
|
||||
title: 'NanoKVM - informacje',
|
||||
information: 'Informacje o systemie',
|
||||
ip: 'IP',
|
||||
mdns: 'mDNS',
|
||||
firmware: 'Wersja oprogramowania',
|
||||
image: 'Wersja obrazu',
|
||||
deviceKey: 'Klucz urządzenia',
|
||||
queryFailed: 'Zapytanie nie powiodło się',
|
||||
community: 'Społeczność'
|
||||
},
|
||||
update: {
|
||||
title: 'Sprawdź aktualizacje',
|
||||
queryFailed: 'Uzyskanie wersji nie powiodło się',
|
||||
updateFailed: 'Aktualizacja nie powiodła się. Spróbuj ponownie.',
|
||||
isLatest: 'Oprogramowanie jest aktualne.',
|
||||
available: 'Aktualizacja jest dostępna. Czy na pewno chcesz dokonać aktualizacji?',
|
||||
updating: 'Aktualizacja rozpoczęta. Proszę czekać...',
|
||||
confirm: 'Potwierdź',
|
||||
cancel: 'Anuluj'
|
||||
},
|
||||
virtualDevice: {
|
||||
network: 'Sieć wirtualna',
|
||||
usb: 'Dysk wirtualny'
|
||||
},
|
||||
tailscale: {
|
||||
loading: 'Ładowanie...',
|
||||
notInstall: 'Nie znaleziono Tailscale! Proszę zainstalować.',
|
||||
install: 'Instaluj',
|
||||
installing: 'Instalowanie',
|
||||
failed: 'Instalowanie nie powiodło się',
|
||||
retry: 'Odśwież stronę i spróbuj ponownie, albo spróbuj zainstalować manualnie.',
|
||||
download: 'Pobierz',
|
||||
package: 'pakiet instalacyjny',
|
||||
unzip: 'i wypakuj pliki',
|
||||
upTailscale: 'Prześlij tailscale do NanoKVM w katalogu /usr/bin/',
|
||||
upTailscaled: 'Prześlij tailscaled do NanoKVM w katalogu /usr/sbin/',
|
||||
refresh: 'Odśwież obecną stronę',
|
||||
notLogin:
|
||||
'Urządzenie nie zostało jeszcze powiązane. Zaloguj się i powiąż to urządzenie ze swoim kontem.',
|
||||
urlPeriod: 'Ten URL jest ważny przez 10 minut',
|
||||
login: 'Zaloguj',
|
||||
loginSuccess: 'Zalogowanie pomyślne',
|
||||
enable: 'Włącz Tailscale',
|
||||
deviceName: 'Nazwa urządzenia',
|
||||
deviceIP: 'Adres IP urządzenia',
|
||||
account: 'Konto',
|
||||
logout: 'Wyloguj',
|
||||
logout2: 'Chcesz się wylogować?'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default pl;
|
||||
@@ -85,11 +85,14 @@ const ru = {
|
||||
title: 'Образы',
|
||||
loading: 'Загрузка...',
|
||||
empty: 'Пусто',
|
||||
mountFailed: 'Монтирование образа не удалось',
|
||||
mountDesc:
|
||||
'В некоторых системах необходимо отсоединить виртуальный диск на удаленном хосте перед монтированием образа.',
|
||||
tips: {
|
||||
title: 'Как загрузить',
|
||||
usb1: 'Подключите NanoKVM к вашему компьютеру через USB.',
|
||||
usb2: 'Убедитесь что Виртуальный USB-накопитель смонтирован (Настройки - Виртуальный USB-накопитель).',
|
||||
usb3: 'Откройте виртуальный USB-накопитель на вашем компьютере и скопируйте файл образа в корневую директорию USB-накопителя.',
|
||||
usb2: 'Убедитесь, что виртуальный диск подключен (Настройки - Виртуальный диск).',
|
||||
usb3: 'Откройте виртуальный диск на вашем компьютере и скопируйте файл образа в корневой каталог диска.',
|
||||
scp1: 'Убедитесь что NanoKVM и ваш компьютер находятся в одной и той же сети.',
|
||||
scp2: 'Откройте терминал на вашем компьютере и используйте команду scp чтобы загрузить файл образа в директорию /data, находящуюся на NanoKVM.',
|
||||
scp3: 'Например: scp путь-к-образу root@ip-вашего-nanokvm:/data',
|
||||
@@ -151,8 +154,8 @@ const ru = {
|
||||
cancel: 'Отмена'
|
||||
},
|
||||
virtualDevice: {
|
||||
network: 'Виртуальная сеть',
|
||||
usb: 'Виртуальный USB-накопитель'
|
||||
network: 'виртуальная сетевая карта',
|
||||
disk: 'виртуальный диск'
|
||||
},
|
||||
tailscale: {
|
||||
loading: 'Загрузка...',
|
||||
|
||||
@@ -79,11 +79,13 @@ const zh = {
|
||||
title: '镜像',
|
||||
loading: '加载中',
|
||||
empty: '无镜像文件',
|
||||
mountFailed: '挂载失败',
|
||||
mountDesc: '在某些系统中,需要在远程主机中弹出虚拟硬盘后再挂载镜像。',
|
||||
tips: {
|
||||
title: '如何上传',
|
||||
usb1: '将 NanoKVM 通过 USB 连接到你的电脑;',
|
||||
usb2: '确保已经挂载了虚拟U盘(设置 - 虚拟U盘);',
|
||||
usb3: '在电脑上打开虚拟U盘,将镜像文件拷贝到虚拟U盘的根目录下。',
|
||||
usb2: '确保已经挂载了虚拟硬盘(设置 - 虚拟硬盘);',
|
||||
usb3: '在电脑上打开虚拟硬盘,将镜像文件拷贝到虚拟硬盘的根目录下。',
|
||||
scp1: '确保 NanoKVM 和你的电脑在同一个局域网内;',
|
||||
scp2: '在电脑上打开终端软件,使用 SCP 命令将镜像文件上传到 NanoKVM 的 /data 目录。',
|
||||
scp3: '示例:scp your-image-path root@your-nanokvm-ip:/data',
|
||||
@@ -145,8 +147,8 @@ const zh = {
|
||||
cancel: '取消'
|
||||
},
|
||||
virtualDevice: {
|
||||
network: '虚拟网口',
|
||||
usb: '虚拟U盘'
|
||||
network: '虚拟网卡',
|
||||
disk: '虚拟硬盘'
|
||||
},
|
||||
tailscale: {
|
||||
loading: '加载中...',
|
||||
|
||||
@@ -49,7 +49,7 @@ export const Desktop = () => {
|
||||
} else {
|
||||
setIsLoading(false);
|
||||
const now = Date.now();
|
||||
setStreamUrl(`${getBaseUrl('http')}/api/stream/mjpeg?${now}`);
|
||||
setStreamUrl(`${getBaseUrl('http')}/api/stream/mjpeg?n=${now}`);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@ import { client } from '@/lib/websocket.ts';
|
||||
import { KeyboardCodes } from './mappings.ts';
|
||||
|
||||
export const Keyboard = () => {
|
||||
const metaRef = useRef(false);
|
||||
const isMetaPressedRef = useRef(false);
|
||||
const isAltRightPressedRef = useRef(false);
|
||||
|
||||
// listen keyboard events
|
||||
useEffect(() => {
|
||||
@@ -16,11 +17,15 @@ export const Keyboard = () => {
|
||||
function handleKeyDown(event: any) {
|
||||
disableEvent(event);
|
||||
|
||||
if (event.code === 'MetaLeft' || event.code === 'MetaRight') {
|
||||
metaRef.current = true;
|
||||
if (['MetaLeft', 'MetaRight'].includes(event.code)) {
|
||||
isMetaPressedRef.current = true;
|
||||
return;
|
||||
}
|
||||
metaRef.current = false;
|
||||
isMetaPressedRef.current = false;
|
||||
|
||||
if (event.code === 'AltRight') {
|
||||
isAltRightPressedRef.current = true;
|
||||
}
|
||||
|
||||
const code = KeyboardCodes.get(event.code);
|
||||
if (!code) {
|
||||
@@ -30,7 +35,7 @@ export const Keyboard = () => {
|
||||
|
||||
const ctrl = event.ctrlKey ? 1 : 0;
|
||||
const shift = event.shiftKey ? 1 : 0;
|
||||
const alt = event.altKey ? 1 : 0;
|
||||
const alt = event.altKey ? (isAltRightPressedRef.current ? 2 : 1) : 0;
|
||||
const meta = event.metaKey ? 1 : 0;
|
||||
|
||||
const data = [1, code, ctrl, shift, alt, meta];
|
||||
@@ -41,13 +46,16 @@ export const Keyboard = () => {
|
||||
function handleKeyUp(event: any) {
|
||||
disableEvent(event);
|
||||
|
||||
if (metaRef.current) {
|
||||
if (isMetaPressedRef.current) {
|
||||
client.send([1, KeyboardCodes.get('MetaLeft')!, 0, 0, 0, 1]);
|
||||
metaRef.current = false;
|
||||
isMetaPressedRef.current = false;
|
||||
}
|
||||
|
||||
const data = [1, 0, 0, 0, 0, 0];
|
||||
client.send(data);
|
||||
if (event.code === 'AltRight') {
|
||||
isAltRightPressedRef.current = false;
|
||||
}
|
||||
|
||||
client.send([1, 0, 0, 0, 0, 0]);
|
||||
}
|
||||
|
||||
return () => {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { notification } from 'antd';
|
||||
import clsx from 'clsx';
|
||||
import { FileBoxIcon, LoaderCircleIcon, PackageIcon, PackageSearchIcon, XIcon } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -12,6 +13,7 @@ type ImagesProps = {
|
||||
|
||||
export const Images = ({ setIsMounted }: ImagesProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [notify, contextHolder] = notification.useNotification();
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [images, setImages] = useState<string[]>([]);
|
||||
@@ -72,6 +74,7 @@ export const Images = ({ setIsMounted }: ImagesProps) => {
|
||||
.mountImage(filename)
|
||||
.then((rsp) => {
|
||||
if (rsp.code !== 0) {
|
||||
openNotification();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -84,8 +87,18 @@ export const Images = ({ setIsMounted }: ImagesProps) => {
|
||||
});
|
||||
}
|
||||
|
||||
function openNotification() {
|
||||
notify.open({
|
||||
message: t('image.mountFailed'),
|
||||
description: t('image.mountDesc'),
|
||||
duration: 6
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{contextHolder}
|
||||
|
||||
{isLoading ? (
|
||||
// loading
|
||||
<div className="flex items-center space-x-2 py-2 pl-2 pr-4 text-neutral-400">
|
||||
|
||||
@@ -7,22 +7,21 @@ import * as api from '@/api/virtual-device';
|
||||
export const VirtualDevices = () => {
|
||||
const { t } = useTranslation();
|
||||
const [isNetworkOn, setIsNetworkOn] = useState(false);
|
||||
const [isUSBOn, setIsUSBOn] = useState(false);
|
||||
const [loading, setLoading] = useState(''); // '' | 'network' | 'usb'
|
||||
const [isDiskOn, setIsDiskOn] = useState(false);
|
||||
const [loading, setLoading] = useState(''); // '' | 'network' | 'disk'
|
||||
|
||||
useEffect(() => {
|
||||
api.getVirtualDevice().then((rsp) => {
|
||||
if (rsp.code !== 0) {
|
||||
console.log(rsp.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
setIsNetworkOn(rsp.data.network);
|
||||
setIsUSBOn(rsp.data.usb);
|
||||
setIsDiskOn(rsp.data.usb);
|
||||
});
|
||||
}, []);
|
||||
|
||||
function update(device: string) {
|
||||
function update(device: 'network' | 'disk') {
|
||||
if (loading) return;
|
||||
setLoading(device);
|
||||
|
||||
@@ -30,14 +29,13 @@ export const VirtualDevices = () => {
|
||||
.updateVirtualDevice(device)
|
||||
.then((rsp) => {
|
||||
if (rsp.code !== 0) {
|
||||
console.log(rsp.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (device === 'network') {
|
||||
setIsNetworkOn(rsp.data.on);
|
||||
} else {
|
||||
setIsUSBOn(rsp.data.on);
|
||||
setIsDiskOn(rsp.data.on);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -47,6 +45,14 @@ export const VirtualDevices = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className="flex cursor-pointer select-none items-center justify-between space-x-3 rounded px-3 py-1.5 text-white hover:bg-neutral-600"
|
||||
onClick={() => update('disk')}
|
||||
>
|
||||
<div>{t('virtualDevice.disk')}</div>
|
||||
<Switch size="small" checked={isDiskOn} loading={loading === 'disk'} />
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="flex cursor-pointer select-none items-center justify-between space-x-3 rounded px-3 py-1.5 text-white hover:bg-neutral-600"
|
||||
onClick={() => update('network')}
|
||||
@@ -54,14 +60,6 @@ export const VirtualDevices = () => {
|
||||
<div>{t('virtualDevice.network')}</div>
|
||||
<Switch size="small" checked={isNetworkOn} loading={loading === 'network'} />
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="flex cursor-pointer select-none items-center justify-between space-x-3 rounded px-3 py-1.5 text-white hover:bg-neutral-600"
|
||||
onClick={() => update('usb')}
|
||||
>
|
||||
<div>{t('virtualDevice.usb')}</div>
|
||||
<Switch size="small" checked={isUSBOn} loading={loading === 'usb'} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { notification } from 'antd';
|
||||
import clsx from 'clsx';
|
||||
import { FileBoxIcon, LoaderCircleIcon, PackageIcon, PackageSearchIcon, XIcon } from 'lucide-react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -12,6 +13,7 @@ type ImagesProps = {
|
||||
|
||||
export const Images = ({ setIsMounted }: ImagesProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [notify, contextHolder] = notification.useNotification();
|
||||
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [images, setImages] = useState<string[]>([]);
|
||||
@@ -72,6 +74,7 @@ export const Images = ({ setIsMounted }: ImagesProps) => {
|
||||
.mountImage(filename)
|
||||
.then((rsp) => {
|
||||
if (rsp.code !== 0) {
|
||||
openNotification();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -84,8 +87,18 @@ export const Images = ({ setIsMounted }: ImagesProps) => {
|
||||
});
|
||||
}
|
||||
|
||||
function openNotification() {
|
||||
notify.open({
|
||||
message: t('image.mountFailed'),
|
||||
description: t('image.mountDesc'),
|
||||
duration: 6
|
||||
});
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{contextHolder}
|
||||
|
||||
{isLoading ? (
|
||||
// loading
|
||||
<div className="flex items-center space-x-2 py-2 pl-2 pr-4 text-neutral-400">
|
||||
|
||||
@@ -7,22 +7,21 @@ import * as api from '@/api/virtual-device';
|
||||
export const VirtualDevices = () => {
|
||||
const { t } = useTranslation();
|
||||
const [isNetworkOn, setIsNetworkOn] = useState(false);
|
||||
const [isUSBOn, setIsUSBOn] = useState(false);
|
||||
const [loading, setLoading] = useState(''); // '' | 'network' | 'usb'
|
||||
const [isDiskOn, setIsDiskOn] = useState(false);
|
||||
const [loading, setLoading] = useState(''); // '' | 'network' | 'disk'
|
||||
|
||||
useEffect(() => {
|
||||
api.getVirtualDevice().then((rsp) => {
|
||||
if (rsp.code !== 0) {
|
||||
console.log(rsp.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
setIsNetworkOn(rsp.data.network);
|
||||
setIsUSBOn(rsp.data.usb);
|
||||
setIsDiskOn(rsp.data.disk);
|
||||
});
|
||||
}, []);
|
||||
|
||||
function update(device: string) {
|
||||
function update(device: 'network' | 'disk') {
|
||||
if (loading) return;
|
||||
setLoading(device);
|
||||
|
||||
@@ -30,14 +29,13 @@ export const VirtualDevices = () => {
|
||||
.updateVirtualDevice(device)
|
||||
.then((rsp) => {
|
||||
if (rsp.code !== 0) {
|
||||
console.log(rsp.msg);
|
||||
return;
|
||||
}
|
||||
|
||||
if (device === 'network') {
|
||||
setIsNetworkOn(rsp.data.on);
|
||||
} else {
|
||||
setIsUSBOn(rsp.data.on);
|
||||
setIsDiskOn(rsp.data.on);
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
@@ -47,6 +45,14 @@ export const VirtualDevices = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className="flex cursor-pointer select-none items-center justify-between space-x-3 rounded px-3 py-1.5 text-white hover:bg-neutral-600"
|
||||
onClick={() => update('disk')}
|
||||
>
|
||||
<div>{t('virtualDevice.disk')}</div>
|
||||
<Switch size="small" checked={isDiskOn} loading={loading === 'disk'} />
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="flex cursor-pointer select-none items-center justify-between space-x-3 rounded px-3 py-1.5 text-white hover:bg-neutral-600"
|
||||
onClick={() => update('network')}
|
||||
@@ -54,14 +60,6 @@ export const VirtualDevices = () => {
|
||||
<div>{t('virtualDevice.network')}</div>
|
||||
<Switch size="small" checked={isNetworkOn} loading={loading === 'network'} />
|
||||
</div>
|
||||
|
||||
<div
|
||||
className="flex cursor-pointer select-none items-center justify-between space-x-3 rounded px-3 py-1.5 text-white hover:bg-neutral-600"
|
||||
onClick={() => update('usb')}
|
||||
>
|
||||
<div>{t('virtualDevice.usb')}</div>
|
||||
<Switch size="small" checked={isUSBOn} loading={loading === 'usb'} />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user