| 1 |
package io.oxygenhub.android.ui.issues |
| 2 |
|
| 3 |
import androidx.lifecycle.ViewModel |
| 4 |
import io.oxygenhub.android.api.HubApi |
| 5 |
import io.oxygenhub.android.api.Issue |
| 6 |
import io.oxygenhub.android.api.IssueState |
| 7 |
import io.oxygenhub.android.ui.common.Load |
| 8 |
import io.oxygenhub.android.ui.common.load |
| 9 |
import kotlinx.coroutines.Job |
| 10 |
import kotlinx.coroutines.flow.MutableStateFlow |
| 11 |
import kotlinx.coroutines.flow.StateFlow |
| 12 |
import kotlinx.coroutines.flow.asStateFlow |
| 13 |
|
| 14 |
/** A repository's issues, open, closed or all; pinned ones first. */ |
| 15 |
class IssuesViewModel( |
| 16 |
private val api: HubApi, |
| 17 |
val owner: String, |
| 18 |
val name: String, |
| 19 |
) : ViewModel() { |
| 20 |
private val _state = MutableStateFlow<Load<List<Issue>>>(Load.Loading) |
| 21 |
val state: StateFlow<Load<List<Issue>>> = _state.asStateFlow() |
| 22 |
|
| 23 |
private val _filter = MutableStateFlow(IssueState.Open) |
| 24 |
val filter: StateFlow<IssueState> = _filter.asStateFlow() |
| 25 |
|
| 26 |
private var job: Job? = null |
| 27 |
|
| 28 |
init { |
| 29 |
refresh() |
| 30 |
} |
| 31 |
|
| 32 |
fun setFilter(state: IssueState) { |
| 33 |
if (state == _filter.value) return |
| 34 |
_filter.value = state |
| 35 |
// Another list: show the spinner rather than the last filter's issues. |
| 36 |
_state.value = Load.Loading |
| 37 |
refresh() |
| 38 |
} |
| 39 |
|
| 40 |
fun refresh() { |
| 41 |
val state = _filter.value |
| 42 |
job = load(_state, job) { order(api.issues(owner, name, state)) } |
| 43 |
} |
| 44 |
|
| 45 |
companion object { |
| 46 |
/** Pinned first, then newest first, as the hub's issue page lists them. */ |
| 47 |
fun order(issues: List<Issue>): List<Issue> = |
| 48 |
issues.sortedWith(compareByDescending<Issue> { it.pinned }.thenByDescending { it.number }) |
| 49 |
} |
| 50 |
} |