Skip to content

Commit 5eea234

Browse files
PM-30130: Remove the Archive Items feature flag
1 parent 8c5c145 commit 5eea234

29 files changed

Lines changed: 31 additions & 413 deletions

File tree

app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/search/SearchViewModel.kt

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import android.os.Parcelable
44
import androidx.lifecycle.SavedStateHandle
55
import androidx.lifecycle.viewModelScope
66
import com.bitwarden.annotation.OmitFromCoverage
7-
import com.bitwarden.core.data.manager.model.FlagKey
87
import com.bitwarden.core.data.repository.model.DataState
98
import com.bitwarden.data.repository.util.baseIconUrl
109
import com.bitwarden.data.repository.util.baseWebSendUrl
@@ -30,7 +29,6 @@ import com.x8bit.bitwarden.data.autofill.accessibility.manager.AccessibilitySele
3029
import com.x8bit.bitwarden.data.autofill.manager.AutofillSelectionManager
3130
import com.x8bit.bitwarden.data.autofill.model.AutofillSelectionData
3231
import com.x8bit.bitwarden.data.autofill.util.login
33-
import com.x8bit.bitwarden.data.platform.manager.FeatureFlagManager
3432
import com.x8bit.bitwarden.data.platform.manager.PolicyManager
3533
import com.x8bit.bitwarden.data.platform.manager.SpecialCircumstanceManager
3634
import com.x8bit.bitwarden.data.platform.manager.clipboard.BitwardenClipboardManager
@@ -104,7 +102,6 @@ class SearchViewModel @Inject constructor(
104102
settingsRepo: SettingsRepository,
105103
snackbarRelayManager: SnackbarRelayManager<SnackbarRelay>,
106104
specialCircumstanceManager: SpecialCircumstanceManager,
107-
featureFlagManager: FeatureFlagManager,
108105
) : BaseViewModel<SearchState, SearchEvent, SearchAction>(
109106
// We load the state from the savedStateHandle for testing purposes.
110107
initialState = savedStateHandle[KEY_STATE]
@@ -140,7 +137,6 @@ class SearchViewModel @Inject constructor(
140137
hasMasterPassword = userState.activeAccount.hasMasterPassword,
141138
isPremium = userState.activeAccount.isPremium,
142139
restrictItemTypesPolicyOrgIds = persistentListOf(),
143-
isArchiveEnabled = featureFlagManager.getFeatureFlag(FlagKey.ArchiveItems),
144140
)
145141
},
146142
) {
@@ -180,12 +176,6 @@ class SearchViewModel @Inject constructor(
180176
.map { SearchAction.Internal.SnackbarDataReceived(it) }
181177
.onEach(::sendAction)
182178
.launchIn(viewModelScope)
183-
184-
featureFlagManager
185-
.getFeatureFlagFlow(FlagKey.ArchiveItems)
186-
.map { SearchAction.Internal.ArchiveItemsFlagUpdateReceive(it) }
187-
.onEach(::sendAction)
188-
.launchIn(viewModelScope)
189179
}
190180

191181
override fun handleAction(action: SearchAction) {
@@ -640,10 +630,6 @@ class SearchViewModel @Inject constructor(
640630
handleDecryptCipherErrorReceive(action)
641631
}
642632

643-
is SearchAction.Internal.ArchiveItemsFlagUpdateReceive -> {
644-
handleArchiveItemsFlagUpdateReceive(action)
645-
}
646-
647633
is SearchAction.Internal.ArchiveCipherReceive -> handleArchiveCipherReceive(action)
648634
is SearchAction.Internal.UnarchiveCipherReceive -> handleUnarchiveCipherReceive(action)
649635
}
@@ -663,12 +649,6 @@ class SearchViewModel @Inject constructor(
663649
}
664650
}
665651

