Remove FeatureFlag.NotificationSettings and FeatureFlag.PinUnlock
This commit is contained in:
parent
92990b27f3
commit
0eadf275e1
12 changed files with 16 additions and 77 deletions
|
|
@ -18,8 +18,6 @@ import io.element.android.features.lockscreen.impl.storage.LockScreenStore
|
||||||
import io.element.android.libraries.di.AppScope
|
import io.element.android.libraries.di.AppScope
|
||||||
import io.element.android.libraries.di.SingleIn
|
import io.element.android.libraries.di.SingleIn
|
||||||
import io.element.android.libraries.di.annotations.AppCoroutineScope
|
import io.element.android.libraries.di.annotations.AppCoroutineScope
|
||||||
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
|
||||||
import io.element.android.libraries.featureflag.api.FeatureFlags
|
|
||||||
import io.element.android.libraries.sessionstorage.api.observer.SessionListener
|
import io.element.android.libraries.sessionstorage.api.observer.SessionListener
|
||||||
import io.element.android.libraries.sessionstorage.api.observer.SessionObserver
|
import io.element.android.libraries.sessionstorage.api.observer.SessionObserver
|
||||||
import io.element.android.services.appnavstate.api.AppForegroundStateService
|
import io.element.android.services.appnavstate.api.AppForegroundStateService
|
||||||
|
|
@ -29,7 +27,6 @@ import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
import kotlinx.coroutines.flow.MutableStateFlow
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
import kotlinx.coroutines.flow.StateFlow
|
||||||
import kotlinx.coroutines.flow.combine
|
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
@ -40,7 +37,6 @@ import kotlin.time.Duration
|
||||||
@ContributesBinding(AppScope::class)
|
@ContributesBinding(AppScope::class)
|
||||||
class DefaultLockScreenService @Inject constructor(
|
class DefaultLockScreenService @Inject constructor(
|
||||||
private val lockScreenConfig: LockScreenConfig,
|
private val lockScreenConfig: LockScreenConfig,
|
||||||
private val featureFlagService: FeatureFlagService,
|
|
||||||
private val lockScreenStore: LockScreenStore,
|
private val lockScreenStore: LockScreenStore,
|
||||||
private val pinCodeManager: PinCodeManager,
|
private val pinCodeManager: PinCodeManager,
|
||||||
@AppCoroutineScope
|
@AppCoroutineScope
|
||||||
|
|
@ -108,12 +104,7 @@ class DefaultLockScreenService @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isPinSetup(): Flow<Boolean> {
|
override fun isPinSetup(): Flow<Boolean> {
|
||||||
return combine(
|
return pinCodeManager.hasPinCode()
|
||||||
featureFlagService.isFeatureEnabledFlow(FeatureFlags.PinUnlock),
|
|
||||||
pinCodeManager.hasPinCode()
|
|
||||||
) { isEnabled, hasPinCode ->
|
|
||||||
isEnabled && hasPinCode
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isSetupRequired(): Flow<Boolean> {
|
override fun isSetupRequired(): Flow<Boolean> {
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,6 @@ import io.element.android.features.rageshake.api.RageshakeFeatureAvailability
|
||||||
import io.element.android.libraries.architecture.Presenter
|
import io.element.android.libraries.architecture.Presenter
|
||||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
||||||
import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarMessageAsState
|
import io.element.android.libraries.designsystem.utils.snackbar.collectSnackbarMessageAsState
|
||||||
import io.element.android.libraries.featureflag.api.FeatureFlagService
|
|
||||||
import io.element.android.libraries.featureflag.api.FeatureFlags
|
|
||||||
import io.element.android.libraries.indicator.api.IndicatorService
|
import io.element.android.libraries.indicator.api.IndicatorService
|
||||||
import io.element.android.libraries.matrix.api.MatrixClient
|
import io.element.android.libraries.matrix.api.MatrixClient
|
||||||
import io.element.android.libraries.matrix.api.oidc.AccountManagementAction
|
import io.element.android.libraries.matrix.api.oidc.AccountManagementAction
|
||||||
|
|
@ -42,7 +40,6 @@ class PreferencesRootPresenter @Inject constructor(
|
||||||
private val analyticsService: AnalyticsService,
|
private val analyticsService: AnalyticsService,
|
||||||
private val versionFormatter: VersionFormatter,
|
private val versionFormatter: VersionFormatter,
|
||||||
private val snackbarDispatcher: SnackbarDispatcher,
|
private val snackbarDispatcher: SnackbarDispatcher,
|
||||||
private val featureFlagService: FeatureFlagService,
|
|
||||||
private val indicatorService: IndicatorService,
|
private val indicatorService: IndicatorService,
|
||||||
private val directLogoutPresenter: Presenter<DirectLogoutState>,
|
private val directLogoutPresenter: Presenter<DirectLogoutState>,
|
||||||
private val showDeveloperSettingsProvider: ShowDeveloperSettingsProvider,
|
private val showDeveloperSettingsProvider: ShowDeveloperSettingsProvider,
|
||||||
|
|
@ -60,15 +57,6 @@ class PreferencesRootPresenter @Inject constructor(
|
||||||
val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
|
val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
|
||||||
val hasAnalyticsProviders = remember { analyticsService.getAvailableAnalyticsProviders().isNotEmpty() }
|
val hasAnalyticsProviders = remember { analyticsService.getAvailableAnalyticsProviders().isNotEmpty() }
|
||||||
|
|
||||||
val showNotificationSettings = remember { mutableStateOf(false) }
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
showNotificationSettings.value = featureFlagService.isFeatureEnabled(FeatureFlags.NotificationSettings)
|
|
||||||
}
|
|
||||||
val showLockScreenSettings = remember { mutableStateOf(false) }
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
showLockScreenSettings.value = featureFlagService.isFeatureEnabled(FeatureFlags.PinUnlock)
|
|
||||||
}
|
|
||||||
|
|
||||||
// We should display the 'complete verification' option if the current session can be verified
|
// We should display the 'complete verification' option if the current session can be verified
|
||||||
val canVerifyUserSession by sessionVerificationService.needsSessionVerification.collectAsState(false)
|
val canVerifyUserSession by sessionVerificationService.needsSessionVerification.collectAsState(false)
|
||||||
|
|
||||||
|
|
@ -122,8 +110,6 @@ class PreferencesRootPresenter @Inject constructor(
|
||||||
canReportBug = canReportBug,
|
canReportBug = canReportBug,
|
||||||
showDeveloperSettings = showDeveloperSettings,
|
showDeveloperSettings = showDeveloperSettings,
|
||||||
canDeactivateAccount = canDeactivateAccount,
|
canDeactivateAccount = canDeactivateAccount,
|
||||||
showNotificationSettings = showNotificationSettings.value,
|
|
||||||
showLockScreenSettings = showLockScreenSettings.value,
|
|
||||||
showBlockedUsersItem = showBlockedUsersItem,
|
showBlockedUsersItem = showBlockedUsersItem,
|
||||||
directLogoutState = directLogoutState,
|
directLogoutState = directLogoutState,
|
||||||
snackbarMessage = snackbarMessage,
|
snackbarMessage = snackbarMessage,
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,6 @@ data class PreferencesRootState(
|
||||||
val showAnalyticsSettings: Boolean,
|
val showAnalyticsSettings: Boolean,
|
||||||
val showDeveloperSettings: Boolean,
|
val showDeveloperSettings: Boolean,
|
||||||
val canDeactivateAccount: Boolean,
|
val canDeactivateAccount: Boolean,
|
||||||
val showLockScreenSettings: Boolean,
|
|
||||||
val showNotificationSettings: Boolean,
|
|
||||||
val showBlockedUsersItem: Boolean,
|
val showBlockedUsersItem: Boolean,
|
||||||
val directLogoutState: DirectLogoutState,
|
val directLogoutState: DirectLogoutState,
|
||||||
val snackbarMessage: SnackbarMessage?,
|
val snackbarMessage: SnackbarMessage?,
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,6 @@ fun aPreferencesRootState(
|
||||||
showAnalyticsSettings = true,
|
showAnalyticsSettings = true,
|
||||||
canReportBug = true,
|
canReportBug = true,
|
||||||
showDeveloperSettings = true,
|
showDeveloperSettings = true,
|
||||||
showNotificationSettings = true,
|
|
||||||
showLockScreenSettings = true,
|
|
||||||
showBlockedUsersItem = true,
|
showBlockedUsersItem = true,
|
||||||
canDeactivateAccount = true,
|
canDeactivateAccount = true,
|
||||||
snackbarMessage = SnackbarMessage(CommonStrings.common_verification_complete),
|
snackbarMessage = SnackbarMessage(CommonStrings.common_verification_complete),
|
||||||
|
|
|
||||||
|
|
@ -121,20 +121,16 @@ private fun ColumnScope.ManageAppSection(
|
||||||
onOpenLockScreenSettings: () -> Unit,
|
onOpenLockScreenSettings: () -> Unit,
|
||||||
onSecureBackupClick: () -> Unit,
|
onSecureBackupClick: () -> Unit,
|
||||||
) {
|
) {
|
||||||
if (state.showNotificationSettings) {
|
ListItem(
|
||||||
ListItem(
|
headlineContent = { Text(stringResource(id = R.string.screen_notification_settings_title)) },
|
||||||
headlineContent = { Text(stringResource(id = R.string.screen_notification_settings_title)) },
|
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Notifications())),
|
||||||
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Notifications())),
|
onClick = onOpenNotificationSettings,
|
||||||
onClick = onOpenNotificationSettings,
|
)
|
||||||
)
|
ListItem(
|
||||||
}
|
headlineContent = { Text(stringResource(id = CommonStrings.common_screen_lock)) },
|
||||||
if (state.showLockScreenSettings) {
|
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Lock())),
|
||||||
ListItem(
|
onClick = onOpenLockScreenSettings,
|
||||||
headlineContent = { Text(stringResource(id = CommonStrings.common_screen_lock)) },
|
)
|
||||||
leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Lock())),
|
|
||||||
onClick = onOpenLockScreenSettings,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
if (state.showSecureBackup) {
|
if (state.showSecureBackup) {
|
||||||
ListItem(
|
ListItem(
|
||||||
headlineContent = { Text(stringResource(id = CommonStrings.common_encryption)) },
|
headlineContent = { Text(stringResource(id = CommonStrings.common_encryption)) },
|
||||||
|
|
@ -143,9 +139,7 @@ private fun ColumnScope.ManageAppSection(
|
||||||
onClick = onSecureBackupClick,
|
onClick = onSecureBackupClick,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (state.showNotificationSettings || state.showLockScreenSettings || state.showSecureBackup) {
|
HorizontalDivider()
|
||||||
HorizontalDivider()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ import io.element.android.features.preferences.impl.utils.ShowDeveloperSettingsP
|
||||||
import io.element.android.features.rageshake.api.RageshakeFeatureAvailability
|
import io.element.android.features.rageshake.api.RageshakeFeatureAvailability
|
||||||
import io.element.android.libraries.core.meta.BuildType
|
import io.element.android.libraries.core.meta.BuildType
|
||||||
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
|
||||||
import io.element.android.libraries.featureflag.test.FakeFeatureFlagService
|
|
||||||
import io.element.android.libraries.indicator.api.IndicatorService
|
import io.element.android.libraries.indicator.api.IndicatorService
|
||||||
import io.element.android.libraries.indicator.test.FakeIndicatorService
|
import io.element.android.libraries.indicator.test.FakeIndicatorService
|
||||||
import io.element.android.libraries.matrix.api.oidc.AccountManagementAction
|
import io.element.android.libraries.matrix.api.oidc.AccountManagementAction
|
||||||
|
|
@ -77,8 +76,6 @@ class PreferencesRootPresenterTest {
|
||||||
assertThat(loadedState.devicesManagementUrl).isNull()
|
assertThat(loadedState.devicesManagementUrl).isNull()
|
||||||
assertThat(loadedState.showAnalyticsSettings).isFalse()
|
assertThat(loadedState.showAnalyticsSettings).isFalse()
|
||||||
assertThat(loadedState.showDeveloperSettings).isTrue()
|
assertThat(loadedState.showDeveloperSettings).isTrue()
|
||||||
assertThat(loadedState.showLockScreenSettings).isTrue()
|
|
||||||
assertThat(loadedState.showNotificationSettings).isTrue()
|
|
||||||
assertThat(loadedState.canDeactivateAccount).isTrue()
|
assertThat(loadedState.canDeactivateAccount).isTrue()
|
||||||
assertThat(loadedState.canReportBug).isTrue()
|
assertThat(loadedState.canReportBug).isTrue()
|
||||||
assertThat(loadedState.directLogoutState).isEqualTo(aDirectLogoutState())
|
assertThat(loadedState.directLogoutState).isEqualTo(aDirectLogoutState())
|
||||||
|
|
@ -194,7 +191,6 @@ class PreferencesRootPresenterTest {
|
||||||
analyticsService = FakeAnalyticsService(),
|
analyticsService = FakeAnalyticsService(),
|
||||||
versionFormatter = FakeVersionFormatter(),
|
versionFormatter = FakeVersionFormatter(),
|
||||||
snackbarDispatcher = SnackbarDispatcher(),
|
snackbarDispatcher = SnackbarDispatcher(),
|
||||||
featureFlagService = FakeFeatureFlagService(),
|
|
||||||
indicatorService = indicatorService,
|
indicatorService = indicatorService,
|
||||||
directLogoutPresenter = { aDirectLogoutState() },
|
directLogoutPresenter = { aDirectLogoutState() },
|
||||||
showDeveloperSettingsProvider = showDeveloperSettingsProvider,
|
showDeveloperSettingsProvider = showDeveloperSettingsProvider,
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.collectAsState
|
import androidx.compose.runtime.collectAsState
|
||||||
import androidx.compose.runtime.derivedStateOf
|
import androidx.compose.runtime.derivedStateOf
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.produceState
|
import androidx.compose.runtime.produceState
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
|
|
@ -77,7 +76,6 @@ class RoomDetailsPresenter @Inject constructor(
|
||||||
override fun present(): RoomDetailsState {
|
override fun present(): RoomDetailsState {
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val leaveRoomState = leaveRoomPresenter.present()
|
val leaveRoomState = leaveRoomPresenter.present()
|
||||||
val canShowNotificationSettings = remember { mutableStateOf(false) }
|
|
||||||
val roomInfo by room.roomInfoFlow.collectAsState()
|
val roomInfo by room.roomInfoFlow.collectAsState()
|
||||||
val isUserAdmin = room.isOwnUserAdmin()
|
val isUserAdmin = room.isOwnUserAdmin()
|
||||||
val syncUpdateFlow = room.syncUpdateFlow.collectAsState()
|
val syncUpdateFlow = room.syncUpdateFlow.collectAsState()
|
||||||
|
|
@ -96,11 +94,8 @@ class RoomDetailsPresenter @Inject constructor(
|
||||||
}.collectAsState(false)
|
}.collectAsState(false)
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
canShowNotificationSettings.value = featureFlagService.isFeatureEnabled(FeatureFlags.NotificationSettings)
|
room.updateRoomNotificationSettings()
|
||||||
if (canShowNotificationSettings.value) {
|
observeNotificationSettings()
|
||||||
room.updateRoomNotificationSettings()
|
|
||||||
observeNotificationSettings()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val membersState by room.membersStateFlow.collectAsState()
|
val membersState by room.membersStateFlow.collectAsState()
|
||||||
|
|
@ -197,7 +192,6 @@ class RoomDetailsPresenter @Inject constructor(
|
||||||
isEncrypted = isEncrypted,
|
isEncrypted = isEncrypted,
|
||||||
canInvite = canInvite,
|
canInvite = canInvite,
|
||||||
canEdit = (canEditAvatar || canEditName || canEditTopic) && roomType == RoomDetailsType.Room,
|
canEdit = (canEditAvatar || canEditName || canEditTopic) && roomType == RoomDetailsType.Room,
|
||||||
canShowNotificationSettings = canShowNotificationSettings.value,
|
|
||||||
roomCallState = roomCallState,
|
roomCallState = roomCallState,
|
||||||
roomType = roomType,
|
roomType = roomType,
|
||||||
roomMemberDetailsState = roomMemberDetailsState,
|
roomMemberDetailsState = roomMemberDetailsState,
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ data class RoomDetailsState(
|
||||||
val roomMemberDetailsState: UserProfileState?,
|
val roomMemberDetailsState: UserProfileState?,
|
||||||
val canEdit: Boolean,
|
val canEdit: Boolean,
|
||||||
val canInvite: Boolean,
|
val canInvite: Boolean,
|
||||||
val canShowNotificationSettings: Boolean,
|
|
||||||
val roomCallState: RoomCallState,
|
val roomCallState: RoomCallState,
|
||||||
val leaveRoomState: LeaveRoomState,
|
val leaveRoomState: LeaveRoomState,
|
||||||
val roomNotificationSettings: RoomNotificationSettings?,
|
val roomNotificationSettings: RoomNotificationSettings?,
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,6 @@ fun aRoomDetailsState(
|
||||||
isEncrypted: Boolean = true,
|
isEncrypted: Boolean = true,
|
||||||
canInvite: Boolean = false,
|
canInvite: Boolean = false,
|
||||||
canEdit: Boolean = false,
|
canEdit: Boolean = false,
|
||||||
canShowNotificationSettings: Boolean = true,
|
|
||||||
roomCallState: RoomCallState = aStandByCallState(),
|
roomCallState: RoomCallState = aStandByCallState(),
|
||||||
roomType: RoomDetailsType = RoomDetailsType.Room,
|
roomType: RoomDetailsType = RoomDetailsType.Room,
|
||||||
roomMemberDetailsState: UserProfileState? = null,
|
roomMemberDetailsState: UserProfileState? = null,
|
||||||
|
|
@ -132,7 +131,6 @@ fun aRoomDetailsState(
|
||||||
isEncrypted = isEncrypted,
|
isEncrypted = isEncrypted,
|
||||||
canInvite = canInvite,
|
canInvite = canInvite,
|
||||||
canEdit = canEdit,
|
canEdit = canEdit,
|
||||||
canShowNotificationSettings = canShowNotificationSettings,
|
|
||||||
roomCallState = roomCallState,
|
roomCallState = roomCallState,
|
||||||
roomType = roomType,
|
roomType = roomType,
|
||||||
roomMemberDetailsState = roomMemberDetailsState,
|
roomMemberDetailsState = roomMemberDetailsState,
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,7 @@ fun RoomDetailsView(
|
||||||
}
|
}
|
||||||
|
|
||||||
PreferenceCategory {
|
PreferenceCategory {
|
||||||
if (state.canShowNotificationSettings && state.roomNotificationSettings != null) {
|
if (state.roomNotificationSettings != null) {
|
||||||
NotificationItem(
|
NotificationItem(
|
||||||
isDefaultMode = state.roomNotificationSettings.isDefault,
|
isDefaultMode = state.roomNotificationSettings.isDefault,
|
||||||
openRoomNotificationSettings = openRoomNotificationSettings
|
openRoomNotificationSettings = openRoomNotificationSettings
|
||||||
|
|
@ -337,8 +337,7 @@ private fun MainActionsSection(
|
||||||
.padding(horizontal = 16.dp),
|
.padding(horizontal = 16.dp),
|
||||||
horizontalArrangement = Arrangement.SpaceEvenly,
|
horizontalArrangement = Arrangement.SpaceEvenly,
|
||||||
) {
|
) {
|
||||||
val roomNotificationSettings = state.roomNotificationSettings
|
state.roomNotificationSettings?.let { roomNotificationSettings ->
|
||||||
if (state.canShowNotificationSettings && roomNotificationSettings != null) {
|
|
||||||
if (roomNotificationSettings.mode == RoomNotificationMode.MUTE) {
|
if (roomNotificationSettings.mode == RoomNotificationMode.MUTE) {
|
||||||
MainActionButton(
|
MainActionButton(
|
||||||
title = stringResource(CommonStrings.common_unmute),
|
title = stringResource(CommonStrings.common_unmute),
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,6 @@ class RoomDetailsPresenterTest {
|
||||||
analyticsService: AnalyticsService = FakeAnalyticsService(),
|
analyticsService: AnalyticsService = FakeAnalyticsService(),
|
||||||
featureFlagService: FeatureFlagService = FakeFeatureFlagService(
|
featureFlagService: FeatureFlagService = FakeFeatureFlagService(
|
||||||
mapOf(
|
mapOf(
|
||||||
FeatureFlags.NotificationSettings.key to true,
|
|
||||||
FeatureFlags.Knock.key to false,
|
FeatureFlags.Knock.key to false,
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -21,12 +21,6 @@ enum class FeatureFlags(
|
||||||
override val defaultValue: (BuildMeta) -> Boolean,
|
override val defaultValue: (BuildMeta) -> Boolean,
|
||||||
override val isFinished: Boolean,
|
override val isFinished: Boolean,
|
||||||
) : Feature {
|
) : Feature {
|
||||||
NotificationSettings(
|
|
||||||
key = "feature.notificationsettings",
|
|
||||||
title = "Show notification settings",
|
|
||||||
defaultValue = { true },
|
|
||||||
isFinished = true,
|
|
||||||
),
|
|
||||||
VoiceMessages(
|
VoiceMessages(
|
||||||
key = "feature.voicemessages",
|
key = "feature.voicemessages",
|
||||||
title = "Voice messages",
|
title = "Voice messages",
|
||||||
|
|
@ -34,13 +28,6 @@ enum class FeatureFlags(
|
||||||
defaultValue = { true },
|
defaultValue = { true },
|
||||||
isFinished = true,
|
isFinished = true,
|
||||||
),
|
),
|
||||||
PinUnlock(
|
|
||||||
key = "feature.pinunlock",
|
|
||||||
title = "Pin unlock",
|
|
||||||
description = "Allow user to lock/unlock the app with a pin code or biometrics",
|
|
||||||
defaultValue = { true },
|
|
||||||
isFinished = true,
|
|
||||||
),
|
|
||||||
MarkAsUnread(
|
MarkAsUnread(
|
||||||
key = "feature.markAsUnread",
|
key = "feature.markAsUnread",
|
||||||
title = "Mark as unread",
|
title = "Mark as unread",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue