mirror of
https://git.quad4.io/RNS-Things/MeshChatX.git
synced 2026-05-11 07:26:53 +00:00
feat(interface): update AddInterfacePage with dynamic interface selection and localization updates for multiple languages
This commit is contained in:
@@ -1117,6 +1117,48 @@
|
||||
placeholder="e.g. eth0, wlan0"
|
||||
class="input-field"
|
||||
/>
|
||||
<div
|
||||
v-if="
|
||||
hostKernelInterfacesLoading ||
|
||||
hostKernelInterfaces.length ||
|
||||
hostKernelInterfacesUnavailable
|
||||
"
|
||||
class="mt-1.5 space-y-1"
|
||||
>
|
||||
<p class="text-[10px] text-gray-500 dark:text-zinc-500">
|
||||
{{ $t("interfaces.auto_iface_ifname_chips_hint") }}
|
||||
</p>
|
||||
<div
|
||||
v-if="hostKernelInterfacesLoading"
|
||||
class="text-[10px] text-gray-400"
|
||||
>
|
||||
{{ $t("interfaces.kernel_iface_loading") }}
|
||||
</div>
|
||||
<div v-else class="flex flex-wrap gap-1 max-h-20 overflow-y-auto">
|
||||
<button
|
||||
v-for="iface in hostKernelInterfaces"
|
||||
:key="'auto-allow-' + iface.name"
|
||||
type="button"
|
||||
class="max-w-full truncate px-1.5 py-0.5 text-[10px] rounded border font-mono transition-colors"
|
||||
:class="
|
||||
autoInterfaceChipActive(
|
||||
'newInterfaceDevices',
|
||||
iface.name
|
||||
)
|
||||
? 'border-blue-400 bg-blue-50/90 text-blue-900 dark:border-blue-500 dark:bg-blue-950/40 dark:text-blue-200'
|
||||
: 'border-gray-200 bg-white/80 text-gray-800 hover:border-blue-300 dark:border-zinc-700 dark:bg-zinc-900/80 dark:text-zinc-200 dark:hover:border-blue-500'
|
||||
"
|
||||
@click="
|
||||
toggleAutoInterfaceCommaToken(
|
||||
'newInterfaceDevices',
|
||||
iface.name
|
||||
)
|
||||
"
|
||||
>
|
||||
{{ iface.name }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<FormLabel class="glass-label"
|
||||
@@ -1128,6 +1170,48 @@
|
||||
placeholder="e.g. tun0, docker0"
|
||||
class="input-field"
|
||||
/>
|
||||
<div
|
||||
v-if="
|
||||
hostKernelInterfacesLoading ||
|
||||
hostKernelInterfaces.length ||
|
||||
hostKernelInterfacesUnavailable
|
||||
"
|
||||
class="mt-1.5 space-y-1"
|
||||
>
|
||||
<p class="text-[10px] text-gray-500 dark:text-zinc-500">
|
||||
{{ $t("interfaces.auto_iface_ifname_chips_hint") }}
|
||||
</p>
|
||||
<div
|
||||
v-if="hostKernelInterfacesLoading"
|
||||
class="text-[10px] text-gray-400"
|
||||
>
|
||||
{{ $t("interfaces.kernel_iface_loading") }}
|
||||
</div>
|
||||
<div v-else class="flex flex-wrap gap-1 max-h-20 overflow-y-auto">
|
||||
<button
|
||||
v-for="iface in hostKernelInterfaces"
|
||||
:key="'auto-ignore-' + iface.name"
|
||||
type="button"
|
||||
class="max-w-full truncate px-1.5 py-0.5 text-[10px] rounded border font-mono transition-colors"
|
||||
:class="
|
||||
autoInterfaceChipActive(
|
||||
'newInterfaceIgnoredDevices',
|
||||
iface.name
|
||||
)
|
||||
? 'border-amber-400 bg-amber-50/90 text-amber-950 dark:border-amber-600 dark:bg-amber-950/40 dark:text-amber-100'
|
||||
: 'border-gray-200 bg-white/80 text-gray-800 hover:border-amber-300 dark:border-zinc-700 dark:bg-zinc-900/80 dark:text-zinc-200 dark:hover:border-amber-600'
|
||||
"
|
||||
@click="
|
||||
toggleAutoInterfaceCommaToken(
|
||||
'newInterfaceIgnoredDevices',
|
||||
iface.name
|
||||
)
|
||||
"
|
||||
>
|
||||
{{ iface.name }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<FormLabel class="glass-label">Configured Bitrate (bps)</FormLabel>
|
||||
@@ -2118,6 +2202,32 @@ export default {
|
||||
}
|
||||
return rest;
|
||||
},
|
||||
autoInterfaceChipActive(fieldKey, token) {
|
||||
const raw = this[fieldKey];
|
||||
if (raw == null || raw === "") {
|
||||
return false;
|
||||
}
|
||||
return String(raw)
|
||||
.split(",")
|
||||
.map((s) => s.trim())
|
||||
.includes(token);
|
||||
},
|
||||
toggleAutoInterfaceCommaToken(fieldKey, token) {
|
||||
const raw = this[fieldKey];
|
||||
let str = raw == null || raw === "" ? "" : String(raw);
|
||||
const tokens = str
|
||||
.split(",")
|
||||
.map((s) => s.trim())
|
||||
.filter(Boolean);
|
||||
const i = tokens.indexOf(token);
|
||||
if (i === -1) {
|
||||
tokens.push(token);
|
||||
} else {
|
||||
tokens.splice(i, 1);
|
||||
}
|
||||
const next = tokens.join(", ");
|
||||
this[fieldKey] = next === "" ? null : next;
|
||||
},
|
||||
async loadHostKernelInterfaces() {
|
||||
this.hostKernelInterfacesLoading = true;
|
||||
this.hostKernelInterfacesUnavailable = null;
|
||||
|
||||
@@ -960,7 +960,8 @@
|
||||
"listen_ip_required": "Listen-IP ist erforderlich.",
|
||||
"kernel_iface_picker_title": "Schnittstellen auf diesem Rechner",
|
||||
"kernel_iface_loading": "Laden…",
|
||||
"kernel_iface_picker_help": "Optional ein Kernel-Interface-Name, oder leer lassen und nur über Listen-IP binden. Klick füllt das Feld."
|
||||
"kernel_iface_picker_help": "Optional ein Kernel-Interface-Name, oder leer lassen und nur über Listen-IP binden. Klick füllt das Feld.",
|
||||
"auto_iface_ifname_chips_hint": "Schnittstellen dieses Rechners: Klicken zum Hinzufügen oder Entfernen im Feld darüber."
|
||||
},
|
||||
"map": {
|
||||
"title": "Karte",
|
||||
|
||||
@@ -908,7 +908,8 @@
|
||||
"listen_ip_required": "Listen IP is required.",
|
||||
"kernel_iface_picker_title": "Interfaces on this host",
|
||||
"kernel_iface_loading": "Loading…",
|
||||
"kernel_iface_picker_help": "Device is optional: one kernel interface name, or leave empty to bind using Listen IP only. Click a row to fill the field."
|
||||
"kernel_iface_picker_help": "Device is optional: one kernel interface name, or leave empty to bind using Listen IP only. Click a row to fill the field.",
|
||||
"auto_iface_ifname_chips_hint": "This host's interfaces: click to add or remove names in the field above."
|
||||
},
|
||||
"map": {
|
||||
"title": "Map",
|
||||
|
||||
@@ -908,7 +908,8 @@
|
||||
"listen_ip_required": "La IP de escucha es obligatoria.",
|
||||
"kernel_iface_picker_title": "Interfaces en este equipo",
|
||||
"kernel_iface_loading": "Cargando…",
|
||||
"kernel_iface_picker_help": "“Dispositivo” es opcional: un nombre de interfaz del kernel, o vacío para enlazar solo con la IP de escucha. Pulse una fila para rellenar."
|
||||
"kernel_iface_picker_help": "“Dispositivo” es opcional: un nombre de interfaz del kernel, o vacío para enlazar solo con la IP de escucha. Pulse una fila para rellenar.",
|
||||
"auto_iface_ifname_chips_hint": "Interfaces de este equipo: pulse para añadir o quitar nombres en el campo de arriba."
|
||||
},
|
||||
"map": {
|
||||
"title": "Mapa",
|
||||
|
||||
@@ -908,7 +908,8 @@
|
||||
"listen_ip_required": "L'adresse IP d'écoute est obligatoire.",
|
||||
"kernel_iface_picker_title": "Interfaces sur cette machine",
|
||||
"kernel_iface_loading": "Chargement…",
|
||||
"kernel_iface_picker_help": "Le champ Périphérique est optionnel : un seul nom d'interface noyau, ou laisser vide pour lier via l'IP d'écoute uniquement. Cliquez sur une ligne pour remplir."
|
||||
"kernel_iface_picker_help": "Le champ Périphérique est optionnel : un seul nom d'interface noyau, ou laisser vide pour lier via l'IP d'écoute uniquement. Cliquez sur une ligne pour remplir.",
|
||||
"auto_iface_ifname_chips_hint": "Interfaces sur cette machine : cliquez pour ajouter ou retirer des noms dans le champ ci-dessus."
|
||||
},
|
||||
"map": {
|
||||
"title": "Carte",
|
||||
|
||||
@@ -960,7 +960,8 @@
|
||||
"listen_ip_required": "L'IP di ascolto è obbligatoria.",
|
||||
"kernel_iface_picker_title": "Interfacce su questo host",
|
||||
"kernel_iface_loading": "Caricamento…",
|
||||
"kernel_iface_picker_help": "Il dispositivo è facoltativo: un solo nome di interfaccia del kernel, o lascia vuoto e lega solo con l'IP di ascolto. Clic su una riga per compilare."
|
||||
"kernel_iface_picker_help": "Il dispositivo è facoltativo: un solo nome di interfaccia del kernel, o lascia vuoto e lega solo con l'IP di ascolto. Clic su una riga per compilare.",
|
||||
"auto_iface_ifname_chips_hint": "Interfacce su questo host: clic per aggiungere o rimuovere nomi nel campo sopra."
|
||||
},
|
||||
"map": {
|
||||
"title": "Mappa",
|
||||
|
||||
@@ -908,7 +908,8 @@
|
||||
"listen_ip_required": "Listen-IP is verplicht.",
|
||||
"kernel_iface_picker_title": "Interfaces op deze host",
|
||||
"kernel_iface_loading": "Laden…",
|
||||
"kernel_iface_picker_help": "Apparaat is optioneel: één kernelinterfacenaam, of leeg laten en alleen via listen-IP binden. Klik op een regel om in te vullen."
|
||||
"kernel_iface_picker_help": "Apparaat is optioneel: één kernelinterfacenaam, of leeg laten en alleen via listen-IP binden. Klik op een regel om in te vullen.",
|
||||
"auto_iface_ifname_chips_hint": "Interfaces op deze host: klik om namen in het veld erboven toe te voegen of te verwijderen."
|
||||
},
|
||||
"map": {
|
||||
"title": "Kaart",
|
||||
|
||||
@@ -960,7 +960,8 @@
|
||||
"listen_ip_required": "Укажите IP для прослушивания.",
|
||||
"kernel_iface_picker_title": "Интерфейсы на этом узле",
|
||||
"kernel_iface_loading": "Загрузка…",
|
||||
"kernel_iface_picker_help": "Поле «устройство» необязательно: одно имя интерфейса ядра или пусто — привязка только по Listen IP. Нажмите строку, чтобы подставить имя."
|
||||
"kernel_iface_picker_help": "Поле «устройство» необязательно: одно имя интерфейса ядра или пусто — привязка только по Listen IP. Нажмите строку, чтобы подставить имя.",
|
||||
"auto_iface_ifname_chips_hint": "Интерфейсы этого узла: нажмите, чтобы добавить или убрать имя в поле выше."
|
||||
},
|
||||
"map": {
|
||||
"title": "Карта",
|
||||
|
||||
@@ -908,7 +908,8 @@
|
||||
"listen_ip_required": "Listen IP 为必填项。",
|
||||
"kernel_iface_picker_title": "本机网络接口",
|
||||
"kernel_iface_loading": "加载中…",
|
||||
"kernel_iface_picker_help": "“设备”为可选,填写一个内核网卡名,或留空仅按 Listen IP 绑定。点击一行填入输入框。"
|
||||
"kernel_iface_picker_help": "“设备”为可选,填写一个内核网卡名,或留空仅按 Listen IP 绑定。点击一行填入输入框。",
|
||||
"auto_iface_ifname_chips_hint": "本机接口:点击可在上方字段中添加或移除名称。"
|
||||
},
|
||||
"map": {
|
||||
"title": "地图",
|
||||
|
||||
Reference in New Issue
Block a user