mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-09-21 19:40:38 +02:00
Adds an isRefreshing status for all feeds.
This commit is contained in:
@@ -21,7 +21,11 @@
|
||||
package com.vitorpamplona.amethyst.ui.feeds
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
import com.vitorpamplona.amethyst.service.checkNotInMainThread
|
||||
@@ -54,6 +58,8 @@ class FeedContentState(
|
||||
|
||||
private var lastFeedKey: String? = null
|
||||
|
||||
override val isRefreshing: MutableState<Boolean> = mutableStateOf(false)
|
||||
|
||||
fun sendToTop() {
|
||||
if (scrolltoTopPending) return
|
||||
|
||||
@@ -72,16 +78,21 @@ class FeedContentState(
|
||||
fun refreshSuspended() {
|
||||
checkNotInMainThread()
|
||||
|
||||
lastFeedKey = localFilter.feedKey()
|
||||
val notes = localFilter.loadTop().distinctBy { it.idHex }.toImmutableList()
|
||||
isRefreshing.value = true
|
||||
try {
|
||||
lastFeedKey = localFilter.feedKey()
|
||||
val notes = localFilter.loadTop().distinctBy { it.idHex }.toImmutableList()
|
||||
|
||||
val oldNotesState = _feedContent.value
|
||||
if (oldNotesState is FeedState.Loaded) {
|
||||
if (!equalImmutableLists(notes, oldNotesState.feed.value.list)) {
|
||||
val oldNotesState = _feedContent.value
|
||||
if (oldNotesState is FeedState.Loaded) {
|
||||
if (!equalImmutableLists(notes, oldNotesState.feed.value.list)) {
|
||||
updateFeed(notes)
|
||||
}
|
||||
} else {
|
||||
updateFeed(notes)
|
||||
}
|
||||
} else {
|
||||
updateFeed(notes)
|
||||
} finally {
|
||||
isRefreshing.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -20,6 +20,10 @@
|
||||
*/
|
||||
package com.vitorpamplona.amethyst.ui.feeds
|
||||
|
||||
import androidx.compose.runtime.MutableState
|
||||
|
||||
interface InvalidatableContent {
|
||||
fun invalidateData(ignoreIfDoing: Boolean = false)
|
||||
|
||||
val isRefreshing: MutableState<Boolean>
|
||||
}
|
||||
|
@@ -260,6 +260,8 @@ abstract class FeedViewModel(
|
||||
InvalidatableContent {
|
||||
val feedState = FeedContentState(localFilter, viewModelScope)
|
||||
|
||||
override val isRefreshing = feedState.isRefreshing
|
||||
|
||||
fun sendToTop() = feedState.sendToTop()
|
||||
|
||||
suspend fun sentToTop() = feedState.sentToTop()
|
||||
|
@@ -21,6 +21,7 @@
|
||||
package com.vitorpamplona.amethyst.ui.screen
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.lifecycle.ViewModel
|
||||
@@ -107,19 +108,27 @@ open class UserFeedViewModel(
|
||||
viewModelScope.launch(Dispatchers.Default) { refreshSuspended() }
|
||||
}
|
||||
|
||||
override val isRefreshing: MutableState<Boolean> = mutableStateOf(false)
|
||||
|
||||
private fun refreshSuspended() {
|
||||
checkNotInMainThread()
|
||||
|
||||
val notes = dataSource.loadTop().toImmutableList()
|
||||
try {
|
||||
isRefreshing.value = true
|
||||
|
||||
val oldNotesState = _feedContent.value
|
||||
if (oldNotesState is UserFeedState.Loaded) {
|
||||
// Using size as a proxy for has changed.
|
||||
if (!equalImmutableLists(notes, oldNotesState.feed.value)) {
|
||||
val notes = dataSource.loadTop().toImmutableList()
|
||||
|
||||
val oldNotesState = _feedContent.value
|
||||
if (oldNotesState is UserFeedState.Loaded) {
|
||||
// Using size as a proxy for has changed.
|
||||
if (!equalImmutableLists(notes, oldNotesState.feed.value)) {
|
||||
updateFeed(notes)
|
||||
}
|
||||
} else {
|
||||
updateFeed(notes)
|
||||
}
|
||||
} else {
|
||||
updateFeed(notes)
|
||||
} finally {
|
||||
isRefreshing.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -22,7 +22,9 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn.notifications
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import com.vitorpamplona.amethyst.model.Account
|
||||
import com.vitorpamplona.amethyst.model.LocalCache
|
||||
import com.vitorpamplona.amethyst.model.Note
|
||||
@@ -72,6 +74,8 @@ class CardFeedContentState(
|
||||
|
||||
private var lastFeedKey: String? = null
|
||||
|
||||
override val isRefreshing: MutableState<Boolean> = mutableStateOf(false)
|
||||
|
||||
fun sendToTop() {
|
||||
if (scrolltoTopPending) return
|
||||
|
||||
@@ -94,41 +98,47 @@ class CardFeedContentState(
|
||||
private fun refreshSuspended() {
|
||||
checkNotInMainThread()
|
||||
|
||||
val notes = localFilter.feed()
|
||||
lastFeedKey = localFilter.feedKey()
|
||||
try {
|
||||
isRefreshing.value = true
|
||||
|
||||
val thisAccount = (localFilter as? NotificationFeedFilter)?.account
|
||||
val lastNotesCopy = if (thisAccount == lastAccount) lastNotes else null
|
||||
val notes = localFilter.feed()
|
||||
lastFeedKey = localFilter.feedKey()
|
||||
|
||||
val oldNotesState = _feedContent.value
|
||||
if (lastNotesCopy != null && oldNotesState is CardFeedState.Loaded) {
|
||||
val newCards = convertToCard(notes.minus(lastNotesCopy))
|
||||
if (newCards.isNotEmpty()) {
|
||||
val thisAccount = (localFilter as? NotificationFeedFilter)?.account
|
||||
val lastNotesCopy = if (thisAccount == lastAccount) lastNotes else null
|
||||
|
||||
val oldNotesState = _feedContent.value
|
||||
if (lastNotesCopy != null && oldNotesState is CardFeedState.Loaded) {
|
||||
val newCards = convertToCard(notes.minus(lastNotesCopy))
|
||||
if (newCards.isNotEmpty()) {
|
||||
lastNotes = notes.toSet()
|
||||
lastAccount = (localFilter as? NotificationFeedFilter)?.account
|
||||
|
||||
val updatedCards =
|
||||
(oldNotesState.feed.value.list + newCards)
|
||||
.distinctBy { it.id() }
|
||||
.sortedWith(DefaultFeedOrderCard)
|
||||
.take(localFilter.limit())
|
||||
.toImmutableList()
|
||||
|
||||
if (!equalImmutableLists(oldNotesState.feed.value.list, updatedCards)) {
|
||||
updateFeed(updatedCards)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
lastNotes = notes.toSet()
|
||||
lastAccount = (localFilter as? NotificationFeedFilter)?.account
|
||||
|
||||
val updatedCards =
|
||||
(oldNotesState.feed.value.list + newCards)
|
||||
.distinctBy { it.id() }
|
||||
val cards =
|
||||
convertToCard(notes)
|
||||
.sortedWith(DefaultFeedOrderCard)
|
||||
.take(localFilter.limit())
|
||||
.toImmutableList()
|
||||
|
||||
if (!equalImmutableLists(oldNotesState.feed.value.list, updatedCards)) {
|
||||
updateFeed(updatedCards)
|
||||
}
|
||||
updateFeed(cards)
|
||||
}
|
||||
} else {
|
||||
lastNotes = notes.toSet()
|
||||
lastAccount = (localFilter as? NotificationFeedFilter)?.account
|
||||
|
||||
val cards =
|
||||
convertToCard(notes)
|
||||
.sortedWith(DefaultFeedOrderCard)
|
||||
.take(localFilter.limit())
|
||||
.toImmutableList()
|
||||
|
||||
updateFeed(cards)
|
||||
} finally {
|
||||
isRefreshing.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -21,7 +21,9 @@
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.profile
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.vitorpamplona.amethyst.model.RelayInfo
|
||||
@@ -50,28 +52,36 @@ class RelayFeedViewModel :
|
||||
|
||||
var currentUser: User? = null
|
||||
|
||||
override val isRefreshing: MutableState<Boolean> = mutableStateOf(false)
|
||||
|
||||
fun refresh() {
|
||||
viewModelScope.launch(Dispatchers.Default) { refreshSuspended() }
|
||||
}
|
||||
|
||||
fun refreshSuspended() {
|
||||
val beingUsed = currentUser?.relaysBeingUsed?.values ?: emptyList()
|
||||
val beingUsedSet = currentUser?.relaysBeingUsed?.keys ?: emptySet()
|
||||
try {
|
||||
isRefreshing.value = true
|
||||
|
||||
val newRelaysFromRecord =
|
||||
currentUser?.latestContactList?.relays()?.entries?.mapNotNullTo(HashSet()) {
|
||||
val url = RelayUrlFormatter.normalize(it.key)
|
||||
if (url !in beingUsedSet) {
|
||||
RelayInfo(url, 0, 0)
|
||||
} else {
|
||||
null
|
||||
val beingUsed = currentUser?.relaysBeingUsed?.values ?: emptyList()
|
||||
val beingUsedSet = currentUser?.relaysBeingUsed?.keys ?: emptySet()
|
||||
|
||||
val newRelaysFromRecord =
|
||||
currentUser?.latestContactList?.relays()?.entries?.mapNotNullTo(HashSet()) {
|
||||
val url = RelayUrlFormatter.normalize(it.key)
|
||||
if (url !in beingUsedSet) {
|
||||
RelayInfo(url, 0, 0)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
?: emptyList()
|
||||
?: emptyList()
|
||||
|
||||
val newList = (beingUsed + newRelaysFromRecord).sortedWith(order)
|
||||
val newList = (beingUsed + newRelaysFromRecord).sortedWith(order)
|
||||
|
||||
_feedContent.update { newList }
|
||||
_feedContent.update { newList }
|
||||
} finally {
|
||||
isRefreshing.value = false
|
||||
}
|
||||
}
|
||||
|
||||
val listener: (UserState) -> Unit = { invalidateData() }
|
||||
|
@@ -21,6 +21,7 @@
|
||||
package com.vitorpamplona.amethyst.ui.screen.loggedIn.settings
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.MutableState
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.lifecycle.ViewModel
|
||||
@@ -63,6 +64,8 @@ open class StringFeedViewModel(
|
||||
private val _feedContent = MutableStateFlow<StringFeedState>(StringFeedState.Loading)
|
||||
val feedContent = _feedContent.asStateFlow()
|
||||
|
||||
override val isRefreshing: MutableState<Boolean> = mutableStateOf(false)
|
||||
|
||||
private fun refresh() {
|
||||
viewModelScope.launch(Dispatchers.Default) { refreshSuspended() }
|
||||
}
|
||||
@@ -70,16 +73,22 @@ open class StringFeedViewModel(
|
||||
private fun refreshSuspended() {
|
||||
checkNotInMainThread()
|
||||
|
||||
val notes = dataSource.loadTop().toImmutableList()
|
||||
try {
|
||||
isRefreshing.value = true
|
||||
|
||||
val oldNotesState = _feedContent.value
|
||||
if (oldNotesState is StringFeedState.Loaded) {
|
||||
// Using size as a proxy for has changed.
|
||||
if (!equalImmutableLists(notes, oldNotesState.feed.value)) {
|
||||
val notes = dataSource.loadTop().toImmutableList()
|
||||
|
||||
val oldNotesState = _feedContent.value
|
||||
if (oldNotesState is StringFeedState.Loaded) {
|
||||
// Using size as a proxy for has changed.
|
||||
if (!equalImmutableLists(notes, oldNotesState.feed.value)) {
|
||||
updateFeed(notes)
|
||||
}
|
||||
} else {
|
||||
updateFeed(notes)
|
||||
}
|
||||
} else {
|
||||
updateFeed(notes)
|
||||
} finally {
|
||||
isRefreshing.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user