shared/src/commonMain/kotlin/org/jetbrains/kotlinconf/screens/LicensesViewModel.kt (61 lines of code) (raw):

package org.jetbrains.kotlinconf.screens import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.mikepenz.aboutlibraries.Libs import com.mikepenz.aboutlibraries.entity.Library import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.stateIn import org.jetbrains.kotlinconf.generated.resources.Res import org.jetbrains.kotlinconf.utils.performSearch data class LibraryWithHighlights( val library: Library, val nameHighlights: List<IntRange> = emptyList(), val authorHighlights: List<IntRange> = emptyList(), val licenseHighlights: List<IntRange> = emptyList(), ) class LicensesViewModel : ViewModel() { private var searchText = MutableStateFlow("") private val libraries = flow { Libs.Builder() .withJson(Res.readBytes("files/aboutlibraries.json").decodeToString()) .build() .libraries .sortedBy { it.name } .let { emit(it) } } fun setSearchText(searchText: String) { this.searchText.value = searchText } private val Library.author: String get() = when { developers.isNotEmpty() -> developers.joinToString { it.name.toString() } else -> organization?.name ?: "" } private val Library.licenseName: String get() = licenses.firstOrNull()?.name ?: "Unknown license" val licensesState: StateFlow<List<LibraryWithHighlights>> = combine( libraries, searchText ) { libs, searchText -> if (searchText.isBlank()) { libs.map { LibraryWithHighlights(it) } } else { libs .performSearch( searchText = searchText, produceResult = { lib, (nameMatches, authorMatches, licenseMatches) -> LibraryWithHighlights(lib, nameMatches, authorMatches, licenseMatches) }, selectors = listOf({ it.name }, { it.author }, { it.licenseName }), ) .sortedBy { it.library.name } } } .flowOn(Dispatchers.Default) .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), emptyList()) }