72222ad86d
* Work in progress upcoming feature * Checkpointing WIP upcoming feature * Functional Upcoming Screen * Rename UpdateCalendar to UpdateUpcoming * Converted Strings to resources * Cleanup * Fixed detekt issues * Removed Link icon per @AntsyLich's suggestion. * Detekt * Fixed Calendar display on wide form factor devices * Added Key to upcoming lazycolumn * Updated tablet mode UI to support two column view * Updated header creation logic * Updated header creation logic... again * Moved stray string to resources * Fixed PR Comments and query refactor * Tweaks to query, refactored to flow, comments on calendar * Switched to Date Formatter * Cleaned up date formatter * More Refactor work * Updated Calendar to support localized week formats * Fixed year format * Refactored Header animation * Moved upcoming FAQ * Completed YearMonth Migration * Replaced currentYearMonth with delegate * Even more cleanup * cleaned up alignment modifiers * Click Handler and other refactors * Removed Wrapped Content Height/Size/extra clips * Huge Refactor for CalendarDay * Another cleanup attempt * Migrated to new mihon.feature.* module pattern * changed access modifier * A Bunch of changes from the next round of reviews * Cleanups * Cleanup 2 --------- Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com>
199 lines
6.8 KiB
Kotlin
199 lines
6.8 KiB
Kotlin
package mihon.feature.upcoming
|
|
|
|
import androidx.compose.foundation.layout.PaddingValues
|
|
import androidx.compose.foundation.layout.padding
|
|
import androidx.compose.foundation.lazy.LazyListState
|
|
import androidx.compose.foundation.lazy.items
|
|
import androidx.compose.foundation.lazy.rememberLazyListState
|
|
import androidx.compose.material.icons.Icons
|
|
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
|
|
import androidx.compose.material3.Icon
|
|
import androidx.compose.material3.IconButton
|
|
import androidx.compose.runtime.Composable
|
|
import androidx.compose.runtime.rememberCoroutineScope
|
|
import androidx.compose.ui.Modifier
|
|
import androidx.compose.ui.platform.LocalUriHandler
|
|
import cafe.adriel.voyager.navigator.LocalNavigator
|
|
import cafe.adriel.voyager.navigator.currentOrThrow
|
|
import eu.kanade.presentation.components.AppBar
|
|
import eu.kanade.presentation.components.relativeDateText
|
|
import eu.kanade.presentation.util.isTabletUi
|
|
import kotlinx.collections.immutable.ImmutableList
|
|
import kotlinx.collections.immutable.ImmutableMap
|
|
import kotlinx.coroutines.launch
|
|
import mihon.feature.upcoming.components.UpcomingItem
|
|
import mihon.feature.upcoming.components.calendar.Calendar
|
|
import tachiyomi.core.common.Constants
|
|
import tachiyomi.domain.manga.model.Manga
|
|
import tachiyomi.i18n.MR
|
|
import tachiyomi.presentation.core.components.FastScrollLazyColumn
|
|
import tachiyomi.presentation.core.components.ListGroupHeader
|
|
import tachiyomi.presentation.core.components.TwoPanelBox
|
|
import tachiyomi.presentation.core.components.material.Scaffold
|
|
import tachiyomi.presentation.core.i18n.stringResource
|
|
import java.time.LocalDate
|
|
import java.time.YearMonth
|
|
|
|
@Composable
|
|
fun UpcomingScreenContent(
|
|
state: UpcomingScreenModel.State,
|
|
setSelectedYearMonth: (YearMonth) -> Unit,
|
|
onClickUpcoming: (manga: Manga) -> Unit,
|
|
modifier: Modifier = Modifier,
|
|
) {
|
|
val scope = rememberCoroutineScope()
|
|
val listState = rememberLazyListState()
|
|
val onClickDay: (LocalDate, Int) -> Unit = { date, offset ->
|
|
state.headerIndexes[date]?.let {
|
|
scope.launch {
|
|
listState.animateScrollToItem(it + offset)
|
|
}
|
|
}
|
|
}
|
|
Scaffold(
|
|
topBar = { UpcomingToolbar() },
|
|
modifier = modifier,
|
|
) { paddingValues ->
|
|
if (isTabletUi()) {
|
|
UpcomingScreenLargeImpl(
|
|
listState = listState,
|
|
items = state.items,
|
|
events = state.events,
|
|
paddingValues = paddingValues,
|
|
selectedYearMonth = state.selectedYearMonth,
|
|
setSelectedYearMonth = setSelectedYearMonth,
|
|
onClickDay = { onClickDay(it, 0) },
|
|
onClickUpcoming = onClickUpcoming,
|
|
)
|
|
} else {
|
|
UpcomingScreenSmallImpl(
|
|
listState = listState,
|
|
items = state.items,
|
|
events = state.events,
|
|
paddingValues = paddingValues,
|
|
selectedYearMonth = state.selectedYearMonth,
|
|
setSelectedYearMonth = setSelectedYearMonth,
|
|
onClickDay = { onClickDay(it, 1) },
|
|
onClickUpcoming = onClickUpcoming,
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
private fun UpcomingToolbar() {
|
|
val navigator = LocalNavigator.currentOrThrow
|
|
val uriHandler = LocalUriHandler.current
|
|
|
|
AppBar(
|
|
title = stringResource(MR.strings.label_upcoming),
|
|
navigateUp = navigator::pop,
|
|
actions = {
|
|
IconButton(onClick = { uriHandler.openUri(Constants.URL_HELP_UPCOMING) }) {
|
|
Icon(
|
|
imageVector = Icons.AutoMirrored.Outlined.HelpOutline,
|
|
contentDescription = stringResource(MR.strings.upcoming_guide),
|
|
)
|
|
}
|
|
},
|
|
)
|
|
}
|
|
|
|
@Composable
|
|
private fun UpcomingScreenSmallImpl(
|
|
listState: LazyListState,
|
|
items: ImmutableList<UpcomingUIModel>,
|
|
events: ImmutableMap<LocalDate, Int>,
|
|
paddingValues: PaddingValues,
|
|
selectedYearMonth: YearMonth,
|
|
setSelectedYearMonth: (YearMonth) -> Unit,
|
|
onClickDay: (LocalDate) -> Unit,
|
|
onClickUpcoming: (manga: Manga) -> Unit,
|
|
) {
|
|
FastScrollLazyColumn(
|
|
contentPadding = paddingValues,
|
|
state = listState,
|
|
) {
|
|
item(key = "upcoming-calendar") {
|
|
Calendar(
|
|
selectedYearMonth = selectedYearMonth,
|
|
events = events,
|
|
setSelectedYearMonth = setSelectedYearMonth,
|
|
onClickDay = onClickDay,
|
|
)
|
|
}
|
|
items(
|
|
items = items,
|
|
key = { "upcoming-${it.hashCode()}" },
|
|
contentType = {
|
|
when (it) {
|
|
is UpcomingUIModel.Header -> "header"
|
|
is UpcomingUIModel.Item -> "item"
|
|
}
|
|
},
|
|
) { item ->
|
|
when (item) {
|
|
is UpcomingUIModel.Item -> {
|
|
UpcomingItem(
|
|
upcoming = item.manga,
|
|
onClick = { onClickUpcoming(item.manga) },
|
|
)
|
|
}
|
|
is UpcomingUIModel.Header -> {
|
|
ListGroupHeader(text = relativeDateText(item.date))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@Composable
|
|
private fun UpcomingScreenLargeImpl(
|
|
listState: LazyListState,
|
|
items: ImmutableList<UpcomingUIModel>,
|
|
events: ImmutableMap<LocalDate, Int>,
|
|
paddingValues: PaddingValues,
|
|
selectedYearMonth: YearMonth,
|
|
setSelectedYearMonth: (YearMonth) -> Unit,
|
|
onClickDay: (LocalDate) -> Unit,
|
|
onClickUpcoming: (manga: Manga) -> Unit,
|
|
) {
|
|
TwoPanelBox(
|
|
modifier = Modifier.padding(paddingValues),
|
|
startContent = {
|
|
Calendar(
|
|
selectedYearMonth = selectedYearMonth,
|
|
events = events,
|
|
setSelectedYearMonth = setSelectedYearMonth,
|
|
onClickDay = onClickDay,
|
|
)
|
|
},
|
|
endContent = {
|
|
FastScrollLazyColumn(state = listState) {
|
|
items(
|
|
items = items,
|
|
key = { "upcoming-${it.hashCode()}" },
|
|
contentType = {
|
|
when (it) {
|
|
is UpcomingUIModel.Header -> "header"
|
|
is UpcomingUIModel.Item -> "item"
|
|
}
|
|
},
|
|
) { item ->
|
|
when (item) {
|
|
is UpcomingUIModel.Item -> {
|
|
UpcomingItem(
|
|
upcoming = item.manga,
|
|
onClick = { onClickUpcoming(item.manga) },
|
|
)
|
|
}
|
|
is UpcomingUIModel.Header -> {
|
|
ListGroupHeader(text = relativeDateText(item.date))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
)
|
|
}
|