From 19202cfca6874856b8191864a878861ca75fb978 Mon Sep 17 00:00:00 2001
From: ganfra <francoisg@matrix.org>
Date: Mon, 1 Jul 2019 20:05:48 +0200
Subject: [PATCH] Perf: try to get better

---
 .../android/internal/crypto/CryptoManager.kt  |  5 +-
 .../DefaultSasVerificationService.kt          |  7 +-
 .../notification/DefaultPushRuleService.kt    | 53 +-------------
 .../session/pushers/DefaultPusherService.kt   | 16 -----
 .../session/pushers/GetPushRulesTask.kt       | 70 ++++++++++++++++--
 .../session/pushers/GetPushersTask.kt         | 30 ++++++--
 .../action/MessageActionsViewModel.kt         |  5 +-
 .../timeline/factory/MessageItemFactory.kt    | 71 ++++++++++++-------
 .../features/settings/VectorLocale.kt         |  3 +-
 9 files changed, 150 insertions(+), 110 deletions(-)

diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt
index 01506b719b..8f34a0809c 100755
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/CryptoManager.kt
@@ -25,6 +25,7 @@ import android.text.TextUtils
 import arrow.core.Try
 import com.squareup.moshi.Types
 import com.zhuinden.monarchy.Monarchy
+import dagger.Lazy
 import im.vector.matrix.android.api.MatrixCallback
 import im.vector.matrix.android.api.auth.data.Credentials
 import im.vector.matrix.android.api.failure.Failure
