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 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
}
}

View file

@ -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<List<Contribution>> getContribution(List<Integer> states);
@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)")
public abstract Single<Integer> getPendingUploads(int[] toUpdateStates);

View file

@ -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<Contribution> contributionWithUri = contributionDao.getContributionWithTitle(uri);
if(!contributionWithUri.isEmpty()){
final List<Contribution> 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<Integer, Contribution> getContributionsWithStatesSortedByDateUploadStarted(
List<Integer> states) {
return contributionDao.getContributionsSortedByDateUploadStarted(states);
}
public Single<List<Long>> saveContributions(final List<Contribution> contributions) {
final List<Contribution> 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) {

View file

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

View file

@ -136,53 +136,7 @@ class PendingUploadsFragment : CommonsDaggerSupportFragment(), PendingUploadsCon
} else {
binding.nopendingTextView.visibility = View.GONE
binding.pendingUplaodsLl.visibility = View.VISIBLE
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)
adapter.submitList(list)
binding.progressTextView.setText(contributionsSize.toString() + " uploads left")
if (pausedOrQueuedUploads == contributionsSize) {
uploadProgressActivity.setPausedIcon(true)

View file

@ -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<Integer, Contribution> 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<Integer, Contribution> 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

View file

@ -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<Contribution> = 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(