From 088cada11e5733f2af491dcab92174cdc6d9807b Mon Sep 17 00:00:00 2001 From: UNITRONIX <36471318+UNITRONIX@users.noreply.github.com> Date: Mon, 6 Jul 2026 20:16:06 +0200 Subject: [PATCH] feat(remote): enhance file transfer functionality and UI improvements - Added a drag-and-drop upload feature in the Web Remote interface, allowing users to easily upload files to the currently open folder on the remote side. - Implemented file transfer features including zstd compression, overwrite confirmation dialogs, and a context menu for file management. - Updated various language files to reflect new UI elements and messages related to file transfer operations. - Enhanced CSS for improved layout and user experience in the file transfer interface. --- CHANGELOG.md | 4 + web-nodejs/lang/ar.json | 19 +- web-nodejs/lang/cs.json | 19 +- web-nodejs/lang/da.json | 19 +- web-nodejs/lang/de.json | 19 +- web-nodejs/lang/en.json | 19 +- web-nodejs/lang/es.json | 19 +- web-nodejs/lang/fi.json | 19 +- web-nodejs/lang/fr.json | 19 +- web-nodejs/lang/hi.json | 19 +- web-nodejs/lang/hu.json | 19 +- web-nodejs/lang/id.json | 19 +- web-nodejs/lang/it.json | 19 +- web-nodejs/lang/ja.json | 19 +- web-nodejs/lang/ko.json | 19 +- web-nodejs/lang/nb.json | 19 +- web-nodejs/lang/nl.json | 19 +- web-nodejs/lang/pl.json | 19 +- web-nodejs/lang/pt.json | 19 +- web-nodejs/lang/ro.json | 19 +- web-nodejs/lang/sv.json | 19 +- web-nodejs/lang/th.json | 19 +- web-nodejs/lang/tr.json | 19 +- web-nodejs/lang/uk.json | 19 +- web-nodejs/lang/vi.json | 19 +- web-nodejs/lang/zh-TW.json | 19 +- web-nodejs/lang/zh.json | 19 +- web-nodejs/public/css/remote.css | 188 +++++++++- web-nodejs/public/js/rdclient/file-modal.js | 354 ++++++++++++++++-- web-nodejs/public/js/rdclient/filetransfer.js | 259 +++++++++++-- web-nodejs/public/js/rdclient/protocol.js | 4 + web-nodejs/tests/filetransfer.logic.test.js | 52 +++ web-nodejs/tests/rdclient.protocol.test.js | 26 ++ 33 files changed, 1262 insertions(+), 119 deletions(-) create mode 100644 web-nodejs/tests/filetransfer.logic.test.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f0418ed..ef08c795 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ ## [Unreleased] +### Added +- **Web Remote — File Transfer drop zone:** left panel shows a drag-and-drop upload box (click to pick files, multi-file supported). Uploads go to the folder currently open on the remote side; progress appears in the Transfers column. +- **Web Remote — RustDesk file transfer parity:** 128 KB blocks, zstd upload compression, resume via `offset_blk` / `transferred_size`, overwrite confirmation dialog (Skip / Overwrite / apply to all), remote context menu (rename, delete, new folder), hidden-files toggle, and Resume in the transfer queue after errors. + ### Changed - **Docker — official single container (default):** `install.sh` and quick-start docs now deploy one pre-built image (`ghcr.io/unitronix/betterdesk`) via `docker-compose.quick.single.yml`. Updates are a single `docker compose pull && up -d`. Legacy two-container layout remains available with `install.sh --split` or `docker-compose.quick.yml`. Panel update instructions respect `BETTERDESK_DOCKER_LAYOUT` (`single` vs `split`). Migrating from split to single reuses the same named volumes; RustDesk client API URL changes from port `21114` to `21121`. diff --git a/web-nodejs/lang/ar.json b/web-nodejs/lang/ar.json index 61a0a899..0dbd6b5a 100644 --- a/web-nodejs/lang/ar.json +++ b/web-nodejs/lang/ar.json @@ -1261,7 +1261,7 @@ "file_status_downloaded": "تم التنزيل", "file_status_uploaded": "تم الرفع", "file_drop_upload_hint": "أفلت للرفع إلى: {path}", - "file_local_upload_hint": "اسحب الملفات إلى اللوحة البعيدة أو استخدم الرفع. تُحفظ التنزيلات في مجلد المتصفح الافتراضي.", + "file_local_upload_hint": "أسقط الملفات في المربع على اليسار أو انقر للرفع. الوجهة هي المجلد المفتوح على الجانب البعيد.", "file_transfer_stalled": "الجهاز البعيد لم يبدأ النقل", "file_no_local_tree": "اختر مجلدًا لتصفح الملفات المحلية (اختياري)", "reset_keyboard": "إعادة تعيين حالة لوحة المفاتيح", @@ -1269,7 +1269,22 @@ "keyboard_mode": "وضع لوحة المفاتيح", "keyboard_mode_auto": "تلقائي (Map، مثل RustDesk)", "keyboard_mode_legacy": "Legacy (حرف)", - "keyboard_mode_map": "Map (رمز مسح فعلي)" + "keyboard_mode_map": "Map (رمز مسح فعلي)", + "file_dropzone_title": "أسقط الملفات هنا", + "file_dropzone_subtitle": "أو انقر لاختيار الملفات", + "file_dropzone_multiple": "يدعم عدة ملفات", + "file_dropzone_waiting": "في انتظار الاتصال البعيد…", + "file_overwrite_title": "الملف موجود بالفعل", + "file_overwrite_message": "يوجد ملف باسم «{name}» على الجهاز البعيد. هل تريد استبداله؟", + "file_overwrite_skip": "تخطي", + "file_overwrite_skip_all": "تخطي الكل", + "file_overwrite_confirm": "استبدال", + "file_overwrite_all": "استبدال الكل", + "file_resume": "استئناف", + "file_open": "فتح", + "file_up": "أعلى", + "file_home": "الرئيسية", + "file_hide_hidden": "إخفاء الملفات المخفية" }, "branding": { "identity_title": "هوية العلامة التجارية", diff --git a/web-nodejs/lang/cs.json b/web-nodejs/lang/cs.json index 3333f808..707a349f 100644 --- a/web-nodejs/lang/cs.json +++ b/web-nodejs/lang/cs.json @@ -1260,9 +1260,24 @@ "file_status_downloaded": "Staženo", "file_status_uploaded": "Nahráno", "file_drop_upload_hint": "Přetáhněte pro nahrání do: {path}", - "file_local_upload_hint": "Přetáhněte soubory na vzdálený panel nebo použijte Nahrát. Stažené soubory se uloží do výchozí složky prohlížeče.", + "file_local_upload_hint": "Přetáhněte soubory do pole vlevo nebo klikněte pro nahrání. Cílem je složka otevřená na vzdálené straně.", "file_transfer_stalled": "Vzdálené zařízení nezahájilo přenos", - "file_no_local_tree": "Vyberte složku pro procházení místních souborů (volitelné)" + "file_no_local_tree": "Vyberte složku pro procházení místních souborů (volitelné)", + "file_dropzone_title": "Přetáhněte soubory sem", + "file_dropzone_subtitle": "nebo klikněte pro výběr souborů", + "file_dropzone_multiple": "Podporováno více souborů", + "file_dropzone_waiting": "Čekání na vzdálené připojení…", + "file_overwrite_title": "Soubor již existuje", + "file_overwrite_message": "Soubor „{name}“ již na vzdáleném počítači existuje. Přepsat?", + "file_overwrite_skip": "Přeskočit", + "file_overwrite_skip_all": "Přeskočit vše", + "file_overwrite_confirm": "Přepsat", + "file_overwrite_all": "Přepsat vše", + "file_resume": "Obnovit", + "file_open": "Otevřít", + "file_up": "Nahoru", + "file_home": "Domů", + "file_hide_hidden": "Skrýt skryté soubory" }, "branding": { "identity_title": "Identita značky", diff --git a/web-nodejs/lang/da.json b/web-nodejs/lang/da.json index b951461a..3765b968 100644 --- a/web-nodejs/lang/da.json +++ b/web-nodejs/lang/da.json @@ -1266,9 +1266,24 @@ "file_status_downloaded": "Downloadet", "file_status_uploaded": "Uploadet", "file_drop_upload_hint": "Slip for at uploade til: {path}", - "file_local_upload_hint": "Træk filer til det fjernpanel eller brug Upload. Downloads gemmes i browserens standardmappe.", + "file_local_upload_hint": "Slip filer i feltet til venstre eller klik for at uploade. Destinationen er mappen åben på remote-siden.", "file_transfer_stalled": "Fjernenhed startede ikke overførslen", - "file_no_local_tree": "Vælg en mappe for at gennemse lokale filer (valgfrit)" + "file_no_local_tree": "Vælg en mappe for at gennemse lokale filer (valgfrit)", + "file_dropzone_title": "Slip filer her", + "file_dropzone_subtitle": "eller klik for at vælge filer", + "file_dropzone_multiple": "Flere filer understøttes", + "file_dropzone_waiting": "Venter på remote-forbindelse…", + "file_overwrite_title": "Filen findes allerede", + "file_overwrite_message": "En fil ved navn «{name}» findes allerede på remote-computeren. Overskrive?", + "file_overwrite_skip": "Spring over", + "file_overwrite_skip_all": "Spring alle over", + "file_overwrite_confirm": "Overskriv", + "file_overwrite_all": "Overskriv alle", + "file_resume": "Genoptag", + "file_open": "Åbn", + "file_up": "Op", + "file_home": "Hjem", + "file_hide_hidden": "Skjul skjulte filer" }, "branding": { "identity_title": "Brand Identitet", diff --git a/web-nodejs/lang/de.json b/web-nodejs/lang/de.json index 621ca0b3..28bc1685 100644 --- a/web-nodejs/lang/de.json +++ b/web-nodejs/lang/de.json @@ -1260,9 +1260,24 @@ "file_status_downloaded": "Heruntergeladen", "file_status_uploaded": "Hochgeladen", "file_drop_upload_hint": "Zum Hochladen hier ablegen: {path}", - "file_local_upload_hint": "Dateien auf das Remote-Panel ziehen oder Hochladen verwenden. Downloads landen im Standardordner des Browsers.", + "file_local_upload_hint": "Dateien links ablegen oder klicken zum Hochladen. Ziel ist der auf der Remote-Seite geöffnete Ordner.", "file_transfer_stalled": "Remote-Gerät hat Transfer nicht gestartet", - "file_no_local_tree": "Ordner wählen, um lokale Dateien zu durchsuchen (optional)" + "file_no_local_tree": "Ordner wählen, um lokale Dateien zu durchsuchen (optional)", + "file_dropzone_title": "Dateien hier ablegen", + "file_dropzone_subtitle": "oder klicken zum Auswählen", + "file_dropzone_multiple": "Mehrere Dateien unterstützt", + "file_dropzone_waiting": "Warte auf Remote-Verbindung…", + "file_overwrite_title": "Datei existiert bereits", + "file_overwrite_message": "Die Datei „{name}“ existiert bereits auf dem Remote-Computer. Überschreiben?", + "file_overwrite_skip": "Überspringen", + "file_overwrite_skip_all": "Alle überspringen", + "file_overwrite_confirm": "Überschreiben", + "file_overwrite_all": "Alle überschreiben", + "file_resume": "Fortsetzen", + "file_open": "Öffnen", + "file_up": "Nach oben", + "file_home": "Start", + "file_hide_hidden": "Versteckte Dateien ausblenden" }, "branding": { "identity_title": "Markenidentität", diff --git a/web-nodejs/lang/en.json b/web-nodejs/lang/en.json index d4d8585d..bf69e497 100644 --- a/web-nodejs/lang/en.json +++ b/web-nodejs/lang/en.json @@ -1281,9 +1281,24 @@ "file_status_downloaded": "Downloaded", "file_status_uploaded": "Uploaded", "file_drop_upload_hint": "Drop to upload to: {path}", - "file_local_upload_hint": "Drag files onto the remote panel or use Upload. Downloads save to your browser's default folder.", + "file_local_upload_hint": "Drop files in the box on the left or click it to upload. Destination is the folder open on the remote side.", "file_transfer_stalled": "Remote did not start transfer", - "file_no_local_tree": "Choose a folder to browse local files (optional)" + "file_no_local_tree": "Choose a folder to browse local files (optional)", + "file_dropzone_title": "Drop files here", + "file_dropzone_subtitle": "or click to choose files", + "file_dropzone_multiple": "Multiple files supported", + "file_dropzone_waiting": "Waiting for remote connection…", + "file_overwrite_title": "File already exists", + "file_overwrite_message": "A file named \"{name}\" already exists on the remote computer. Overwrite it?", + "file_overwrite_skip": "Skip", + "file_overwrite_skip_all": "Skip all", + "file_overwrite_confirm": "Overwrite", + "file_overwrite_all": "Overwrite all", + "file_resume": "Resume", + "file_open": "Open", + "file_up": "Up", + "file_home": "Home", + "file_hide_hidden": "Hide hidden files" }, "remote_dashboard": { "title": "Remote Desktop Client", diff --git a/web-nodejs/lang/es.json b/web-nodejs/lang/es.json index c9eee561..ec447f0f 100644 --- a/web-nodejs/lang/es.json +++ b/web-nodejs/lang/es.json @@ -1260,9 +1260,24 @@ "file_status_downloaded": "Descargado", "file_status_uploaded": "Subido", "file_drop_upload_hint": "Suelta para subir a: {path}", - "file_local_upload_hint": "Arrastra archivos al panel remoto o usa Subir. Las descargas se guardan en la carpeta predeterminada del navegador.", + "file_local_upload_hint": "Suelta archivos en el recuadro izquierdo o haz clic para subir. El destino es la carpeta abierta en el equipo remoto.", "file_transfer_stalled": "El dispositivo remoto no inició la transferencia", - "file_no_local_tree": "Elige una carpeta para explorar archivos locales (opcional)" + "file_no_local_tree": "Elige una carpeta para explorar archivos locales (opcional)", + "file_dropzone_title": "Suelta archivos aquí", + "file_dropzone_subtitle": "o haz clic para elegir archivos", + "file_dropzone_multiple": "Varios archivos admitidos", + "file_dropzone_waiting": "Esperando conexión remota…", + "file_overwrite_title": "El archivo ya existe", + "file_overwrite_message": "Ya existe un archivo llamado «{name}» en el equipo remoto. ¿Sobrescribir?", + "file_overwrite_skip": "Omitir", + "file_overwrite_skip_all": "Omitir todos", + "file_overwrite_confirm": "Sobrescribir", + "file_overwrite_all": "Sobrescribir todos", + "file_resume": "Reanudar", + "file_open": "Abrir", + "file_up": "Subir", + "file_home": "Inicio", + "file_hide_hidden": "Ocultar archivos ocultos" }, "branding": { "identity_title": "Identidad de marca", diff --git a/web-nodejs/lang/fi.json b/web-nodejs/lang/fi.json index 8b7ba075..4209dc33 100644 --- a/web-nodejs/lang/fi.json +++ b/web-nodejs/lang/fi.json @@ -1266,9 +1266,24 @@ "file_status_downloaded": "Ladattu", "file_status_uploaded": "Lähetetty", "file_drop_upload_hint": "Pudota ladataksesi kohteeseen: {path}", - "file_local_upload_hint": "Vedä tiedostot etäpaneeliin tai käytä Lataa. Lataukset tallentuvat selaimen oletuskansioon.", + "file_local_upload_hint": "Pudota tiedostot vasemmalla olevaan laatikkoon tai napsauta ladataksesi. Kohde on etäpuolella avoinna oleva kansio.", "file_transfer_stalled": "Etälaite ei aloittanut siirtoa", - "file_no_local_tree": "Valitse kansio paikallisten tiedostojen selaamiseen (valinnainen)" + "file_no_local_tree": "Valitse kansio paikallisten tiedostojen selaamiseen (valinnainen)", + "file_dropzone_title": "Pudota tiedostot tähän", + "file_dropzone_subtitle": "tai napsauta valitaksesi tiedostot", + "file_dropzone_multiple": "Useita tiedostoja tuettu", + "file_dropzone_waiting": "Odotetaan etäyhteyttä…", + "file_overwrite_title": "Tiedosto on jo olemassa", + "file_overwrite_message": "Tiedosto «{name}» on jo etätietokoneella. Korvataanko?", + "file_overwrite_skip": "Ohita", + "file_overwrite_skip_all": "Ohita kaikki", + "file_overwrite_confirm": "Korvaa", + "file_overwrite_all": "Korvaa kaikki", + "file_resume": "Jatka", + "file_open": "Avaa", + "file_up": "Ylös", + "file_home": "Alku", + "file_hide_hidden": "Piilota piilotetut tiedostot" }, "branding": { "identity_title": "Brändin identiteetti", diff --git a/web-nodejs/lang/fr.json b/web-nodejs/lang/fr.json index 39434f7c..410aaf2c 100644 --- a/web-nodejs/lang/fr.json +++ b/web-nodejs/lang/fr.json @@ -1277,9 +1277,24 @@ "file_status_downloaded": "Téléchargé", "file_status_uploaded": "Envoyé", "file_drop_upload_hint": "Déposez pour envoyer vers : {path}", - "file_local_upload_hint": "Glissez des fichiers sur le panneau distant ou utilisez Envoyer. Les téléchargements vont dans le dossier par défaut du navigateur.", + "file_local_upload_hint": "Déposez les fichiers dans la zone à gauche ou cliquez pour téléverser. La destination est le dossier ouvert côté distant.", "file_transfer_stalled": "L'appareil distant n'a pas démarré le transfert", - "file_no_local_tree": "Choisissez un dossier pour parcourir les fichiers locaux (facultatif)" + "file_no_local_tree": "Choisissez un dossier pour parcourir les fichiers locaux (facultatif)", + "file_dropzone_title": "Déposez les fichiers ici", + "file_dropzone_subtitle": "ou cliquez pour choisir des fichiers", + "file_dropzone_multiple": "Plusieurs fichiers pris en charge", + "file_dropzone_waiting": "En attente de la connexion distante…", + "file_overwrite_title": "Le fichier existe déjà", + "file_overwrite_message": "Un fichier nommé « {name} » existe déjà sur l’ordinateur distant. Remplacer ?", + "file_overwrite_skip": "Ignorer", + "file_overwrite_skip_all": "Tout ignorer", + "file_overwrite_confirm": "Remplacer", + "file_overwrite_all": "Tout remplacer", + "file_resume": "Reprendre", + "file_open": "Ouvrir", + "file_up": "Monter", + "file_home": "Accueil", + "file_hide_hidden": "Masquer les fichiers cachés" }, "branding": { "identity_title": "Identité de marque", diff --git a/web-nodejs/lang/hi.json b/web-nodejs/lang/hi.json index f2d6136e..2a4ddb48 100644 --- a/web-nodejs/lang/hi.json +++ b/web-nodejs/lang/hi.json @@ -1266,9 +1266,24 @@ "file_status_downloaded": "डाउनलोड हो गया", "file_status_uploaded": "अपलोड हो गया", "file_drop_upload_hint": "अपलोड करने के लिए यहाँ छोड़ें: {path}", - "file_local_upload_hint": "फ़ाइलों को रिमोट पैनल पर खींचें या अपलोड का उपयोग करें। डाउनलोड आपके ब्राउज़र के डिफ़ॉल्ट फ़ोल्डर में सहेजे जाते हैं।", + "file_local_upload_hint": "बाएँ बॉक्स में फ़ाइलें छोड़ें या अपलोड के लिए क्लिक करें। गंतव्य रिमोट पर खुला फ़ोल्डर है।", "file_transfer_stalled": "रिमोट ने स्थानांतरण शुरू नहीं किया", - "file_no_local_tree": "स्थानीय फ़ाइलें ब्राउज़ करने के लिए फ़ोल्डर चुनें (वैकल्पिक)" + "file_no_local_tree": "स्थानीय फ़ाइलें ब्राउज़ करने के लिए फ़ोल्डर चुनें (वैकल्पिक)", + "file_dropzone_title": "फ़ाइलें यहाँ छोड़ें", + "file_dropzone_subtitle": "या फ़ाइलें चुनने के लिए क्लिक करें", + "file_dropzone_multiple": "कई फ़ाइलें समर्थित", + "file_dropzone_waiting": "रिमोट कनेक्शन की प्रतीक्षा…", + "file_overwrite_title": "फ़ाइल पहले से मौजूद है", + "file_overwrite_message": "«{name}» नाम की फ़ाइल रिमोट कंप्यूटर पर पहले से है। ओवरराइट करें?", + "file_overwrite_skip": "छोड़ें", + "file_overwrite_skip_all": "सभी छोड़ें", + "file_overwrite_confirm": "ओवरराइट", + "file_overwrite_all": "सभी ओवरराइट", + "file_resume": "फिर से शुरू", + "file_open": "खोलें", + "file_up": "ऊपर", + "file_home": "होम", + "file_hide_hidden": "छिपी फ़ाइलें छुपाएँ" }, "branding": { "identity_title": "ब्रांड पहचान", diff --git a/web-nodejs/lang/hu.json b/web-nodejs/lang/hu.json index 00908b0a..e9427030 100644 --- a/web-nodejs/lang/hu.json +++ b/web-nodejs/lang/hu.json @@ -1266,9 +1266,24 @@ "file_status_downloaded": "Letöltve", "file_status_uploaded": "Feltöltve", "file_drop_upload_hint": "Engedje el a feltöltéshez ide: {path}", - "file_local_upload_hint": "Húzza a fájlokat a távoli panelre, vagy használja a Feltöltést. A letöltések a böngésző alapértelmezett mappájába kerülnek.", + "file_local_upload_hint": "Húzza ide a fájlokat a bal oldali mezőbe, vagy kattintson a feltöltéshez. A cél a távoli oldalon megnyitott mappa.", "file_transfer_stalled": "A távoli eszköz nem indította el az átvitelt", - "file_no_local_tree": "Válasszon mappát a helyi fájlok böngészéséhez (opcionális)" + "file_no_local_tree": "Válasszon mappát a helyi fájlok böngészéséhez (opcionális)", + "file_dropzone_title": "Húzza ide a fájlokat", + "file_dropzone_subtitle": "vagy kattintson a fájlok kiválasztásához", + "file_dropzone_multiple": "Több fájl támogatott", + "file_dropzone_waiting": "Várakozás a távoli kapcsolatra…", + "file_overwrite_title": "A fájl már létezik", + "file_overwrite_message": "A(z) «{name}» nevű fájl már létezik a távoli gépen. Felülírja?", + "file_overwrite_skip": "Kihagyás", + "file_overwrite_skip_all": "Összes kihagyása", + "file_overwrite_confirm": "Felülírás", + "file_overwrite_all": "Összes felülírása", + "file_resume": "Folytatás", + "file_open": "Megnyitás", + "file_up": "Fel", + "file_home": "Kezdőlap", + "file_hide_hidden": "Rejtett fájlok elrejtése" }, "branding": { "identity_title": "Márkaidentitás", diff --git a/web-nodejs/lang/id.json b/web-nodejs/lang/id.json index 4fbe6d3a..c5778c6e 100644 --- a/web-nodejs/lang/id.json +++ b/web-nodejs/lang/id.json @@ -1266,9 +1266,24 @@ "file_status_downloaded": "Diunduh", "file_status_uploaded": "Diunggah", "file_drop_upload_hint": "Lepaskan untuk mengunggah ke: {path}", - "file_local_upload_hint": "Seret file ke panel remote atau gunakan Unggah. Unduhan disimpan ke folder default browser.", + "file_local_upload_hint": "Letakkan file di kotak kiri atau klik untuk mengunggah. Tujuan adalah folder yang terbuka di sisi remote.", "file_transfer_stalled": "Perangkat remote tidak memulai transfer", - "file_no_local_tree": "Pilih folder untuk menelusuri file lokal (opsional)" + "file_no_local_tree": "Pilih folder untuk menelusuri file lokal (opsional)", + "file_dropzone_title": "Letakkan file di sini", + "file_dropzone_subtitle": "atau klik untuk memilih file", + "file_dropzone_multiple": "Beberapa file didukung", + "file_dropzone_waiting": "Menunggu koneksi remote…", + "file_overwrite_title": "File sudah ada", + "file_overwrite_message": "File bernama «{name}» sudah ada di komputer remote. Timpa?", + "file_overwrite_skip": "Lewati", + "file_overwrite_skip_all": "Lewati semua", + "file_overwrite_confirm": "Timpa", + "file_overwrite_all": "Timpa semua", + "file_resume": "Lanjutkan", + "file_open": "Buka", + "file_up": "Naik", + "file_home": "Beranda", + "file_hide_hidden": "Sembunyikan file tersembunyi" }, "branding": { "identity_title": "Identitas Merek", diff --git a/web-nodejs/lang/it.json b/web-nodejs/lang/it.json index 7850c649..3d2ffb30 100644 --- a/web-nodejs/lang/it.json +++ b/web-nodejs/lang/it.json @@ -1260,9 +1260,24 @@ "file_status_downloaded": "Scaricato", "file_status_uploaded": "Caricato", "file_drop_upload_hint": "Rilascia per caricare in: {path}", - "file_local_upload_hint": "Trascina i file sul pannello remoto o usa Carica. I download vanno nella cartella predefinita del browser.", + "file_local_upload_hint": "Trascina i file nel riquadro a sinistra o clicca per caricare. La destinazione è la cartella aperta sul lato remoto.", "file_transfer_stalled": "Il dispositivo remoto non ha avviato il trasferimento", - "file_no_local_tree": "Scegli una cartella per sfogliare i file locali (facoltativo)" + "file_no_local_tree": "Scegli una cartella per sfogliare i file locali (facoltativo)", + "file_dropzone_title": "Trascina i file qui", + "file_dropzone_subtitle": "o clicca per scegliere i file", + "file_dropzone_multiple": "Più file supportati", + "file_dropzone_waiting": "In attesa della connessione remota…", + "file_overwrite_title": "Il file esiste già", + "file_overwrite_message": "Un file denominato «{name}» esiste già sul computer remoto. Sovrascrivere?", + "file_overwrite_skip": "Salta", + "file_overwrite_skip_all": "Salta tutti", + "file_overwrite_confirm": "Sovrascrivi", + "file_overwrite_all": "Sovrascrivi tutti", + "file_resume": "Riprendi", + "file_open": "Apri", + "file_up": "Su", + "file_home": "Home", + "file_hide_hidden": "Nascondi file nascosti" }, "branding": { "identity_title": "Identità del marchio", diff --git a/web-nodejs/lang/ja.json b/web-nodejs/lang/ja.json index 0a0e7434..f27aea0b 100644 --- a/web-nodejs/lang/ja.json +++ b/web-nodejs/lang/ja.json @@ -1260,9 +1260,24 @@ "file_status_downloaded": "ダウンロード完了", "file_status_uploaded": "アップロード完了", "file_drop_upload_hint": "ドロップしてアップロード先: {path}", - "file_local_upload_hint": "ファイルをリモートパネルにドラッグするか、アップロードを使用してください。ダウンロードはブラウザの既定フォルダーに保存されます。", + "file_local_upload_hint": "左のボックスにファイルをドロップするか、クリックしてアップロードします。送信先はリモート側で開いているフォルダーです。", "file_transfer_stalled": "リモートが転送を開始しませんでした", - "file_no_local_tree": "ローカルファイルを参照するフォルダーを選択(任意)" + "file_no_local_tree": "ローカルファイルを参照するフォルダーを選択(任意)", + "file_dropzone_title": "ここにファイルをドロップ", + "file_dropzone_subtitle": "またはクリックしてファイルを選択", + "file_dropzone_multiple": "複数ファイルに対応", + "file_dropzone_waiting": "リモート接続を待機中…", + "file_overwrite_title": "ファイルは既に存在します", + "file_overwrite_message": "リモートに「{name}」というファイルが既にあります。上書きしますか?", + "file_overwrite_skip": "スキップ", + "file_overwrite_skip_all": "すべてスキップ", + "file_overwrite_confirm": "上書き", + "file_overwrite_all": "すべて上書き", + "file_resume": "再開", + "file_open": "開く", + "file_up": "上へ", + "file_home": "ホーム", + "file_hide_hidden": "隠しファイルを非表示" }, "branding": { "identity_title": "ブランドアイデンティティ", diff --git a/web-nodejs/lang/ko.json b/web-nodejs/lang/ko.json index aa3659d6..a7250e6f 100644 --- a/web-nodejs/lang/ko.json +++ b/web-nodejs/lang/ko.json @@ -1260,9 +1260,24 @@ "file_status_downloaded": "다운로드됨", "file_status_uploaded": "업로드됨", "file_drop_upload_hint": "업로드 대상에 놓기: {path}", - "file_local_upload_hint": "파일을 원격 패널에 끌어다 놓거나 업로드를 사용하세요. 다운로드는 브라우저 기본 폴더에 저장됩니다.", + "file_local_upload_hint": "왼쪽 상자에 파일을 놓거나 클릭하여 업로드하세요. 대상은 원격 쪽에서 열린 폴더입니다.", "file_transfer_stalled": "원격 장치가 전송을 시작하지 않았습니다", - "file_no_local_tree": "로컬 파일을 탐색하려면 폴더 선택(선택 사항)" + "file_no_local_tree": "로컬 파일을 탐색하려면 폴더 선택(선택 사항)", + "file_dropzone_title": "여기에 파일 놓기", + "file_dropzone_subtitle": "또는 클릭하여 파일 선택", + "file_dropzone_multiple": "여러 파일 지원", + "file_dropzone_waiting": "원격 연결 대기 중…", + "file_overwrite_title": "파일이 이미 있습니다", + "file_overwrite_message": "원격 컴퓨터에 «{name}» 파일이 이미 있습니다. 덮어쓸까요?", + "file_overwrite_skip": "건너뛰기", + "file_overwrite_skip_all": "모두 건너뛰기", + "file_overwrite_confirm": "덮어쓰기", + "file_overwrite_all": "모두 덮어쓰기", + "file_resume": "재개", + "file_open": "열기", + "file_up": "위로", + "file_home": "홈", + "file_hide_hidden": "숨김 파일 숨기기" }, "branding": { "identity_title": "브랜드 아이덴티티", diff --git a/web-nodejs/lang/nb.json b/web-nodejs/lang/nb.json index 5706bcf5..81291548 100644 --- a/web-nodejs/lang/nb.json +++ b/web-nodejs/lang/nb.json @@ -1266,9 +1266,24 @@ "file_status_downloaded": "Lastet ned", "file_status_uploaded": "Lastet opp", "file_drop_upload_hint": "Slipp for å laste opp til: {path}", - "file_local_upload_hint": "Dra filer til fjernpanelet eller bruk Last opp. Nedlastinger lagres i nettleserens standardmappe.", + "file_local_upload_hint": "Slipp filer i boksen til venstre eller klikk for å laste opp. Målet er mappen som er åpen på fjernsiden.", "file_transfer_stalled": "Fjernenheten startet ikke overføringen", - "file_no_local_tree": "Velg en mappe for å bla i lokale filer (valgfritt)" + "file_no_local_tree": "Velg en mappe for å bla i lokale filer (valgfritt)", + "file_dropzone_title": "Slipp filer her", + "file_dropzone_subtitle": "eller klikk for å velge filer", + "file_dropzone_multiple": "Flere filer støttes", + "file_dropzone_waiting": "Venter på fjernforbindelse…", + "file_overwrite_title": "Filen finnes allerede", + "file_overwrite_message": "En fil med navnet «{name}» finnes allerede på fjernmaskinen. Overskrive?", + "file_overwrite_skip": "Hopp over", + "file_overwrite_skip_all": "Hopp over alle", + "file_overwrite_confirm": "Overskriv", + "file_overwrite_all": "Overskriv alle", + "file_resume": "Gjenoppta", + "file_open": "Åpne", + "file_up": "Opp", + "file_home": "Hjem", + "file_hide_hidden": "Skjul skjulte filer" }, "branding": { "identity_title": "Merkeidentitet", diff --git a/web-nodejs/lang/nl.json b/web-nodejs/lang/nl.json index 90beeba2..f6fedd6f 100644 --- a/web-nodejs/lang/nl.json +++ b/web-nodejs/lang/nl.json @@ -1260,9 +1260,24 @@ "file_status_downloaded": "Gedownload", "file_status_uploaded": "Geüpload", "file_drop_upload_hint": "Laat los om te uploaden naar: {path}", - "file_local_upload_hint": "Sleep bestanden naar het externe paneel of gebruik Uploaden. Downloads worden opgeslagen in de standaardmap van de browser.", + "file_local_upload_hint": "Sleep bestanden in het vak links of klik om te uploaden. Bestemming is de map open aan de remote-kant.", "file_transfer_stalled": "Extern apparaat startte overdracht niet", - "file_no_local_tree": "Kies een map om lokale bestanden te bladeren (optioneel)" + "file_no_local_tree": "Kies een map om lokale bestanden te bladeren (optioneel)", + "file_dropzone_title": "Sleep bestanden hierheen", + "file_dropzone_subtitle": "of klik om bestanden te kiezen", + "file_dropzone_multiple": "Meerdere bestanden ondersteund", + "file_dropzone_waiting": "Wachten op remote-verbinding…", + "file_overwrite_title": "Bestand bestaat al", + "file_overwrite_message": "Er bestaat al een bestand «{name}» op de remote-computer. Overschrijven?", + "file_overwrite_skip": "Overslaan", + "file_overwrite_skip_all": "Alles overslaan", + "file_overwrite_confirm": "Overschrijven", + "file_overwrite_all": "Alles overschrijven", + "file_resume": "Hervatten", + "file_open": "Openen", + "file_up": "Omhoog", + "file_home": "Home", + "file_hide_hidden": "Verborgen bestanden verbergen" }, "branding": { "identity_title": "Merkidentiteit", diff --git a/web-nodejs/lang/pl.json b/web-nodejs/lang/pl.json index 6627cdcb..a2b89a8a 100644 --- a/web-nodejs/lang/pl.json +++ b/web-nodejs/lang/pl.json @@ -1273,9 +1273,24 @@ "file_status_downloaded": "Pobrano", "file_status_uploaded": "Wysłano", "file_drop_upload_hint": "Upuść, aby przesłać do: {path}", - "file_local_upload_hint": "Przeciągnij pliki na panel zdalny lub użyj Prześlij. Pobrania trafiają do domyślnego folderu przeglądarki.", + "file_local_upload_hint": "Upuść pliki w polu po lewej lub kliknij je, aby przesłać. Folder docelowy to ten otwarty po stronie zdalnej.", "file_transfer_stalled": "Urządzenie zdalne nie rozpoczęło transferu", - "file_no_local_tree": "Wybierz folder, aby przeglądać pliki lokalne (opcjonalnie)" + "file_no_local_tree": "Wybierz folder, aby przeglądać pliki lokalne (opcjonalnie)", + "file_dropzone_title": "Upuść pliki tutaj", + "file_dropzone_subtitle": "lub kliknij, aby wybrać pliki", + "file_dropzone_multiple": "Obsługiwane wiele plików", + "file_dropzone_waiting": "Oczekiwanie na połączenie ze zdalnym komputerem…", + "file_overwrite_title": "Plik już istnieje", + "file_overwrite_message": "Plik „{name}” już istnieje na komputerze zdalnym. Nadpisać?", + "file_overwrite_skip": "Pomiń", + "file_overwrite_skip_all": "Pomiń wszystkie", + "file_overwrite_confirm": "Nadpisz", + "file_overwrite_all": "Nadpisz wszystkie", + "file_resume": "Wznów", + "file_open": "Otwórz", + "file_up": "W górę", + "file_home": "Początek", + "file_hide_hidden": "Ukryj ukryte pliki" }, "branding": { "identity_title": "Identyfikacja marki", diff --git a/web-nodejs/lang/pt.json b/web-nodejs/lang/pt.json index e40ff12f..2567570e 100644 --- a/web-nodejs/lang/pt.json +++ b/web-nodejs/lang/pt.json @@ -1260,9 +1260,24 @@ "file_status_downloaded": "Transferido", "file_status_uploaded": "Enviado", "file_drop_upload_hint": "Largue para enviar para: {path}", - "file_local_upload_hint": "Arraste ficheiros para o painel remoto ou use Enviar. As transferências são guardadas na pasta predefinida do navegador.", + "file_local_upload_hint": "Solte ficheiros na caixa à esquerda ou clique para enviar. O destino é a pasta aberta no lado remoto.", "file_transfer_stalled": "O dispositivo remoto não iniciou a transferência", - "file_no_local_tree": "Escolha uma pasta para procurar ficheiros locais (opcional)" + "file_no_local_tree": "Escolha uma pasta para procurar ficheiros locais (opcional)", + "file_dropzone_title": "Solte ficheiros aqui", + "file_dropzone_subtitle": "ou clique para escolher ficheiros", + "file_dropzone_multiple": "Vários ficheiros suportados", + "file_dropzone_waiting": "A aguardar ligação remota…", + "file_overwrite_title": "O ficheiro já existe", + "file_overwrite_message": "Já existe um ficheiro chamado «{name}» no computador remoto. Substituir?", + "file_overwrite_skip": "Ignorar", + "file_overwrite_skip_all": "Ignorar todos", + "file_overwrite_confirm": "Substituir", + "file_overwrite_all": "Substituir todos", + "file_resume": "Retomar", + "file_open": "Abrir", + "file_up": "Acima", + "file_home": "Início", + "file_hide_hidden": "Ocultar ficheiros ocultos" }, "branding": { "identity_title": "Identidade da marca", diff --git a/web-nodejs/lang/ro.json b/web-nodejs/lang/ro.json index 8a38ea6d..98cbf9ca 100644 --- a/web-nodejs/lang/ro.json +++ b/web-nodejs/lang/ro.json @@ -1266,9 +1266,24 @@ "file_status_downloaded": "Descărcat", "file_status_uploaded": "Încărcat", "file_drop_upload_hint": "Plasați pentru a încărca în: {path}", - "file_local_upload_hint": "Trageți fișiere pe panoul la distanță sau folosiți Încărcare. Descărcările se salvează în folderul implicit al browserului.", + "file_local_upload_hint": "Trageți fișierele în caseta din stânga sau faceți clic pentru încărcare. Destinația este folderul deschis pe partea remote.", "file_transfer_stalled": "Dispozitivul la distanță nu a pornit transferul", - "file_no_local_tree": "Alegeți un folder pentru a răsfoi fișierele locale (opțional)" + "file_no_local_tree": "Alegeți un folder pentru a răsfoi fișierele locale (opțional)", + "file_dropzone_title": "Trageți fișierele aici", + "file_dropzone_subtitle": "sau faceți clic pentru a alege fișiere", + "file_dropzone_multiple": "Mai multe fișiere acceptate", + "file_dropzone_waiting": "Se așteaptă conexiunea remote…", + "file_overwrite_title": "Fișierul există deja", + "file_overwrite_message": "Un fișier numit «{name}» există deja pe calculatorul remote. Suprascrieți?", + "file_overwrite_skip": "Omite", + "file_overwrite_skip_all": "Omite toate", + "file_overwrite_confirm": "Suprascrie", + "file_overwrite_all": "Suprascrie toate", + "file_resume": "Reia", + "file_open": "Deschide", + "file_up": "Sus", + "file_home": "Acasă", + "file_hide_hidden": "Ascunde fișierele ascunse" }, "branding": { "identity_title": "Identitatea de marcă", diff --git a/web-nodejs/lang/sv.json b/web-nodejs/lang/sv.json index 0b5b9c68..ba6c42d3 100644 --- a/web-nodejs/lang/sv.json +++ b/web-nodejs/lang/sv.json @@ -1266,9 +1266,24 @@ "file_status_downloaded": "Nedladdad", "file_status_uploaded": "Uppladdad", "file_drop_upload_hint": "Släpp för att ladda upp till: {path}", - "file_local_upload_hint": "Dra filer till fjärrpanelen eller använd Ladda upp. Nedladdningar sparas i webbläsarens standardmapp.", + "file_local_upload_hint": "Släpp filer i rutan till vänster eller klicka för att ladda upp. Målet är mappen som är öppen på fjärrsidan.", "file_transfer_stalled": "Fjärrenheten startade inte överföringen", - "file_no_local_tree": "Välj en mapp för att bläddra lokala filer (valfritt)" + "file_no_local_tree": "Välj en mapp för att bläddra lokala filer (valfritt)", + "file_dropzone_title": "Släpp filer här", + "file_dropzone_subtitle": "eller klicka för att välja filer", + "file_dropzone_multiple": "Flera filer stöds", + "file_dropzone_waiting": "Väntar på fjärranslutning…", + "file_overwrite_title": "Filen finns redan", + "file_overwrite_message": "En fil med namnet «{name}» finns redan på fjärrdatorn. Skriva över?", + "file_overwrite_skip": "Hoppa över", + "file_overwrite_skip_all": "Hoppa över alla", + "file_overwrite_confirm": "Skriv över", + "file_overwrite_all": "Skriv över alla", + "file_resume": "Återuppta", + "file_open": "Öppna", + "file_up": "Upp", + "file_home": "Hem", + "file_hide_hidden": "Dölj dolda filer" }, "branding": { "identity_title": "Varumärkesidentitet", diff --git a/web-nodejs/lang/th.json b/web-nodejs/lang/th.json index 4ba0b243..91027524 100644 --- a/web-nodejs/lang/th.json +++ b/web-nodejs/lang/th.json @@ -1266,9 +1266,24 @@ "file_status_downloaded": "ดาวน์โหลดแล้ว", "file_status_uploaded": "อัปโหลดแล้ว", "file_drop_upload_hint": "วางเพื่ออัปโหลดไปที่: {path}", - "file_local_upload_hint": "ลากไฟล์ไปที่แผงระยะไกลหรือใช้การอัปโหลด การดาวน์โหลดจะบันทึกไปยังโฟลเดอร์เริ่มต้นของเบราว์เซอร์", + "file_local_upload_hint": "วางไฟล์ในกล่องทางซ้ายหรือคลิกเพื่ออัปโหลด ปลายทางคือโฟลเดอร์ที่เปิดอยู่ฝั่ง remote", "file_transfer_stalled": "อุปกรณ์ระยะไกลไม่เริ่มการถ่ายโอน", - "file_no_local_tree": "เลือกโฟลเดอร์เพื่อเรียกดูไฟล์ในเครื่อง (ไม่บังคับ)" + "file_no_local_tree": "เลือกโฟลเดอร์เพื่อเรียกดูไฟล์ในเครื่อง (ไม่บังคับ)", + "file_dropzone_title": "วางไฟล์ที่นี่", + "file_dropzone_subtitle": "หรือคลิกเพื่อเลือกไฟล์", + "file_dropzone_multiple": "รองรับหลายไฟล์", + "file_dropzone_waiting": "กำลังรอการเชื่อมต่อ remote…", + "file_overwrite_title": "มีไฟล์นี้อยู่แล้ว", + "file_overwrite_message": "มีไฟล์ «{name}» อยู่บนคอมพิวเตอร์ remote แล้ว เขียนทับหรือไม่?", + "file_overwrite_skip": "ข้าม", + "file_overwrite_skip_all": "ข้ามทั้งหมด", + "file_overwrite_confirm": "เขียนทับ", + "file_overwrite_all": "เขียนทับทั้งหมด", + "file_resume": "ดำเนินต่อ", + "file_open": "เปิด", + "file_up": "ขึ้น", + "file_home": "หน้าแรก", + "file_hide_hidden": "ซ่อนไฟล์ที่ซ่อนอยู่" }, "branding": { "identity_title": "เอกลักษณ์ของแบรนด์", diff --git a/web-nodejs/lang/tr.json b/web-nodejs/lang/tr.json index 16f640dc..ada4a153 100644 --- a/web-nodejs/lang/tr.json +++ b/web-nodejs/lang/tr.json @@ -1266,9 +1266,24 @@ "file_status_downloaded": "İndirildi", "file_status_uploaded": "Yüklendi", "file_drop_upload_hint": "Yüklemek için bırakın: {path}", - "file_local_upload_hint": "Dosyaları uzak panele sürükleyin veya Yükle'yi kullanın. İndirmeler tarayıcının varsayılan klasörüne kaydedilir.", + "file_local_upload_hint": "Dosyaları soldaki kutuya bırakın veya yüklemek için tıklayın. Hedef, uzak tarafta açık klasördür.", "file_transfer_stalled": "Uzak cihaz aktarımı başlatmadı", - "file_no_local_tree": "Yerel dosyalara göz atmak için klasör seçin (isteğe bağlı)" + "file_no_local_tree": "Yerel dosyalara göz atmak için klasör seçin (isteğe bağlı)", + "file_dropzone_title": "Dosyaları buraya bırakın", + "file_dropzone_subtitle": "veya dosya seçmek için tıklayın", + "file_dropzone_multiple": "Birden fazla dosya desteklenir", + "file_dropzone_waiting": "Uzak bağlantı bekleniyor…", + "file_overwrite_title": "Dosya zaten var", + "file_overwrite_message": "«{name}» adlı dosya uzak bilgisayarda zaten mevcut. Üzerine yazılsın mı?", + "file_overwrite_skip": "Atla", + "file_overwrite_skip_all": "Tümünü atla", + "file_overwrite_confirm": "Üzerine yaz", + "file_overwrite_all": "Tümünün üzerine yaz", + "file_resume": "Sürdür", + "file_open": "Aç", + "file_up": "Yukarı", + "file_home": "Ana", + "file_hide_hidden": "Gizli dosyaları gizle" }, "branding": { "identity_title": "Marka Kimliği", diff --git a/web-nodejs/lang/uk.json b/web-nodejs/lang/uk.json index 35d8562a..f4776bb6 100644 --- a/web-nodejs/lang/uk.json +++ b/web-nodejs/lang/uk.json @@ -1266,9 +1266,24 @@ "file_status_downloaded": "Завантажено", "file_status_uploaded": "Завантажено", "file_drop_upload_hint": "Перетягніть для завантаження в: {path}", - "file_local_upload_hint": "Перетягніть файли на віддалену панель або скористайтеся завантаженням. Завантаження зберігаються в папці браузера за замовчуванням.", + "file_local_upload_hint": "Перетягніть файли в поле зліва або натисніть для завантаження. Призначення — папка, відкрита на віддаленій стороні.", "file_transfer_stalled": "Віддалений пристрій не розпочав передачу", - "file_no_local_tree": "Оберіть папку для перегляду локальних файлів (необов'язково)" + "file_no_local_tree": "Оберіть папку для перегляду локальних файлів (необов'язково)", + "file_dropzone_title": "Перетягніть файли сюди", + "file_dropzone_subtitle": "або натисніть, щоб вибрати файли", + "file_dropzone_multiple": "Підтримується кілька файлів", + "file_dropzone_waiting": "Очікування віддаленого з’єднання…", + "file_overwrite_title": "Файл уже існує", + "file_overwrite_message": "Файл «{name}» уже існує на віддаленому комп’ютері. Перезаписати?", + "file_overwrite_skip": "Пропустити", + "file_overwrite_skip_all": "Пропустити всі", + "file_overwrite_confirm": "Перезаписати", + "file_overwrite_all": "Перезаписати всі", + "file_resume": "Відновити", + "file_open": "Відкрити", + "file_up": "Вгору", + "file_home": "Початок", + "file_hide_hidden": "Приховати приховані файли" }, "branding": { "identity_title": "Ідентичність бренду", diff --git a/web-nodejs/lang/vi.json b/web-nodejs/lang/vi.json index 9caa5a30..22d31b7c 100644 --- a/web-nodejs/lang/vi.json +++ b/web-nodejs/lang/vi.json @@ -1266,9 +1266,24 @@ "file_status_downloaded": "Đã tải xuống", "file_status_uploaded": "Đã tải lên", "file_drop_upload_hint": "Thả để tải lên: {path}", - "file_local_upload_hint": "Kéo tệp vào bảng từ xa hoặc dùng Tải lên. Tệp tải xuống lưu vào thư mục mặc định của trình duyệt.", + "file_local_upload_hint": "Thả tệp vào hộp bên trái hoặc nhấp để tải lên. Đích là thư mục đang mở ở phía remote.", "file_transfer_stalled": "Thiết bị từ xa không bắt đầu truyền", - "file_no_local_tree": "Chọn thư mục để duyệt tệp cục bộ (tùy chọn)" + "file_no_local_tree": "Chọn thư mục để duyệt tệp cục bộ (tùy chọn)", + "file_dropzone_title": "Thả tệp vào đây", + "file_dropzone_subtitle": "hoặc nhấp để chọn tệp", + "file_dropzone_multiple": "Hỗ trợ nhiều tệp", + "file_dropzone_waiting": "Đang chờ kết nối remote…", + "file_overwrite_title": "Tệp đã tồn tại", + "file_overwrite_message": "Tệp «{name}» đã có trên máy remote. Ghi đè?", + "file_overwrite_skip": "Bỏ qua", + "file_overwrite_skip_all": "Bỏ qua tất cả", + "file_overwrite_confirm": "Ghi đè", + "file_overwrite_all": "Ghi đè tất cả", + "file_resume": "Tiếp tục", + "file_open": "Mở", + "file_up": "Lên", + "file_home": "Trang chủ", + "file_hide_hidden": "Ẩn tệp ẩn" }, "branding": { "identity_title": "Nhận diện thương hiệu", diff --git a/web-nodejs/lang/zh-TW.json b/web-nodejs/lang/zh-TW.json index 7c8a3f81..8e05bf3c 100644 --- a/web-nodejs/lang/zh-TW.json +++ b/web-nodejs/lang/zh-TW.json @@ -1277,9 +1277,24 @@ "file_status_downloaded": "已下載", "file_status_uploaded": "已上傳", "file_drop_upload_hint": "拖放到此處上傳到:{path}", - "file_local_upload_hint": "將檔案拖到遠端面板或使用上傳。下載會儲存到瀏覽器的預設資料夾。", + "file_local_upload_hint": "將檔案拖到左側框中或點擊上傳。目的地為遠端側目前開啟的資料夾。", "file_transfer_stalled": "遠端裝置未開始傳輸", - "file_no_local_tree": "選擇資料夾以瀏覽本機檔案(選用)" + "file_no_local_tree": "選擇資料夾以瀏覽本機檔案(選用)", + "file_dropzone_title": "將檔案拖放到此處", + "file_dropzone_subtitle": "或點擊選擇檔案", + "file_dropzone_multiple": "支援多個檔案", + "file_dropzone_waiting": "正在等待遠端連線…", + "file_overwrite_title": "檔案已存在", + "file_overwrite_message": "遠端電腦上已存在名為「{name}」的檔案。是否覆寫?", + "file_overwrite_skip": "略過", + "file_overwrite_skip_all": "全部略過", + "file_overwrite_confirm": "覆寫", + "file_overwrite_all": "全部覆寫", + "file_resume": "繼續", + "file_open": "開啟", + "file_up": "上層", + "file_home": "首頁", + "file_hide_hidden": "隱藏隱藏檔案" }, "branding": { "identity_title": "品牌標識", diff --git a/web-nodejs/lang/zh.json b/web-nodejs/lang/zh.json index f8b78002..11bb73ac 100644 --- a/web-nodejs/lang/zh.json +++ b/web-nodejs/lang/zh.json @@ -1260,9 +1260,24 @@ "file_status_downloaded": "已下载", "file_status_uploaded": "已上传", "file_drop_upload_hint": "拖放到此处上传到:{path}", - "file_local_upload_hint": "将文件拖到远程面板或使用上传。下载会保存到浏览器的默认文件夹。", + "file_local_upload_hint": "将文件拖到左侧框中或点击上传。目标为远程侧当前打开的文件夹。", "file_transfer_stalled": "远程设备未开始传输", - "file_no_local_tree": "选择文件夹以浏览本地文件(可选)" + "file_no_local_tree": "选择文件夹以浏览本地文件(可选)", + "file_dropzone_title": "将文件拖放到此处", + "file_dropzone_subtitle": "或点击选择文件", + "file_dropzone_multiple": "支持多个文件", + "file_dropzone_waiting": "正在等待远程连接…", + "file_overwrite_title": "文件已存在", + "file_overwrite_message": "远程计算机上已存在名为「{name}」的文件。是否覆盖?", + "file_overwrite_skip": "跳过", + "file_overwrite_skip_all": "全部跳过", + "file_overwrite_confirm": "覆盖", + "file_overwrite_all": "全部覆盖", + "file_resume": "继续", + "file_open": "打开", + "file_up": "上级", + "file_home": "主页", + "file_hide_hidden": "隐藏隐藏文件" }, "branding": { "identity_title": "品牌标识", diff --git a/web-nodejs/public/css/remote.css b/web-nodejs/public/css/remote.css index 37290253..495fa3bb 100644 --- a/web-nodejs/public/css/remote.css +++ b/web-nodejs/public/css/remote.css @@ -1449,6 +1449,7 @@ flex-direction: column; box-shadow: 0 16px 48px rgba(0, 0, 0, 0.45); overflow: hidden; + position: relative; } .ft-modal-header { @@ -1661,14 +1662,191 @@ font-size: 36px; } -.ft-local-hint { - padding: 6px 10px; - font-size: 11px; +.ft-local-body { + flex: 1; + display: flex; + flex-direction: column; + min-height: 0; +} + +.ft-local-dropzone { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 6px; + margin: 12px; + min-height: 180px; + padding: 24px 16px; + border: 2px dashed var(--border-primary, #30363d); + border-radius: 8px; + text-align: center; + cursor: pointer; + transition: border-color 0.15s, background 0.15s; + user-select: none; +} + +.ft-local-dropzone.compact { + flex: 0 0 auto; + min-height: 0; + padding: 10px 12px; + margin: 8px; + gap: 2px; +} + +.ft-local-dropzone.compact .ft-dropzone-icon { + font-size: 24px !important; +} + +.ft-local-dropzone.compact .ft-dropzone-subtitle, +.ft-local-dropzone.compact .ft-dropzone-multiple { + display: none; +} + +.ft-local-dropzone:hover:not(.ft-dropzone-disabled) { + border-color: var(--accent, #3884ff); + background: rgba(56, 132, 255, 0.04); +} + +.ft-local-dropzone.ft-dropzone-active { + border-color: var(--accent, #3884ff); + background: rgba(56, 132, 255, 0.08); +} + +.ft-local-dropzone.ft-dropzone-disabled { + opacity: 0.45; + cursor: not-allowed; + pointer-events: none; +} + +.ft-dropzone-icon { + font-size: 40px !important; + color: var(--accent, #3884ff); +} + +.ft-dropzone-title { + font-size: 14px; + font-weight: 600; + color: var(--text-primary, #e6edf3); +} + +.ft-dropzone-subtitle, +.ft-dropzone-multiple { + font-size: 12px; color: var(--text-secondary, #8b949e); } -.ft-local-hint .ft-hint-text { - display: inline; +.ft-dropzone-target { + font-size: 11px; + color: var(--text-secondary, #8b949e); + margin-top: 4px; + max-width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + padding: 0 8px; +} + +.ft-btn.active { + color: var(--accent, #3884ff); +} + +.ft-overwrite-dialog { + position: absolute; + inset: 0; + z-index: 20; + display: flex; + align-items: center; + justify-content: center; + background: rgba(0, 0, 0, 0.55); +} + +.ft-overwrite-dialog[hidden] { + display: none !important; +} + +.ft-overwrite-panel { + background: var(--bg-secondary, #161b22); + border: 1px solid var(--border-primary, #30363d); + border-radius: 8px; + padding: 16px 20px; + max-width: 420px; + width: 90%; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4); +} + +.ft-overwrite-title { + font-weight: 600; + font-size: 14px; + margin-bottom: 8px; +} + +.ft-overwrite-message { + font-size: 12px; + color: var(--text-secondary, #8b949e); + margin-bottom: 16px; + line-height: 1.5; +} + +.ft-overwrite-actions { + display: flex; + flex-wrap: wrap; + gap: 8px; + justify-content: flex-end; +} + +.ft-context-menu { + position: fixed; + z-index: 300; + min-width: 160px; + background: var(--bg-secondary, #161b22); + border: 1px solid var(--border-primary, #30363d); + border-radius: 6px; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.45); + padding: 4px 0; +} + +.ft-context-item { + display: flex; + align-items: center; + gap: 8px; + width: 100%; + padding: 8px 12px; + background: none; + border: none; + color: var(--text-primary, #e6edf3); + font-size: 12px; + cursor: pointer; + text-align: left; +} + +.ft-context-item:hover { + background: rgba(255, 255, 255, 0.06); +} + +.ft-context-item .material-icons { + font-size: 16px; + color: var(--text-secondary, #8b949e); +} + +.ft-transfer-resume { + flex-shrink: 0; + background: none; + border: none; + color: var(--accent, #3884ff); + cursor: pointer; + padding: 2px; + border-radius: 4px; + line-height: 1; +} + +.ft-transfer-resume:hover { + background: rgba(56, 132, 255, 0.12); +} + +.ft-transfer-resume .material-icons { + font-size: 16px; } .ft-btn:disabled { diff --git a/web-nodejs/public/js/rdclient/file-modal.js b/web-nodejs/public/js/rdclient/file-modal.js index dcd1ec1b..a8a675cc 100644 --- a/web-nodejs/public/js/rdclient/file-modal.js +++ b/web-nodejs/public/js/rdclient/file-modal.js @@ -36,6 +36,8 @@ this._selectedRemote = null; this._transferMeta = new Map(); this._wiredSessionId = null; + this._remoteReady = false; + this._contextMenu = null; } FileTransferModal.prototype._ensureDom = function () { @@ -55,19 +57,29 @@ '