Skip to content

Commit b3a2273

Browse files
committed
Change TreeFolder to DisplayTreeFolder and move the mapping into the GetDisplayTreeFolder use case
1 parent 68dc18d commit b3a2273

15 files changed

Lines changed: 730 additions & 179 deletions

File tree

feature/navigation/drawer/dropdown/src/debug/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/ui/FakeData.kt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import kotlinx.collections.immutable.toPersistentList
1212
import net.thunderbird.feature.navigation.drawer.dropdown.domain.entity.DisplayAccount
1313
import net.thunderbird.feature.navigation.drawer.dropdown.domain.entity.DisplayAccountFolder
1414
import net.thunderbird.feature.navigation.drawer.dropdown.domain.entity.DisplayFolder
15+
import net.thunderbird.feature.navigation.drawer.dropdown.domain.entity.DisplayTreeFolder
1516
import net.thunderbird.feature.navigation.drawer.dropdown.domain.entity.DisplayUnifiedFolder
1617
import net.thunderbird.feature.navigation.drawer.dropdown.domain.entity.DisplayUnifiedFolderType
1718

@@ -64,13 +65,60 @@ internal object FakeData {
6465
starredMessageCount = 5,
6566
)
6667

68+
val DISPLAY_TREE_FOLDER = DisplayTreeFolder(
69+
displayFolder = null,
70+
displayName = null,
71+
totalUnreadCount = 14,
72+
totalStarredCount = 5,
73+
children = persistentListOf(
74+
DisplayTreeFolder(
75+
displayFolder = DISPLAY_FOLDER,
76+
displayName = DISPLAY_FOLDER.folder.name,
77+
totalUnreadCount = 14,
78+
totalStarredCount = 5,
79+
children = persistentListOf(),
80+
),
81+
),
82+
)
83+
84+
val EMPTY_DISPLAY_TREE_FOLDER = DisplayTreeFolder(
85+
displayFolder = null,
86+
displayName = null,
87+
totalUnreadCount = 0,
88+
totalStarredCount = 0,
89+
children = persistentListOf(),
90+
)
91+
6792
val UNIFIED_FOLDER = DisplayUnifiedFolder(
6893
id = "unified_inbox",
6994
unifiedType = DisplayUnifiedFolderType.INBOX,
7095
unreadMessageCount = 123,
7196
starredMessageCount = 567,
7297
)
7398

