Skip to content

Commit 6366ddf

Browse files
committed
MessagesListFragment. Restored shopwing progress.| #1806
1 parent a7e3f12 commit 6366ddf

File tree

5 files changed

+104
-107
lines changed

5 files changed

+104
-107
lines changed

FlowCrypt/src/main/java/com/flowcrypt/email/data/MessagesRemoteMediator.kt

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import androidx.paging.ExperimentalPagingApi
1010
import androidx.paging.LoadType
1111
import androidx.paging.PagingState
1212
import androidx.paging.RemoteMediator
13+
import com.flowcrypt.email.R
1314
import com.flowcrypt.email.api.email.EmailUtil
1415
import com.flowcrypt.email.api.email.IMAPStoreManager
1516
import com.flowcrypt.email.api.email.JavaEmailConstants
@@ -52,35 +53,38 @@ class MessagesRemoteMediator(
5253
private val context: Context,
5354
private val roomDatabase: FlowCryptRoomDatabase,
5455
private val localFolder: LocalFolder? = null,
56+
private val progressNotifier: (resultCode: Int, progress: Double) -> Unit
5557
) : RemoteMediator<Int, MessageEntity>() {
5658
private var searchNextPageToken: String? = null
5759

5860
override suspend fun load(
5961
loadType: LoadType,
6062
state: PagingState<Int, MessageEntity>
6163
): MediatorResult {
62-
if (loadType == LoadType.PREPEND || localFolder == null || localFolder.isOutbox()) {
63-
return MediatorResult.Success(endOfPaginationReached = true)
64-
}
65-
val activeAccountWithProtectedData = roomDatabase.accountDao().getActiveAccountSuspend()
66-
val accountEntity =
67-
AccountViewModel.getAccountEntityWithDecryptedInfoSuspend(activeAccountWithProtectedData)
68-
?: return MediatorResult.Success(endOfPaginationReached = true)
69-
70-
val totalItemsCount = roomDatabase.msgDao().getMsgsCount(
71-
account = accountEntity.email,
72-
label = if (localFolder.searchQuery.isNullOrEmpty()) {
73-
localFolder.fullName
74-
} else {
75-
JavaEmailConstants.FOLDER_SEARCH
64+
try {
65+
progressNotifier.invoke(R.id.progress_id_start_of_loading_new_messages, 0.0)
66+
if (loadType == LoadType.PREPEND || localFolder == null || localFolder.isOutbox()) {
67+
return MediatorResult.Success(endOfPaginationReached = true)
7668
}
77-
)
69+
val activeAccountWithProtectedData = roomDatabase.accountDao().getActiveAccountSuspend()
70+
val accountEntity =
71+
AccountViewModel.getAccountEntityWithDecryptedInfoSuspend(activeAccountWithProtectedData)
72+
?: return MediatorResult.Success(endOfPaginationReached = true)
73+
74+
val totalItemsCount = roomDatabase.msgDao().getMsgsCount(
75+
account = accountEntity.email,
76+
label = if (localFolder.searchQuery.isNullOrEmpty()) {
77+
localFolder.fullName
78+
} else {
79+
JavaEmailConstants.FOLDER_SEARCH
80+
}
81+
)
7882

79-
if (loadType == LoadType.REFRESH && totalItemsCount != 0) {
80-
return MediatorResult.Success(endOfPaginationReached = false)
81-
}
83+
if (loadType == LoadType.REFRESH && totalItemsCount != 0) {
84+
return MediatorResult.Success(endOfPaginationReached = false)
85+
}
8286

83-
try {
87+
progressNotifier.invoke(R.id.progress_id_start_of_loading_new_messages, 10.0)
8488
val actionResult = fetchAndCacheMessages(
8589
accountEntity = accountEntity,
8690
localFolder = localFolder,
@@ -95,6 +99,8 @@ class MessagesRemoteMediator(
9599
return MediatorResult.Success(endOfPaginationReached = (actionResult.data ?: 0) == 0)
96100
} catch (exception: Exception) {
97101
return MediatorResult.Error(exception)
102+
} finally {
103+
progressNotifier.invoke(R.id.progress_id_done, 100.0)
98104
}
99105
}
100106

@@ -154,7 +160,9 @@ class MessagesRemoteMediator(
154160
var countOfFetchedMsgs = 0
155161
store.getFolder(localFolder.fullName).use { folder ->
156162
val imapFolder = folder as IMAPFolder
163+
progressNotifier.invoke(R.id.progress_id_opening_store, 20.0)
157164
imapFolder.open(Folder.READ_ONLY)
165+
progressNotifier.invoke(R.id.progress_id_opening_store, 40.0)
158166

159167
val countOfLoadedMsgs = when {
160168
countOfAlreadyLoadedMsgs < 0 -> 0
@@ -186,6 +194,7 @@ class MessagesRemoteMediator(
186194
.getLabelSuspend(accountEntity.email, accountEntity.accountType, folderName)?.let {
187195
roomDatabase.labelDao().updateSuspend(it.copy(messagesTotal = msgsCount))
188196
}
197+
progressNotifier.invoke(R.id.progress_id_getting_list_of_emails, 60.0)
189198
if (end < 1) {
190199
handleReceivedMsgs(accountEntity, localFolder, imapFolder, arrayOf())
191200
} else {
@@ -206,7 +215,7 @@ class MessagesRemoteMediator(
206215
handleReceivedMsgs(accountEntity, localFolder, folder, msgs)
207216
}
208217
}
209-
218+
progressNotifier.invoke(R.id.progress_id_getting_list_of_emails, 80.0)
210219
return@withContext Result.success(countOfFetchedMsgs)
211220
}
212221

@@ -221,21 +230,25 @@ class MessagesRemoteMediator(
221230
AccountEntity.ACCOUNT_TYPE_GOOGLE -> {
222231
val labelEntity: LabelEntity? = roomDatabase.labelDao()
223232
.getLabelSuspend(accountEntity.email, accountEntity.accountType, localFolder.fullName)
233+
progressNotifier.invoke(R.id.progress_id_gmail_list, 20.0)
224234
val messagesBaseInfo = GmailApiHelper.loadMsgsBaseInfo(
225235
context = context,
226236
accountEntity = accountEntity,
227237
localFolder = localFolder,
228238
maxResults = pageSize.toLong(),
229239
nextPageToken = if (totalItemsCount > 0) labelEntity?.nextPageToken else null
230240
)
231-
241+
progressNotifier.invoke(R.id.progress_id_gmail_msgs_info, 60.0)
232242
if (messagesBaseInfo.messages?.isNotEmpty() == true) {
233243
val msgs = GmailApiHelper.loadMsgsInParallel(
234244
context, accountEntity, messagesBaseInfo.messages
235245
?: emptyList(), localFolder
236246
)
237247
countOfFetchedMsgs = msgs.size
248+
progressNotifier.invoke(R.id.progress_id_gmail_msgs_info, 90.0)
238249
handleReceivedMsgs(accountEntity, localFolder, msgs)
250+
} else {
251+
progressNotifier.invoke(R.id.progress_id_gmail_msgs_info, 90.0)
239252
}
240253

241254
labelEntity?.let {
@@ -392,25 +405,29 @@ class MessagesRemoteMediator(
392405
var countOfFetchedMsgs = 0
393406
when (accountEntity.accountType) {
394407
AccountEntity.ACCOUNT_TYPE_GOOGLE -> {
408+
progressNotifier.invoke(R.id.progress_id_gmail_list, 20.0)
395409
val messagesBaseInfo = GmailApiHelper.loadMsgsBaseInfoUsingSearch(
396410
context = context,
397411
accountEntity = accountEntity,
398412
localFolder = localFolder,
399413
maxResults = pageSize.toLong(),
400414
nextPageToken = if (totalItemsCount > 0) searchNextPageToken else null
401415
)
402-
416+
progressNotifier.invoke(R.id.progress_id_gmail_msgs_info, 70.0)
403417
if (messagesBaseInfo.messages?.isNotEmpty() == true) {
404418
val msgs = GmailApiHelper.loadMsgsInParallel(
405419
context, accountEntity, messagesBaseInfo.messages
406420
?: emptyList(), localFolder
407421
)
408422
countOfFetchedMsgs = msgs.size
423+
progressNotifier.invoke(R.id.progress_id_gmail_msgs_info, 90.0)
409424
handleSearchResults(
410425
accountEntity,
411426
localFolder.copy(fullName = JavaEmailConstants.FOLDER_SEARCH),
412427
msgs
413428
)
429+
} else {
430+
progressNotifier.invoke(R.id.progress_id_gmail_msgs_info, 90.0)
414431
}
415432

416433
searchNextPageToken = messagesBaseInfo.nextPageToken
@@ -429,7 +446,9 @@ class MessagesRemoteMediator(
429446
var countOfFetchedMsgs = 0
430447
store.getFolder(localFolder.fullName).use { folder ->
431448
val imapFolder = folder as IMAPFolder
449+
progressNotifier.invoke(R.id.progress_id_opening_store, 20.0)
432450
imapFolder.open(Folder.READ_ONLY)
451+
progressNotifier.invoke(R.id.progress_id_opening_store, 40.0)
433452

434453
val countOfLoadedMsgs = when {
435454
countOfAlreadyLoadedMsgs < 0 -> 0
@@ -445,6 +464,7 @@ class MessagesRemoteMediator(
445464
startCandidate < 1 -> 1
446465
else -> startCandidate
447466
}
467+
progressNotifier.invoke(R.id.progress_id_getting_list_of_emails, 60.0)
448468

449469
if (end < 1) {
450470
handleSearchResults(accountEntity, localFolder, imapFolder, arrayOf())
@@ -461,6 +481,8 @@ class MessagesRemoteMediator(
461481
countOfFetchedMsgs = bufferedMsgs.size
462482
handleSearchResults(accountEntity, localFolder, imapFolder, bufferedMsgs)
463483
}
484+
485+
progressNotifier.invoke(R.id.progress_id_getting_list_of_emails, 80.0)
464486
}
465487

466488
return@withContext Result.success(countOfFetchedMsgs)

FlowCrypt/src/main/java/com/flowcrypt/email/data/MessagesRepository.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,12 @@ import com.flowcrypt.email.database.entity.MessageEntity
2020
2121
*/
2222
object MessagesRepository {
23-
const val PAGE_SIZE = 15
23+
const val PAGE_SIZE = 20
2424

2525
fun getMessagesPager(
2626
context: Context,
27-
localFolder: LocalFolder?
27+
localFolder: LocalFolder?,
28+
remoteMediatorProgressNotifier: (resultCode: Int, progress: Double) -> Unit
2829
): Pager<Int, MessageEntity> {
2930
val roomDatabase = FlowCryptRoomDatabase.getDatabase(context)
3031
@OptIn(ExperimentalPagingApi::class)
@@ -39,7 +40,12 @@ object MessagesRepository {
3940
folder = localFolder?.fullName ?: ""
4041
)
4142
},
42-
remoteMediator = MessagesRemoteMediator(context, roomDatabase, localFolder)
43+
remoteMediator = MessagesRemoteMediator(
44+
context = context,
45+
roomDatabase = roomDatabase,
46+
localFolder = localFolder,
47+
progressNotifier = remoteMediatorProgressNotifier
48+
)
4349
)
4450
}
4551
}

FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MessagesViewModel.kt

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import android.app.Application
99
import androidx.lifecycle.LiveData
1010
import androidx.lifecycle.MutableLiveData
1111
import androidx.lifecycle.Transformations
12-
import androidx.lifecycle.liveData
1312
import androidx.lifecycle.viewModelScope
1413
import androidx.paging.cachedIn
1514
import com.flowcrypt.email.Constants
@@ -76,9 +75,17 @@ class MessagesViewModel(application: Application) : AccountViewModel(application
7675
private val activeLocalFolderStateFlow: StateFlow<LocalFolder?> =
7776
activeLocalFolderMutableStateFlow.asStateFlow()
7877

78+
private val loadMsgsListProgressMutableStateFlow: MutableStateFlow<Pair<Int, Double>> =
79+
MutableStateFlow(Pair(0, 0.0))
80+
val loadMsgsListProgressStateFlow: StateFlow<Pair<Int, Double>> =
81+
loadMsgsListProgressMutableStateFlow.asStateFlow()
82+
7983
@ExperimentalCoroutinesApi
8084
val pagerFlow = activeLocalFolderStateFlow.flatMapLatest { localFolder ->
81-
val pager = MessagesRepository.getMessagesPager(application, localFolder)
85+
val pager =
86+
MessagesRepository.getMessagesPager(application, localFolder) { resultCode, progress ->
87+
loadMsgsListProgressMutableStateFlow.value = Pair(resultCode, progress)
88+
}
8289
pager.flow.cachedIn(viewModelScope)
8390
}
8491

@@ -88,23 +95,8 @@ class MessagesViewModel(application: Application) : AccountViewModel(application
8895
roomDatabase.msgDao().getOutboxMsgsLD(it?.email ?: "")
8996
}
9097

91-
val loadMsgsFromRemoteServerLiveData = MutableLiveData<Result<Boolean?>>()
9298
val refreshMsgsLiveData = MutableLiveData<Result<Boolean?>>()
9399

94-
val msgsCountLiveData = Transformations.switchMap(loadMsgsFromRemoteServerLiveData) {
95-
liveData {
96-
if (it.status != Result.Status.SUCCESS) return@liveData
97-
val account = roomDatabase.accountDao().getActiveAccountSuspend()?.email ?: return@liveData
98-
val folder = activeLocalFolderMutableStateFlow.value ?: return@liveData
99-
val label = if (folder.searchQuery.isNullOrEmpty()) {
100-
folder.fullName
101-
} else {
102-
JavaEmailConstants.FOLDER_SEARCH
103-
}
104-
emit(roomDatabase.msgDao().countSuspend(account, label))
105-
}
106-
}
107-
108100
fun switchFolder(newFolder: LocalFolder, deleteAllMsgs: Boolean, forceClearFolderCache: Boolean) {
109101
if (activeLocalFolderMutableStateFlow.value == newFolder) {
110102
return

0 commit comments

Comments
 (0)