mirror of
https://github.com/bitwarden/android.git
synced 2025-03-15 10:48:47 +03:00
Add helper method for getting sendView icons (#678)
This commit is contained in:
parent
cb306a8377
commit
2c749186e1
9 changed files with 151 additions and 70 deletions
|
@ -1,10 +1,12 @@
|
|||
package com.x8bit.bitwarden.ui.platform.components.model
|
||||
|
||||
import android.os.Parcelable
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.Text
|
||||
import kotlinx.parcelize.Parcelize
|
||||
|
||||
/**
|
||||
* Data class representing the resources required for an icon.
|
||||
|
@ -23,11 +25,12 @@ data class IconResource(
|
|||
* @property iconRes Resource for the icon.
|
||||
* @property contentDescription The icon's content description.
|
||||
*/
|
||||
@Parcelize
|
||||
data class IconRes(
|
||||
@DrawableRes
|
||||
val iconRes: Int,
|
||||
val contentDescription: Text,
|
||||
)
|
||||
) : Parcelable
|
||||
|
||||
/**
|
||||
* A helper method to convert a list of [IconRes] to a list of [IconResource].
|
||||
|
|
|
@ -15,10 +15,10 @@ import com.x8bit.bitwarden.ui.platform.components.BitwardenListItem
|
|||
import com.x8bit.bitwarden.ui.platform.components.BitwardenTwoButtonDialog
|
||||
import com.x8bit.bitwarden.ui.platform.components.SelectionItemData
|
||||
import com.x8bit.bitwarden.ui.platform.components.model.IconData
|
||||
import com.x8bit.bitwarden.ui.platform.components.model.IconRes
|
||||
import com.x8bit.bitwarden.ui.platform.components.model.IconResource
|
||||
import com.x8bit.bitwarden.ui.platform.theme.BitwardenTheme
|
||||
import com.x8bit.bitwarden.ui.platform.util.persistentListOfNotNull
|
||||
import com.x8bit.bitwarden.ui.tools.feature.send.model.SendStatusIcon
|
||||
import kotlinx.collections.immutable.toPersistentList
|
||||
|
||||
/**
|
||||
|
@ -43,7 +43,7 @@ fun SendListItem(
|
|||
label: String,
|
||||
supportingLabel: String,
|
||||
startIcon: IconData,
|
||||
trailingLabelIcons: List<SendStatusIcon>,
|
||||
trailingLabelIcons: List<IconRes>,
|
||||
onClick: () -> Unit,
|
||||
onEditClick: () -> Unit,
|
||||
onCopyClick: () -> Unit,
|
||||
|
|
|
@ -18,7 +18,7 @@ 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.base.util.concat
|
||||
import com.x8bit.bitwarden.ui.tools.feature.send.model.SendStatusIcon
|
||||
import com.x8bit.bitwarden.ui.platform.components.model.IconRes
|
||||
import com.x8bit.bitwarden.ui.tools.feature.send.util.toViewState
|
||||
import com.x8bit.bitwarden.ui.vault.feature.item.VaultItemScreen
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
|
@ -350,7 +350,7 @@ data class SendState(
|
|||
val name: String,
|
||||
val deletionDate: String,
|
||||
val type: Type,
|
||||
val iconList: List<SendStatusIcon>,
|
||||
val iconList: List<IconRes>,
|
||||
val shareUrl: String,
|
||||
val hasPassword: Boolean,
|
||||
) : Parcelable {
|
||||
|
|
|
@ -5,8 +5,6 @@ import com.bitwarden.core.SendView
|
|||
import com.x8bit.bitwarden.data.vault.repository.model.SendData
|
||||
import com.x8bit.bitwarden.ui.platform.util.toFormattedPattern
|
||||
import com.x8bit.bitwarden.ui.tools.feature.send.SendState
|
||||
import com.x8bit.bitwarden.ui.tools.feature.send.model.SendStatusIcon
|
||||
import java.time.Instant
|
||||
|
||||
private const val DELETION_DATE_PATTERN: String = "MMM d, uuuu, hh:mm a"
|
||||
|
||||
|
@ -38,21 +36,7 @@ private fun List<SendView>.toSendContent(
|
|||
SendType.TEXT -> SendState.ViewState.Content.SendItem.Type.TEXT
|
||||
SendType.FILE -> SendState.ViewState.Content.SendItem.Type.FILE
|
||||
},
|
||||
iconList = listOfNotNull(
|
||||
SendStatusIcon.DISABLED.takeIf { sendView.disabled },
|
||||
SendStatusIcon.PASSWORD.takeIf { sendView.hasPassword },
|
||||
SendStatusIcon.MAX_ACCESS_COUNT_REACHED.takeIf {
|
||||
sendView.maxAccessCount?.let { maxCount ->
|
||||
sendView.accessCount >= maxCount
|
||||
} == true
|
||||
},
|
||||
SendStatusIcon.EXPIRED.takeIf {
|
||||
sendView.expirationDate?.isBefore(Instant.now()) == true
|
||||
},
|
||||
SendStatusIcon.PENDING_DELETE.takeIf {
|
||||
sendView.deletionDate.isBefore(Instant.now())
|
||||
},
|
||||
),
|
||||
iconList = sendView.toLabelIcons(),
|
||||
shareUrl = sendView.toSendUrl(baseWebSendUrl),
|
||||
hasPassword = sendView.hasPassword,
|
||||
)
|
||||
|
|
|
@ -1,6 +1,24 @@
|
|||
package com.x8bit.bitwarden.ui.tools.feature.send.util
|
||||
|
||||
import com.bitwarden.core.SendView
|
||||
import com.x8bit.bitwarden.ui.platform.components.model.IconRes
|
||||
import com.x8bit.bitwarden.ui.tools.feature.send.model.SendStatusIcon
|
||||
import java.time.Clock
|
||||
|
||||
/**
|
||||
* Creates the list of trailing label icons to be displayed for a [SendView].
|
||||
*/
|
||||
fun SendView.toLabelIcons(clock: Clock = Clock.systemDefaultZone()): List<IconRes> =
|
||||
listOfNotNull(
|
||||
SendStatusIcon.DISABLED.takeIf { disabled },
|
||||
SendStatusIcon.PASSWORD.takeIf { hasPassword },
|
||||
SendStatusIcon.MAX_ACCESS_COUNT_REACHED.takeIf {
|
||||
maxAccessCount?.let { maxCount -> accessCount >= maxCount } == true
|
||||
},
|
||||
SendStatusIcon.EXPIRED.takeIf { expirationDate?.isBefore(clock.instant()) == true },
|
||||
SendStatusIcon.PENDING_DELETE.takeIf { deletionDate.isBefore(clock.instant()) },
|
||||
)
|
||||
.map { IconRes(iconRes = it.iconRes, contentDescription = it.contentDescription) }
|
||||
|
||||
/**
|
||||
* Creates a sharable url from a [SendView].
|
||||
|
|
|
@ -10,8 +10,7 @@ import com.bitwarden.core.SendView
|
|||
import com.x8bit.bitwarden.R
|
||||
import com.x8bit.bitwarden.ui.platform.base.util.asText
|
||||
import com.x8bit.bitwarden.ui.platform.components.model.IconData
|
||||
import com.x8bit.bitwarden.ui.platform.components.model.IconRes
|
||||
import com.x8bit.bitwarden.ui.tools.feature.send.model.SendStatusIcon
|
||||
import com.x8bit.bitwarden.ui.tools.feature.send.util.toLabelIcons
|
||||
import com.x8bit.bitwarden.ui.tools.feature.send.util.toSendUrl
|
||||
import com.x8bit.bitwarden.ui.vault.feature.itemlisting.VaultItemListingState
|
||||
import com.x8bit.bitwarden.ui.vault.feature.itemlisting.VaultItemListingsAction
|
||||
|
@ -207,23 +206,7 @@ private fun SendView.toDisplayItem(
|
|||
SendType.FILE -> R.drawable.ic_send_file
|
||||
},
|
||||
),
|
||||
extraIconList = listOfNotNull(
|
||||
SendStatusIcon.DISABLED
|
||||
.takeIf { disabled }
|
||||
?.let { IconRes(iconRes = it.iconRes, contentDescription = it.contentDescription) },
|
||||
SendStatusIcon.PASSWORD
|
||||
.takeIf { hasPassword }
|
||||
?.let { IconRes(iconRes = it.iconRes, contentDescription = it.contentDescription) },
|
||||
SendStatusIcon.MAX_ACCESS_COUNT_REACHED
|
||||
.takeIf { maxAccessCount?.let { maxCount -> accessCount >= maxCount } == true }
|
||||
?.let { IconRes(iconRes = it.iconRes, contentDescription = it.contentDescription) },
|
||||
SendStatusIcon.EXPIRED
|
||||
.takeIf { expirationDate?.isBefore(clock.instant()) == true }
|
||||
?.let { IconRes(iconRes = it.iconRes, contentDescription = it.contentDescription) },
|
||||
SendStatusIcon.PENDING_DELETE
|
||||
.takeIf { deletionDate.isBefore(clock.instant()) }
|
||||
?.let { IconRes(iconRes = it.iconRes, contentDescription = it.contentDescription) },
|
||||
),
|
||||
extraIconList = toLabelIcons(clock = clock),
|
||||
overflowOptions = listOfNotNull(
|
||||
VaultItemListingState.DisplayItem.OverflowItem(
|
||||
title = R.string.edit.asText(),
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.x8bit.bitwarden.ui.tools.feature.send.util
|
|||
import com.bitwarden.core.SendType
|
||||
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockSendView
|
||||
import com.x8bit.bitwarden.data.vault.repository.model.SendData
|
||||
import com.x8bit.bitwarden.ui.platform.components.model.IconRes
|
||||
import com.x8bit.bitwarden.ui.tools.feature.send.SendState
|
||||
import com.x8bit.bitwarden.ui.tools.feature.send.model.SendStatusIcon
|
||||
import io.mockk.every
|
||||
|
@ -52,6 +53,8 @@ class SendDataExtensionsTest {
|
|||
val sendData = SendData(list)
|
||||
every { textSendView.toSendUrl(DEFAULT_BASE_URL) } returns textSendViewUrl2
|
||||
every { fileSendView.toSendUrl(DEFAULT_BASE_URL) } returns textSendViewUrl1
|
||||
every { textSendView.toLabelIcons(any()) } returns DEFAULT_SEND_STATUS_ICONS
|
||||
every { fileSendView.toLabelIcons(any()) } returns DEFAULT_SEND_STATUS_ICONS
|
||||
|
||||
val result = sendData.toViewState(DEFAULT_BASE_URL)
|
||||
|
||||
|
@ -65,12 +68,7 @@ class SendDataExtensionsTest {
|
|||
name = "mockName-1",
|
||||
deletionDate = "Oct 27, 2023, 12:00 PM",
|
||||
type = SendState.ViewState.Content.SendItem.Type.FILE,
|
||||
iconList = listOf(
|
||||
SendStatusIcon.PASSWORD,
|
||||
SendStatusIcon.MAX_ACCESS_COUNT_REACHED,
|
||||
SendStatusIcon.EXPIRED,
|
||||
SendStatusIcon.PENDING_DELETE,
|
||||
),
|
||||
iconList = DEFAULT_SEND_STATUS_ICONS,
|
||||
shareUrl = "www.test.com/#/send/mockAccessId-1/mockKey-1",
|
||||
hasPassword = true,
|
||||
),
|
||||
|
@ -79,12 +77,7 @@ class SendDataExtensionsTest {
|
|||
name = "mockName-2",
|
||||
deletionDate = "Oct 27, 2023, 12:00 PM",
|
||||
type = SendState.ViewState.Content.SendItem.Type.TEXT,
|
||||
iconList = listOf(
|
||||
SendStatusIcon.PASSWORD,
|
||||
SendStatusIcon.MAX_ACCESS_COUNT_REACHED,
|
||||
SendStatusIcon.EXPIRED,
|
||||
SendStatusIcon.PENDING_DELETE,
|
||||
),
|
||||
iconList = DEFAULT_SEND_STATUS_ICONS,
|
||||
shareUrl = "www.test.com/#/send/mockAccessId-2/mockKey-2",
|
||||
hasPassword = true,
|
||||
),
|
||||
|
@ -99,3 +92,26 @@ private const val SEND_VIEW_EXTENSIONS_PATH: String =
|
|||
"com.x8bit.bitwarden.ui.tools.feature.send.util.SendViewExtensionsKt"
|
||||
|
||||
private const val DEFAULT_BASE_URL: String = "www.test.com/"
|
||||
|
||||
private val DEFAULT_SEND_STATUS_ICONS: List<IconRes> = listOf(
|
||||
IconRes(
|
||||
iconRes = SendStatusIcon.DISABLED.iconRes,
|
||||
contentDescription = SendStatusIcon.DISABLED.contentDescription,
|
||||
),
|
||||
IconRes(
|
||||
iconRes = SendStatusIcon.PASSWORD.iconRes,
|
||||
contentDescription = SendStatusIcon.PASSWORD.contentDescription,
|
||||
),
|
||||
IconRes(
|
||||
iconRes = SendStatusIcon.MAX_ACCESS_COUNT_REACHED.iconRes,
|
||||
contentDescription = SendStatusIcon.MAX_ACCESS_COUNT_REACHED.contentDescription,
|
||||
),
|
||||
IconRes(
|
||||
iconRes = SendStatusIcon.EXPIRED.iconRes,
|
||||
contentDescription = SendStatusIcon.EXPIRED.contentDescription,
|
||||
),
|
||||
IconRes(
|
||||
iconRes = SendStatusIcon.PENDING_DELETE.iconRes,
|
||||
contentDescription = SendStatusIcon.PENDING_DELETE.contentDescription,
|
||||
),
|
||||
)
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
package com.x8bit.bitwarden.ui.tools.feature.send.util
|
||||
|
||||
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockSendView
|
||||
import com.x8bit.bitwarden.ui.platform.components.model.IconRes
|
||||
import com.x8bit.bitwarden.ui.tools.feature.send.model.SendStatusIcon
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
import java.time.Clock
|
||||
import java.time.Instant
|
||||
import java.time.ZoneOffset
|
||||
|
||||
class SendViewExtensionsTest {
|
||||
|
||||
private val clock: Clock = Clock.fixed(
|
||||
Instant.parse("2023-10-27T12:00:00Z"),
|
||||
ZoneOffset.UTC,
|
||||
)
|
||||
|
||||
@Test
|
||||
fun `toLabelIcons should return all of the icons when all checks have passed`() {
|
||||
val sendView = createMockSendView(number = 1).copy(
|
||||
// Show the password icon when true
|
||||
hasPassword = true,
|
||||
// Show the disabled icon when true
|
||||
disabled = true,
|
||||
// Show the max access count reached icon when accessCount is greater than or equal to
|
||||
// the maxAccessCount
|
||||
maxAccessCount = 1u,
|
||||
accessCount = 1u,
|
||||
// Show the pending deletion icon when the deletion date is in the past
|
||||
deletionDate = Instant.parse("2023-10-26T12:00:00Z"),
|
||||
// Show the expired icon when the expiration date is in the past
|
||||
expirationDate = Instant.parse("2023-10-26T12:00:00Z"),
|
||||
)
|
||||
|
||||
val result = sendView.toLabelIcons(clock)
|
||||
|
||||
assertEquals(ALL_SEND_STATUS_ICONS, result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `toLabelIcons should return none of the icons when none of the checks have passed`() {
|
||||
val sendView = createMockSendView(number = 1).copy(
|
||||
// Hide the password icon when false
|
||||
hasPassword = false,
|
||||
// Hide the disabled icon when false
|
||||
disabled = false,
|
||||
// Hide the max access count reached icon when accessCount is less than the
|
||||
// maxAccessCount
|
||||
maxAccessCount = 10u,
|
||||
accessCount = 1u,
|
||||
// Hide the pending deletion icon when the deletion date is in the future
|
||||
deletionDate = Instant.parse("2023-10-28T12:00:00Z"),
|
||||
// Hide the expired icon when the expiration date is in the future
|
||||
expirationDate = Instant.parse("2023-10-28T12:00:00Z"),
|
||||
)
|
||||
|
||||
val result = sendView.toLabelIcons(clock)
|
||||
|
||||
assertEquals(emptyList<IconRes>(), result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `toSendUrl should create an appropriate url`() {
|
||||
val sendView = createMockSendView(number = 1)
|
||||
|
||||
val result = sendView.toSendUrl(baseWebSendUrl = "www.test.com/")
|
||||
|
||||
assertEquals("www.test.com/mockAccessId-1/mockKey-1", result)
|
||||
}
|
||||
}
|
||||
|
||||
private val ALL_SEND_STATUS_ICONS: List<IconRes> = listOf(
|
||||
IconRes(
|
||||
iconRes = SendStatusIcon.DISABLED.iconRes,
|
||||
contentDescription = SendStatusIcon.DISABLED.contentDescription,
|
||||
),
|
||||
IconRes(
|
||||
iconRes = SendStatusIcon.PASSWORD.iconRes,
|
||||
contentDescription = SendStatusIcon.PASSWORD.contentDescription,
|
||||
),
|
||||
IconRes(
|
||||
iconRes = SendStatusIcon.MAX_ACCESS_COUNT_REACHED.iconRes,
|
||||
contentDescription = SendStatusIcon.MAX_ACCESS_COUNT_REACHED.contentDescription,
|
||||
),
|
||||
IconRes(
|
||||
iconRes = SendStatusIcon.EXPIRED.iconRes,
|
||||
contentDescription = SendStatusIcon.EXPIRED.contentDescription,
|
||||
),
|
||||
IconRes(
|
||||
iconRes = SendStatusIcon.PENDING_DELETE.iconRes,
|
||||
contentDescription = SendStatusIcon.PENDING_DELETE.contentDescription,
|
||||
),
|
||||
)
|
|
@ -1,17 +0,0 @@
|
|||
package com.x8bit.bitwarden.ui.tools.feature.send.util
|
||||
|
||||
import com.x8bit.bitwarden.data.vault.datasource.sdk.model.createMockSendView
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
class SendViewTest {
|
||||
|
||||
@Test
|
||||
fun `toSendUrl should create an appropriate url`() {
|
||||
val sendView = createMockSendView(number = 1)
|
||||
|
||||
val result = sendView.toSendUrl(baseWebSendUrl = "www.test.com/")
|
||||
|
||||
assertEquals("www.test.com/mockAccessId-1/mockKey-1", result)
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue