# -*- coding: utf-8 -*- """ F2: Netzwerk-Konfiguration — WiFi-Hotspot, WLAN-Verbindung, Server-Verbindung. """ from __future__ import annotations from textual.widgets import Checkbox, Input, Label, RadioButton, RadioSet, Static from .base import InstallerView class NetworkView(InstallerView): """Netzwerk-Einstellungen (F2).""" TITLE = "Netzwerk" VIEW_ID = "network" MODES = ["server", "client", "standalone"] def compose(self): if self._config.mode == "server": yield from self._compose_server() elif self._config.mode == "client": yield from self._compose_wifi_connect() yield from self._compose_client() elif self._config.mode == "standalone": yield from self._compose_wifi_connect() def _compose_server(self): """Server: WiFi-Hotspot Konfiguration.""" yield Static("── WiFi-Hotspot ──", classes="section-header") yield Checkbox( "WiFi-Hotspot aktivieren", value=self._config.wifi_enabled, id="cb-wifi-enabled", ) yield Label("") yield Label("SSID:") yield Input( value=self._config.wifi_ssid, placeholder="z.B. trixyone_srv", id="input-wifi-ssid", ) yield Label("Passwort (min. 8 Zeichen):") yield Input( value=self._config.wifi_password, placeholder="WiFi-Passwort", id="input-wifi-password", password=True, ) yield Label("Kanal (1-13):") yield Input( value=str(self._config.wifi_channel), placeholder="6", id="input-wifi-channel", ) yield Label("Access-Point IP:") yield Input( value=self._config.ap_ip, placeholder="10.10.10.1", id="input-ap-ip", ) yield Label("DHCP-Bereich Start:") yield Input( value=self._config.dhcp_range_start, placeholder="10.10.10.10", id="input-dhcp-start", ) yield Label("DHCP-Bereich Ende:") yield Input( value=self._config.dhcp_range_end, placeholder="10.10.10.50", id="input-dhcp-end", ) def _compose_wifi_connect(self): """Client/Standalone: WLAN-Verbindung konfigurieren.""" yield Static("── WLAN-Verbindung ──", classes="section-header") yield RadioSet( RadioButton( "Keine Aenderung — bestehendes WLAN beibehalten", value=not self._config.wifi_connect, id="rb-wifi-keep", ), RadioButton( "WLAN konfigurieren — mit Netzwerk verbinden", value=self._config.wifi_connect, id="rb-wifi-connect", ), id="rs-wifi-connect", ) yield Label("") yield Label("WLAN SSID:") yield Input( value=self._config.wifi_connect_ssid, placeholder="z.B. trixyone_srv", id="input-wifi-connect-ssid", disabled=not self._config.wifi_connect, ) yield Label("WLAN Passwort:") yield Input( value=self._config.wifi_connect_password, placeholder="WLAN-Passwort", id="input-wifi-connect-password", password=True, disabled=not self._config.wifi_connect, ) yield Label("") def _compose_client(self): """Client: Server-Verbindung.""" yield Static("── Server-Verbindung ──", classes="section-header") yield Label("Server-Host:") yield Input( value=self._config.server_host, placeholder="z.B. 10.10.10.1", id="input-server-host", ) yield Label("Server-Port:") yield Input( value=str(self._config.server_port), placeholder="2101", id="input-server-port", ) yield Label("Raum:") yield Input( value=self._config.room, placeholder="z.B. Wohnzimmer", id="input-room", ) yield Label("Alias:") yield Input( value=self._config.alias, placeholder="z.B. Patrick", id="input-alias", ) def on_radio_set_changed(self, event: RadioSet.Changed) -> None: """WLAN-Modus umschalten.""" if event.radio_set.id == "rs-wifi-connect": pressed_id = event.pressed.id if event.pressed else "" connect = pressed_id == "rb-wifi-connect" self._config.wifi_connect = connect # Eingabefelder aktivieren/deaktivieren try: self.query_one("#input-wifi-connect-ssid", Input).disabled = not connect self.query_one("#input-wifi-connect-password", Input).disabled = not connect except Exception: pass def on_input_changed(self, event: Input.Changed) -> None: """Aktualisiert Konfig bei Eingabeaenderungen.""" mapping = { "input-wifi-ssid": "wifi_ssid", "input-wifi-password": "wifi_password", "input-ap-ip": "ap_ip", "input-dhcp-start": "dhcp_range_start", "input-dhcp-end": "dhcp_range_end", "input-wifi-connect-ssid": "wifi_connect_ssid", "input-wifi-connect-password": "wifi_connect_password", "input-server-host": "server_host", "input-room": "room", "input-alias": "alias", } attr = mapping.get(event.input.id or "") if attr: setattr(self._config, attr, event.value) elif event.input.id == "input-wifi-channel": try: self._config.wifi_channel = int(event.value) except ValueError: pass elif event.input.id == "input-server-port": try: self._config.server_port = int(event.value) except ValueError: pass def on_checkbox_changed(self, event: Checkbox.Changed) -> None: if event.checkbox.id == "cb-wifi-enabled": self._config.wifi_enabled = event.value def validate(self) -> str | None: if self._config.mode == "server" and self._config.wifi_enabled: if not self._config.wifi_ssid.strip(): return "WiFi SSID darf nicht leer sein" if len(self._config.wifi_password) < 8: return "WiFi Passwort muss mindestens 8 Zeichen haben" elif self._config.mode == "client": if not self._config.server_host.strip(): return "Server-Host darf nicht leer sein" if not self._config.room.strip(): return "Raum darf nicht leer sein" if not self._config.alias.strip(): return "Alias darf nicht leer sein" # WLAN-Validierung (Client/Standalone) if self._config.wifi_connect: if not self._config.wifi_connect_ssid.strip(): return "WLAN SSID darf nicht leer sein" if len(self._config.wifi_connect_password) < 8: return "WLAN Passwort muss mindestens 8 Zeichen haben" return None