@@ -98,7 +99,7 @@ internal class CryptoManager @Inject constructor(
         private val olmManager: OlmManager,
         // The credentials,
         private val credentials: Credentials,
-        private val myDeviceInfoHolder: MyDeviceInfoHolder,
+        private val myDeviceInfoHolder: Lazy<MyDeviceInfoHolder>,
         // the crypto store
         private val cryptoStore: IMXCryptoStore,
         // Olm device
@@ -190,7 +191,7 @@ internal class CryptoManager @Inject constructor(
     }
 
     override fun getMyDevice(): MXDeviceInfo {
-        return myDeviceInfoHolder.myDevice
+        return myDeviceInfoHolder.get().myDevice
     }
 
     override fun getDevicesList(callback: MatrixCallback<DevicesListResponse>) {
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt
index ebf3294a09..fd4239b6f7 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/verification/DefaultSasVerificationService.kt
@@ -18,6 +18,7 @@ package im.vector.matrix.android.internal.crypto.verification
 
 import android.os.Handler
 import android.os.Looper
+import dagger.Lazy
 import im.vector.matrix.android.api.MatrixCallback
 import im.vector.matrix.android.api.auth.data.Credentials
 import im.vector.matrix.android.api.session.crypto.sas.CancelCode
@@ -55,7 +56,7 @@ import kotlin.collections.HashMap
 @SessionScope
 internal class DefaultSasVerificationService @Inject constructor(private val credentials: Credentials,
                                                                  private val cryptoStore: IMXCryptoStore,
-                                                                 private val myDeviceInfoHolder: MyDeviceInfoHolder,
+                                                                 private val myDeviceInfoHolder: Lazy<MyDeviceInfoHolder>,
                                                                  private val deviceListManager: DeviceListManager,
                                                                  private val setDeviceVerificationAction: SetDeviceVerificationAction,
                                                                  private val sendToDeviceTask: SendToDeviceTask,
@@ -197,7 +198,7 @@ internal class DefaultSasVerificationService @Inject constructor(private val cre
                                     cryptoStore,
                                     sendToDeviceTask,
                                     taskExecutor,
-                                    myDeviceInfoHolder.myDevice.fingerprint()!!,
+                                    myDeviceInfoHolder.get().myDevice.fingerprint()!!,
                                     startReq.transactionID!!,
                                     otherUserId)
                             addTransaction(tx)
@@ -366,7 +367,7 @@ internal class DefaultSasVerificationService @Inject constructor(private val cre
                     cryptoStore,
                     sendToDeviceTask,
                     taskExecutor,
-                    myDeviceInfoHolder.myDevice.fingerprint()!!,
+                    myDeviceInfoHolder.get().myDevice.fingerprint()!!,
                     txID,
                     userId,
                     deviceID)
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/notification/DefaultPushRuleService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/notification/DefaultPushRuleService.kt
index e8ef2f7df8..5b21f0e562 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/notification/DefaultPushRuleService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/notification/DefaultPushRuleService.kt
@@ -48,58 +48,7 @@ internal class DefaultPushRuleService @Inject constructor(
 
     override fun fetchPushRules(scope: String) {
         pushRulesTask
-                .configureWith(Unit)
-                .dispatchTo(object : MatrixCallback<GetPushRulesResponse> {
-                    override fun onSuccess(data: GetPushRulesResponse) {
-                        monarchy.runTransactionSync { realm ->
-                            //clear existings?
-                            //TODO
-                            realm.where(PushRulesEntity::class.java)
-                                    .equalTo(PusherEntityFields.USER_ID, sessionParams.credentials.userId)
-                                    .findAll().deleteAllFromRealm()
-
-                            val content = PushRulesEntity(sessionParams.credentials.userId, scope, "content")
-                            data.global.content?.forEach { rule ->
-                                PushRulesMapper.map(rule).also {
-                                    content.pushRules.add(it)
-                                }
-                            }
-                            realm.insertOrUpdate(content)
-
-                            val override = PushRulesEntity(sessionParams.credentials.userId, scope, "override")
-                            data.global.override?.forEach { rule ->
-                                PushRulesMapper.map(rule).also {
-                                    override.pushRules.add(it)
-                                }
-                            }
-                            realm.insertOrUpdate(override)
-
-                            val rooms = PushRulesEntity(sessionParams.credentials.userId, scope, "room")
-                            data.global.room?.forEach { rule ->
-                                PushRulesMapper.map(rule).also {
-                                    rooms.pushRules.add(it)
-                                }
-                            }
-                            realm.insertOrUpdate(rooms)
-
-                            val senders = PushRulesEntity(sessionParams.credentials.userId, scope, "sender")
-                            data.global.sender?.forEach { rule ->
-                                PushRulesMapper.map(rule).also {
-                                    senders.pushRules.add(it)
-                                }
-                            }
-                            realm.insertOrUpdate(senders)
-
-                            val underrides = PushRulesEntity(sessionParams.credentials.userId, scope, "underride")
-                            data.global.underride?.forEach { rule ->
-                                PushRulesMapper.map(rule).also {
-                                    underrides.pushRules.add(it)
-                                }
-                            }
-                            realm.insertOrUpdate(underrides)
-                        }
-                    }
-                })
+                .configureWith(GetPushRulesTask.Params(scope))
                 .executeBy(taskExecutor)
     }
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/DefaultPusherService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/DefaultPusherService.kt
index 103bdb71e4..8401f3e628 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/DefaultPusherService.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/DefaultPusherService.kt
@@ -54,22 +54,6 @@ internal class DefaultPusherService @Inject constructor(
     override fun refreshPushers() {
         getPusherTask
                 .configureWith(Unit)
-                .dispatchTo(object : MatrixCallback<GetPushersResponse> {
-                    override fun onSuccess(data: GetPushersResponse) {
-                        monarchy.runTransactionSync { realm ->
-                            //clear existings?
-                            realm.where(PusherEntity::class.java)
-                                    .equalTo(PusherEntityFields.USER_ID, sessionParam.credentials.userId)
-                                    .findAll().deleteAllFromRealm()
-                            data.pushers?.forEach { jsonPusher ->
-                                jsonPusher.toEntity(sessionParam.credentials.userId).also {
-                                    it.state = PusherState.REGISTERED
-                                    realm.insertOrUpdate(it)
-                                }
-                            }
-                        }
-                    }
-                })
                 .executeBy(taskExecutor)
     }
 
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/GetPushRulesTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/GetPushRulesTask.kt
index 46af3b6366..cbd8dcac22 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/GetPushRulesTask.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/GetPushRulesTask.kt
@@ -16,19 +16,81 @@
 package im.vector.matrix.android.internal.session.pushers
 
 import arrow.core.Try
+import com.zhuinden.monarchy.Monarchy
+import im.vector.matrix.android.api.auth.data.SessionParams
 import im.vector.matrix.android.api.pushrules.rest.GetPushRulesResponse
+import im.vector.matrix.android.internal.database.mapper.PushRulesMapper
+import im.vector.matrix.android.internal.database.model.PushRulesEntity
+import im.vector.matrix.android.internal.database.model.PusherEntityFields
 import im.vector.matrix.android.internal.network.executeRequest
 import im.vector.matrix.android.internal.task.Task
+import im.vector.matrix.android.internal.util.tryTransactionSync
 import javax.inject.Inject
 
 
-internal interface GetPushRulesTask : Task<Unit, GetPushRulesResponse>
+internal interface GetPushRulesTask : Task<GetPushRulesTask.Params, Unit> {
 
-internal class DefaultGetPushRulesTask @Inject constructor(private val pushRulesApi: PushRulesApi) : GetPushRulesTask {
+    data class Params(val scope: String)
 
-    override suspend fun execute(params: Unit): Try<GetPushRulesResponse> {
-        return executeRequest {
+}
+
+
+internal class DefaultGetPushRulesTask @Inject constructor(private val pushRulesApi: PushRulesApi,
+                                                           private val monarchy: Monarchy,
+                                                           private val sessionParams: SessionParams) : GetPushRulesTask {
+
+    override suspend fun execute(params: GetPushRulesTask.Params): Try<Unit> {
+        return executeRequest<GetPushRulesResponse> {
             apiCall = pushRulesApi.getAllRules()
+        }.flatMap { response ->
+            val scope = params.scope
+            return monarchy.tryTransactionSync { realm ->
+                //clear existings?
+                //TODO
+                realm.where(PushRulesEntity::class.java)
+                        .equalTo(PusherEntityFields.USER_ID, sessionParams.credentials.userId)
+                        .findAll().deleteAllFromRealm()
+
+                val content = PushRulesEntity(sessionParams.credentials.userId, scope, "content")
+                response.global.content?.forEach { rule ->
+                    PushRulesMapper.map(rule).also {
+                        content.pushRules.add(it)
+                    }
+                }
+                realm.insertOrUpdate(content)
+
+                val override = PushRulesEntity(sessionParams.credentials.userId, scope, "override")
+                response.global.override?.forEach { rule ->
+                    PushRulesMapper.map(rule).also {
+                        override.pushRules.add(it)
+                    }
+                }
+                realm.insertOrUpdate(override)
+
+                val rooms = PushRulesEntity(sessionParams.credentials.userId, scope, "room")
+                response.global.room?.forEach { rule ->
+                    PushRulesMapper.map(rule).also {
+                        rooms.pushRules.add(it)
+                    }
+                }
+                realm.insertOrUpdate(rooms)
+
+                val senders = PushRulesEntity(sessionParams.credentials.userId, scope, "sender")
+                response.global.sender?.forEach { rule ->
+                    PushRulesMapper.map(rule).also {
+                        senders.pushRules.add(it)
+                    }
+                }
+                realm.insertOrUpdate(senders)
+
+                val underrides = PushRulesEntity(sessionParams.credentials.userId, scope, "underride")
+                response.global.underride?.forEach { rule ->
+                    PushRulesMapper.map(rule).also {
+                        underrides.pushRules.add(it)
+                    }
+                }
+                realm.insertOrUpdate(underrides)
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/GetPushersTask.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/GetPushersTask.kt
index 05b36fb5bc..57ea8a38ba 100644
--- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/GetPushersTask.kt
+++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/session/pushers/GetPushersTask.kt
@@ -16,17 +16,39 @@
 package im.vector.matrix.android.internal.session.pushers
 
 import arrow.core.Try
+import com.zhuinden.monarchy.Monarchy
+import im.vector.matrix.android.api.auth.data.SessionParams
+import im.vector.matrix.android.api.session.pushers.PusherState
+import im.vector.matrix.android.internal.database.mapper.toEntity
+import im.vector.matrix.android.internal.database.model.PusherEntity
+import im.vector.matrix.android.internal.database.model.PusherEntityFields
 import im.vector.matrix.android.internal.network.executeRequest
 import im.vector.matrix.android.internal.task.Task
+import im.vector.matrix.android.internal.util.tryTransactionSync
 import javax.inject.Inject
 
-internal interface GetPushersTask : Task<Unit, GetPushersResponse>
+internal interface GetPushersTask : Task<Unit, Unit>
 
-internal class DefaultGetPusherTask @Inject constructor(private val pushersAPI: PushersAPI) : GetPushersTask {
+internal class DefaultGetPusherTask @Inject constructor(private val pushersAPI: PushersAPI,
+                                                        private val monarchy: Monarchy,
+                                                        private val sessionParams: SessionParams) : GetPushersTask {
 
-    override suspend fun execute(params: Unit): Try<GetPushersResponse> {
-        return executeRequest {
+    override suspend fun execute(params: Unit): Try<Unit> {
+        return executeRequest<GetPushersResponse> {
             apiCall = pushersAPI.getPushers()
+        }.flatMap { response ->
+            monarchy.tryTransactionSync { realm ->
+                //clear existings?
+                realm.where(PusherEntity::class.java)
+                        .equalTo(PusherEntityFields.USER_ID, sessionParams.credentials.userId)
+                        .findAll().deleteAllFromRealm()
+                response.pushers?.forEach { jsonPusher ->
+                    jsonPusher.toEntity(sessionParams.credentials.userId).also {
+                        it.state = PusherState.REGISTERED
+                        realm.insertOrUpdate(it)
+                    }
+                }
+            }
         }
     }
 }
\ No newline at end of file
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageActionsViewModel.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageActionsViewModel.kt
index 58c8cf61ac..9bd6bda2a1 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageActionsViewModel.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/action/MessageActionsViewModel.kt
@@ -18,6 +18,7 @@ package im.vector.riotredesign.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)
     }
 
 }
\ No newline at end of file
diff --git a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt
index 5cb7c94346..b8917f1d8d 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/home/room/detail/timeline/factory/MessageItemFactory.kt
@@ -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.riotredesign.EmojiCompatFontProvider
@@ -42,7 +50,18 @@ import im.vector.riotredesign.features.home.AvatarRenderer
 import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
 import im.vector.riotredesign.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder
 import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider
-import im.vector.riotredesign.features.home.room.detail.timeline.item.*
+import im.vector.riotredesign.features.home.room.detail.timeline.item.BlankItem_
+import im.vector.riotredesign.features.home.room.detail.timeline.item.DefaultItem
+import im.vector.riotredesign.features.home.room.detail.timeline.item.DefaultItem_
+import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageFileItem
+import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageFileItem_
+import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageImageVideoItem
+import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageImageVideoItem_
+import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
+import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageTextItem
+import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageTextItem_
+import im.vector.riotredesign.features.home.room.detail.timeline.item.RedactedMessageItem
+import im.vector.riotredesign.features.home.room.detail.timeline.item.RedactedMessageItem_
 import im.vector.riotredesign.features.home.room.detail.timeline.util.MessageInformationDataFactory
 import im.vector.riotredesign.features.html.EventHtmlRenderer
 import im.vector.riotredesign.features.media.ImageContentRenderer
@@ -54,7 +73,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,
@@ -78,9 +97,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
@@ -90,16 +109,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)
@@ -133,7 +152,7 @@ class MessageItemFactory @Inject constructor(
                         }))
                 .longClickListener { view ->
                     return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
-                            ?: false
+                                             ?: false
                 }
     }
 
@@ -156,7 +175,7 @@ class MessageItemFactory @Inject constructor(
                         }))
                 .longClickListener { view ->
                     return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
-                            ?: false
+                                             ?: false
                 }
                 .clickListener(
                         DebouncedClickListener(View.OnClickListener { _ ->
@@ -208,7 +227,7 @@ class MessageItemFactory @Inject constructor(
                         }))
                 .longClickListener { view ->
                     return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
-                            ?: false
+                                             ?: false
                 }
     }
 
@@ -251,7 +270,7 @@ class MessageItemFactory @Inject constructor(
                 .clickListener { view -> callback?.onVideoMessageClicked(messageContent, videoData, view) }
                 .longClickListener { view ->
                     return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
-                            ?: false
+                                             ?: false
                 }
     }
 
@@ -263,7 +282,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)
@@ -291,7 +310,7 @@ class MessageItemFactory @Inject constructor(
                         }))
                 .longClickListener { view ->
                     return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
-                            ?: false
+                                             ?: false
                 }
     }
 
@@ -323,9 +342,9 @@ class MessageItemFactory @Inject constructor(
                 //nop
             }
         },
-                editStart,
-                editEnd,
-                Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
+                          editStart,
+                          editEnd,
+                          Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
         return spannable
     }
 
