fix: resolve auto-connect race conditions and pairing success redirects

This commit is contained in:
2026-07-04 14:50:11 -06:00
parent cffbeb0e4c
commit e4048fd78c
3 changed files with 33 additions and 13 deletions

View File

@@ -95,6 +95,11 @@ class MainActivity : ComponentActivity() {
// SharedPreferences for connection details
val prefs = getSharedPreferences("meatbag_prefs", Context.MODE_PRIVATE)
val deviceId = prefs.getString("device_id", null) ?: run {
val newId = java.util.UUID.randomUUID().toString()
prefs.edit().putString("device_id", newId).apply()
newId
}
setContent {
var host by remember { mutableStateOf(prefs.getString("host", "10.0.0.7") ?: "10.0.0.7") }
@@ -110,18 +115,21 @@ class MainActivity : ComponentActivity() {
var errorMessage by remember { mutableStateOf<String?>(null) }
var activeProfileId by remember { mutableStateOf(intent.getStringExtra("LAUNCH_PROFILE_ID")) }
var isInitialLaunch by remember { mutableStateOf(true) }
LaunchedEffect(Unit) {
onProfileLaunch = { id ->
activeProfileId = id
isInitialLaunch = true
}
}
// Auto-connect when a specific profile is launched via shortcut or intent
// Auto-connect when a specific profile is launched via shortcut or intent on startup/new intent
LaunchedEffect(activeProfileId) {
if (activeProfileId != null && connectionState == ConnectionState.DISCONNECTED && clientState == null) {
if (isInitialLaunch && activeProfileId != null && connectionState == ConnectionState.DISCONNECTED && clientState == null) {
isInitialLaunch = false
errorMessage = null
scope.launch(Dispatchers.Default) {
val newClient = MeatbagClient(host.trim(), portStr.trim().toIntOrNull() ?: 8080, feedback)
val newClient = MeatbagClient(host.trim(), portStr.trim().toIntOrNull() ?: 8080, feedback, deviceId = deviceId)
clientState = newClient
newClient.connect(deviceType, activeProfileId)
}
@@ -380,6 +388,7 @@ class MainActivity : ComponentActivity() {
Button(
onClick = {
isInitialLaunch = false
errorMessage = null
// Save preferences
prefs.edit().apply {
@@ -405,7 +414,8 @@ class MainActivity : ComponentActivity() {
host = host.trim(),
port = portStr.trim().toIntOrNull() ?: 8080,
attentionFeedback = feedback,
socksPort = socksPort
socksPort = socksPort,
deviceId = deviceId
)
clientState = newClient
newClient.connect(deviceType, activeProfileId)
@@ -471,9 +481,10 @@ class MainActivity : ComponentActivity() {
Button(
onClick = {
activeProfileId = "meatbag"
isInitialLaunch = false
errorMessage = null
scope.launch(Dispatchers.Default) {
val newClient = MeatbagClient(host.trim(), portStr.trim().toIntOrNull() ?: 8080, feedback)
val newClient = MeatbagClient(host.trim(), portStr.trim().toIntOrNull() ?: 8080, feedback, deviceId = deviceId)
clientState = newClient
newClient.connect(deviceType, "meatbag")
}
@@ -513,9 +524,10 @@ class MainActivity : ComponentActivity() {
Button(
onClick = {
activeProfileId = "lm_studio_remote"
isInitialLaunch = false
errorMessage = null
scope.launch(Dispatchers.Default) {
val newClient = MeatbagClient(host.trim(), portStr.trim().toIntOrNull() ?: 8080, feedback)
val newClient = MeatbagClient(host.trim(), portStr.trim().toIntOrNull() ?: 8080, feedback, deviceId = deviceId)
clientState = newClient
newClient.connect(deviceType, "lm_studio_remote")
}

View File

@@ -35,7 +35,8 @@ class MeatbagClient(
private val host: String = "localhost",
private val port: Int = 8080,
private val attentionFeedback: AttentionFeedback = NoOpAttentionFeedback,
private val socksPort: Int? = null
private val socksPort: Int? = null,
private val deviceId: String? = null
) {
private val jsonConfig = Json {
ignoreUnknownKeys = true
@@ -76,10 +77,17 @@ class MeatbagClient(
connectionJob = CoroutineScope(Dispatchers.Default).launch {
while (isActive) {
try {
val queryParams = if (profileId != null) {
"?deviceType=$deviceType&profileId=$profileId"
} else {
"?deviceType=$deviceType"
val queryParams = buildString {
append("?deviceType=")
append(deviceType)
if (profileId != null) {
append("&profileId=")
append(profileId)
}
if (deviceId != null) {
append("&deviceId=")
append(deviceId)
}
}
log("Connecting to ws://$host:$port/ws/connect$queryParams ...")
_connectionState.value = ConnectionState.CONNECTING