From b8723ad5afd7e473989d5d331927949943be7666 Mon Sep 17 00:00:00 2001 From: Kanahia Date: Sun, 21 Jul 2024 20:07:27 +0530 Subject: [PATCH] Fixed sorting, list size issue --- .../nrw/commons/contributions/Contribution.kt | 5 ++ .../contributions/ContributionDao.java | 10 +++- .../ContributionsLocalDataSource.java | 33 ++++++++----- .../ContributionsRepository.java | 4 ++ .../commons/upload/PendingUploadsFragment.kt | 48 +------------------ .../upload/PendingUploadsPresenter.java | 23 +++++---- .../nrw/commons/upload/worker/UploadWorker.kt | 32 +++++++------ 7 files changed, 72 insertions(+), 83 deletions(-) diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.kt b/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.kt index 4e86f1d09..e140fd427 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.kt +++ b/app/src/main/java/fr/free/nrw/commons/contributions/Contribution.kt @@ -43,6 +43,7 @@ data class Contribution constructor( var dateCreated: Date? = null, var dateCreatedString: String? = null, var dateModified: Date? = null, + var dateUploadStarted: Date? = null, var hasInvalidLocation : Int = 0, var contentUri: Uri? = null, var countryCode : String? = null, @@ -140,4 +141,8 @@ data class Contribution constructor( return dateModified!!.time } + fun dateUploadStartedInMillis(): Long { + return dateUploadStarted!!.time + } + } diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java index 40efe028c..5ecf3cba3 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionDao.java @@ -27,6 +27,9 @@ public abstract class ContributionDao { return Completable .fromAction(() -> { contribution.setDateModified(Calendar.getInstance().getTime()); + if (contribution.getDateUploadStarted() == null) { + contribution.setDateUploadStarted(Calendar.getInstance().getTime()); + } saveSynchronous(contribution); }); } @@ -67,7 +70,12 @@ public abstract class ContributionDao { public abstract Single> getContribution(List states); @Query("SELECT * from contribution WHERE state IN (:states) order by media_dateUploaded DESC") - public abstract DataSource.Factory getContributions(List states); + public abstract DataSource.Factory getContributions( + List states); + + @Query("SELECT * from contribution WHERE state IN (:states) order by dateUploadStarted ASC") + public abstract DataSource.Factory getContributionsSortedByDateUploadStarted( + List states); @Query("SELECT COUNT(*) from contribution WHERE state in (:toUpdateStates)") public abstract Single getPendingUploads(int[] toUpdateStates); diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsLocalDataSource.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsLocalDataSource.java index 609b1d8a5..6e493cc56 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsLocalDataSource.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsLocalDataSource.java @@ -1,16 +1,14 @@ package fr.free.nrw.commons.contributions; import androidx.paging.DataSource.Factory; +import fr.free.nrw.commons.kvstore.JsonKvStore; import io.reactivex.Completable; +import io.reactivex.Single; import java.util.ArrayList; import java.util.List; - import javax.inject.Inject; import javax.inject.Named; -import fr.free.nrw.commons.kvstore.JsonKvStore; -import io.reactivex.Single; - /** * The LocalDataSource class for Contributions */ @@ -21,8 +19,8 @@ class ContributionsLocalDataSource { @Inject public ContributionsLocalDataSource( - @Named("default_preferences") final JsonKvStore defaultKVStore, - final ContributionDao contributionDao) { + @Named("default_preferences") final JsonKvStore defaultKVStore, + final ContributionDao contributionDao) { this.defaultKVStore = defaultKVStore; this.contributionDao = contributionDao; } @@ -38,17 +36,19 @@ class ContributionsLocalDataSource { * Fetch default number of contributions to be show, based on user preferences */ public long getLong(final String key) { - return defaultKVStore.getLong(key); + return defaultKVStore.getLong(key); } /** * Get contribution object from cursor + * * @param uri * @return */ public Contribution getContributionWithFileName(final String uri) { - final List contributionWithUri = contributionDao.getContributionWithTitle(uri); - if(!contributionWithUri.isEmpty()){ + final List contributionWithUri = contributionDao.getContributionWithTitle( + uri); + if (!contributionWithUri.isEmpty()) { return contributionWithUri.get(0); } return null; @@ -56,6 +56,7 @@ class ContributionsLocalDataSource { /** * Remove a contribution from the contributions table + * * @param contribution * @return */ @@ -75,11 +76,17 @@ class ContributionsLocalDataSource { return contributionDao.getContributions(states); } + public Factory getContributionsWithStatesSortedByDateUploadStarted( + List states) { + return contributionDao.getContributionsSortedByDateUploadStarted(states); + } + public Single> saveContributions(final List contributions) { final List contributionList = new ArrayList<>(); - for(final Contribution contribution: contributions) { - final Contribution oldContribution = contributionDao.getContribution(contribution.getPageId()); - if(oldContribution != null) { + for (final Contribution contribution : contributions) { + final Contribution oldContribution = contributionDao.getContribution( + contribution.getPageId()); + if (oldContribution != null) { contribution.setWikidataPlace(oldContribution.getWikidataPlace()); } contributionList.add(contribution); @@ -92,7 +99,7 @@ class ContributionsLocalDataSource { } public void set(final String key, final long value) { - defaultKVStore.putLong(key,value); + defaultKVStore.putLong(key, value); } public Completable updateContribution(final Contribution contribution) { diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsRepository.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsRepository.java index 8418bea00..8f9aa1c5f 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsRepository.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsRepository.java @@ -57,6 +57,10 @@ public class ContributionsRepository { return localDataSource.getContributionsWithStates(states); } + public Factory fetchContributionsWithStatesSortedByDateUploadStarted(List states) { + return localDataSource.getContributionsWithStatesSortedByDateUploadStarted(states); + } + public Single> save(List contributions) { return localDataSource.saveContributions(contributions); } diff --git a/app/src/main/java/fr/free/nrw/commons/upload/PendingUploadsFragment.kt b/app/src/main/java/fr/free/nrw/commons/upload/PendingUploadsFragment.kt index d3dda5af9..75301a3e1 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/PendingUploadsFragment.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/PendingUploadsFragment.kt @@ -136,53 +136,7 @@ class PendingUploadsFragment : CommonsDaggerSupportFragment(), PendingUploadsCon } else { binding.nopendingTextView.visibility = View.GONE binding.pendingUplaodsLl.visibility = View.VISIBLE - - val sortedContributionsList: List = - if (VERSION.SDK_INT >= VERSION_CODES.N) { - contributionsList.sortedByDescending { it.dateModifiedInMillis() } - } else { - contributionsList.sortedBy { it.dateModifiedInMillis() }.reversed() - } - - val newContributionList: MutableList = - sortedContributionsList.toMutableList() -// val listOfRemoved: MutableList = mutableListOf() -// val last = sortedContributionsList.last() -// for (i in sortedContributionsList.indices) { -// val current = sortedContributionsList[i] -// if (current.transferred == 0L && (current.dateModifiedInMillis() / 100) > (last.dateModifiedInMillis() / 100)) { -// listOfRemoved.add(current) -// } -// } -// newContributionList.removeAll(listOfRemoved) -// newContributionList.addAll(listOfRemoved) - - // TODO: WORK ON THE SORTING ISSUE - val dataSource = object : PositionalDataSource() { - override fun loadInitial( - params: LoadInitialParams, - callback: LoadInitialCallback - ) { - callback.onResult(newContributionList, 0, newContributionList.size) - } - - override fun loadRange( - params: LoadRangeParams, - callback: LoadRangeCallback - ) { - val start = params.startPosition - val end = Math.min(start + params.loadSize, newContributionList.size) - callback.onResult(newContributionList.subList(start, end)) - } - } - - val pagedList = PagedList.Builder(dataSource, 10) - .setFetchExecutor(AsyncTask.THREAD_POOL_EXECUTOR) - .setNotifyExecutor(AsyncTask.THREAD_POOL_EXECUTOR) - .build() - - adapter.submitList(pagedList) - + adapter.submitList(list) binding.progressTextView.setText(contributionsSize.toString() + " uploads left") if (pausedOrQueuedUploads == contributionsSize) { uploadProgressActivity.setPausedIcon(true) diff --git a/app/src/main/java/fr/free/nrw/commons/upload/PendingUploadsPresenter.java b/app/src/main/java/fr/free/nrw/commons/upload/PendingUploadsPresenter.java index 34c78b414..25134780a 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/PendingUploadsPresenter.java +++ b/app/src/main/java/fr/free/nrw/commons/upload/PendingUploadsPresenter.java @@ -20,6 +20,7 @@ import fr.free.nrw.commons.upload.worker.WorkRequestHelper; import io.reactivex.Scheduler; import io.reactivex.disposables.CompositeDisposable; import java.util.Arrays; +import java.util.Calendar; import java.util.Collections; import java.util.List; import javax.inject.Inject; @@ -67,7 +68,7 @@ public class PendingUploadsPresenter implements UserActionListener { .setPageSize(10).build(); Factory factory; - factory = repository.fetchContributionsWithStates( + factory = repository.fetchContributionsWithStatesSortedByDateUploadStarted( Arrays.asList(Contribution.STATE_QUEUED, Contribution.STATE_IN_PROGRESS, Contribution.STATE_PAUSED)); LivePagedListBuilder livePagedListBuilder = new LivePagedListBuilder(factory, @@ -81,7 +82,7 @@ public class PendingUploadsPresenter implements UserActionListener { .setPrefetchDistance(50) .setPageSize(10).build(); Factory factory; - factory = repository.fetchContributionsWithStates( + factory = repository.fetchContributionsWithStatesSortedByDateUploadStarted( Collections.singletonList(Contribution.STATE_FAILED)); LivePagedListBuilder livePagedListBuilder = new LivePagedListBuilder(factory, pagedListConfig); @@ -150,9 +151,12 @@ public class PendingUploadsPresenter implements UserActionListener { return; } Contribution it = contributionList.get(index); - if (it.getErrorInfo() == null && it.getState() == Contribution.STATE_FAILED) { - it.setChunkInfo(null); - it.setTransferred(0); + if (it.getState() == Contribution.STATE_FAILED) { + it.setDateUploadStarted(Calendar.getInstance().getTime()); + if (it.getErrorInfo() == null){ + it.setChunkInfo(null); + it.setTransferred(0); + } } it.setState(Contribution.STATE_QUEUED); compositeDisposable.add(repository @@ -178,9 +182,12 @@ public class PendingUploadsPresenter implements UserActionListener { return; } Contribution it = contributionList.get(index); - if (it.getErrorInfo() == null && it.getState() == Contribution.STATE_FAILED) { - it.setChunkInfo(null); - it.setTransferred(0); + if (it.getState() == Contribution.STATE_FAILED) { + it.setDateUploadStarted(Calendar.getInstance().getTime()); + if (it.getErrorInfo() == null){ + it.setChunkInfo(null); + it.setTransferred(0); + } } it.setState(Contribution.STATE_QUEUED); compositeDisposable.add(repository diff --git a/app/src/main/java/fr/free/nrw/commons/upload/worker/UploadWorker.kt b/app/src/main/java/fr/free/nrw/commons/upload/worker/UploadWorker.kt index a3b33d95d..88ec14486 100644 --- a/app/src/main/java/fr/free/nrw/commons/upload/worker/UploadWorker.kt +++ b/app/src/main/java/fr/free/nrw/commons/upload/worker/UploadWorker.kt @@ -8,6 +8,8 @@ import android.content.Context import android.content.Intent import android.graphics.BitmapFactory import android.os.Build +import android.os.Build.VERSION +import android.os.Build.VERSION_CODES import androidx.core.app.NotificationCompat import androidx.core.app.NotificationManagerCompat import androidx.multidex.BuildConfig @@ -203,25 +205,27 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) : processingUploads.build() ) + val sortedQueuedContributionsList: List = queuedContributions.sortedBy { it.dateUploadStartedInMillis() } + /** * To avoid race condition when multiple of these workers are working, assign this state so that the next one does not process these contribution again */ - queuedContributions.forEach { - it.state = Contribution.STATE_IN_PROGRESS - contributionDao.saveSynchronous(it) - } +// sortedQueuedContributionsList.forEach { +// it.state = Contribution.STATE_IN_PROGRESS +// contributionDao.saveSynchronous(it) +// } - queuedContributions.asFlow().map { contribution -> - if (contributionDao.getContribution(contribution.pageId) != null) { - contribution.transferred = 0 - contribution.state = Contribution.STATE_IN_PROGRESS - contributionDao.saveSynchronous(contribution) - setProgressAsync(Data.Builder().putInt("progress", countUpload).build()) - countUpload++ - uploadContribution(contribution = contribution) - } - }.collect() + var contribution = sortedQueuedContributionsList.first() + + if (contributionDao.getContribution(contribution.pageId) != null) { + contribution.transferred = 0 + contribution.state = Contribution.STATE_IN_PROGRESS + contributionDao.saveSynchronous(contribution) + setProgressAsync(Data.Builder().putInt("progress", countUpload).build()) + countUpload++ + uploadContribution(contribution = contribution) + } //Dismiss the global notification notificationManager?.cancel(