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, events: ImmutableMap, 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, events: ImmutableMap, 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)) } } } } }, ) }