Skip to content

Commit

Permalink
Sources menu improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
Syer10 committed Aug 25, 2022
1 parent 11920e2 commit cfdeb70
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@

package ca.gosyer.jui.ui.sources.home

import androidx.compose.ui.text.intl.Locale
import ca.gosyer.jui.core.lang.displayName
import ca.gosyer.jui.data.source.SourceRepositoryImpl
import ca.gosyer.jui.domain.source.model.Source
import ca.gosyer.jui.domain.source.service.CatalogPreferences
import ca.gosyer.jui.i18n.MR
import ca.gosyer.jui.uicore.vm.ContextWrapper
import ca.gosyer.jui.uicore.vm.ViewModel
import kotlinx.coroutines.flow.MutableStateFlow
Expand Down Expand Up @@ -37,9 +40,39 @@ class SourceHomeScreenViewModel @Inject constructor(
val languages = _languages.asStateFlow()

val sources = combine(installedSources, languages) { installedSources, languages ->
installedSources.filter {
it.lang in languages || it.id == Source.LOCAL_SOURCE_ID
}
val all = MR.strings.all.toPlatformString()
val other = MR.strings.other.toPlatformString()
installedSources
.distinctBy { it.id }
.filter {
it.lang in languages || it.id == Source.LOCAL_SOURCE_ID
}
.groupBy(Source::displayLang)

.mapValues {
it.value.sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER, Source::name))
.map(SourceUI::SourceItem)
}
.mapKeys { (key) ->
when (key) {
"all" -> all
"other" -> other
else -> Locale(key).displayName
}
}
.toList()
.sortedWith(
compareBy<Pair<String, *>> { (key) ->
when (key) {
all -> 1
other -> 3
else -> 2
}
}.thenBy(String.CASE_INSENSITIVE_ORDER, Pair<String, *>::first)
)
.flatMap { (key, value) ->
listOf(SourceUI.Header(key)) + value
}
}.stateIn(scope, SharingStarted.Eagerly, emptyList())

