mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-27 21:03:54 +01:00
updated
This commit is contained in:
parent
91174778b5
commit
8747226a4d
3 changed files with 85 additions and 124 deletions
|
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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.
|
||||
* <p>
|
||||
* 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<Contribution> stuckUploads = contributionDao.getContribution(
|
||||
|
|
@ -333,7 +296,6 @@ public class MainActivity extends BaseActivity
|
|||
@Override
|
||||
protected void onPostCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onPostCreate(savedInstanceState);
|
||||
//quizChecker.initQuizCheck(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -371,22 +333,16 @@ public class MainActivity extends BaseActivity
|
|||
@Override
|
||||
public void onBackPressed() {
|
||||
if (contributionsFragment != null && activeFragment == ActiveFragment.CONTRIBUTIONS) {
|
||||
// Means that contribution fragment is visible
|
||||
if (!contributionsFragment.backButtonClicked()) {//If this one does not wan't to handle
|
||||
// the back press, let the activity do so
|
||||
if (!contributionsFragment.backButtonClicked()) {
|
||||
super.onBackPressed();
|
||||
}
|
||||
} else if (nearbyParentFragment != null && activeFragment == ActiveFragment.NEARBY) {
|
||||
// Means that nearby fragment is visible
|
||||
/* If function nearbyParentFragment.backButtonClick() returns false, it means that the bottomsheet is
|
||||
not expanded. So if the back button is pressed, then go back to the Contributions tab */
|
||||
if (!nearbyParentFragment.backButtonClicked()) {
|
||||
getSupportFragmentManager().beginTransaction().remove(nearbyParentFragment)
|
||||
.commit();
|
||||
setSelectedItemId(NavTab.CONTRIBUTIONS.code());
|
||||
}
|
||||
} else if (exploreFragment != null && activeFragment == ActiveFragment.EXPLORE) {
|
||||
// Means that explore fragment is visible
|
||||
if (!exploreFragment.onBackPressed()) {
|
||||
if (applicationKvStore.getBoolean("login_skipped")) {
|
||||
super.onBackPressed();
|
||||
|
|
@ -395,7 +351,6 @@ public class MainActivity extends BaseActivity
|
|||
}
|
||||
}
|
||||
} else if (bookmarkFragment != null && activeFragment == ActiveFragment.BOOKMARK) {
|
||||
// Means that bookmark fragment is visible
|
||||
bookmarkFragment.onBackPressed();
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
|
|
@ -404,12 +359,8 @@ public class MainActivity extends BaseActivity
|
|||
|
||||
@Override
|
||||
public void onBackStackChanged() {
|
||||
//initBackButton();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retry all failed uploads as soon as the user returns to the app
|
||||
*/
|
||||
@SuppressLint("CheckResult")
|
||||
private void retryAllFailedUploads() {
|
||||
contributionDao.
|
||||
|
|
@ -422,10 +373,6 @@ public class MainActivity extends BaseActivity
|
|||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles item selection in the options menu. This method is called when a user interacts with
|
||||
* the options menu in the Top Bar.
|
||||
*/
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
|
|
@ -436,21 +383,17 @@ public class MainActivity extends BaseActivity
|
|||
NotificationActivity.Companion.startYourself(this, "unread");
|
||||
return true;
|
||||
case R.id.menu_refresh:
|
||||
// Refresh button handled in onCreateOptionsMenu through action layout
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
menu.clear(); // Clear the old menu to prevent duplication
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.contribution_activity_notification_menu, menu);
|
||||
|
||||
// Handle refresh button click
|
||||
MenuItem refreshItem = menu.findItem(R.id.menu_refresh);
|
||||
if (refreshItem != null) {
|
||||
View actionView = refreshItem.getActionView();
|
||||
|
|
@ -462,8 +405,22 @@ public class MainActivity extends BaseActivity
|
|||
Animation rotateAnimation = AnimationUtils.loadAnimation(this, R.anim.rotate);
|
||||
v.startAnimation(rotateAnimation);
|
||||
|
||||
// Trigger refresh logic
|
||||
contributionsListPresenter.fetchContributions();
|
||||
// Initialize userName if it's null
|
||||
if (userName == null) {
|
||||
userName = sessionManager.getUserName();
|
||||
}
|
||||
|
||||
if (Objects.equals(sessionManager.getUserName(), userName)) {
|
||||
if (refresh != null && refresh.swipeRefreshLayout != null) {
|
||||
refresh.swipeRefreshLayout.setRefreshing(true);
|
||||
refresh.swipeRefreshLayout.setEnabled(true);
|
||||
contributionsListPresenter.refreshList(refresh.swipeRefreshLayout);
|
||||
}
|
||||
} else {
|
||||
if (refresh != null && refresh.swipeRefreshLayout != null) {
|
||||
refresh.swipeRefreshLayout.setEnabled(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -486,7 +443,6 @@ public class MainActivity extends BaseActivity
|
|||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
// Check if it's the first run and the user hasn't skipped login
|
||||
if (applicationKvStore.getBoolean("firstrun", true) &&
|
||||
!applicationKvStore.getBoolean("login_skipped")) {
|
||||
defaultKvStore.putBoolean("inAppCameraFirstRun", true);
|
||||
|
|
@ -494,22 +450,33 @@ public class MainActivity extends BaseActivity
|
|||
}
|
||||
|
||||
retryAllFailedUploads();
|
||||
// Background check for new contributions
|
||||
contributionsListPresenter.fetchContributions();
|
||||
//check for new contributions
|
||||
// Initialize userName if it's null
|
||||
if (userName == null) {
|
||||
userName = sessionManager.getUserName();
|
||||
}
|
||||
|
||||
if (Objects.equals(sessionManager.getUserName(), userName)) {
|
||||
if (refresh != null && refresh.swipeRefreshLayout != null) {
|
||||
refresh.swipeRefreshLayout.setRefreshing(true);
|
||||
refresh.swipeRefreshLayout.setEnabled(true);
|
||||
contributionsListPresenter.refreshList(refresh.swipeRefreshLayout);
|
||||
}
|
||||
} else {
|
||||
if (refresh != null && refresh.swipeRefreshLayout != null) {
|
||||
refresh.swipeRefreshLayout.setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
quizChecker.cleanup();
|
||||
locationManager.unregisterLocationManager();
|
||||
// Remove ourself from hashmap to prevent memory leaks
|
||||
locationManager = null;
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Public method to show nearby from the reference of this.
|
||||
*/
|
||||
public void showNearby() {
|
||||
binding.fragmentMainNavTabLayout.setSelectedItemId(NavTab.NEARBY.code());
|
||||
}
|
||||
|
|
@ -522,9 +489,6 @@ public class MainActivity extends BaseActivity
|
|||
MORE
|
||||
}
|
||||
|
||||
/**
|
||||
* Load default language in onCreate from SharedPreferences
|
||||
*/
|
||||
private void loadLocale() {
|
||||
final SharedPreferences preferences = getSharedPreferences("Settings",
|
||||
Activity.MODE_PRIVATE);
|
||||
|
|
@ -536,4 +500,4 @@ public class MainActivity extends BaseActivity
|
|||
public OnNavigationItemSelectedListener getNavListener() {
|
||||
return navListener;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue