package com.vgmlr.wedge
import android.content.Context
import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.Wifi
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.content.edit
import java.net.Inet4Address
import java.net.NetworkInterface
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
@Composable
fun SyncViewContent(vm: MainViewModel, prefs: PreferenceManager) {
val context = LocalContext.current
val sharedPrefs = remember { context.getSharedPreferences("sync_prefs", Context.MODE_PRIVATE) }
val noteEntity by vm.dao.getNote().collectAsState(initial = null)
val lastModifiedStr = WedgeDate.getOtcMetadata(
noteEntity?.lastModified ?: System.currentTimeMillis()
)
var selectedRoute by remember { mutableStateOf(sharedPrefs.getString("route", "USB") ?: "USB") }
var peerIp by remember { mutableStateOf(sharedPrefs.getString("peer_ip", "") ?: "") }
var autoMerge by remember { mutableStateOf(sharedPrefs.getBoolean("auto_merge", false)) }
val passKeyFlow by prefs.passKey.collectAsState(initial = "wedge03569")
var localPassKey by remember { mutableStateOf<String?>(null) }
val displayPassKey = localPassKey ?: passKeyFlow
val syncStatusText by vm.syncStatus.collectAsState()
val syncStamp = remember(syncStatusText) { sharedPrefs.getLong("sync_last_stamp", 0L) }
val syncedStr = if (syncStamp == 0L) "[none]" else WedgeDate.getOtcMetadata(syncStamp)
val localIpAddress = remember {
try {
NetworkInterface.getNetworkInterfaces().asSequence()
.flatMap { it.inetAddresses.asSequence() }
.firstOrNull { !it.isLoopbackAddress && it is Inet4Address }
?.hostAddress ?: "Unknown"
} catch (_: Exception) {
"Unknown"
}
}
LaunchedEffect(selectedRoute) { sharedPrefs.edit { putString("route", selectedRoute) } }
LaunchedEffect(peerIp) { sharedPrefs.edit { putString("peer_ip", peerIp) } }
Column(modifier = Modifier.fillMaxWidth()) {
WgSection("Sync", Icons.Outlined.Wifi, CHeadSync, CCardSync) {
WgRow("Route") {
WgRadio(
value = selectedRoute,
options = listOf("USB", "WIFI", "BT"),
disabledOptions = listOf("BT")
) { selectedRoute = it }
}
WgDivider()
WgRow("Pass Key", edit = true) {
WgField(
value = displayPassKey,
onValueChange = {
localPassKey = it
vm.updatePassKey(it)
},
placeholder = "",
modifier = Modifier.weight(1f),
visualTransformation = PasswordVisualTransformation(),
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)
)
}
WgDivider()
WgRow("Auto-Merge") {
WgRadio(
value = if (autoMerge) "True" else "False",
options = listOf("True", "False")
) {
autoMerge = it == "True"
vm.setAutoMerge(autoMerge)
}
}
WgDivider()
WgRow("Local IP") {
WgValue(localIpAddress, mono = true, color = CText)
}
WgDivider()
WgRow("Peer IP", edit = true) {
WgField(
value = peerIp,
onValueChange = { peerIp = it },
placeholder = "0.0.0.0",
modifier = Modifier.weight(1f)
)
}
WgDivider()
WgRow("Modified") {
WgValue(lastModifiedStr, mono = true)
}
WgDivider()
WgRow("Synced") {
WgValue(syncedStr, mono = true)
}
WgDivider()
WgRow("Status") {
WgValue(syncStatusText, mono = true, color = CText)
}
WgDivider()
Button(
onClick = { vm.trySendNoteText(selectedRoute, peerIp) },
enabled = selectedRoute == "USB" || selectedRoute == "WIFI",
modifier = Modifier.fillMaxWidth().height(46.dp),
shape = RectangleShape,
elevation = null,
colors = ButtonDefaults.buttonColors(
containerColor = CHeadSync,
contentColor = CText,
disabledContainerColor = CHeadSync,
disabledContentColor = CChip
)
) {
Text("Send", fontSize = FSend, letterSpacing = 1.4.sp)
}
}
}
}