git.iko.soy/opencode-android
on master help sign in
Fix stale lists on auto-reconnect, accidental clipboard copy on tap, CrashLogger clearAll deleting non-crash files, and replace Math.random with kotlin.random
commit987f968a6ca0a01468d385f2a80b155f97fa12af authoriko <mail@iko.soy> dateTue 30 Jun 2026, 03:42 (3 months ago) parent710ef2d
6 files changed+14−4
app/src/main/java/soy/iko/opencode/data/network/EventStreamClient.kt+2−1 app/src/main/java/soy/iko/opencode/data/network/OpencodeApiClient.kt+2−1 app/src/main/java/soy/iko/opencode/data/repo/CrashLogger.kt+1−1 app/src/main/java/soy/iko/opencode/ui/components/MarkdownText.kt+1−1 app/src/main/java/soy/iko/opencode/ui/file/FileBrowserViewModel.kt+4 app/src/main/java/soy/iko/opencode/ui/session/SessionListViewModel.kt+4
app/src/main/java/soy/iko/opencode/data/network/EventStreamClient.kt+2−1
@@ -25,6 +25,7 @@ import kotlinx.coroutines.isActive
2525import kotlinx.coroutines.selects.onTimeout
2626import kotlinx.coroutines.selects.select
2727import java.io.IOException
28+import kotlin.random.Random
2829
2930/**
3031 * Owns the single long-lived `GET /event` SSE subscription and exposes it as a hot
@@ -131,7 +132,7 @@ class EventStreamClient(
131132 if (!isActive) break
132133 // Wait for the backoff, but allow a reconnect signal to cut it short.
133134 var signaled = false
134− val jitter = (backoffMs * 0.2 * Math.random()).toLong()
135+ val jitter = (backoffMs * 0.2 * Random.nextDouble()).toLong()
135136 select {
136137 reconnectSignal.onReceive { signaled = true }
137138 onTimeout(backoffMs + jitter) { /* normal backoff elapsed */ }
app/src/main/java/soy/iko/opencode/data/network/OpencodeApiClient.kt+2−1
@@ -28,6 +28,7 @@ import io.ktor.client.request.setBody
2828import io.ktor.http.ContentType
2929import io.ktor.http.contentType
3030import kotlinx.coroutines.delay
31+import kotlin.random.Random
3132
3233/**
3334 * Request/response wrapper over the opencode REST endpoints. The long-lived `/event`
@@ -171,7 +172,7 @@ internal suspend fun <T> withRetryInternal(
171172 if (t is ClientRequestException) throw t
172173 if (attempt < maxAttempts) {
173174 val baseDelay = initialDelayMs * (1 shl (attempt - 1))
174− val jitter = (baseDelay * jitterFactor * Math.random()).toLong()
175+ val jitter = (baseDelay * jitterFactor * Random.nextDouble()).toLong()
175176 delay(baseDelay + jitter)
176177 }
177178 }
app/src/main/java/soy/iko/opencode/data/repo/CrashLogger.kt+1−1
@@ -76,7 +76,7 @@ class CrashLogger private constructor(private val appContext: Context) {
7676 }
7777
7878 fun clearAll() {
79− crashDir.listFiles()?.forEach { it.delete() }
79+ crashDir.listFiles { f -> f.isFile && f.name.endsWith(".txt") }?.forEach { it.delete() }
8080 refresh()
8181 }
8282
app/src/main/java/soy/iko/opencode/ui/components/MarkdownText.kt+1−1
@@ -54,7 +54,7 @@ fun MarkdownText(
5454 Markdown(
5555 content = markdown,
5656 modifier = modifier.combinedClickable(
57− onClick = { copyToClipboard(context, markdown) },
57+ onClick = {},
5858 onLongClick = { copyToClipboard(context, markdown) },
5959 ),
6060 components = markdownComponents(
app/src/main/java/soy/iko/opencode/ui/file/FileBrowserViewModel.kt+4
@@ -55,6 +55,10 @@ class FileBrowserViewModel(private val container: AppContainer) : ViewModel() {
5555 container.activeConnection.collectLatest { conn ->
5656 if (conn == null) return@collectLatest
5757 loadStatus()
58+ // Re-open the current directory when a connection becomes available
59+ // so the initial open("") (which may have run before auto-reconnect
60+ // finished and found no connection) doesn't leave a stale error.
61+ open(_state.value.path)
5862 }
5963 }
6064 }
app/src/main/java/soy/iko/opencode/ui/session/SessionListViewModel.kt+4
@@ -111,6 +111,10 @@ class SessionListViewModel(private val container: AppContainer) : ViewModel() {
111111 container.activeConnection.collectLatest { conn ->
112112 if (conn == null) return@collectLatest
113113 _serverLabel.value = conn.profile.displayLabel
114+ // Reload the session list when a connection becomes available so the
115+ // initial load (which may have run before auto-reconnect finished and
116+ // found no connection) doesn't leave a stale "not connected" error.
117+ refresh()
114118 conn.events.events.collect { event ->
115119 when (event) {
116120 is SessionUpdated -> {