kopia lustrzana https://github.com/vitorpamplona/amethyst
Merge pull request #75 from clackbib/habib/threading-perf-fixes
Scroll Perf Improvements.pull/87/head
commit
bb50099021
|
@ -11,6 +11,9 @@ import nostr.postr.events.Event
|
|||
* RelayPool manages the connection to multiple Relays and lets consumers deal with simple events.
|
||||
*/
|
||||
object RelayPool: Relay.Listener {
|
||||
|
||||
val scope = CoroutineScope(Job() + Dispatchers.IO)
|
||||
|
||||
private var relays = listOf<Relay>()
|
||||
private var listeners = setOf<Listener>()
|
||||
|
||||
|
@ -114,7 +117,6 @@ object RelayPool: Relay.Listener {
|
|||
val live: RelayPoolLiveData = RelayPoolLiveData(this)
|
||||
|
||||
private fun refreshObservers() {
|
||||
val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
scope.launch {
|
||||
live.refresh()
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class CardFeedViewModel(val dataSource: NostrDataSource<Note>): ViewModel() {
|
||||
private val _feedContent = MutableStateFlow<CardFeedState>(CardFeedState.Loading)
|
||||
|
@ -29,11 +30,8 @@ class CardFeedViewModel(val dataSource: NostrDataSource<Note>): ViewModel() {
|
|||
|
||||
private var lastNotes: List<Note>? = null
|
||||
|
||||
fun refresh() {
|
||||
val scope = CoroutineScope(Job() + Dispatchers.Default)
|
||||
scope.launch {
|
||||
refreshSuspended()
|
||||
}
|
||||
suspend fun refresh() = withContext(Dispatchers.IO) {
|
||||
refreshSuspended()
|
||||
}
|
||||
|
||||
private fun refreshSuspended() {
|
||||
|
@ -83,19 +81,16 @@ class CardFeedViewModel(val dataSource: NostrDataSource<Note>): ViewModel() {
|
|||
return (reactionCards + boostCards + textNoteCards).sortedBy { it.createdAt() }.reversed()
|
||||
}
|
||||
|
||||
fun updateFeed(notes: List<Card>) {
|
||||
val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
scope.launch {
|
||||
val currentState = feedContent.value
|
||||
private fun updateFeed(notes: List<Card>) {
|
||||
val currentState = feedContent.value
|
||||
|
||||
if (notes.isEmpty()) {
|
||||
_feedContent.update { CardFeedState.Empty }
|
||||
} else if (currentState is CardFeedState.Loaded) {
|
||||
// updates the current list
|
||||
currentState.feed.value = notes
|
||||
} else {
|
||||
_feedContent.update { CardFeedState.Loaded(mutableStateOf(notes)) }
|
||||
}
|
||||
if (notes.isEmpty()) {
|
||||
_feedContent.update { CardFeedState.Empty }
|
||||
} else if (currentState is CardFeedState.Loaded) {
|
||||
// updates the current list
|
||||
currentState.feed.value = notes
|
||||
} else {
|
||||
_feedContent.update { CardFeedState.Loaded(mutableStateOf(notes)) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import kotlinx.coroutines.flow.update
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import nostr.postr.events.TextNoteEvent
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
class NostrChannelFeedViewModel: FeedViewModel(NostrChannelDataSource)
|
||||
class NostrChatRoomFeedViewModel: FeedViewModel(NostrChatRoomDataSource)
|
||||
|
@ -82,25 +83,21 @@ abstract class FeedViewModel(val dataSource: NostrDataSource<Note>): ViewModel()
|
|||
}
|
||||
|
||||
fun refresh() {
|
||||
viewModelScope.launch(Dispatchers.Default) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val notes = newListFromDataSource()
|
||||
|
||||
val oldNotesState = feedContent.value
|
||||
if (oldNotesState is FeedState.Loaded) {
|
||||
if (notes != oldNotesState.feed) {
|
||||
withContext(Dispatchers.Main) {
|
||||
updateFeed(notes)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
withContext(Dispatchers.Main) {
|
||||
updateFeed(notes)
|
||||
}
|
||||
} else {
|
||||
updateFeed(notes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateFeed(notes: List<Note>) {
|
||||
private fun updateFeed(notes: List<Note>) {
|
||||
val currentState = feedContent.value
|
||||
|
||||
if (notes.isEmpty()) {
|
||||
|
@ -113,19 +110,18 @@ abstract class FeedViewModel(val dataSource: NostrDataSource<Note>): ViewModel()
|
|||
}
|
||||
}
|
||||
|
||||
var handlerWaiting = false
|
||||
fun invalidateData() {
|
||||
synchronized(handlerWaiting) {
|
||||
if (handlerWaiting) return
|
||||
private var handlerWaiting = AtomicBoolean()
|
||||
@Synchronized
|
||||
private fun invalidateData() {
|
||||
if (handlerWaiting.get()) return
|
||||
|
||||
handlerWaiting = true
|
||||
handlerWaiting.set(true)
|
||||
val scope = CoroutineScope(Job() + Dispatchers.Default)
|
||||
scope.launch {
|
||||
delay(100)
|
||||
refresh()
|
||||
handlerWaiting = false
|
||||
handlerWaiting.set(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val cacheListener: (LocalCacheState) -> Unit = {
|
||||
|
|
|
@ -22,6 +22,8 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
|||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
class NostrUserProfileFollowsUserFeedViewModel(): UserFeedViewModel(
|
||||
NostrUserProfileFollowsDataSource
|
||||
|
@ -39,13 +41,11 @@ open class UserFeedViewModel(val dataSource: NostrDataSource<User>): ViewModel()
|
|||
private val _feedContent = MutableStateFlow<UserFeedState>(UserFeedState.Loading)
|
||||
val feedContent = _feedContent.asStateFlow()
|
||||
|
||||
fun refresh() {
|
||||
val scope = CoroutineScope(Job() + Dispatchers.Default)
|
||||
scope.launch {
|
||||
refreshSuspended()
|
||||
}
|
||||
suspend fun refresh() = withContext(Dispatchers.IO) {
|
||||
refreshSuspended()
|
||||
}
|
||||
|
||||
|
||||
private fun refreshSuspended() {
|
||||
val notes = dataSource.loadTop()
|
||||
|
||||
|
@ -59,34 +59,30 @@ open class UserFeedViewModel(val dataSource: NostrDataSource<User>): ViewModel()
|
|||
}
|
||||
}
|
||||
|
||||
fun updateFeed(notes: List<User>) {
|
||||
val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||
scope.launch {
|
||||
val currentState = feedContent.value
|
||||
|
||||
if (notes.isEmpty()) {
|
||||
_feedContent.update { UserFeedState.Empty }
|
||||
} else if (currentState is UserFeedState.Loaded) {
|
||||
// updates the current list
|
||||
currentState.feed.value = notes
|
||||
} else {
|
||||
_feedContent.update { UserFeedState.Loaded(mutableStateOf(notes)) }
|
||||
}
|
||||
private fun updateFeed(notes: List<User>) {
|
||||
val currentState = feedContent.value
|
||||
if (notes.isEmpty()) {
|
||||
_feedContent.update { UserFeedState.Empty }
|
||||
} else if (currentState is UserFeedState.Loaded) {
|
||||
// updates the current list
|
||||
currentState.feed.value = notes
|
||||
} else {
|
||||
_feedContent.update { UserFeedState.Loaded(mutableStateOf(notes)) }
|
||||
}
|
||||
}
|
||||
|
||||
var handlerWaiting = false
|
||||
fun invalidateData() {
|
||||
synchronized(handlerWaiting) {
|
||||
if (handlerWaiting) return
|
||||
var handlerWaiting = AtomicBoolean()
|
||||
|
||||
handlerWaiting = true
|
||||
val scope = CoroutineScope(Job() + Dispatchers.Default)
|
||||
scope.launch {
|
||||
delay(100)
|
||||
refresh()
|
||||
handlerWaiting = false
|
||||
}
|
||||
@Synchronized
|
||||
private fun invalidateData() {
|
||||
if (handlerWaiting.get()) return
|
||||
|
||||
handlerWaiting.set(true)
|
||||
val scope = CoroutineScope(Job() + Dispatchers.Default)
|
||||
scope.launch {
|
||||
delay(100)
|
||||
refresh()
|
||||
handlerWaiting.set(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue