diff --git a/changelog.d/5582.feature b/changelog.d/5582.feature
new file mode 100644
index 0000000000..e6e72c8e9d
--- /dev/null
+++ b/changelog.d/5582.feature
@@ -0,0 +1 @@
+Add a setting to be able to always appear offline
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt
index c4bc289b75..f8472319fd 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt
@@ -61,10 +61,6 @@ data class MatrixConfiguration(
* RoomDisplayNameFallbackProvider to provide default room display name.
*/
val roomDisplayNameFallbackProvider: RoomDisplayNameFallbackProvider,
- /**
- * True to enable presence information sync (if available). False to disable regardless of server setting.
- */
- val presenceSyncEnabled: Boolean = true,
/**
* Thread messages default enable/disabled value
*/
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/lightweight/LightweightSettingsStorage.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/lightweight/LightweightSettingsStorage.kt
index 069e539e2c..90b0a57ceb 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/lightweight/LightweightSettingsStorage.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/lightweight/LightweightSettingsStorage.kt
@@ -20,6 +20,7 @@ import android.content.Context
import androidx.core.content.edit
import androidx.preference.PreferenceManager
import org.matrix.android.sdk.api.MatrixConfiguration
+import org.matrix.android.sdk.internal.session.sync.SyncPresence
import javax.inject.Inject
/**
@@ -45,7 +46,29 @@ class LightweightSettingsStorage @Inject constructor(
return sdkDefaultPrefs.getBoolean(MATRIX_SDK_SETTINGS_THREAD_MESSAGES_ENABLED, matrixConfiguration.threadMessagesEnabledDefault)
}
+ /**
+ * Set the presence status sent on syncs when the application is in foreground.
+ *
+ * @param presence the presence status that should be sent on sync
+ */
+ internal fun setSyncPresenceStatus(presence: SyncPresence) {
+ sdkDefaultPrefs.edit {
+ putString(MATRIX_SDK_SETTINGS_FOREGROUND_PRESENCE_STATUS, presence.value)
+ }
+ }
+
+ /**
+ * Get the presence status that should be sent on syncs when the application is in foreground.
+ *
+ * @return the presence status that should be sent on sync
+ */
+ internal fun getSyncPresenceStatus(): SyncPresence {
+ val presenceString = sdkDefaultPrefs.getString(MATRIX_SDK_SETTINGS_FOREGROUND_PRESENCE_STATUS, SyncPresence.Online.value)
+ return SyncPresence.from(presenceString) ?: SyncPresence.Online
+ }
+
companion object {
const val MATRIX_SDK_SETTINGS_THREAD_MESSAGES_ENABLED = "MATRIX_SDK_SETTINGS_THREAD_MESSAGES_ENABLED"
+ private const val MATRIX_SDK_SETTINGS_FOREGROUND_PRESENCE_STATUS = "MATRIX_SDK_SETTINGS_FOREGROUND_PRESENCE_STATUS"
}
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/presence/service/DefaultPresenceService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/presence/service/DefaultPresenceService.kt
index 1083d5b4c2..d74251ae96 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/presence/service/DefaultPresenceService.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/presence/service/DefaultPresenceService.kt
@@ -20,18 +20,22 @@ package org.matrix.android.sdk.internal.session.presence.service
import org.matrix.android.sdk.api.session.presence.PresenceService
import org.matrix.android.sdk.api.session.presence.model.PresenceEnum
import org.matrix.android.sdk.api.session.presence.model.UserPresence
+import org.matrix.android.sdk.internal.database.lightweight.LightweightSettingsStorage
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.session.presence.service.task.GetPresenceTask
import org.matrix.android.sdk.internal.session.presence.service.task.SetPresenceTask
+import org.matrix.android.sdk.internal.session.sync.SyncPresence
import javax.inject.Inject
internal class DefaultPresenceService @Inject constructor(
@UserId private val userId: String,
private val setPresenceTask: SetPresenceTask,
- private val getPresenceTask: GetPresenceTask
+ private val getPresenceTask: GetPresenceTask,
+ private val lightweightSettingsStorage: LightweightSettingsStorage
) : PresenceService {
override suspend fun setMyPresence(presence: PresenceEnum, statusMsg: String?) {
+ lightweightSettingsStorage.setSyncPresenceStatus(SyncPresence.from(presence))
setPresenceTask.execute(SetPresenceTask.Params(userId, presence, statusMsg))
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncPresence.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncPresence.kt
index 18e17c7d13..c67cc54b75 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncPresence.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncPresence.kt
@@ -16,6 +16,8 @@
package org.matrix.android.sdk.internal.session.sync
+import org.matrix.android.sdk.api.session.presence.model.PresenceEnum
+
/**
* For `set_presence` parameter in the /sync request
*
@@ -27,5 +29,16 @@ package org.matrix.android.sdk.internal.session.sync
enum class SyncPresence(val value: String) {
Offline("offline"),
Online("online"),
- Unavailable("unavailable")
+ Unavailable("unavailable");
+
+ companion object {
+ fun from(presenceEnum: PresenceEnum): SyncPresence {
+ return when (presenceEnum) {
+ PresenceEnum.ONLINE -> Online
+ PresenceEnum.OFFLINE -> Offline
+ PresenceEnum.UNAVAILABLE -> Unavailable
+ }
+ }
+ fun from(s: String?): SyncPresence? = values().find { it.value == s }
+ }
}
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/PresenceSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/PresenceSyncHandler.kt
index e5bed12181..6a7af1dda4 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/PresenceSyncHandler.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/PresenceSyncHandler.kt
@@ -31,26 +31,24 @@ import javax.inject.Inject
internal class PresenceSyncHandler @Inject constructor(private val matrixConfiguration: MatrixConfiguration) {
fun handle(realm: Realm, presenceSyncResponse: PresenceSyncResponse?) {
- if (matrixConfiguration.presenceSyncEnabled) {
- presenceSyncResponse?.events
- ?.filter { event -> event.type == EventType.PRESENCE }
- ?.forEach { event ->
- val content = event.getPresenceContent() ?: return@forEach
- val userId = event.senderId ?: return@forEach
- val userPresenceEntity = UserPresenceEntity(
- userId = userId,
- lastActiveAgo = content.lastActiveAgo,
- statusMessage = content.statusMessage,
- isCurrentlyActive = content.isCurrentlyActive,
- avatarUrl = content.avatarUrl,
- displayName = content.displayName
- ).also {
- it.presence = content.presence
- }
-
- storePresenceToDB(realm, userPresenceEntity)
+ presenceSyncResponse?.events
+ ?.filter { event -> event.type == EventType.PRESENCE }
+ ?.forEach { event ->
+ val content = event.getPresenceContent() ?: return@forEach
+ val userId = event.senderId ?: return@forEach
+ val userPresenceEntity = UserPresenceEntity(
+ userId = userId,
+ lastActiveAgo = content.lastActiveAgo,
+ statusMessage = content.statusMessage,
+ isCurrentlyActive = content.isCurrentlyActive,
+ avatarUrl = content.avatarUrl,
+ displayName = content.displayName
+ ).also {
+ it.presence = content.presence
}
- }
+
+ storePresenceToDB(realm, userPresenceEntity)
+ }
}
/**
diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt
index 50049dacab..da49098413 100644
--- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt
+++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt
@@ -37,9 +37,9 @@ import org.matrix.android.sdk.api.logger.LoggerTag
import org.matrix.android.sdk.api.session.call.MxCall
import org.matrix.android.sdk.api.session.sync.SyncState
import org.matrix.android.sdk.api.session.sync.model.SyncResponse
+import org.matrix.android.sdk.internal.database.lightweight.LightweightSettingsStorage
import org.matrix.android.sdk.internal.network.NetworkConnectivityChecker
import org.matrix.android.sdk.internal.session.call.ActiveCallHandler
-import org.matrix.android.sdk.internal.session.sync.SyncPresence
import org.matrix.android.sdk.internal.session.sync.SyncTask
import org.matrix.android.sdk.internal.util.BackgroundDetectionObserver
import org.matrix.android.sdk.internal.util.Debouncer
@@ -59,7 +59,8 @@ private val loggerTag = LoggerTag("SyncThread", LoggerTag.SYNC)
internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
private val networkConnectivityChecker: NetworkConnectivityChecker,
private val backgroundDetectionObserver: BackgroundDetectionObserver,
- private val activeCallHandler: ActiveCallHandler
+ private val activeCallHandler: ActiveCallHandler,
+ private val lightweightSettingsStorage: LightweightSettingsStorage
) : Thread("SyncThread"), NetworkConnectivityChecker.Listener, BackgroundDetectionObserver.Listener {
private var state: SyncState = SyncState.Idle
@@ -182,7 +183,8 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask,
else -> DEFAULT_LONG_POOL_TIMEOUT
}
Timber.tag(loggerTag.value).d("Execute sync request with timeout $timeout")
- val params = SyncTask.Params(timeout, SyncPresence.Online, afterPause = afterPause)
+ val presence = lightweightSettingsStorage.getSyncPresenceStatus()
+ val params = SyncTask.Params(timeout, presence, afterPause = afterPause)
val sync = syncScope.launch {
previousSyncResponseHasToDevice = doSync(params)
}
diff --git a/vector-config/src/main/res/values/config-settings.xml b/vector-config/src/main/res/values/config-settings.xml
index 40fc68bbae..b6d1c6676c 100755
--- a/vector-config/src/main/res/values/config-settings.xml
+++ b/vector-config/src/main/res/values/config-settings.xml
@@ -28,6 +28,8 @@
true
false
+ false
+ false
diff --git a/vector/build.gradle b/vector/build.gradle
index de0b08d632..52132ee074 100644
--- a/vector/build.gradle
+++ b/vector/build.gradle
@@ -151,7 +151,6 @@ android {
buildConfigField "Boolean", "enableLocationSharing", "true"
buildConfigField "String", "mapTilerKey", "\"fU3vlMsMn4Jb6dnEIFsx\""
- buildConfigField "Boolean", "PRESENCE_SYNC_ENABLED", "true"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
diff --git a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt
index fdd6e3c2ba..5eaa35c5c7 100644
--- a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt
+++ b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt
@@ -121,7 +121,6 @@ object VectorStaticModule {
applicationFlavor = BuildConfig.FLAVOR_DESCRIPTION,
roomDisplayNameFallbackProvider = vectorRoomDisplayNameFallbackProvider,
threadMessagesEnabledDefault = vectorPreferences.areThreadMessagesEnabled(),
- presenceSyncEnabled = BuildConfig.PRESENCE_SYNC_ENABLED
)
}
diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt
index c32657e45b..8a90295967 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt
@@ -210,7 +210,6 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.billcarsonfr.jsonviewer.JSonViewerDialog
import org.commonmark.parser.Parser
-import org.matrix.android.sdk.api.MatrixConfiguration
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.content.ContentAttachmentData
import org.matrix.android.sdk.api.session.events.model.EventType
@@ -266,8 +265,7 @@ class TimelineFragment @Inject constructor(
private val pillsPostProcessorFactory: PillsPostProcessor.Factory,
private val callManager: WebRtcCallManager,
private val audioMessagePlaybackTracker: AudioMessagePlaybackTracker,
- private val clock: Clock,
- private val matrixConfiguration: MatrixConfiguration
+ private val clock: Clock
) :
VectorBaseFragment(),
TimelineEventController.Callback,
@@ -1650,7 +1648,7 @@ class TimelineFragment @Inject constructor(
views.includeRoomToolbar.roomToolbarContentView.isClickable = roomSummary.membership == Membership.JOIN
views.includeRoomToolbar.roomToolbarTitleView.text = roomSummary.displayName
avatarRenderer.render(roomSummary.toMatrixItem(), views.includeRoomToolbar.roomToolbarAvatarImageView)
- val showPresence = roomSummary.isDirect && matrixConfiguration.presenceSyncEnabled
+ val showPresence = roomSummary.isDirect
views.includeRoomToolbar.roomToolbarPresenceImageView.render(showPresence, roomSummary.directUserPresence)
val shieldView = if (showPresence) views.includeRoomToolbar.roomToolbarTitleShield else views.includeRoomToolbar.roomToolbarAvatarShield
shieldView.render(roomSummary.roomEncryptionTrustLevel)
diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt
index ca2a747b3b..6326d9c97a 100644
--- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt
+++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt
@@ -29,7 +29,6 @@ import im.vector.app.features.home.AvatarRenderer
import im.vector.app.features.home.room.detail.timeline.format.DisplayableEventFormatter
import im.vector.app.features.home.room.typing.TypingHelper
import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence
-import org.matrix.android.sdk.api.MatrixConfiguration
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.api.session.room.model.RoomSummary
@@ -42,8 +41,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
private val stringProvider: StringProvider,
private val typingHelper: TypingHelper,
private val avatarRenderer: AvatarRenderer,
- private val errorFormatter: ErrorFormatter,
- private val matrixConfiguration: MatrixConfiguration) {
+ private val errorFormatter: ErrorFormatter) {
fun create(roomSummary: RoomSummary,
roomChangeMembershipStates: Map,
@@ -127,7 +125,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor
// We do not display shield in the room list anymore
// .encryptionTrustLevel(roomSummary.roomEncryptionTrustLevel)
.izPublic(roomSummary.isPublic)
- .showPresence(roomSummary.isDirect && matrixConfiguration.presenceSyncEnabled)
+ .showPresence(roomSummary.isDirect)
.userPresence(roomSummary.directUserPresence)
.matrixItem(roomSummary.toMatrixItem())
.lastEventTime(latestEventTime)
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt
index 9177f843a0..3944066584 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt
@@ -54,7 +54,6 @@ import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedA
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.parcelize.Parcelize
-import org.matrix.android.sdk.api.MatrixConfiguration
import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState
import org.matrix.android.sdk.api.util.toMatrixItem
import timber.log.Timber
@@ -69,7 +68,6 @@ class RoomProfileFragment @Inject constructor(
private val roomProfileController: RoomProfileController,
private val avatarRenderer: AvatarRenderer,
private val roomDetailPendingActionStore: RoomDetailPendingActionStore,
- private val matrixConfiguration: MatrixConfiguration
) :
VectorBaseFragment(),
RoomProfileController.Callback {
@@ -224,7 +222,7 @@ class RoomProfileFragment @Inject constructor(
avatarRenderer.render(matrixItem, views.matrixProfileToolbarAvatarImageView)
headerViews.roomProfileDecorationImageView.render(it.roomEncryptionTrustLevel)
views.matrixProfileDecorationToolbarAvatarImageView.render(it.roomEncryptionTrustLevel)
- headerViews.roomProfilePresenceImageView.render(it.isDirect && matrixConfiguration.presenceSyncEnabled, it.directUserPresence)
+ headerViews.roomProfilePresenceImageView.render(it.isDirect, it.directUserPresence)
headerViews.roomProfilePublicImageView.isVisible = it.isPublic && !it.isDirect
}
}
diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt
index 6e0bb12642..07236fb397 100644
--- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt
+++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt
@@ -27,7 +27,6 @@ import im.vector.app.core.resources.ColorProvider
import im.vector.app.core.resources.StringProvider
import im.vector.app.features.home.AvatarRenderer
import me.gujun.android.span.span
-import org.matrix.android.sdk.api.MatrixConfiguration
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
@@ -40,8 +39,7 @@ class RoomMemberListController @Inject constructor(
private val avatarRenderer: AvatarRenderer,
private val stringProvider: StringProvider,
private val colorProvider: ColorProvider,
- private val roomMemberSummaryFilter: RoomMemberSummaryFilter,
- private val matrixConfiguration: MatrixConfiguration
+ private val roomMemberSummaryFilter: RoomMemberSummaryFilter
) : TypedEpoxyController() {
interface Callback {
@@ -124,7 +122,6 @@ class RoomMemberListController @Inject constructor(
host: RoomMemberListController,
data: RoomMemberListViewState) {
val powerLabel = stringProvider.getString(powerLevelCategory.titleRes)
- val presenceSyncEnabled = matrixConfiguration.presenceSyncEnabled
profileMatrixItemWithPowerLevelWithPresence {
id(roomMember.userId)
@@ -134,7 +131,7 @@ class RoomMemberListController @Inject constructor(
clickListener {
host.callback?.onRoomMemberClicked(roomMember)
}
- showPresence(presenceSyncEnabled)
+ showPresence(true)
userPresence(roomMember.userPresence)
powerLevelLabel(
span {
diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt
index 74fcc0be5d..195072465b 100755
--- a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt
@@ -100,6 +100,7 @@ class VectorPreferences @Inject constructor(private val context: Context) {
private const val SETTINGS_ENABLE_CHAT_EFFECTS = "SETTINGS_ENABLE_CHAT_EFFECTS"
private const val SETTINGS_SHOW_EMOJI_KEYBOARD = "SETTINGS_SHOW_EMOJI_KEYBOARD"
private const val SETTINGS_LABS_ENABLE_LATEX_MATHS = "SETTINGS_LABS_ENABLE_LATEX_MATHS"
+ const val SETTINGS_PRESENCE_USER_ALWAYS_APPEARS_OFFLINE = "SETTINGS_PRESENCE_USER_ALWAYS_APPEARS_OFFLINE"
// Room directory
private const val SETTINGS_ROOM_DIRECTORY_SHOW_ALL_PUBLIC_ROOMS = "SETTINGS_ROOM_DIRECTORY_SHOW_ALL_PUBLIC_ROOMS"
@@ -865,6 +866,16 @@ class VectorPreferences @Inject constructor(private val context: Context) {
return defaultPrefs.getBoolean(SETTINGS_INTERFACE_BUBBLE_KEY, getDefault(R.bool.settings_interface_bubble_default))
}
+ /**
+ * Tells if user should always appear offline or not.
+ *
+ * @return true if user should always appear offline
+ */
+ fun userAlwaysAppearsOffline(): Boolean {
+ return defaultPrefs.getBoolean(SETTINGS_PRESENCE_USER_ALWAYS_APPEARS_OFFLINE,
+ getDefault(R.bool.settings_presence_user_always_appears_offline_default))
+ }
+
/**
* Update the rage shake enabled status.
*
diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt
index 0c7b1bd7d9..155234a172 100644
--- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt
@@ -21,6 +21,7 @@ import android.content.Context
import android.os.Bundle
import android.widget.CheckedTextView
import androidx.core.view.children
+import androidx.lifecycle.lifecycleScope
import androidx.preference.Preference
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import im.vector.app.BuildConfig
@@ -36,6 +37,8 @@ import im.vector.app.features.MainActivityArgs
import im.vector.app.features.analytics.plan.MobileScreen
import im.vector.app.features.configuration.VectorConfiguration
import im.vector.app.features.themes.ThemeUtils
+import kotlinx.coroutines.launch
+import org.matrix.android.sdk.api.session.presence.model.PresenceEnum
import javax.inject.Inject
class VectorSettingsPreferencesFragment @Inject constructor(
@@ -78,6 +81,17 @@ class VectorSettingsPreferencesFragment @Inject constructor(
}
}
+ findPreference(VectorPreferences.SETTINGS_PRESENCE_USER_ALWAYS_APPEARS_OFFLINE)!!.let { pref ->
+ pref.isChecked = vectorPreferences.userAlwaysAppearsOffline()
+ pref.setOnPreferenceChangeListener { _, newValue ->
+ val presenceOfflineModeEnabled = newValue as? Boolean ?: false
+ lifecycleScope.launch {
+ session.setMyPresence(if (presenceOfflineModeEnabled) PresenceEnum.OFFLINE else PresenceEnum.ONLINE)
+ }
+ true
+ }
+ }
+
findPreference(VectorPreferences.SETTINGS_PREF_SPACE_SHOW_ALL_ROOM_IN_HOME)!!.let { pref ->
pref.isChecked = vectorPreferences.prefSpacesShowAllRoomInHome()
pref.setOnPreferenceChangeListener { _, _ ->
diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml
index 8cbd42c578..b39870832d 100644
--- a/vector/src/main/res/values/strings.xml
+++ b/vector/src/main/res/values/strings.xml
@@ -1056,6 +1056,11 @@
1 month
Forever
+
+ Presence
+ Offline mode
+ If enabled, you will always appear offline to other users, even when using the application.
+
diff --git a/vector/src/main/res/xml/vector_settings_preferences.xml b/vector/src/main/res/xml/vector_settings_preferences.xml
index 78bd64111c..6c8250a76a 100644
--- a/vector/src/main/res/xml/vector_settings_preferences.xml
+++ b/vector/src/main/res/xml/vector_settings_preferences.xml
@@ -198,6 +198,18 @@
+
+
+
+
+
+