package eu.kanade.presentation.browse import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.lazy.grid.GridCells import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.HelpOutline import androidx.compose.material.icons.outlined.Public import androidx.compose.material.icons.outlined.Refresh import androidx.compose.material3.SnackbarDuration import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarResult import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.platform.LocalContext import androidx.paging.LoadState import androidx.paging.compose.LazyPagingItems import eu.kanade.data.source.NoResultsException import eu.kanade.domain.library.model.LibraryDisplayMode import eu.kanade.domain.manga.model.Manga import eu.kanade.presentation.browse.components.BrowseSourceComfortableGrid import eu.kanade.presentation.browse.components.BrowseSourceCompactGrid import eu.kanade.presentation.browse.components.BrowseSourceList import eu.kanade.presentation.components.EmptyScreen import eu.kanade.presentation.components.EmptyScreenAction import eu.kanade.presentation.components.LoadingScreen import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.LocalSource import kotlinx.coroutines.flow.StateFlow @Composable fun BrowseSourceContent( source: CatalogueSource?, mangaList: LazyPagingItems>, columns: GridCells, displayMode: LibraryDisplayMode, snackbarHostState: SnackbarHostState, contentPadding: PaddingValues, onWebViewClick: () -> Unit, onHelpClick: () -> Unit, onLocalSourceHelpClick: () -> Unit, onMangaClick: (Manga) -> Unit, onMangaLongClick: (Manga) -> Unit, ) { val context = LocalContext.current val errorState = mangaList.loadState.refresh.takeIf { it is LoadState.Error } ?: mangaList.loadState.append.takeIf { it is LoadState.Error } val getErrorMessage: (LoadState.Error) -> String = { state -> when { state.error is NoResultsException -> context.getString(R.string.no_results_found) state.error.message.isNullOrEmpty() -> "" state.error.message.orEmpty().startsWith("HTTP error") -> "${state.error.message}: ${context.getString(R.string.http_error_hint)}" else -> state.error.message.orEmpty() } } LaunchedEffect(errorState) { if (mangaList.itemCount > 0 && errorState != null && errorState is LoadState.Error) { val result = snackbarHostState.showSnackbar( message = getErrorMessage(errorState), actionLabel = context.getString(R.string.action_webview_refresh), duration = SnackbarDuration.Indefinite, ) when (result) { SnackbarResult.Dismissed -> snackbarHostState.currentSnackbarData?.dismiss() SnackbarResult.ActionPerformed -> mangaList.refresh() } } } if (mangaList.itemCount <= 0 && errorState != null && errorState is LoadState.Error) { EmptyScreen( message = getErrorMessage(errorState), actions = if (source is LocalSource) { listOf( EmptyScreenAction( stringResId = R.string.local_source_help_guide, icon = Icons.Outlined.HelpOutline, onClick = onLocalSourceHelpClick, ), ) } else { listOf( EmptyScreenAction( stringResId = R.string.action_retry, icon = Icons.Outlined.Refresh, onClick = mangaList::refresh, ), EmptyScreenAction( stringResId = R.string.action_open_in_web_view, icon = Icons.Outlined.Public, onClick = onWebViewClick, ), EmptyScreenAction( stringResId = R.string.label_help, icon = Icons.Outlined.HelpOutline, onClick = onHelpClick, ), ) }, ) return } if (mangaList.itemCount == 0 && mangaList.loadState.refresh is LoadState.Loading) { LoadingScreen() return } when (displayMode) { LibraryDisplayMode.ComfortableGrid -> { BrowseSourceComfortableGrid( mangaList = mangaList, columns = columns, contentPadding = contentPadding, onMangaClick = onMangaClick, onMangaLongClick = onMangaLongClick, ) } LibraryDisplayMode.List -> { BrowseSourceList( mangaList = mangaList, contentPadding = contentPadding, onMangaClick = onMangaClick, onMangaLongClick = onMangaLongClick, ) } LibraryDisplayMode.CompactGrid, LibraryDisplayMode.CoverOnlyGrid -> { BrowseSourceCompactGrid( mangaList = mangaList, columns = columns, contentPadding = contentPadding, onMangaClick = onMangaClick, onMangaLongClick = onMangaLongClick, ) } } }