diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrGlobalDataSource.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrGlobalDataSource.kt index 32cfd52ec..d5ef100f2 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/NostrGlobalDataSource.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/NostrGlobalDataSource.kt @@ -8,7 +8,7 @@ import nostr.postr.events.TextNoteEvent object NostrGlobalDataSource: NostrDataSource("GlobalFeed") { fun createGlobalFilter() = JsonFilter( kinds = listOf(TextNoteEvent.kind), - limit = 200 + limit = 50 ) val globalFeedChannel = requestNewChannel() diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Relay.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Relay.kt index 960d3f3e5..93684bd58 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Relay.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/relays/Relay.kt @@ -1,7 +1,6 @@ package com.vitorpamplona.amethyst.service.relays import com.google.gson.JsonElement -import java.util.Collections import nostr.postr.events.Event import okhttp3.OkHttpClient import okhttp3.Request diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedViewModel.kt index 75a8fbb8e..f8ec098a8 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/CardFeedViewModel.kt @@ -1,5 +1,7 @@ package com.vitorpamplona.amethyst.ui.screen +import android.os.Handler +import android.os.Looper import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.vitorpamplona.amethyst.model.LocalCache @@ -89,8 +91,21 @@ class CardFeedViewModel(val dataSource: NostrDataSource): ViewModel() { } } + val filterHandler = Handler(Looper.getMainLooper()) + var handlerWaiting = false + @Synchronized + fun invalidateData() { + if (handlerWaiting) return + + handlerWaiting = true + filterHandler.postDelayed({ + refresh() + handlerWaiting = false + }, 100) + } + private val cacheListener: (LocalCacheState) -> Unit = { - refresh() + invalidateData() } init { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedViewModel.kt index 53cb3aa44..73e63ad0a 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/FeedViewModel.kt @@ -1,11 +1,15 @@ package com.vitorpamplona.amethyst.ui.screen +import android.os.Handler +import android.os.Looper import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.LocalCacheState import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.service.NostrDataSource +import kotlin.time.ExperimentalTime +import kotlin.time.measureTimedValue import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job @@ -20,16 +24,23 @@ class FeedViewModel(val dataSource: NostrDataSource): ViewModel() { private val _feedContent = MutableStateFlow(FeedState.Loading) val feedContent = _feedContent.asStateFlow() + @OptIn(ExperimentalTime::class) fun refresh() { - val notes = dataSource.loadTop() + val scope = CoroutineScope(Job() + Dispatchers.Main) + scope.launch { + println("AAA" + measureTimedValue { + val notes = dataSource.loadTop() + + val oldNotesState = feedContent.value + if (oldNotesState is FeedState.Loaded) { + if (notes != oldNotesState.feed) { + updateFeed(notes) + } + } else { + updateFeed(notes) + } + }.duration) - val oldNotesState = feedContent.value - if (oldNotesState is FeedState.Loaded) { - if (notes != oldNotesState.feed) { - updateFeed(notes) - } - } else { - updateFeed(notes) } } @@ -48,8 +59,21 @@ class FeedViewModel(val dataSource: NostrDataSource): ViewModel() { } } + val filterHandler = Handler(Looper.getMainLooper()) + var handlerWaiting = false + @Synchronized + fun invalidateData() { + if (handlerWaiting) return + + handlerWaiting = true + filterHandler.postDelayed({ + refresh() + handlerWaiting = false + }, 100) + } + private val cacheListener: (LocalCacheState) -> Unit = { - refresh() + invalidateData() } init { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/UserFeedViewModel.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/UserFeedViewModel.kt index 83bc35dc1..3a32ce02e 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/UserFeedViewModel.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/UserFeedViewModel.kt @@ -1,5 +1,7 @@ package com.vitorpamplona.amethyst.ui.screen +import android.os.Handler +import android.os.Looper import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.vitorpamplona.amethyst.model.LocalCache @@ -61,8 +63,21 @@ open class UserFeedViewModel(val dataSource: NostrDataSource): ViewModel() } } + val filterHandler = Handler(Looper.getMainLooper()) + var handlerWaiting = false + @Synchronized + fun invalidateData() { + if (handlerWaiting) return + + handlerWaiting = true + filterHandler.postDelayed({ + refresh() + handlerWaiting = false + }, 100) + } + private val cacheListener: (LocalCacheState) -> Unit = { - refresh() + invalidateData() } init { diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt index be049c353..969b4140f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChannelScreen.kt @@ -57,6 +57,10 @@ fun ChannelScreen(channelId: String?, accountViewModel: AccountViewModel, navCon val feedViewModel: FeedViewModel = viewModel { FeedViewModel( NostrChannelDataSource ) } + LaunchedEffect(Unit) { + feedViewModel.refresh() + } + Column(Modifier.fillMaxHeight()) { ChannelHeader( channel, diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomListScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomListScreen.kt index 744fa59ec..eb138951f 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomListScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomListScreen.kt @@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.ui.Modifier @@ -20,6 +21,10 @@ fun ChatroomListScreen(accountViewModel: AccountViewModel, navController: NavCon if (account != null) { val feedViewModel: FeedViewModel = viewModel { FeedViewModel( NostrChatroomListDataSource ) } + LaunchedEffect(Unit) { + feedViewModel.refresh() + } + Column(Modifier.fillMaxHeight()) { Column( modifier = Modifier.padding(vertical = 0.dp) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt index fae7afcb6..6a47ffd46 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/ChatroomScreen.kt @@ -17,6 +17,7 @@ import androidx.compose.material.OutlinedTextField import androidx.compose.material.Text import androidx.compose.material.TextField import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.mutableStateOf @@ -48,6 +49,10 @@ fun ChatroomScreen(userId: String?, accountViewModel: AccountViewModel, navContr val feedViewModel: FeedViewModel = viewModel { FeedViewModel( NostrChatRoomDataSource ) } + LaunchedEffect(Unit) { + feedViewModel.refresh() + } + Column(Modifier.fillMaxHeight()) { NostrChatRoomDataSource.withUser?.let { ChatroomHeader( diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt index 3478deafb..20cc29cf1 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/HomeScreen.kt @@ -4,6 +4,8 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.remember @@ -12,6 +14,9 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController import com.vitorpamplona.amethyst.service.NostrHomeDataSource +import com.vitorpamplona.amethyst.service.NostrUserProfileDataSource +import com.vitorpamplona.amethyst.service.NostrUserProfileFollowersDataSource +import com.vitorpamplona.amethyst.service.NostrUserProfileFollowsDataSource import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import java.lang.System.currentTimeMillis @@ -22,6 +27,10 @@ fun HomeScreen(accountViewModel: AccountViewModel, navController: NavController) if (accountState != null) { val feedViewModel: FeedViewModel = viewModel { FeedViewModel( NostrHomeDataSource ) } + LaunchedEffect(Unit) { + feedViewModel.refresh() + } + Column(Modifier.fillMaxHeight()) { Column( modifier = Modifier.padding(vertical = 0.dp) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NotificationScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NotificationScreen.kt index ae962e68c..e03cb9300 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NotificationScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/NotificationScreen.kt @@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.ui.Modifier @@ -21,6 +22,10 @@ fun NotificationScreen(accountViewModel: AccountViewModel, navController: NavCon val feedViewModel: CardFeedViewModel = viewModel { CardFeedViewModel( NostrNotificationDataSource ) } + LaunchedEffect(Unit) { + feedViewModel.refresh() + } + Column(Modifier.fillMaxHeight()) { Column( modifier = Modifier.padding(vertical = 0.dp) diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt index d234db914..1f1f91708 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/SearchScreen.kt @@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel @@ -15,6 +16,10 @@ import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel fun SearchScreen(accountViewModel: AccountViewModel, navController: NavController) { val feedViewModel: FeedViewModel = viewModel { FeedViewModel( NostrGlobalDataSource ) } + LaunchedEffect(Unit) { + feedViewModel.refresh() + } + Column(Modifier.fillMaxHeight()) { Column( modifier = Modifier.padding(vertical = 0.dp)