Implement Parent/Children icons for Folders in Move To
MAILAND-2301
This commit is contained in:
parent
dd35ed5aed
commit
e70556022f
|
@ -28,7 +28,6 @@ import ch.protonmail.android.labels.data.remote.worker.UpdateConversationsLabels
|
|||
import ch.protonmail.android.labels.domain.model.LabelId
|
||||
import ch.protonmail.android.labels.domain.model.LabelType
|
||||
import ch.protonmail.android.labels.domain.model.ManageLabelActionResult
|
||||
import ch.protonmail.android.labels.domain.usecase.GetLabelsByType
|
||||
import ch.protonmail.android.labels.domain.usecase.GetLabelsOrFolderWithChildrenByType
|
||||
import ch.protonmail.android.labels.domain.usecase.UpdateMessageLabels
|
||||
import ch.protonmail.android.labels.presentation.mapper.LabelDomainActionItemUiMapper
|
||||
|
@ -60,7 +59,6 @@ private const val MAX_NUMBER_OF_SELECTED_LABELS = 100
|
|||
@HiltViewModel
|
||||
internal class LabelsActionSheetViewModel @Inject constructor(
|
||||
private val savedStateHandle: SavedStateHandle,
|
||||
private val getLabelsByType: GetLabelsByType,
|
||||
private val getLabelsOrFolderWithChildrenByType: GetLabelsOrFolderWithChildrenByType,
|
||||
private val accountManager: AccountManager,
|
||||
private val userManager: UserManager,
|
||||
|
|
|
@ -94,11 +94,14 @@ class LabelDomainActionItemUiMapper @Inject constructor(
|
|||
is LabelOrFolderWithChildren.Label -> LabelType.MESSAGE_LABEL
|
||||
is LabelOrFolderWithChildren.Folder -> LabelType.FOLDER
|
||||
}
|
||||
val iconRes = when (labelType) {
|
||||
LabelType.MESSAGE_LABEL -> R.drawable.circle_labels_selection
|
||||
LabelType.FOLDER ->
|
||||
if (useFolderColor) R.drawable.ic_folder_filled else R.drawable.ic_folder
|
||||
LabelType.CONTACT_GROUP -> throw IllegalArgumentException("Contacts are currently unsupported")
|
||||
val iconRes = when (label) {
|
||||
is LabelOrFolderWithChildren.Label -> R.drawable.circle_labels_selection
|
||||
is LabelOrFolderWithChildren.Folder ->
|
||||
if (useFolderColor) {
|
||||
if (label.children.isEmpty()) R.drawable.ic_folder_filled else R.drawable.ic_folder_multiple_filled
|
||||
} else {
|
||||
if (label.children.isEmpty()) R.drawable.ic_folder else R.drawable.ic_folder_multiple
|
||||
}
|
||||
}
|
||||
|
||||
val colorInt = if (useFolderColor) {
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<!--
|
||||
~ Copyright (c) 2020 Proton Technologies AG
|
||||
~
|
||||
~ This file is part of ProtonMail.
|
||||
~
|
||||
~ ProtonMail is free software: you can redistribute it and/or modify
|
||||
~ it under the terms of the GNU General Public License as published by
|
||||
~ the Free Software Foundation, either version 3 of the License, or
|
||||
~ (at your option) any later version.
|
||||
~
|
||||
~ ProtonMail is distributed in the hope that it will be useful,
|
||||
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
~ GNU General Public License for more details.
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with ProtonMail. If not, see https://www.gnu.org/licenses/.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:pathData="M6,1.5H12.3462L14.8846,3.9546H24V16.5H6V1.5ZM1.5,6H4.5V18L19.5,18V21H4.5H3H1.5V6Z"
|
||||
android:fillColor="@color/icon_norm"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
|
@ -151,24 +151,24 @@ class LabelDomainActionItemUiMapperTest {
|
|||
val thirdFirstSecond = "third.first.second"
|
||||
val thirdSecond = "third.second"
|
||||
val input = buildFolders {
|
||||
+first {
|
||||
+firstFirst
|
||||
folder(first) {
|
||||
folder(firstFirst)
|
||||
}
|
||||
+second
|
||||
+third {
|
||||
+thirdFirst {
|
||||
+thirdFirstFirst
|
||||
+thirdFirstSecond
|
||||
folder(second)
|
||||
folder(third) {
|
||||
folder(thirdFirst) {
|
||||
folder(thirdFirstFirst)
|
||||
folder(thirdFirstSecond)
|
||||
}
|
||||
+thirdSecond
|
||||
folder(thirdSecond)
|
||||
}
|
||||
}
|
||||
val expected = listOf(
|
||||
buildActionItem(name = first, folderLevel = 0),
|
||||
buildActionItem(name = first, folderLevel = 0, hasChildren = true),
|
||||
buildActionItem(name = firstFirst, folderLevel = 1),
|
||||
buildActionItem(name = second, folderLevel = 0),
|
||||
buildActionItem(name = third, folderLevel = 0),
|
||||
buildActionItem(name = thirdFirst, folderLevel = 1),
|
||||
buildActionItem(name = third, folderLevel = 0, hasChildren = true),
|
||||
buildActionItem(name = thirdFirst, folderLevel = 1, hasChildren = true),
|
||||
buildActionItem(name = thirdFirstFirst, folderLevel = 2),
|
||||
buildActionItem(name = thirdFirstSecond, folderLevel = 2),
|
||||
buildActionItem(name = thirdSecond, folderLevel = 1)
|
||||
|
@ -199,7 +199,7 @@ class LabelDomainActionItemUiMapperTest {
|
|||
every { Color.parseColor(blueString) } returns blueInt
|
||||
|
||||
val expected = listOf(
|
||||
buildActionItem(name = parent, folderLevel = 0, colorInt = redInt),
|
||||
buildActionItem(name = parent, folderLevel = 0, hasChildren = true, colorInt = redInt),
|
||||
buildActionItem(name = child, folderLevel = 1, colorInt = blueInt),
|
||||
)
|
||||
|
||||
|
@ -228,7 +228,7 @@ class LabelDomainActionItemUiMapperTest {
|
|||
}
|
||||
|
||||
val expected = listOf(
|
||||
buildActionItem(name = parent, folderLevel = 0, colorInt = redInt),
|
||||
buildActionItem(name = parent, folderLevel = 0, hasChildren = true, colorInt = redInt),
|
||||
buildActionItem(name = child, folderLevel = 1, colorInt = redInt),
|
||||
)
|
||||
|
||||
|
@ -254,7 +254,7 @@ class LabelDomainActionItemUiMapperTest {
|
|||
}
|
||||
|
||||
val expected = listOf(
|
||||
buildActionItem(name = parent, folderLevel = 0, colorInt = 0),
|
||||
buildActionItem(name = parent, folderLevel = 0, hasChildren = true, colorInt = 0),
|
||||
buildActionItem(name = child, folderLevel = 1, colorInt = 0),
|
||||
)
|
||||
|
||||
|
@ -287,12 +287,13 @@ class LabelDomainActionItemUiMapperTest {
|
|||
private fun buildActionItem(
|
||||
name: String,
|
||||
folderLevel: Int,
|
||||
hasChildren: Boolean = false,
|
||||
colorInt: Int = TEST_COLOR_INT
|
||||
) = LabelActonItemUiModel(
|
||||
labelId = LabelId(name),
|
||||
title = name,
|
||||
folderLevel = folderLevel,
|
||||
iconRes = R.drawable.ic_folder_filled,
|
||||
iconRes = if (hasChildren) R.drawable.ic_folder_multiple_filled else R.drawable.ic_folder_filled,
|
||||
colorInt = colorInt,
|
||||
labelType = LabelType.FOLDER
|
||||
)
|
||||
|
|
|
@ -27,11 +27,10 @@ import ch.protonmail.android.core.Constants
|
|||
import ch.protonmail.android.core.UserManager
|
||||
import ch.protonmail.android.data.local.model.Message
|
||||
import ch.protonmail.android.labels.data.remote.worker.UpdateConversationsLabelsWorker
|
||||
import ch.protonmail.android.labels.domain.model.Label
|
||||
import ch.protonmail.android.labels.domain.model.LabelId
|
||||
import ch.protonmail.android.labels.domain.model.LabelOrFolderWithChildren
|
||||
import ch.protonmail.android.labels.domain.model.LabelType
|
||||
import ch.protonmail.android.labels.domain.model.ManageLabelActionResult
|
||||
import ch.protonmail.android.labels.domain.usecase.GetLabelsByType
|
||||
import ch.protonmail.android.labels.domain.usecase.GetLabelsOrFolderWithChildrenByType
|
||||
import ch.protonmail.android.labels.domain.usecase.UpdateMessageLabels
|
||||
import ch.protonmail.android.labels.presentation.LabelsActionSheetViewModel
|
||||
|
@ -62,12 +61,13 @@ import me.proton.core.accountmanager.domain.AccountManager
|
|||
import me.proton.core.domain.entity.UserId
|
||||
import me.proton.core.test.android.ArchTest
|
||||
import me.proton.core.test.kotlin.CoroutinesTest
|
||||
import me.proton.core.util.kotlin.EMPTY_STRING
|
||||
import kotlin.test.AfterTest
|
||||
import kotlin.test.BeforeTest
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
private val TEST_USER_ID = UserId("userId")
|
||||
|
||||
class LabelsActionSheetViewModelTest : ArchTest, CoroutinesTest {
|
||||
|
||||
@MockK
|
||||
|
@ -79,15 +79,12 @@ class LabelsActionSheetViewModelTest : ArchTest, CoroutinesTest {
|
|||
@MockK
|
||||
private lateinit var userManager: UserManager
|
||||
|
||||
@MockK
|
||||
private lateinit var getLabelsByType: GetLabelsByType
|
||||
|
||||
private val getLabelsOrFolderWithChildrenByType: GetLabelsOrFolderWithChildrenByType = mockk {
|
||||
coEvery { this@mockk(any(), any()) } returns emptyList()
|
||||
}
|
||||
|
||||
private val accountManager: AccountManager = mockk {
|
||||
every { getPrimaryUserId() } returns flowOf(userId)
|
||||
every { getPrimaryUserId() } returns flowOf(TEST_USER_ID)
|
||||
}
|
||||
|
||||
@MockK
|
||||
|
@ -113,7 +110,6 @@ class LabelsActionSheetViewModelTest : ArchTest, CoroutinesTest {
|
|||
private val context: Context = mockk {
|
||||
every { getColor(any()) } returns defaultColorInt
|
||||
}
|
||||
val userId = UserId("userId")
|
||||
|
||||
private val labelDomainUiMapper = LabelDomainActionItemUiMapper(context)
|
||||
|
||||
|
@ -131,25 +127,6 @@ class LabelsActionSheetViewModelTest : ArchTest, CoroutinesTest {
|
|||
every { messageId } returns messageId1
|
||||
every { labelIDsNotIncludingLocations } returns listOf(labelId1)
|
||||
}
|
||||
private val label1 = Label(
|
||||
id = LabelId(labelId1),
|
||||
name = title,
|
||||
color = color,
|
||||
order = 0,
|
||||
type = LabelType.MESSAGE_LABEL,
|
||||
path = EMPTY_STRING,
|
||||
parentId = EMPTY_STRING
|
||||
)
|
||||
|
||||
private val label2 = Label(
|
||||
id = LabelId(labelId2),
|
||||
name = title,
|
||||
color = color,
|
||||
order = 0,
|
||||
type = LabelType.FOLDER,
|
||||
path = EMPTY_STRING,
|
||||
parentId = EMPTY_STRING
|
||||
)
|
||||
|
||||
private val model1UiLabel = LabelActonItemUiModel(
|
||||
labelId = LabelId(labelId1),
|
||||
|
@ -195,26 +172,11 @@ class LabelsActionSheetViewModelTest : ArchTest, CoroutinesTest {
|
|||
savedStateHandle.get<ActionSheetTarget>(LabelsActionSheet.EXTRA_ARG_ACTION_TARGET)
|
||||
} returns ActionSheetTarget.MAILBOX_ITEMS_IN_MAILBOX_SCREEN
|
||||
|
||||
coEvery { getLabelsByType.invoke(any()) } returns listOf(label1)
|
||||
coEvery { messageRepository.findMessageById(messageId1) } returns message1
|
||||
every { userManager.requireCurrentUserId() } returns userId
|
||||
every { userManager.requireCurrentUserId() } returns TEST_USER_ID
|
||||
coEvery { conversationModeEnabled(any()) } returns false
|
||||
|
||||
viewModel = LabelsActionSheetViewModel(
|
||||
savedStateHandle = savedStateHandle,
|
||||
getLabelsByType = getLabelsByType,
|
||||
getLabelsOrFolderWithChildrenByType = getLabelsOrFolderWithChildrenByType,
|
||||
accountManager = accountManager,
|
||||
userManager = userManager,
|
||||
updateMessageLabels = updateMessageLabels,
|
||||
updateConversationsLabels = updateConversationsLabels,
|
||||
moveMessagesToFolder = moveMessagesToFolder,
|
||||
moveConversationsToFolder = moveConversationsToFolder,
|
||||
conversationModeEnabled = conversationModeEnabled,
|
||||
messageRepository = messageRepository,
|
||||
conversationsRepository = conversationsRepository,
|
||||
labelDomainUiMapper = labelDomainUiMapper
|
||||
)
|
||||
viewModel = buildViewModel()
|
||||
}
|
||||
|
||||
@AfterTest
|
||||
|
@ -234,7 +196,7 @@ class LabelsActionSheetViewModelTest : ArchTest, CoroutinesTest {
|
|||
moveMessagesToFolder(
|
||||
listOf(messageId1), Constants.MessageLocationType.ARCHIVE.messageLocationTypeValue.toString(),
|
||||
Constants.MessageLocationType.INBOX.messageLocationTypeValue.toString(),
|
||||
userId
|
||||
TEST_USER_ID
|
||||
)
|
||||
} just Runs
|
||||
|
||||
|
@ -248,7 +210,7 @@ class LabelsActionSheetViewModelTest : ArchTest, CoroutinesTest {
|
|||
listOf(messageId1),
|
||||
archiveLocationId,
|
||||
inboxLocationId,
|
||||
userId
|
||||
TEST_USER_ID
|
||||
)
|
||||
}
|
||||
assertEquals(ManageLabelActionResult.LabelsSuccessfullySaved, viewModel.actionsResult.value)
|
||||
|
@ -278,7 +240,10 @@ class LabelsActionSheetViewModelTest : ArchTest, CoroutinesTest {
|
|||
runBlockingTest {
|
||||
|
||||
// given
|
||||
coEvery { getLabelsOrFolderWithChildrenByType(any(), any()) } returns
|
||||
listOf(buildLabelOrFolderWithChildrenLabel(id = LabelId(labelId1), name = title))
|
||||
coEvery { userManager.didReachLabelsThreshold(any()) } returns false
|
||||
val viewModel = buildViewModel()
|
||||
|
||||
// when
|
||||
viewModel.onLabelClicked(model1UiLabel)
|
||||
|
@ -292,7 +257,10 @@ class LabelsActionSheetViewModelTest : ArchTest, CoroutinesTest {
|
|||
fun verifyThatAfterOnLabelIsClickedForLabelTypeStandardLabelsAreAdded() = runBlockingTest {
|
||||
|
||||
// given
|
||||
coEvery { getLabelsOrFolderWithChildrenByType(any(), any()) } returns
|
||||
listOf(buildLabelOrFolderWithChildrenLabel(id = LabelId(labelId1), name = title))
|
||||
coEvery { userManager.didReachLabelsThreshold(any()) } returns false
|
||||
val viewModel = buildViewModel()
|
||||
|
||||
// when
|
||||
viewModel.onLabelClicked(model1UiLabel)
|
||||
|
@ -313,23 +281,8 @@ class LabelsActionSheetViewModelTest : ArchTest, CoroutinesTest {
|
|||
}
|
||||
coEvery { messageRepository.findMessageById(any()) } returns testMessage
|
||||
val expectedResult = ManageLabelActionResult.ErrorLabelsThresholdReached(maximumLabelsSelectedThreshold)
|
||||
val buildAListOfMoreThanOneHundredSelectedLabels = buildAListOfMoreThanOneHundredSelectedLabels()
|
||||
coEvery { getLabelsByType.invoke(any()) } returns buildAListOfMoreThanOneHundredSelectedLabels
|
||||
val labelsActionSheetViewModel = LabelsActionSheetViewModel(
|
||||
savedStateHandle = savedStateHandle,
|
||||
getLabelsByType = getLabelsByType,
|
||||
getLabelsOrFolderWithChildrenByType = getLabelsOrFolderWithChildrenByType,
|
||||
accountManager = accountManager,
|
||||
userManager = userManager,
|
||||
updateMessageLabels = updateMessageLabels,
|
||||
updateConversationsLabels = updateConversationsLabels,
|
||||
moveMessagesToFolder = moveMessagesToFolder,
|
||||
moveConversationsToFolder = moveConversationsToFolder,
|
||||
conversationModeEnabled = conversationModeEnabled,
|
||||
messageRepository = messageRepository,
|
||||
conversationsRepository = conversationsRepository,
|
||||
labelDomainUiMapper = labelDomainUiMapper
|
||||
)
|
||||
coEvery { getLabelsOrFolderWithChildrenByType(any(), any()) } returns buildAListOfMoreThanOneHundredSelectedLabels()
|
||||
val labelsActionSheetViewModel = buildViewModel()
|
||||
|
||||
// when
|
||||
labelsActionSheetViewModel.onLabelClicked(model1UiLabel)
|
||||
|
@ -363,7 +316,7 @@ class LabelsActionSheetViewModelTest : ArchTest, CoroutinesTest {
|
|||
runBlockingTest {
|
||||
|
||||
// given
|
||||
coEvery { userManager.currentUserId } returns userId
|
||||
coEvery { userManager.currentUserId } returns TEST_USER_ID
|
||||
coEvery { moveMessagesToFolder.invoke(any(), any(), any(), any()) } just Runs
|
||||
coEvery { conversationModeEnabled(any()) } returns true
|
||||
every {
|
||||
|
@ -384,7 +337,7 @@ class LabelsActionSheetViewModelTest : ArchTest, CoroutinesTest {
|
|||
fun verifyThatWhenLabelIsClickedForFolderTypeWithConversationModeEnabledAndMoveConversationsToFolderReturnsErrorResultErrorMovingToFolderIsEmitted() =
|
||||
runBlockingTest {
|
||||
// given
|
||||
coEvery { userManager.currentUserId } returns userId
|
||||
coEvery { userManager.currentUserId } returns TEST_USER_ID
|
||||
coEvery { conversationModeEnabled(any()) } returns true
|
||||
coEvery {
|
||||
moveConversationsToFolder.invoke(any(), any(), any())
|
||||
|
@ -403,8 +356,8 @@ class LabelsActionSheetViewModelTest : ArchTest, CoroutinesTest {
|
|||
|
||||
// given
|
||||
|
||||
coEvery { userManager.currentUserId } returns userId
|
||||
coEvery { moveMessagesToFolder.invoke(any(), any(), any(), userId) } just Runs
|
||||
coEvery { userManager.currentUserId } returns TEST_USER_ID
|
||||
coEvery { moveMessagesToFolder.invoke(any(), any(), any(), TEST_USER_ID) } just Runs
|
||||
coEvery { conversationModeEnabled(any()) } returns true
|
||||
every {
|
||||
savedStateHandle.get<ActionSheetTarget>("extra_arg_labels_action_sheet_actions_target")
|
||||
|
@ -419,18 +372,30 @@ class LabelsActionSheetViewModelTest : ArchTest, CoroutinesTest {
|
|||
assertEquals(ManageLabelActionResult.MessageSuccessfullyMoved(false), viewModel.actionsResult.value)
|
||||
}
|
||||
|
||||
private fun buildAListOfMoreThanOneHundredSelectedLabels(): List<Label> {
|
||||
return (0..100).map { index ->
|
||||
Label(
|
||||
id = LabelId("$index"),
|
||||
name = "title $index",
|
||||
color = color,
|
||||
order = 0,
|
||||
type = LabelType.MESSAGE_LABEL,
|
||||
path = EMPTY_STRING,
|
||||
parentId = EMPTY_STRING
|
||||
)
|
||||
}
|
||||
private fun buildViewModel() = LabelsActionSheetViewModel(
|
||||
savedStateHandle = savedStateHandle,
|
||||
getLabelsOrFolderWithChildrenByType = getLabelsOrFolderWithChildrenByType,
|
||||
accountManager = accountManager,
|
||||
userManager = userManager,
|
||||
updateMessageLabels = updateMessageLabels,
|
||||
updateConversationsLabels = updateConversationsLabels,
|
||||
moveMessagesToFolder = moveMessagesToFolder,
|
||||
moveConversationsToFolder = moveConversationsToFolder,
|
||||
conversationModeEnabled = conversationModeEnabled,
|
||||
messageRepository = messageRepository,
|
||||
conversationsRepository = conversationsRepository,
|
||||
labelDomainUiMapper = labelDomainUiMapper
|
||||
)
|
||||
|
||||
}
|
||||
private fun buildLabelOrFolderWithChildrenLabel(
|
||||
name: String = labelId1,
|
||||
id: LabelId = LabelId(name)
|
||||
) = LabelOrFolderWithChildren.Label(
|
||||
id = id,
|
||||
name = name,
|
||||
color = color
|
||||
)
|
||||
|
||||
private fun buildAListOfMoreThanOneHundredSelectedLabels(): List<LabelOrFolderWithChildren.Label> =
|
||||
(0..100).map { index -> buildLabelOrFolderWithChildrenLabel("$index") }
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue