Add lab option to show hidden events in timeline

+ cleaning labs settings
This commit is contained in:
Valere 2019-06-27 16:48:07 +02:00 committed by Benoit Marty
parent b92cc524b6
commit b14a6224ba
10 changed files with 175 additions and 155 deletions

View File

@ -92,7 +92,6 @@ android {
debug { debug {
resValue "bool", "debug_mode", "true" resValue "bool", "debug_mode", "true"
buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false" buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false"
buildConfigField "boolean", "SHOW_HIDDEN_TIMELINE_EVENTS", "false"
signingConfig signingConfigs.debug signingConfig signingConfigs.debug
} }
@ -100,7 +99,6 @@ android {
release { release {
resValue "bool", "debug_mode", "false" resValue "bool", "debug_mode", "false"
buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false" buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false"
buildConfigField "boolean", "SHOW_HIDDEN_TIMELINE_EVENTS", "false"
minifyEnabled false minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

View File

@ -0,0 +1,28 @@
/*
* 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.riotredesign.core.resources
import android.content.Context
import im.vector.riotredesign.features.settings.PreferencesManager
import javax.inject.Inject
class UserPreferencesProvider @Inject constructor(private val context: Context) {
fun shouldShowHiddenEvents(): Boolean {
return PreferencesManager.shouldShowHiddenEvents(context)
}
}

View File

@ -37,6 +37,7 @@ import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.matrix.rx.rx import im.vector.matrix.rx.rx
import im.vector.riotredesign.R import im.vector.riotredesign.R
import im.vector.riotredesign.core.platform.VectorViewModel import im.vector.riotredesign.core.platform.VectorViewModel
import im.vector.riotredesign.core.resources.UserPreferencesProvider
import im.vector.riotredesign.core.utils.LiveEvent import im.vector.riotredesign.core.utils.LiveEvent
import im.vector.riotredesign.features.command.CommandParser import im.vector.riotredesign.features.command.CommandParser
import im.vector.riotredesign.features.command.ParsedCommand import im.vector.riotredesign.features.command.ParsedCommand
@ -51,6 +52,7 @@ import java.util.concurrent.TimeUnit
class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: RoomDetailViewState, class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: RoomDetailViewState,
userPreferencesProvider: UserPreferencesProvider,
private val session: Session private val session: Session
) : VectorViewModel<RoomDetailViewState>(initialState) { ) : VectorViewModel<RoomDetailViewState>(initialState) {
@ -58,7 +60,7 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
private val roomId = initialState.roomId private val roomId = initialState.roomId
private val eventId = initialState.eventId private val eventId = initialState.eventId
private val displayedEventsObservable = BehaviorRelay.create<RoomDetailActions.EventDisplayed>() private val displayedEventsObservable = BehaviorRelay.create<RoomDetailActions.EventDisplayed>()
private val allowedTypes = if (TimelineDisplayableEvents.DEBUG_HIDDEN_EVENT) { private val allowedTypes = if (userPreferencesProvider.shouldShowHiddenEvents()) {
TimelineDisplayableEvents.DEBUG_DISPLAYABLE_TYPES TimelineDisplayableEvents.DEBUG_DISPLAYABLE_TYPES
} else { } else {
TimelineDisplayableEvents.DISPLAYABLE_TYPES TimelineDisplayableEvents.DISPLAYABLE_TYPES
@ -77,13 +79,9 @@ class RoomDetailViewModel @AssistedInject constructor(@Assisted initialState: Ro
@JvmStatic @JvmStatic
override fun create(viewModelContext: ViewModelContext, state: RoomDetailViewState): RoomDetailViewModel? { override fun create(viewModelContext: ViewModelContext, state: RoomDetailViewState): RoomDetailViewModel? {
val fragment: RoomDetailFragment = (viewModelContext as FragmentViewModelContext).fragment() val fragment: RoomDetailFragment = (viewModelContext as FragmentViewModelContext).fragment()
return fragment.roomDetailViewModelFactory.create(state) return fragment.roomDetailViewModelFactory.create(state)
} }
override fun initialState(viewModelContext: ViewModelContext): RoomDetailViewState? {
return super.initialState(viewModelContext)
}
} }
init { init {

View File

@ -30,6 +30,7 @@ import im.vector.matrix.android.api.session.room.timeline.Timeline
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.riotredesign.core.epoxy.LoadingItem_ import im.vector.riotredesign.core.epoxy.LoadingItem_
import im.vector.riotredesign.core.extensions.localDateTime import im.vector.riotredesign.core.extensions.localDateTime
import im.vector.riotredesign.core.resources.UserPreferencesProvider
import im.vector.riotredesign.features.home.AvatarRenderer import im.vector.riotredesign.features.home.AvatarRenderer
import im.vector.riotredesign.features.home.room.detail.timeline.factory.TimelineItemFactory import im.vector.riotredesign.features.home.room.detail.timeline.factory.TimelineItemFactory
import im.vector.riotredesign.features.home.room.detail.timeline.helper.* import im.vector.riotredesign.features.home.room.detail.timeline.helper.*
@ -47,7 +48,8 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Tim
private val timelineMediaSizeProvider: TimelineMediaSizeProvider, private val timelineMediaSizeProvider: TimelineMediaSizeProvider,
private val avatarRenderer: AvatarRenderer, private val avatarRenderer: AvatarRenderer,
@TimelineEventControllerHandler @TimelineEventControllerHandler
private val backgroundHandler: Handler private val backgroundHandler: Handler,
userPreferencesProvider: UserPreferencesProvider
) : EpoxyController(backgroundHandler, backgroundHandler), Timeline.Listener { ) : EpoxyController(backgroundHandler, backgroundHandler), Timeline.Listener {
interface Callback : ReactionPillCallback, AvatarCallback, BaseCallback, UrlClickCallback { interface Callback : ReactionPillCallback, AvatarCallback, BaseCallback, UrlClickCallback {
@ -132,6 +134,8 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Tim
} }
} }
private val showHiddenEvents = userPreferencesProvider.shouldShowHiddenEvents()
init { init {
requestModelBuild() requestModelBuild()
} }
@ -234,7 +238,7 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Tim
private fun buildItemModels(currentPosition: Int, items: List<TimelineEvent>): CacheItemData { private fun buildItemModels(currentPosition: Int, items: List<TimelineEvent>): CacheItemData {
val event = items[currentPosition] val event = items[currentPosition]
val nextEvent = items.nextDisplayableEvent(currentPosition) val nextEvent = items.nextDisplayableEvent(currentPosition, showHiddenEvents)
val date = event.root.localDateTime() val date = event.root.localDateTime()
val nextDate = nextEvent?.root?.localDateTime() val nextDate = nextEvent?.root?.localDateTime()
val addDaySeparator = date.toLocalDate() != nextDate?.toLocalDate() val addDaySeparator = date.toLocalDate() != nextDate?.toLocalDate()

View File

@ -17,16 +17,14 @@
package im.vector.riotredesign.features.home.room.detail.timeline.factory package im.vector.riotredesign.features.home.room.detail.timeline.factory
import im.vector.matrix.android.api.session.events.model.EventType 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.model.message.MessageContent
import im.vector.matrix.android.api.session.room.model.message.MessageDefaultContent
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.riotredesign.core.epoxy.EmptyItem_ import im.vector.riotredesign.core.epoxy.EmptyItem_
import im.vector.riotredesign.core.epoxy.VectorEpoxyModel import im.vector.riotredesign.core.epoxy.VectorEpoxyModel
import im.vector.riotredesign.features.home.AvatarRenderer
import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventController
import im.vector.riotredesign.features.home.room.detail.timeline.helper.TimelineDisplayableEvents import im.vector.riotredesign.features.home.room.detail.timeline.helper.senderAvatar
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageInformationData
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageTextItem_ import im.vector.riotredesign.features.home.room.detail.timeline.item.NoticeItem_
import timber.log.Timber import timber.log.Timber
import javax.inject.Inject import javax.inject.Inject
@ -34,7 +32,8 @@ class TimelineItemFactory @Inject constructor(private val messageItemFactory: Me
private val encryptionItemFactory: EncryptionItemFactory, private val encryptionItemFactory: EncryptionItemFactory,
private val encryptedItemFactory: EncryptedItemFactory, private val encryptedItemFactory: EncryptedItemFactory,
private val noticeItemFactory: NoticeItemFactory, private val noticeItemFactory: NoticeItemFactory,
private val defaultItemFactory: DefaultItemFactory) { private val defaultItemFactory: DefaultItemFactory,
private val avatarRenderer: AvatarRenderer) {
fun create(event: TimelineEvent, fun create(event: TimelineEvent,
nextEvent: TimelineEvent?, nextEvent: TimelineEvent?,
@ -65,30 +64,21 @@ class TimelineItemFactory @Inject constructor(private val messageItemFactory: Me
else -> { else -> {
//These are just for debug to display hidden event, they should be filtered out in normal mode //These are just for debug to display hidden event, they should be filtered out in normal mode
if (TimelineDisplayableEvents.DEBUG_HIDDEN_EVENT) { val informationData = MessageInformationData(
val informationData = MessageInformationData(eventId = event.root.eventId eventId = event.root.eventId ?: "?",
?: "?", senderId = event.root.senderId ?: "",
senderId = event.root.senderId ?: "", sendState = event.sendState,
sendState = event.sendState, time = "",
time = "", avatarUrl = event.senderAvatar(),
avatarUrl = null, memberName = "",
memberName = "", showInformation = false
showInformation = false )
) NoticeItem_()
val messageContent = event.root.content.toModel<MessageContent>() .avatarRenderer(avatarRenderer)
?: MessageDefaultContent("", "", null, null) .informationData(informationData)
MessageTextItem_() .noticeText("{ \"type\": ${event.root.type} }")
.informationData(informationData) .highlighted(highlight)
.message("{ \"type\": ${event.root.type} }") .baseCallback(callback)
.highlighted(highlight)
.longClickListener { view ->
return@longClickListener callback?.onEventLongClicked(informationData, messageContent, view)
?: false
}
} else {
Timber.w("Ignored event (type: ${event.root.type}")
null
}
} }
} }
} catch (e: Exception) { } catch (e: Exception) {

View File

@ -22,14 +22,10 @@ import im.vector.matrix.android.api.session.events.model.toModel
import im.vector.matrix.android.api.session.room.model.RoomMember import im.vector.matrix.android.api.session.room.model.RoomMember
import im.vector.matrix.android.api.session.room.model.message.MessageContent import im.vector.matrix.android.api.session.room.model.message.MessageContent
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
import im.vector.riotredesign.BuildConfig
import im.vector.riotredesign.core.extensions.localDateTime import im.vector.riotredesign.core.extensions.localDateTime
object TimelineDisplayableEvents { object TimelineDisplayableEvents {
//Debug helper, to show invisible items in time line (reaction, redacts)
val DEBUG_HIDDEN_EVENT = BuildConfig.SHOW_HIDDEN_TIMELINE_EVENTS
val DISPLAYABLE_TYPES = listOf( val DISPLAYABLE_TYPES = listOf(
EventType.MESSAGE, EventType.MESSAGE,
EventType.STATE_ROOM_NAME, EventType.STATE_ROOM_NAME,
@ -52,8 +48,10 @@ object TimelineDisplayableEvents {
) )
} }
fun TimelineEvent.isDisplayable(): Boolean { fun TimelineEvent.isDisplayable(showHiddenEvent: Boolean): Boolean {
if (!TimelineDisplayableEvents.DISPLAYABLE_TYPES.contains(root.type)) { val allowed = TimelineDisplayableEvents.DEBUG_DISPLAYABLE_TYPES.takeIf { showHiddenEvent }
?: TimelineDisplayableEvents.DISPLAYABLE_TYPES
if (!allowed.contains(root.type)) {
return false return false
} }
if (root.content.isNullOrEmpty()) { if (root.content.isNullOrEmpty()) {
@ -132,10 +130,10 @@ fun List<TimelineEvent>.prevSameTypeEvents(index: Int, minSize: Int): List<Timel
.reversed() .reversed()
} }
fun List<TimelineEvent>.nextDisplayableEvent(index: Int): TimelineEvent? { fun List<TimelineEvent>.nextDisplayableEvent(index: Int, showHiddenEvent: Boolean): TimelineEvent? {
return if (index >= size - 1) { return if (index >= size - 1) {
null null
} else { } else {
subList(index + 1, this.size).firstOrNull { it.isDisplayable() } subList(index + 1, this.size).firstOrNull { it.isDisplayable(showHiddenEvent) }
} }
} }

View File

@ -155,6 +155,8 @@ public class PreferencesManager {
private static final String SETTINGS_USE_NATIVE_CAMERA_PREFERENCE_KEY = "SETTINGS_USE_NATIVE_CAMERA_PREFERENCE_KEY"; private static final String SETTINGS_USE_NATIVE_CAMERA_PREFERENCE_KEY = "SETTINGS_USE_NATIVE_CAMERA_PREFERENCE_KEY";
private static final String SETTINGS_ENABLE_SEND_VOICE_FEATURE_PREFERENCE_KEY = "SETTINGS_ENABLE_SEND_VOICE_FEATURE_PREFERENCE_KEY"; private static final String SETTINGS_ENABLE_SEND_VOICE_FEATURE_PREFERENCE_KEY = "SETTINGS_ENABLE_SEND_VOICE_FEATURE_PREFERENCE_KEY";
private static final String SETTINGS_LABS_SHOW_HIDDEN_EVENTS_PREFERENCE_KEY = "SETTINGS_LABS_SHOW_HIDDEN_EVENTS_PREFERENCE_KEY";
// analytics // analytics
public static final String SETTINGS_USE_ANALYTICS_KEY = "SETTINGS_USE_ANALYTICS_KEY"; public static final String SETTINGS_USE_ANALYTICS_KEY = "SETTINGS_USE_ANALYTICS_KEY";
public static final String SETTINGS_USE_RAGE_SHAKE_KEY = "SETTINGS_USE_RAGE_SHAKE_KEY"; public static final String SETTINGS_USE_RAGE_SHAKE_KEY = "SETTINGS_USE_RAGE_SHAKE_KEY";
@ -253,6 +255,10 @@ public class PreferencesManager {
.apply(); .apply();
} }
public static boolean shouldShowHiddenEvents(Context context) {
return PreferenceManager.getDefaultSharedPreferences(context).getBoolean(SETTINGS_LABS_SHOW_HIDDEN_EVENTS_PREFERENCE_KEY, false);
}
/** /**
* Tells if we have already asked the user to disable battery optimisations on android >= M devices. * Tells if we have already asked the user to disable battery optimisations on android >= M devices.
* *

View File

@ -16,11 +16,6 @@
package im.vector.riotredesign.features.settings package im.vector.riotredesign.features.settings
import android.text.TextUtils
import androidx.appcompat.app.AlertDialog
import androidx.preference.Preference
import androidx.preference.PreferenceCategory
import androidx.preference.SwitchPreference
import im.vector.riotredesign.R import im.vector.riotredesign.R
class VectorSettingsLabsFragment : VectorSettingsBaseFragment() { class VectorSettingsLabsFragment : VectorSettingsBaseFragment() {
@ -28,101 +23,97 @@ class VectorSettingsLabsFragment : VectorSettingsBaseFragment() {
override var titleRes = R.string.room_settings_labs_pref_title override var titleRes = R.string.room_settings_labs_pref_title
override val preferenceXmlRes = R.xml.vector_settings_labs override val preferenceXmlRes = R.xml.vector_settings_labs
private val mLabsCategory by lazy {
findPreference(PreferencesManager.SETTINGS_LABS_PREFERENCE_KEY) as PreferenceCategory
}
override fun bindPref() { override fun bindPref() {
// Lab // Lab
val useCryptoPref = findPreference(PreferencesManager.SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_PREFERENCE_KEY) as SwitchPreference // val useCryptoPref = findPreference(PreferencesManager.SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_PREFERENCE_KEY) as SwitchPreference
val cryptoIsEnabledPref = findPreference(PreferencesManager.SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_IS_ACTIVE_PREFERENCE_KEY) // val cryptoIsEnabledPref = findPreference(PreferencesManager.SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_IS_ACTIVE_PREFERENCE_KEY)
if (session.isCryptoEnabled()) { if (session.isCryptoEnabled()) {
mLabsCategory.removePreference(useCryptoPref) // mLabsCategory.removePreference(useCryptoPref)
//
cryptoIsEnabledPref.isEnabled = false // cryptoIsEnabledPref.isEnabled = false
} else { } else {
mLabsCategory.removePreference(cryptoIsEnabledPref) // mLabsCategory.removePreference(cryptoIsEnabledPref)
//
useCryptoPref.isChecked = false // useCryptoPref.isChecked = false
//
useCryptoPref.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValueAsVoid -> // useCryptoPref.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValueAsVoid ->
if (TextUtils.isEmpty(session.sessionParams.credentials.deviceId)) { // if (TextUtils.isEmpty(mSession.sessionParams.credentials.deviceId)) {
activity?.let { activity -> // activity?.let { activity ->
AlertDialog.Builder(activity) // AlertDialog.Builder(activity)
.setMessage(R.string.room_settings_labs_end_to_end_warnings) // .setMessage(R.string.room_settings_labs_end_to_end_warnings)
.setPositiveButton(R.string.logout) { _, _ -> // .setPositiveButton(R.string.logout) { _, _ ->
notImplemented() // notImplemented()
// TODO CommonActivityUtils.logout(activity) // // TODO CommonActivityUtils.logout(activity)
} // }
.setNegativeButton(R.string.cancel) { _, _ -> // .setNegativeButton(R.string.cancel) { _, _ ->
useCryptoPref.isChecked = false // useCryptoPref.isChecked = false
} // }
.setOnCancelListener { // .setOnCancelListener {
useCryptoPref.isChecked = false // useCryptoPref.isChecked = false
} // }
.show() // .show()
} // }
} else { // } else {
val newValue = newValueAsVoid as Boolean // val newValue = newValueAsVoid as Boolean
//
if (session.isCryptoEnabled() != newValue) { // if (mSession.isCryptoEnabled() != newValue) {
notImplemented() // notImplemented()
/* TODO // /* TODO
displayLoadingView() // displayLoadingView()
//
session.enableCrypto(newValue, object : MatrixCallback<Unit> { // session.enableCrypto(newValue, object : MatrixCallback<Unit> {
private fun refresh() { // private fun refresh() {
activity?.runOnUiThread { // activity?.runOnUiThread {
hideLoadingView() // hideLoadingView()
useCryptoPref.isChecked = session.isCryptoEnabled // useCryptoPref.isChecked = session.isCryptoEnabled
//
if (session.isCryptoEnabled) { // if (session.isCryptoEnabled) {
mLabsCategory.removePreference(useCryptoPref) // mLabsCategory.removePreference(useCryptoPref)
mLabsCategory.addPreference(cryptoIsEnabledPref) // mLabsCategory.addPreference(cryptoIsEnabledPref)
} // }
} // }
} // }
//
override fun onSuccess(info: Void?) { // override fun onSuccess(info: Void?) {
useCryptoPref.isEnabled = false // useCryptoPref.isEnabled = false
refresh() // refresh()
} // }
//
override fun onNetworkError(e: Exception) { // override fun onNetworkError(e: Exception) {
useCryptoPref.isChecked = false // useCryptoPref.isChecked = false
} // }
//
override fun onMatrixError(e: MatrixError) { // override fun onMatrixError(e: MatrixError) {
useCryptoPref.isChecked = false // useCryptoPref.isChecked = false
} // }
//
override fun onUnexpectedError(e: Exception) { // override fun onUnexpectedError(e: Exception) {
useCryptoPref.isChecked = false // useCryptoPref.isChecked = false
} // }
}) // })
*/ // */
} // }
} // }
//
true // true
} // }
} }
// SaveMode Management // SaveMode Management
findPreference(PreferencesManager.SETTINGS_DATA_SAVE_MODE_PREFERENCE_KEY) // findPreference(PreferencesManager.SETTINGS_DATA_SAVE_MODE_PREFERENCE_KEY)
.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue -> // .onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
notImplemented() // notImplemented()
/* TODO // /* TODO
val sessions = Matrix.getMXSessions(activity) // val sessions = Matrix.getMXSessions(activity)
for (session in sessions) { // for (session in sessions) {
session.setUseDataSaveMode(newValue as Boolean) // session.setUseDataSaveMode(newValue as Boolean)
} // }
*/ // */
//
true // true
} // }
} }
} }