99+
val DISPLAY_TREE_FOLDER_WITH_UNIFIED_FOLDER = DisplayTreeFolder(
100+
displayFolder = null,
101+
displayName = null,
102+
totalUnreadCount = 14,
103+
totalStarredCount = 5,
104+
children = persistentListOf(
105+
DisplayTreeFolder(
106+
displayFolder = UNIFIED_FOLDER,
107+
displayName = null,
108+
totalUnreadCount = 7,
109+
totalStarredCount = 2,
110+
children = persistentListOf(),
111+
),
112+
DisplayTreeFolder(
113+
displayFolder = DISPLAY_FOLDER,
114+
displayName = DISPLAY_FOLDER.folder.name,
115+
totalUnreadCount = 7,
116+
totalStarredCount = 3,
117+
children = persistentListOf(),
118+
),
119+
),
120+
)
121+
74122
fun createAccountList(): PersistentList<DisplayAccount> {
75123
return persistentListOf(
76124
DisplayAccount(

feature/navigation/drawer/dropdown/src/debug/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/ui/folder/FolderListPreview.kt

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,17 @@ package net.thunderbird.feature.navigation.drawer.dropdown.ui.folder
33
import androidx.compose.runtime.Composable
44
import androidx.compose.ui.tooling.preview.Preview
55
import app.k9mail.core.ui.compose.designsystem.PreviewWithTheme
6-
import kotlinx.collections.immutable.persistentListOf
7-
import net.thunderbird.feature.navigation.drawer.dropdown.domain.entity.TreeFolder
86
import net.thunderbird.feature.navigation.drawer.dropdown.ui.FakeData.DISPLAY_FOLDER
9-
import net.thunderbird.feature.navigation.drawer.dropdown.ui.FakeData.UNIFIED_FOLDER
7+
import net.thunderbird.feature.navigation.drawer.dropdown.ui.FakeData.DISPLAY_TREE_FOLDER
8+
import net.thunderbird.feature.navigation.drawer.dropdown.ui.FakeData.DISPLAY_TREE_FOLDER_WITH_UNIFIED_FOLDER
9+
import net.thunderbird.feature.navigation.drawer.dropdown.ui.FakeData.EMPTY_DISPLAY_TREE_FOLDER
1010

1111
@Composable
1212
@Preview(showBackground = true)
1313
internal fun FolderListPreview() {
1414
PreviewWithTheme {
1515
FolderList(
16-
rootFolder = TreeFolder.createFromFolders(
17-
persistentListOf(DISPLAY_FOLDER),
18-
),
16+
rootFolder = EMPTY_DISPLAY_TREE_FOLDER,
1917
selectedFolder = null,
2018
onFolderClick = {},
2119
showStarredCount = false,
@@ -28,9 +26,7 @@ internal fun FolderListPreview() {
2826
internal fun FolderListPreviewSelected() {
2927
PreviewWithTheme {
3028
FolderList(
31-
rootFolder = TreeFolder.createFromFolders(
32-
persistentListOf(DISPLAY_FOLDER),
33-
),
29+
rootFolder = DISPLAY_TREE_FOLDER,
3430
selectedFolder = DISPLAY_FOLDER,
3531
onFolderClick = {},
3632
showStarredCount = false,
@@ -43,10 +39,7 @@ internal fun FolderListPreviewSelected() {
4339
internal fun FolderListWithUnifiedFolderPreview() {
4440
PreviewWithTheme {
4541
FolderList(
46-
rootFolder = TreeFolder.createFromFolders(persistentListOf(
47-
UNIFIED_FOLDER,
48-
DISPLAY_FOLDER,
49-
)),
42+
rootFolder = DISPLAY_TREE_FOLDER_WITH_UNIFIED_FOLDER,
5043
selectedFolder = DISPLAY_FOLDER,
5144
onFolderClick = {},
5245
showStarredCount = false,

feature/navigation/drawer/dropdown/src/main/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/NavigationDrawerModule.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import net.thunderbird.feature.navigation.drawer.dropdown.domain.DomainContract
55
import net.thunderbird.feature.navigation.drawer.dropdown.domain.DomainContract.UseCase
66
import net.thunderbird.feature.navigation.drawer.dropdown.domain.usecase.GetDisplayAccounts
77
import net.thunderbird.feature.navigation.drawer.dropdown.domain.usecase.GetDisplayFoldersForAccount
8+
import net.thunderbird.feature.navigation.drawer.dropdown.domain.usecase.GetDisplayTreeFolder
89
import net.thunderbird.feature.navigation.drawer.dropdown.domain.usecase.GetDrawerConfig
9-
import net.thunderbird.feature.navigation.drawer.dropdown.domain.usecase.GetTreeFolders
1010
import net.thunderbird.feature.navigation.drawer.dropdown.domain.usecase.SaveDrawerConfig
1111
import net.thunderbird.feature.navigation.drawer.dropdown.domain.usecase.SyncAccount
1212
import net.thunderbird.feature.navigation.drawer.dropdown.domain.usecase.SyncAllAccounts
@@ -49,8 +49,8 @@ val navigationDropDownDrawerModule: Module = module {
4949
)
5050
}
5151

52-
single<UseCase.GetTreeFolders> {
53-
GetTreeFolders()
52+
single<UseCase.GetDisplayTreeFolder> {
53+
GetDisplayTreeFolder()
5454
}
5555

5656
single<UseCase.SyncAccount> {
@@ -72,7 +72,7 @@ val navigationDropDownDrawerModule: Module = module {
7272
saveDrawerConfig = get(),
7373
getDisplayAccounts = get(),
7474
getDisplayFoldersForAccount = get(),
75-
getTreeFolders = get(),
75+
getDisplayTreeFolder = get(),
7676
syncAccount = get(),
7777
syncAllAccounts = get(),
7878
)

feature/navigation/drawer/dropdown/src/main/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/domain/DomainContract.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ import kotlinx.coroutines.flow.Flow
44
import net.thunderbird.feature.navigation.drawer.api.NavigationDrawerExternalContract.DrawerConfig
55
import net.thunderbird.feature.navigation.drawer.dropdown.domain.entity.DisplayAccount
66
import net.thunderbird.feature.navigation.drawer.dropdown.domain.entity.DisplayFolder
7+
import net.thunderbird.feature.navigation.drawer.dropdown.domain.entity.DisplayTreeFolder
78
import net.thunderbird.feature.navigation.drawer.dropdown.domain.entity.DisplayUnifiedFolder
89
import net.thunderbird.feature.navigation.drawer.dropdown.domain.entity.DisplayUnifiedFolderType
9-
import net.thunderbird.feature.navigation.drawer.dropdown.domain.entity.TreeFolder
1010

1111
internal interface DomainContract {
1212

@@ -27,8 +27,8 @@ internal interface DomainContract {
2727
operator fun invoke(accountId: String, includeUnifiedFolders: Boolean): Flow<List<DisplayFolder>>
2828
}
2929

30-
fun interface GetTreeFolders {
31-
operator fun invoke(folders: List<DisplayFolder>, maxDepth: Int): TreeFolder
30+
fun interface GetDisplayTreeFolder {
31+
operator fun invoke(folders: List<DisplayFolder>, maxDepth: Int): DisplayTreeFolder
3232
}
3333

3434
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package net.thunderbird.feature.navigation.drawer.dropdown.domain.entity
2+
3+
import kotlinx.collections.immutable.ImmutableList
4+
5+
internal data class DisplayTreeFolder(
6+
val displayFolder: DisplayFolder?,
7+
val displayName: String?,
8+
val totalUnreadCount: Int,
9+
val totalStarredCount: Int,
10+
val children: ImmutableList<DisplayTreeFolder>,
11+
)

feature/navigation/drawer/dropdown/src/main/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/domain/entity/TreeFolder.kt

Lines changed: 0 additions & 96 deletions
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package net.thunderbird.feature.navigation.drawer.dropdown.domain.usecase
2+
3+
import app.k9mail.core.mail.folder.api.Folder
4+
import app.k9mail.core.mail.folder.api.FolderType
5+
import kotlinx.collections.immutable.persistentListOf
6+
import kotlinx.collections.immutable.toImmutableList
7+
import net.thunderbird.feature.navigation.drawer.dropdown.domain.DomainContract.UseCase
8+
import net.thunderbird.feature.navigation.drawer.dropdown.domain.entity.DisplayAccountFolder
9+
import net.thunderbird.feature.navigation.drawer.dropdown.domain.entity.DisplayFolder
10+
import net.thunderbird.feature.navigation.drawer.dropdown.domain.entity.DisplayTreeFolder
11+
import net.thunderbird.feature.navigation.drawer.dropdown.domain.entity.DisplayUnifiedFolder
12+
13+
internal class GetDisplayTreeFolder : UseCase.GetDisplayTreeFolder {
14+
15+
override fun invoke(folders: List<DisplayFolder>, maxDepth: Int): DisplayTreeFolder {
16+
val unifiedFolderTreeList = folders.filterIsInstance<DisplayUnifiedFolder>().map {
17+
DisplayTreeFolder(
18+
displayFolder = it,
19+
displayName = it.unifiedType.id,
20+
totalUnreadCount = it.unreadMessageCount,
21+
totalStarredCount = it.starredMessageCount,
22+
children = persistentListOf(),
23+
)
24+
}
25+
26+
val accountFolders = folders.filterIsInstance<DisplayAccountFolder>().map {
27+
val path = flattenPath(it.folder.name, maxDepth)
28+
println("Flattened path for ${it.folder.name}$path")
29+
path to it
30+
}
31+
val accountFolderTreeList = buildAccountFolderTree(accountFolders)
32+
33+
return DisplayTreeFolder(
34+
displayFolder = null,
35+
displayName = null,
36+
totalUnreadCount = accountFolderTreeList.sumOf { it.totalUnreadCount },
37+
totalStarredCount = accountFolderTreeList.sumOf { it.totalStarredCount },
38+
children = (unifiedFolderTreeList + accountFolderTreeList).toImmutableList(),
39+
)
40+
}
41+
42+
private fun flattenPath(folderName: String, maxDepth: Int): List<String> {
43+
val parts = folderName.split("/").map { it.takeIf { it.isNotBlank() } ?: "(Unnamed)" }
44+
45+
return if (parts.size <= maxDepth) {
46+
parts
47+
} else {
48+
parts.take(maxDepth) + listOf(parts.drop(maxDepth).joinToString("/"))
49+
}
50+
}
51+
52+
fun buildAccountFolderTree(
53+
paths: List<Pair<List<String>, DisplayAccountFolder>>,
54+
parentPath: String = "",
55+
): List<DisplayTreeFolder> {
56+
return paths.groupBy { it.first.getOrNull(0) ?: "(Unnamed)" }
57+
.map { (segment, entries) ->
58+
val childPaths = entries.mapNotNull { (segments, folders) ->
59+
if (segments.size > 1) {
60+
Pair(segments.drop(1), folders)
61+
} else {
62+
null
63+
}
64+
}
65+
66+
val currentFolders = entries.mapNotNull { (segments, folder) ->
67+
if (segments.size == 1) folder else null
68+
}
69+
70+
val fullPath = if (parentPath.isBlank()) segment else "$parentPath/$segment"
71+
72+
val currentFolder = currentFolders.firstOrNull() ?: createPlaceholderFolder(fullPath)
73+
74+
val children = buildAccountFolderTree(childPaths, fullPath)
75+
76+
val totalUnread = children.sumOf { it.totalUnreadCount } + currentFolder.unreadMessageCount
77+
val totalStarred = children.sumOf { it.totalStarredCount } + currentFolder.starredMessageCount
78+
79+
DisplayTreeFolder(
80+
displayFolder = currentFolder,
81+
displayName = segment,
82+
totalUnreadCount = totalUnread,
83+
totalStarredCount = totalStarred,
84+
children = children.toImmutableList(),
85+
)
86+
}
87+
}
88+
89+
private fun createPlaceholderFolder(name: String): DisplayAccountFolder {
90+
return DisplayAccountFolder(
91+
accountId = "accountId",
92+
folder = Folder(
93+
id = 0L,
94+
name = name,
95+
type = FolderType.REGULAR,
96+
isLocalOnly = false,
97+
),
98+
isInTopGroup = true,
99+
unreadMessageCount = 0,
100+
starredMessageCount = 0,
101+
)
102+
}
103+
}

feature/navigation/drawer/dropdown/src/main/kotlin/net/thunderbird/feature/navigation/drawer/dropdown/domain/usecase/GetTreeFolders.kt

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)