1package soy.iko.opencode
3import android.app.Application
4import android.content.Context
5import androidx.core.content.edit
6import androidx.lifecycle.AndroidViewModel
7import androidx.lifecycle.viewModelScope
8import kotlinx.coroutines.flow.distinctUntilChangedBy
9import kotlinx.coroutines.launch
10import soy.iko.opencode.core.Event
11import soy.iko.opencode.core.OpencodeCore
14 * Lifecycle-scoped host for the [OpencodeCore] so a single core (and its SSE
15 * connection) survives configuration changes. It also persists the last server
16 * URL / username so reconnecting is one tap.
18class CoreViewModel(app: Application) : AndroidViewModel(app) {
19 private val prefs = app.getSharedPreferences("opencode", Context.MODE_PRIVATE)
21 val core = OpencodeCore(viewModelScope)
24 prefs.getString(KEY_URL, null)?.let { core.dispatch(Event.ServerUrlChanged(it)) }
25 prefs.getString(KEY_USER, null)?.let { core.dispatch(Event.UsernameChanged(it)) }
27 // On a fresh process after a configuration change, resume the SSE stream if
28 // the core is already connected (no-op otherwise — it guards on `connected`).
29 core.resumeStreamingIfConnected()
31 // Persist connection details once a connection succeeds.
32 viewModelScope.launch {
33 core.view.distinctUntilChangedBy { it.connected to it.serverUrl }.collect { state ->
34 if (state.connected) {
36 putString(KEY_URL, state.serverUrl)
37 putString(KEY_USER, state.username)
44 override fun onCleared() {
48 private companion object {
49 const val KEY_URL = "serverUrl"
50 const val KEY_USER = "username"
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list