Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import snd.komelia.ui.LoadState.Uninitialized
import snd.komelia.ui.LocalKomgaState
import snd.komelia.ui.LocalOfflineMode
import snd.komelia.ui.LocalReloadEvents
import snd.komelia.ui.LocalStrings
import snd.komelia.ui.LocalViewModelFactory
import snd.komelia.ui.ReloadableScreen
import snd.komelia.ui.collection.CollectionScreen
Expand All @@ -60,10 +61,8 @@ import kotlin.jvm.Transient

class LibraryScreen(
val libraryId: KomgaLibraryId? = null,
@Transient
private val seriesFilter: SeriesScreenFilter? = null
@Transient private val seriesFilter: SeriesScreenFilter? = null
) : ReloadableScreen {

override val key: ScreenKey = "${libraryId}_${seriesFilter.hashCode()}"

@Composable
Expand Down Expand Up @@ -96,10 +95,16 @@ class LibraryScreen(
readListsCount = vm.readListsCount,
onBrowseClick = vm::toBrowseTab,
onCollectionsClick = vm::toCollectionsTab,
onReadListsClick = vm::toReadListsTab
onReadListsClick = vm::toReadListsTab,
randomSeriesEnabled = vm.seriesTabState.totalSeriesCount > 0,
onRandomSeriesClick = {
vm.seriesTabState.openRandomSeries { navigator.push(seriesScreen(it)) }
},
onRandomUnreadSeriesClick = {
vm.seriesTabState.openRandomUnreadSeries { navigator.push(seriesScreen(it)) }
}
)
}

when (vm.currentTab) {
SERIES -> BrowseTab(vm.seriesTabState)
COLLECTIONS -> CollectionsTab(vm.collectionsTabState)
Expand Down Expand Up @@ -129,26 +134,23 @@ class LibraryScreen(

else -> {
val loading = state is Loading || state is Uninitialized

SeriesListContent(
series = seriesTabState.series,
seriesActions = seriesTabState.seriesMenuActions(),
seriesTotalCount = seriesTabState.totalSeriesCount,
onSeriesClick = { navigator.push(seriesScreen(it)) },

editMode = seriesTabState.isInEditMode.collectAsState().value,
onEditModeChange = seriesTabState::onEditModeChange,
selectedSeries = seriesTabState.selectedSeries,
onSeriesSelect = seriesTabState::onSeriesSelect,

isLoading = loading,
filterState = seriesTabState.filterState,

currentPage = seriesTabState.currentSeriesPage,
totalPages = seriesTabState.totalSeriesPages,
pageSize = seriesTabState.pageLoadSize.collectAsState().value,
onPageSizeChange = seriesTabState::onPageSizeChange,
onPageChange = seriesTabState::onPageChange,

minSize = seriesTabState.cardWidth.collectAsState().value,
)
}
Expand Down Expand Up @@ -179,19 +181,15 @@ class LibraryScreen(
onCollectionClick = { navigator push CollectionScreen(it) },
onCollectionDelete = collectionsTabState::onCollectionDelete,
isLoading = loading,

totalPages = collectionsTabState.totalPages,
currentPage = collectionsTabState.currentPage,
pageSize = collectionsTabState.pageSize,
onPageChange = collectionsTabState::onPageChange,
onPageSizeChange = collectionsTabState::onPageSizeChange,

minSize = collectionsTabState.cardWidth.collectAsState().value
)

}
}

}

@Composable
Expand All @@ -214,19 +212,16 @@ class LibraryScreen(
onReadListClick = { navigator push ReadListScreen(it) },
onReadListDelete = readListTabState::onReadListDelete,
isLoading = loading,

totalPages = readListTabState.totalPages,
currentPage = readListTabState.currentPage,
pageSize = readListTabState.pageSize,
onPageChange = readListTabState::onPageChange,
onPageSizeChange = readListTabState::onPageSizeChange,

minSize = readListTabState.cardWidth.collectAsState().value
)
}
}
}

}

