Refine
This commit is contained in:
1 parent
35cff4647a
commit
16fddcb377
1 file changed
+97
-95
@@ -39,6 +39,7 @@ import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.ListItem
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ShapeDefaults
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
|
||||
@@ -126,7 +127,6 @@ import moe.tarsin.coroutines.runSuspendCatching
|
||||
fun FavouritesScreen(navigator: NavController) {
|
||||
// Meta State
|
||||
var urlBuilder by rememberSaveable { mutableStateOf(FavListUrlBuilder(favCat = Settings.recentFavCat)) }
|
||||
var refreshKey by rememberSaveable { mutableStateOf(false) }
|
||||
var searchBarOffsetY by remember { mutableStateOf(0) }
|
||||
|
||||
// Derived State
|
||||
@@ -149,69 +149,7 @@ fun FavouritesScreen(navigator: NavController) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val localFavCountFlow = rememberInVM { EhDB.localFavCount }
|
||||
val searchBarHint = stringResource(R.string.search_bar_hint, favCatName)
|
||||
|
||||
fun refresh(newUrlBuilder: FavListUrlBuilder) {
|
||||
if (urlBuilder == newUrlBuilder) {
|
||||
refreshKey = !refreshKey
|
||||
} else {
|
||||
urlBuilder = newUrlBuilder
|
||||
}
|
||||
}
|
||||
|
||||
fun switchFav(newCat: Int, keyword: String? = null) {
|
||||
refresh(
|
||||
urlBuilder.copy(
|
||||
keyword = keyword,
|
||||
favCat = newCat,
|
||||
jumpTo = null,
|
||||
).apply { setIndex(null, true) },
|
||||
)
|
||||
Settings.recentFavCat = urlBuilder.favCat
|
||||
}
|
||||
|
||||
with(activity) {
|
||||
ProvideSideSheetContent { sheetState ->
|
||||
val localFavCount by localFavCountFlow.collectAsState(0)
|
||||
TopAppBar(
|
||||
title = { Text(text = stringResource(id = R.string.collections)) },
|
||||
windowInsets = WindowInsets(0, 0, 0, 0),
|
||||
)
|
||||
val scope = currentRecomposeScope
|
||||
LaunchedEffect(Unit) {
|
||||
Settings.favChangesFlow.collect {
|
||||
scope.invalidate()
|
||||
}
|
||||
}
|
||||
val localFav = stringResource(id = R.string.local_favorites) to localFavCount
|
||||
val faves = if (EhCookieStore.hasSignedIn()) {
|
||||
arrayOf(
|
||||
localFav,
|
||||
stringResource(id = R.string.cloud_favorites) to Settings.favCloudCount,
|
||||
*Settings.favCat.zip(Settings.favCount.toTypedArray()).toTypedArray(),
|
||||
)
|
||||
} else {
|
||||
arrayOf(localFav)
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier.verticalScroll(rememberScrollState())
|
||||
.windowInsetsPadding(WindowInsets.systemBars.only(WindowInsetsSides.Bottom)),
|
||||
) {
|
||||
faves.forEachIndexed { index, (name, count) ->
|
||||
ListItem(
|
||||
headlineContent = { Text(text = name) },
|
||||
trailingContent = { Text(text = count.toString(), style = MaterialTheme.typography.bodyLarge) },
|
||||
modifier = Modifier.clickable {
|
||||
switchFav(index - 2)
|
||||
coroutineScope.launch { sheetState.close() }
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val searchFieldState = rememberTextFieldState()
|
||||
val data = rememberInVM(urlBuilder, refreshKey) {
|
||||
val data = rememberInVM(urlBuilder.favCat == FavListUrlBuilder.FAV_CAT_LOCAL) {
|
||||
if (urlBuilder.favCat == FavListUrlBuilder.FAV_CAT_LOCAL) {
|
||||
Pager(PagingConfig(20, jumpThreshold = 40)) {
|
||||
if (keyword.isBlank()) {
|
||||
@@ -255,13 +193,63 @@ fun FavouritesScreen(navigator: NavController) {
|
||||
}.flow.cachedIn(viewModelScope)
|
||||
}.collectAsLazyPagingItems()
|
||||
|
||||
fun refresh(newUrlBuilder: FavListUrlBuilder = urlBuilder.copy(jumpTo = null, prev = null, next = null)) {
|
||||
urlBuilder = newUrlBuilder
|
||||
data.refresh()
|
||||
}
|
||||
|
||||
with(activity) {
|
||||
ProvideSideSheetContent { sheetState ->
|
||||
val localFavCount by localFavCountFlow.collectAsState(0)
|
||||
TopAppBar(
|
||||
title = { Text(text = stringResource(id = R.string.collections)) },
|
||||
windowInsets = WindowInsets(0, 0, 0, 0),
|
||||
)
|
||||
val scope = currentRecomposeScope
|
||||
LaunchedEffect(Unit) {
|
||||
Settings.favChangesFlow.collect {
|
||||
scope.invalidate()
|
||||
}
|
||||
}
|
||||
val localFav = stringResource(id = R.string.local_favorites) to localFavCount
|
||||
val faves = if (EhCookieStore.hasSignedIn()) {
|
||||
arrayOf(
|
||||
localFav,
|
||||
stringResource(id = R.string.cloud_favorites) to Settings.favCloudCount,
|
||||
*Settings.favCat.zip(Settings.favCount.toTypedArray()).toTypedArray(),
|
||||
)
|
||||
} else {
|
||||
arrayOf(localFav)
|
||||
}
|
||||
Column(
|
||||
modifier = Modifier.verticalScroll(rememberScrollState())
|
||||
.windowInsetsPadding(WindowInsets.systemBars.only(WindowInsetsSides.Bottom)),
|
||||
) {
|
||||
faves.forEachIndexed { index, (name, count) ->
|
||||
ListItem(
|
||||
headlineContent = { Text(text = name) },
|
||||
trailingContent = { Text(text = count.toString(), style = MaterialTheme.typography.bodyLarge) },
|
||||
modifier = Modifier.clickable {
|
||||
val newCat = index - 2
|
||||
refresh(FavListUrlBuilder(newCat))
|
||||
Settings.recentFavCat = newCat
|
||||
coroutineScope.launch { sheetState.close() }
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val searchFieldState = rememberTextFieldState()
|
||||
|
||||
val refreshState = rememberPullToRefreshState {
|
||||
data.loadState.refresh is LoadState.NotLoading
|
||||
}
|
||||
|
||||
if (refreshState.isRefreshing) {
|
||||
LaunchedEffect(Unit) {
|
||||
data.refresh()
|
||||
refresh()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,7 +276,7 @@ fun FavouritesScreen(navigator: NavController) {
|
||||
title = title,
|
||||
searchFieldState = searchFieldState,
|
||||
searchFieldHint = searchBarHint,
|
||||
onApplySearch = { switchFav(urlBuilder.favCat, it) },
|
||||
onApplySearch = { refresh(FavListUrlBuilder(urlBuilder.favCat, it)) },
|
||||
onSearchExpanded = { hidden = true },
|
||||
onSearchHidden = { hidden = false },
|
||||
refreshState = refreshState,
|
||||
@@ -312,33 +300,6 @@ fun FavouritesScreen(navigator: NavController) {
|
||||
Settings.listModeBackField.valueFlow()
|
||||
}.collectAsState(Settings.listMode)
|
||||
Box(modifier = Modifier.fillMaxSize()) {
|
||||
when (val state = data.loadState.refresh) {
|
||||
is LoadState.Loading -> if (data.itemCount == 0) {
|
||||
CircularProgressIndicator(modifier = Modifier.align(Alignment.Center))
|
||||
}
|
||||
is LoadState.Error -> {
|
||||
Column(
|
||||
modifier = Modifier.align(Alignment.Center).widthIn(max = 228.dp)
|
||||
.clip(ShapeDefaults.Small).clickable { data.retry() },
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = EhIcons.Big.Default.SadAndroid,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.padding(16.dp).size(120.dp),
|
||||
tint = MaterialTheme.colorScheme.tertiary,
|
||||
)
|
||||
Text(
|
||||
text = ExceptionUtils.getReadableString(state.error),
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
}
|
||||
is LoadState.NotLoading -> SideEffect {
|
||||
refreshState.endRefresh()
|
||||
}
|
||||
}
|
||||
if (listMode == 0) {
|
||||
val height = (3 * Settings.listThumbSize * 3).pxToDp.dp
|
||||
val showPages = Settings.showGalleryPages
|
||||
@@ -428,6 +389,47 @@ fun FavouritesScreen(navigator: NavController) {
|
||||
}
|
||||
}
|
||||
}
|
||||
when (val state = data.loadState.refresh) {
|
||||
is LoadState.Loading -> if (!refreshState.isRefreshing) {
|
||||
Surface {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
CircularProgressIndicator()
|
||||
}
|
||||
}
|
||||
}
|
||||
is LoadState.Error -> {
|
||||
Surface {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier.widthIn(max = 228.dp)
|
||||
.clip(ShapeDefaults.Small).clickable { data.retry() },
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
) {
|
||||
Icon(
|
||||
imageVector = EhIcons.Big.Default.SadAndroid,
|
||||
contentDescription = null,
|
||||
modifier = Modifier.padding(16.dp).size(120.dp),
|
||||
tint = MaterialTheme.colorScheme.tertiary,
|
||||
)
|
||||
Text(
|
||||
text = ExceptionUtils.getReadableString(state.error),
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is LoadState.NotLoading -> SideEffect {
|
||||
refreshState.endRefresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -468,10 +470,10 @@ fun FavouritesScreen(navigator: NavController) {
|
||||
}
|
||||
}
|
||||
onClick(Icons.Default.Refresh) {
|
||||
switchFav(urlBuilder.favCat)
|
||||
refresh()
|
||||
}
|
||||
onClick(Icons.AutoMirrored.Default.LastPage) {
|
||||
refresh(urlBuilder.copy().apply { setIndex("1-0", false) })
|
||||
refresh(urlBuilder.copy(jumpTo = null, prev = "1-0", next = null))
|
||||
}
|
||||
} else {
|
||||
onClick(Icons.Default.DoneAll) {
|
||||
|
||||
Reference in new issue
Block a user