View File

@ -46,4 +46,6 @@
<string name="send_suggestion_sent">Thanks, the suggestion has been successfully sent</string> <string name="send_suggestion_sent">Thanks, the suggestion has been successfully sent</string>
<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>
</resources> </resources>

View File

@ -3,28 +3,28 @@
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<im.vector.riotredesign.core.preference.VectorPreferenceCategory <!--<im.vector.riotredesign.core.preference.VectorPreferenceCategory-->
android:key="SETTINGS_LABS_PREFERENCE_KEY" <!--android:key="SETTINGS_LABS_PREFERENCE_KEY"-->
android:title="@string/room_settings_labs_pref_title"> <!--android:title="@string/room_settings_labs_pref_title">-->
<im.vector.riotredesign.core.preference.VectorPreference <im.vector.riotredesign.core.preference.VectorPreference
android:focusable="false" android:focusable="false"
android:key="labs_warning" android:key="labs_warning"
android:title="@string/room_settings_labs_warning_message" /> android:summary="@string/room_settings_labs_warning_message" />
<im.vector.riotredesign.core.preference.VectorSwitchPreference <!--<im.vector.riotredesign.core.preference.VectorSwitchPreference-->
android:key="SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_PREFERENCE_KEY" <!--android:key="SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_PREFERENCE_KEY"-->
android:title="@string/room_settings_labs_end_to_end" /> <!--android:title="@string/room_settings_labs_end_to_end" />-->
<im.vector.riotredesign.core.preference.VectorPreference <!--<im.vector.riotredesign.core.preference.VectorPreference-->
android:focusable="false" <!--android:focusable="false"-->
android:key="SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_IS_ACTIVE_PREFERENCE_KEY" <!--android:key="SETTINGS_ROOM_SETTINGS_LABS_END_TO_END_IS_ACTIVE_PREFERENCE_KEY"-->
android:title="@string/room_settings_labs_end_to_end_is_active" /> <!--android:title="@string/room_settings_labs_end_to_end_is_active" />-->
<im.vector.riotredesign.core.preference.VectorSwitchPreference <!--<im.vector.riotredesign.core.preference.VectorSwitchPreference-->
android:key="SETTINGS_DATA_SAVE_MODE_PREFERENCE_KEY" <!--android:key="SETTINGS_DATA_SAVE_MODE_PREFERENCE_KEY"-->
android:summary="@string/settings_data_save_mode_summary" <!--android:summary="@string/settings_data_save_mode_summary"-->
android:title="@string/settings_data_save_mode" /> <!--android:title="@string/settings_data_save_mode" />-->
<im.vector.riotredesign.core.preference.VectorSwitchPreference <im.vector.riotredesign.core.preference.VectorSwitchPreference
android:defaultValue="true" android:defaultValue="true"
@ -36,6 +36,11 @@
android:summary="@string/settings_labs_enable_send_voice_summary" android:summary="@string/settings_labs_enable_send_voice_summary"
android:title="@string/settings_labs_enable_send_voice" /> android:title="@string/settings_labs_enable_send_voice" />
</im.vector.riotredesign.core.preference.VectorPreferenceCategory> <im.vector.riotredesign.core.preference.VectorSwitchPreference
android:key="SETTINGS_LABS_SHOW_HIDDEN_EVENTS_PREFERENCE_KEY"
android:defaultValue="false"
android:title="@string/settings_labs_show_hidden_events_in_timeline" />
<!--</im.vector.riotredesign.core.preference.VectorPreferenceCategory>-->
</androidx.preference.PreferenceScreen> </androidx.preference.PreferenceScreen>