From 333c0bcbf34f4248a28cc84aca3626e53c496b0a Mon Sep 17 00:00:00 2001 From: Sujal-Gupta-SG Date: Sat, 4 Jan 2025 02:09:33 +0530 Subject: [PATCH] Fixed #6084 --- .../ContributionsListPresenter.java | 76 +++++++++++++++++++ .../ContributionsRemoteDataSource.kt | 8 +- 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListPresenter.java b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListPresenter.java index 100c8be03..a7c49c23e 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListPresenter.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsListPresenter.java @@ -2,8 +2,12 @@ package fr.free.nrw.commons.contributions; import static fr.free.nrw.commons.di.CommonsApplicationModule.IO_THREAD; +import android.os.Handler; +import android.os.Looper; + import androidx.annotation.NonNull; import androidx.lifecycle.LiveData; +import androidx.lifecycle.MutableLiveData; import androidx.paging.DataSource; import androidx.paging.DataSource.Factory; import androidx.paging.LivePagedListBuilder; @@ -12,7 +16,9 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; import fr.free.nrw.commons.contributions.ContributionsListContract.UserActionListener; import io.reactivex.Scheduler; import io.reactivex.disposables.CompositeDisposable; +import java.util.ArrayList; import java.util.Collections; +import java.util.List; import javax.inject.Inject; import javax.inject.Named; import kotlin.Unit; @@ -32,6 +38,15 @@ public class ContributionsListPresenter implements UserActionListener { LiveData> contributionList; + private MutableLiveData> liveData = new MutableLiveData<>(); + + private List existingContributions = new ArrayList<>(); + + // Timer for polling new contributions + private Handler pollingHandler; + private Runnable pollingRunnable; + private long pollingInterval = 1 * 60 * 1000L; // Poll every minute + @Inject ContributionsListPresenter( final ContributionBoundaryCallback contributionBoundaryCallback, @@ -87,6 +102,15 @@ public class ContributionsListPresenter implements UserActionListener { } contributionList = livePagedListBuilder.build(); + contributionList.observeForever(pagedList -> { + if (pagedList != null) { + existingContributions.clear(); + existingContributions.addAll(pagedList); + liveData.setValue(existingContributions); // Update liveData with the latest list + } + }); + // Start polling for new contributions + startPollingForNewContributions(); } @Override @@ -94,6 +118,7 @@ public class ContributionsListPresenter implements UserActionListener { compositeDisposable.clear(); contributionsRemoteDataSource.dispose(); contributionBoundaryCallback.dispose(); + stopPollingForNewContributions(); } /** @@ -109,4 +134,55 @@ public class ContributionsListPresenter implements UserActionListener { return Unit.INSTANCE; }); } + + /** + * Start polling for new contributions every 15 minutes. + */ + private void startPollingForNewContributions() { + if (pollingHandler != null) { + stopPollingForNewContributions(); + } + + pollingHandler = new Handler(Looper.getMainLooper()); + pollingRunnable = new Runnable() { + @Override + public void run() { + fetchNewContributions(); // Fetch new contributions in background + pollingHandler.postDelayed(this, pollingInterval); // Repeat after the interval + } + }; + pollingHandler.post(pollingRunnable); // Start polling immediately + } + + /** + * Stop the polling task when the view is detached or the activity is paused. + */ + private void stopPollingForNewContributions() { + if (pollingHandler != null && pollingRunnable != null) { + pollingHandler.removeCallbacks(pollingRunnable); + pollingHandler = null; + pollingRunnable = null; + } + } + + public void appendContributions(List newContributions) { + if (newContributions != null && !newContributions.isEmpty()) { + existingContributions.addAll(newContributions); + liveData.postValue(existingContributions); + } + } + /** + * Fetch new contributions from the server and append them to the existing list. + */ + private void fetchNewContributions() { + contributionsRemoteDataSource.fetchContributions(new ContributionsRemoteDataSource.LoadCallback() { + @Override + public void onResult(List newContributions) { + if (newContributions != null && !newContributions.isEmpty()) { + appendContributions(newContributions); // Add new contributions + } + } + }); + } + } diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsRemoteDataSource.kt b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsRemoteDataSource.kt index e8ff01b3e..e840fe86f 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsRemoteDataSource.kt +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionsRemoteDataSource.kt @@ -46,7 +46,13 @@ class ContributionsRemoteDataSource /** * Fetches contributions using the MediaWiki API */ - private fun fetchContributions(callback: LoadCallback) { + public fun fetchContributions(callback: LoadCallback) { + if (userName.isNullOrEmpty()) { + Timber.e("Failed to fetch contributions: userName is null or empty") + return + } + Timber.d("Fetching contributions for user: $userName") + compositeDisposable.add( mediaClient .getMediaListForUser(userName!!)