Fixed sorting, list size issue

This commit is contained in:
Kanahia 2024-07-21 20:07:27 +05:30
parent 283e2c0a63
commit b8723ad5af
7 changed files with 72 additions and 83 deletions

View file

@ -43,6 +43,7 @@ data class Contribution constructor(
var dateCreated: Date? = null, var dateCreated: Date? = null,
var dateCreatedString: String? = null, var dateCreatedString: String? = null,
var dateModified: Date? = null, var dateModified: Date? = null,
var dateUploadStarted: Date? = null,
var hasInvalidLocation : Int = 0, var hasInvalidLocation : Int = 0,
var contentUri: Uri? = null, var contentUri: Uri? = null,
var countryCode : String? = null, var countryCode : String? = null,
@ -140,4 +141,8 @@ data class Contribution constructor(
return dateModified!!.time return dateModified!!.time
} }
fun dateUploadStartedInMillis(): Long {
return dateUploadStarted!!.time
}
} }

View file

@ -27,6 +27,9 @@ public abstract class ContributionDao {
return Completable return Completable
.fromAction(() -> { .fromAction(() -> {
contribution.setDateModified(Calendar.getInstance().getTime()); contribution.setDateModified(Calendar.getInstance().getTime());
if (contribution.getDateUploadStarted() == null) {
contribution.setDateUploadStarted(Calendar.getInstance().getTime());
}
saveSynchronous(contribution); saveSynchronous(contribution);
}); });
} }
@ -67,7 +70,12 @@ public abstract class ContributionDao {
public abstract Single<List<Contribution>> getContribution(List<Integer> states); public abstract Single<List<Contribution>> getContribution(List<Integer> states);
@Query("SELECT * from contribution WHERE state IN (:states) order by media_dateUploaded DESC") @Query("SELECT * from contribution WHERE state IN (:states) order by media_dateUploaded DESC")
public abstract DataSource.Factory<Integer, Contribution> getContributions(List<Integer> states); public abstract DataSource.Factory<Integer, Contribution> getContributions(
List<Integer> states);
@Query("SELECT * from contribution WHERE state IN (:states) order by dateUploadStarted ASC")
public abstract DataSource.Factory<Integer, Contribution> getContributionsSortedByDateUploadStarted(
List<Integer> states);
@Query("SELECT COUNT(*) from contribution WHERE state in (:toUpdateStates)") @Query("SELECT COUNT(*) from contribution WHERE state in (:toUpdateStates)")
public abstract Single<Integer> getPendingUploads(int[] toUpdateStates); public abstract Single<Integer> getPendingUploads(int[] toUpdateStates);

View file

@ -1,16 +1,14 @@
package fr.free.nrw.commons.contributions; package fr.free.nrw.commons.contributions;
import androidx.paging.DataSource.Factory; import androidx.paging.DataSource.Factory;
import fr.free.nrw.commons.kvstore.JsonKvStore;
import io.reactivex.Completable; import io.reactivex.Completable;
import io.reactivex.Single;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Named; import javax.inject.Named;
import fr.free.nrw.commons.kvstore.JsonKvStore;
import io.reactivex.Single;
/** /**
* The LocalDataSource class for Contributions * The LocalDataSource class for Contributions
*/ */
@ -43,12 +41,14 @@ class ContributionsLocalDataSource {
/** /**
* Get contribution object from cursor * Get contribution object from cursor
*
* @param uri * @param uri
* @return * @return
*/ */
public Contribution getContributionWithFileName(final String uri) { public Contribution getContributionWithFileName(final String uri) {
final List<Contribution> contributionWithUri = contributionDao.getContributionWithTitle(uri); final List<Contribution> contributionWithUri = contributionDao.getContributionWithTitle(
if(!contributionWithUri.isEmpty()){ uri);
if (!contributionWithUri.isEmpty()) {
return contributionWithUri.get(0); return contributionWithUri.get(0);
} }
return null; return null;
@ -56,6 +56,7 @@ class ContributionsLocalDataSource {
/** /**
* Remove a contribution from the contributions table * Remove a contribution from the contributions table
*
* @param contribution * @param contribution
* @return * @return
*/ */
@ -75,11 +76,17 @@ class ContributionsLocalDataSource {
return contributionDao.getContributions(states); return contributionDao.getContributions(states);
} }
public Factory<Integer, Contribution> getContributionsWithStatesSortedByDateUploadStarted(
List<Integer> states) {
return contributionDao.getContributionsSortedByDateUploadStarted(states);
}
public Single<List<Long>> saveContributions(final List<Contribution> contributions) { public Single<List<Long>> saveContributions(final List<Contribution> contributions) {
final List<Contribution> contributionList = new ArrayList<>(); final List<Contribution> contributionList = new ArrayList<>();
for(final Contribution contribution: contributions) { for (final Contribution contribution : contributions) {
final Contribution oldContribution = contributionDao.getContribution(contribution.getPageId()); final Contribution oldContribution = contributionDao.getContribution(
if(oldContribution != null) { contribution.getPageId());
if (oldContribution != null) {
contribution.setWikidataPlace(oldContribution.getWikidataPlace()); contribution.setWikidataPlace(oldContribution.getWikidataPlace());
} }
contributionList.add(contribution); contributionList.add(contribution);
@ -92,7 +99,7 @@ class ContributionsLocalDataSource {
} }
public void set(final String key, final long value) { public void set(final String key, final long value) {
defaultKVStore.putLong(key,value); defaultKVStore.putLong(key, value);
} }
public Completable updateContribution(final Contribution contribution) { public Completable updateContribution(final Contribution contribution) {

View file

@ -57,6 +57,10 @@ public class ContributionsRepository {
return localDataSource.getContributionsWithStates(states); return localDataSource.getContributionsWithStates(states);
} }
public Factory<Integer, Contribution> fetchContributionsWithStatesSortedByDateUploadStarted(List<Integer> states) {
return localDataSource.getContributionsWithStatesSortedByDateUploadStarted(states);
}
public Single<List<Long>> save(List<Contribution> contributions) { public Single<List<Long>> save(List<Contribution> contributions) {
return localDataSource.saveContributions(contributions); return localDataSource.saveContributions(contributions);
} }

View file

@ -136,53 +136,7 @@ class PendingUploadsFragment : CommonsDaggerSupportFragment(), PendingUploadsCon
} else { } else {
binding.nopendingTextView.visibility = View.GONE binding.nopendingTextView.visibility = View.GONE
binding.pendingUplaodsLl.visibility = View.VISIBLE binding.pendingUplaodsLl.visibility = View.VISIBLE
adapter.submitList(list)
val sortedContributionsList: List<Contribution> =
if (VERSION.SDK_INT >= VERSION_CODES.N) {
contributionsList.sortedByDescending { it.dateModifiedInMillis() }
} else {
contributionsList.sortedBy { it.dateModifiedInMillis() }.reversed()
}
val newContributionList: MutableList<Contribution> =
sortedContributionsList.toMutableList()
// val listOfRemoved: MutableList<Contribution> = 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<Contribution>() {
override fun loadInitial(
params: LoadInitialParams,
callback: LoadInitialCallback<Contribution>
) {
callback.onResult(newContributionList, 0, newContributionList.size)
}
override fun loadRange(
params: LoadRangeParams,
callback: LoadRangeCallback<Contribution>
) {
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)
binding.progressTextView.setText(contributionsSize.toString() + " uploads left") binding.progressTextView.setText(contributionsSize.toString() + " uploads left")
if (pausedOrQueuedUploads == contributionsSize) { if (pausedOrQueuedUploads == contributionsSize) {
uploadProgressActivity.setPausedIcon(true) uploadProgressActivity.setPausedIcon(true)

View file

@ -20,6 +20,7 @@ import fr.free.nrw.commons.upload.worker.WorkRequestHelper;
import io.reactivex.Scheduler; import io.reactivex.Scheduler;
import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.CompositeDisposable;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import javax.inject.Inject; import javax.inject.Inject;
@ -67,7 +68,7 @@ public class PendingUploadsPresenter implements UserActionListener {
.setPageSize(10).build(); .setPageSize(10).build();
Factory<Integer, Contribution> factory; Factory<Integer, Contribution> factory;
factory = repository.fetchContributionsWithStates( factory = repository.fetchContributionsWithStatesSortedByDateUploadStarted(
Arrays.asList(Contribution.STATE_QUEUED, Contribution.STATE_IN_PROGRESS, Arrays.asList(Contribution.STATE_QUEUED, Contribution.STATE_IN_PROGRESS,
Contribution.STATE_PAUSED)); Contribution.STATE_PAUSED));
LivePagedListBuilder livePagedListBuilder = new LivePagedListBuilder(factory, LivePagedListBuilder livePagedListBuilder = new LivePagedListBuilder(factory,
@ -81,7 +82,7 @@ public class PendingUploadsPresenter implements UserActionListener {
.setPrefetchDistance(50) .setPrefetchDistance(50)
.setPageSize(10).build(); .setPageSize(10).build();
Factory<Integer, Contribution> factory; Factory<Integer, Contribution> factory;
factory = repository.fetchContributionsWithStates( factory = repository.fetchContributionsWithStatesSortedByDateUploadStarted(
Collections.singletonList(Contribution.STATE_FAILED)); Collections.singletonList(Contribution.STATE_FAILED));
LivePagedListBuilder livePagedListBuilder = new LivePagedListBuilder(factory, LivePagedListBuilder livePagedListBuilder = new LivePagedListBuilder(factory,
pagedListConfig); pagedListConfig);
@ -150,10 +151,13 @@ public class PendingUploadsPresenter implements UserActionListener {
return; return;
} }
Contribution it = contributionList.get(index); Contribution it = contributionList.get(index);
if (it.getErrorInfo() == null && it.getState() == Contribution.STATE_FAILED) { if (it.getState() == Contribution.STATE_FAILED) {
it.setDateUploadStarted(Calendar.getInstance().getTime());
if (it.getErrorInfo() == null){
it.setChunkInfo(null); it.setChunkInfo(null);
it.setTransferred(0); it.setTransferred(0);
} }
}
it.setState(Contribution.STATE_QUEUED); it.setState(Contribution.STATE_QUEUED);
compositeDisposable.add(repository compositeDisposable.add(repository
.save(it) .save(it)
@ -178,10 +182,13 @@ public class PendingUploadsPresenter implements UserActionListener {
return; return;
} }
Contribution it = contributionList.get(index); Contribution it = contributionList.get(index);
if (it.getErrorInfo() == null && it.getState() == Contribution.STATE_FAILED) { if (it.getState() == Contribution.STATE_FAILED) {
it.setDateUploadStarted(Calendar.getInstance().getTime());
if (it.getErrorInfo() == null){
it.setChunkInfo(null); it.setChunkInfo(null);
it.setTransferred(0); it.setTransferred(0);
} }
}
it.setState(Contribution.STATE_QUEUED); it.setState(Contribution.STATE_QUEUED);
compositeDisposable.add(repository compositeDisposable.add(repository
.save(it) .save(it)

View file

@ -8,6 +8,8 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.graphics.BitmapFactory import android.graphics.BitmapFactory
import android.os.Build import android.os.Build
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat import androidx.core.app.NotificationManagerCompat
import androidx.multidex.BuildConfig import androidx.multidex.BuildConfig
@ -203,16 +205,19 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) :
processingUploads.build() processingUploads.build()
) )
val sortedQueuedContributionsList: List<Contribution> = queuedContributions.sortedBy { it.dateUploadStartedInMillis() }
/** /**
* To avoid race condition when multiple of these workers are working, assign this state * 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 so that the next one does not process these contribution again
*/ */
queuedContributions.forEach { // sortedQueuedContributionsList.forEach {
it.state = Contribution.STATE_IN_PROGRESS // it.state = Contribution.STATE_IN_PROGRESS
contributionDao.saveSynchronous(it) // contributionDao.saveSynchronous(it)
} // }
var contribution = sortedQueuedContributionsList.first()
queuedContributions.asFlow().map { contribution ->
if (contributionDao.getContribution(contribution.pageId) != null) { if (contributionDao.getContribution(contribution.pageId) != null) {
contribution.transferred = 0 contribution.transferred = 0
contribution.state = Contribution.STATE_IN_PROGRESS contribution.state = Contribution.STATE_IN_PROGRESS
@ -221,7 +226,6 @@ class UploadWorker(var appContext: Context, workerParams: WorkerParameters) :
countUpload++ countUpload++
uploadContribution(contribution = contribution) uploadContribution(contribution = contribution)
} }
}.collect()
//Dismiss the global notification //Dismiss the global notification
notificationManager?.cancel( notificationManager?.cancel(