OXYGENHUB
◆ v0.1.4 oxygenhub-android / app / src / main / java / io / oxygenhub / android / ui / issues / IssuesViewModel.kt
1.6 KiB · last changed Sign-in, dashboard, repositories, issues and inbox screens, adaptive (refs #2) 11 days ago source blame history raw
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
}