666-
private fun handleArchiveItemsFlagUpdateReceive(
667-
action: SearchAction.Internal.ArchiveItemsFlagUpdateReceive,
668-
) {
669-
mutableStateFlow.update { it.copy(isArchiveEnabled = action.isEnabled) }
670-
}
671-
672652
private fun handleArchiveCipherReceive(action: SearchAction.Internal.ArchiveCipherReceive) {
673653
when (val result = action.result) {
674654
is ArchiveCipherResult.Error -> {
@@ -1017,7 +997,6 @@ class SearchViewModel @Inject constructor(
1017997
isIconLoadingDisabled = state.isIconLoadingDisabled,
1018998
isAutofill = state.isAutofill,
1019999
isPremiumUser = state.isPremium,
1020-
isArchiveEnabled = state.isArchiveEnabled,
10211000
)
10221001
}
10231002

@@ -1084,7 +1063,6 @@ data class SearchState(
10841063
val hasMasterPassword: Boolean,
10851064
val isPremium: Boolean,
10861065
val restrictItemTypesPolicyOrgIds: ImmutableList<String>,
1087-
val isArchiveEnabled: Boolean,
10881066
) : Parcelable {
10891067

10901068
/**
@@ -1537,13 +1515,6 @@ sealed class SearchAction {
15371515
data class DecryptCipherErrorReceive(
15381516
val error: Throwable?,
15391517
) : Internal()
1540-
1541-
/**
1542-
* Indicates that the Archive Items flag has been updated.
1543-
*/
1544-
data class ArchiveItemsFlagUpdateReceive(
1545-
val isEnabled: Boolean,
1546-
) : Internal()
15471518
}
15481519
}
15491520

app/src/main/kotlin/com/x8bit/bitwarden/ui/platform/feature/search/util/SearchTypeDataExtensions.kt

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,6 @@ fun List<CipherListView>.toViewState(
189189
isIconLoadingDisabled: Boolean,
190190
isAutofill: Boolean,
191191
isPremiumUser: Boolean,
192-
isArchiveEnabled: Boolean,
193192
): SearchState.ViewState =
194193
when {
195194
searchTerm.isEmpty() -> SearchState.ViewState.Empty(message = null)
@@ -201,7 +200,6 @@ fun List<CipherListView>.toViewState(
201200
isIconLoadingDisabled = isIconLoadingDisabled,
202201
isAutofill = isAutofill,
203202
isPremiumUser = isPremiumUser,
204-
isArchiveEnabled = isArchiveEnabled,
205203
),
206204
)
207205
}
@@ -213,14 +211,12 @@ fun List<CipherListView>.toViewState(
213211
}
214212
}
215213

216-
@Suppress("LongParameterList")
217214
private fun List<CipherListView>.toDisplayItemList(
218215
baseIconUrl: String,
219216
hasMasterPassword: Boolean,
220217
isIconLoadingDisabled: Boolean,
221218
isAutofill: Boolean,
222219
isPremiumUser: Boolean,
223-
isArchiveEnabled: Boolean,
224220
): ImmutableList<SearchState.DisplayItem> =
225221
this
226222
.map {
@@ -230,20 +226,17 @@ private fun List<CipherListView>.toDisplayItemList(
230226
isIconLoadingDisabled = isIconLoadingDisabled,
231227
isAutofill = isAutofill,
232228
isPremiumUser = isPremiumUser,
233-
isArchiveEnabled = isArchiveEnabled,
234229
)
235230
}
236231
.sortAlphabetically()
237232
.toImmutableList()
238233

239-
@Suppress("LongParameterList")
240234
private fun CipherListView.toDisplayItem(
241235
baseIconUrl: String,
242236
hasMasterPassword: Boolean,
243237
isIconLoadingDisabled: Boolean,
244238
isAutofill: Boolean,
245239
isPremiumUser: Boolean,
246-
isArchiveEnabled: Boolean,
247240
): SearchState.DisplayItem =
248241
SearchState.DisplayItem(
249242
id = id.orEmpty(),
@@ -259,7 +252,6 @@ private fun CipherListView.toDisplayItem(
259252
overflowOptions = toOverflowActions(
260253
hasMasterPassword = hasMasterPassword,
261254
isPremiumUser = isPremiumUser,
262-
isArchiveEnabled = isArchiveEnabled,
263255
),
264256
overflowTestTag = "CipherOptionsButton",
265257
totpCode = login?.totp,

app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/addedit/VaultAddEditViewModel.kt

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import androidx.credentials.CreatePublicKeyCredentialRequest
55
import androidx.credentials.provider.CallingAppInfo
66
import androidx.lifecycle.SavedStateHandle
77
import androidx.lifecycle.viewModelScope
8-
import com.bitwarden.core.data.manager.model.FlagKey
98
import com.bitwarden.core.data.manager.toast.ToastManager
109
import com.bitwarden.core.data.repository.model.DataState
1110
import com.bitwarden.core.data.repository.util.takeUntilLoaded
@@ -34,7 +33,6 @@ import com.x8bit.bitwarden.data.credentials.manager.BitwardenCredentialManager
3433
import com.x8bit.bitwarden.data.credentials.model.CreateCredentialRequest
3534
import com.x8bit.bitwarden.data.credentials.model.Fido2RegisterCredentialResult
3635
import com.x8bit.bitwarden.data.credentials.model.UserVerificationRequirement
37-
import com.x8bit.bitwarden.data.platform.manager.FeatureFlagManager
3836
import com.x8bit.bitwarden.data.platform.manager.FirstTimeActionManager
3937
import com.x8bit.bitwarden.data.platform.manager.PolicyManager
4038
import com.x8bit.bitwarden.data.platform.manager.SpecialCircumstanceManager
@@ -119,7 +117,6 @@ private const val KEY_STATE = "state"
119117
@Suppress("TooManyFunctions", "LargeClass", "LongParameterList", "LongMethod")
120118
class VaultAddEditViewModel @Inject constructor(
121119
savedStateHandle: SavedStateHandle,
122-
featureFlagManager: FeatureFlagManager,
123120
generatorRepository: GeneratorRepository,
124121
private val snackbarRelayManager: SnackbarRelayManager<SnackbarRelay>,
125122
private val toastManager: ToastManager,
@@ -177,7 +174,6 @@ class VaultAddEditViewModel @Inject constructor(
177174
}
178175

179176
VaultAddEditState(
180-
isArchiveEnabled = featureFlagManager.getFeatureFlag(FlagKey.ArchiveItems),
181177
vaultAddEditType = vaultAddEditType,
182178
cipherType = vaultCipherType,
183179
viewState = when (vaultAddEditType) {
@@ -273,12 +269,6 @@ class VaultAddEditViewModel @Inject constructor(
273269
.onEach(::sendAction)
274270
.launchIn(viewModelScope)
275271

276-
featureFlagManager
277-
.getFeatureFlagFlow(FlagKey.ArchiveItems)
278-
.map { VaultAddEditAction.Internal.ArchiveItemsFlagUpdateReceive(it) }
279-
.onEach(::sendAction)
280-
.launchIn(viewModelScope)
281-
282272
snackbarRelayManager
283273
.getSnackbarDataFlow(SnackbarRelay.CIPHER_MOVED_TO_ORGANIZATION)
284274
.map { VaultAddEditAction.Internal.SnackbarDataReceived(it) }
@@ -1649,10 +1639,6 @@ class VaultAddEditViewModel @Inject constructor(
16491639
handleUnarchiveCipherReceive(action)
16501640
}
16511641

1652-
is VaultAddEditAction.Internal.ArchiveItemsFlagUpdateReceive -> {
1653-
handleArchiveItemsFlagUpdateReceive(action)
1654-
}
1655-
16561642
is VaultAddEditAction.Internal.DeleteCipherReceive -> handleDeleteCipherReceive(action)
16571643
is VaultAddEditAction.Internal.TotpCodeReceive -> handleVaultTotpCodeReceive(action)
16581644
is VaultAddEditAction.Internal.VaultDataReceive -> handleVaultDataReceive(action)
@@ -1864,12 +1850,6 @@ class VaultAddEditViewModel @Inject constructor(
18641850
}
18651851
}
18661852

1867-
private fun handleArchiveItemsFlagUpdateReceive(
1868-
action: VaultAddEditAction.Internal.ArchiveItemsFlagUpdateReceive,
1869-
) {
1870-
mutableStateFlow.update { it.copy(isArchiveEnabled = action.isEnabled) }
1871-
}
1872-
18731853
private fun handleDeleteCipherReceive(action: VaultAddEditAction.Internal.DeleteCipherReceive) {
18741854
when (val result = action.result) {
18751855
is DeleteCipherResult.Error -> {
@@ -2427,7 +2407,6 @@ data class VaultAddEditState(
24272407
val createCredentialRequest: CreateCredentialRequest? = null,
24282408
val defaultUriMatchType: UriMatchType,
24292409
private val shouldShowCoachMarkTour: Boolean,
2430-
private val isArchiveEnabled: Boolean,
24312410
) : Parcelable {
24322411

24332412
/**
@@ -2484,8 +2463,7 @@ data class VaultAddEditState(
24842463
* Helper to determine if the UI should display the archive button.
24852464
*/
24862465
val displayArchiveButton: Boolean
2487-
get() = isArchiveEnabled &&
2488-
isEditItemMode &&
2466+
get() = isEditItemMode &&
24892467
(viewState as? ViewState.Content)
24902468
?.common
24912469
?.originalCipher
@@ -2495,8 +2473,7 @@ data class VaultAddEditState(
24952473
* Helper to determine if the UI should display the unarchive button.
24962474
*/
24972475
val displayUnarchiveButton: Boolean
2498-
get() = isArchiveEnabled &&
2499-
isEditItemMode &&
2476+
get() = isEditItemMode &&
25002477
(viewState as? ViewState.Content)
25012478
?.common
25022479
?.originalCipher
@@ -3834,12 +3811,5 @@ sealed class VaultAddEditAction {
38343811
data class AvailableFoldersReceive(
38353812
val folderData: DataState<List<FolderView>>,
38363813
) : Internal()
3837-
3838-
/**
3839-
* Indicates that the Archive Items flag has been updated.
3840-
*/
3841-
data class ArchiveItemsFlagUpdateReceive(
3842-
val isEnabled: Boolean,
3843-
) : Internal()
38443814
}
38453815
}

app/src/main/kotlin/com/x8bit/bitwarden/ui/vault/feature/item/VaultItemViewModel.kt

Lines changed: 8 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import android.net.Uri
44
import android.os.Parcelable
55
import androidx.lifecycle.SavedStateHandle
66
import androidx.lifecycle.viewModelScope
7-
import com.bitwarden.core.data.manager.model.FlagKey
87
import com.bitwarden.core.data.repository.model.DataState
98
import com.bitwarden.core.data.repository.util.combineDataStates
109
import com.bitwarden.core.data.repository.util.mapNullable
@@ -27,7 +26,6 @@ import com.bitwarden.vault.CipherView
2726
import com.x8bit.bitwarden.data.auth.repository.AuthRepository
2827
import com.x8bit.bitwarden.data.auth.repository.model.BreachCountResult
2928
import com.x8bit.bitwarden.data.auth.repository.model.UserState
30-
import com.x8bit.bitwarden.data.platform.manager.FeatureFlagManager
3129
import com.x8bit.bitwarden.data.platform.manager.clipboard.BitwardenClipboardManager
3230
import com.x8bit.bitwarden.data.platform.manager.event.OrganizationEventManager
3331
import com.x8bit.bitwarden.data.platform.manager.model.OrganizationEvent
@@ -81,7 +79,6 @@ class VaultItemViewModel @Inject constructor(
8179
private val environmentRepository: EnvironmentRepository,
8280
private val settingsRepository: SettingsRepository,
8381
private val snackbarRelayManager: SnackbarRelayManager<SnackbarRelay>,
84-
featureFlagManager: FeatureFlagManager,
8582
) : BaseViewModel<VaultItemState, VaultItemEvent, VaultItemAction>(
8683
// We load the state from the savedStateHandle for testing purposes.
8784
initialState = savedStateHandle[KEY_STATE] ?: run {
@@ -94,7 +91,6 @@ class VaultItemViewModel @Inject constructor(
9491
baseIconUrl = environmentRepository.environment.environmentUrlData.baseIconUrl,
9592
isIconLoadingDisabled = settingsRepository.isIconLoadingDisabled,
9693
hasPremium = authRepository.userStateFlow.value?.activeAccount?.isPremium == true,
97-
isArchiveEnabled = featureFlagManager.getFeatureFlag(FlagKey.ArchiveItems),
9894
)
9995
},
10096
) {
@@ -231,12 +227,6 @@ class VaultItemViewModel @Inject constructor(
231227
.map { VaultItemAction.Internal.SnackbarDataReceived(it) }
232228
.onEach(::sendAction)
233229
.launchIn(viewModelScope)
234-
235-
featureFlagManager
236-
.getFeatureFlagFlow(FlagKey.ArchiveItems)
237-
.map { VaultItemAction.Internal.ArchiveItemsFlagUpdateReceive(it) }
238-
.onEach(::sendAction)
239-
.launchIn(viewModelScope)
240230
}
241231

242232
override fun handleAction(action: VaultItemAction) {
@@ -1062,10 +1052,6 @@ class VaultItemViewModel @Inject constructor(
10621052
handleIsIconLoadingDisabledUpdateReceive(action)
10631053
}
10641054

1065-
is VaultItemAction.Internal.ArchiveItemsFlagUpdateReceive -> {
1066-
handleArchiveItemsFlagUpdateReceive(action)
1067-
}
1068-
10691055
is VaultItemAction.Internal.ArchiveCipherReceive -> handleArchiveCipherReceive(action)
10701056
is VaultItemAction.Internal.UnarchiveCipherReceive -> {
10711057
handleUnarchiveCipherReceive(action)
@@ -1301,12 +1287,6 @@ class VaultItemViewModel @Inject constructor(
13011287
mutableStateFlow.update { it.copy(isIconLoadingDisabled = action.isDisabled) }
13021288
}
13031289

1304-
private fun handleArchiveItemsFlagUpdateReceive(
1305-
action: VaultItemAction.Internal.ArchiveItemsFlagUpdateReceive,
1306-
) {
1307-
mutableStateFlow.update { it.copy(isArchiveEnabled = action.isEnabled) }
1308-
}
1309-
13101290
private fun handleArchiveCipherReceive(action: VaultItemAction.Internal.ArchiveCipherReceive) {
13111291
when (val result = action.result) {
13121292
is ArchiveCipherResult.Error -> {
@@ -1445,7 +1425,6 @@ data class VaultItemState(
14451425
val dialog: DialogState?,
14461426
val baseIconUrl: String,
14471427
val isIconLoadingDisabled: Boolean,
1448-
val isArchiveEnabled: Boolean,
14491428
val hasPremium: Boolean,
14501429
) : Parcelable {
14511430

@@ -1512,21 +1491,19 @@ data class VaultItemState(
15121491
* Helper to determine if the UI should display the archive button.
15131492
*/
15141493
val displayArchiveButton: Boolean
1515-
get() = isArchiveEnabled &&
1516-
viewState.asContentOrNull()
1517-
?.common
1518-
?.currentCipher
1519-
?.let { it.archivedDate == null && it.deletedDate == null } == true
1494+
get() = viewState.asContentOrNull()
1495+
?.common
1496+
?.currentCipher
1497+
?.let { it.archivedDate == null && it.deletedDate == null } == true
15201498

15211499
/**
15221500
* Helper to determine if the UI should display the unarchive button.
15231501
*/
15241502
val displayUnarchiveButton: Boolean
1525-
get() = isArchiveEnabled &&
1526-
viewState.asContentOrNull()
1527-
?.common
1528-
?.currentCipher
1529-
?.let { it.archivedDate != null && it.deletedDate == null } == true
1503+
get() = viewState.asContentOrNull()
1504+
?.common
1505+
?.currentCipher
1506+
?.let { it.archivedDate != null && it.deletedDate == null } == true
15301507

15311508
val canAssignToCollections: Boolean
15321509
get() = viewState.asContentOrNull()
@@ -2371,13 +2348,6 @@ sealed class VaultItemAction {
23712348
val data: BitwardenSnackbarData,
23722349
) : Internal()
23732350

2374-
/**
2375-
* Indicates that the Archive Items flag has been updated.
2376-
*/
2377-
data class ArchiveItemsFlagUpdateReceive(
2378-
val isEnabled: Boolean,
2379-
) : Internal()
2380-
23812351
/**
23822352
* Indicates that the archive cipher result has been received.
23832353
*/

0 commit comments

Comments
 (0)