forked from GitHub-Mirror/riotX-android
Merge branch 'feature/Perf' into develop
This commit is contained in:
@ -33,6 +33,7 @@ import im.vector.riotx.features.home.AvatarRenderer
|
||||
import im.vector.riotx.features.home.HomeNavigator
|
||||
import im.vector.riotx.features.home.HomeRoomListObservableStore
|
||||
import im.vector.riotx.features.home.group.SelectedGroupStore
|
||||
import im.vector.riotx.features.html.EventHtmlRenderer
|
||||
import im.vector.riotx.features.navigation.Navigator
|
||||
import im.vector.riotx.features.notifications.NotifiableEventResolver
|
||||
import im.vector.riotx.features.notifications.NotificationBroadcastReceiver
|
||||
@ -68,6 +69,8 @@ interface VectorComponent {
|
||||
|
||||
fun emojiCompatFontProvider(): EmojiCompatFontProvider
|
||||
|
||||
fun eventHtmlRenderer(): EventHtmlRenderer
|
||||
|
||||
fun navigator(): Navigator
|
||||
|
||||
fun homeNavigator(): HomeNavigator
|
||||
|
@ -73,7 +73,7 @@ class HomeActivityViewModel @AssistedInject constructor(@Assisted initialState:
|
||||
private fun observeRoomAndGroup() {
|
||||
Observable
|
||||
.combineLatest<List<RoomSummary>, Option<GroupSummary>, List<RoomSummary>>(
|
||||
session.rx().liveRoomSummaries().throttleLast(300, TimeUnit.MILLISECONDS),
|
||||
session.rx().liveRoomSummaries(fetchLastEvents = true).throttleLast(300, TimeUnit.MILLISECONDS),
|
||||
selectedGroupStore.observe(),
|
||||
BiFunction { rooms, selectedGroupOption ->
|
||||
val selectedGroup = selectedGroupOption.orNull()
|
||||
|
@ -498,7 +498,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
|
||||
}
|
||||
|
||||
private fun observeRoomSummary() {
|
||||
room.rx().liveRoomSummary()
|
||||
room.rx().liveRoomSummary(false)
|
||||
.execute { async ->
|
||||
copy(
|
||||
asyncRoomSummary = async,
|
||||
|
@ -18,6 +18,7 @@ package im.vector.riotx.features.home.room.detail.timeline.action
|
||||
import com.airbnb.mvrx.*
|
||||
import com.squareup.inject.assisted.Assisted
|
||||
import com.squareup.inject.assisted.AssistedInject
|
||||
import dagger.Lazy
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
@ -84,7 +85,7 @@ data class MessageActionState(
|
||||
*/
|
||||
class MessageActionsViewModel @AssistedInject constructor(@Assisted
|
||||
initialState: MessageActionState,
|
||||
private val eventHtmlRenderer: EventHtmlRenderer,
|
||||
private val eventHtmlRenderer: Lazy<EventHtmlRenderer>,
|
||||
session: Session,
|
||||
private val noticeEventFormatter: NoticeEventFormatter
|
||||
) : VectorViewModel<MessageActionState>(initialState) {
|
||||
@ -121,7 +122,7 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted
|
||||
}
|
||||
|
||||
fun resolveBody(state: MessageActionState): CharSequence? {
|
||||
return state.messageBody(eventHtmlRenderer, noticeEventFormatter)
|
||||
return state.messageBody(eventHtmlRenderer.get(), noticeEventFormatter)
|
||||
}
|
||||
|
||||
}
|
@ -23,12 +23,20 @@ import android.text.style.ClickableSpan
|
||||
import android.text.style.ForegroundColorSpan
|
||||
import android.text.style.RelativeSizeSpan
|
||||
import android.view.View
|
||||
import dagger.Lazy
|
||||
import im.vector.matrix.android.api.permalinks.MatrixLinkify
|
||||
import im.vector.matrix.android.api.permalinks.MatrixPermalinkSpan
|
||||
import im.vector.matrix.android.api.session.events.model.RelationType
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.model.EditAggregatedSummary
|
||||
import im.vector.matrix.android.api.session.room.model.message.*
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageAudioContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageEmoteContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageFileContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageImageContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageNoticeContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageTextContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageVideoContent
|
||||
import im.vector.matrix.android.api.session.room.send.SendState
|
||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||
import im.vector.matrix.android.internal.crypto.attachments.toElementToDecrypt
|
||||
@ -55,7 +63,7 @@ class MessageItemFactory @Inject constructor(
|
||||
private val avatarRenderer: AvatarRenderer,
|
||||
private val colorProvider: ColorProvider,
|
||||
private val timelineMediaSizeProvider: TimelineMediaSizeProvider,
|
||||
private val htmlRenderer: EventHtmlRenderer,
|
||||
private val htmlRenderer: Lazy<EventHtmlRenderer>,
|
||||
private val stringProvider: StringProvider,
|
||||
private val emojiCompatFontProvider: EmojiCompatFontProvider,
|
||||
private val imageContentRenderer: ImageContentRenderer,
|
||||
@ -79,9 +87,9 @@ class MessageItemFactory @Inject constructor(
|
||||
|
||||
val messageContent: MessageContent =
|
||||
event.annotations?.editSummary?.aggregatedContent?.toModel()
|
||||
?: event.root.getClearContent().toModel()
|
||||
?: //Malformed content, we should echo something on screen
|
||||
return DefaultItem_().text(stringProvider.getString(R.string.malformed_message))
|
||||
?: event.root.getClearContent().toModel()
|
||||
?: //Malformed content, we should echo something on screen
|
||||
return DefaultItem_().text(stringProvider.getString(R.string.malformed_message))
|
||||
|
||||
if (messageContent.relatesTo?.type == RelationType.REPLACE) {
|
||||
// ignore replace event, the targeted id is already edited
|
||||
@ -91,16 +99,16 @@ class MessageItemFactory @Inject constructor(
|
||||
// val ev = all.toModel<Event>()
|
||||
return when (messageContent) {
|
||||
is MessageEmoteContent -> buildEmoteMessageItem(messageContent,
|
||||
informationData,
|
||||
event.annotations?.editSummary,
|
||||
highlight,
|
||||
callback)
|
||||
informationData,
|
||||
event.annotations?.editSummary,
|
||||
highlight,
|
||||
callback)
|
||||
is MessageTextContent -> buildTextMessageItem(event.sendState,
|
||||
messageContent,
|
||||
informationData,
|
||||
event.annotations?.editSummary,
|
||||
highlight,
|
||||
callback
|
||||
messageContent,
|
||||
informationData,
|
||||
event.annotations?.editSummary,
|
||||
highlight,
|
||||
callback
|
||||
)
|
||||
is MessageImageContent -> buildImageMessageItem(messageContent, informationData, highlight, callback)
|
||||
is MessageNoticeContent -> buildNoticeMessageItem(messageContent, informationData, highlight, callback)
|
||||
@ -134,7 +142,7 @@ class MessageItemFactory @Inject constructor(
|
||||
}))
|
||||
.longClickListener { view ->
|
||||
return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
|
||||
?: false
|
||||
?: false
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,7 +165,7 @@ class MessageItemFactory @Inject constructor(
|
||||
}))
|
||||
.longClickListener { view ->
|
||||
return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
|
||||
?: false
|
||||
?: false
|
||||
}
|
||||
.clickListener(
|
||||
DebouncedClickListener(View.OnClickListener { _ ->
|
||||
@ -210,7 +218,7 @@ class MessageItemFactory @Inject constructor(
|
||||
}))
|
||||
.longClickListener { view ->
|
||||
return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
|
||||
?: false
|
||||
?: false
|
||||
}
|
||||
}
|
||||
|
||||
@ -254,7 +262,7 @@ class MessageItemFactory @Inject constructor(
|
||||
.clickListener { view -> callback?.onVideoMessageClicked(messageContent, videoData, view) }
|
||||
.longClickListener { view ->
|
||||
return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
|
||||
?: false
|
||||
?: false
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,7 +274,7 @@ class MessageItemFactory @Inject constructor(
|
||||
callback: TimelineEventController.Callback?): MessageTextItem? {
|
||||
|
||||
val bodyToUse = messageContent.formattedBody?.let {
|
||||
htmlRenderer.render(it.trim())
|
||||
htmlRenderer.get().render(it.trim())
|
||||
} ?: messageContent.body
|
||||
|
||||
val linkifiedBody = linkifyBody(bodyToUse, callback)
|
||||
@ -294,7 +302,7 @@ class MessageItemFactory @Inject constructor(
|
||||
}))
|
||||
.longClickListener { view ->
|
||||
return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
|
||||
?: false
|
||||
?: false
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,9 +334,9 @@ class MessageItemFactory @Inject constructor(
|
||||
//nop
|
||||
}
|
||||
},
|
||||
editStart,
|
||||
editEnd,
|
||||
Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
|
||||
editStart,
|
||||
editEnd,
|
||||
Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
|
||||
return spannable
|
||||
}
|
||||
|
||||
@ -364,7 +372,7 @@ class MessageItemFactory @Inject constructor(
|
||||
}))
|
||||
.longClickListener { view ->
|
||||
return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
|
||||
?: false
|
||||
?: false
|
||||
}
|
||||
}
|
||||
|
||||
@ -400,7 +408,7 @@ class MessageItemFactory @Inject constructor(
|
||||
}))
|
||||
.longClickListener { view ->
|
||||
return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
|
||||
?: false
|
||||
?: false
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,10 +18,9 @@ package im.vector.riotx.features.html
|
||||
|
||||
import android.content.Context
|
||||
import android.text.style.URLSpan
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import im.vector.matrix.android.api.permalinks.PermalinkData
|
||||
import im.vector.matrix.android.api.permalinks.PermalinkParser
|
||||
import im.vector.matrix.android.api.session.Session
|
||||
import im.vector.riotx.core.di.ActiveSessionHolder
|
||||
import im.vector.riotx.core.glide.GlideApp
|
||||
import im.vector.riotx.core.glide.GlideRequests
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
@ -37,12 +36,14 @@ import ru.noties.markwon.html.TagHandler
|
||||
import ru.noties.markwon.html.tag.*
|
||||
import java.util.Arrays.asList
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
class EventHtmlRenderer @Inject constructor(context: AppCompatActivity,
|
||||
@Singleton
|
||||
class EventHtmlRenderer @Inject constructor(context: Context,
|
||||
val avatarRenderer: AvatarRenderer,
|
||||
session: Session) {
|
||||
sessionHolder: ActiveSessionHolder) {
|
||||
private val markwon = Markwon.builder(context)
|
||||
.usePlugin(MatrixPlugin.create(GlideApp.with(context), context, avatarRenderer, session))
|
||||
.usePlugin(MatrixPlugin.create(GlideApp.with(context), context, avatarRenderer, sessionHolder))
|
||||
.build()
|
||||
|
||||
fun render(text: String): CharSequence {
|
||||
@ -54,7 +55,7 @@ class EventHtmlRenderer @Inject constructor(context: AppCompatActivity,
|
||||
private class MatrixPlugin private constructor(private val glideRequests: GlideRequests,
|
||||
private val context: Context,
|
||||
private val avatarRenderer: AvatarRenderer,
|
||||
private val session: Session) : AbstractMarkwonPlugin() {
|
||||
private val session: ActiveSessionHolder) : AbstractMarkwonPlugin() {
|
||||
|
||||
override fun configureConfiguration(builder: MarkwonConfiguration.Builder) {
|
||||
builder.htmlParser(MarkwonHtmlParserImpl.create())
|
||||
@ -99,7 +100,7 @@ private class MatrixPlugin private constructor(private val glideRequests: GlideR
|
||||
asList<String>("h1", "h2", "h3", "h4", "h5", "h6"),
|
||||
HeadingHandler())
|
||||
.setHandler("mx-reply",
|
||||
MxReplyTagHandler())
|
||||
MxReplyTagHandler())
|
||||
|
||||
}
|
||||
|
||||
@ -122,7 +123,7 @@ private class MatrixPlugin private constructor(private val glideRequests: GlideR
|
||||
|
||||
companion object {
|
||||
|
||||
fun create(glideRequests: GlideRequests, context: Context, avatarRenderer: AvatarRenderer, session: Session): MatrixPlugin {
|
||||
fun create(glideRequests: GlideRequests, context: Context, avatarRenderer: AvatarRenderer, session: ActiveSessionHolder): MatrixPlugin {
|
||||
return MatrixPlugin(glideRequests, context, avatarRenderer, session)
|
||||
}
|
||||
}
|
||||
@ -131,7 +132,7 @@ private class MatrixPlugin private constructor(private val glideRequests: GlideR
|
||||
private class MxLinkHandler(private val glideRequests: GlideRequests,
|
||||
private val context: Context,
|
||||
private val avatarRenderer: AvatarRenderer,
|
||||
private val session: Session) : TagHandler() {
|
||||
private val sessionHolder: ActiveSessionHolder) : TagHandler() {
|
||||
|
||||
private val linkHandler = LinkHandler()
|
||||
|
||||
@ -141,7 +142,7 @@ private class MxLinkHandler(private val glideRequests: GlideRequests,
|
||||
val permalinkData = PermalinkParser.parse(link)
|
||||
when (permalinkData) {
|
||||
is PermalinkData.UserLink -> {
|
||||
val user = session.getUser(permalinkData.userId)
|
||||
val user = sessionHolder.getSafeActiveSession()?.getUser(permalinkData.userId)
|
||||
val span = PillImageSpan(glideRequests, avatarRenderer, context, permalinkData.userId, user)
|
||||
SpannableBuilder.setSpans(
|
||||
visitor.builder(),
|
||||
|
@ -117,7 +117,7 @@ class NotifiableEventResolver @Inject constructor(private val stringProvider: St
|
||||
val body = event.annotations?.editSummary?.aggregatedContent?.toModel<MessageContent>()?.body
|
||||
?: event.root.getClearContent().toModel<MessageContent>()?.body
|
||||
?: stringProvider.getString(R.string.notification_unknown_new_event)
|
||||
val roomName = room.roomSummary?.displayName ?: ""
|
||||
val roomName = room.roomSummary()?.displayName ?: ""
|
||||
val senderDisplayName = event.senderName ?: event.root.senderId
|
||||
|
||||
val notifiableEvent = NotifiableMessageEvent(
|
||||
@ -129,7 +129,7 @@ class NotifiableEventResolver @Inject constructor(private val stringProvider: St
|
||||
body = body,
|
||||
roomId = event.root.roomId!!,
|
||||
roomName = roomName,
|
||||
roomIsDirect = room.roomSummary?.isDirect ?: false)
|
||||
roomIsDirect = room.roomSummary()?.isDirect ?: false)
|
||||
|
||||
notifiableEvent.matrixID = session.sessionParams.credentials.userId
|
||||
notifiableEvent.soundName = null
|
||||
@ -137,7 +137,7 @@ class NotifiableEventResolver @Inject constructor(private val stringProvider: St
|
||||
// Get the avatars URL
|
||||
// TODO They will be not displayed the first time (known limitation)
|
||||
notifiableEvent.roomAvatarPath = session.contentUrlResolver()
|
||||
.resolveThumbnail(room.roomSummary?.avatarUrl,
|
||||
.resolveThumbnail(room.roomSummary()?.avatarUrl,
|
||||
250,
|
||||
250,
|
||||
ContentUrlResolver.ThumbnailMethod.SCALE)
|
||||
|
@ -100,8 +100,8 @@ class NotificationBroadcastReceiver : BroadcastReceiver() {
|
||||
session.sessionParams.credentials.userId,
|
||||
message,
|
||||
room.roomId,
|
||||
room.roomSummary?.displayName ?: room.roomId,
|
||||
room.roomSummary?.isDirect == true
|
||||
room.roomSummary()?.displayName ?: room.roomId,
|
||||
room.roomSummary()?.isDirect == true
|
||||
)
|
||||
notifiableMessageEvent.outGoingMessage = true
|
||||
|
||||
|
@ -86,7 +86,7 @@ class RoomDirectoryViewModel @AssistedInject constructor(@Assisted initialState:
|
||||
private fun observeJoinedRooms() {
|
||||
session
|
||||
.rx()
|
||||
.liveRoomSummaries()
|
||||
.liveRoomSummaries(fetchLastEvents = false)
|
||||
.subscribe { list ->
|
||||
val joinedRoomIds = list
|
||||
// Keep only joined room
|
||||
|
@ -54,7 +54,7 @@ class RoomPreviewViewModel @AssistedInject constructor(@Assisted initialState: R
|
||||
private fun observeJoinedRooms() {
|
||||
session
|
||||
.rx()
|
||||
.liveRoomSummaries()
|
||||
.liveRoomSummaries(fetchLastEvents = false)
|
||||
.subscribe { list ->
|
||||
withState { state ->
|
||||
val isRoomJoined = list
|
||||
|
@ -23,6 +23,7 @@ import android.preference.PreferenceManager
|
||||
import android.text.TextUtils
|
||||
import android.util.Pair
|
||||
import androidx.core.content.edit
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import im.vector.riotx.R
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
@ -75,7 +76,7 @@ object VectorLocale {
|
||||
}
|
||||
|
||||
// init the known locales in background, using kotlin coroutines
|
||||
GlobalScope.launch {
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
initApplicationLocales(context)
|
||||
}
|
||||
}
|
||||
|
@ -86,9 +86,7 @@ class VectorSettingsActivity : VectorBaseActivity(),
|
||||
try {
|
||||
pref?.fragment?.let {
|
||||
oFragment = supportFragmentManager.fragmentFactory
|
||||
.instantiate(
|
||||
classLoader,
|
||||
it, pref.extras)
|
||||
.instantiate(classLoader, it)
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
showSnackbar(getString(R.string.not_implemented))
|
||||
|
Reference in New Issue
Block a user