commit
3c682430d9
|
@ -5,7 +5,7 @@ Features ✨:
|
|||
-
|
||||
|
||||
Improvements 🙌:
|
||||
-
|
||||
- Render events m.room.encryption and m.room.guest_access in the timeline
|
||||
|
||||
Other changes:
|
||||
-
|
||||
|
@ -17,7 +17,7 @@ Translations 🗣:
|
|||
-
|
||||
|
||||
Build 🧱:
|
||||
-
|
||||
- Change the way versionCode is computed (#827)
|
||||
|
||||
Changes in RiotX 0.12.0 (2020-01-09)
|
||||
===================================================
|
||||
|
|
|
@ -91,7 +91,8 @@ object EventType {
|
|||
STATE_ROOM_CANONICAL_ALIAS,
|
||||
STATE_ROOM_HISTORY_VISIBILITY,
|
||||
STATE_ROOM_RELATED_GROUPS,
|
||||
STATE_ROOM_PINNED_EVENT
|
||||
STATE_ROOM_PINNED_EVENT,
|
||||
STATE_ROOM_ENCRYPTION
|
||||
)
|
||||
|
||||
fun isStateEvent(type: String): Boolean {
|
||||
|
|
|
@ -28,17 +28,20 @@ fun roomMemberQueryParams(init: (RoomMemberQueryParams.Builder.() -> Unit) = {})
|
|||
*/
|
||||
data class RoomMemberQueryParams(
|
||||
val displayName: QueryStringValue,
|
||||
val memberships: List<Membership>
|
||||
val memberships: List<Membership>,
|
||||
val excludeSelf: Boolean
|
||||
) {
|
||||
|
||||
class Builder {
|
||||
|
||||
var displayName: QueryStringValue = QueryStringValue.IsNotEmpty
|
||||
var memberships: List<Membership> = Membership.all()
|
||||
var excludeSelf: Boolean = false
|
||||
|
||||
fun build() = RoomMemberQueryParams(
|
||||
displayName = displayName,
|
||||
memberships = memberships
|
||||
memberships = memberships,
|
||||
excludeSelf = excludeSelf
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright 2019 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.matrix.android.api.session.room.model
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
|
||||
/**
|
||||
* Class representing the EventType.STATE_ROOM_GUEST_ACCESS state event content
|
||||
* Ref: https://matrix.org/docs/spec/client_server/latest#m-room-guest-access
|
||||
*/
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class RoomGuestAccessContent(
|
||||
// Required. Whether guests can join the room. One of: ["can_join", "forbidden"]
|
||||
@Json(name = "guest_access") val guestAccess: GuestAccess? = null
|
||||
)
|
||||
|
||||
enum class GuestAccess(val value: String) {
|
||||
@Json(name = "can_join")
|
||||
CanJoin("can_join"),
|
||||
@Json(name = "forbidden")
|
||||
Forbidden("forbidden")
|
||||
}
|
|
@ -28,6 +28,8 @@ import im.vector.matrix.android.api.session.room.model.PowerLevels
|
|||
import im.vector.matrix.android.api.session.room.model.RoomDirectoryVisibility
|
||||
import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibility
|
||||
import im.vector.matrix.android.internal.auth.data.ThreePidMedium
|
||||
import im.vector.matrix.android.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* Parameter to create a room, with facilities functions to configure it
|
||||
|
@ -88,7 +90,7 @@ class CreateRoomParams {
|
|||
* A list of state events to set in the new room.
|
||||
* This allows the user to override the default state events set in the new room.
|
||||
* The expected format of the state events are an object with type, state_key and content keys set.
|
||||
* Takes precedence over events set by presets, but gets overriden by name and topic keys.
|
||||
* Takes precedence over events set by presets, but gets overridden by name and topic keys.
|
||||
*/
|
||||
@Json(name = "initial_state")
|
||||
var initialStates: MutableList<Event>? = null
|
||||
|
@ -120,12 +122,12 @@ class CreateRoomParams {
|
|||
*
|
||||
* @param algorithm the algorithm
|
||||
*/
|
||||
fun addCryptoAlgorithm(algorithm: String) {
|
||||
if (algorithm.isNotBlank()) {
|
||||
val contentMap = HashMap<String, String>()
|
||||
contentMap["algorithm"] = algorithm
|
||||
fun enableEncryptionWithAlgorithm(algorithm: String) {
|
||||
if (algorithm == MXCRYPTO_ALGORITHM_MEGOLM) {
|
||||
val contentMap = mapOf("algorithm" to algorithm)
|
||||
|
||||
val algoEvent = Event(type = EventType.STATE_ROOM_ENCRYPTION,
|
||||
val algoEvent = Event(
|
||||
type = EventType.STATE_ROOM_ENCRYPTION,
|
||||
stateKey = "",
|
||||
content = contentMap.toContent()
|
||||
)
|
||||
|
@ -135,6 +137,8 @@ class CreateRoomParams {
|
|||
} else {
|
||||
initialStates!!.add(algoEvent)
|
||||
}
|
||||
} else {
|
||||
Timber.e("Unsupported algorithm: $algorithm")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,13 +149,13 @@ class CreateRoomParams {
|
|||
*/
|
||||
fun setHistoryVisibility(historyVisibility: RoomHistoryVisibility?) {
|
||||
// Remove the existing value if any.
|
||||
initialStates?.removeAll { it.getClearType() == EventType.STATE_ROOM_HISTORY_VISIBILITY }
|
||||
initialStates?.removeAll { it.type == EventType.STATE_ROOM_HISTORY_VISIBILITY }
|
||||
|
||||
if (historyVisibility != null) {
|
||||
val contentMap = HashMap<String, RoomHistoryVisibility>()
|
||||
contentMap["history_visibility"] = historyVisibility
|
||||
val contentMap = mapOf("history_visibility" to historyVisibility)
|
||||
|
||||
val historyVisibilityEvent = Event(type = EventType.STATE_ROOM_HISTORY_VISIBILITY,
|
||||
val historyVisibilityEvent = Event(
|
||||
type = EventType.STATE_ROOM_HISTORY_VISIBILITY,
|
||||
stateKey = "",
|
||||
content = contentMap.toContent())
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import im.vector.matrix.android.api.util.Cancelable
|
|||
import im.vector.matrix.android.internal.database.mapper.asDomain
|
||||
import im.vector.matrix.android.internal.database.model.RoomMemberEntity
|
||||
import im.vector.matrix.android.internal.database.model.RoomMemberEntityFields
|
||||
import im.vector.matrix.android.internal.di.UserId
|
||||
import im.vector.matrix.android.internal.query.process
|
||||
import im.vector.matrix.android.internal.session.room.membership.joining.InviteTask
|
||||
import im.vector.matrix.android.internal.session.room.membership.joining.JoinRoomTask
|
||||
|
@ -39,13 +40,16 @@ import im.vector.matrix.android.internal.util.fetchCopied
|
|||
import io.realm.Realm
|
||||
import io.realm.RealmQuery
|
||||
|
||||
internal class DefaultMembershipService @AssistedInject constructor(@Assisted private val roomId: String,
|
||||
internal class DefaultMembershipService @AssistedInject constructor(
|
||||
@Assisted private val roomId: String,
|
||||
private val monarchy: Monarchy,
|
||||
private val taskExecutor: TaskExecutor,
|
||||
private val loadRoomMembersTask: LoadRoomMembersTask,
|
||||
private val inviteTask: InviteTask,
|
||||
private val joinTask: JoinRoomTask,
|
||||
private val leaveRoomTask: LeaveRoomTask
|
||||
private val leaveRoomTask: LeaveRoomTask,
|
||||
@UserId
|
||||
private val userId: String
|
||||
) : MembershipService {
|
||||
|
||||
@AssistedInject.Factory
|
||||
|
@ -95,6 +99,11 @@ internal class DefaultMembershipService @AssistedInject constructor(@Assisted pr
|
|||
return RoomMembers(realm, roomId).queryRoomMembersEvent()
|
||||
.process(RoomMemberEntityFields.MEMBERSHIP_STR, queryParams.memberships)
|
||||
.process(RoomMemberEntityFields.DISPLAY_NAME, queryParams.displayName)
|
||||
.apply {
|
||||
if (queryParams.excludeSelf) {
|
||||
notEqualTo(RoomMemberEntityFields.USER_ID, userId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getNumberOfJoinedMembers(): Int {
|
||||
|
|
|
@ -272,4 +272,7 @@
|
|||
<string name="notice_room_canonical_alias_set">"%1$s set the main address for this room to %2$s."</string>
|
||||
<string name="notice_room_canonical_alias_unset">"%1$s removed the main address for this room."</string>
|
||||
|
||||
<string name="notice_room_guest_access_can_join">"%1$s has allowed guests to join the room."</string>
|
||||
<string name="notice_room_guest_access_forbidden">"%1$s has prevented guests from joining the room."</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -24,12 +24,16 @@ static def getGitTimestamp() {
|
|||
}
|
||||
|
||||
static def generateVersionCodeFromTimestamp() {
|
||||
// It's unix timestamp divided by 10: It's incremented by one every 10 seconds.
|
||||
return (getGitTimestamp() / 10).toInteger()
|
||||
// It's unix timestamp, minus timestamp of October 3rd 2018 (first commit date) divided by 100: It's incremented by one every 100 seconds.
|
||||
// plus 20_000_000 for compatibility reason with the previous way the Version Code was computed
|
||||
// Note that the result will be multiplied by 10 when adding the digit for the arch
|
||||
return ((getGitTimestamp() - 1_538_524_800 ) / 100).toInteger() + 20_000_000
|
||||
}
|
||||
|
||||
def generateVersionCodeFromVersionName() {
|
||||
return versionMajor * 1_00_00 + versionMinor * 1_00 + versionPatch
|
||||
// plus 4_000_000 for compatibility reason with the previous way the Version Code was computed
|
||||
// Note that the result will be multiplied by 10 when adding the digit for the arch
|
||||
return (versionMajor * 1_00_00 + versionMinor * 1_00 + versionPatch) + 4_000_000
|
||||
}
|
||||
|
||||
def getVersionCode() {
|
||||
|
@ -77,8 +81,8 @@ project.android.buildTypes.all { buildType ->
|
|||
]
|
||||
}
|
||||
|
||||
// map for the version codes
|
||||
// x86 must have greater values than arm, see https://software.intel.com/en-us/android/articles/google-play-supports-cpu-architecture-filtering-for-multiple-apk
|
||||
// map for the version codes last digit
|
||||
// x86 must have greater values than arm
|
||||
// 64 bits have greater value than 32 bits
|
||||
ext.abiVersionCodes = ["armeabi-v7a": 1, "arm64-v8a": 2, "x86": 3, "x86_64": 4].withDefault { 0 }
|
||||
|
||||
|
@ -144,7 +148,7 @@ android {
|
|||
variant.outputs.each { output ->
|
||||
def baseAbiVersionCode = project.ext.abiVersionCodes.get(output.getFilter(OutputFile.ABI))
|
||||
// Known limitation: it does not modify the value in the BuildConfig.java generated file
|
||||
output.versionCodeOverride = baseAbiVersionCode * 10_000_000 + variant.versionCode
|
||||
output.versionCodeOverride = variant.versionCode * 10 + baseAbiVersionCode
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,14 +16,13 @@
|
|||
|
||||
package im.vector.riotx.core.error
|
||||
|
||||
import im.vector.riotx.BuildConfig
|
||||
import timber.log.Timber
|
||||
|
||||
/**
|
||||
* throw in debug, only log in production. As this method does not always throw, next statement should be a return
|
||||
*/
|
||||
fun fatalError(message: String) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
fun fatalError(message: String, failFast: Boolean) {
|
||||
if (failFast) {
|
||||
error(message)
|
||||
} else {
|
||||
Timber.e(message)
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package im.vector.riotx.core.rx
|
||||
|
||||
import im.vector.riotx.BuildConfig
|
||||
import im.vector.riotx.features.settings.VectorPreferences
|
||||
import io.reactivex.plugins.RxJavaPlugins
|
||||
import timber.log.Timber
|
||||
|
@ -33,8 +32,8 @@ class RxConfig @Inject constructor(
|
|||
RxJavaPlugins.setErrorHandler { throwable ->
|
||||
Timber.e(throwable, "RxError")
|
||||
|
||||
// Avoid crash in production
|
||||
if (BuildConfig.DEBUG || vectorPreferences.failFast()) {
|
||||
// Avoid crash in production, except if user wants it
|
||||
if (vectorPreferences.failFast()) {
|
||||
throw throwable
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,6 +63,7 @@ class AutocompleteMemberPresenter @AssistedInject constructor(context: Context,
|
|||
QueryStringValue.Contains(query.toString(), QueryStringValue.Case.INSENSITIVE)
|
||||
}
|
||||
memberships = listOf(Membership.JOIN)
|
||||
excludeSelf = true
|
||||
}
|
||||
val members = room.getRoomMembers(queryParams)
|
||||
.asSequence()
|
||||
|
|
|
@ -55,7 +55,6 @@ import im.vector.matrix.android.internal.crypto.attachments.toElementToDecrypt
|
|||
import im.vector.matrix.android.internal.crypto.model.event.EncryptedEventContent
|
||||
import im.vector.matrix.rx.rx
|
||||
import im.vector.matrix.rx.unwrap
|
||||
import im.vector.riotx.BuildConfig
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.extensions.postLiveEvent
|
||||
import im.vector.riotx.core.platform.VectorViewModel
|
||||
|
@ -308,7 +307,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
|
|||
fun isMenuItemVisible(@IdRes itemId: Int) = when (itemId) {
|
||||
R.id.clear_message_queue ->
|
||||
/* For now always disable on production, worker cancellation is not working properly */
|
||||
timeline.pendingEventCount() > 0 && BuildConfig.DEBUG
|
||||
timeline.pendingEventCount() > 0 && vectorPreferences.developerMode()
|
||||
R.id.resend_all -> timeline.failedToDeliverEventCount() > 0
|
||||
R.id.clear_all -> timeline.failedToDeliverEventCount() > 0
|
||||
else -> false
|
||||
|
|
|
@ -47,8 +47,8 @@ class DefaultItemFactory @Inject constructor(private val avatarSizeProvider: Ava
|
|||
fun create(event: TimelineEvent,
|
||||
highlight: Boolean,
|
||||
callback: TimelineEventController.Callback?,
|
||||
exception: Exception? = null): DefaultItem {
|
||||
val text = if (exception == null) {
|
||||
throwable: Throwable? = null): DefaultItem {
|
||||
val text = if (throwable == null) {
|
||||
"${event.root.getClearType()} events are not yet handled"
|
||||
} else {
|
||||
"an exception occurred when rendering the event ${event.root.eventId}"
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* Copyright 2019 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.riotx.features.home.room.detail.timeline.factory
|
||||
|
||||
import android.view.View
|
||||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.EventType
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||
import im.vector.matrix.android.internal.crypto.model.event.EncryptionEventContent
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.resources.StringProvider
|
||||
import im.vector.riotx.features.home.AvatarRenderer
|
||||
import im.vector.riotx.features.home.room.detail.timeline.TimelineEventController
|
||||
import im.vector.riotx.features.home.room.detail.timeline.helper.AvatarSizeProvider
|
||||
import im.vector.riotx.features.home.room.detail.timeline.item.MessageInformationData
|
||||
import im.vector.riotx.features.home.room.detail.timeline.item.NoticeItem
|
||||
import im.vector.riotx.features.home.room.detail.timeline.item.NoticeItem_
|
||||
import javax.inject.Inject
|
||||
|
||||
class EncryptionItemFactory @Inject constructor(private val stringProvider: StringProvider,
|
||||
private val avatarRenderer: AvatarRenderer,
|
||||
private val avatarSizeProvider: AvatarSizeProvider) {
|
||||
|
||||
fun create(event: TimelineEvent,
|
||||
highlight: Boolean,
|
||||
callback: TimelineEventController.Callback?): NoticeItem? {
|
||||
val text = buildNoticeText(event.root, event.getDisambiguatedDisplayName()) ?: return null
|
||||
val informationData = MessageInformationData(
|
||||
eventId = event.root.eventId ?: "?",
|
||||
senderId = event.root.senderId ?: "",
|
||||
sendState = event.root.sendState,
|
||||
avatarUrl = event.senderAvatar,
|
||||
memberName = event.getDisambiguatedDisplayName(),
|
||||
showInformation = false
|
||||
)
|
||||
val attributes = NoticeItem.Attributes(
|
||||
avatarRenderer = avatarRenderer,
|
||||
informationData = informationData,
|
||||
noticeText = text,
|
||||
itemLongClickListener = View.OnLongClickListener { view ->
|
||||
callback?.onEventLongClicked(informationData, null, view) ?: false
|
||||
},
|
||||
readReceiptsCallback = callback
|
||||
)
|
||||
return NoticeItem_()
|
||||
.leftGuideline(avatarSizeProvider.leftGuideline)
|
||||
.highlighted(highlight)
|
||||
.attributes(attributes)
|
||||
}
|
||||
|
||||
private fun buildNoticeText(event: Event, senderName: String?): CharSequence? {
|
||||
return when {
|
||||
EventType.STATE_ROOM_ENCRYPTION == event.getClearType() -> {
|
||||
val content = event.content.toModel<EncryptionEventContent>() ?: return null
|
||||
stringProvider.getString(R.string.notice_end_to_end, senderName, content.algorithm)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
|
@ -24,7 +24,8 @@ import im.vector.riotx.features.home.room.detail.timeline.TimelineEventControlle
|
|||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
class TimelineItemFactory @Inject constructor(private val messageItemFactory: MessageItemFactory,
|
||||
class TimelineItemFactory @Inject constructor(
|
||||
private val messageItemFactory: MessageItemFactory,
|
||||
private val encryptedItemFactory: EncryptedItemFactory,
|
||||
private val noticeItemFactory: NoticeItemFactory,
|
||||
private val defaultItemFactory: DefaultItemFactory,
|
||||
|
@ -49,6 +50,7 @@ class TimelineItemFactory @Inject constructor(private val messageItemFactory: Me
|
|||
EventType.STATE_ROOM_CANONICAL_ALIAS,
|
||||
EventType.STATE_ROOM_JOIN_RULES,
|
||||
EventType.STATE_ROOM_HISTORY_VISIBILITY,
|
||||
EventType.STATE_ROOM_GUEST_ACCESS,
|
||||
EventType.CALL_INVITE,
|
||||
EventType.CALL_HANGUP,
|
||||
EventType.CALL_ANSWER,
|
||||
|
@ -74,9 +76,9 @@ class TimelineItemFactory @Inject constructor(private val messageItemFactory: Me
|
|||
null
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "failed to create message item")
|
||||
defaultItemFactory.create(event, highlight, callback, e)
|
||||
} catch (throwable: Throwable) {
|
||||
Timber.e(throwable, "failed to create message item")
|
||||
defaultItemFactory.create(event, highlight, callback, throwable)
|
||||
}
|
||||
return (computedModel ?: EmptyItem_())
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import im.vector.matrix.android.api.session.events.model.toModel
|
|||
import im.vector.matrix.android.api.session.room.model.*
|
||||
import im.vector.matrix.android.api.session.room.model.call.CallInviteContent
|
||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||
import im.vector.matrix.android.internal.crypto.model.event.EncryptionEventContent
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.core.di.ActiveSessionHolder
|
||||
import im.vector.riotx.core.resources.StringProvider
|
||||
|
@ -40,6 +41,8 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active
|
|||
EventType.STATE_ROOM_ALIASES -> formatRoomAliasesEvent(timelineEvent.root, timelineEvent.getDisambiguatedDisplayName())
|
||||
EventType.STATE_ROOM_CANONICAL_ALIAS -> formatRoomCanonicalAliasEvent(timelineEvent.root, timelineEvent.getDisambiguatedDisplayName())
|
||||
EventType.STATE_ROOM_HISTORY_VISIBILITY -> formatRoomHistoryVisibilityEvent(timelineEvent.root, timelineEvent.getDisambiguatedDisplayName())
|
||||
EventType.STATE_ROOM_GUEST_ACCESS -> formatRoomGuestAccessEvent(timelineEvent.root, timelineEvent.getDisambiguatedDisplayName())
|
||||
EventType.STATE_ROOM_ENCRYPTION -> formatRoomEncryptionEvent(timelineEvent.root, timelineEvent.getDisambiguatedDisplayName())
|
||||
EventType.STATE_ROOM_TOMBSTONE -> formatRoomTombstoneEvent(timelineEvent.getDisambiguatedDisplayName())
|
||||
EventType.CALL_INVITE,
|
||||
EventType.CALL_HANGUP,
|
||||
|
@ -166,6 +169,20 @@ class NoticeEventFormatter @Inject constructor(private val sessionHolder: Active
|
|||
?: sp.getString(R.string.notice_room_canonical_alias_unset, senderName)
|
||||
}
|
||||
|
||||
private fun formatRoomGuestAccessEvent(event: Event, senderName: String?): String? {
|
||||
val eventContent: RoomGuestAccessContent? = event.getClearContent().toModel()
|
||||
return when (eventContent?.guestAccess) {
|
||||
GuestAccess.CanJoin -> sp.getString(R.string.notice_room_guest_access_can_join, senderName)
|
||||
GuestAccess.Forbidden -> sp.getString(R.string.notice_room_guest_access_forbidden, senderName)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun formatRoomEncryptionEvent(event: Event, senderName: String?): CharSequence? {
|
||||
val content = event.content.toModel<EncryptionEventContent>() ?: return null
|
||||
return sp.getString(R.string.notice_end_to_end, senderName, content.algorithm)
|
||||
}
|
||||
|
||||
private fun buildProfileNotice(event: Event, senderName: String?, eventContent: RoomMemberContent?, prevEventContent: RoomMemberContent?): String {
|
||||
val displayText = StringBuilder()
|
||||
// Check display name has been changed
|
||||
|
|
|
@ -35,6 +35,7 @@ object TimelineDisplayableEvents {
|
|||
EventType.CALL_ANSWER,
|
||||
EventType.ENCRYPTED,
|
||||
EventType.STATE_ROOM_ENCRYPTION,
|
||||
EventType.STATE_ROOM_GUEST_ACCESS,
|
||||
EventType.STATE_ROOM_THIRD_PARTY_INVITE,
|
||||
EventType.STICKER,
|
||||
EventType.STATE_ROOM_CREATE,
|
||||
|
|
|
@ -36,6 +36,7 @@ import im.vector.riotx.features.home.room.filtered.FilteredRoomsActivity
|
|||
import im.vector.riotx.features.roomdirectory.RoomDirectoryActivity
|
||||
import im.vector.riotx.features.roomdirectory.createroom.CreateRoomActivity
|
||||
import im.vector.riotx.features.roomdirectory.roompreview.RoomPreviewActivity
|
||||
import im.vector.riotx.features.settings.VectorPreferences
|
||||
import im.vector.riotx.features.settings.VectorSettingsActivity
|
||||
import im.vector.riotx.features.share.SharedData
|
||||
import timber.log.Timber
|
||||
|
@ -44,12 +45,13 @@ import javax.inject.Singleton
|
|||
|
||||
@Singleton
|
||||
class DefaultNavigator @Inject constructor(
|
||||
private val sessionHolder: ActiveSessionHolder
|
||||
private val sessionHolder: ActiveSessionHolder,
|
||||
private val vectorPreferences: VectorPreferences
|
||||
) : Navigator {
|
||||
|
||||
override fun openRoom(context: Context, roomId: String, eventId: String?, buildTask: Boolean) {
|
||||
if (sessionHolder.getSafeActiveSession()?.getRoom(roomId) == null) {
|
||||
fatalError("Trying to open an unknown room $roomId")
|
||||
fatalError("Trying to open an unknown room $roomId", vectorPreferences.failFast())
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import android.provider.MediaStore
|
|||
import androidx.core.content.edit
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.squareup.seismic.ShakeDetector
|
||||
import im.vector.riotx.BuildConfig
|
||||
import im.vector.riotx.R
|
||||
import im.vector.riotx.features.homeserver.ServerUrlsRepository
|
||||
import im.vector.riotx.features.themes.ThemeUtils
|
||||
|
@ -268,7 +269,7 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
|||
}
|
||||
|
||||
fun failFast(): Boolean {
|
||||
return developerMode() && defaultPrefs.getBoolean(SETTINGS_DEVELOPER_MODE_FAIL_FAST_PREFERENCE_KEY, false)
|
||||
return BuildConfig.DEBUG || (developerMode() && defaultPrefs.getBoolean(SETTINGS_DEVELOPER_MODE_FAIL_FAST_PREFERENCE_KEY, false))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue