mirror of
https://github.com/vector-im/element-android.git
synced 2024-11-16 02:05:06 +08:00
UTD pagination: clean up and add developer settings to enable complete history
This commit is contained in:
parent
0a0330a48c
commit
f0272fd283
@ -50,6 +50,7 @@ import im.vector.app.features.home.room.detail.timeline.item.ReadReceiptData
|
|||||||
import im.vector.app.features.home.room.detail.timeline.item.TimelineReadMarkerItem_
|
import im.vector.app.features.home.room.detail.timeline.item.TimelineReadMarkerItem_
|
||||||
import im.vector.app.features.media.ImageContentRenderer
|
import im.vector.app.features.media.ImageContentRenderer
|
||||||
import im.vector.app.features.media.VideoContentRenderer
|
import im.vector.app.features.media.VideoContentRenderer
|
||||||
|
import im.vector.app.features.settings.VectorPreferences
|
||||||
import org.matrix.android.sdk.api.session.Session
|
import org.matrix.android.sdk.api.session.Session
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
@ -64,6 +65,7 @@ import javax.inject.Inject
|
|||||||
private const val DEFAULT_PREFETCH_THRESHOLD = 30
|
private const val DEFAULT_PREFETCH_THRESHOLD = 30
|
||||||
|
|
||||||
class TimelineEventController @Inject constructor(private val dateFormatter: VectorDateFormatter,
|
class TimelineEventController @Inject constructor(private val dateFormatter: VectorDateFormatter,
|
||||||
|
private val vectorPreferences: VectorPreferences,
|
||||||
private val contentUploadStateTrackerBinder: ContentUploadStateTrackerBinder,
|
private val contentUploadStateTrackerBinder: ContentUploadStateTrackerBinder,
|
||||||
private val contentDownloadStateTrackerBinder: ContentDownloadStateTrackerBinder,
|
private val contentDownloadStateTrackerBinder: ContentDownloadStateTrackerBinder,
|
||||||
private val timelineItemFactory: TimelineItemFactory,
|
private val timelineItemFactory: TimelineItemFactory,
|
||||||
@ -394,6 +396,9 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun updateUTDStates(event: TimelineEvent, nextEvent: TimelineEvent?) {
|
private fun updateUTDStates(event: TimelineEvent, nextEvent: TimelineEvent?) {
|
||||||
|
if (vectorPreferences.labShowCompleteHistoryInEncryptedRoom()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
if (event.root.type == EventType.STATE_ROOM_MEMBER
|
if (event.root.type == EventType.STATE_ROOM_MEMBER
|
||||||
&& event.root.stateKey == session.myUserId) {
|
&& event.root.stateKey == session.myUserId) {
|
||||||
val content = event.root.content.toModel<RoomMemberContent>()
|
val content = event.root.content.toModel<RoomMemberContent>()
|
||||||
|
@ -31,9 +31,6 @@ import im.vector.app.features.home.room.detail.timeline.item.MergedMembershipEve
|
|||||||
import im.vector.app.features.home.room.detail.timeline.item.MergedMembershipEventsItem_
|
import im.vector.app.features.home.room.detail.timeline.item.MergedMembershipEventsItem_
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.MergedRoomCreationItem
|
import im.vector.app.features.home.room.detail.timeline.item.MergedRoomCreationItem
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.MergedRoomCreationItem_
|
import im.vector.app.features.home.room.detail.timeline.item.MergedRoomCreationItem_
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.MergedUTDItem
|
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.MergedUTDItem_
|
|
||||||
import im.vector.app.features.settings.VectorPreferences
|
|
||||||
import org.matrix.android.sdk.api.extensions.orFalse
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
import org.matrix.android.sdk.api.session.events.model.EventType
|
import org.matrix.android.sdk.api.session.events.model.EventType
|
||||||
import org.matrix.android.sdk.api.session.events.model.toModel
|
import org.matrix.android.sdk.api.session.events.model.toModel
|
||||||
@ -41,14 +38,12 @@ import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent
|
|||||||
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
|
||||||
import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
|
||||||
import org.matrix.android.sdk.internal.crypto.model.event.EncryptionEventContent
|
import org.matrix.android.sdk.internal.crypto.model.event.EncryptionEventContent
|
||||||
import timber.log.Timber
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class MergedHeaderItemFactory @Inject constructor(private val activeSessionHolder: ActiveSessionHolder,
|
class MergedHeaderItemFactory @Inject constructor(private val activeSessionHolder: ActiveSessionHolder,
|
||||||
private val avatarRenderer: AvatarRenderer,
|
private val avatarRenderer: AvatarRenderer,
|
||||||
private val avatarSizeProvider: AvatarSizeProvider,
|
private val avatarSizeProvider: AvatarSizeProvider,
|
||||||
private val roomSummaryHolder: RoomSummaryHolder,
|
private val roomSummaryHolder: RoomSummaryHolder) {
|
||||||
private val vectorPreferences: VectorPreferences) {
|
|
||||||
|
|
||||||
private val collapsedEventIds = linkedSetOf<Long>()
|
private val collapsedEventIds = linkedSetOf<Long>()
|
||||||
private val mergeItemCollapseStates = HashMap<Long, Boolean>()
|
private val mergeItemCollapseStates = HashMap<Long, Boolean>()
|
||||||
@ -66,10 +61,7 @@ class MergedHeaderItemFactory @Inject constructor(private val activeSessionHolde
|
|||||||
callback: TimelineEventController.Callback?,
|
callback: TimelineEventController.Callback?,
|
||||||
requestModelBuild: () -> Unit)
|
requestModelBuild: () -> Unit)
|
||||||
: BasedMergedItem<*>? {
|
: BasedMergedItem<*>? {
|
||||||
return if (shouldMergedAsCannotDecryptGroup(event, nextEvent)) {
|
return if (nextEvent?.root?.getClearType() == EventType.STATE_ROOM_CREATE
|
||||||
Timber.v("## MERGE: Candidate for merge, top event ${event.eventId}")
|
|
||||||
buildUTDMergedSummary(currentPosition, items, event, eventIdToHighlight, /*requestModelBuild,*/ callback)
|
|
||||||
} else if (nextEvent?.root?.getClearType() == EventType.STATE_ROOM_CREATE
|
|
||||||
&& event.isRoomConfiguration(nextEvent.root.getClearContent()?.toModel<RoomCreateContent>()?.creator)) {
|
&& event.isRoomConfiguration(nextEvent.root.getClearContent()?.toModel<RoomCreateContent>()?.creator)) {
|
||||||
// It's the first item before room.create
|
// It's the first item before room.create
|
||||||
// Collapse all room configuration events
|
// Collapse all room configuration events
|
||||||
@ -144,83 +136,6 @@ class MergedHeaderItemFactory @Inject constructor(private val activeSessionHolde
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Event should be UTD
|
|
||||||
// Next event should not
|
|
||||||
private fun shouldMergedAsCannotDecryptGroup(event: TimelineEvent, nextEvent: TimelineEvent?): Boolean {
|
|
||||||
if (!vectorPreferences.mergeUTDinTimeline()) return false
|
|
||||||
// if event is not UTD return false
|
|
||||||
if (!isEventUTD(event)) return false
|
|
||||||
// At this point event cannot be decrypted
|
|
||||||
// Let's check if older event is not UTD
|
|
||||||
return nextEvent == null || !isEventUTD(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isEventUTD(event: TimelineEvent): Boolean {
|
|
||||||
return event.root.getClearType() == EventType.ENCRYPTED && !event.root.isRedacted()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildUTDMergedSummary(currentPosition: Int,
|
|
||||||
items: List<TimelineEvent>,
|
|
||||||
event: TimelineEvent,
|
|
||||||
eventIdToHighlight: String?,
|
|
||||||
// requestModelBuild: () -> Unit,
|
|
||||||
callback: TimelineEventController.Callback?): MergedUTDItem_? {
|
|
||||||
Timber.v("## MERGE: buildUTDMergedSummary from position $currentPosition")
|
|
||||||
var prevEvent = items.prevOrNull(currentPosition)
|
|
||||||
var tmpPos = currentPosition - 1
|
|
||||||
val mergedEvents = ArrayList<TimelineEvent>().also { it.add(event) }
|
|
||||||
|
|
||||||
while (prevEvent != null && isEventUTD(prevEvent)) {
|
|
||||||
mergedEvents.add(prevEvent)
|
|
||||||
tmpPos--
|
|
||||||
prevEvent = if (tmpPos >= 0) items[tmpPos] else null
|
|
||||||
}
|
|
||||||
|
|
||||||
Timber.v("## MERGE: buildUTDMergedSummary merge group size ${mergedEvents.size}")
|
|
||||||
if (mergedEvents.size < 3) return null
|
|
||||||
|
|
||||||
var highlighted = false
|
|
||||||
val mergedData = ArrayList<BasedMergedItem.Data>(mergedEvents.size)
|
|
||||||
mergedEvents.reversed()
|
|
||||||
.forEach { mergedEvent ->
|
|
||||||
if (!highlighted && mergedEvent.root.eventId == eventIdToHighlight) {
|
|
||||||
highlighted = true
|
|
||||||
}
|
|
||||||
val senderAvatar = mergedEvent.senderInfo.avatarUrl
|
|
||||||
val senderName = mergedEvent.senderInfo.disambiguatedDisplayName
|
|
||||||
val data = BasedMergedItem.Data(
|
|
||||||
userId = mergedEvent.root.senderId ?: "",
|
|
||||||
avatarUrl = senderAvatar,
|
|
||||||
memberName = senderName,
|
|
||||||
localId = mergedEvent.localId,
|
|
||||||
eventId = mergedEvent.root.eventId ?: "",
|
|
||||||
isDirectRoom = isDirectRoom()
|
|
||||||
)
|
|
||||||
mergedData.add(data)
|
|
||||||
}
|
|
||||||
val mergedEventIds = mergedEvents.map { it.localId }
|
|
||||||
|
|
||||||
collapsedEventIds.addAll(mergedEventIds)
|
|
||||||
|
|
||||||
val mergeId = mergedEventIds.joinToString(separator = "_") { it.toString() }
|
|
||||||
|
|
||||||
val attributes = MergedUTDItem.Attributes(
|
|
||||||
isCollapsed = true,
|
|
||||||
mergeData = mergedData,
|
|
||||||
avatarRenderer = avatarRenderer,
|
|
||||||
onCollapsedStateChanged = {}
|
|
||||||
)
|
|
||||||
return MergedUTDItem_()
|
|
||||||
.id(mergeId)
|
|
||||||
.big(mergedEventIds.size > 5)
|
|
||||||
.leftGuideline(avatarSizeProvider.leftGuideline)
|
|
||||||
.highlighted(highlighted)
|
|
||||||
.attributes(attributes)
|
|
||||||
.also {
|
|
||||||
it.setOnVisibilityStateChanged(MergedTimelineEventVisibilityStateChangedListener(callback, mergedEvents))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun buildRoomCreationMergedSummary(currentPosition: Int,
|
private fun buildRoomCreationMergedSummary(currentPosition: Int,
|
||||||
items: List<TimelineEvent>,
|
items: List<TimelineEvent>,
|
||||||
event: TimelineEvent,
|
event: TimelineEvent,
|
||||||
|
@ -1,127 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (c) 2020 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.features.home.room.detail.timeline.item
|
|
||||||
|
|
||||||
import android.util.TypedValue
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.LinearLayout
|
|
||||||
import android.widget.RelativeLayout
|
|
||||||
import androidx.core.view.isVisible
|
|
||||||
import androidx.core.view.updateLayoutParams
|
|
||||||
import com.airbnb.epoxy.EpoxyAttribute
|
|
||||||
import com.airbnb.epoxy.EpoxyModelClass
|
|
||||||
import im.vector.app.R
|
|
||||||
import im.vector.app.features.home.AvatarRenderer
|
|
||||||
import im.vector.app.features.home.room.detail.timeline.TimelineEventController
|
|
||||||
|
|
||||||
@EpoxyModelClass(layout = R.layout.item_timeline_event_base_noinfo)
|
|
||||||
abstract class MergedUTDItem : BasedMergedItem<MergedUTDItem.Holder>() {
|
|
||||||
|
|
||||||
@EpoxyAttribute
|
|
||||||
override lateinit var attributes: Attributes
|
|
||||||
|
|
||||||
@EpoxyAttribute
|
|
||||||
var big: Boolean? = false
|
|
||||||
|
|
||||||
override fun getViewType() = STUB_ID
|
|
||||||
|
|
||||||
override fun bind(holder: Holder) {
|
|
||||||
super.bind(holder)
|
|
||||||
|
|
||||||
holder.mergedTile.updateLayoutParams<RelativeLayout.LayoutParams> {
|
|
||||||
this.marginEnd = leftGuideline
|
|
||||||
if (big == true) {
|
|
||||||
this.height = TypedValue.applyDimension(
|
|
||||||
TypedValue.COMPLEX_UNIT_DIP,
|
|
||||||
800f,
|
|
||||||
holder.view.context.resources.displayMetrics
|
|
||||||
).toInt()
|
|
||||||
} else {
|
|
||||||
this.height = LinearLayout.LayoutParams.WRAP_CONTENT
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (attributes.isCollapsed) {
|
|
||||||
// // Take the oldest data
|
|
||||||
// val data = distinctMergeData.lastOrNull()
|
|
||||||
//
|
|
||||||
// val summary = holder.expandView.resources.getString(R.string.room_created_summary_item,
|
|
||||||
// data?.memberName ?: data?.userId ?: "")
|
|
||||||
// holder.summaryView.text = summary
|
|
||||||
// holder.summaryView.visibility = View.VISIBLE
|
|
||||||
// holder.avatarView.visibility = View.VISIBLE
|
|
||||||
// if (data != null) {
|
|
||||||
// holder.avatarView.visibility = View.VISIBLE
|
|
||||||
// attributes.avatarRenderer.render(data.toMatrixItem(), holder.avatarView)
|
|
||||||
// } else {
|
|
||||||
// holder.avatarView.visibility = View.GONE
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (attributes.hasEncryptionEvent) {
|
|
||||||
// holder.encryptionTile.isVisible = true
|
|
||||||
// holder.encryptionTile.updateLayoutParams<RelativeLayout.LayoutParams> {
|
|
||||||
// this.marginEnd = leftGuideline
|
|
||||||
// }
|
|
||||||
// if (attributes.isEncryptionAlgorithmSecure) {
|
|
||||||
// holder.e2eTitleTextView.text = holder.expandView.resources.getString(R.string.encryption_enabled)
|
|
||||||
// holder.e2eTitleDescriptionView.text = holder.expandView.resources.getString(R.string.encryption_enabled_tile_description)
|
|
||||||
// holder.e2eTitleDescriptionView.textAlignment = View.TEXT_ALIGNMENT_CENTER
|
|
||||||
// holder.e2eTitleTextView.setCompoundDrawablesWithIntrinsicBounds(
|
|
||||||
// ContextCompat.getDrawable(holder.view.context, R.drawable.ic_shield_black),
|
|
||||||
// null, null, null
|
|
||||||
// )
|
|
||||||
// } else {
|
|
||||||
// holder.e2eTitleTextView.text = holder.expandView.resources.getString(R.string.encryption_not_enabled)
|
|
||||||
// holder.e2eTitleDescriptionView.text = holder.expandView.resources.getString(R.string.encryption_unknown_algorithm_tile_description)
|
|
||||||
// holder.e2eTitleTextView.setCompoundDrawablesWithIntrinsicBounds(
|
|
||||||
// ContextCompat.getDrawable(holder.view.context, R.drawable.ic_shield_warning),
|
|
||||||
// null, null, null
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// holder.encryptionTile.isVisible = false
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
// holder.avatarView.visibility = View.INVISIBLE
|
|
||||||
// holder.summaryView.visibility = View.GONE
|
|
||||||
// holder.encryptionTile.isGone = true
|
|
||||||
// }
|
|
||||||
// No read receipt for this item
|
|
||||||
holder.readReceiptsView.isVisible = false
|
|
||||||
}
|
|
||||||
|
|
||||||
class Holder : BasedMergedItem.Holder(STUB_ID) {
|
|
||||||
// val summaryView by bind<TextView>(R.id.itemNoticeTextView)
|
|
||||||
// val avatarView by bind<ImageView>(R.id.itemNoticeAvatarView)
|
|
||||||
val mergedTile by bind<ViewGroup>(R.id.mergedUTDTile)
|
|
||||||
//
|
|
||||||
// val e2eTitleTextView by bind<TextView>(R.id.itemVerificationDoneTitleTextView)
|
|
||||||
// val e2eTitleDescriptionView by bind<TextView>(R.id.itemVerificationDoneDetailTextView)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val STUB_ID = R.id.messageContentMergedUTDStub
|
|
||||||
}
|
|
||||||
|
|
||||||
data class Attributes(
|
|
||||||
override val isCollapsed: Boolean,
|
|
||||||
override val mergeData: List<Data>,
|
|
||||||
override val avatarRenderer: AvatarRenderer,
|
|
||||||
override val readReceiptsCallback: TimelineEventController.ReadReceiptsCallback? = null,
|
|
||||||
override val onCollapsedStateChanged: (Boolean) -> Unit
|
|
||||||
) : BasedMergedItem.Attributes
|
|
||||||
}
|
|
@ -153,7 +153,7 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
|||||||
private const val SETTINGS_DEVELOPER_MODE_FAIL_FAST_PREFERENCE_KEY = "SETTINGS_DEVELOPER_MODE_FAIL_FAST_PREFERENCE_KEY"
|
private const val SETTINGS_DEVELOPER_MODE_FAIL_FAST_PREFERENCE_KEY = "SETTINGS_DEVELOPER_MODE_FAIL_FAST_PREFERENCE_KEY"
|
||||||
|
|
||||||
// SETTINGS_LABS_HIDE_TECHNICAL_E2E_ERRORS
|
// SETTINGS_LABS_HIDE_TECHNICAL_E2E_ERRORS
|
||||||
private const val SETTINGS_LABS_MERGE_E2E_ERRORS = "SETTINGS_LABS_MERGE_E2E_ERRORS"
|
private const val SETTINGS_LABS_SHOW_COMPLETE_HISTORY_IN_ENCRYPTED_ROOM = "SETTINGS_LABS_SHOW_COMPLETE_HISTORY_IN_ENCRYPTED_ROOM"
|
||||||
const val SETTINGS_LABS_UNREAD_NOTIFICATIONS_AS_TAB = "SETTINGS_LABS_UNREAD_NOTIFICATIONS_AS_TAB"
|
const val SETTINGS_LABS_UNREAD_NOTIFICATIONS_AS_TAB = "SETTINGS_LABS_UNREAD_NOTIFICATIONS_AS_TAB"
|
||||||
|
|
||||||
// analytics
|
// analytics
|
||||||
@ -285,8 +285,8 @@ class VectorPreferences @Inject constructor(private val context: Context) {
|
|||||||
return defaultPrefs.getBoolean(SETTINGS_LABS_ENABLE_SWIPE_TO_REPLY, true)
|
return defaultPrefs.getBoolean(SETTINGS_LABS_ENABLE_SWIPE_TO_REPLY, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun mergeUTDinTimeline(): Boolean {
|
fun labShowCompleteHistoryInEncryptedRoom(): Boolean {
|
||||||
return defaultPrefs.getBoolean(SETTINGS_LABS_MERGE_E2E_ERRORS, false)
|
return defaultPrefs.getBoolean(SETTINGS_LABS_SHOW_COMPLETE_HISTORY_IN_ENCRYPTED_ROOM, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun labAllowedExtendedLogging(): Boolean {
|
fun labAllowedExtendedLogging(): Boolean {
|
||||||
|
@ -1710,6 +1710,7 @@
|
|||||||
<string name="send_suggestion_failed">The suggestion failed to be sent (%s)</string>
|
<string name="send_suggestion_failed">The suggestion failed to be sent (%s)</string>
|
||||||
|
|
||||||
<string name="settings_labs_show_hidden_events_in_timeline">Show hidden events in timeline</string>
|
<string name="settings_labs_show_hidden_events_in_timeline">Show hidden events in timeline</string>
|
||||||
|
<string name="settings_labs_show_complete_history_in_encrypted_room">"Show complete history in encrypted rooms"</string>
|
||||||
|
|
||||||
<string name="bottom_action_people_x">Direct Messages</string>
|
<string name="bottom_action_people_x">Direct Messages</string>
|
||||||
|
|
||||||
|
@ -16,6 +16,12 @@
|
|||||||
android:key="SETTINGS_LABS_SHOW_HIDDEN_EVENTS_PREFERENCE_KEY"
|
android:key="SETTINGS_LABS_SHOW_HIDDEN_EVENTS_PREFERENCE_KEY"
|
||||||
android:title="@string/settings_labs_show_hidden_events_in_timeline" />
|
android:title="@string/settings_labs_show_hidden_events_in_timeline" />
|
||||||
|
|
||||||
|
<im.vector.app.core.preference.VectorSwitchPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:dependency="SETTINGS_DEVELOPER_MODE_PREFERENCE_KEY"
|
||||||
|
android:key="SETTINGS_LABS_SHOW_COMPLETE_HISTORY_IN_ENCRYPTED_ROOM"
|
||||||
|
android:title="@string/settings_labs_show_complete_history_in_encrypted_room" />
|
||||||
|
|
||||||
<im.vector.app.core.preference.VectorSwitchPreference
|
<im.vector.app.core.preference.VectorSwitchPreference
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:dependency="SETTINGS_DEVELOPER_MODE_PREFERENCE_KEY"
|
android:dependency="SETTINGS_DEVELOPER_MODE_PREFERENCE_KEY"
|
||||||
|
@ -39,13 +39,6 @@
|
|||||||
android:key="SETTINGS_LABS_ENABLE_SWIPE_TO_REPLY"
|
android:key="SETTINGS_LABS_ENABLE_SWIPE_TO_REPLY"
|
||||||
android:title="@string/labs_swipe_to_reply_in_timeline" />
|
android:title="@string/labs_swipe_to_reply_in_timeline" />
|
||||||
|
|
||||||
|
|
||||||
<im.vector.app.core.preference.VectorSwitchPreference
|
|
||||||
android:defaultValue="false"
|
|
||||||
android:key="SETTINGS_LABS_MERGE_E2E_ERRORS"
|
|
||||||
android:title="@string/labs_merge_e2e_in_timeline" />
|
|
||||||
|
|
||||||
|
|
||||||
<im.vector.app.core.preference.VectorSwitchPreference
|
<im.vector.app.core.preference.VectorSwitchPreference
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:key="SETTINGS_LABS_UNREAD_NOTIFICATIONS_AS_TAB"
|
android:key="SETTINGS_LABS_UNREAD_NOTIFICATIONS_AS_TAB"
|
||||||
|
Loading…
Reference in New Issue
Block a user