@Composable
Expand All @@ -239,9 +234,12 @@ fun LibraryToolBar(
onBrowseClick: () -> Unit,
onCollectionsClick: () -> Unit,
onReadListsClick: () -> Unit,
randomSeriesEnabled: Boolean,
onRandomSeriesClick: () -> Unit,
onRandomUnreadSeriesClick: () -> Unit,
) {

val chipColors = AppFilterChipDefaults.filterChipColors()
val strings = LocalStrings.current
var showOptionsMenu by remember { mutableStateOf(false) }
val isAdmin = LocalKomgaState.current.authenticatedUser.collectAsState().value?.roleAdmin() ?: true
val isOffline = LocalOfflineMode.current.collectAsState().value
Expand All @@ -261,7 +259,6 @@ fun LibraryToolBar(
contentDescription = null,
)
}

LibraryActionsMenu(
library = library,
actions = libraryActions,
Expand All @@ -270,49 +267,65 @@ fun LibraryToolBar(
)
}
}
Text(library?.let { library.name } ?: "All Libraries")

Text(library?.let { library.name } ?: "All Libraries")
Spacer(Modifier.width(5.dp))
}

if (collectionsCount > 0 || readListsCount > 0) item {
FilterChip(
onClick = onBrowseClick,
selected = currentTab == SERIES,
label = { Text("Series") },
colors = chipColors,
border = null,
)
}

if (collectionsCount > 0 || readListsCount > 0)
item {
FilterChip(
onClick = onBrowseClick,
selected = currentTab == SERIES,
label = { Text("Series") },
colors = chipColors,
border = null,
)
}
if (collectionsCount > 0) item {
FilterChip(
onClick = onCollectionsClick,
selected = currentTab == COLLECTIONS,
label = { Text("Collections") },
colors = chipColors,
border = null,
)
}

if (collectionsCount > 0)
item {
FilterChip(
onClick = onCollectionsClick,
selected = currentTab == COLLECTIONS,
label = { Text("Collections") },
colors = chipColors,
border = null,
)
}
if (readListsCount > 0) item {
FilterChip(
onClick = onReadListsClick,
selected = currentTab == READ_LISTS,
label = { Text("Read Lists") },
colors = chipColors,
border = null,
)
}

if (readListsCount > 0)
item {
FilterChip(
onClick = onReadListsClick,
selected = currentTab == READ_LISTS,
label = { Text("Read Lists") },
colors = chipColors,
border = null,
)
}
item {
FilterChip(
onClick = onRandomSeriesClick,
enabled = randomSeriesEnabled,
selected = false,
label = { Text(strings.seriesFilter.sortRandom) },
colors = chipColors,
border = null,
)
}

item {
FilterChip(
onClick = onRandomUnreadSeriesClick,
enabled = randomSeriesEnabled,
selected = false,
label = { Text(strings.seriesFilter.randomUnread) },
colors = chipColors,
border = null,
)
}
}
}


data class SeriesScreenFilter(
val publicationStatus: List<KomgaSeriesStatus>? = null,
val ageRating: List<Int>? = null,
Expand All @@ -321,4 +334,4 @@ data class SeriesScreenFilter(
val genres: List<String>? = null,
val tags: List<String>? = null,
val authors: List<KomgaAuthor>? = null,
)
)
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,21 @@ import snd.komelia.ui.LoadState
import snd.komelia.ui.common.menus.SeriesMenuActions
import snd.komelia.ui.series.SeriesFilter
import snd.komelia.ui.series.SeriesFilterState
import snd.komga.client.book.KomgaReadStatus.IN_PROGRESS
import snd.komga.client.book.KomgaReadStatus.UNREAD
import snd.komga.client.common.KomgaPageRequest
import snd.komga.client.common.KomgaSort.Direction.ASC
import snd.komga.client.common.KomgaSort.KomgaSeriesSort
import snd.komga.client.common.KomgaSort.Order
import snd.komga.client.common.Page
import snd.komga.client.library.KomgaLibrary
import snd.komga.client.search.allOfSeries
import snd.komga.client.series.KomgaSeries
import snd.komga.client.sse.KomgaEvent