@@ -361,7 +380,7 @@ class MessageItemFactory @Inject constructor(
                         }))
                 .longClickListener { view ->
                     return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
-                            ?: false
+                                             ?: false
                 }
     }
 
@@ -397,7 +416,7 @@ class MessageItemFactory @Inject constructor(
                         }))
                 .longClickListener { view ->
                     return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
-                            ?: false
+                                             ?: false
                 }
     }
 
diff --git a/vector/src/main/java/im/vector/riotredesign/features/settings/VectorLocale.kt b/vector/src/main/java/im/vector/riotredesign/features/settings/VectorLocale.kt
index 0c88f508bb..b5faddf97e 100644
--- a/vector/src/main/java/im/vector/riotredesign/features/settings/VectorLocale.kt
+++ b/vector/src/main/java/im/vector/riotredesign/features/settings/VectorLocale.kt
@@ -24,6 +24,7 @@ import android.text.TextUtils
 import android.util.Pair
 import androidx.core.content.edit
 import im.vector.riotredesign.R
+import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.GlobalScope
 import kotlinx.coroutines.launch
 import timber.log.Timber
@@ -75,7 +76,7 @@ object VectorLocale {
         }
 
         // init the known locales in background, using kotlin coroutines
-        GlobalScope.launch {
+        GlobalScope.launch(Dispatchers.IO) {
             initApplicationLocales(context)
         }
     }