Display the selected attachment name (#770)

This commit is contained in:
David Perez 2024-01-24 19:50:47 -06:00 committed by Álison Fernandes
parent 04d60a50ff
commit 84346e2b29
6 changed files with 77 additions and 9 deletions

View file

@ -86,7 +86,10 @@ fun AttachmentsContent(
item {
Spacer(modifier = Modifier.height(16.dp))
Text(
text = stringResource(id = R.string.no_file_chosen),
text = viewState
.newAttachment
?.displayName
?: stringResource(id = R.string.no_file_chosen),
color = MaterialTheme.colorScheme.onSurfaceVariant,
style = MaterialTheme.typography.bodySmall,
textAlign = TextAlign.Center,

View file

@ -1,5 +1,6 @@
package com.x8bit.bitwarden.ui.vault.feature.attachments
import android.net.Uri
import android.os.Parcelable
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.viewModelScope
@ -81,8 +82,15 @@ class AttachmentsViewModel @Inject constructor(
}
private fun handleFileChoose(action: AttachmentsAction.FileChoose) {
sendEvent(AttachmentsEvent.ShowToast("Not Yet Implemented".asText()))
// TODO: Handle choosing a file the attachments (BIT-522)
updateContent {
it.copy(
newAttachment = AttachmentsState.NewAttachment(
uri = action.fileData.uri,
displayName = action.fileData.fileName,
sizeBytes = action.fileData.sizeBytes,
),
)
}
}
private fun handleDeleteClick(action: AttachmentsAction.DeleteClick) {
@ -195,6 +203,18 @@ class AttachmentsViewModel @Inject constructor(
) {
(state.viewState as? AttachmentsState.ViewState.Content)?.let(block)
}
private inline fun updateContent(
crossinline block: (
AttachmentsState.ViewState.Content,
) -> AttachmentsState.ViewState.Content,
) {
val currentViewState = state.viewState
val updatedContent = (currentViewState as? AttachmentsState.ViewState.Content)
?.let(block)
?: return
mutableStateFlow.update { it.copy(viewState = updatedContent) }
}
}
/**
@ -231,9 +251,20 @@ data class AttachmentsState(
@IgnoredOnParcel
val originalCipher: CipherView? = null,
val attachments: List<AttachmentItem>,
val newAttachment: NewAttachment?,
) : ViewState()
}
/**
* Represents an individual attachment that is ready to be added to the cipher.
*/
@Parcelize
data class NewAttachment(
val uri: Uri,
val displayName: String,
val sizeBytes: Long,
) : Parcelable
/**
* Represents an individual attachment that is already saved to the cipher.
*/

View file

@ -20,4 +20,5 @@ fun CipherView.toViewState(): AttachmentsState.ViewState.Content =
displaySize = it.sizeName.orEmpty(),
)
},
newAttachment = null,
)

View file

@ -247,6 +247,7 @@ private val DEFAULT_CONTENT_WITHOUT_ATTACHMENTS: AttachmentsState.ViewState.Cont
AttachmentsState.ViewState.Content(
originalCipher = createMockCipherView(number = 1),
attachments = emptyList(),
newAttachment = null,
)
private val DEFAULT_CONTENT_WITH_ATTACHMENTS: AttachmentsState.ViewState.Content =
@ -259,4 +260,5 @@ private val DEFAULT_CONTENT_WITH_ATTACHMENTS: AttachmentsState.ViewState.Content
displaySize = "10 MB",
),
),
newAttachment = null,
)

View file

@ -1,5 +1,6 @@
package com.x8bit.bitwarden.ui.vault.feature.attachments
import android.net.Uri
import androidx.lifecycle.SavedStateHandle
import app.cash.turbine.test
import com.bitwarden.core.CipherView
@ -35,11 +36,13 @@ class AttachmentsViewModelTest : BaseViewModelTest() {
@BeforeEach
fun setup() {
mockkStatic(CipherView::toViewState)
mockkStatic(Uri::class)
}
@AfterEach
fun tearDown() {
unmockkStatic(CipherView::toViewState)
unmockkStatic(Uri::class)
}
@Test
@ -96,13 +99,31 @@ class AttachmentsViewModelTest : BaseViewModelTest() {
}
@Test
fun `ChooseFile should emit ShowToast`() = runTest {
val fileData = mockk<IntentManager.FileData>()
fun `ChooseFile should update state with new file data`() = runTest {
val uri = createMockUri()
val fileData = IntentManager.FileData(
fileName = "filename-1",
uri = uri,
sizeBytes = 100L,
)
val cipherView = createMockCipherView(number = 1)
val initialState = DEFAULT_STATE.copy(viewState = DEFAULT_CONTENT_WITH_ATTACHMENTS)
mutableVaultItemStateFlow.tryEmit(DataState.Loaded(cipherView))
val viewModel = createViewModel()
viewModel.eventFlow.test {
viewModel.trySendAction(AttachmentsAction.FileChoose(fileData))
assertEquals(AttachmentsEvent.ShowToast("Not Yet Implemented".asText()), awaitItem())
}
viewModel.trySendAction(AttachmentsAction.FileChoose(fileData))
assertEquals(
initialState.copy(
viewState = DEFAULT_CONTENT_WITH_ATTACHMENTS.copy(
newAttachment = AttachmentsState.NewAttachment(
displayName = "filename-1",
uri = uri,
sizeBytes = 100L,
),
),
),
viewModel.stateFlow.value,
)
}
@Test
@ -302,4 +323,11 @@ private val DEFAULT_CONTENT_WITH_ATTACHMENTS: AttachmentsState.ViewState.Content
displaySize = "mockSizeName-1",
),
),
newAttachment = null,
)
private fun createMockUri(): Uri {
val uriMock = mockk<Uri>()
every { Uri.parse(any()) } returns uriMock
return uriMock
}

View file

@ -24,6 +24,7 @@ class CipherViewExtensionsTest {
displaySize = "mockSizeName-1",
),
),
newAttachment = null,
),
result,
)
@ -41,6 +42,7 @@ class CipherViewExtensionsTest {
AttachmentsState.ViewState.Content(
originalCipher = cipherView,
attachments = emptyList(),
newAttachment = null,
),
result,
)
@ -62,6 +64,7 @@ class CipherViewExtensionsTest {
AttachmentsState.ViewState.Content(
originalCipher = cipherView,
attachments = emptyList(),
newAttachment = null,
),
result,
)