@@ -23,16 +23,16 @@ import androidx.recyclerview.widget.DiffUtil
23
23
import androidx.recyclerview.widget.ListAdapter
24
24
import androidx.recyclerview.widget.RecyclerView.ViewHolder
25
25
import androidx.viewbinding.ViewBinding
26
+ import com.infomaniak.mail.R
26
27
import com.infomaniak.mail.data.models.Folder
27
28
import com.infomaniak.mail.data.models.mailbox.Mailbox
28
- import com.infomaniak.mail.databinding.ItemInvalidMailboxBinding
29
- import com.infomaniak.mail.databinding.ItemMenuDrawerCustomFoldersHeaderBinding
30
- import com.infomaniak.mail.databinding.ItemMenuDrawerFolderBinding
31
- import com.infomaniak.mail.databinding.ItemMenuDrawerFooterBinding
32
- import com.infomaniak.mail.databinding.ItemMenuDrawerMailboxBinding
33
- import com.infomaniak.mail.databinding.ItemMenuDrawerMailboxesHeaderBinding
29
+ import com.infomaniak.mail.data.models.mailbox.MailboxPermissions
34
30
import com.infomaniak.mail.ui.main.menuDrawer.MenuDrawerAdapter.MenuDrawerViewHolder
35
31
import com.infomaniak.mail.ui.main.menuDrawer.MenuDrawerFragment.MediatorContainer
32
+ import com.infomaniak.mail.ui.main.menuDrawer.items.ActionViewHolder
33
+ import com.infomaniak.mail.ui.main.menuDrawer.items.ActionViewHolder.MenuDrawerAction
34
+ import com.infomaniak.mail.ui.main.menuDrawer.items.ActionViewHolder.MenuDrawerAction.ActionType
35
+ import com.infomaniak.mail.ui.main.menuDrawer.items.ActionsHeaderViewHolder
36
36
import com.infomaniak.mail.ui.main.menuDrawer.items.DividerItemViewHolder
37
37
import com.infomaniak.mail.ui.main.menuDrawer.items.EmptyFoldersViewHolder
38
38
import com.infomaniak.mail.ui.main.menuDrawer.items.FolderViewHolder
@@ -66,53 +66,75 @@ class MenuDrawerAdapter @Inject constructor() : ListAdapter<Any, MenuDrawerViewH
66
66
val (
67
67
mailboxes,
68
68
areMailboxesExpanded,
69
- allFolders,
69
+ defaultFolders,
70
+ customFolders,
70
71
areCustomFoldersExpanded,
72
+ areActionsExpanded,
71
73
permissions,
72
74
quotas,
73
75
) = mediatorContainer
74
76
75
- var count = 0
76
- var temporaryHasCollapsableDefaultFolder = false
77
- var temporaryHasCollapsableCustomFolder = false
77
+ addMailboxes(mailboxes, areMailboxesExpanded)
78
78
79
- // Mailboxes
80
- val currentMailboxIndex = mailboxes.indexOfFirst { it.mailboxId == AccountUtils .currentMailboxId }
81
- val otherMailboxes = mailboxes.toMutableList()
82
- val currentMailbox = otherMailboxes.removeAt(currentMailboxIndex)
83
- add(MailboxesHeader (currentMailbox, otherMailboxes.isNotEmpty(), areMailboxesExpanded))
84
- if (areMailboxesExpanded) addAll(otherMailboxes)
79
+ add(ItemType .DIVIDER )
80
+ hasCollapsableDefaultFolder = addDefaultFolders(defaultFolders)
85
81
86
- // Default Folders
87
82
add(ItemType .DIVIDER )
88
- while (count < allFolders.count() && (allFolders[count].role != null || ! allFolders[count].isRoot)) {
89
- val defaultFolder = allFolders[count]
90
- if (defaultFolder.canBeCollapsed) temporaryHasCollapsableDefaultFolder = true
91
- add(defaultFolder)
92
- count++
93
- }
83
+ hasCollapsableCustomFolder = addCustomFolders(customFolders, areCustomFoldersExpanded)
94
84
95
- // Custom Folders
96
85
add(ItemType .DIVIDER )
97
- add(ItemType .FOLDERS_HEADER )
98
- if (areCustomFoldersExpanded) {
99
- if (count == allFolders.count()) {
100
- add(ItemType .EMPTY_FOLDERS )
101
- } else {
102
- while (count < allFolders.count()) {
103
- val customFolder = allFolders[count]
104
- if (customFolder.canBeCollapsed) temporaryHasCollapsableCustomFolder = true
105
- add(customFolder)
106
- count++
107
- }
108
- }
86
+ addAdvancedActions(areActionsExpanded, permissions)
87
+
88
+ add(MenuDrawerFooter (quotas))
89
+ }
90
+ }
91
+
92
+ private fun MutableList<Any>.addMailboxes (mailboxes : List <Mailbox >, areMailboxesExpanded : Boolean ) {
93
+ val currentMailboxIndex = mailboxes.indexOfFirst { it.mailboxId == AccountUtils .currentMailboxId }
94
+ val otherMailboxes = mailboxes.toMutableList()
95
+ val currentMailbox = otherMailboxes.removeAt(currentMailboxIndex)
96
+
97
+ add(MailboxesHeader (currentMailbox, otherMailboxes.isNotEmpty(), areMailboxesExpanded))
98
+ if (areMailboxesExpanded) addAll(otherMailboxes)
99
+ }
100
+
101
+ private fun MutableList<Any>.addDefaultFolders (defaultFolders : List <Folder >): Boolean {
102
+ var atLeastOneFolderIsIndented = false
103
+
104
+ defaultFolders.forEach { defaultFolder ->
105
+ if (defaultFolder.canBeCollapsed) atLeastOneFolderIsIndented = true
106
+ add(defaultFolder)
107
+ }
108
+
109
+ return atLeastOneFolderIsIndented
110
+ }
111
+
112
+ private fun MutableList<Any>.addCustomFolders (customFolders : List <Folder >, areCustomFoldersExpanded : Boolean ): Boolean {
113
+ var atLeastOneFolderIsIndented = false
114
+
115
+ add(ItemType .FOLDERS_HEADER )
116
+ if (! areCustomFoldersExpanded) return false
117
+
118
+ if (customFolders.isEmpty()) {
119
+ add(ItemType .EMPTY_FOLDERS )
120
+ } else {
121
+ customFolders.forEach { customFolder ->
122
+ if (customFolder.canBeCollapsed) atLeastOneFolderIsIndented = true
123
+ add(customFolder)
109
124
}
110
- hasCollapsableDefaultFolder = temporaryHasCollapsableDefaultFolder
111
- hasCollapsableCustomFolder = temporaryHasCollapsableCustomFolder
125
+ }
112
126
113
- // Footer
114
- add(ItemType .DIVIDER )
115
- add(MenuDrawerFooter (permissions, quotas))
127
+ return atLeastOneFolderIsIndented
128
+ }
129
+
130
+ private fun MutableList<Any>.addAdvancedActions (areActionsExpanded : Boolean , permissions : MailboxPermissions ? ) {
131
+
132
+ add(ItemType .ACTIONS_HEADER )
133
+
134
+ if (areActionsExpanded) {
135
+ add(SYNC_AUTO_CONFIG_ACTION )
136
+ add(IMPORT_MAILS_ACTION )
137
+ if (permissions?.canRestoreEmails == true ) add(RESTORE_MAILS_ACTION )
116
138
}
117
139
}
118
140
@@ -154,6 +176,8 @@ class MenuDrawerAdapter @Inject constructor() : ListAdapter<Any, MenuDrawerViewH
154
176
ItemType .FOLDERS_HEADER -> ItemType .FOLDERS_HEADER .ordinal
155
177
is Folder -> ItemType .FOLDER .ordinal
156
178
ItemType .EMPTY_FOLDERS -> ItemType .EMPTY_FOLDERS .ordinal
179
+ ItemType .ACTIONS_HEADER -> ItemType .ACTIONS_HEADER .ordinal
180
+ is MenuDrawerAction -> ItemType .ACTION .ordinal
157
181
is MenuDrawerFooter -> ItemType .FOOTER .ordinal
158
182
else -> error(" Failed to find a viewType for MenuDrawer item" )
159
183
}
@@ -170,69 +194,66 @@ class MenuDrawerAdapter @Inject constructor() : ListAdapter<Any, MenuDrawerViewH
170
194
ItemType .FOLDERS_HEADER .ordinal -> FoldersHeaderViewHolder (inflater, parent)
171
195
ItemType .FOLDER .ordinal -> FolderViewHolder (inflater, parent)
172
196
ItemType .EMPTY_FOLDERS .ordinal -> EmptyFoldersViewHolder (inflater, parent)
197
+ ItemType .ACTIONS_HEADER .ordinal -> ActionsHeaderViewHolder (inflater, parent)
198
+ ItemType .ACTION .ordinal -> ActionViewHolder (inflater, parent)
173
199
ItemType .FOOTER .ordinal -> FooterViewHolder (inflater, parent)
174
200
else -> error(" Failed to find a binding for MenuDrawer viewType" )
175
201
}
176
202
}
177
203
178
204
override fun onBindViewHolder (holder : MenuDrawerViewHolder , position : Int , payloads : MutableList <Any >) {
179
205
if (payloads.firstOrNull() == NotifyType .MAILBOXES_HEADER_CLICKED ) {
180
- (holder as MailboxesHeaderViewHolder ).updateCollapseState(
181
- header = currentList[position] as MailboxesHeader ,
182
- binding = holder.binding as ItemMenuDrawerMailboxesHeaderBinding ,
183
- )
206
+ (holder as MailboxesHeaderViewHolder ).updateCollapseState(header = currentList[position] as MailboxesHeader )
184
207
} else {
185
208
super .onBindViewHolder(holder, position, payloads)
186
209
}
187
210
}
188
211
189
- override fun onBindViewHolder (holder : MenuDrawerViewHolder , position : Int ): Unit = with (holder.binding) {
212
+ override fun onBindViewHolder (holder : MenuDrawerViewHolder , position : Int ) {
190
213
val item = currentList[position]
191
214
192
215
when (holder) {
193
216
is MailboxesHeaderViewHolder -> holder.displayMailboxesHeader(
194
217
header = item as MailboxesHeader ,
195
- binding = this as ItemMenuDrawerMailboxesHeaderBinding ,
196
218
onMailboxesHeaderClicked = callbacks.onMailboxesHeaderClicked,
197
219
)
198
220
is MailboxViewHolder -> holder.displayMailbox(
199
221
mailbox = item as Mailbox ,
200
- binding = this as ItemMenuDrawerMailboxBinding ,
201
222
onValidMailboxClicked = callbacks.onValidMailboxClicked,
202
223
)
203
224
is InvalidMailboxViewHolder -> holder.displayInvalidMailbox(
204
225
mailbox = item as Mailbox ,
205
- binding = this as ItemInvalidMailboxBinding ,
206
226
onLockedMailboxClicked = callbacks.onLockedMailboxClicked,
207
227
onInvalidPasswordMailboxClicked = callbacks.onInvalidPasswordMailboxClicked,
208
228
)
209
229
is FoldersHeaderViewHolder -> holder.displayFoldersHeader(
210
- binding = this as ItemMenuDrawerCustomFoldersHeaderBinding ,
211
230
onFoldersHeaderClicked = callbacks.onFoldersHeaderClicked,
212
231
onCreateFolderClicked = callbacks.onCreateFolderClicked,
213
232
)
214
233
is FolderViewHolder -> holder.displayFolder(
215
234
folder = item as Folder ,
216
- binding = this as ItemMenuDrawerFolderBinding ,
217
235
currentFolderId = currentFolderId,
218
236
hasCollapsableFolder = if (item.role == null ) hasCollapsableCustomFolder else hasCollapsableDefaultFolder,
219
237
onFolderClicked = callbacks.onFolderClicked,
220
238
onCollapseChildrenClicked = callbacks.onCollapseChildrenClicked,
221
239
)
240
+ is ActionsHeaderViewHolder -> holder.displayActionsHeader(
241
+ onActionsHeaderClicked = callbacks.onActionsHeaderClicked,
242
+ )
243
+ is ActionViewHolder -> holder.displayAction(
244
+ action = item as MenuDrawerAction ,
245
+ onActionClicked = callbacks.onActionClicked,
246
+ )
222
247
is FooterViewHolder -> holder.displayFooter(
223
248
footer = item as MenuDrawerFooter ,
224
- binding = this as ItemMenuDrawerFooterBinding ,
225
- onSyncAutoConfigClicked = callbacks.onSyncAutoConfigClicked,
226
- onImportMailsClicked = callbacks.onImportMailsClicked,
227
- onRestoreMailsClicked = callbacks.onRestoreMailsClicked,
228
249
onFeedbackClicked = callbacks.onFeedbackClicked,
229
250
onHelpClicked = callbacks.onHelpClicked,
230
251
onAppVersionClicked = callbacks.onAppVersionClicked,
231
252
)
232
253
}
233
254
}
234
255
235
- abstract class MenuDrawerViewHolder (val binding : ViewBinding ) : ViewHolder(binding.root)
256
+ abstract class MenuDrawerViewHolder (open val binding : ViewBinding ) : ViewHolder(binding.root)
236
257
237
258
enum class ItemType {
238
259
DIVIDER ,
@@ -242,6 +263,8 @@ class MenuDrawerAdapter @Inject constructor() : ListAdapter<Any, MenuDrawerViewH
242
263
FOLDERS_HEADER ,
243
264
FOLDER ,
244
265
EMPTY_FOLDERS ,
266
+ ACTIONS_HEADER ,
267
+ ACTION ,
245
268
FOOTER ,
246
269
}
247
270
@@ -259,29 +282,33 @@ class MenuDrawerAdapter @Inject constructor() : ListAdapter<Any, MenuDrawerViewH
259
282
ItemType .FOLDERS_HEADER -> newItem == ItemType .FOLDERS_HEADER
260
283
is Folder -> newItem is Folder && newItem.id == oldItem.id
261
284
ItemType .EMPTY_FOLDERS -> newItem == ItemType .EMPTY_FOLDERS
285
+ ItemType .ACTIONS_HEADER -> newItem == ItemType .ACTIONS_HEADER
286
+ is MenuDrawerAction -> newItem is MenuDrawerAction && newItem.type == oldItem.type
262
287
is MenuDrawerFooter -> newItem is MenuDrawerFooter
263
288
else -> error(" oldItem wasn't any known item type (in MenuDrawer `areItemsTheSame`)" )
264
289
}
265
290
}.getOrDefault(false )
266
291
267
292
override fun areContentsTheSame (oldItem : Any , newItem : Any ) = runCatchingRealm {
268
293
when (oldItem) {
269
- ItemType .DIVIDER -> true
270
294
is MailboxesHeader -> newItem is MailboxesHeader
271
295
&& newItem.hasMoreThanOneMailbox == oldItem.hasMoreThanOneMailbox
272
296
&& newItem.isExpanded == oldItem.isExpanded
273
297
&& newItem.mailbox?.unreadCountDisplay?.count == oldItem.mailbox?.unreadCountDisplay?.count
274
298
is Mailbox -> newItem is Mailbox && newItem.unreadCountDisplay.count == oldItem.unreadCountDisplay.count
275
- ItemType .FOLDERS_HEADER -> true
276
299
is Folder -> newItem is Folder &&
277
300
newItem.name == oldItem.name &&
278
301
newItem.isFavorite == oldItem.isFavorite &&
279
302
newItem.path == oldItem.path &&
280
303
newItem.unreadCountDisplay == oldItem.unreadCountDisplay &&
281
304
newItem.threads.count() == oldItem.threads.count() &&
282
305
newItem.canBeCollapsed == oldItem.canBeCollapsed
283
- ItemType .EMPTY_FOLDERS -> true
284
306
is MenuDrawerFooter -> newItem is MenuDrawerFooter && newItem.quotas?.size == oldItem.quotas?.size
307
+ ItemType .DIVIDER ,
308
+ ItemType .FOLDERS_HEADER ,
309
+ ItemType .EMPTY_FOLDERS ,
310
+ ItemType .ACTIONS_HEADER ,
311
+ is MenuDrawerAction -> true
285
312
else -> error(" oldItem wasn't any known item type (in MenuDrawer `areContentsTheSame`)" )
286
313
}
287
314
}.getOrDefault(false )
@@ -294,4 +321,25 @@ class MenuDrawerAdapter @Inject constructor() : ListAdapter<Any, MenuDrawerViewH
294
321
}
295
322
}
296
323
}
324
+
325
+ companion object {
326
+ private val SYNC_AUTO_CONFIG_ACTION = MenuDrawerAction (
327
+ type = ActionType .SYNC_AUTO_CONFIG ,
328
+ icon = R .drawable.ic_synchronize,
329
+ text = R .string.syncCalendarsAndContactsTitle,
330
+ maxLines = 2 ,
331
+ )
332
+ private val IMPORT_MAILS_ACTION = MenuDrawerAction (
333
+ type = ActionType .IMPORT_MAILS ,
334
+ icon = R .drawable.ic_drawer_download,
335
+ text = R .string.buttonImportEmails,
336
+ maxLines = 1 ,
337
+ )
338
+ private val RESTORE_MAILS_ACTION = MenuDrawerAction (
339
+ type = ActionType .RESTORE_MAILS ,
340
+ icon = R .drawable.ic_restore_arrow,
341
+ text = R .string.buttonRestoreEmails,
342
+ maxLines = 1 ,
343
+ )
344
+ }
297
345
}
0 commit comments