Moves to hold the feed itself in a stateflow
This commit is contained in:
@@ -22,7 +22,6 @@ package com.vitorpamplona.amethyst.ui.feeds
|
|||||||
|
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
||||||
@@ -38,7 +37,6 @@ import kotlinx.coroutines.CoroutineScope
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.update
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
@@ -79,7 +77,7 @@ class FeedContentState(
|
|||||||
|
|
||||||
val oldNotesState = _feedContent.value
|
val oldNotesState = _feedContent.value
|
||||||
if (oldNotesState is FeedState.Loaded) {
|
if (oldNotesState is FeedState.Loaded) {
|
||||||
if (!equalImmutableLists(notes, oldNotesState.feed.value)) {
|
if (!equalImmutableLists(notes, oldNotesState.feed.value.list)) {
|
||||||
updateFeed(notes)
|
updateFeed(notes)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -88,21 +86,15 @@ class FeedContentState(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateFeed(notes: ImmutableList<Note>) {
|
private fun updateFeed(notes: ImmutableList<Note>) {
|
||||||
viewModelScope.launch(Dispatchers.Main) {
|
val currentState = _feedContent.value
|
||||||
val currentState = _feedContent.value
|
if (notes.isEmpty()) {
|
||||||
if (notes.isEmpty()) {
|
_feedContent.tryEmit(FeedState.Empty)
|
||||||
_feedContent.update { FeedState.Empty }
|
} else if (currentState is FeedState.Loaded) {
|
||||||
} else if (currentState is FeedState.Loaded) {
|
currentState.feed.tryEmit(LoadedFeedState(notes, localFilter.showHiddenKey()))
|
||||||
// updates the current list
|
} else {
|
||||||
if (currentState.showHidden.value != localFilter.showHiddenKey()) {
|
_feedContent.tryEmit(
|
||||||
currentState.showHidden.value = localFilter.showHiddenKey()
|
FeedState.Loaded(MutableStateFlow(LoadedFeedState(notes, localFilter.showHiddenKey()))),
|
||||||
}
|
)
|
||||||
currentState.feed.value = notes
|
|
||||||
} else {
|
|
||||||
_feedContent.update {
|
|
||||||
FeedState.Loaded(mutableStateOf(notes), mutableStateOf(localFilter.showHiddenKey()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,11 +110,11 @@ class FeedContentState(
|
|||||||
|
|
||||||
val oldList =
|
val oldList =
|
||||||
if (deletionEvents.isEmpty()) {
|
if (deletionEvents.isEmpty()) {
|
||||||
oldNotesState.feed.value
|
oldNotesState.feed.value.list
|
||||||
} else {
|
} else {
|
||||||
val deletedEventIds = deletionEvents.flatMapTo(HashSet()) { it.deleteEvents() }
|
val deletedEventIds = deletionEvents.flatMapTo(HashSet()) { it.deleteEvents() }
|
||||||
val deletedEventAddresses = deletionEvents.flatMapTo(HashSet()) { it.deleteAddresses() }
|
val deletedEventAddresses = deletionEvents.flatMapTo(HashSet()) { it.deleteAddresses() }
|
||||||
oldNotesState.feed.value
|
oldNotesState.feed.value.list
|
||||||
.filter { !it.wasOrShouldBeDeletedBy(deletedEventIds, deletedEventAddresses) }
|
.filter { !it.wasOrShouldBeDeletedBy(deletedEventIds, deletedEventAddresses) }
|
||||||
.toImmutableList()
|
.toImmutableList()
|
||||||
}
|
}
|
||||||
@@ -132,7 +124,7 @@ class FeedContentState(
|
|||||||
.updateListWith(oldList, newItems)
|
.updateListWith(oldList, newItems)
|
||||||
.distinctBy { it.idHex }
|
.distinctBy { it.idHex }
|
||||||
.toImmutableList()
|
.toImmutableList()
|
||||||
if (!equalImmutableLists(newList, oldNotesState.feed.value)) {
|
if (!equalImmutableLists(newList, oldNotesState.feed.value.list)) {
|
||||||
updateFeed(newList)
|
updateFeed(newList)
|
||||||
}
|
}
|
||||||
} else if (oldNotesState is FeedState.Empty) {
|
} else if (oldNotesState is FeedState.Empty) {
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ import androidx.compose.foundation.lazy.LazyListState
|
|||||||
import androidx.compose.foundation.lazy.itemsIndexed
|
import androidx.compose.foundation.lazy.itemsIndexed
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import com.vitorpamplona.amethyst.ui.note.NoteCompose
|
import com.vitorpamplona.amethyst.ui.note.NoteCompose
|
||||||
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel
|
||||||
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
import com.vitorpamplona.amethyst.ui.theme.DividerThickness
|
||||||
@@ -37,24 +39,26 @@ import com.vitorpamplona.amethyst.ui.theme.FeedPadding
|
|||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun FeedLoaded(
|
fun FeedLoaded(
|
||||||
state: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
routeForLastRead: String?,
|
routeForLastRead: String?,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: (String) -> Unit,
|
nav: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
contentPadding = FeedPadding,
|
contentPadding = FeedPadding,
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(state.feed.value, key = { _, item -> item.idHex }) { _, item ->
|
itemsIndexed(items.list, key = { _, item -> item.idHex }) { _, item ->
|
||||||
Row(Modifier.fillMaxWidth().animateItemPlacement()) {
|
Row(Modifier.fillMaxWidth().animateItemPlacement()) {
|
||||||
NoteCompose(
|
NoteCompose(
|
||||||
item,
|
item,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
routeForLastRead = routeForLastRead,
|
routeForLastRead = routeForLastRead,
|
||||||
isBoostedNote = false,
|
isBoostedNote = false,
|
||||||
isHiddenFeed = state.showHidden.value,
|
isHiddenFeed = items.showHidden,
|
||||||
quotesLeft = 3,
|
quotesLeft = 3,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
|
|||||||
@@ -20,16 +20,17 @@
|
|||||||
*/
|
*/
|
||||||
package com.vitorpamplona.amethyst.ui.feeds
|
package com.vitorpamplona.amethyst.ui.feeds
|
||||||
|
|
||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.Stable
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
||||||
|
@Stable
|
||||||
sealed class FeedState {
|
sealed class FeedState {
|
||||||
object Loading : FeedState()
|
object Loading : FeedState()
|
||||||
|
|
||||||
class Loaded(
|
class Loaded(
|
||||||
val feed: MutableState<ImmutableList<Note>>,
|
val feed: MutableStateFlow<LoadedFeedState<Note>>,
|
||||||
val showHidden: MutableState<Boolean>,
|
|
||||||
) : FeedState()
|
) : FeedState()
|
||||||
|
|
||||||
object Empty : FeedState()
|
object Empty : FeedState()
|
||||||
@@ -38,3 +39,9 @@ sealed class FeedState {
|
|||||||
val errorMessage: String,
|
val errorMessage: String,
|
||||||
) : FeedState()
|
) : FeedState()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Stable
|
||||||
|
class LoadedFeedState<T>(
|
||||||
|
val list: ImmutableList<T>,
|
||||||
|
val showHidden: Boolean,
|
||||||
|
)
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ import androidx.compose.ui.tooling.preview.Preview
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.em
|
import androidx.compose.ui.unit.em
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import coil.compose.AsyncImage
|
import coil.compose.AsyncImage
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
@@ -224,22 +225,24 @@ fun ThreadFeedView(
|
|||||||
@Composable
|
@Composable
|
||||||
fun RenderThreadFeed(
|
fun RenderThreadFeed(
|
||||||
noteId: String,
|
noteId: String,
|
||||||
state: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: (String) -> Unit,
|
nav: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LaunchedEffect(noteId) {
|
LaunchedEffect(noteId) {
|
||||||
// waits to load the thread to scroll to item.
|
// waits to load the thread to scroll to item.
|
||||||
delay(100)
|
delay(100)
|
||||||
val noteForPosition =
|
val noteForPosition =
|
||||||
state.feed.value
|
items.list
|
||||||
.filter { it.idHex == noteId }
|
.filter { it.idHex == noteId }
|
||||||
.firstOrNull()
|
.firstOrNull()
|
||||||
var position = state.feed.value.indexOf(noteForPosition)
|
var position = items.list.indexOf(noteForPosition)
|
||||||
|
|
||||||
if (position >= 0) {
|
if (position >= 0) {
|
||||||
if (position >= 1 && position < state.feed.value.size - 1) {
|
if (position >= 1 && position < items.list.size - 1) {
|
||||||
position-- // show the replying note
|
position-- // show the replying note
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,7 +254,7 @@ fun RenderThreadFeed(
|
|||||||
contentPadding = FeedPadding,
|
contentPadding = FeedPadding,
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(state.feed.value, key = { _, item -> item.idHex }) { index, item ->
|
itemsIndexed(items.list, key = { _, item -> item.idHex }) { index, item ->
|
||||||
if (index == 0) {
|
if (index == 0) {
|
||||||
ProvideTextStyle(TextStyle(fontSize = 18.sp, lineHeight = 1.20.em)) {
|
ProvideTextStyle(TextStyle(fontSize = 18.sp, lineHeight = 1.20.em)) {
|
||||||
NoteMaster(
|
NoteMaster(
|
||||||
|
|||||||
+7
-4
@@ -46,6 +46,7 @@ import androidx.compose.ui.platform.LocalLifecycleOwner
|
|||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.lifecycle.Lifecycle
|
import androidx.lifecycle.Lifecycle
|
||||||
import androidx.lifecycle.LifecycleEventObserver
|
import androidx.lifecycle.LifecycleEventObserver
|
||||||
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.vitorpamplona.amethyst.R
|
import com.vitorpamplona.amethyst.R
|
||||||
import com.vitorpamplona.amethyst.ui.components.SwipeToDeleteContainer
|
import com.vitorpamplona.amethyst.ui.components.SwipeToDeleteContainer
|
||||||
@@ -119,12 +120,14 @@ private fun RenderDraftListScreen(
|
|||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun DraftFeedLoaded(
|
private fun DraftFeedLoaded(
|
||||||
state: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
routeForLastRead: String?,
|
routeForLastRead: String?,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: (String) -> Unit,
|
nav: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
var showDeleteDialog by remember { mutableStateOf(false) }
|
var showDeleteDialog by remember { mutableStateOf(false) }
|
||||||
|
|
||||||
if (showDeleteDialog) {
|
if (showDeleteDialog) {
|
||||||
@@ -141,7 +144,7 @@ private fun DraftFeedLoaded(
|
|||||||
confirmButton = {
|
confirmButton = {
|
||||||
TextButton(
|
TextButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
accountViewModel.delete(state.feed.value)
|
accountViewModel.delete(items.list)
|
||||||
showDeleteDialog = false
|
showDeleteDialog = false
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
@@ -177,7 +180,7 @@ private fun DraftFeedLoaded(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
itemsIndexed(state.feed.value, key = { _, item -> item.idHex }) { _, item ->
|
itemsIndexed(items.list, key = { _, item -> item.idHex }) { _, item ->
|
||||||
Row(
|
Row(
|
||||||
Modifier
|
Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
@@ -196,7 +199,7 @@ private fun DraftFeedLoaded(
|
|||||||
modifier = MaterialTheme.colorScheme.maxWidthWithBackground,
|
modifier = MaterialTheme.colorScheme.maxWidthWithBackground,
|
||||||
routeForLastRead = routeForLastRead,
|
routeForLastRead = routeForLastRead,
|
||||||
isBoostedNote = false,
|
isBoostedNote = false,
|
||||||
isHiddenFeed = state.showHidden.value,
|
isHiddenFeed = items.showHidden,
|
||||||
quotesLeft = 3,
|
quotesLeft = 3,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
|
|||||||
+5
-11
@@ -40,7 +40,6 @@ import androidx.compose.runtime.Immutable
|
|||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
import androidx.compose.runtime.livedata.observeAsState
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Alignment.Companion.BottomStart
|
import androidx.compose.ui.Alignment.Companion.BottomStart
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
@@ -118,26 +117,21 @@ fun RenderGalleryFeed(
|
|||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun GalleryFeedLoaded(
|
private fun GalleryFeedLoaded(
|
||||||
state: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
routeForLastRead: String?,
|
routeForLastRead: String?,
|
||||||
listState: LazyGridState,
|
listState: LazyGridState,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: (String) -> Unit,
|
nav: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LazyVerticalGrid(
|
LazyVerticalGrid(
|
||||||
columns = GridCells.Fixed(3),
|
columns = GridCells.Fixed(3),
|
||||||
contentPadding = FeedPadding,
|
contentPadding = FeedPadding,
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(state.feed.value, key = { _, item -> item.idHex }) { _, item ->
|
itemsIndexed(items.list, key = { _, item -> item.idHex }) { _, item ->
|
||||||
val defaultModifier =
|
Row(Modifier.fillMaxWidth().animateItemPlacement()) {
|
||||||
remember {
|
|
||||||
Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.animateItemPlacement()
|
|
||||||
}
|
|
||||||
|
|
||||||
Row(defaultModifier) {
|
|
||||||
GalleryCardCompose(
|
GalleryCardCompose(
|
||||||
baseNote = item,
|
baseNote = item,
|
||||||
routeForLastRead = routeForLastRead,
|
routeForLastRead = routeForLastRead,
|
||||||
|
|||||||
+16
-6
@@ -1238,12 +1238,7 @@ private fun DisplayAppRecommendations(
|
|||||||
Column {
|
Column {
|
||||||
Text(stringRes(id = R.string.recommended_apps))
|
Text(stringRes(id = R.string.recommended_apps))
|
||||||
|
|
||||||
FlowRow(
|
Recommends(state, nav)
|
||||||
verticalArrangement = Arrangement.Center,
|
|
||||||
modifier = Modifier.padding(vertical = 5.dp),
|
|
||||||
) {
|
|
||||||
state.feed.value.forEach { app -> WatchApp(app, nav) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {}
|
else -> {}
|
||||||
@@ -1251,6 +1246,21 @@ private fun DisplayAppRecommendations(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
@OptIn(ExperimentalLayoutApi::class)
|
||||||
|
private fun Recommends(
|
||||||
|
loaded: FeedState.Loaded,
|
||||||
|
nav: (String) -> Unit,
|
||||||
|
) {
|
||||||
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
FlowRow(
|
||||||
|
verticalArrangement = Arrangement.Center,
|
||||||
|
modifier = Modifier.padding(vertical = 5.dp),
|
||||||
|
) {
|
||||||
|
items.list.forEach { app -> WatchApp(app, nav) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun WatchApp(
|
private fun WatchApp(
|
||||||
baseApp: Note,
|
baseApp: Note,
|
||||||
|
|||||||
+5
-3
@@ -122,7 +122,7 @@ fun RenderChatroomFeedView(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun ChatroomFeedLoaded(
|
fun ChatroomFeedLoaded(
|
||||||
state: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
nav: (String) -> Unit,
|
nav: (String) -> Unit,
|
||||||
@@ -131,7 +131,9 @@ fun ChatroomFeedLoaded(
|
|||||||
onWantsToEditDraft: (Note) -> Unit,
|
onWantsToEditDraft: (Note) -> Unit,
|
||||||
avoidDraft: String? = null,
|
avoidDraft: String? = null,
|
||||||
) {
|
) {
|
||||||
LaunchedEffect(state.feed.value.firstOrNull()) {
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
|
LaunchedEffect(items.list.firstOrNull()) {
|
||||||
if (listState.firstVisibleItemIndex <= 1) {
|
if (listState.firstVisibleItemIndex <= 1) {
|
||||||
listState.animateScrollToItem(0)
|
listState.animateScrollToItem(0)
|
||||||
}
|
}
|
||||||
@@ -143,7 +145,7 @@ fun ChatroomFeedLoaded(
|
|||||||
reverseLayout = true,
|
reverseLayout = true,
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(state.feed.value, key = { _, item -> item.idHex }) { _, item ->
|
itemsIndexed(items.list, key = { _, item -> item.idHex }) { _, item ->
|
||||||
val noteEvent = item.event
|
val noteEvent = item.event
|
||||||
if (avoidDraft == null || noteEvent !is DraftEvent || noteEvent.dTag() != avoidDraft) {
|
if (avoidDraft == null || noteEvent !is DraftEvent || noteEvent.dTag() != avoidDraft) {
|
||||||
ChatroomMessageCompose(
|
ChatroomMessageCompose(
|
||||||
|
|||||||
+5
-3
@@ -88,16 +88,18 @@ private fun CrossFadeState(
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun FeedLoaded(
|
private fun FeedLoaded(
|
||||||
state: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: (String) -> Unit,
|
nav: (String) -> Unit,
|
||||||
markAsRead: MutableState<Boolean>,
|
markAsRead: MutableState<Boolean>,
|
||||||
) {
|
) {
|
||||||
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
val listState = rememberLazyListState()
|
val listState = rememberLazyListState()
|
||||||
|
|
||||||
LaunchedEffect(key1 = markAsRead.value) {
|
LaunchedEffect(key1 = markAsRead.value) {
|
||||||
if (markAsRead.value) {
|
if (markAsRead.value) {
|
||||||
accountViewModel.markAllAsRead(state.feed.value) { markAsRead.value = false }
|
accountViewModel.markAllAsRead(items.list) { markAsRead.value = false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,7 +108,7 @@ private fun FeedLoaded(
|
|||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(
|
itemsIndexed(
|
||||||
state.feed.value,
|
items.list,
|
||||||
key = { index, item -> if (index == 0) index else item.idHex },
|
key = { index, item -> if (index == 0) index else item.idHex },
|
||||||
) { _, item ->
|
) { _, item ->
|
||||||
Row(Modifier.fillMaxWidth()) {
|
Row(Modifier.fillMaxWidth()) {
|
||||||
|
|||||||
+8
-4
@@ -347,18 +347,20 @@ fun WatchAccountForDiscoveryScreen(
|
|||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun DiscoverFeedLoaded(
|
private fun DiscoverFeedLoaded(
|
||||||
state: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
routeForLastRead: String?,
|
routeForLastRead: String?,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
forceEventKind: Int?,
|
forceEventKind: Int?,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: (String) -> Unit,
|
nav: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
contentPadding = FeedPadding,
|
contentPadding = FeedPadding,
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(state.feed.value, key = { _, item -> item.idHex }) { _, item ->
|
itemsIndexed(items.list, key = { _, item -> item.idHex }) { _, item ->
|
||||||
val defaultModifier = remember { Modifier.fillMaxWidth().animateItemPlacement() }
|
val defaultModifier = remember { Modifier.fillMaxWidth().animateItemPlacement() }
|
||||||
|
|
||||||
Row(defaultModifier) {
|
Row(defaultModifier) {
|
||||||
@@ -382,19 +384,21 @@ private fun DiscoverFeedLoaded(
|
|||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun DiscoverFeedColumnsLoaded(
|
private fun DiscoverFeedColumnsLoaded(
|
||||||
state: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
routeForLastRead: String?,
|
routeForLastRead: String?,
|
||||||
listState: LazyGridState,
|
listState: LazyGridState,
|
||||||
forceEventKind: Int?,
|
forceEventKind: Int?,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: (String) -> Unit,
|
nav: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LazyVerticalGrid(
|
LazyVerticalGrid(
|
||||||
columns = GridCells.Fixed(2),
|
columns = GridCells.Fixed(2),
|
||||||
contentPadding = FeedPadding,
|
contentPadding = FeedPadding,
|
||||||
state = listState,
|
state = listState,
|
||||||
) {
|
) {
|
||||||
itemsIndexed(state.feed.value, key = { _, item -> item.idHex }) { _, item ->
|
itemsIndexed(items.list, key = { _, item -> item.idHex }) { _, item ->
|
||||||
val defaultModifier = remember { Modifier.fillMaxWidth().animateItemPlacement() }
|
val defaultModifier = remember { Modifier.fillMaxWidth().animateItemPlacement() }
|
||||||
|
|
||||||
Row(defaultModifier) {
|
Row(defaultModifier) {
|
||||||
|
|||||||
+14
-21
@@ -23,7 +23,6 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications
|
|||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import com.vitorpamplona.amethyst.model.Account
|
import com.vitorpamplona.amethyst.model.Account
|
||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
@@ -34,6 +33,7 @@ import com.vitorpamplona.amethyst.ui.dal.DefaultFeedOrderCard
|
|||||||
import com.vitorpamplona.amethyst.ui.dal.FeedFilter
|
import com.vitorpamplona.amethyst.ui.dal.FeedFilter
|
||||||
import com.vitorpamplona.amethyst.ui.dal.NotificationFeedFilter
|
import com.vitorpamplona.amethyst.ui.dal.NotificationFeedFilter
|
||||||
import com.vitorpamplona.amethyst.ui.feeds.InvalidatableContent
|
import com.vitorpamplona.amethyst.ui.feeds.InvalidatableContent
|
||||||
|
import com.vitorpamplona.amethyst.ui.feeds.LoadedFeedState
|
||||||
import com.vitorpamplona.ammolite.relays.BundledInsert
|
import com.vitorpamplona.ammolite.relays.BundledInsert
|
||||||
import com.vitorpamplona.ammolite.relays.BundledUpdate
|
import com.vitorpamplona.ammolite.relays.BundledUpdate
|
||||||
import com.vitorpamplona.quartz.events.BadgeAwardEvent
|
import com.vitorpamplona.quartz.events.BadgeAwardEvent
|
||||||
@@ -51,7 +51,6 @@ import kotlinx.coroutines.CoroutineScope
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.flow.update
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.ZoneId
|
import java.time.ZoneId
|
||||||
@@ -109,13 +108,13 @@ class CardFeedContentState(
|
|||||||
lastAccount = (localFilter as? NotificationFeedFilter)?.account
|
lastAccount = (localFilter as? NotificationFeedFilter)?.account
|
||||||
|
|
||||||
val updatedCards =
|
val updatedCards =
|
||||||
(oldNotesState.feed.value + newCards)
|
(oldNotesState.feed.value.list + newCards)
|
||||||
.distinctBy { it.id() }
|
.distinctBy { it.id() }
|
||||||
.sortedWith(DefaultFeedOrderCard)
|
.sortedWith(DefaultFeedOrderCard)
|
||||||
.take(localFilter.limit())
|
.take(localFilter.limit())
|
||||||
.toImmutableList()
|
.toImmutableList()
|
||||||
|
|
||||||
if (!equalImmutableLists(oldNotesState.feed.value, updatedCards)) {
|
if (!equalImmutableLists(oldNotesState.feed.value.list, updatedCards)) {
|
||||||
updateFeed(updatedCards)
|
updateFeed(updatedCards)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -291,21 +290,15 @@ class CardFeedContentState(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateFeed(notes: ImmutableList<Card>) {
|
private fun updateFeed(notes: ImmutableList<Card>) {
|
||||||
viewModelScope.launch(Dispatchers.Main) {
|
val currentState = _feedContent.value
|
||||||
val currentState = _feedContent.value
|
if (notes.isEmpty()) {
|
||||||
|
_feedContent.tryEmit(CardFeedState.Empty)
|
||||||
if (notes.isEmpty()) {
|
} else if (currentState is CardFeedState.Loaded) {
|
||||||
_feedContent.update { CardFeedState.Empty }
|
currentState.feed.tryEmit(LoadedFeedState(notes, localFilter.showHiddenKey()))
|
||||||
} else if (currentState is CardFeedState.Loaded) {
|
} else {
|
||||||
if (currentState.showHidden.value != localFilter.showHiddenKey()) {
|
_feedContent.tryEmit(
|
||||||
currentState.showHidden.value = localFilter.showHiddenKey()
|
CardFeedState.Loaded(MutableStateFlow(LoadedFeedState(notes, localFilter.showHiddenKey()))),
|
||||||
}
|
)
|
||||||
currentState.feed.value = notes
|
|
||||||
} else {
|
|
||||||
_feedContent.update {
|
|
||||||
CardFeedState.Loaded(mutableStateOf(notes), mutableStateOf(localFilter.showHiddenKey()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,14 +329,14 @@ class CardFeedContentState(
|
|||||||
lastAccount = (localFilter as? NotificationFeedFilter)?.account
|
lastAccount = (localFilter as? NotificationFeedFilter)?.account
|
||||||
|
|
||||||
val updatedCards =
|
val updatedCards =
|
||||||
(oldNotesState.feed.value + newCards)
|
(oldNotesState.feed.value.list + newCards)
|
||||||
.distinctBy { it.id() }
|
.distinctBy { it.id() }
|
||||||
.sortedWith(compareBy({ it.createdAt() }, { it.id() }))
|
.sortedWith(compareBy({ it.createdAt() }, { it.id() }))
|
||||||
.reversed()
|
.reversed()
|
||||||
.take(localFilter.limit())
|
.take(localFilter.limit())
|
||||||
.toImmutableList()
|
.toImmutableList()
|
||||||
|
|
||||||
if (!equalImmutableLists(oldNotesState.feed.value, updatedCards)) {
|
if (!equalImmutableLists(oldNotesState.feed.value.list, updatedCards)) {
|
||||||
updateFeed(updatedCards)
|
updateFeed(updatedCards)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -21,15 +21,16 @@
|
|||||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications
|
package com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.runtime.MutableState
|
|
||||||
import androidx.compose.runtime.Stable
|
import androidx.compose.runtime.Stable
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.model.User
|
import com.vitorpamplona.amethyst.model.User
|
||||||
import com.vitorpamplona.amethyst.service.firstFullCharOrEmoji
|
import com.vitorpamplona.amethyst.service.firstFullCharOrEmoji
|
||||||
|
import com.vitorpamplona.amethyst.ui.feeds.LoadedFeedState
|
||||||
import com.vitorpamplona.quartz.events.ImmutableListOfLists
|
import com.vitorpamplona.quartz.events.ImmutableListOfLists
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
import kotlinx.collections.immutable.ImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableList
|
import kotlinx.collections.immutable.toImmutableList
|
||||||
import kotlinx.collections.immutable.toImmutableMap
|
import kotlinx.collections.immutable.toImmutableMap
|
||||||
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
abstract class Card {
|
abstract class Card {
|
||||||
@@ -119,8 +120,7 @@ sealed class CardFeedState {
|
|||||||
|
|
||||||
@Stable
|
@Stable
|
||||||
class Loaded(
|
class Loaded(
|
||||||
val feed: MutableState<ImmutableList<Card>>,
|
val feed: MutableStateFlow<LoadedFeedState<Card>>,
|
||||||
val showHidden: MutableState<Boolean>,
|
|
||||||
) : CardFeedState()
|
) : CardFeedState()
|
||||||
|
|
||||||
@Immutable object Empty : CardFeedState()
|
@Immutable object Empty : CardFeedState()
|
||||||
|
|||||||
+7
-13
@@ -33,7 +33,6 @@ import androidx.compose.material3.HorizontalDivider
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.MutableState
|
import androidx.compose.runtime.MutableState
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
@@ -115,7 +114,7 @@ fun RenderCardFeed(
|
|||||||
}
|
}
|
||||||
is CardFeedState.Loaded -> {
|
is CardFeedState.Loaded -> {
|
||||||
FeedLoaded(
|
FeedLoaded(
|
||||||
state = state,
|
loaded = state,
|
||||||
listState = listState,
|
listState = listState,
|
||||||
routeForLastRead = routeForLastRead,
|
routeForLastRead = routeForLastRead,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
@@ -132,12 +131,14 @@ fun RenderCardFeed(
|
|||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun FeedLoaded(
|
private fun FeedLoaded(
|
||||||
state: CardFeedState.Loaded,
|
loaded: CardFeedState.Loaded,
|
||||||
listState: LazyListState,
|
listState: LazyListState,
|
||||||
routeForLastRead: String,
|
routeForLastRead: String,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: (String) -> Unit,
|
nav: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
contentPadding = FeedPadding,
|
contentPadding = FeedPadding,
|
||||||
@@ -148,22 +149,15 @@ private fun FeedLoaded(
|
|||||||
}
|
}
|
||||||
|
|
||||||
itemsIndexed(
|
itemsIndexed(
|
||||||
items = state.feed.value,
|
items = items.list,
|
||||||
key = { _, item -> item.id() },
|
key = { _, item -> item.id() },
|
||||||
contentType = { _, item -> item.javaClass.simpleName },
|
contentType = { _, item -> item.javaClass.simpleName },
|
||||||
) { _, item ->
|
) { _, item ->
|
||||||
val defaultModifier =
|
Row(Modifier.fillMaxWidth().animateItemPlacement()) {
|
||||||
remember {
|
|
||||||
Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.animateItemPlacement()
|
|
||||||
}
|
|
||||||
|
|
||||||
Row(defaultModifier) {
|
|
||||||
RenderCardItem(
|
RenderCardItem(
|
||||||
item,
|
item,
|
||||||
routeForLastRead,
|
routeForLastRead,
|
||||||
showHidden = state.showHidden.value,
|
showHidden = items.showHidden,
|
||||||
accountViewModel,
|
accountViewModel,
|
||||||
nav,
|
nav,
|
||||||
)
|
)
|
||||||
|
|||||||
+21
-23
@@ -32,7 +32,6 @@ import androidx.compose.foundation.layout.fillMaxSize
|
|||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.pager.PagerState
|
|
||||||
import androidx.compose.foundation.pager.VerticalPager
|
import androidx.compose.foundation.pager.VerticalPager
|
||||||
import androidx.compose.foundation.pager.rememberPagerState
|
import androidx.compose.foundation.pager.rememberPagerState
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
@@ -42,7 +41,6 @@ import androidx.compose.material3.MaterialTheme
|
|||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.DisposableEffect
|
import androidx.compose.runtime.DisposableEffect
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.MutableState
|
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
@@ -101,7 +99,6 @@ import com.vitorpamplona.amethyst.ui.theme.placeholderText
|
|||||||
import com.vitorpamplona.quartz.events.FileHeaderEvent
|
import com.vitorpamplona.quartz.events.FileHeaderEvent
|
||||||
import com.vitorpamplona.quartz.events.FileStorageHeaderEvent
|
import com.vitorpamplona.quartz.events.FileStorageHeaderEvent
|
||||||
import com.vitorpamplona.quartz.events.VideoEvent
|
import com.vitorpamplona.quartz.events.VideoEvent
|
||||||
import kotlinx.collections.immutable.ImmutableList
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun VideoScreen(
|
fun VideoScreen(
|
||||||
@@ -183,28 +180,18 @@ fun RenderPage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
@OptIn(ExperimentalFoundationApi::class)
|
|
||||||
private fun LoadedState(
|
private fun LoadedState(
|
||||||
state: FeedState.Loaded,
|
loaded: FeedState.Loaded,
|
||||||
pagerStateKey: String?,
|
pagerStateKey: String?,
|
||||||
videoFeedContentState: FeedContentState,
|
videoFeedContentState: FeedContentState,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: (String) -> Unit,
|
nav: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
val pagerState =
|
|
||||||
if (pagerStateKey != null) {
|
|
||||||
rememberForeverPagerState(pagerStateKey) { state.feed.value.size }
|
|
||||||
} else {
|
|
||||||
rememberPagerState { state.feed.value.size }
|
|
||||||
}
|
|
||||||
|
|
||||||
WatchScrollToTop(videoFeedContentState, pagerState)
|
|
||||||
|
|
||||||
RefresheableBox(invalidateableContent = videoFeedContentState) {
|
RefresheableBox(invalidateableContent = videoFeedContentState) {
|
||||||
SlidingCarousel(
|
SlidingCarousel(
|
||||||
state.feed,
|
loaded,
|
||||||
pagerState,
|
pagerStateKey,
|
||||||
state.showHidden.value,
|
videoFeedContentState,
|
||||||
accountViewModel,
|
accountViewModel,
|
||||||
nav,
|
nav,
|
||||||
)
|
)
|
||||||
@@ -214,25 +201,36 @@ private fun LoadedState(
|
|||||||
@OptIn(ExperimentalFoundationApi::class)
|
@OptIn(ExperimentalFoundationApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
fun SlidingCarousel(
|
fun SlidingCarousel(
|
||||||
feed: MutableState<ImmutableList<Note>>,
|
loaded: FeedState.Loaded,
|
||||||
pagerState: PagerState,
|
pagerStateKey: String?,
|
||||||
showHidden: Boolean,
|
videoFeedContentState: FeedContentState,
|
||||||
accountViewModel: AccountViewModel,
|
accountViewModel: AccountViewModel,
|
||||||
nav: (String) -> Unit,
|
nav: (String) -> Unit,
|
||||||
) {
|
) {
|
||||||
|
val items by loaded.feed.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
|
val pagerState =
|
||||||
|
if (pagerStateKey != null) {
|
||||||
|
rememberForeverPagerState(pagerStateKey, items.list.size) { items.list.size }
|
||||||
|
} else {
|
||||||
|
rememberPagerState(items.list.size) { items.list.size }
|
||||||
|
}
|
||||||
|
|
||||||
|
WatchScrollToTop(videoFeedContentState, pagerState)
|
||||||
|
|
||||||
VerticalPager(
|
VerticalPager(
|
||||||
state = pagerState,
|
state = pagerState,
|
||||||
beyondBoundsPageCount = 1,
|
beyondBoundsPageCount = 1,
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
key = { index -> feed.value.getOrNull(index)?.idHex ?: "$index" },
|
key = { index -> items.list.getOrNull(index)?.idHex ?: "$index" },
|
||||||
) { index ->
|
) { index ->
|
||||||
feed.value.getOrNull(index)?.let { note ->
|
items.list.getOrNull(index)?.let { note ->
|
||||||
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
|
||||||
CheckHiddenFeedWatchBlockAndReport(
|
CheckHiddenFeedWatchBlockAndReport(
|
||||||
note = note,
|
note = note,
|
||||||
modifier = Modifier.fillMaxWidth(),
|
modifier = Modifier.fillMaxWidth(),
|
||||||
showHiddenWarning = true,
|
showHiddenWarning = true,
|
||||||
ignoreAllBlocksAndReports = showHidden,
|
ignoreAllBlocksAndReports = items.showHidden,
|
||||||
accountViewModel = accountViewModel,
|
accountViewModel = accountViewModel,
|
||||||
nav = nav,
|
nav = nav,
|
||||||
) {
|
) {
|
||||||
|
|||||||
Reference in New Issue
Block a user