diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionBoundaryCallback.kt b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionBoundaryCallback.kt index 52be55552..9af37af36 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/ContributionBoundaryCallback.kt +++ b/app/src/main/java/fr/free/nrw/commons/contributions/ContributionBoundaryCallback.kt @@ -1,5 +1,6 @@ package fr.free.nrw.commons.contributions +import android.annotation.SuppressLint import androidx.paging.PagedList.BoundaryCallback import fr.free.nrw.commons.auth.SessionManager import fr.free.nrw.commons.di.CommonsApplicationModule.Companion.IO_THREAD @@ -66,31 +67,34 @@ class ContributionBoundaryCallback * with either error or success. */ private fun fetchContributions(onRefreshFinish: () -> Unit = {}) { + if (sessionManager.userName != null) { - userName - ?.let { userName -> - mediaClient - .getMediaListForUser(userName) - .map { mediaList -> - mediaList.map { media -> - Contribution(media = media, state = Contribution.STATE_COMPLETED) - } - }.subscribeOn(ioThreadScheduler) - .subscribe({ list -> - saveContributionsToDB(list, onRefreshFinish) - },{ error -> - onRefreshFinish() - Timber.e( - "Failed to fetch contributions: %s", - error.message, - ) - }) - }?.let { - compositeDisposable.add( - it, - ) - } + + sessionManager.userName?.let { userName -> + + mediaClient + .getMediaListForUser(userName) + .map { mediaList -> + Timber.d("Mapping media list of size: ${mediaList.size}") + mediaList.map { media -> + Contribution(media = media, state = Contribution.STATE_COMPLETED) + } + }.subscribeOn(ioThreadScheduler) + .subscribe({ list -> + saveContributionsToDB(list, onRefreshFinish) + },{ error -> + Timber.e("Failed to fetch contributions: ${error.message}") + Timber.e(error) // Log full stack trace + onRefreshFinish() + }) + }?.let { + compositeDisposable.add(it) + } ?: run { + // Add logging if userName?.let returns null + Timber.d("userName?.let returned null") + } } else { + Timber.d("SessionManager userName is null, clearing disposable") compositeDisposable.clear() } } 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 5428c405f..219a55d48 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 @@ -129,11 +129,4 @@ public class ContributionsListPresenter implements UserActionListener { }); } - /** - * Check for new contributions by comparing the latest contribution identifier. - */ - void fetchContributions() { - contributionBoundaryCallback.refreshList(() -> Unit.INSTANCE); - } - } \ No newline at end of file diff --git a/app/src/main/java/fr/free/nrw/commons/contributions/MainActivity.java b/app/src/main/java/fr/free/nrw/commons/contributions/MainActivity.java index 0a9ea9f35..968f1074c 100644 --- a/app/src/main/java/fr/free/nrw/commons/contributions/MainActivity.java +++ b/app/src/main/java/fr/free/nrw/commons/contributions/MainActivity.java @@ -1,13 +1,12 @@ package fr.free.nrw.commons.contributions; -import static android.mediautil.MediaUtil.getContext; - import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; +import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; @@ -23,6 +22,7 @@ import androidx.fragment.app.FragmentManager; import androidx.fragment.app.FragmentManager.OnBackStackChangedListener; import androidx.work.ExistingWorkPolicy; import com.google.android.material.bottomnavigation.BottomNavigationView.OnNavigationItemSelectedListener; +import fr.free.nrw.commons.databinding.FragmentContributionsListBinding; import fr.free.nrw.commons.databinding.MainBinding; import fr.free.nrw.commons.R; import fr.free.nrw.commons.WelcomeActivity; @@ -42,8 +42,8 @@ import fr.free.nrw.commons.nearby.Place; import fr.free.nrw.commons.nearby.fragments.NearbyParentFragment; import fr.free.nrw.commons.nearby.fragments.NearbyParentFragment.NearbyParentFragmentInstanceReadyCallback; import fr.free.nrw.commons.notification.NotificationActivity; -import fr.free.nrw.commons.notification.NotificationActivity.Companion; import fr.free.nrw.commons.notification.NotificationController; +import fr.free.nrw.commons.profile.ProfileActivity; import fr.free.nrw.commons.quiz.QuizChecker; import fr.free.nrw.commons.settings.SettingsFragment; import fr.free.nrw.commons.theme.BaseActivity; @@ -59,9 +59,11 @@ import io.reactivex.schedulers.Schedulers; import java.util.Calendar; import java.util.Collections; import java.util.List; +import java.util.Objects; import javax.inject.Inject; import javax.inject.Named; import kotlin.Unit; +import org.apache.commons.lang3.StringUtils; import timber.log.Timber; public class MainActivity extends BaseActivity @@ -95,8 +97,7 @@ public class MainActivity extends BaseActivity QuizChecker quizChecker; @Inject @Named("default_preferences") - public - JsonKvStore applicationKvStore; + public JsonKvStore applicationKvStore; @Inject ViewUtilWrapper viewUtilWrapper; @@ -106,6 +107,9 @@ public class MainActivity extends BaseActivity NavTabLayout tabLayout; + private FragmentContributionsListBinding refresh; + + private String userName; /** * Consumers should be simply using this method to use this activity. @@ -143,15 +147,7 @@ public class MainActivity extends BaseActivity binding.toolbarBinding.toolbar.setNavigationOnClickListener(view -> { onSupportNavigateUp(); }); - /* - "first_edit_depict" is a key for getting information about opening the depiction editor - screen for the first time after opening the app. - Getting true by the key means the depiction editor screen is opened for the first time - after opening the app. - Getting false by the key means the depiction editor screen is not opened for the first time - after opening the app. - */ applicationKvStore.putBoolean("first_edit_depict", true); if (applicationKvStore.getBoolean("login_skipped") == true) { setTitle(getString(R.string.navigation_item_explore)); @@ -162,8 +158,6 @@ public class MainActivity extends BaseActivity applicationKvStore.putBoolean("hasAlreadyLaunchedCategoriesDialog", false); } if (savedInstanceState == null) { - //starting a fresh fragment. - // Open Last opened screen if it is Contributions or Nearby, otherwise Contributions if (applicationKvStore.getBoolean("last_opened_nearby")) { setTitle(getString(R.string.nearby_fragment)); showNearby(); @@ -173,22 +167,15 @@ public class MainActivity extends BaseActivity loadFragment(ContributionsFragment.newInstance(), false); } } + refresh = FragmentContributionsListBinding.inflate(getLayoutInflater()); + if (getIntent().getExtras() != null) { + userName = getIntent().getExtras().getString(ProfileActivity.KEY_USERNAME); + } + + if (StringUtils.isEmpty(userName)) { + userName = sessionManager.getUserName(); + } setUpPager(); - /** - * Ask the user for media location access just after login - * so that location in the EXIF metadata of the images shared by the user - * is retained on devices running Android 10 or above - */ -// if (VERSION.SDK_INT >= VERSION_CODES.Q) { -// ActivityCompat.requestPermissions(this, -// new String[]{Manifest.permission.ACCESS_MEDIA_LOCATION}, 0); -// PermissionUtils.checkPermissionsAndPerformAction( -// this, -// () -> {}, -// R.string.media_location_permission_denied, -// R.string.add_location_manually, -// permission.ACCESS_MEDIA_LOCATION); -// } checkAndResumeStuckUploads(); } } @@ -201,10 +188,8 @@ public class MainActivity extends BaseActivity binding.fragmentMainNavTabLayout.setOnNavigationItemSelectedListener( navListener = (item) -> { if (!item.getTitle().equals(getString(R.string.more))) { - // do not change title for more fragment setTitle(item.getTitle()); } - // set last_opened_nearby true if item is nearby screen else set false applicationKvStore.putBoolean("last_opened_nearby", item.getTitle().equals(getString(R.string.nearby_fragment))); final Fragment fragment = NavTab.of(item.getOrder()).newInstance(); @@ -216,7 +201,6 @@ public class MainActivity extends BaseActivity loadFragment(ExploreFragment.newInstance(), false); binding.fragmentMainNavTabLayout.setOnNavigationItemSelectedListener(item -> { if (!item.getTitle().equals(getString(R.string.more))) { - // do not change title for more fragment setTitle(item.getTitle()); } Fragment fragment = NavTabLoggedOut.of(item.getOrder()).newInstance(); @@ -225,44 +209,38 @@ public class MainActivity extends BaseActivity } private boolean loadFragment(Fragment fragment, boolean showBottom) { - //showBottom so that we do not show the bottom tray again when constructing - //from the saved instance state. if (fragment instanceof ContributionsFragment) { if (activeFragment == ActiveFragment.CONTRIBUTIONS) { - // scroll to top if already on the Contributions tab contributionsFragment.scrollToTop(); return true; } contributionsFragment = (ContributionsFragment) fragment; activeFragment = ActiveFragment.CONTRIBUTIONS; } else if (fragment instanceof NearbyParentFragment) { - if (activeFragment == ActiveFragment.NEARBY) { // Do nothing if same tab + if (activeFragment == ActiveFragment.NEARBY) { return true; } nearbyParentFragment = (NearbyParentFragment) fragment; activeFragment = ActiveFragment.NEARBY; } else if (fragment instanceof ExploreFragment) { - if (activeFragment == ActiveFragment.EXPLORE) { // Do nothing if same tab + if (activeFragment == ActiveFragment.EXPLORE) { return true; } exploreFragment = (ExploreFragment) fragment; activeFragment = ActiveFragment.EXPLORE; } else if (fragment instanceof BookmarkFragment) { - if (activeFragment == ActiveFragment.BOOKMARK) { // Do nothing if same tab + if (activeFragment == ActiveFragment.BOOKMARK) { return true; } bookmarkFragment = (BookmarkFragment) fragment; activeFragment = ActiveFragment.BOOKMARK; } else if (fragment == null && showBottom) { - if (applicationKvStore.getBoolean("login_skipped") - == true) { // If logged out, more sheet is different + if (applicationKvStore.getBoolean("login_skipped") == true) { MoreBottomSheetLoggedOutFragment bottomSheet = new MoreBottomSheetLoggedOutFragment(); - bottomSheet.show(getSupportFragmentManager(), - "MoreBottomSheetLoggedOut"); + bottomSheet.show(getSupportFragmentManager(), "MoreBottomSheetLoggedOut"); } else { MoreBottomSheetFragment bottomSheet = new MoreBottomSheetFragment(); - bottomSheet.show(getSupportFragmentManager(), - "MoreBottomSheet"); + bottomSheet.show(getSupportFragmentManager(), "MoreBottomSheet"); } } @@ -284,12 +262,6 @@ public class MainActivity extends BaseActivity binding.fragmentMainNavTabLayout.setVisibility(View.VISIBLE); } - /** - * Adds number of uploads next to tab text "Contributions" then it will look like "Contributions - * (NUMBER)" - * - * @param uploadCount - */ public void setNumOfUploads(int uploadCount) { if (activeFragment == ActiveFragment.CONTRIBUTIONS) { setTitle(getResources().getString(R.string.contributions_fragment) + " " + ( @@ -301,15 +273,6 @@ public class MainActivity extends BaseActivity } } - /** - * Resume the uploads that got stuck because of the app being killed or the device being - * rebooted. - *
- * When the app is terminated or the device is restarted, contributions remain in the
- * 'STATE_IN_PROGRESS' state. This status persists and doesn't change during these events. So,
- * retrieving contributions labeled as 'STATE_IN_PROGRESS' from the database will provide the
- * list of uploads that appear as stuck on opening the app again
- */
@SuppressLint("CheckResult")
private void checkAndResumeStuckUploads() {
List