private const val SERIES_RANDOM_SORT = "random"
private val SERIES_UNREAD_STATUSES = listOf(UNREAD, IN_PROGRESS)

class LibrarySeriesTabState(
private val seriesApi: KomgaSeriesApi,
referentialApi: KomgaReferentialApi,
Expand Down Expand Up @@ -108,6 +115,18 @@ class LibrarySeriesTabState(

fun seriesMenuActions() = SeriesMenuActions(seriesApi, notifications, taskEmitter, screenModelScope)

fun openRandomSeries(onSeriesSelected: (KomgaSeries) -> Unit) {
notifications.runCatchingToNotifications(screenModelScope) {
getRandomSeries(filterState.state.value)?.let(onSeriesSelected)
}
}

fun openRandomUnreadSeries(onSeriesSelected: (KomgaSeries) -> Unit) {
notifications.runCatchingToNotifications(screenModelScope) {
getRandomSeries(filterState.state.value.copy(readStatus = SERIES_UNREAD_STATUSES))?.let(onSeriesSelected)
}
}

fun onPageSizeChange(pageSize: Int) {
pageLoadSize.value = pageSize
screenModelScope.launch { settingsRepository.putSeriesPageLoadSize(pageSize) }
Expand Down Expand Up @@ -173,6 +192,23 @@ class LibrarySeriesTabState(
)
}

private suspend fun getRandomSeries(filter: SeriesFilter): KomgaSeries? {
val condition = allOfSeries {
library.value?.let { library { isEqualTo(it.id) } }
filter.addConditionTo(this)
}

return seriesApi.getSeriesList(
conditionBuilder = condition,
fulltextSearch = filter.searchTerm.ifBlank { null },
pageRequest = KomgaPageRequest(
size = 1,
pageIndex = 0,
sort = SeriesSort.RANDOM.komgaSort
)
).content.firstOrNull()
}

private fun delayLoadState(): Deferred<Unit> {
return screenModelScope.async {
delay(200)
Expand Down Expand Up @@ -224,6 +260,7 @@ class LibrarySeriesTabState(
TITLE_DESC(KomgaSeriesSort.byTitleDesc()),
DATE_ADDED_DESC(KomgaSeriesSort.byCreatedDateDesc()),
DATE_ADDED_ASC(KomgaSeriesSort.byCreatedDateAsc()),
RANDOM(KomgaSeriesSort(listOf(Order(SERIES_RANDOM_SORT, ASC)))),
// FOLDER_NAME_ASC(KomgaSeriesSort.byFolderNameAsc()),
// FOLDER_NAME_DESC(KomgaSeriesSort.byFolderNameDesc()),
// BOOKS_COUNT_ASC(KomgaSeriesSort.byBooksCountAsc()),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,8 @@ data class SeriesFilterStrings(
val anyValue: String,
val search: String,
val sort: String,
val sortRandom: String,
val randomUnread: String,
val sortTitleAsc: String,
val sortTitleDesc: String,
val sortDateAddedAsc: String,
Expand Down Expand Up @@ -487,6 +489,7 @@ data class SeriesFilterStrings(
LibrarySeriesTabState.SeriesSort.RELEASE_DATE_DESC -> sortReleaseDateDesc
LibrarySeriesTabState.SeriesSort.UPDATED_DESC -> sortUpdatedDesc
LibrarySeriesTabState.SeriesSort.UPDATED_ASC -> sortUpdatedAsc
LibrarySeriesTabState.SeriesSort.RANDOM -> sortRandom
// FOLDER_NAME_ASC -> sortFolderNameAsc
// FOLDER_NAME_DESC -> sortFolderNameDesc
// BOOKS_COUNT_ASC -> sortBooksCountAsc
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ val EnStrings = AppStrings(
search = "Search",

sort = "Sort by",
sortRandom = "Random",
randomUnread = "Random unread",
sortTitleAsc = "Title Ascending",
sortTitleDesc = "Title Descending",
sortDateAddedAsc = "Oldest Added",
Expand Down