mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2025-09-27 23:16:24 +02:00
Additional Performance Improvements
This commit is contained in:
@@ -297,8 +297,6 @@ object LocalCache {
|
|||||||
it.addReply(note)
|
it.addReply(note)
|
||||||
}
|
}
|
||||||
|
|
||||||
UrlCachedPreviewer.preloadPreviewsFor(note)
|
|
||||||
|
|
||||||
refreshObservers()
|
refreshObservers()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,6 +8,10 @@ import com.vitorpamplona.amethyst.ui.components.isValidURL
|
|||||||
import com.vitorpamplona.amethyst.ui.components.noProtocolUrlValidator
|
import com.vitorpamplona.amethyst.ui.components.noProtocolUrlValidator
|
||||||
import com.vitorpamplona.amethyst.ui.components.videoExtension
|
import com.vitorpamplona.amethyst.ui.components.videoExtension
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
object UrlCachedPreviewer {
|
object UrlCachedPreviewer {
|
||||||
val cache = ConcurrentHashMap<String, UrlInfoItem>()
|
val cache = ConcurrentHashMap<String, UrlInfoItem>()
|
||||||
@@ -18,16 +22,19 @@ object UrlCachedPreviewer {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
BahaUrlPreview(url, object : IUrlPreviewCallback {
|
val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||||
override fun onComplete(urlInfo: UrlInfoItem) {
|
scope.launch {
|
||||||
cache.put(url, urlInfo)
|
BahaUrlPreview(url, object : IUrlPreviewCallback {
|
||||||
callback?.onComplete(urlInfo)
|
override fun onComplete(urlInfo: UrlInfoItem) {
|
||||||
}
|
cache.put(url, urlInfo)
|
||||||
|
callback?.onComplete(urlInfo)
|
||||||
|
}
|
||||||
|
|
||||||
override fun onFailed(throwable: Throwable) {
|
override fun onFailed(throwable: Throwable) {
|
||||||
callback?.onFailed(throwable)
|
callback?.onFailed(throwable)
|
||||||
}
|
}
|
||||||
}).fetchUrlPreview()
|
}).fetchUrlPreview()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun findUrlsInMessage(message: String): List<String> {
|
fun findUrlsInMessage(message: String): List<String> {
|
||||||
|
@@ -137,13 +137,14 @@ class UserMetadata {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class UserLiveData(val user: User): LiveData<UserState>(UserState(user)) {
|
class UserLiveData(val user: User): LiveData<UserState>(UserState(user)) {
|
||||||
|
val scope = CoroutineScope(Job() + Dispatchers.Main)
|
||||||
|
|
||||||
fun refresh() {
|
fun refresh() {
|
||||||
postValue(UserState(user))
|
postValue(UserState(user))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActive() {
|
override fun onActive() {
|
||||||
super.onActive()
|
super.onActive()
|
||||||
val scope = CoroutineScope(Job() + Dispatchers.Main)
|
|
||||||
scope.launch {
|
scope.launch {
|
||||||
NostrSingleUserDataSource.add(user.pubkeyHex)
|
NostrSingleUserDataSource.add(user.pubkeyHex)
|
||||||
}
|
}
|
||||||
@@ -151,7 +152,6 @@ class UserLiveData(val user: User): LiveData<UserState>(UserState(user)) {
|
|||||||
|
|
||||||
override fun onInactive() {
|
override fun onInactive() {
|
||||||
super.onInactive()
|
super.onInactive()
|
||||||
val scope = CoroutineScope(Job() + Dispatchers.Main)
|
|
||||||
scope.launch {
|
scope.launch {
|
||||||
NostrSingleUserDataSource.remove(user.pubkeyHex)
|
NostrSingleUserDataSource.remove(user.pubkeyHex)
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,7 @@
|
|||||||
package com.vitorpamplona.amethyst.service
|
package com.vitorpamplona.amethyst.service
|
||||||
|
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
import com.vitorpamplona.amethyst.model.LocalCache
|
import com.vitorpamplona.amethyst.model.LocalCache
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.model.UrlCachedPreviewer
|
import com.vitorpamplona.amethyst.model.UrlCachedPreviewer
|
||||||
@@ -125,7 +127,7 @@ abstract class NostrDataSource<T>(val debugName: String) {
|
|||||||
return returningList
|
return returningList
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun loadPreviews(list: List<T>) {
|
fun loadPreviews(list: List<T>) {
|
||||||
list.forEach {
|
list.forEach {
|
||||||
if (it is Note) {
|
if (it is Note) {
|
||||||
UrlCachedPreviewer.preloadPreviewsFor(it)
|
UrlCachedPreviewer.preloadPreviewsFor(it)
|
||||||
@@ -146,6 +148,19 @@ abstract class NostrDataSource<T>(val debugName: String) {
|
|||||||
channelIds.remove(channel.id)
|
channelIds.remove(channel.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val filterHandler = Handler(Looper.getMainLooper())
|
||||||
|
var handlerWaiting = false
|
||||||
|
@Synchronized
|
||||||
|
fun invalidateFilters() {
|
||||||
|
if (handlerWaiting) return
|
||||||
|
|
||||||
|
handlerWaiting = true
|
||||||
|
filterHandler.postDelayed({
|
||||||
|
resetFilters()
|
||||||
|
handlerWaiting = false
|
||||||
|
}, 200)
|
||||||
|
}
|
||||||
|
|
||||||
fun resetFilters() {
|
fun resetFilters() {
|
||||||
// saves the channels that are currently active
|
// saves the channels that are currently active
|
||||||
val activeChannels = channels.filter { it.filter != null }
|
val activeChannels = channels.filter { it.filter != null }
|
||||||
|
@@ -70,11 +70,11 @@ object NostrSingleEventDataSource: NostrDataSource<Note>("SingleEventFeed") {
|
|||||||
|
|
||||||
fun add(eventId: String) {
|
fun add(eventId: String) {
|
||||||
eventsToWatch = eventsToWatch.plus(eventId)
|
eventsToWatch = eventsToWatch.plus(eventId)
|
||||||
resetFilters()
|
invalidateFilters()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun remove(eventId: String) {
|
fun remove(eventId: String) {
|
||||||
eventsToWatch = eventsToWatch.minus(eventId)
|
eventsToWatch = eventsToWatch.minus(eventId)
|
||||||
resetFilters()
|
invalidateFilters()
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -35,11 +35,11 @@ object NostrSingleUserDataSource: NostrDataSource<Note>("SingleUserFeed") {
|
|||||||
|
|
||||||
fun add(userId: String) {
|
fun add(userId: String) {
|
||||||
usersToWatch = usersToWatch.plus(userId)
|
usersToWatch = usersToWatch.plus(userId)
|
||||||
resetFilters()
|
invalidateFilters()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun remove(userId: String) {
|
fun remove(userId: String) {
|
||||||
usersToWatch = usersToWatch.minus(userId)
|
usersToWatch = usersToWatch.minus(userId)
|
||||||
resetFilters()
|
invalidateFilters()
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -16,6 +16,7 @@ import coil.decode.ImageDecoderDecoder
|
|||||||
import coil.decode.SvgDecoder
|
import coil.decode.SvgDecoder
|
||||||
import com.vitorpamplona.amethyst.KeyStorage
|
import com.vitorpamplona.amethyst.KeyStorage
|
||||||
import com.vitorpamplona.amethyst.service.NostrAccountDataSource
|
import com.vitorpamplona.amethyst.service.NostrAccountDataSource
|
||||||
|
import com.vitorpamplona.amethyst.service.NostrChannelDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrChatroomListDataSource
|
import com.vitorpamplona.amethyst.service.NostrChatroomListDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrGlobalDataSource
|
import com.vitorpamplona.amethyst.service.NostrGlobalDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrHomeDataSource
|
import com.vitorpamplona.amethyst.service.NostrHomeDataSource
|
||||||
@@ -71,6 +72,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
NostrAccountDataSource.stop()
|
NostrAccountDataSource.stop()
|
||||||
NostrHomeDataSource.stop()
|
NostrHomeDataSource.stop()
|
||||||
|
NostrChannelDataSource.stop()
|
||||||
NostrChatroomListDataSource.stop()
|
NostrChatroomListDataSource.stop()
|
||||||
NostrUserProfileDataSource.stop()
|
NostrUserProfileDataSource.stop()
|
||||||
NostrUserProfileFollowersDataSource.stop()
|
NostrUserProfileFollowersDataSource.stop()
|
||||||
|
@@ -6,6 +6,7 @@ import com.vitorpamplona.amethyst.model.Account
|
|||||||
import com.vitorpamplona.amethyst.model.DefaultChannels
|
import com.vitorpamplona.amethyst.model.DefaultChannels
|
||||||
import com.vitorpamplona.amethyst.model.toByteArray
|
import com.vitorpamplona.amethyst.model.toByteArray
|
||||||
import com.vitorpamplona.amethyst.service.NostrAccountDataSource
|
import com.vitorpamplona.amethyst.service.NostrAccountDataSource
|
||||||
|
import com.vitorpamplona.amethyst.service.NostrChannelDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrChatroomListDataSource
|
import com.vitorpamplona.amethyst.service.NostrChatroomListDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrGlobalDataSource
|
import com.vitorpamplona.amethyst.service.NostrGlobalDataSource
|
||||||
import com.vitorpamplona.amethyst.service.NostrHomeDataSource
|
import com.vitorpamplona.amethyst.service.NostrHomeDataSource
|
||||||
@@ -70,6 +71,7 @@ class AccountStateViewModel(private val encryptedPreferences: EncryptedSharedPre
|
|||||||
NostrNotificationDataSource.account = account
|
NostrNotificationDataSource.account = account
|
||||||
NostrChatroomListDataSource.account = account
|
NostrChatroomListDataSource.account = account
|
||||||
|
|
||||||
|
NostrChannelDataSource.start()
|
||||||
NostrAccountDataSource.start()
|
NostrAccountDataSource.start()
|
||||||
NostrGlobalDataSource.start()
|
NostrGlobalDataSource.start()
|
||||||
NostrHomeDataSource.start()
|
NostrHomeDataSource.start()
|
||||||
|
@@ -6,6 +6,9 @@ import com.vitorpamplona.amethyst.model.LocalCache
|
|||||||
import com.vitorpamplona.amethyst.model.LocalCacheState
|
import com.vitorpamplona.amethyst.model.LocalCacheState
|
||||||
import com.vitorpamplona.amethyst.model.Note
|
import com.vitorpamplona.amethyst.model.Note
|
||||||
import com.vitorpamplona.amethyst.service.NostrDataSource
|
import com.vitorpamplona.amethyst.service.NostrDataSource
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
import kotlinx.coroutines.cancel
|
import kotlinx.coroutines.cancel
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
@@ -18,13 +21,6 @@ class FeedViewModel(val dataSource: NostrDataSource<Note>): ViewModel() {
|
|||||||
val feedContent = _feedContent.asStateFlow()
|
val feedContent = _feedContent.asStateFlow()
|
||||||
|
|
||||||
fun refresh() {
|
fun refresh() {
|
||||||
// For some reason, view Model Scope doesn't call
|
|
||||||
viewModelScope.launch {
|
|
||||||
refreshSuspend()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun refreshSuspend() {
|
|
||||||
val notes = dataSource.loadTop()
|
val notes = dataSource.loadTop()
|
||||||
|
|
||||||
val oldNotesState = feedContent.value
|
val oldNotesState = feedContent.value
|
||||||
|
@@ -17,6 +17,7 @@ import androidx.compose.material.OutlinedTextField
|
|||||||
import androidx.compose.material.Text
|
import androidx.compose.material.Text
|
||||||
import androidx.compose.material.TextField
|
import androidx.compose.material.TextField
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
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.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
Reference in New Issue
Block a user