mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-27 04:43:54 +01:00
Fixed sorting, list size issue
This commit is contained in:
parent
283e2c0a63
commit
b8723ad5af
7 changed files with 72 additions and 83 deletions
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
@ -21,8 +19,8 @@ class ContributionsLocalDataSource {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ContributionsLocalDataSource(
|
public ContributionsLocalDataSource(
|
||||||
@Named("default_preferences") final JsonKvStore defaultKVStore,
|
@Named("default_preferences") final JsonKvStore defaultKVStore,
|
||||||
final ContributionDao contributionDao) {
|
final ContributionDao contributionDao) {
|
||||||
this.defaultKVStore = defaultKVStore;
|
this.defaultKVStore = defaultKVStore;
|
||||||
this.contributionDao = contributionDao;
|
this.contributionDao = contributionDao;
|
||||||
}
|
}
|
||||||
|
|
@ -38,17 +36,19 @@ class ContributionsLocalDataSource {
|
||||||
* Fetch default number of contributions to be show, based on user preferences
|
* Fetch default number of contributions to be show, based on user preferences
|
||||||
*/
|
*/
|
||||||
public long getLong(final String key) {
|
public long getLong(final String key) {
|
||||||
return defaultKVStore.getLong(key);
|
return defaultKVStore.getLong(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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) {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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,9 +151,12 @@ 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.setChunkInfo(null);
|
it.setDateUploadStarted(Calendar.getInstance().getTime());
|
||||||
it.setTransferred(0);
|
if (it.getErrorInfo() == null){
|
||||||
|
it.setChunkInfo(null);
|
||||||
|
it.setTransferred(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
it.setState(Contribution.STATE_QUEUED);
|
it.setState(Contribution.STATE_QUEUED);
|
||||||
compositeDisposable.add(repository
|
compositeDisposable.add(repository
|
||||||
|
|
@ -178,9 +182,12 @@ 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.setChunkInfo(null);
|
it.setDateUploadStarted(Calendar.getInstance().getTime());
|
||||||
it.setTransferred(0);
|
if (it.getErrorInfo() == null){
|
||||||
|
it.setChunkInfo(null);
|
||||||
|
it.setTransferred(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
it.setState(Contribution.STATE_QUEUED);
|
it.setState(Contribution.STATE_QUEUED);
|
||||||
compositeDisposable.add(repository
|
compositeDisposable.add(repository
|
||||||
|
|
|
||||||
|
|
@ -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,25 +205,27 @@ 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)
|
||||||
}
|
// }
|
||||||
|
|
||||||
queuedContributions.asFlow().map { contribution ->
|
var contribution = sortedQueuedContributionsList.first()
|
||||||
if (contributionDao.getContribution(contribution.pageId) != null) {
|
|
||||||
contribution.transferred = 0
|
if (contributionDao.getContribution(contribution.pageId) != null) {
|
||||||
contribution.state = Contribution.STATE_IN_PROGRESS
|
contribution.transferred = 0
|
||||||
contributionDao.saveSynchronous(contribution)
|
contribution.state = Contribution.STATE_IN_PROGRESS
|
||||||
setProgressAsync(Data.Builder().putInt("progress", countUpload).build())
|
contributionDao.saveSynchronous(contribution)
|
||||||
countUpload++
|
setProgressAsync(Data.Builder().putInt("progress", countUpload).build())
|
||||||
uploadContribution(contribution = contribution)
|
countUpload++
|
||||||
}
|
uploadContribution(contribution = contribution)
|
||||||
}.collect()
|
}
|
||||||
|
|
||||||
//Dismiss the global notification
|
//Dismiss the global notification
|
||||||
notificationManager?.cancel(
|
notificationManager?.cancel(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue