mirror of
https://github.com/bitwarden/android.git
synced 2024-10-31 15:15:34 +03:00
Clean up usages for the DateTimeFormatter (#1113)
This commit is contained in:
parent
9736aacd53
commit
c986131afd
12 changed files with 67 additions and 63 deletions
|
@ -322,7 +322,7 @@ private fun SendView.toDisplayItem(
|
|||
SearchState.DisplayItem(
|
||||
id = id.orEmpty(),
|
||||
title = name,
|
||||
subtitle = deletionDate.toFormattedPattern(DELETION_DATE_PATTERN, clock.zone),
|
||||
subtitle = deletionDate.toFormattedPattern(DELETION_DATE_PATTERN, clock),
|
||||
iconData = IconData.Local(
|
||||
iconRes = when (type) {
|
||||
SendType.TEXT -> R.drawable.ic_send_text
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.x8bit.bitwarden.data.platform.manager.model.SpecialCircumstance
|
|||
import com.x8bit.bitwarden.ui.platform.base.BaseViewModel
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.Text
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import com.x8bit.bitwarden.ui.platform.util.toFormattedPattern
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
@ -20,7 +21,6 @@ import kotlinx.coroutines.flow.update
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import java.time.Clock
|
||||
import java.time.format.DateTimeFormatter
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val KEY_STATE = "state"
|
||||
|
@ -52,11 +52,6 @@ class LoginApprovalViewModel @Inject constructor(
|
|||
)
|
||||
},
|
||||
) {
|
||||
private val dateTimeFormatter
|
||||
get() = DateTimeFormatter
|
||||
.ofPattern("M/d/yy hh:mm a")
|
||||
.withZone(clock.zone)
|
||||
|
||||
init {
|
||||
state
|
||||
.specialCircumstance
|
||||
|
@ -171,7 +166,10 @@ class LoginApprovalViewModel @Inject constructor(
|
|||
email = email,
|
||||
fingerprint = result.authRequest.fingerprint,
|
||||
ipAddress = result.authRequest.ipAddress,
|
||||
time = dateTimeFormatter.format(result.authRequest.creationDate),
|
||||
time = result.authRequest.creationDate.toFormattedPattern(
|
||||
pattern = "M/d/yy hh:mm a",
|
||||
clock = clock,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.x8bit.bitwarden.data.platform.repository.SettingsRepository
|
|||
import com.x8bit.bitwarden.ui.platform.base.BaseViewModel
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.Text
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.isOverFiveMinutesOld
|
||||
import com.x8bit.bitwarden.ui.platform.util.toFormattedPattern
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
|
@ -19,7 +20,6 @@ import kotlinx.coroutines.flow.update
|
|||
import kotlinx.coroutines.launch
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import java.time.Clock
|
||||
import java.time.format.DateTimeFormatter
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val KEY_STATE = "state"
|
||||
|
@ -42,11 +42,6 @@ class PendingRequestsViewModel @Inject constructor(
|
|||
) {
|
||||
private var authJob: Job = Job().apply { complete() }
|
||||
|
||||
private val dateTimeFormatter
|
||||
get() = DateTimeFormatter
|
||||
.ofPattern("M/d/yy hh:mm a")
|
||||
.withZone(clock.zone)
|
||||
|
||||
init {
|
||||
updateAuthRequestList()
|
||||
settingsRepository
|
||||
|
@ -140,8 +135,9 @@ class PendingRequestsViewModel @Inject constructor(
|
|||
PendingRequestsState.ViewState.Content.PendingLoginRequest(
|
||||
fingerprintPhrase = request.fingerprint,
|
||||
platform = request.platform,
|
||||
timestamp = dateTimeFormatter.format(
|
||||
request.creationDate,
|
||||
timestamp = request.creationDate.toFormattedPattern(
|
||||
pattern = "M/d/yy hh:mm a",
|
||||
clock = clock,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -217,6 +217,7 @@ class ExportVaultViewModel @Inject constructor(
|
|||
is ExportVaultDataResult.Success -> {
|
||||
val date = clock.instant().toFormattedPattern(
|
||||
pattern = "yyyyMMddHHmmss",
|
||||
clock = clock,
|
||||
)
|
||||
val extension = state.exportFormat.fileExtension
|
||||
val fileName = "bitwarden_export_$date.$extension"
|
||||
|
|
|
@ -42,7 +42,7 @@ class OtherViewModel @Inject constructor(
|
|||
clearClipboardFrequency = settingsRepo.clearClipboardFrequency,
|
||||
lastSyncTime = settingsRepo
|
||||
.vaultLastSync
|
||||
?.toFormattedPattern(VAULT_LAST_SYNC_TIME_PATTERN, clock.zone)
|
||||
?.toFormattedPattern(VAULT_LAST_SYNC_TIME_PATTERN, clock)
|
||||
.orEmpty(),
|
||||
dialogState = null,
|
||||
),
|
||||
|
@ -105,7 +105,7 @@ class OtherViewModel @Inject constructor(
|
|||
it.copy(
|
||||
lastSyncTime = action
|
||||
.vaultLastSyncTime
|
||||
?.toFormattedPattern(VAULT_LAST_SYNC_TIME_PATTERN, clock.zone)
|
||||
?.toFormattedPattern(VAULT_LAST_SYNC_TIME_PATTERN, clock)
|
||||
.orEmpty(),
|
||||
dialogState = null,
|
||||
)
|
||||
|
|
|
@ -1,17 +1,22 @@
|
|||
package com.x8bit.bitwarden.ui.platform.util
|
||||
|
||||
import java.time.Clock
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.time.temporal.TemporalAccessor
|
||||
import java.util.TimeZone
|
||||
|
||||
/**
|
||||
* Converts the [TemporalAccessor] to a formatted string based on the provided pattern and timezone.
|
||||
*/
|
||||
fun TemporalAccessor.toFormattedPattern(
|
||||
pattern: String,
|
||||
zone: ZoneId = TimeZone.getDefault().toZoneId(),
|
||||
): String {
|
||||
val formatter = DateTimeFormatter.ofPattern(pattern).withZone(zone)
|
||||
return formatter.format(this)
|
||||
}
|
||||
zone: ZoneId,
|
||||
): String = DateTimeFormatter.ofPattern(pattern).withZone(zone).format(this)
|
||||
|
||||
/**
|
||||
* Converts the [TemporalAccessor] to a formatted string based on the provided pattern and timezone.
|
||||
*/
|
||||
fun TemporalAccessor.toFormattedPattern(
|
||||
pattern: String,
|
||||
clock: Clock = Clock.systemDefaultZone(),
|
||||
): String = toFormattedPattern(pattern = pattern, zone = clock.zone)
|
||||
|
|
|
@ -24,6 +24,7 @@ import kotlinx.coroutines.flow.onEach
|
|||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.parcelize.Parcelize
|
||||
import java.time.Clock
|
||||
import javax.inject.Inject
|
||||
|
||||
private const val KEY_STATE = "state"
|
||||
|
@ -34,10 +35,11 @@ private const val KEY_STATE = "state"
|
|||
@HiltViewModel
|
||||
@Suppress("TooManyFunctions")
|
||||
class PasswordHistoryViewModel @Inject constructor(
|
||||
savedStateHandle: SavedStateHandle,
|
||||
private val clock: Clock,
|
||||
private val clipboardManager: BitwardenClipboardManager,
|
||||
private val generatorRepository: GeneratorRepository,
|
||||
private val vaultRepository: VaultRepository,
|
||||
savedStateHandle: SavedStateHandle,
|
||||
) : BaseViewModel<PasswordHistoryState, PasswordHistoryEvent, PasswordHistoryAction>(
|
||||
initialState = savedStateHandle[KEY_STATE]
|
||||
?: run {
|
||||
|
@ -138,6 +140,7 @@ class PasswordHistoryViewModel @Inject constructor(
|
|||
password = passwordHistoryView.password,
|
||||
date = passwordHistoryView.lastUsedDate.toFormattedPattern(
|
||||
pattern = "MM/dd/yy h:mm a",
|
||||
clock = clock,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -13,19 +13,16 @@ import com.x8bit.bitwarden.ui.platform.base.util.capitalize
|
|||
import com.x8bit.bitwarden.ui.platform.base.util.nullIfAllEqual
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.orNullIfBlank
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.orZeroWidthSpace
|
||||
import com.x8bit.bitwarden.ui.platform.util.toFormattedPattern
|
||||
import com.x8bit.bitwarden.ui.vault.feature.item.VaultItemState
|
||||
import com.x8bit.bitwarden.ui.vault.feature.item.model.TotpCodeItemData
|
||||
import com.x8bit.bitwarden.ui.vault.feature.vault.VaultState
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultCardBrand
|
||||
import com.x8bit.bitwarden.ui.vault.model.VaultLinkedFieldType
|
||||
import com.x8bit.bitwarden.ui.vault.model.findVaultCardBrandWithNameOrNull
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.TimeZone
|
||||
|
||||
private val dateTimeFormatter
|
||||
get() = DateTimeFormatter
|
||||
.ofPattern("M/d/yy hh:mm a")
|
||||
.withZone(TimeZone.getDefault().toZoneId())
|
||||
private const val DATE_TIME_PATTERN: String = "M/d/yy hh:mm a"
|
||||
|
||||
/**
|
||||
* Transforms [VaultData] into [VaultState.ViewState].
|
||||
|
@ -41,7 +38,10 @@ fun CipherView.toViewState(
|
|||
name = name,
|
||||
requiresReprompt = reprompt == CipherRepromptType.PASSWORD,
|
||||
customFields = fields.orEmpty().map { it.toCustomField() },
|
||||
lastUpdated = dateTimeFormatter.format(revisionDate),
|
||||
lastUpdated = revisionDate.toFormattedPattern(
|
||||
pattern = DATE_TIME_PATTERN,
|
||||
zone = TimeZone.getDefault().toZoneId(),
|
||||
),
|
||||
notes = notes,
|
||||
attachments = attachments
|
||||
?.mapNotNull {
|
||||
|
@ -83,9 +83,12 @@ fun CipherView.toViewState(
|
|||
)
|
||||
},
|
||||
uris = loginValues.uris.orEmpty().map { it.toUriData() },
|
||||
passwordRevisionDate = loginValues.passwordRevisionDate?.let {
|
||||
dateTimeFormatter.format(it)
|
||||
},
|
||||
passwordRevisionDate = loginValues
|
||||
.passwordRevisionDate
|
||||
?.toFormattedPattern(
|
||||
pattern = DATE_TIME_PATTERN,
|
||||
zone = TimeZone.getDefault().toZoneId(),
|
||||
),
|
||||
passwordHistoryCount = passwordHistory?.count(),
|
||||
isPremiumUser = isPremiumUser,
|
||||
totpCodeItemData = totpCodeItemData,
|
||||
|
|
|
@ -283,7 +283,7 @@ private fun SendView.toDisplayItem(
|
|||
VaultItemListingState.DisplayItem(
|
||||
id = id.orEmpty(),
|
||||
title = name,
|
||||
subtitle = deletionDate.toFormattedPattern(DELETION_DATE_PATTERN, clock.zone),
|
||||
subtitle = deletionDate.toFormattedPattern(DELETION_DATE_PATTERN, clock),
|
||||
iconData = IconData.Local(
|
||||
iconRes = when (type) {
|
||||
SendType.TEXT -> R.drawable.ic_send_text
|
||||
|
|
|
@ -20,14 +20,11 @@ import io.mockk.coVerify
|
|||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.time.Clock
|
||||
import java.time.Instant
|
||||
import java.time.ZoneOffset
|
||||
import java.util.TimeZone
|
||||
|
||||
class ExportVaultViewModelTest : BaseViewModelTest() {
|
||||
private val authRepository: AuthRepository = mockk()
|
||||
|
@ -48,16 +45,6 @@ class ExportVaultViewModelTest : BaseViewModelTest() {
|
|||
}
|
||||
private val fileManager: FileManager = mockk()
|
||||
|
||||
@BeforeEach
|
||||
fun setup() {
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("UTC"))
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun teardown() {
|
||||
TimeZone.setDefault(null)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `initial state should be correct`() = runTest {
|
||||
every {
|
||||
|
|
|
@ -2,13 +2,15 @@ package com.x8bit.bitwarden.ui.platform.util
|
|||
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.time.Clock
|
||||
import java.time.Instant
|
||||
import java.time.ZoneId
|
||||
import java.time.ZoneOffset
|
||||
|
||||
class TemporalAccessorExtensionsTest {
|
||||
|
||||
@Test
|
||||
fun `toFormattedPattern should return correctly formatted string`() {
|
||||
fun `toFormattedPattern should return correctly formatted string with timezone`() {
|
||||
val instant = Instant.parse("2023-12-10T15:30:00Z")
|
||||
val pattern = "MM/dd/yyyy hh:mm a"
|
||||
val zone = ZoneId.of("UTC")
|
||||
|
@ -17,4 +19,18 @@ class TemporalAccessorExtensionsTest {
|
|||
|
||||
assertEquals(expectedFormattedString, formattedString)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `toFormattedPattern should return correctly formatted string with clock`() {
|
||||
val instant = Instant.parse("2023-12-10T15:30:00Z")
|
||||
val pattern = "MM/dd/yyyy hh:mm a"
|
||||
val clock: Clock = Clock.fixed(
|
||||
Instant.parse("2023-10-27T12:00:00Z"),
|
||||
ZoneOffset.UTC,
|
||||
)
|
||||
val expectedFormattedString = "12/10/2023 03:30 PM"
|
||||
val formattedString = instant.toFormattedPattern(pattern, clock)
|
||||
|
||||
assertEquals(expectedFormattedString, formattedString)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,18 +22,21 @@ import io.mockk.runs
|
|||
import io.mockk.verify
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.AfterEach
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertTrue
|
||||
import org.junit.jupiter.api.BeforeEach
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.time.Clock
|
||||
import java.time.Instant
|
||||
import java.util.TimeZone
|
||||
import java.time.ZoneOffset
|
||||
|
||||
class PasswordHistoryViewModelTest : BaseViewModelTest() {
|
||||
|
||||
private val initialState = createPasswordHistoryState()
|
||||
|
||||
private val fixedClock: Clock = Clock.fixed(
|
||||
Instant.parse("2023-10-27T12:00:00Z"),
|
||||
ZoneOffset.UTC,
|
||||
)
|
||||
private val clipboardManager: BitwardenClipboardManager = mockk()
|
||||
private val fakeGeneratorRepository = FakeGeneratorRepository()
|
||||
private val mutableVaultItemFlow = MutableStateFlow<DataState<CipherView?>>(DataState.Loading)
|
||||
|
@ -41,16 +44,6 @@ class PasswordHistoryViewModelTest : BaseViewModelTest() {
|
|||
every { getVaultItemStateFlow("mockId-1") } returns mutableVaultItemFlow
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
fun setUp() {
|
||||
TimeZone.setDefault(TimeZone.getTimeZone("UTC"))
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
fun tearDown() {
|
||||
TimeZone.setDefault(null)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `initial state should be correct`() = runTest {
|
||||
val viewModel = createViewModel()
|
||||
|
@ -200,6 +193,7 @@ class PasswordHistoryViewModelTest : BaseViewModelTest() {
|
|||
password = "password",
|
||||
date = passwordHistoryView.lastUsedDate.toFormattedPattern(
|
||||
pattern = "MM/dd/yy h:mm a",
|
||||
clock = fixedClock,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -260,10 +254,11 @@ class PasswordHistoryViewModelTest : BaseViewModelTest() {
|
|||
private fun createViewModel(
|
||||
initialState: PasswordHistoryState = createPasswordHistoryState(),
|
||||
): PasswordHistoryViewModel = PasswordHistoryViewModel(
|
||||
savedStateHandle = createSavedStateHandleWithState(state = initialState),
|
||||
clock = fixedClock,
|
||||
clipboardManager = clipboardManager,
|
||||
generatorRepository = fakeGeneratorRepository,
|
||||
vaultRepository = fakeVaultRepository,
|
||||
savedStateHandle = createSavedStateHandleWithState(state = initialState),
|
||||
)
|
||||
|
||||
private fun createPasswordHistoryState(
|
||||
|
|
Loading…
Reference in a new issue