mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2024-11-22 09:25:49 +03:00
Merge pull request #4837 from vector-im/feature/bma/safe_epoxy_char_sequence
Safe epoxy char sequence
This commit is contained in:
commit
279f9e00a3
76 changed files with 307 additions and 251 deletions
1
changelog.d/4837.bugfix
Normal file
1
changelog.d/4837.bugfix
Normal file
|
@ -0,0 +1 @@
|
|||
Stop using CharSequence as EpoxyAttribute because it can lead to crash if the CharSequence mutates during rendering.
|
|
@ -108,7 +108,6 @@ class SpanUtilsTest : InstrumentedTest {
|
|||
val string = SpannableString("Text")
|
||||
val result = spanUtils.getBindingOptions(string)
|
||||
result.canUseTextFuture shouldBeEqualTo true
|
||||
result.preventMutation shouldBeEqualTo false
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -117,7 +116,6 @@ class SpanUtilsTest : InstrumentedTest {
|
|||
string.setSpan(StrikethroughSpan(), 10, 23, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
|
||||
val result = spanUtils.getBindingOptions(string)
|
||||
result.canUseTextFuture shouldBeEqualTo false
|
||||
result.preventMutation shouldBeEqualTo false
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -125,7 +123,6 @@ class SpanUtilsTest : InstrumentedTest {
|
|||
val string = SpannableString("Emoji \uD83D\uDE2E\u200D\uD83D\uDCA8")
|
||||
val result = spanUtils.getBindingOptions(string)
|
||||
result.canUseTextFuture shouldBeEqualTo false
|
||||
result.preventMutation shouldBeEqualTo true
|
||||
}
|
||||
|
||||
private fun trueIfAlwaysAllowed() = Build.VERSION.SDK_INT < Build.VERSION_CODES.P
|
||||
|
|
|
@ -26,15 +26,14 @@ import im.vector.app.R
|
|||
import im.vector.app.core.epoxy.ClickListener
|
||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.app.core.epoxy.charsequence.EpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.core.epoxy.util.preventMutation
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.features.displayname.getBestName
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
import im.vector.app.features.home.room.detail.timeline.item.BindingOptions
|
||||
import im.vector.app.features.home.room.detail.timeline.tools.findPillsAndProcess
|
||||
import im.vector.app.features.media.ImageContentRenderer
|
||||
import org.matrix.android.sdk.api.extensions.orFalse
|
||||
import org.matrix.android.sdk.api.util.MatrixItem
|
||||
|
||||
/**
|
||||
|
@ -50,13 +49,13 @@ abstract class BottomSheetMessagePreviewItem : VectorEpoxyModel<BottomSheetMessa
|
|||
lateinit var matrixItem: MatrixItem
|
||||
|
||||
@EpoxyAttribute
|
||||
lateinit var body: CharSequence
|
||||
lateinit var body: EpoxyCharSequence
|
||||
|
||||
@EpoxyAttribute
|
||||
var bindingOptions: BindingOptions? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var bodyDetails: CharSequence? = null
|
||||
var bodyDetails: EpoxyCharSequence? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var imageContentRenderer: ImageContentRenderer? = null
|
||||
|
@ -65,7 +64,7 @@ abstract class BottomSheetMessagePreviewItem : VectorEpoxyModel<BottomSheetMessa
|
|||
var data: ImageContentRenderer.Data? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var time: CharSequence? = null
|
||||
var time: String? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var movementMethod: MovementMethod? = null
|
||||
|
@ -84,13 +83,9 @@ abstract class BottomSheetMessagePreviewItem : VectorEpoxyModel<BottomSheetMessa
|
|||
}
|
||||
holder.imagePreview.isVisible = data != null
|
||||
holder.body.movementMethod = movementMethod
|
||||
holder.body.text = if (bindingOptions?.preventMutation.orFalse()) {
|
||||
body.preventMutation()
|
||||
} else {
|
||||
body
|
||||
}
|
||||
holder.bodyDetails.setTextOrHide(bodyDetails)
|
||||
body.findPillsAndProcess(coroutineScope) { it.bind(holder.body) }
|
||||
holder.body.text = body.charSequence
|
||||
holder.bodyDetails.setTextOrHide(bodyDetails?.charSequence)
|
||||
body.charSequence.findPillsAndProcess(coroutineScope) { it.bind(holder.body) }
|
||||
holder.timestamp.setTextOrHide(time)
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ import im.vector.app.core.extensions.setTextOrHide
|
|||
abstract class BottomSheetRadioActionItem : VectorEpoxyModel<BottomSheetRadioActionItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
var title: CharSequence? = null
|
||||
var title: String? = null
|
||||
|
||||
@StringRes
|
||||
@EpoxyAttribute
|
||||
|
@ -47,7 +47,7 @@ abstract class BottomSheetRadioActionItem : VectorEpoxyModel<BottomSheetRadioAct
|
|||
var selected = false
|
||||
|
||||
@EpoxyAttribute
|
||||
var description: CharSequence? = null
|
||||
var description: String? = null
|
||||
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
|
||||
lateinit var listener: ClickListener
|
||||
|
|
|
@ -36,7 +36,7 @@ abstract class BottomSheetSendStateItem : VectorEpoxyModel<BottomSheetSendStateI
|
|||
var showProgress: Boolean = false
|
||||
|
||||
@EpoxyAttribute
|
||||
lateinit var text: CharSequence
|
||||
lateinit var text: String
|
||||
|
||||
@EpoxyAttribute
|
||||
@DrawableRes
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* Copyright (c) 2022 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.app.core.epoxy.charsequence
|
||||
|
||||
/**
|
||||
* Wrapper for a CharSequence, which support mutation of the CharSequence, which can happen during rendering
|
||||
*/
|
||||
class EpoxyCharSequence(val charSequence: CharSequence) {
|
||||
private val hash = charSequence.toString().hashCode()
|
||||
|
||||
override fun hashCode() = hash
|
||||
override fun equals(other: Any?) = other is EpoxyCharSequence && other.hash == hash
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2021 New Vector Ltd
|
||||
* Copyright (c) 2022 New Vector Ltd
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
|
@ -14,8 +14,9 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package im.vector.app.core.epoxy.util
|
||||
package im.vector.app.core.epoxy.charsequence
|
||||
|
||||
import android.text.SpannableString
|
||||
|
||||
fun CharSequence?.preventMutation(): CharSequence? = this?.let { SpannableString(it) }
|
||||
/**
|
||||
* Extensions to wrap CharSequence to EpoxyCharSequence
|
||||
*/
|
||||
fun CharSequence.toEpoxyCharSequence() = EpoxyCharSequence(this)
|
|
@ -33,7 +33,7 @@ import im.vector.app.core.extensions.setAttributeTintedImageResource
|
|||
abstract class RadioButtonItem : VectorEpoxyModel<RadioButtonItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
var title: CharSequence? = null
|
||||
var title: String? = null
|
||||
|
||||
@StringRes
|
||||
@EpoxyAttribute
|
||||
|
|
|
@ -23,7 +23,7 @@ import im.vector.app.core.platform.VectorSharedAction
|
|||
* Parent class for a bottom sheet action
|
||||
*/
|
||||
open class BottomSheetGenericRadioAction(
|
||||
open val title: CharSequence?,
|
||||
open val title: String?,
|
||||
open val description: String? = null,
|
||||
open val isSelected: Boolean
|
||||
) : VectorSharedAction {
|
||||
|
|
|
@ -39,10 +39,10 @@ import im.vector.app.core.extensions.setTextOrHide
|
|||
abstract class GenericEmptyWithActionItem : VectorEpoxyModel<GenericEmptyWithActionItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
var title: CharSequence? = null
|
||||
var title: String? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var description: CharSequence? = null
|
||||
var description: String? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
@DrawableRes
|
||||
|
|
|
@ -38,7 +38,7 @@ import im.vector.app.features.themes.ThemeUtils
|
|||
abstract class GenericFooterItem : VectorEpoxyModel<GenericFooterItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
var text: CharSequence? = null
|
||||
var text: String? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var style: ItemStyle = ItemStyle.NORMAL_TEXT
|
||||
|
|
|
@ -28,6 +28,7 @@ import im.vector.app.R
|
|||
import im.vector.app.core.epoxy.ClickListener
|
||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.app.core.epoxy.charsequence.EpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
|
||||
|
@ -41,10 +42,10 @@ import im.vector.app.core.extensions.setTextOrHide
|
|||
abstract class GenericItem : VectorEpoxyModel<GenericItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
var title: CharSequence? = null
|
||||
var title: EpoxyCharSequence? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var description: CharSequence? = null
|
||||
var description: EpoxyCharSequence? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var style: ItemStyle = ItemStyle.NORMAL_TEXT
|
||||
|
@ -71,7 +72,7 @@ abstract class GenericItem : VectorEpoxyModel<GenericItem.Holder>() {
|
|||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
holder.titleText.setTextOrHide(title)
|
||||
holder.titleText.setTextOrHide(title?.charSequence)
|
||||
|
||||
if (titleIconResourceId != -1) {
|
||||
holder.titleIcon.setImageResource(titleIconResourceId)
|
||||
|
@ -82,7 +83,7 @@ abstract class GenericItem : VectorEpoxyModel<GenericItem.Holder>() {
|
|||
|
||||
holder.titleText.textSize = style.toTextSize()
|
||||
|
||||
holder.descriptionText.setTextOrHide(description)
|
||||
holder.descriptionText.setTextOrHide(description?.charSequence)
|
||||
|
||||
if (hasIndeterminateProcess) {
|
||||
holder.progressBar.isVisible = true
|
||||
|
|
|
@ -28,6 +28,7 @@ import im.vector.app.R
|
|||
import im.vector.app.core.epoxy.ClickListener
|
||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.app.core.epoxy.charsequence.EpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.features.themes.ThemeUtils
|
||||
|
@ -39,7 +40,7 @@ import im.vector.app.features.themes.ThemeUtils
|
|||
abstract class GenericPillItem : VectorEpoxyModel<GenericPillItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
var text: CharSequence? = null
|
||||
var text: EpoxyCharSequence? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var style: ItemStyle = ItemStyle.NORMAL_TEXT
|
||||
|
@ -60,7 +61,7 @@ abstract class GenericPillItem : VectorEpoxyModel<GenericPillItem.Holder>() {
|
|||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
|
||||
holder.textView.setTextOrHide(text)
|
||||
holder.textView.setTextOrHide(text?.charSequence)
|
||||
holder.textView.typeface = style.toTypeFace()
|
||||
holder.textView.textSize = style.toTextSize()
|
||||
holder.textView.gravity = if (centered) Gravity.CENTER_HORIZONTAL else Gravity.START
|
||||
|
|
|
@ -27,6 +27,7 @@ import im.vector.app.R
|
|||
import im.vector.app.core.epoxy.ClickListener
|
||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.app.core.epoxy.charsequence.EpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.features.themes.ThemeUtils
|
||||
|
@ -41,10 +42,10 @@ import im.vector.app.features.themes.ThemeUtils
|
|||
abstract class GenericWithValueItem : VectorEpoxyModel<GenericWithValueItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
var title: CharSequence? = null
|
||||
var title: EpoxyCharSequence? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var value: CharSequence? = null
|
||||
var value: String? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
@ColorInt
|
||||
|
@ -62,7 +63,7 @@ abstract class GenericWithValueItem : VectorEpoxyModel<GenericWithValueItem.Hold
|
|||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
holder.titleText.setTextOrHide(title)
|
||||
holder.titleText.setTextOrHide(title?.charSequence)
|
||||
|
||||
if (titleIconResourceId != -1) {
|
||||
holder.titleIcon.setImageResource(titleIconResourceId)
|
||||
|
|
|
@ -29,13 +29,13 @@ import im.vector.app.core.epoxy.onClick
|
|||
abstract class AutocompleteCommandItem : VectorEpoxyModel<AutocompleteCommandItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
var name: CharSequence? = null
|
||||
var name: String? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var parameters: CharSequence? = null
|
||||
var parameters: String? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var description: CharSequence? = null
|
||||
var description: String? = null
|
||||
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
|
||||
var clickListener: ClickListener? = null
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.airbnb.mvrx.Loading
|
|||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.errorWithRetryItem
|
||||
import im.vector.app.core.epoxy.loadingItem
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
|
@ -73,11 +74,11 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(
|
|||
KeysBackupState.Disabled -> {
|
||||
genericItem {
|
||||
id("summary")
|
||||
title(host.stringProvider.getString(R.string.keys_backup_settings_status_not_setup))
|
||||
title(host.stringProvider.getString(R.string.keys_backup_settings_status_not_setup).toEpoxyCharSequence())
|
||||
style(ItemStyle.BIG_TEXT)
|
||||
|
||||
if (data.keysBackupVersionTrust()?.usable == false) {
|
||||
description(host.stringProvider.getString(R.string.keys_backup_settings_untrusted_backup))
|
||||
description(host.stringProvider.getString(R.string.keys_backup_settings_untrusted_backup).toEpoxyCharSequence())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,12 +89,12 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(
|
|||
KeysBackupState.Enabling -> {
|
||||
genericItem {
|
||||
id("summary")
|
||||
title(host.stringProvider.getString(R.string.keys_backup_settings_status_ko))
|
||||
title(host.stringProvider.getString(R.string.keys_backup_settings_status_ko).toEpoxyCharSequence())
|
||||
style(ItemStyle.BIG_TEXT)
|
||||
if (data.keysBackupVersionTrust()?.usable == false) {
|
||||
description(host.stringProvider.getString(R.string.keys_backup_settings_untrusted_backup))
|
||||
description(host.stringProvider.getString(R.string.keys_backup_settings_untrusted_backup).toEpoxyCharSequence())
|
||||
} else {
|
||||
description(keyBackupState.toString())
|
||||
description(keyBackupState.toString().toEpoxyCharSequence())
|
||||
}
|
||||
endIconResourceId(R.drawable.unit_test_ko)
|
||||
}
|
||||
|
@ -103,12 +104,12 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(
|
|||
KeysBackupState.ReadyToBackUp -> {
|
||||
genericItem {
|
||||
id("summary")
|
||||
title(host.stringProvider.getString(R.string.keys_backup_settings_status_ok))
|
||||
title(host.stringProvider.getString(R.string.keys_backup_settings_status_ok).toEpoxyCharSequence())
|
||||
style(ItemStyle.BIG_TEXT)
|
||||
if (data.keysBackupVersionTrust()?.usable == false) {
|
||||
description(host.stringProvider.getString(R.string.keys_backup_settings_untrusted_backup))
|
||||
description(host.stringProvider.getString(R.string.keys_backup_settings_untrusted_backup).toEpoxyCharSequence())
|
||||
} else {
|
||||
description(host.stringProvider.getString(R.string.keys_backup_info_keys_all_backup_up))
|
||||
description(host.stringProvider.getString(R.string.keys_backup_info_keys_all_backup_up).toEpoxyCharSequence())
|
||||
}
|
||||
endIconResourceId(R.drawable.unit_test_ok)
|
||||
}
|
||||
|
@ -119,7 +120,7 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(
|
|||
KeysBackupState.BackingUp -> {
|
||||
genericItem {
|
||||
id("summary")
|
||||
title(host.stringProvider.getString(R.string.keys_backup_settings_status_ok))
|
||||
title(host.stringProvider.getString(R.string.keys_backup_settings_status_ok).toEpoxyCharSequence())
|
||||
style(ItemStyle.BIG_TEXT)
|
||||
hasIndeterminateProcess(true)
|
||||
|
||||
|
@ -129,10 +130,11 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(
|
|||
val remainingKeysToBackup = totalKeys - backedUpKeys
|
||||
|
||||
if (data.keysBackupVersionTrust()?.usable == false) {
|
||||
description(host.stringProvider.getString(R.string.keys_backup_settings_untrusted_backup))
|
||||
description(host.stringProvider.getString(R.string.keys_backup_settings_untrusted_backup).toEpoxyCharSequence())
|
||||
} else {
|
||||
description(host.stringProvider
|
||||
.getQuantityString(R.plurals.keys_backup_info_keys_backing_up, remainingKeysToBackup, remainingKeysToBackup))
|
||||
.getQuantityString(R.plurals.keys_backup_info_keys_backing_up, remainingKeysToBackup, remainingKeysToBackup)
|
||||
.toEpoxyCharSequence())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,14 +146,14 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(
|
|||
// Add infos
|
||||
genericItem {
|
||||
id("version")
|
||||
title(host.stringProvider.getString(R.string.keys_backup_info_title_version))
|
||||
description(keyVersionResult?.version ?: "")
|
||||
title(host.stringProvider.getString(R.string.keys_backup_info_title_version).toEpoxyCharSequence())
|
||||
description(keyVersionResult?.version.orEmpty().toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
genericItem {
|
||||
id("algorithm")
|
||||
title(host.stringProvider.getString(R.string.keys_backup_info_title_algorithm))
|
||||
description(keyVersionResult?.algorithm ?: "")
|
||||
title(host.stringProvider.getString(R.string.keys_backup_info_title_algorithm).toEpoxyCharSequence())
|
||||
description(keyVersionResult?.algorithm.orEmpty().toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
if (vectorPreferences.developerMode()) {
|
||||
|
@ -189,7 +191,7 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(
|
|||
keysVersionTrust().signatures.forEach {
|
||||
genericItem {
|
||||
id(UUID.randomUUID().toString())
|
||||
title(host.stringProvider.getString(R.string.keys_backup_info_title_signature))
|
||||
title(host.stringProvider.getString(R.string.keys_backup_info_title_signature).toEpoxyCharSequence())
|
||||
|
||||
val isDeviceKnown = it.device != null
|
||||
val isDeviceVerified = it.device?.isVerified ?: false
|
||||
|
@ -197,21 +199,27 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(
|
|||
val deviceId: String = it.deviceId ?: ""
|
||||
|
||||
if (!isDeviceKnown) {
|
||||
description(host.stringProvider.getString(R.string.keys_backup_settings_signature_from_unknown_device, deviceId))
|
||||
description(host.stringProvider
|
||||
.getString(R.string.keys_backup_settings_signature_from_unknown_device, deviceId)
|
||||
.toEpoxyCharSequence())
|
||||
endIconResourceId(R.drawable.e2e_warning)
|
||||
} else {
|
||||
if (isSignatureValid) {
|
||||
if (host.session.sessionParams.deviceId == it.deviceId) {
|
||||
description(host.stringProvider.getString(R.string.keys_backup_settings_valid_signature_from_this_device))
|
||||
description(host.stringProvider
|
||||
.getString(R.string.keys_backup_settings_valid_signature_from_this_device)
|
||||
.toEpoxyCharSequence())
|
||||
endIconResourceId(R.drawable.e2e_verified)
|
||||
} else {
|
||||
if (isDeviceVerified) {
|
||||
description(host.stringProvider
|
||||
.getString(R.string.keys_backup_settings_valid_signature_from_verified_device, deviceId))
|
||||
.getString(R.string.keys_backup_settings_valid_signature_from_verified_device, deviceId)
|
||||
.toEpoxyCharSequence())
|
||||
endIconResourceId(R.drawable.e2e_verified)
|
||||
} else {
|
||||
description(host.stringProvider
|
||||
.getString(R.string.keys_backup_settings_valid_signature_from_unverified_device, deviceId))
|
||||
.getString(R.string.keys_backup_settings_valid_signature_from_unverified_device, deviceId)
|
||||
.toEpoxyCharSequence())
|
||||
endIconResourceId(R.drawable.e2e_warning)
|
||||
}
|
||||
}
|
||||
|
@ -220,10 +228,12 @@ class KeysBackupSettingsRecyclerViewController @Inject constructor(
|
|||
endIconResourceId(R.drawable.e2e_warning)
|
||||
if (isDeviceVerified) {
|
||||
description(host.stringProvider
|
||||
.getString(R.string.keys_backup_settings_invalid_signature_from_verified_device, deviceId))
|
||||
.getString(R.string.keys_backup_settings_invalid_signature_from_verified_device, deviceId)
|
||||
.toEpoxyCharSequence())
|
||||
} else {
|
||||
description(host.stringProvider
|
||||
.getString(R.string.keys_backup_settings_invalid_signature_from_unverified_device, deviceId))
|
||||
.getString(R.string.keys_backup_settings_invalid_signature_from_unverified_device, deviceId)
|
||||
.toEpoxyCharSequence())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@ import androidx.core.text.toSpannable
|
|||
import com.airbnb.epoxy.EpoxyController
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.bottomSheetDividerItem
|
||||
import im.vector.app.core.epoxy.charsequence.EpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.core.utils.colorizeMatchingText
|
||||
|
@ -49,12 +51,12 @@ class VerificationCancelController @Inject constructor(
|
|||
if (state.currentDeviceCanCrossSign) {
|
||||
bottomSheetVerificationNoticeItem {
|
||||
id("notice")
|
||||
notice(host.stringProvider.getString(R.string.verify_cancel_self_verification_from_trusted))
|
||||
notice(host.stringProvider.getString(R.string.verify_cancel_self_verification_from_trusted).toEpoxyCharSequence())
|
||||
}
|
||||
} else {
|
||||
bottomSheetVerificationNoticeItem {
|
||||
id("notice")
|
||||
notice(host.stringProvider.getString(R.string.verify_cancel_self_verification_from_untrusted))
|
||||
notice(host.stringProvider.getString(R.string.verify_cancel_self_verification_from_untrusted).toEpoxyCharSequence())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -63,9 +65,11 @@ class VerificationCancelController @Inject constructor(
|
|||
bottomSheetVerificationNoticeItem {
|
||||
id("notice")
|
||||
notice(
|
||||
host.stringProvider.getString(R.string.verify_cancel_other, otherDisplayName, otherUserID)
|
||||
.toSpannable()
|
||||
.colorizeMatchingText(otherUserID, host.colorProvider.getColorFromAttribute(R.attr.vctr_notice_text_color))
|
||||
EpoxyCharSequence(
|
||||
host.stringProvider.getString(R.string.verify_cancel_other, otherDisplayName, otherUserID)
|
||||
.toSpannable()
|
||||
.colorizeMatchingText(otherUserID, host.colorProvider.getColorFromAttribute(R.attr.vctr_notice_text_color))
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ package im.vector.app.features.crypto.verification.cancel
|
|||
import com.airbnb.epoxy.EpoxyController
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.bottomSheetDividerItem
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.crypto.verification.VerificationBottomSheetViewState
|
||||
|
@ -46,7 +47,7 @@ class VerificationNotMeController @Inject constructor(
|
|||
val host = this
|
||||
bottomSheetVerificationNoticeItem {
|
||||
id("notice")
|
||||
notice(host.eventHtmlRenderer.render(host.stringProvider.getString(R.string.verify_not_me_self_verification)))
|
||||
notice(host.eventHtmlRenderer.render(host.stringProvider.getString(R.string.verify_not_me_self_verification)).toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
bottomSheetDividerItem {
|
||||
|
|
|
@ -19,6 +19,7 @@ package im.vector.app.features.crypto.verification.choose
|
|||
import com.airbnb.epoxy.EpoxyController
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.bottomSheetDividerItem
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationActionItem
|
||||
|
@ -60,7 +61,7 @@ class VerificationChooseMethodController @Inject constructor(
|
|||
|
||||
bottomSheetVerificationNoticeItem {
|
||||
id("notice")
|
||||
notice(scanCodeInstructions)
|
||||
notice(scanCodeInstructions.toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
if (state.otherCanScanQrCode && !state.qrCodeText.isNullOrBlank()) {
|
||||
|
|
|
@ -19,6 +19,7 @@ package im.vector.app.features.crypto.verification.conclusion
|
|||
import com.airbnb.epoxy.EpoxyController
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.bottomSheetDividerItem
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationActionItem
|
||||
|
@ -53,7 +54,8 @@ class VerificationConclusionController @Inject constructor(
|
|||
id("notice")
|
||||
notice(host.stringProvider.getString(
|
||||
if (state.isSelfVerification) R.string.verification_conclusion_ok_self_notice
|
||||
else R.string.verification_conclusion_ok_notice))
|
||||
else R.string.verification_conclusion_ok_notice)
|
||||
.toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
bottomSheetVerificationBigImageItem {
|
||||
|
@ -66,7 +68,7 @@ class VerificationConclusionController @Inject constructor(
|
|||
ConclusionState.WARNING -> {
|
||||
bottomSheetVerificationNoticeItem {
|
||||
id("notice")
|
||||
notice(host.stringProvider.getString(R.string.verification_conclusion_not_secure))
|
||||
notice(host.stringProvider.getString(R.string.verification_conclusion_not_secure).toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
bottomSheetVerificationBigImageItem {
|
||||
|
@ -76,7 +78,7 @@ class VerificationConclusionController @Inject constructor(
|
|||
|
||||
bottomSheetVerificationNoticeItem {
|
||||
id("warning_notice")
|
||||
notice(host.eventHtmlRenderer.render(host.stringProvider.getString(R.string.verification_conclusion_compromised)))
|
||||
notice(host.eventHtmlRenderer.render(host.stringProvider.getString(R.string.verification_conclusion_compromised)).toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
bottomDone()
|
||||
|
@ -84,7 +86,7 @@ class VerificationConclusionController @Inject constructor(
|
|||
ConclusionState.CANCELLED -> {
|
||||
bottomSheetVerificationNoticeItem {
|
||||
id("notice_cancelled")
|
||||
notice(host.stringProvider.getString(R.string.verify_cancelled_notice))
|
||||
notice(host.stringProvider.getString(R.string.verify_cancelled_notice).toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
bottomSheetDividerItem {
|
||||
|
|
|
@ -21,6 +21,7 @@ import com.airbnb.mvrx.Fail
|
|||
import com.airbnb.mvrx.Success
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.bottomSheetDividerItem
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.errorWithRetryItem
|
||||
import im.vector.app.core.error.ErrorFormatter
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
|
@ -64,7 +65,7 @@ class VerificationEmojiCodeController @Inject constructor(
|
|||
is Success -> {
|
||||
bottomSheetVerificationNoticeItem {
|
||||
id("notice")
|
||||
notice(host.stringProvider.getString(R.string.verification_emoji_notice))
|
||||
notice(host.stringProvider.getString(R.string.verification_emoji_notice).toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
bottomSheetVerificationEmojisItem {
|
||||
|
@ -101,7 +102,7 @@ class VerificationEmojiCodeController @Inject constructor(
|
|||
is Success -> {
|
||||
bottomSheetVerificationNoticeItem {
|
||||
id("notice")
|
||||
notice(host.stringProvider.getString(R.string.verification_code_notice))
|
||||
notice(host.stringProvider.getString(R.string.verification_code_notice).toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
bottomSheetVerificationDecimalCodeItem {
|
||||
|
|
|
@ -42,10 +42,10 @@ abstract class BottomSheetVerificationActionItem : VectorEpoxyModel<BottomSheetV
|
|||
var iconRes: Int = -1
|
||||
|
||||
@EpoxyAttribute
|
||||
var title: CharSequence = ""
|
||||
var title: String = ""
|
||||
|
||||
@EpoxyAttribute
|
||||
var subTitle: CharSequence? = null
|
||||
var subTitle: String? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var titleColor: Int = 0
|
||||
|
|
|
@ -30,7 +30,7 @@ import im.vector.app.core.epoxy.VectorEpoxyModel
|
|||
abstract class BottomSheetVerificationDecimalCodeItem : VectorEpoxyModel<BottomSheetVerificationDecimalCodeItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
var code: CharSequence = ""
|
||||
var code: String = ""
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.airbnb.epoxy.EpoxyModelClass
|
|||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.app.core.epoxy.charsequence.EpoxyCharSequence
|
||||
|
||||
/**
|
||||
* A action for bottom sheet.
|
||||
|
@ -30,11 +31,11 @@ import im.vector.app.core.epoxy.VectorEpoxyModel
|
|||
abstract class BottomSheetVerificationNoticeItem : VectorEpoxyModel<BottomSheetVerificationNoticeItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
var notice: CharSequence = ""
|
||||
lateinit var notice: EpoxyCharSequence
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
holder.notice.text = notice
|
||||
holder.notice.text = notice.charSequence
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
|
|
|
@ -30,7 +30,7 @@ import im.vector.app.core.epoxy.VectorEpoxyModel
|
|||
abstract class BottomSheetVerificationWaitingItem : VectorEpoxyModel<BottomSheetVerificationWaitingItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
var title: CharSequence = ""
|
||||
var title: String = ""
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
|
|
|
@ -18,6 +18,7 @@ package im.vector.app.features.crypto.verification.qrconfirmation
|
|||
|
||||
import com.airbnb.epoxy.EpoxyController
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationBigImageItem
|
||||
|
@ -45,7 +46,7 @@ class VerificationQRWaitingController @Inject constructor(
|
|||
bottomSheetVerificationNoticeItem {
|
||||
id("notice")
|
||||
apply {
|
||||
notice(host.stringProvider.getString(R.string.qr_code_scanned_verif_waiting_notice))
|
||||
notice(host.stringProvider.getString(R.string.qr_code_scanned_verif_waiting_notice).toEpoxyCharSequence())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ package im.vector.app.features.crypto.verification.qrconfirmation
|
|||
import com.airbnb.epoxy.EpoxyController
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.bottomSheetDividerItem
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.crypto.verification.VerificationBottomSheetViewState
|
||||
|
@ -51,10 +52,10 @@ class VerificationQrScannedByOtherController @Inject constructor(
|
|||
id("notice")
|
||||
apply {
|
||||
if (state.isMe) {
|
||||
notice(host.stringProvider.getString(R.string.qr_code_scanned_self_verif_notice))
|
||||
notice(host.stringProvider.getString(R.string.qr_code_scanned_self_verif_notice).toEpoxyCharSequence())
|
||||
} else {
|
||||
val name = state.otherUserMxItem?.getBestName() ?: ""
|
||||
notice(host.stringProvider.getString(R.string.qr_code_scanned_by_other_notice, name))
|
||||
notice(host.stringProvider.getString(R.string.qr_code_scanned_by_other_notice, name).toEpoxyCharSequence())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import com.airbnb.mvrx.Success
|
|||
import com.airbnb.mvrx.Uninitialized
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.bottomSheetDividerItem
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.core.utils.colorizeMatchingText
|
||||
|
@ -57,7 +58,7 @@ class VerificationRequestController @Inject constructor(
|
|||
if (state.hasAnyOtherSession) {
|
||||
bottomSheetVerificationNoticeItem {
|
||||
id("notice")
|
||||
notice(host.stringProvider.getString(R.string.verification_open_other_to_verify))
|
||||
notice(host.stringProvider.getString(R.string.verification_open_other_to_verify).toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
bottomSheetSelfWaitItem {
|
||||
|
@ -112,7 +113,7 @@ class VerificationRequestController @Inject constructor(
|
|||
|
||||
bottomSheetVerificationNoticeItem {
|
||||
id("notice")
|
||||
notice(styledText)
|
||||
notice(styledText.toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
bottomSheetDividerItem {
|
||||
|
|
|
@ -18,6 +18,7 @@ package im.vector.app.features.devtools
|
|||
|
||||
import com.airbnb.epoxy.TypedEpoxyController
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.noResultItem
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
|
@ -48,8 +49,8 @@ class RoomStateListController @Inject constructor(
|
|||
stateEventsGroups.forEach { entry ->
|
||||
genericItem {
|
||||
id(entry.key)
|
||||
title(entry.key)
|
||||
description(host.stringProvider.getQuantityString(R.plurals.entries, entry.value.size, entry.value.size))
|
||||
title(entry.key.toEpoxyCharSequence())
|
||||
description(host.stringProvider.getQuantityString(R.plurals.entries, entry.value.size, entry.value.size).toEpoxyCharSequence())
|
||||
itemClickAction {
|
||||
host.interactionListener?.processAction(RoomDevToolAction.ShowStateEventType(entry.key))
|
||||
}
|
||||
|
@ -88,8 +89,8 @@ class RoomStateListController @Inject constructor(
|
|||
text = stateEvent.stateKey.let { "\"$it\"" }
|
||||
textStyle = "normal"
|
||||
}
|
||||
})
|
||||
description(contentJson)
|
||||
}.toEpoxyCharSequence())
|
||||
description(contentJson.toEpoxyCharSequence())
|
||||
itemClickAction {
|
||||
host.interactionListener?.processAction(RoomDevToolAction.ShowStateEvent(stateEvent))
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ abstract class SettingsItem : EpoxyModelWithHolder<SettingsItem.Holder>() {
|
|||
var descriptionResId: Int? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var description: CharSequence? = null
|
||||
var description: String? = null
|
||||
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
|
||||
var itemClickListener: ClickListener? = null
|
||||
|
|
|
@ -31,7 +31,7 @@ import im.vector.app.features.themes.ThemeUtils
|
|||
@EpoxyModelClass(layout = R.layout.item_form_advanced_toggle)
|
||||
abstract class FormAdvancedToggleItem : VectorEpoxyModel<FormAdvancedToggleItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute lateinit var title: CharSequence
|
||||
@EpoxyAttribute lateinit var title: String
|
||||
@EpoxyAttribute var expanded: Boolean = false
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var listener: ClickListener? = null
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ abstract class FormSwitchItem : VectorEpoxyModel<FormSwitchItem.Holder>() {
|
|||
var switchChecked: Boolean = false
|
||||
|
||||
@EpoxyAttribute
|
||||
var title: CharSequence? = null
|
||||
var title: String? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var summary: String? = null
|
||||
|
|
|
@ -34,7 +34,7 @@ import org.matrix.android.sdk.api.util.MatrixItem
|
|||
abstract class DisplayReadReceiptItem : EpoxyModelWithHolder<DisplayReadReceiptItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute lateinit var matrixItem: MatrixItem
|
||||
@EpoxyAttribute var timestamp: CharSequence? = null
|
||||
@EpoxyAttribute var timestamp: String? = null
|
||||
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var userClicked: ClickListener? = null
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import com.airbnb.epoxy.VisibilityState
|
|||
import im.vector.app.R
|
||||
import im.vector.app.core.date.DateFormatKind
|
||||
import im.vector.app.core.date.VectorDateFormatter
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.loadingItem
|
||||
import im.vector.app.core.epoxy.noResultItem
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
|
@ -100,7 +101,7 @@ class SearchResultController @Inject constructor(
|
|||
|
||||
// Take new content first
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val text = ((event.content?.get("m.new_content") as? Content) ?: event.content)?.get("body") as? String ?: return@forEach
|
||||
val text = ((event.content?.get("m.new_content") as? Content) ?: event.content)?.get("body") as? String ?: return@forEach
|
||||
val spannable = setHighLightedText(text, data.highlights) ?: return@forEach
|
||||
|
||||
val eventDate = Calendar.getInstance().apply {
|
||||
|
@ -118,7 +119,7 @@ val text = ((event.content?.get("m.new_content") as? Content) ?: event.content)?
|
|||
.id(eventAndSender.event.eventId)
|
||||
.avatarRenderer(avatarRenderer)
|
||||
.formattedDate(dateFormatter.format(event.originServerTs, DateFormatKind.MESSAGE_SIMPLE))
|
||||
.spannable(spannable)
|
||||
.spannable(spannable.toEpoxyCharSequence())
|
||||
.sender(eventAndSender.sender
|
||||
?: eventAndSender.event.senderId?.let { session.getRoomMember(it, data.roomId) }?.toMatrixItem())
|
||||
.listener { listener?.onItemClicked(eventAndSender.event) }
|
||||
|
|
|
@ -24,6 +24,7 @@ import im.vector.app.R
|
|||
import im.vector.app.core.epoxy.ClickListener
|
||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.app.core.epoxy.charsequence.EpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.features.displayname.getBestName
|
||||
|
@ -35,7 +36,7 @@ abstract class SearchResultItem : VectorEpoxyModel<SearchResultItem.Holder>() {
|
|||
|
||||
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
|
||||
@EpoxyAttribute var formattedDate: String? = null
|
||||
@EpoxyAttribute lateinit var spannable: CharSequence
|
||||
@EpoxyAttribute lateinit var spannable: EpoxyCharSequence
|
||||
@EpoxyAttribute var sender: MatrixItem? = null
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var listener: ClickListener? = null
|
||||
|
||||
|
@ -46,7 +47,7 @@ abstract class SearchResultItem : VectorEpoxyModel<SearchResultItem.Holder>() {
|
|||
sender?.let { avatarRenderer.render(it, holder.avatarImageView) }
|
||||
holder.memberNameView.setTextOrHide(sender?.getBestName())
|
||||
holder.timeView.text = formattedDate
|
||||
holder.contentView.text = spannable
|
||||
holder.contentView.text = spannable.charSequence
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
|
|
|
@ -27,6 +27,7 @@ import im.vector.app.core.epoxy.bottomsheet.bottomSheetActionItem
|
|||
import im.vector.app.core.epoxy.bottomsheet.bottomSheetMessagePreviewItem
|
||||
import im.vector.app.core.epoxy.bottomsheet.bottomSheetQuickReactionsItem
|
||||
import im.vector.app.core.epoxy.bottomsheet.bottomSheetSendStateItem
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.error.ErrorFormatter
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.core.utils.DimensionConverter
|
||||
|
@ -77,8 +78,8 @@ class MessageActionsEpoxyController @Inject constructor(
|
|||
data(state.timelineEvent()?.buildImageContentRendererData(host.dimensionConverter.dpToPx(66)))
|
||||
userClicked { host.listener?.didSelectMenuAction(EventSharedAction.OpenUserProfile(state.informationData.senderId)) }
|
||||
bindingOptions(bindingOptions)
|
||||
body(body)
|
||||
bodyDetails(host.eventDetailsFormatter.format(state.timelineEvent()?.root))
|
||||
body(body.toEpoxyCharSequence())
|
||||
bodyDetails(host.eventDetailsFormatter.format(state.timelineEvent()?.root)?.toEpoxyCharSequence())
|
||||
time(formattedDate)
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import com.airbnb.mvrx.Success
|
|||
import im.vector.app.R
|
||||
import im.vector.app.core.date.DateFormatKind
|
||||
import im.vector.app.core.date.VectorDateFormatter
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.core.ui.list.genericFooterItem
|
||||
|
@ -75,7 +76,7 @@ class ViewEditHistoryEpoxyController @Inject constructor(
|
|||
if (sourceEvents.isEmpty()) {
|
||||
genericItem {
|
||||
id("footer")
|
||||
title(host.stringProvider.getString(R.string.no_message_edits_found))
|
||||
title(host.stringProvider.getString(R.string.no_message_edits_found).toEpoxyCharSequence())
|
||||
}
|
||||
} else {
|
||||
var lastDate: Calendar? = null
|
||||
|
@ -133,8 +134,8 @@ class ViewEditHistoryEpoxyController @Inject constructor(
|
|||
}
|
||||
genericItem {
|
||||
id(timelineEvent.eventId)
|
||||
title(host.dateFormatter.format(timelineEvent.originServerTs, DateFormatKind.EDIT_HISTORY_ROW))
|
||||
description(spannedDiff ?: body)
|
||||
title(host.dateFormatter.format(timelineEvent.originServerTs, DateFormatKind.EDIT_HISTORY_ROW).toEpoxyCharSequence())
|
||||
description((spannedDiff ?: body).toEpoxyCharSequence())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package im.vector.app.features.home.room.detail.timeline.factory
|
|||
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.DrawableProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
|
@ -110,7 +111,7 @@ class EncryptedItemFactory @Inject constructor(private val messageInformationDat
|
|||
.leftGuideline(avatarSizeProvider.leftGuideline)
|
||||
.highlighted(params.isHighlighted)
|
||||
.attributes(attributes)
|
||||
.message(spannableStr)
|
||||
.message(spannableStr.toEpoxyCharSequence())
|
||||
.movementMethod(createLinkMovementMethod(params.callback))
|
||||
}
|
||||
else -> null
|
||||
|
|
|
@ -28,6 +28,7 @@ import dagger.Lazy
|
|||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.ClickListener
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.files.LocalFilesHelper
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
|
@ -501,14 +502,14 @@ class MessageItemFactory @Inject constructor(
|
|||
val bindingOptions = spanUtils.getBindingOptions(body)
|
||||
val linkifiedBody = body.linkify(callback)
|
||||
|
||||
return MessageTextItem_().apply {
|
||||
if (informationData.hasBeenEdited) {
|
||||
val spannable = annotateWithEdited(linkifiedBody, callback, informationData)
|
||||
message(spannable)
|
||||
} else {
|
||||
message(linkifiedBody)
|
||||
}
|
||||
}
|
||||
return MessageTextItem_()
|
||||
.message(
|
||||
if (informationData.hasBeenEdited) {
|
||||
annotateWithEdited(linkifiedBody, callback, informationData)
|
||||
} else {
|
||||
linkifiedBody
|
||||
}.toEpoxyCharSequence()
|
||||
)
|
||||
.useBigFont(linkifiedBody.length <= MAX_NUMBER_OF_EMOJI_FOR_BIG_FONT * 2 && containsOnlyEmojis(linkifiedBody.toString()))
|
||||
.bindingOptions(bindingOptions)
|
||||
.searchForPills(isFormatted)
|
||||
|
@ -530,13 +531,13 @@ class MessageItemFactory @Inject constructor(
|
|||
.apply {
|
||||
if (informationData.hasBeenEdited) {
|
||||
val spannable = annotateWithEdited("", callback, informationData)
|
||||
editedSpan(spannable)
|
||||
editedSpan(spannable.toEpoxyCharSequence())
|
||||
}
|
||||
}
|
||||
.leftGuideline(avatarSizeProvider.leftGuideline)
|
||||
.attributes(attributes)
|
||||
.highlighted(highlight)
|
||||
.message(formattedBody)
|
||||
.message(formattedBody.toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
private fun annotateWithEdited(linkifiedBody: CharSequence,
|
||||
|
@ -599,7 +600,7 @@ class MessageItemFactory @Inject constructor(
|
|||
.imageContentRenderer(imageContentRenderer)
|
||||
.previewUrlCallback(callback)
|
||||
.attributes(attributes)
|
||||
.message(message)
|
||||
.message(message.toEpoxyCharSequence())
|
||||
.bindingOptions(bindingOptions)
|
||||
.highlighted(highlight)
|
||||
.movementMethod(createLinkMovementMethod(callback))
|
||||
|
@ -617,14 +618,13 @@ class MessageItemFactory @Inject constructor(
|
|||
val message = formattedBody.linkify(callback)
|
||||
|
||||
return MessageTextItem_()
|
||||
.apply {
|
||||
if (informationData.hasBeenEdited) {
|
||||
val spannable = annotateWithEdited(message, callback, informationData)
|
||||
message(spannable)
|
||||
} else {
|
||||
message(message)
|
||||
}
|
||||
}
|
||||
.message(
|
||||
if (informationData.hasBeenEdited) {
|
||||
annotateWithEdited(message, callback, informationData)
|
||||
} else {
|
||||
message
|
||||
}.toEpoxyCharSequence()
|
||||
)
|
||||
.bindingOptions(bindingOptions)
|
||||
.leftGuideline(avatarSizeProvider.leftGuideline)
|
||||
.previewUrlRetriever(callback?.getPreviewUrlRetriever())
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package im.vector.app.features.home.room.detail.timeline.factory
|
||||
|
||||
import im.vector.app.core.epoxy.charsequence.EpoxyCharSequence
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
import im.vector.app.features.home.room.detail.timeline.format.NoticeEventFormatter
|
||||
import im.vector.app.features.home.room.detail.timeline.helper.AvatarSizeProvider
|
||||
|
@ -37,7 +38,7 @@ class NoticeItemFactory @Inject constructor(private val eventFormatter: NoticeEv
|
|||
val attributes = NoticeItem.Attributes(
|
||||
avatarRenderer = avatarRenderer,
|
||||
informationData = informationData,
|
||||
noticeText = formattedText,
|
||||
noticeText = EpoxyCharSequence(formattedText),
|
||||
itemLongClickListener = { view ->
|
||||
params.callback?.onEventLongClicked(informationData, null, view) ?: false
|
||||
},
|
||||
|
|
|
@ -18,6 +18,7 @@ package im.vector.app.features.home.room.detail.timeline.factory
|
|||
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.core.resources.UserPreferencesProvider
|
||||
import im.vector.app.features.home.room.detail.timeline.item.RoomCreateItem_
|
||||
|
@ -46,7 +47,7 @@ class RoomCreateItemFactory @Inject constructor(private val stringProvider: Stri
|
|||
}
|
||||
}
|
||||
return RoomCreateItem_()
|
||||
.text(text)
|
||||
.text(text.toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
private fun defaultRendering(params: TimelineItemFactoryParams): VectorEpoxyModel<*>? {
|
||||
|
|
|
@ -18,7 +18,5 @@ package im.vector.app.features.home.room.detail.timeline.item
|
|||
|
||||
data class BindingOptions(
|
||||
// Allowed by default
|
||||
val canUseTextFuture: Boolean = true,
|
||||
// No need to prevent mutation by default
|
||||
val preventMutation: Boolean = false
|
||||
val canUseTextFuture: Boolean = true
|
||||
)
|
||||
|
|
|
@ -26,7 +26,7 @@ import im.vector.app.core.epoxy.VectorEpoxyHolder
|
|||
@EpoxyModelClass(layout = R.layout.item_timeline_event_day_separator)
|
||||
abstract class DaySeparatorItem : EpoxyModelWithHolder<DaySeparatorItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute lateinit var formattedDay: CharSequence
|
||||
@EpoxyAttribute lateinit var formattedDay: String
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
|
|
|
@ -56,7 +56,7 @@ abstract class DefaultItem : BaseEventItem<DefaultItem.Holder>() {
|
|||
data class Attributes(
|
||||
val avatarRenderer: AvatarRenderer,
|
||||
val informationData: MessageInformationData,
|
||||
val text: CharSequence,
|
||||
val text: String,
|
||||
val itemLongClickListener: View.OnLongClickListener? = null
|
||||
)
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ import android.widget.TextView
|
|||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.EpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import me.saket.bettermovementmethod.BetterLinkMovementMethod
|
||||
|
@ -28,19 +29,19 @@ import me.saket.bettermovementmethod.BetterLinkMovementMethod
|
|||
abstract class MessageBlockCodeItem : AbsMessageItem<MessageBlockCodeItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
var message: CharSequence? = null
|
||||
var message: EpoxyCharSequence? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var editedSpan: CharSequence? = null
|
||||
var editedSpan: EpoxyCharSequence? = null
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
holder.messageView.text = message
|
||||
holder.messageView.text = message?.charSequence
|
||||
renderSendState(holder.messageView, holder.messageView)
|
||||
holder.messageView.onClick(attributes.itemClickListener)
|
||||
holder.messageView.setOnLongClickListener(attributes.itemLongClickListener)
|
||||
holder.editedView.movementMethod = BetterLinkMovementMethod.getInstance()
|
||||
holder.editedView.setTextOrHide(editedSpan)
|
||||
holder.editedView.setTextOrHide(editedSpan?.charSequence)
|
||||
}
|
||||
|
||||
override fun getViewType() = STUB_ID
|
||||
|
|
|
@ -34,7 +34,7 @@ import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStat
|
|||
abstract class MessageFileItem : AbsMessageItem<MessageFileItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
var filename: CharSequence = ""
|
||||
var filename: String = ""
|
||||
|
||||
@EpoxyAttribute
|
||||
var mxcUrl: String = ""
|
||||
|
|
|
@ -24,9 +24,9 @@ import androidx.core.widget.TextViewCompat
|
|||
import com.airbnb.epoxy.EpoxyAttribute
|
||||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.EpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.core.epoxy.onLongClickIgnoringLinks
|
||||
import im.vector.app.core.epoxy.util.preventMutation
|
||||
import im.vector.app.features.home.room.detail.timeline.TimelineEventController
|
||||
import im.vector.app.features.home.room.detail.timeline.tools.findPillsAndProcess
|
||||
import im.vector.app.features.home.room.detail.timeline.url.PreviewUrlRetriever
|
||||
|
@ -42,7 +42,7 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
|
|||
var searchForPills: Boolean = false
|
||||
|
||||
@EpoxyAttribute
|
||||
var message: CharSequence? = null
|
||||
var message: EpoxyCharSequence? = null
|
||||
|
||||
@EpoxyAttribute
|
||||
var bindingOptions: BindingOptions? = null
|
||||
|
@ -82,14 +82,14 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
|
|||
holder.messageView.textSize = 14F
|
||||
}
|
||||
if (searchForPills) {
|
||||
message?.findPillsAndProcess(coroutineScope) {
|
||||
message?.charSequence?.findPillsAndProcess(coroutineScope) {
|
||||
// mmm.. not sure this is so safe in regards to cell reuse
|
||||
it.bind(holder.messageView)
|
||||
}
|
||||
}
|
||||
val textFuture = if (bindingOptions?.canUseTextFuture.orFalse()) {
|
||||
PrecomputedTextCompat.getTextFuture(
|
||||
message ?: "",
|
||||
message?.charSequence ?: "",
|
||||
TextViewCompat.getTextMetricsParams(holder.messageView),
|
||||
null)
|
||||
} else {
|
||||
|
@ -104,11 +104,7 @@ abstract class MessageTextItem : AbsMessageItem<MessageTextItem.Holder>() {
|
|||
if (bindingOptions?.canUseTextFuture.orFalse()) {
|
||||
holder.messageView.setTextFuture(textFuture)
|
||||
} else {
|
||||
holder.messageView.text = if (bindingOptions?.preventMutation.orFalse()) {
|
||||
message.preventMutation()
|
||||
} else {
|
||||
message
|
||||
}
|
||||
holder.messageView.text = message?.charSequence
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ import com.airbnb.epoxy.EpoxyAttribute
|
|||
import com.airbnb.epoxy.EpoxyModelClass
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.ClickListener
|
||||
import im.vector.app.core.epoxy.charsequence.EpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.core.ui.views.ShieldImageView
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
|
@ -37,7 +38,7 @@ abstract class NoticeItem : BaseEventItem<NoticeItem.Holder>() {
|
|||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
holder.noticeTextView.text = attributes.noticeText
|
||||
holder.noticeTextView.text = attributes.noticeText.charSequence
|
||||
attributes.avatarRenderer.render(attributes.informationData.matrixItem, holder.avatarImageView)
|
||||
holder.view.setOnLongClickListener(attributes.itemLongClickListener)
|
||||
holder.avatarImageView.onClick(attributes.avatarClickListener)
|
||||
|
@ -74,7 +75,7 @@ abstract class NoticeItem : BaseEventItem<NoticeItem.Holder>() {
|
|||
data class Attributes(
|
||||
val avatarRenderer: AvatarRenderer,
|
||||
val informationData: MessageInformationData,
|
||||
val noticeText: CharSequence,
|
||||
val noticeText: EpoxyCharSequence,
|
||||
val itemLongClickListener: View.OnLongClickListener? = null,
|
||||
val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null,
|
||||
val avatarClickListener: ClickListener? = null
|
||||
|
|
|
@ -22,17 +22,18 @@ import com.airbnb.epoxy.EpoxyModelClass
|
|||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.app.core.epoxy.charsequence.EpoxyCharSequence
|
||||
import me.saket.bettermovementmethod.BetterLinkMovementMethod
|
||||
|
||||
@EpoxyModelClass(layout = R.layout.item_timeline_event_create)
|
||||
abstract class RoomCreateItem : VectorEpoxyModel<RoomCreateItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute lateinit var text: CharSequence
|
||||
@EpoxyAttribute lateinit var text: EpoxyCharSequence
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
holder.description.movementMethod = BetterLinkMovementMethod.getInstance()
|
||||
holder.description.text = text
|
||||
holder.description.text = text.charSequence
|
||||
}
|
||||
|
||||
class Holder : VectorEpoxyHolder() {
|
||||
|
|
|
@ -83,8 +83,8 @@ abstract class StatusTileTimelineItem : AbsBaseMessageItem<StatusTileTimelineIte
|
|||
*/
|
||||
data class Attributes(
|
||||
val shieldUIState: ShieldUIState,
|
||||
val title: CharSequence,
|
||||
val description: CharSequence,
|
||||
val title: String,
|
||||
val description: String,
|
||||
override val informationData: MessageInformationData,
|
||||
override val avatarRenderer: AvatarRenderer,
|
||||
override val messageColorProvider: MessageColorProvider,
|
||||
|
|
|
@ -73,7 +73,7 @@ abstract class WidgetTileTimelineItem : AbsBaseMessageItem<WidgetTileTimelineIte
|
|||
* This class holds all the common attributes for timeline items.
|
||||
*/
|
||||
data class Attributes(
|
||||
val title: CharSequence,
|
||||
val title: String,
|
||||
@DrawableRes
|
||||
val drawableStart: Int,
|
||||
override val informationData: MessageInformationData,
|
||||
|
|
|
@ -24,8 +24,8 @@ import com.airbnb.epoxy.EpoxyModelWithHolder
|
|||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.ClickListener
|
||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.app.core.epoxy.charsequence.EpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.core.epoxy.util.preventMutation
|
||||
|
||||
/**
|
||||
* Item displaying an emoji reaction (single line with emoji, author, time)
|
||||
|
@ -34,20 +34,20 @@ import im.vector.app.core.epoxy.util.preventMutation
|
|||
abstract class ReactionInfoSimpleItem : EpoxyModelWithHolder<ReactionInfoSimpleItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute
|
||||
lateinit var reactionKey: CharSequence
|
||||
lateinit var reactionKey: EpoxyCharSequence
|
||||
|
||||
@EpoxyAttribute
|
||||
lateinit var authorDisplayName: CharSequence
|
||||
lateinit var authorDisplayName: String
|
||||
|
||||
@EpoxyAttribute
|
||||
var timeStamp: CharSequence? = null
|
||||
var timeStamp: String? = null
|
||||
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash)
|
||||
var userClicked: ClickListener? = null
|
||||
|
||||
override fun bind(holder: Holder) {
|
||||
super.bind(holder)
|
||||
holder.emojiReactionView.text = reactionKey.preventMutation()
|
||||
holder.emojiReactionView.text = reactionKey.charSequence
|
||||
holder.displayNameView.text = authorDisplayName
|
||||
timeStamp?.let {
|
||||
holder.timeStampView.text = it
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.airbnb.mvrx.Incomplete
|
|||
import com.airbnb.mvrx.Success
|
||||
import im.vector.app.EmojiSpanify
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.core.ui.list.genericFooterItem
|
||||
import im.vector.app.core.ui.list.genericLoaderItem
|
||||
|
@ -56,7 +57,7 @@ class ViewReactionsEpoxyController @Inject constructor(
|
|||
reactionInfoSimpleItem {
|
||||
id(reactionInfo.eventId)
|
||||
timeStamp(reactionInfo.timestamp)
|
||||
reactionKey(host.emojiSpanify.spanify(reactionInfo.reactionKey))
|
||||
reactionKey(host.emojiSpanify.spanify(reactionInfo.reactionKey).toEpoxyCharSequence())
|
||||
authorDisplayName(reactionInfo.authorName ?: reactionInfo.authorId)
|
||||
userClicked { host.listener?.didSelectUser(reactionInfo.authorId) }
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ import im.vector.app.features.themes.ThemeUtils
|
|||
@EpoxyModelClass(layout = R.layout.item_room_category)
|
||||
abstract class RoomCategoryItem : VectorEpoxyModel<RoomCategoryItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute lateinit var title: CharSequence
|
||||
@EpoxyAttribute lateinit var title: String
|
||||
@EpoxyAttribute var expanded: Boolean = false
|
||||
@EpoxyAttribute var unreadNotificationCount: Int = 0
|
||||
@EpoxyAttribute var showHighlighted: Boolean = false
|
||||
|
|
|
@ -39,7 +39,7 @@ abstract class RoomInvitationItem : VectorEpoxyModel<RoomInvitationItem.Holder>(
|
|||
|
||||
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
|
||||
@EpoxyAttribute lateinit var matrixItem: MatrixItem
|
||||
@EpoxyAttribute var secondLine: CharSequence? = null
|
||||
@EpoxyAttribute var secondLine: String? = null
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var listener: ClickListener? = null
|
||||
@EpoxyAttribute lateinit var changeMembershipState: ChangeMembershipState
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var acceptListener: ClickListener? = null
|
||||
|
|
|
@ -30,6 +30,7 @@ import im.vector.app.R
|
|||
import im.vector.app.core.epoxy.ClickListener
|
||||
import im.vector.app.core.epoxy.VectorEpoxyHolder
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.app.core.epoxy.charsequence.EpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.onClick
|
||||
import im.vector.app.core.extensions.setTextOrHide
|
||||
import im.vector.app.core.ui.views.PresenceStateImageView
|
||||
|
@ -44,16 +45,12 @@ import org.matrix.android.sdk.api.util.MatrixItem
|
|||
@EpoxyModelClass(layout = R.layout.item_room)
|
||||
abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute lateinit var typingMessage: CharSequence
|
||||
@EpoxyAttribute lateinit var typingMessage: String
|
||||
@EpoxyAttribute lateinit var avatarRenderer: AvatarRenderer
|
||||
@EpoxyAttribute lateinit var matrixItem: MatrixItem
|
||||
|
||||
// Used only for diff calculation
|
||||
@EpoxyAttribute lateinit var lastEvent: String
|
||||
|
||||
// We use DoNotHash here as Spans are not implementing equals/hashcode
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) lateinit var lastFormattedEvent: CharSequence
|
||||
@EpoxyAttribute lateinit var lastEventTime: CharSequence
|
||||
@EpoxyAttribute lateinit var lastFormattedEvent: EpoxyCharSequence
|
||||
@EpoxyAttribute lateinit var lastEventTime: String
|
||||
@EpoxyAttribute var encryptionTrustLevel: RoomEncryptionTrustLevel? = null
|
||||
@EpoxyAttribute var userPresence: UserPresence? = null
|
||||
@EpoxyAttribute var showPresence: Boolean = false
|
||||
|
@ -76,7 +73,7 @@ abstract class RoomSummaryItem : VectorEpoxyModel<RoomSummaryItem.Holder>() {
|
|||
}
|
||||
holder.titleView.text = matrixItem.getBestName()
|
||||
holder.lastEventTimeView.text = lastEventTime
|
||||
holder.lastEventView.text = lastFormattedEvent
|
||||
holder.lastEventView.text = lastFormattedEvent.charSequence
|
||||
holder.unreadCounterBadgeView.render(UnreadCounterBadgeView.State(unreadNotificationCount, showHighlighted))
|
||||
holder.unreadIndentIndicator.isVisible = hasUnreadMessage
|
||||
holder.draftView.isVisible = hasDraft
|
||||
|
|
|
@ -23,6 +23,7 @@ import im.vector.app.R
|
|||
import im.vector.app.core.date.DateFormatKind
|
||||
import im.vector.app.core.date.VectorDateFormatter
|
||||
import im.vector.app.core.epoxy.VectorEpoxyModel
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.error.ErrorFormatter
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
|
@ -111,7 +112,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
|
|||
val showHighlighted = roomSummary.highlightCount > 0
|
||||
val showSelected = selectedRoomIds.contains(roomSummary.roomId)
|
||||
var latestFormattedEvent: CharSequence = ""
|
||||
var latestEventTime: CharSequence = ""
|
||||
var latestEventTime = ""
|
||||
val latestEvent = roomSummary.latestPreviewableEvent
|
||||
if (latestEvent != null) {
|
||||
latestFormattedEvent = displayableEventFormatter.format(latestEvent, roomSummary.isDirect, roomSummary.isDirect.not())
|
||||
|
@ -129,8 +130,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
|
|||
.matrixItem(roomSummary.toMatrixItem())
|
||||
.lastEventTime(latestEventTime)
|
||||
.typingMessage(typingMessage)
|
||||
.lastEvent(latestFormattedEvent.toString())
|
||||
.lastFormattedEvent(latestFormattedEvent)
|
||||
.lastFormattedEvent(latestFormattedEvent.toEpoxyCharSequence())
|
||||
.showHighlighted(showHighlighted)
|
||||
.showSelected(showSelected)
|
||||
.hasFailedSending(roomSummary.hasFailedSending)
|
||||
|
|
|
@ -35,8 +35,7 @@ class SpanUtils @Inject constructor(
|
|||
}
|
||||
|
||||
return BindingOptions(
|
||||
canUseTextFuture = canUseTextFuture(emojiCharSequence),
|
||||
preventMutation = mustPreventMutation(emojiCharSequence)
|
||||
canUseTextFuture = canUseTextFuture(emojiCharSequence)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -49,11 +48,4 @@ class SpanUtils @Inject constructor(
|
|||
.getSpans(0, spanned.length, Any::class.java)
|
||||
.all { it !is StrikethroughSpan && it !is UnderlineSpan && it !is MetricAffectingSpan }
|
||||
}
|
||||
|
||||
// Workaround for setting text during binding which mutate the text itself
|
||||
private fun mustPreventMutation(spanned: Spanned): Boolean {
|
||||
return spanned
|
||||
.getSpans(0, spanned.length, Any::class.java)
|
||||
.any { it is MetricAffectingSpan }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import android.view.Gravity
|
|||
import android.view.inputmethod.EditorInfo
|
||||
import com.airbnb.epoxy.EpoxyController
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.core.ui.list.ItemStyle
|
||||
|
@ -49,7 +50,7 @@ class CreatePollController @Inject constructor(
|
|||
genericItem {
|
||||
id("question_title")
|
||||
style(ItemStyle.BIG_TEXT)
|
||||
title(host.stringProvider.getString(R.string.create_poll_question_title))
|
||||
title(host.stringProvider.getString(R.string.create_poll_question_title).toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
val questionImeAction = if (currentState.options.isEmpty()) EditorInfo.IME_ACTION_DONE else EditorInfo.IME_ACTION_NEXT
|
||||
|
@ -69,7 +70,7 @@ class CreatePollController @Inject constructor(
|
|||
genericItem {
|
||||
id("options_title")
|
||||
style(ItemStyle.BIG_TEXT)
|
||||
title(host.stringProvider.getString(R.string.create_poll_options_title))
|
||||
title(host.stringProvider.getString(R.string.create_poll_options_title).toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
currentState.options.forEachIndexed { index, option ->
|
||||
|
|
|
@ -20,6 +20,7 @@ import com.airbnb.epoxy.TypedEpoxyController
|
|||
import com.airbnb.mvrx.Fail
|
||||
import com.airbnb.mvrx.Loading
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.profiles.buildProfileAction
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.core.ui.list.genericPillItem
|
||||
|
@ -52,7 +53,7 @@ class CreateSubSpaceController @Inject constructor(
|
|||
id("beta")
|
||||
imageRes(R.drawable.ic_beta_pill)
|
||||
tintIcon(false)
|
||||
text(host.stringProvider.getString(R.string.space_add_space_to_any_space_you_manage))
|
||||
text(host.stringProvider.getString(R.string.space_add_space_to_any_space_you_manage).toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
formEditableSquareAvatarItem {
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.airbnb.mvrx.Loading
|
|||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.errorWithRetryItem
|
||||
import im.vector.app.core.epoxy.loadingItem
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
|
@ -40,7 +41,7 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
|
|||
private val colorProvider: ColorProvider,
|
||||
private val dimensionConverter: DimensionConverter,
|
||||
private val vectorPreferences: VectorPreferences) :
|
||||
TypedEpoxyController<DeviceListViewState>() {
|
||||
TypedEpoxyController<DeviceListViewState>() {
|
||||
|
||||
interface InteractionListener {
|
||||
fun onDeviceSelected(device: CryptoDeviceInfo)
|
||||
|
@ -75,11 +76,11 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
|
|||
style(ItemStyle.BIG_TEXT)
|
||||
titleIconResourceId(if (allGreen) R.drawable.ic_shield_trusted else R.drawable.ic_shield_warning)
|
||||
title(
|
||||
host.stringProvider.getString(
|
||||
if (allGreen) R.string.verification_profile_verified else R.string.verification_profile_warning
|
||||
)
|
||||
host.stringProvider
|
||||
.getString(if (allGreen) R.string.verification_profile_verified else R.string.verification_profile_warning)
|
||||
.toEpoxyCharSequence()
|
||||
)
|
||||
description(host.stringProvider.getString(R.string.verification_conclusion_ok_notice))
|
||||
description(host.stringProvider.getString(R.string.verification_conclusion_ok_notice).toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
if (vectorPreferences.developerMode()) {
|
||||
|
@ -90,7 +91,7 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
|
|||
genericItem {
|
||||
id("sessions")
|
||||
style(ItemStyle.BIG_TEXT)
|
||||
title(host.stringProvider.getString(R.string.room_member_profile_sessions_section_title))
|
||||
title(host.stringProvider.getString(R.string.room_member_profile_sessions_section_title).toEpoxyCharSequence())
|
||||
}
|
||||
if (deviceList.isEmpty()) {
|
||||
// Can this really happen?
|
||||
|
@ -105,7 +106,7 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
|
|||
id(device.deviceId)
|
||||
titleIconResourceId(if (device.isVerified) R.drawable.ic_shield_trusted else R.drawable.ic_shield_warning)
|
||||
apply {
|
||||
if (host.vectorPreferences.developerMode()) {
|
||||
val title = if (host.vectorPreferences.developerMode()) {
|
||||
val seq = span {
|
||||
+(device.displayName() ?: device.deviceId)
|
||||
+"\n"
|
||||
|
@ -115,10 +116,11 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
|
|||
textSize = host.dimensionConverter.spToPx(14)
|
||||
}
|
||||
}
|
||||
title(seq)
|
||||
seq
|
||||
} else {
|
||||
title(device.displayName() ?: device.deviceId)
|
||||
device.displayName() ?: device.deviceId
|
||||
}
|
||||
title(title.toEpoxyCharSequence())
|
||||
}
|
||||
value(
|
||||
host.stringProvider.getString(
|
||||
|
@ -163,7 +165,7 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
|
|||
textColor = host.colorProvider.getColorFromAttribute(R.attr.vctr_content_secondary)
|
||||
textSize = host.dimensionConverter.spToPx(12)
|
||||
}
|
||||
}
|
||||
}.toEpoxyCharSequence()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -179,7 +181,7 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
|
|||
textColor = host.colorProvider.getColorFromAttribute(R.attr.vctr_content_secondary)
|
||||
textSize = host.dimensionConverter.spToPx(12)
|
||||
}
|
||||
}
|
||||
}.toEpoxyCharSequence()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -195,7 +197,7 @@ class DeviceListEpoxyController @Inject constructor(private val stringProvider:
|
|||
textColor = host.colorProvider.getColorFromAttribute(R.attr.vctr_content_secondary)
|
||||
textSize = host.dimensionConverter.spToPx(12)
|
||||
}
|
||||
}
|
||||
}.toEpoxyCharSequence()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package im.vector.app.features.roommemberprofile.devices
|
|||
|
||||
import com.airbnb.epoxy.TypedEpoxyController
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.core.ui.list.ItemStyle
|
||||
|
@ -52,9 +53,9 @@ class DeviceTrustInfoEpoxyController @Inject constructor(private val stringProvi
|
|||
style(ItemStyle.BIG_TEXT)
|
||||
titleIconResourceId(if (isVerified) R.drawable.ic_shield_trusted else R.drawable.ic_shield_warning)
|
||||
title(
|
||||
host.stringProvider.getString(
|
||||
if (isVerified) R.string.verification_profile_verified else R.string.verification_profile_warning
|
||||
)
|
||||
host.stringProvider
|
||||
.getString(if (isVerified) R.string.verification_profile_verified else R.string.verification_profile_warning)
|
||||
.toEpoxyCharSequence()
|
||||
)
|
||||
}
|
||||
genericFooterItem {
|
||||
|
@ -88,7 +89,7 @@ class DeviceTrustInfoEpoxyController @Inject constructor(private val stringProvi
|
|||
textColor = host.colorProvider.getColorFromAttribute(R.attr.vctr_content_secondary)
|
||||
textSize = host.dimensionConverter.spToPx(14)
|
||||
}
|
||||
}
|
||||
}.toEpoxyCharSequence()
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomJoinRules
|
|||
|
||||
class RoomJoinRuleRadioAction(
|
||||
val roomJoinRule: RoomJoinRules,
|
||||
title: CharSequence,
|
||||
title: String,
|
||||
description: String,
|
||||
isSelected: Boolean
|
||||
) : BottomSheetGenericRadioAction(
|
||||
|
|
|
@ -17,6 +17,7 @@ package im.vector.app.features.settings.crosssigning
|
|||
|
||||
import com.airbnb.epoxy.TypedEpoxyController
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.core.ui.list.genericButtonItem
|
||||
|
@ -47,7 +48,7 @@ class CrossSigningSettingsController @Inject constructor(
|
|||
genericItem {
|
||||
id("can")
|
||||
titleIconResourceId(R.drawable.ic_shield_trusted)
|
||||
title(host.stringProvider.getString(R.string.encryption_information_dg_xsigning_complete))
|
||||
title(host.stringProvider.getString(R.string.encryption_information_dg_xsigning_complete).toEpoxyCharSequence())
|
||||
}
|
||||
genericButtonItem {
|
||||
id("Reset")
|
||||
|
@ -61,7 +62,7 @@ class CrossSigningSettingsController @Inject constructor(
|
|||
genericItem {
|
||||
id("trusted")
|
||||
titleIconResourceId(R.drawable.ic_shield_custom)
|
||||
title(host.stringProvider.getString(R.string.encryption_information_dg_xsigning_trusted))
|
||||
title(host.stringProvider.getString(R.string.encryption_information_dg_xsigning_trusted).toEpoxyCharSequence())
|
||||
}
|
||||
genericButtonItem {
|
||||
id("Reset")
|
||||
|
@ -75,7 +76,7 @@ class CrossSigningSettingsController @Inject constructor(
|
|||
genericItem {
|
||||
id("enable")
|
||||
titleIconResourceId(R.drawable.ic_shield_black)
|
||||
title(host.stringProvider.getString(R.string.encryption_information_dg_xsigning_not_trusted))
|
||||
title(host.stringProvider.getString(R.string.encryption_information_dg_xsigning_not_trusted).toEpoxyCharSequence())
|
||||
}
|
||||
genericButtonItem {
|
||||
id("Reset")
|
||||
|
@ -88,7 +89,7 @@ class CrossSigningSettingsController @Inject constructor(
|
|||
else -> {
|
||||
genericItem {
|
||||
id("not")
|
||||
title(host.stringProvider.getString(R.string.encryption_information_dg_xsigning_disabled))
|
||||
title(host.stringProvider.getString(R.string.encryption_information_dg_xsigning_disabled).toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
genericPositiveButtonItem {
|
||||
|
@ -115,7 +116,7 @@ class CrossSigningSettingsController @Inject constructor(
|
|||
textColor = host.colorProvider.getColorFromAttribute(R.attr.vctr_content_secondary)
|
||||
textSize = host.dimensionConverter.spToPx(12)
|
||||
}
|
||||
}
|
||||
}.toEpoxyCharSequence()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +132,7 @@ class CrossSigningSettingsController @Inject constructor(
|
|||
textColor = host.colorProvider.getColorFromAttribute(R.attr.vctr_content_secondary)
|
||||
textSize = host.dimensionConverter.spToPx(12)
|
||||
}
|
||||
}
|
||||
}.toEpoxyCharSequence()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +148,7 @@ class CrossSigningSettingsController @Inject constructor(
|
|||
textColor = host.colorProvider.getColorFromAttribute(R.attr.vctr_content_secondary)
|
||||
textSize = host.dimensionConverter.spToPx(12)
|
||||
}
|
||||
}
|
||||
}.toEpoxyCharSequence()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package im.vector.app.features.settings.devices
|
|||
import com.airbnb.epoxy.TypedEpoxyController
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.bottomSheetDividerItem
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.loadingItem
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
|
@ -34,7 +35,7 @@ import javax.inject.Inject
|
|||
class DeviceVerificationInfoBottomSheetController @Inject constructor(
|
||||
private val stringProvider: StringProvider,
|
||||
private val colorProvider: ColorProvider) :
|
||||
TypedEpoxyController<DeviceVerificationInfoBottomSheetViewState>() {
|
||||
TypedEpoxyController<DeviceVerificationInfoBottomSheetViewState>() {
|
||||
|
||||
var callback: Callback? = null
|
||||
|
||||
|
@ -88,8 +89,8 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor(
|
|||
id("trust${cryptoDeviceInfo.deviceId}")
|
||||
style(ItemStyle.BIG_TEXT)
|
||||
titleIconResourceId(shield)
|
||||
title(host.stringProvider.getString(R.string.encryption_information_verified))
|
||||
description(host.stringProvider.getString(R.string.settings_active_sessions_verified_device_desc))
|
||||
title(host.stringProvider.getString(R.string.encryption_information_verified).toEpoxyCharSequence())
|
||||
description(host.stringProvider.getString(R.string.settings_active_sessions_verified_device_desc).toEpoxyCharSequence())
|
||||
}
|
||||
} else if (data.canVerifySession) {
|
||||
// You need to complete security, only if there are other session(s) available, or if 4S contains secrets
|
||||
|
@ -97,12 +98,11 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor(
|
|||
id("trust${cryptoDeviceInfo.deviceId}")
|
||||
style(ItemStyle.BIG_TEXT)
|
||||
titleIconResourceId(shield)
|
||||
title(host.stringProvider.getString(R.string.crosssigning_verify_this_session))
|
||||
if (data.hasOtherSessions) {
|
||||
description(host.stringProvider.getString(R.string.confirm_your_identity))
|
||||
} else {
|
||||
description(host.stringProvider.getString(R.string.confirm_your_identity_quad_s))
|
||||
}
|
||||
title(host.stringProvider.getString(R.string.crosssigning_verify_this_session).toEpoxyCharSequence())
|
||||
description(host.stringProvider
|
||||
.getString(if (data.hasOtherSessions) R.string.confirm_your_identity else R.string.confirm_your_identity_quad_s)
|
||||
.toEpoxyCharSequence()
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -117,16 +117,16 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor(
|
|||
id("trust${cryptoDeviceInfo.deviceId}")
|
||||
style(ItemStyle.BIG_TEXT)
|
||||
titleIconResourceId(shield)
|
||||
title(host.stringProvider.getString(R.string.encryption_information_verified))
|
||||
description(host.stringProvider.getString(R.string.settings_active_sessions_verified_device_desc))
|
||||
title(host.stringProvider.getString(R.string.encryption_information_verified).toEpoxyCharSequence())
|
||||
description(host.stringProvider.getString(R.string.settings_active_sessions_verified_device_desc).toEpoxyCharSequence())
|
||||
}
|
||||
} else {
|
||||
genericItem {
|
||||
id("trust${cryptoDeviceInfo.deviceId}")
|
||||
titleIconResourceId(shield)
|
||||
style(ItemStyle.BIG_TEXT)
|
||||
title(host.stringProvider.getString(R.string.encryption_information_not_verified))
|
||||
description(host.stringProvider.getString(R.string.settings_active_sessions_unverified_device_desc))
|
||||
title(host.stringProvider.getString(R.string.encryption_information_not_verified).toEpoxyCharSequence())
|
||||
description(host.stringProvider.getString(R.string.settings_active_sessions_unverified_device_desc).toEpoxyCharSequence())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -135,8 +135,8 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor(
|
|||
// DEVICE INFO SECTION
|
||||
genericItem {
|
||||
id("info${cryptoDeviceInfo.deviceId}")
|
||||
title(cryptoDeviceInfo.displayName() ?: "")
|
||||
description("(${cryptoDeviceInfo.deviceId})")
|
||||
title(cryptoDeviceInfo.displayName().orEmpty().toEpoxyCharSequence())
|
||||
description("(${cryptoDeviceInfo.deviceId})".toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
if (isMine && !currentSessionIsTrusted && data.canVerifySession) {
|
||||
|
@ -176,24 +176,24 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor(
|
|||
id("trust${cryptoDeviceInfo.deviceId}")
|
||||
style(ItemStyle.BIG_TEXT)
|
||||
titleIconResourceId(shield)
|
||||
title(host.stringProvider.getString(R.string.encryption_information_verified))
|
||||
description(host.stringProvider.getString(R.string.settings_active_sessions_verified_device_desc))
|
||||
title(host.stringProvider.getString(R.string.encryption_information_verified).toEpoxyCharSequence())
|
||||
description(host.stringProvider.getString(R.string.settings_active_sessions_verified_device_desc).toEpoxyCharSequence())
|
||||
}
|
||||
} else {
|
||||
genericItem {
|
||||
id("trust${cryptoDeviceInfo.deviceId}")
|
||||
titleIconResourceId(shield)
|
||||
style(ItemStyle.BIG_TEXT)
|
||||
title(host.stringProvider.getString(R.string.encryption_information_not_verified))
|
||||
description(host.stringProvider.getString(R.string.settings_active_sessions_unverified_device_desc))
|
||||
title(host.stringProvider.getString(R.string.encryption_information_not_verified).toEpoxyCharSequence())
|
||||
description(host.stringProvider.getString(R.string.settings_active_sessions_unverified_device_desc).toEpoxyCharSequence())
|
||||
}
|
||||
}
|
||||
|
||||
// DEVICE INFO SECTION
|
||||
genericItem {
|
||||
id("info${cryptoDeviceInfo.deviceId}")
|
||||
title(cryptoDeviceInfo.displayName() ?: "")
|
||||
description("(${cryptoDeviceInfo.deviceId})")
|
||||
title(cryptoDeviceInfo.displayName().orEmpty().toEpoxyCharSequence())
|
||||
description("(${cryptoDeviceInfo.deviceId})".toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
// ACTIONS
|
||||
|
@ -287,8 +287,8 @@ class DeviceVerificationInfoBottomSheetController @Inject constructor(
|
|||
val info = data.deviceInfo.invoke() ?: return
|
||||
genericItem {
|
||||
id("info${info.deviceId}")
|
||||
title(info.displayName ?: "")
|
||||
description("(${info.deviceId})")
|
||||
title(info.displayName.orEmpty().toEpoxyCharSequence())
|
||||
description("(${info.deviceId})".toEpoxyCharSequence())
|
||||
}
|
||||
|
||||
genericFooterItem {
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.airbnb.mvrx.Fail
|
|||
import com.airbnb.mvrx.Loading
|
||||
import com.airbnb.mvrx.Success
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.loadingItem
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.core.ui.list.genericFooterItem
|
||||
|
@ -67,7 +68,7 @@ class AccountDataEpoxyController @Inject constructor(
|
|||
dataList.forEach { accountData ->
|
||||
genericWithValueItem {
|
||||
id(accountData.type)
|
||||
title(accountData.type)
|
||||
title(accountData.type.toEpoxyCharSequence())
|
||||
itemClickAction {
|
||||
host.interactionListener?.didTap(accountData)
|
||||
}
|
||||
|
|
|
@ -21,8 +21,8 @@ import com.airbnb.epoxy.paging.PagedListEpoxyController
|
|||
import im.vector.app.R
|
||||
import im.vector.app.core.date.DateFormatKind
|
||||
import im.vector.app.core.date.VectorDateFormatter
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.core.ui.list.GenericItem_
|
||||
import im.vector.app.core.utils.createUIHandler
|
||||
import me.gujun.android.span.span
|
||||
|
@ -38,7 +38,6 @@ import org.matrix.android.sdk.internal.crypto.model.rest.SecretShareRequest
|
|||
import javax.inject.Inject
|
||||
|
||||
class GossipingTrailPagedEpoxyController @Inject constructor(
|
||||
private val stringProvider: StringProvider,
|
||||
private val vectorDateFormatter: VectorDateFormatter,
|
||||
private val colorProvider: ColorProvider
|
||||
) : PagedListEpoxyController<Event>(
|
||||
|
@ -63,7 +62,7 @@ class GossipingTrailPagedEpoxyController @Inject constructor(
|
|||
"${event.getClearType()} [encrypted]"
|
||||
} else {
|
||||
event.type
|
||||
}
|
||||
}?.toEpoxyCharSequence()
|
||||
)
|
||||
description(
|
||||
span {
|
||||
|
@ -157,11 +156,11 @@ class GossipingTrailPagedEpoxyController @Inject constructor(
|
|||
+"${content?.requestingDeviceId}"
|
||||
} else if (event.getClearType() == EventType.ENCRYPTED) {
|
||||
span("**Failed to Decrypt** ${event.mCryptoError}") {
|
||||
textColor = host.colorProvider.getColorFromAttribute(R.attr.colorError)
|
||||
}
|
||||
textColor = host.colorProvider.getColorFromAttribute(R.attr.colorError)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.toEpoxyCharSequence()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import com.airbnb.epoxy.EpoxyModel
|
|||
import com.airbnb.epoxy.paging.PagedListEpoxyController
|
||||
import im.vector.app.core.date.DateFormatKind
|
||||
import im.vector.app.core.date.VectorDateFormatter
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.ui.list.GenericItem_
|
||||
import im.vector.app.core.utils.createUIHandler
|
||||
import me.gujun.android.span.span
|
||||
|
@ -45,7 +46,7 @@ class IncomingKeyRequestPagedController @Inject constructor(
|
|||
|
||||
return GenericItem_().apply {
|
||||
id(roomKeyRequest.requestId)
|
||||
title(roomKeyRequest.requestId)
|
||||
title(roomKeyRequest.requestId?.toEpoxyCharSequence())
|
||||
description(
|
||||
span {
|
||||
span("From: ") {
|
||||
|
@ -65,7 +66,7 @@ class IncomingKeyRequestPagedController @Inject constructor(
|
|||
textStyle = "bold"
|
||||
}
|
||||
+roomKeyRequest.state.name
|
||||
}
|
||||
}.toEpoxyCharSequence()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package im.vector.app.features.settings.devtools
|
|||
|
||||
import com.airbnb.epoxy.EpoxyModel
|
||||
import com.airbnb.epoxy.paging.PagedListEpoxyController
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.ui.list.GenericItem_
|
||||
import im.vector.app.core.utils.createUIHandler
|
||||
import me.gujun.android.span.span
|
||||
|
@ -40,7 +41,7 @@ class OutgoingKeyRequestPagedController @Inject constructor() : PagedListEpoxyCo
|
|||
|
||||
return GenericItem_().apply {
|
||||
id(roomKeyRequest.requestId)
|
||||
title(roomKeyRequest.requestId)
|
||||
title(roomKeyRequest.requestId.toEpoxyCharSequence())
|
||||
description(
|
||||
span {
|
||||
span("roomId: ") {
|
||||
|
@ -56,7 +57,7 @@ class OutgoingKeyRequestPagedController @Inject constructor() : PagedListEpoxyCo
|
|||
textStyle = "bold"
|
||||
}
|
||||
+roomKeyRequest.state.name
|
||||
}
|
||||
}.toEpoxyCharSequence()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.airbnb.mvrx.Loading
|
|||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.errorWithRetryItem
|
||||
import im.vector.app.core.epoxy.loadingItem
|
||||
import im.vector.app.core.error.ErrorFormatter
|
||||
|
@ -143,14 +144,14 @@ class HomeserverSettingsController @Inject constructor(
|
|||
|
||||
genericWithValueItem {
|
||||
id("room_version_default")
|
||||
title(host.stringProvider.getString(R.string.settings_server_default_room_version))
|
||||
title(host.stringProvider.getString(R.string.settings_server_default_room_version).toEpoxyCharSequence())
|
||||
value(roomCapabilities.defaultRoomVersion)
|
||||
}
|
||||
|
||||
roomCapabilities.supportedVersion.forEach {
|
||||
genericWithValueItem {
|
||||
id("room_version_${it.version}")
|
||||
title(it.version)
|
||||
title(it.version.toEpoxyCharSequence())
|
||||
value(
|
||||
host.stringProvider.getString(
|
||||
when (it.status) {
|
||||
|
|
|
@ -20,6 +20,7 @@ import android.text.InputType
|
|||
import com.airbnb.epoxy.TypedEpoxyController
|
||||
import com.google.android.material.textfield.TextInputLayout
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.resources.ColorProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.core.ui.list.ItemStyle
|
||||
|
@ -57,7 +58,7 @@ class SpaceAdd3pidEpoxyController @Inject constructor(
|
|||
genericPillItem {
|
||||
id("no_IDS")
|
||||
imageRes(R.drawable.ic_baseline_perm_contact_calendar_24)
|
||||
text(host.stringProvider.getString(R.string.create_space_identity_server_info_none))
|
||||
text(host.stringProvider.getString(R.string.create_space_identity_server_info_none).toEpoxyCharSequence())
|
||||
}
|
||||
genericButtonItem {
|
||||
id("Discover_Settings")
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.airbnb.mvrx.Incomplete
|
|||
import com.airbnb.mvrx.Uninitialized
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.ClickListener
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.errorWithRetryItem
|
||||
import im.vector.app.core.epoxy.loadingItem
|
||||
import im.vector.app.core.error.ErrorFormatter
|
||||
|
@ -87,7 +88,7 @@ class SpaceDirectoryController @Inject constructor(
|
|||
span(host.stringProvider.getString(R.string.spaces_no_server_support_description)) {
|
||||
textColor = host.colorProvider.getColorFromAttribute(R.attr.vctr_content_secondary)
|
||||
}
|
||||
}
|
||||
}.toEpoxyCharSequence()
|
||||
)
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -20,6 +20,7 @@ import androidx.recyclerview.widget.DiffUtil
|
|||
import com.airbnb.epoxy.EpoxyModel
|
||||
import com.airbnb.epoxy.paging.PagedListEpoxyController
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.ui.list.GenericPillItem_
|
||||
import im.vector.app.core.utils.createUIHandler
|
||||
import im.vector.app.features.home.AvatarRenderer
|
||||
|
@ -56,7 +57,7 @@ class AddRoomListController @Inject constructor(
|
|||
var listener: Listener? = null
|
||||
var ignoreRooms: List<String>? = null
|
||||
|
||||
var subHeaderText: CharSequence? = null
|
||||
var subHeaderText: String? = null
|
||||
|
||||
var initialLoadOccurred = false
|
||||
|
||||
|
@ -130,7 +131,7 @@ class AddRoomListController @Inject constructor(
|
|||
add(
|
||||
GenericPillItem_().apply {
|
||||
id("sub_header")
|
||||
text(host.subHeaderText)
|
||||
text(host.subHeaderText?.toEpoxyCharSequence())
|
||||
imageRes(R.drawable.ic_info)
|
||||
}
|
||||
)
|
||||
|
|
|
@ -18,6 +18,7 @@ package im.vector.app.features.spaces.people
|
|||
|
||||
import com.airbnb.epoxy.TypedEpoxyController
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.dividerItem
|
||||
import im.vector.app.core.epoxy.loadingItem
|
||||
import im.vector.app.core.epoxy.profiles.profileMatrixItemWithPowerLevel
|
||||
|
@ -128,7 +129,7 @@ class SpacePeopleListController @Inject constructor(
|
|||
span {
|
||||
+"\n"
|
||||
+host.stringProvider.getString(R.string.no_result_placeholder)
|
||||
}
|
||||
}.toEpoxyCharSequence()
|
||||
)
|
||||
description(
|
||||
span {
|
||||
|
@ -138,7 +139,7 @@ class SpacePeopleListController @Inject constructor(
|
|||
textColor = host.colorProvider.getColorFromAttribute(R.attr.colorPrimary)
|
||||
textStyle = "bold"
|
||||
}
|
||||
}
|
||||
}.toEpoxyCharSequence()
|
||||
)
|
||||
itemClickAction {
|
||||
host.listener?.onInviteToSpaceSelected()
|
||||
|
|
|
@ -31,7 +31,7 @@ import im.vector.app.core.extensions.setTextOrHide
|
|||
@EpoxyModelClass(layout = R.layout.item_contact_action)
|
||||
abstract class ActionItem : VectorEpoxyModel<ActionItem.Holder>() {
|
||||
|
||||
@EpoxyAttribute var title: CharSequence? = null
|
||||
@EpoxyAttribute var title: String? = null
|
||||
@EpoxyAttribute @DrawableRes var actionIconRes: Int? = null
|
||||
@EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var clickAction: ClickListener? = null
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.airbnb.mvrx.Loading
|
|||
import com.airbnb.mvrx.Success
|
||||
import com.airbnb.mvrx.Uninitialized
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.errorWithRetryItem
|
||||
import im.vector.app.core.epoxy.loadingItem
|
||||
import im.vector.app.core.epoxy.noResultItem
|
||||
|
@ -154,7 +155,7 @@ class UserListController @Inject constructor(private val session: Session,
|
|||
textStyle = "bold"
|
||||
textColor = host.colorProvider.getColorFromAttribute(R.attr.colorPrimary)
|
||||
}
|
||||
}
|
||||
}.toEpoxyCharSequence()
|
||||
)
|
||||
itemClickAction {
|
||||
host.callback?.giveIdentityServerConsent()
|
||||
|
@ -182,7 +183,7 @@ class UserListController @Inject constructor(private val session: Session,
|
|||
textStyle = "bold"
|
||||
textColor = host.colorProvider.getColorFromAttribute(R.attr.colorPrimary)
|
||||
}
|
||||
}
|
||||
}.toEpoxyCharSequence()
|
||||
)
|
||||
itemClickAction {
|
||||
host.callback?.onSetupDiscovery()
|
||||
|
|
Loading…
Reference in a new issue