Skip to content

Commit

Permalink
MessagesListFragment. Restored shopwing progress.| #1806
Browse files Browse the repository at this point in the history
  • Loading branch information
DenBond7 committed May 20, 2022
1 parent a7e3f12 commit 6366ddf
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 107 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import androidx.paging.ExperimentalPagingApi
import androidx.paging.LoadType
import androidx.paging.PagingState
import androidx.paging.RemoteMediator
import com.flowcrypt.email.R
import com.flowcrypt.email.api.email.EmailUtil
import com.flowcrypt.email.api.email.IMAPStoreManager
import com.flowcrypt.email.api.email.JavaEmailConstants
Expand Down Expand Up @@ -52,35 +53,38 @@ class MessagesRemoteMediator(
private val context: Context,
private val roomDatabase: FlowCryptRoomDatabase,
private val localFolder: LocalFolder? = null,
private val progressNotifier: (resultCode: Int, progress: Double) -> Unit
) : RemoteMediator<Int, MessageEntity>() {
private var searchNextPageToken: String? = null

override suspend fun load(
loadType: LoadType,
state: PagingState<Int, MessageEntity>
): MediatorResult {
if (loadType == LoadType.PREPEND || localFolder == null || localFolder.isOutbox()) {
return MediatorResult.Success(endOfPaginationReached = true)
}
val activeAccountWithProtectedData = roomDatabase.accountDao().getActiveAccountSuspend()
val accountEntity =
AccountViewModel.getAccountEntityWithDecryptedInfoSuspend(activeAccountWithProtectedData)
?: return MediatorResult.Success(endOfPaginationReached = true)

val totalItemsCount = roomDatabase.msgDao().getMsgsCount(
account = accountEntity.email,
label = if (localFolder.searchQuery.isNullOrEmpty()) {
localFolder.fullName
} else {
JavaEmailConstants.FOLDER_SEARCH
try {
progressNotifier.invoke(R.id.progress_id_start_of_loading_new_messages, 0.0)
if (loadType == LoadType.PREPEND || localFolder == null || localFolder.isOutbox()) {
return MediatorResult.Success(endOfPaginationReached = true)
}
)
val activeAccountWithProtectedData = roomDatabase.accountDao().getActiveAccountSuspend()
val accountEntity =
AccountViewModel.getAccountEntityWithDecryptedInfoSuspend(activeAccountWithProtectedData)
?: return MediatorResult.Success(endOfPaginationReached = true)

val totalItemsCount = roomDatabase.msgDao().getMsgsCount(
account = accountEntity.email,
label = if (localFolder.searchQuery.isNullOrEmpty()) {
localFolder.fullName
} else {
JavaEmailConstants.FOLDER_SEARCH
}
)

if (loadType == LoadType.REFRESH && totalItemsCount != 0) {
return MediatorResult.Success(endOfPaginationReached = false)
}
if (loadType == LoadType.REFRESH && totalItemsCount != 0) {
return MediatorResult.Success(endOfPaginationReached = false)
}

try {
progressNotifier.invoke(R.id.progress_id_start_of_loading_new_messages, 10.0)
val actionResult = fetchAndCacheMessages(
accountEntity = accountEntity,
localFolder = localFolder,
Expand All @@ -95,6 +99,8 @@ class MessagesRemoteMediator(
return MediatorResult.Success(endOfPaginationReached = (actionResult.data ?: 0) == 0)
} catch (exception: Exception) {
return MediatorResult.Error(exception)
} finally {
progressNotifier.invoke(R.id.progress_id_done, 100.0)
}
}

Expand Down Expand Up @@ -154,7 +160,9 @@ class MessagesRemoteMediator(
var countOfFetchedMsgs = 0
store.getFolder(localFolder.fullName).use { folder ->
val imapFolder = folder as IMAPFolder
progressNotifier.invoke(R.id.progress_id_opening_store, 20.0)
imapFolder.open(Folder.READ_ONLY)
progressNotifier.invoke(R.id.progress_id_opening_store, 40.0)

val countOfLoadedMsgs = when {
countOfAlreadyLoadedMsgs < 0 -> 0
Expand Down Expand Up @@ -186,6 +194,7 @@ class MessagesRemoteMediator(
.getLabelSuspend(accountEntity.email, accountEntity.accountType, folderName)?.let {
roomDatabase.labelDao().updateSuspend(it.copy(messagesTotal = msgsCount))
}
progressNotifier.invoke(R.id.progress_id_getting_list_of_emails, 60.0)
if (end < 1) {
handleReceivedMsgs(accountEntity, localFolder, imapFolder, arrayOf())
} else {
Expand All @@ -206,7 +215,7 @@ class MessagesRemoteMediator(
handleReceivedMsgs(accountEntity, localFolder, folder, msgs)
}
}

progressNotifier.invoke(R.id.progress_id_getting_list_of_emails, 80.0)
return@withContext Result.success(countOfFetchedMsgs)
}

Expand All @@ -221,21 +230,25 @@ class MessagesRemoteMediator(
AccountEntity.ACCOUNT_TYPE_GOOGLE -> {
val labelEntity: LabelEntity? = roomDatabase.labelDao()
.getLabelSuspend(accountEntity.email, accountEntity.accountType, localFolder.fullName)
progressNotifier.invoke(R.id.progress_id_gmail_list, 20.0)
val messagesBaseInfo = GmailApiHelper.loadMsgsBaseInfo(
context = context,
accountEntity = accountEntity,
localFolder = localFolder,
maxResults = pageSize.toLong(),
nextPageToken = if (totalItemsCount > 0) labelEntity?.nextPageToken else null
)

progressNotifier.invoke(R.id.progress_id_gmail_msgs_info, 60.0)
if (messagesBaseInfo.messages?.isNotEmpty() == true) {
val msgs = GmailApiHelper.loadMsgsInParallel(
context, accountEntity, messagesBaseInfo.messages
?: emptyList(), localFolder
)
countOfFetchedMsgs = msgs.size
progressNotifier.invoke(R.id.progress_id_gmail_msgs_info, 90.0)
handleReceivedMsgs(accountEntity, localFolder, msgs)
} else {
progressNotifier.invoke(R.id.progress_id_gmail_msgs_info, 90.0)
}

labelEntity?.let {
Expand Down Expand Up @@ -392,25 +405,29 @@ class MessagesRemoteMediator(
var countOfFetchedMsgs = 0
when (accountEntity.accountType) {
AccountEntity.ACCOUNT_TYPE_GOOGLE -> {
progressNotifier.invoke(R.id.progress_id_gmail_list, 20.0)
val messagesBaseInfo = GmailApiHelper.loadMsgsBaseInfoUsingSearch(
context = context,
accountEntity = accountEntity,
localFolder = localFolder,
maxResults = pageSize.toLong(),
nextPageToken = if (totalItemsCount > 0) searchNextPageToken else null
)

progressNotifier.invoke(R.id.progress_id_gmail_msgs_info, 70.0)
if (messagesBaseInfo.messages?.isNotEmpty() == true) {
val msgs = GmailApiHelper.loadMsgsInParallel(
context, accountEntity, messagesBaseInfo.messages
?: emptyList(), localFolder
)
countOfFetchedMsgs = msgs.size
progressNotifier.invoke(R.id.progress_id_gmail_msgs_info, 90.0)
handleSearchResults(
accountEntity,
localFolder.copy(fullName = JavaEmailConstants.FOLDER_SEARCH),
msgs
)
} else {
progressNotifier.invoke(R.id.progress_id_gmail_msgs_info, 90.0)
}

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

val countOfLoadedMsgs = when {
countOfAlreadyLoadedMsgs < 0 -> 0
Expand All @@ -445,6 +464,7 @@ class MessagesRemoteMediator(
startCandidate < 1 -> 1
else -> startCandidate
}
progressNotifier.invoke(R.id.progress_id_getting_list_of_emails, 60.0)

if (end < 1) {
handleSearchResults(accountEntity, localFolder, imapFolder, arrayOf())
Expand All @@ -461,6 +481,8 @@ class MessagesRemoteMediator(
countOfFetchedMsgs = bufferedMsgs.size
handleSearchResults(accountEntity, localFolder, imapFolder, bufferedMsgs)
}

progressNotifier.invoke(R.id.progress_id_getting_list_of_emails, 80.0)
}

return@withContext Result.success(countOfFetchedMsgs)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@ import com.flowcrypt.email.database.entity.MessageEntity
* E-mail: DenBond7@gmail.com
*/
object MessagesRepository {
const val PAGE_SIZE = 15
const val PAGE_SIZE = 20

fun getMessagesPager(
context: Context,
localFolder: LocalFolder?
localFolder: LocalFolder?,
remoteMediatorProgressNotifier: (resultCode: Int, progress: Double) -> Unit
): Pager<Int, MessageEntity> {
val roomDatabase = FlowCryptRoomDatabase.getDatabase(context)
@OptIn(ExperimentalPagingApi::class)
Expand All @@ -39,7 +40,12 @@ object MessagesRepository {
folder = localFolder?.fullName ?: ""
)
},
remoteMediator = MessagesRemoteMediator(context, roomDatabase, localFolder)
remoteMediator = MessagesRemoteMediator(
context = context,
roomDatabase = roomDatabase,
localFolder = localFolder,
progressNotifier = remoteMediatorProgressNotifier
)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import android.app.Application
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Transformations
import androidx.lifecycle.liveData
import androidx.lifecycle.viewModelScope
import androidx.paging.cachedIn
import com.flowcrypt.email.Constants
Expand Down Expand Up @@ -76,9 +75,17 @@ class MessagesViewModel(application: Application) : AccountViewModel(application
private val activeLocalFolderStateFlow: StateFlow<LocalFolder?> =
activeLocalFolderMutableStateFlow.asStateFlow()

private val loadMsgsListProgressMutableStateFlow: MutableStateFlow<Pair<Int, Double>> =
MutableStateFlow(Pair(0, 0.0))
val loadMsgsListProgressStateFlow: StateFlow<Pair<Int, Double>> =
loadMsgsListProgressMutableStateFlow.asStateFlow()

@ExperimentalCoroutinesApi
val pagerFlow = activeLocalFolderStateFlow.flatMapLatest { localFolder ->
val pager = MessagesRepository.getMessagesPager(application, localFolder)
val pager =
MessagesRepository.getMessagesPager(application, localFolder) { resultCode, progress ->
loadMsgsListProgressMutableStateFlow.value = Pair(resultCode, progress)
}
pager.flow.cachedIn(viewModelScope)
}

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

val loadMsgsFromRemoteServerLiveData = MutableLiveData<Result<Boolean?>>()
val refreshMsgsLiveData = MutableLiveData<Result<Boolean?>>()

val msgsCountLiveData = Transformations.switchMap(loadMsgsFromRemoteServerLiveData) {
liveData {
if (it.status != Result.Status.SUCCESS) return@liveData
val account = roomDatabase.accountDao().getActiveAccountSuspend()?.email ?: return@liveData
val folder = activeLocalFolderMutableStateFlow.value ?: return@liveData
val label = if (folder.searchQuery.isNullOrEmpty()) {
folder.fullName
} else {
JavaEmailConstants.FOLDER_SEARCH
}
emit(roomDatabase.msgDao().countSuspend(account, label))
}
}

fun switchFolder(newFolder: LocalFolder, deleteAllMsgs: Boolean, forceClearFolderCache: Boolean) {
if (activeLocalFolderMutableStateFlow.value == newFolder) {
return
Expand Down
Loading

0 comments on commit 6366ddf

Please sign in to comment.