val sourceLanguages = installedSources.map { sources ->
Expand All @@ -56,10 +89,7 @@ class SourceHomeScreenViewModel @Inject constructor(
private fun getSources() {
sourceHandler.getSourceList()
.onEach {
installedSources.value = it.sortedWith(
compareBy(String.CASE_INSENSITIVE_ORDER, Source::displayLang)
.thenBy(String.CASE_INSENSITIVE_ORDER, Source::name)
)
installedSources.value = it
_isLoading.value = false
}
.catch {
Expand All @@ -82,3 +112,8 @@ class SourceHomeScreenViewModel @Inject constructor(
private val log = logging()
}
}

sealed class SourceUI {
data class Header(val header: String) : SourceUI()
data class SourceItem(val source: Source): SourceUI()
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package ca.gosyer.jui.ui.sources.home.components

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
Expand All @@ -21,6 +22,7 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.foundation.lazy.grid.rememberLazyGridState
Expand All @@ -39,9 +41,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.graphics.FilterQuality
import androidx.compose.ui.text.intl.Locale
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.text.toUpperCase
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import ca.gosyer.jui.domain.source.model.Source
Expand All @@ -51,6 +51,7 @@ import ca.gosyer.jui.ui.base.components.localeToString
import ca.gosyer.jui.ui.base.navigation.ActionItem
import ca.gosyer.jui.ui.base.navigation.Toolbar
import ca.gosyer.jui.ui.extensions.components.LanguageDialog
import ca.gosyer.jui.ui.sources.home.SourceUI
import ca.gosyer.jui.uicore.components.LoadingScreen
import ca.gosyer.jui.uicore.components.VerticalScrollbar
import ca.gosyer.jui.uicore.components.rememberScrollbarAdapter
Expand All @@ -64,7 +65,7 @@ import com.vanpra.composematerialdialogs.rememberMaterialDialogState
fun SourceHomeScreenContent(
onAddSource: (Source) -> Unit,
isLoading: Boolean,
sources: List<Source>,
sources: List<SourceUI>,
languages: Set<String>,
sourceLanguages: List<String>,
setEnabledLanguages: (Set<String>) -> Unit,
Expand All @@ -82,44 +83,15 @@ fun SourceHomeScreenContent(
submitSearch = submitSearch
)
}
) {
) { padding ->
if (sources.isEmpty()) {
LoadingScreen(isLoading)
} else {
BoxWithConstraints(Modifier.fillMaxSize().padding(it), Alignment.TopCenter) {
BoxWithConstraints(Modifier.fillMaxSize().padding(padding), Alignment.TopCenter) {
if (maxWidth > 720.dp) {
val state = rememberLazyGridState()
val cells = GridCells.Adaptive(120.dp)
LazyVerticalGrid(cells, state = state) {
items(sources) { source ->
WideSourceItem(
source,
onSourceClicked = onAddSource
)
}
}
VerticalScrollbar(
modifier = Modifier.align(Alignment.CenterEnd)
.fillMaxHeight()
.scrollbarPadding(),
adapter = rememberVerticalScrollbarAdapter(state, cells)
)
WideSourcesMenu(sources, onAddSource)
} else {
val state = rememberLazyListState()
LazyColumn(state = state) {
items(sources) { source ->
ThinSourceItem(
source,
onSourceClicked = onAddSource
)
}
}
VerticalScrollbar(
modifier = Modifier.align(Alignment.CenterEnd)
.fillMaxHeight()
.scrollbarPadding(),
adapter = rememberScrollbarAdapter(state)
)
ThinSourcesMenu(sources, onAddSource)
}
}
}
Expand Down Expand Up @@ -151,6 +123,58 @@ fun SourceHomeScreenToolbar(
)
}

@Composable
fun WideSourcesMenu(
sources: List<SourceUI>,
onAddSource: (Source) -> Unit
) {
Box {
val state = rememberLazyGridState()
val cells = GridCells.Adaptive(120.dp)
LazyVerticalGrid(cells, state = state, modifier = Modifier.fillMaxSize()) {
items(
sources,
contentType = {
when (it) {
is SourceUI.Header -> "header"
is SourceUI.SourceItem -> "source"
}
},
key = {
when (it) {
is SourceUI.Header -> it.header
is SourceUI.SourceItem -> it.source.id
}
},
span = {
when (it) {
is SourceUI.Header -> GridItemSpan(maxLineSpan)
is SourceUI.SourceItem -> GridItemSpan(1)
}
}
) { sourceUI ->
when (sourceUI) {
is SourceUI.Header -> Text(
sourceUI.header,
modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp)
)
is SourceUI.SourceItem -> WideSourceItem(
sourceUI.source,
onSourceClicked = onAddSource
)
}

}
}
VerticalScrollbar(
modifier = Modifier.align(Alignment.CenterEnd)
.fillMaxHeight()
.scrollbarPadding(),
adapter = rememberVerticalScrollbarAdapter(state, cells)
)
}
}

@Composable
fun WideSourceItem(
source: Source,
Expand Down Expand Up @@ -182,14 +206,58 @@ fun WideSourceItem(
)
Spacer(Modifier.height(4.dp))
Text(
"${source.name} (${source.displayLang.toUpperCase(Locale.current)})",
source.name,
color = MaterialTheme.colors.onBackground,
maxLines = 2,
overflow = TextOverflow.Ellipsis
)
}
}
}
@Composable
fun ThinSourcesMenu(
sources: List<SourceUI>,
onAddSource: (Source) -> Unit
) {
Box {
val state = rememberLazyListState()
LazyColumn(state = state, modifier = Modifier.fillMaxSize()) {
items(
sources,
contentType = {
when (it) {
is SourceUI.Header -> "header"
is SourceUI.SourceItem -> "source"
}
},
key = {
when (it) {
is SourceUI.Header -> it.header
is SourceUI.SourceItem -> it.source.id
}
}
) { sourceUI ->
when (sourceUI) {
is SourceUI.Header -> Text(
sourceUI.header,
modifier = Modifier.padding(horizontal = 16.dp, vertical = 4.dp)
)
is SourceUI.SourceItem -> ThinSourceItem(
sourceUI.source,
onSourceClicked = onAddSource
)
}

}
}
VerticalScrollbar(
modifier = Modifier.align(Alignment.CenterEnd)
.fillMaxHeight()
.scrollbarPadding(),
adapter = rememberScrollbarAdapter(state)
)
}
}

@Composable
fun ThinSourceItem(
Expand Down

0 comments on commit cfdeb70

Please sign in to comment.