feat(device-initialization, core): mDNS-Discovery erweitert, Geräte- und UI-Interaktion optimiert
Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
This commit is contained in:
+15
-9
@@ -11,7 +11,6 @@ import androidx.compose.ui.unit.dp
|
||||
import java.awt.FileDialog
|
||||
import java.awt.Frame
|
||||
import java.io.File
|
||||
import javax.swing.JFileChooser
|
||||
|
||||
@Composable
|
||||
actual fun MsFilePicker(
|
||||
@@ -45,19 +44,26 @@ actual fun MsFilePicker(
|
||||
MsButton(
|
||||
onClick = {
|
||||
if (directoryOnly) {
|
||||
// JFileChooser ist für Verzeichnisse auf dem Desktop oft stabiler/einfacher
|
||||
val chooser = JFileChooser().apply {
|
||||
fileSelectionMode = JFileChooser.DIRECTORIES_ONLY
|
||||
dialogTitle = label
|
||||
// AWT FileDialog für nativen Look auch bei Verzeichnissen (Windows/Linux/macOS)
|
||||
// unter macOS erzwingt dies die Verzeichnisauswahl. Unter Windows/Linux ist es der Standard-Dialog.
|
||||
System.setProperty("apple.awt.fileDialogForDirectories", "true")
|
||||
val dialog = FileDialog(null as Frame?, label, FileDialog.LOAD).apply {
|
||||
selectedPath?.let {
|
||||
val currentDir = File(it)
|
||||
if (currentDir.exists()) currentDirectory = currentDir
|
||||
if (currentDir.exists()) {
|
||||
directory = currentDir.absolutePath
|
||||
}
|
||||
}
|
||||
}
|
||||
val result = chooser.showOpenDialog(null)
|
||||
if (result == JFileChooser.APPROVE_OPTION) {
|
||||
onFileSelected(chooser.selectedFile.absolutePath)
|
||||
dialog.isVisible = true
|
||||
if (dialog.directory != null && dialog.file != null) {
|
||||
// Bei FileDialog.LOAD unter Windows/Linux wählt man oft eine Datei im Ordner,
|
||||
// aber wir wollen den Ordner. Wir nehmen also das Verzeichnis.
|
||||
onFileSelected(File(dialog.directory, dialog.file).parentFile.absolutePath)
|
||||
} else if (dialog.directory != null) {
|
||||
onFileSelected(dialog.directory)
|
||||
}
|
||||
System.setProperty("apple.awt.fileDialogForDirectories", "false")
|
||||
} else {
|
||||
// AWT FileDialog für nativen Look bei Dateiauswahl (wie vom User gewünscht)
|
||||
val dialog = FileDialog(null as Frame?, label, FileDialog.LOAD).apply {
|
||||
|
||||
+2
-1
@@ -38,8 +38,9 @@ interface NetworkDiscoveryService {
|
||||
* Registriert den eigenen Dienst, damit andere Instanzen ihn finden können.
|
||||
* @param port Der Port, auf dem der lokale WebSocket-Server lauscht.
|
||||
* @param preferredIp Optional eine IP-Adresse, an die der Discovery-Dienst gebunden werden soll.
|
||||
* @param deviceName Der Name des Geräts, das im Netzwerk angezeigt werden soll.
|
||||
*/
|
||||
fun registerService(port: Int, preferredIp: String? = null)
|
||||
fun registerService(port: Int, preferredIp: String? = null, deviceName: String? = null)
|
||||
|
||||
/**
|
||||
* Gibt die Liste der aktuell entdeckten Dienste zurück (Snapshot).
|
||||
|
||||
+13
-4
@@ -63,20 +63,29 @@ class JmDnsDiscoveryService : NetworkDiscoveryService {
|
||||
_discoveredServices.value = emptyList()
|
||||
}
|
||||
|
||||
override fun registerService(port: Int, preferredIp: String?) {
|
||||
override fun registerService(port: Int, preferredIp: String?, deviceName: String?) {
|
||||
if (jmdns == null) {
|
||||
val addr = preferredIp?.let { InetAddress.getByName(it) } ?: InetAddress.getLocalHost()
|
||||
println("[Discovery] Registriere Dienst gebunden an: $addr")
|
||||
jmdns = JmDNS.create(addr)
|
||||
}
|
||||
|
||||
// Wir nutzen den übergebenen Namen, den vom System gesetzten oder einen sprechenden Default
|
||||
val name = deviceName ?: System.getProperty("meldestelle.device.name") ?: "Meldestelle-${System.getProperty("user.name")}"
|
||||
|
||||
val serviceInfo = ServiceInfo.create(
|
||||
SERVICE_TYPE,
|
||||
"Meldestelle-${System.getProperty("user.name")}",
|
||||
name,
|
||||
port,
|
||||
"Offline-First Sync Node"
|
||||
0, 0, // weight, priority
|
||||
mapOf(
|
||||
"version" to "1.0.0",
|
||||
"type" to "master",
|
||||
"nodeId" to name
|
||||
)
|
||||
)
|
||||
jmdns?.registerService(serviceInfo)
|
||||
println("[Discovery] Eigenen Dienst registriert auf Port $port")
|
||||
println("[Discovery] Eigenen Dienst '$name' registriert auf Port $port")
|
||||
}
|
||||
|
||||
override fun getDiscoveredServices(): List<DiscoveredService> {
|
||||
|
||||
+1
-1
@@ -19,6 +19,6 @@ class NoOpDiscoveryService : NetworkDiscoveryService {
|
||||
|
||||
override fun startDiscovery(preferredIp: String?) {}
|
||||
override fun stopDiscovery() {}
|
||||
override fun registerService(port: Int, preferredIp: String?) {}
|
||||
override fun registerService(port: Int, preferredIp: String?, deviceName: String?) {}
|
||||
override fun getDiscoveredServices(): List<DiscoveredService> = emptyList()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user