mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-27 21:03:54 +01:00
Fix crash(es) caused by failing to dispose Rx observables (#2669)
This commit is contained in:
parent
38d39e08ac
commit
8474c04c64
21 changed files with 121 additions and 86 deletions
|
|
@ -44,6 +44,8 @@ import fr.free.nrw.commons.modifications.ModifierSequenceDao;
|
||||||
import fr.free.nrw.commons.upload.FileUtils;
|
import fr.free.nrw.commons.upload.FileUtils;
|
||||||
import fr.free.nrw.commons.utils.ConfigUtils;
|
import fr.free.nrw.commons.utils.ConfigUtils;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.internal.functions.Functions;
|
||||||
|
import io.reactivex.plugins.RxJavaPlugins;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
|
@ -128,6 +130,9 @@ public class CommonsApplication extends Application {
|
||||||
|
|
||||||
createNotificationChannel(this);
|
createNotificationChannel(this);
|
||||||
|
|
||||||
|
// This handler will catch exceptions thrown from Observables after they are disposed,
|
||||||
|
// or from Observables that are (deliberately or not) missing an onError handler.
|
||||||
|
RxJavaPlugins.setErrorHandler(Functions.emptyConsumer());
|
||||||
|
|
||||||
if (setupLeakCanary() == RefWatcher.DISABLED) {
|
if (setupLeakCanary() == RefWatcher.DISABLED) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -142,6 +142,12 @@ public class AchievementsActivity extends NavigationBaseActivity {
|
||||||
initDrawer();
|
initDrawer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
compositeDisposable.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To invoke the AlertDialog on clicking info button
|
* To invoke the AlertDialog on clicking info button
|
||||||
*/
|
*/
|
||||||
|
|
@ -238,12 +244,12 @@ public class AchievementsActivity extends NavigationBaseActivity {
|
||||||
if (StringUtils.isNullOrWhiteSpace(userName)) {
|
if (StringUtils.isNullOrWhiteSpace(userName)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
okHttpJsonApiClient.getWikidataEdits(userName)
|
compositeDisposable.add(okHttpJsonApiClient.getWikidataEdits(userName)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(edits -> wikidataEditsText.setText(String.valueOf(edits)), e -> {
|
.subscribe(edits -> wikidataEditsText.setText(String.valueOf(edits)), e -> {
|
||||||
Timber.e("Error:" + e);
|
Timber.e("Error:" + e);
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showSnackBarWithRetry() {
|
private void showSnackBarWithRetry() {
|
||||||
|
|
|
||||||
|
|
@ -58,13 +58,12 @@ public abstract class AuthenticatedActivity extends NavigationBaseActivity {
|
||||||
* Makes API call to check if user is blocked from Commons. If the user is blocked, a snackbar
|
* Makes API call to check if user is blocked from Commons. If the user is blocked, a snackbar
|
||||||
* is created to notify the user
|
* is created to notify the user
|
||||||
*/
|
*/
|
||||||
protected void showBlockStatus()
|
protected void showBlockStatus() {
|
||||||
{
|
compositeDisposable.add(Observable.fromCallable(() -> mediaWikiApi.isUserBlockedFromCommons())
|
||||||
Observable.fromCallable(() -> mediaWikiApi.isUserBlockedFromCommons())
|
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.filter(result -> result)
|
.filter(result -> result)
|
||||||
.subscribe(result -> ViewUtil.showShortSnackbar(findViewById(android.R.id.content), R.string.block_notification)
|
.subscribe(result -> ViewUtil.showShortSnackbar(findViewById(android.R.id.content), R.string.block_notification)
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ import fr.free.nrw.commons.utils.ConfigUtils;
|
||||||
import fr.free.nrw.commons.utils.ViewUtil;
|
import fr.free.nrw.commons.utils.ViewUtil;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
|
@ -83,6 +84,7 @@ public class LoginActivity extends AccountAuthenticatorActivity {
|
||||||
ProgressDialog progressDialog;
|
ProgressDialog progressDialog;
|
||||||
private AppCompatDelegate delegate;
|
private AppCompatDelegate delegate;
|
||||||
private LoginTextWatcher textWatcher = new LoginTextWatcher();
|
private LoginTextWatcher textWatcher = new LoginTextWatcher();
|
||||||
|
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||||
|
|
||||||
private Boolean loginCurrentlyInProgress = false;
|
private Boolean loginCurrentlyInProgress = false;
|
||||||
private Boolean errorMessageShown = false;
|
private Boolean errorMessageShown = false;
|
||||||
|
|
@ -195,6 +197,7 @@ public class LoginActivity extends AccountAuthenticatorActivity {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
|
compositeDisposable.clear();
|
||||||
try {
|
try {
|
||||||
// To prevent leaked window when finish() is called, see http://stackoverflow.com/questions/32065854/activity-has-leaked-window-at-alertdialog-show-method
|
// To prevent leaked window when finish() is called, see http://stackoverflow.com/questions/32065854/activity-has-leaked-window-at-alertdialog-show-method
|
||||||
if (progressDialog != null && progressDialog.isShowing()) {
|
if (progressDialog != null && progressDialog.isShowing()) {
|
||||||
|
|
@ -219,10 +222,10 @@ public class LoginActivity extends AccountAuthenticatorActivity {
|
||||||
String twoFactorCode = twoFactorEdit.getText().toString();
|
String twoFactorCode = twoFactorEdit.getText().toString();
|
||||||
|
|
||||||
showLoggingProgressBar();
|
showLoggingProgressBar();
|
||||||
Observable.fromCallable(() -> login(username, password, twoFactorCode))
|
compositeDisposable.add(Observable.fromCallable(() -> login(username, password, twoFactorCode))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(result -> handleLogin(username, rawUsername, password, result));
|
.subscribe(result -> handleLogin(username, rawUsername, password, result)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String login(String username, String password, String twoFactorCode) {
|
private String login(String username, String password, String twoFactorCode) {
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import fr.free.nrw.commons.utils.NetworkUtils;
|
||||||
import fr.free.nrw.commons.utils.ViewUtil;
|
import fr.free.nrw.commons.utils.ViewUtil;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
|
@ -41,6 +42,7 @@ public class BookmarkPicturesFragment extends DaggerFragment {
|
||||||
private static final int TIMEOUT_SECONDS = 15;
|
private static final int TIMEOUT_SECONDS = 15;
|
||||||
|
|
||||||
private GridViewAdapter gridAdapter;
|
private GridViewAdapter gridAdapter;
|
||||||
|
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||||
|
|
||||||
@BindView(R.id.statusMessage) TextView statusTextView;
|
@BindView(R.id.statusMessage) TextView statusTextView;
|
||||||
@BindView(R.id.loadingImagesProgressBar) ProgressBar progressBar;
|
@BindView(R.id.loadingImagesProgressBar) ProgressBar progressBar;
|
||||||
|
|
@ -82,6 +84,12 @@ public class BookmarkPicturesFragment extends DaggerFragment {
|
||||||
controller.stop();
|
controller.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
compositeDisposable.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
|
|
@ -113,11 +121,11 @@ public class BookmarkPicturesFragment extends DaggerFragment {
|
||||||
progressBar.setVisibility(VISIBLE);
|
progressBar.setVisibility(VISIBLE);
|
||||||
statusTextView.setVisibility(GONE);
|
statusTextView.setVisibility(GONE);
|
||||||
|
|
||||||
Observable.fromCallable(() -> controller.loadBookmarkedPictures())
|
compositeDisposable.add(Observable.fromCallable(() -> controller.loadBookmarkedPictures())
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
||||||
.subscribe(this::handleSuccess, this::handleError);
|
.subscribe(this::handleSuccess, this::handleError));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import fr.free.nrw.commons.utils.NetworkUtils;
|
||||||
import fr.free.nrw.commons.utils.ViewUtil;
|
import fr.free.nrw.commons.utils.ViewUtil;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
|
@ -51,6 +52,7 @@ public class CategoryImagesListFragment extends DaggerFragment {
|
||||||
@BindView(R.id.loadingImagesProgressBar) ProgressBar progressBar;
|
@BindView(R.id.loadingImagesProgressBar) ProgressBar progressBar;
|
||||||
@BindView(R.id.categoryImagesList) GridView gridView;
|
@BindView(R.id.categoryImagesList) GridView gridView;
|
||||||
@BindView(R.id.parentLayout) RelativeLayout parentLayout;
|
@BindView(R.id.parentLayout) RelativeLayout parentLayout;
|
||||||
|
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||||
private boolean hasMoreImages = true;
|
private boolean hasMoreImages = true;
|
||||||
private boolean isLoading = true;
|
private boolean isLoading = true;
|
||||||
private String categoryName = null;
|
private String categoryName = null;
|
||||||
|
|
@ -74,6 +76,12 @@ public class CategoryImagesListFragment extends DaggerFragment {
|
||||||
initViews();
|
initViews();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
compositeDisposable.clear();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the UI elements for the fragment
|
* Initializes the UI elements for the fragment
|
||||||
* Setup the grid view to and scroll listener for it
|
* Setup the grid view to and scroll listener for it
|
||||||
|
|
@ -109,11 +117,11 @@ public class CategoryImagesListFragment extends DaggerFragment {
|
||||||
|
|
||||||
isLoading = true;
|
isLoading = true;
|
||||||
progressBar.setVisibility(VISIBLE);
|
progressBar.setVisibility(VISIBLE);
|
||||||
Observable.fromCallable(() -> controller.getCategoryImages(categoryName))
|
compositeDisposable.add(Observable.fromCallable(() -> controller.getCategoryImages(categoryName))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
||||||
.subscribe(this::handleSuccess, this::handleError);
|
.subscribe(this::handleSuccess, this::handleError));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -215,11 +223,11 @@ public class CategoryImagesListFragment extends DaggerFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
progressBar.setVisibility(VISIBLE);
|
progressBar.setVisibility(VISIBLE);
|
||||||
Observable.fromCallable(() -> controller.getCategoryImages(categoryName))
|
compositeDisposable.add(Observable.fromCallable(() -> controller.getCategoryImages(categoryName))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
||||||
.subscribe(this::handleSuccess, this::handleError);
|
.subscribe(this::handleSuccess, this::handleError));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -97,17 +97,17 @@ public class SubCategoryListFragment extends CommonsDaggerSupportFragment {
|
||||||
}
|
}
|
||||||
progressBar.setVisibility(View.VISIBLE);
|
progressBar.setVisibility(View.VISIBLE);
|
||||||
if (!isParentCategory){
|
if (!isParentCategory){
|
||||||
Observable.fromCallable(() -> mwApi.getSubCategoryList(categoryName))
|
compositeDisposable.add(Observable.fromCallable(() -> mwApi.getSubCategoryList(categoryName))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
||||||
.subscribe(this::handleSuccess, this::handleError);
|
.subscribe(this::handleSuccess, this::handleError));
|
||||||
}else {
|
}else {
|
||||||
Observable.fromCallable(() -> mwApi.getParentCategoryList(categoryName))
|
compositeDisposable.add(Observable.fromCallable(() -> mwApi.getParentCategoryList(categoryName))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
||||||
.subscribe(this::handleSuccess, this::handleError);
|
.subscribe(this::handleSuccess, this::handleError));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,6 @@ import fr.free.nrw.commons.utils.ViewUtil;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.disposables.CompositeDisposable;
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
import io.reactivex.disposables.Disposable;
|
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
|
@ -101,7 +100,6 @@ public class ContributionsFragment
|
||||||
@BindView(R.id.card_view_nearby) public NearbyNotificationCardView nearbyNotificationCardView;
|
@BindView(R.id.card_view_nearby) public NearbyNotificationCardView nearbyNotificationCardView;
|
||||||
@BindView(R.id.campaigns_view) CampaignView campaignView;
|
@BindView(R.id.campaigns_view) CampaignView campaignView;
|
||||||
|
|
||||||
private Disposable placesDisposable;
|
|
||||||
private LatLng curLatLng;
|
private LatLng curLatLng;
|
||||||
|
|
||||||
private boolean firstLocationUpdate = true;
|
private boolean firstLocationUpdate = true;
|
||||||
|
|
@ -592,7 +590,7 @@ public class ContributionsFragment
|
||||||
private void updateClosestNearbyCardViewInfo() {
|
private void updateClosestNearbyCardViewInfo() {
|
||||||
curLatLng = locationManager.getLastLocation();
|
curLatLng = locationManager.getLastLocation();
|
||||||
|
|
||||||
placesDisposable = Observable.fromCallable(() -> nearbyController
|
compositeDisposable.add(Observable.fromCallable(() -> nearbyController
|
||||||
.loadAttractionsFromLocation(curLatLng, curLatLng, true, false)) // thanks to boolean, it will only return closest result
|
.loadAttractionsFromLocation(curLatLng, curLatLng, true, false)) // thanks to boolean, it will only return closest result
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
|
@ -600,7 +598,7 @@ public class ContributionsFragment
|
||||||
throwable -> {
|
throwable -> {
|
||||||
Timber.d(throwable);
|
Timber.d(throwable);
|
||||||
updateNearbyNotification(null);
|
updateNearbyNotification(null);
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateNearbyNotification(@Nullable NearbyController.NearbyPlacesInfo nearbyPlacesInfo) {
|
private void updateNearbyNotification(@Nullable NearbyController.NearbyPlacesInfo nearbyPlacesInfo) {
|
||||||
|
|
@ -635,10 +633,6 @@ public class ContributionsFragment
|
||||||
isUploadServiceConnected = false;
|
isUploadServiceConnected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (placesDisposable != null) {
|
|
||||||
placesDisposable.dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -307,11 +307,11 @@ public class MainActivity extends AuthenticatedActivity implements FragmentManag
|
||||||
|
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
private void setNotificationCount() {
|
private void setNotificationCount() {
|
||||||
Observable.fromCallable(() -> notificationController.getNotifications(false))
|
compositeDisposable.add(Observable.fromCallable(() -> notificationController.getNotifications(false))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(this::initNotificationViews,
|
.subscribe(this::initNotificationViews,
|
||||||
throwable -> Timber.e(throwable, "Error occurred while loading notifications"));
|
throwable -> Timber.e(throwable, "Error occurred while loading notifications")));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initNotificationViews(List<Notification> notificationList) {
|
private void initNotificationViews(List<Notification> notificationList) {
|
||||||
|
|
|
||||||
|
|
@ -9,18 +9,27 @@ import androidx.fragment.app.Fragment;
|
||||||
import dagger.android.AndroidInjector;
|
import dagger.android.AndroidInjector;
|
||||||
import dagger.android.DispatchingAndroidInjector;
|
import dagger.android.DispatchingAndroidInjector;
|
||||||
import dagger.android.support.HasSupportFragmentInjector;
|
import dagger.android.support.HasSupportFragmentInjector;
|
||||||
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
|
|
||||||
public abstract class CommonsDaggerSupportFragment extends Fragment implements HasSupportFragmentInjector {
|
public abstract class CommonsDaggerSupportFragment extends Fragment implements HasSupportFragmentInjector {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
DispatchingAndroidInjector<Fragment> childFragmentInjector;
|
DispatchingAndroidInjector<Fragment> childFragmentInjector;
|
||||||
|
|
||||||
|
protected CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttach(Context context) {
|
public void onAttach(Context context) {
|
||||||
inject();
|
inject();
|
||||||
super.onAttach(context);
|
super.onAttach(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
compositeDisposable.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AndroidInjector<Fragment> supportFragmentInjector() {
|
public AndroidInjector<Fragment> supportFragmentInjector() {
|
||||||
return childFragmentInjector;
|
return childFragmentInjector;
|
||||||
|
|
|
||||||
|
|
@ -98,7 +98,7 @@ public class SearchActivity extends NavigationBaseActivity implements MediaDetai
|
||||||
|
|
||||||
viewPagerAdapter.setTabData(fragmentList, titleList);
|
viewPagerAdapter.setTabData(fragmentList, titleList);
|
||||||
viewPagerAdapter.notifyDataSetChanged();
|
viewPagerAdapter.notifyDataSetChanged();
|
||||||
RxSearchView.queryTextChanges(searchView)
|
compositeDisposable.add(RxSearchView.queryTextChanges(searchView)
|
||||||
.takeUntil(RxView.detaches(searchView))
|
.takeUntil(RxView.detaches(searchView))
|
||||||
.debounce(500, TimeUnit.MILLISECONDS)
|
.debounce(500, TimeUnit.MILLISECONDS)
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
|
@ -120,7 +120,7 @@ public class SearchActivity extends NavigationBaseActivity implements MediaDetai
|
||||||
searchHistoryContainer.setVisibility(View.VISIBLE);
|
searchHistoryContainer.setVisibility(View.VISIBLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package fr.free.nrw.commons.explore.categories;
|
||||||
|
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
|
||||||
import androidx.recyclerview.widget.GridLayoutManager;
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
@ -136,12 +135,12 @@ public class SearchCategoryFragment extends CommonsDaggerSupportFragment {
|
||||||
progressBar.setVisibility(GONE);
|
progressBar.setVisibility(GONE);
|
||||||
queryList.clear();
|
queryList.clear();
|
||||||
categoriesAdapter.clear();
|
categoriesAdapter.clear();
|
||||||
Observable.fromCallable(() -> mwApi.searchCategory(query,queryList.size()))
|
compositeDisposable.add(Observable.fromCallable(() -> mwApi.searchCategory(query,queryList.size()))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
||||||
.doOnSubscribe(disposable -> saveQuery(query))
|
.doOnSubscribe(disposable -> saveQuery(query))
|
||||||
.subscribe(this::handleSuccess, this::handleError);
|
.subscribe(this::handleSuccess, this::handleError));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -152,11 +151,11 @@ public class SearchCategoryFragment extends CommonsDaggerSupportFragment {
|
||||||
this.query = query;
|
this.query = query;
|
||||||
bottomProgressBar.setVisibility(View.VISIBLE);
|
bottomProgressBar.setVisibility(View.VISIBLE);
|
||||||
progressBar.setVisibility(GONE);
|
progressBar.setVisibility(GONE);
|
||||||
Observable.fromCallable(() -> mwApi.searchCategory(query,queryList.size()))
|
compositeDisposable.add(Observable.fromCallable(() -> mwApi.searchCategory(query,queryList.size()))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
||||||
.subscribe(this::handlePaginationSuccess, this::handleError);
|
.subscribe(this::handlePaginationSuccess, this::handleError));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ package fr.free.nrw.commons.explore.images;
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
|
||||||
import androidx.recyclerview.widget.GridLayoutManager;
|
import androidx.recyclerview.widget.GridLayoutManager;
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
import androidx.recyclerview.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
@ -142,12 +141,12 @@ public class SearchImageFragment extends CommonsDaggerSupportFragment {
|
||||||
bottomProgressBar.setVisibility(GONE);
|
bottomProgressBar.setVisibility(GONE);
|
||||||
queryList.clear();
|
queryList.clear();
|
||||||
imagesAdapter.clear();
|
imagesAdapter.clear();
|
||||||
okHttpJsonApiClient.searchImages(query, queryList.size())
|
compositeDisposable.add(okHttpJsonApiClient.searchImages(query, queryList.size())
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
||||||
.doOnSubscribe(disposable -> saveQuery(query))
|
.doOnSubscribe(disposable -> saveQuery(query))
|
||||||
.subscribe(this::handleSuccess, this::handleError);
|
.subscribe(this::handleSuccess, this::handleError));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -159,11 +158,11 @@ public class SearchImageFragment extends CommonsDaggerSupportFragment {
|
||||||
this.query = query;
|
this.query = query;
|
||||||
bottomProgressBar.setVisibility(View.VISIBLE);
|
bottomProgressBar.setVisibility(View.VISIBLE);
|
||||||
progressBar.setVisibility(GONE);
|
progressBar.setVisibility(GONE);
|
||||||
okHttpJsonApiClient.searchImages(query, queryList.size())
|
compositeDisposable.add(okHttpJsonApiClient.searchImages(query, queryList.size())
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
.timeout(TIMEOUT_SECONDS, TimeUnit.SECONDS)
|
||||||
.subscribe(this::handlePaginationSuccess, this::handleError);
|
.subscribe(this::handlePaginationSuccess, this::handleError));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -420,7 +420,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
||||||
private void onDeleteClicked(Spinner spinner) {
|
private void onDeleteClicked(Spinner spinner) {
|
||||||
String reason = spinner.getSelectedItem().toString();
|
String reason = spinner.getSelectedItem().toString();
|
||||||
Single<String> deletionReason = reasonBuilder.getReason(media, reason);
|
Single<String> deletionReason = reasonBuilder.getReason(media, reason);
|
||||||
deletionReason
|
compositeDisposable.add(deletionReason
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(s -> {
|
.subscribe(s -> {
|
||||||
|
|
@ -428,7 +428,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
||||||
deleteTask.execute();
|
deleteTask.execute();
|
||||||
isDeleted = true;
|
isDeleted = true;
|
||||||
enableDeleteButton(false);
|
enableDeleteButton(false);
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.seeMore)
|
@OnClick(R.id.seeMore)
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@ import fr.free.nrw.commons.utils.ViewUtil;
|
||||||
import fr.free.nrw.commons.wikidata.WikidataEditListener;
|
import fr.free.nrw.commons.wikidata.WikidataEditListener;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.disposables.Disposable;
|
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
|
@ -85,8 +84,6 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
|
||||||
private BottomSheetBehavior bottomSheetBehaviorForDetails; // Behavior for details bottom sheet
|
private BottomSheetBehavior bottomSheetBehaviorForDetails; // Behavior for details bottom sheet
|
||||||
|
|
||||||
private LatLng curLatLng;
|
private LatLng curLatLng;
|
||||||
private Disposable placesDisposable;
|
|
||||||
private Disposable placesDisposableCustom;
|
|
||||||
private boolean lockNearbyView; //Determines if the nearby places needs to be refreshed
|
private boolean lockNearbyView; //Determines if the nearby places needs to be refreshed
|
||||||
public View view;
|
public View view;
|
||||||
private Snackbar snackbar;
|
private Snackbar snackbar;
|
||||||
|
|
@ -298,7 +295,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
|
||||||
bundle.clear();
|
bundle.clear();
|
||||||
bundle.putString("CurLatLng", gsonCurLatLng);
|
bundle.putString("CurLatLng", gsonCurLatLng);
|
||||||
|
|
||||||
placesDisposable = Observable.fromCallable(() -> nearbyController
|
compositeDisposable.add(Observable.fromCallable(() -> nearbyController
|
||||||
.loadAttractionsFromLocation(curLatLng, curLatLng, false, true))
|
.loadAttractionsFromLocation(curLatLng, curLatLng, false, true))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
|
@ -307,7 +304,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
|
||||||
Timber.d(throwable);
|
Timber.d(throwable);
|
||||||
showErrorMessage(getString(R.string.error_fetching_nearby_places));
|
showErrorMessage(getString(R.string.error_fetching_nearby_places));
|
||||||
progressBar.setVisibility(View.GONE);
|
progressBar.setVisibility(View.GONE);
|
||||||
});
|
}));
|
||||||
|
|
||||||
} else if (locationChangeType
|
} else if (locationChangeType
|
||||||
.equals(LOCATION_SLIGHTLY_CHANGED) && nearbyMapFragment != null) {
|
.equals(LOCATION_SLIGHTLY_CHANGED) && nearbyMapFragment != null) {
|
||||||
|
|
@ -335,7 +332,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
|
||||||
|
|
||||||
populateForCurrentLocation = refreshForCurrentLocation;
|
populateForCurrentLocation = refreshForCurrentLocation;
|
||||||
this.customLatLng = customLatLng;
|
this.customLatLng = customLatLng;
|
||||||
placesDisposableCustom = Observable.fromCallable(() -> nearbyController
|
compositeDisposable.add(Observable.fromCallable(() -> nearbyController
|
||||||
.loadAttractionsFromLocation(curLatLng, customLatLng, false, populateForCurrentLocation))
|
.loadAttractionsFromLocation(curLatLng, customLatLng, false, populateForCurrentLocation))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
|
@ -343,7 +340,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
|
||||||
throwable -> {
|
throwable -> {
|
||||||
Timber.d(throwable);
|
Timber.d(throwable);
|
||||||
showErrorMessage(getString(R.string.error_fetching_nearby_places));
|
showErrorMessage(getString(R.string.error_fetching_nearby_places));
|
||||||
});
|
}));
|
||||||
|
|
||||||
if (nearbyMapFragment != null) {
|
if (nearbyMapFragment != null) {
|
||||||
nearbyMapFragment.searchThisAreaButton.setVisibility(View.GONE);
|
nearbyMapFragment.searchThisAreaButton.setVisibility(View.GONE);
|
||||||
|
|
@ -467,7 +464,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
|
||||||
|| curLatLng.getLongitude() < nearbyMapFragment.boundaryCoordinates[2].getLongitude()
|
|| curLatLng.getLongitude() < nearbyMapFragment.boundaryCoordinates[2].getLongitude()
|
||||||
|| curLatLng.getLongitude() > nearbyMapFragment.boundaryCoordinates[3].getLongitude())) {
|
|| curLatLng.getLongitude() > nearbyMapFragment.boundaryCoordinates[3].getLongitude())) {
|
||||||
// populate places
|
// populate places
|
||||||
placesDisposable = Observable.fromCallable(() -> nearbyController
|
compositeDisposable.add(Observable.fromCallable(() -> nearbyController
|
||||||
.loadAttractionsFromLocation(curLatLng, curLatLng, false, updateViaButton))
|
.loadAttractionsFromLocation(curLatLng, curLatLng, false, updateViaButton))
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
|
@ -476,7 +473,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
|
||||||
Timber.d(throwable);
|
Timber.d(throwable);
|
||||||
showErrorMessage(getString(R.string.error_fetching_nearby_places));
|
showErrorMessage(getString(R.string.error_fetching_nearby_places));
|
||||||
progressBar.setVisibility(View.GONE);
|
progressBar.setVisibility(View.GONE);
|
||||||
});
|
}));
|
||||||
nearbyMapFragment.setBundleForUpdates(bundle);
|
nearbyMapFragment.setBundleForUpdates(bundle);
|
||||||
nearbyMapFragment.updateMapSignificantlyForCurrentLocation();
|
nearbyMapFragment.updateMapSignificantlyForCurrentLocation();
|
||||||
updateListFragment();
|
updateListFragment();
|
||||||
|
|
@ -782,13 +779,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
|
||||||
@Override
|
@Override
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
if (placesDisposable != null) {
|
|
||||||
placesDisposable.dispose();
|
|
||||||
}
|
|
||||||
wikidataEditListener.setAuthenticationStateListener(null);
|
wikidataEditListener.setAuthenticationStateListener(null);
|
||||||
if (placesDisposableCustom != null) {
|
|
||||||
placesDisposableCustom.dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,14 @@ import javax.inject.Named;
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerAppCompatActivity;
|
import fr.free.nrw.commons.di.CommonsDaggerAppCompatActivity;
|
||||||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
|
|
||||||
public abstract class BaseActivity extends CommonsDaggerAppCompatActivity {
|
public abstract class BaseActivity extends CommonsDaggerAppCompatActivity {
|
||||||
@Inject
|
@Inject
|
||||||
@Named("default_preferences")
|
@Named("default_preferences")
|
||||||
public JsonKvStore defaultKvStore;
|
public JsonKvStore defaultKvStore;
|
||||||
|
|
||||||
|
protected CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||||
protected boolean wasPreviouslyDarkTheme;
|
protected boolean wasPreviouslyDarkTheme;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -33,4 +34,10 @@ public abstract class BaseActivity extends CommonsDaggerAppCompatActivity {
|
||||||
|
|
||||||
super.onResume();
|
super.onResume();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy() {
|
||||||
|
super.onDestroy();
|
||||||
|
compositeDisposable.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import androidx.exifinterface.media.ExifInterface;
|
||||||
import fr.free.nrw.commons.caching.CacheController;
|
import fr.free.nrw.commons.caching.CacheController;
|
||||||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||||
import fr.free.nrw.commons.mwapi.CategoryApi;
|
import fr.free.nrw.commons.mwapi.CategoryApi;
|
||||||
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
|
@ -42,11 +43,16 @@ public class FileProcessor implements SimilarImageDialogFragment.onResponse {
|
||||||
private ExifInterface exifInterface;
|
private ExifInterface exifInterface;
|
||||||
private boolean haveCheckedForOtherImages = false;
|
private boolean haveCheckedForOtherImages = false;
|
||||||
private GPSExtractor tempImageObj;
|
private GPSExtractor tempImageObj;
|
||||||
|
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
FileProcessor() {
|
FileProcessor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void cleanup() {
|
||||||
|
compositeDisposable.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void initFileDetails(@NonNull String filePath, ContentResolver contentResolver) {
|
void initFileDetails(@NonNull String filePath, ContentResolver contentResolver) {
|
||||||
this.filePath = filePath;
|
this.filePath = filePath;
|
||||||
this.contentResolver = contentResolver;
|
this.contentResolver = contentResolver;
|
||||||
|
|
@ -138,7 +144,7 @@ public class FileProcessor implements SimilarImageDialogFragment.onResponse {
|
||||||
|
|
||||||
// If no categories found in cache, call MediaWiki API to match image coords with nearby Commons categories
|
// If no categories found in cache, call MediaWiki API to match image coords with nearby Commons categories
|
||||||
if (catListEmpty) {
|
if (catListEmpty) {
|
||||||
apiCall.request(decimalCoords)
|
compositeDisposable.add(apiCall.request(decimalCoords)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(Schedulers.io())
|
.observeOn(Schedulers.io())
|
||||||
.subscribe(
|
.subscribe(
|
||||||
|
|
@ -147,7 +153,7 @@ public class FileProcessor implements SimilarImageDialogFragment.onResponse {
|
||||||
Timber.e(throwable);
|
Timber.e(throwable);
|
||||||
gpsCategoryModel.clear();
|
gpsCategoryModel.clear();
|
||||||
}
|
}
|
||||||
);
|
));
|
||||||
Timber.d("displayCatList size 0, calling MWAPI %s", displayCatList);
|
Timber.d("displayCatList size 0, calling MWAPI %s", displayCatList);
|
||||||
} else {
|
} else {
|
||||||
Timber.d("Cache found, setting categoryList in model to %s", displayCatList);
|
Timber.d("Cache found, setting categoryList in model to %s", displayCatList);
|
||||||
|
|
|
||||||
|
|
@ -33,16 +33,19 @@ public class ImageProcessingService {
|
||||||
private final MediaWikiApi mwApi;
|
private final MediaWikiApi mwApi;
|
||||||
private final ReadFBMD readFBMD;
|
private final ReadFBMD readFBMD;
|
||||||
private final EXIFReader EXIFReader;
|
private final EXIFReader EXIFReader;
|
||||||
|
private final Context context;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ImageProcessingService(FileUtilsWrapper fileUtilsWrapper,
|
public ImageProcessingService(FileUtilsWrapper fileUtilsWrapper,
|
||||||
ImageUtilsWrapper imageUtilsWrapper,
|
ImageUtilsWrapper imageUtilsWrapper,
|
||||||
MediaWikiApi mwApi, ReadFBMD readFBMD, EXIFReader EXIFReader) {
|
MediaWikiApi mwApi, ReadFBMD readFBMD, EXIFReader EXIFReader,
|
||||||
|
Context context) {
|
||||||
this.fileUtilsWrapper = fileUtilsWrapper;
|
this.fileUtilsWrapper = fileUtilsWrapper;
|
||||||
this.imageUtilsWrapper = imageUtilsWrapper;
|
this.imageUtilsWrapper = imageUtilsWrapper;
|
||||||
this.mwApi = mwApi;
|
this.mwApi = mwApi;
|
||||||
this.readFBMD = readFBMD;
|
this.readFBMD = readFBMD;
|
||||||
this.EXIFReader = EXIFReader;
|
this.EXIFReader = EXIFReader;
|
||||||
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -61,13 +64,13 @@ public class ImageProcessingService {
|
||||||
Timber.d("Checking the validity of image");
|
Timber.d("Checking the validity of image");
|
||||||
String filePath = uploadItem.getMediaUri().getPath();
|
String filePath = uploadItem.getMediaUri().getPath();
|
||||||
Uri contentUri=uploadItem.getContentUri();
|
Uri contentUri=uploadItem.getContentUri();
|
||||||
Context context=uploadItem.getContext();
|
|
||||||
Single<Integer> duplicateImage = checkDuplicateImage(filePath);
|
Single<Integer> duplicateImage = checkDuplicateImage(filePath);
|
||||||
Single<Integer> wrongGeoLocation = checkImageGeoLocation(uploadItem.getPlace(), filePath);
|
Single<Integer> wrongGeoLocation = checkImageGeoLocation(uploadItem.getPlace(), filePath);
|
||||||
Single<Integer> darkImage = checkDarkImage(filePath);
|
Single<Integer> darkImage = checkDarkImage(filePath);
|
||||||
Single<Integer> itemTitle = checkTitle ? validateItemTitle(uploadItem) : Single.just(ImageUtils.IMAGE_OK);
|
Single<Integer> itemTitle = checkTitle ? validateItemTitle(uploadItem) : Single.just(ImageUtils.IMAGE_OK);
|
||||||
Single<Integer> checkFBMD = checkFBMD(context,contentUri);
|
Single<Integer> checkFBMD = checkFBMD(context,contentUri);
|
||||||
Single<Integer> checkEXIF = checkEXIF(filePath);
|
Single<Integer> checkEXIF = checkEXIF(filePath);
|
||||||
|
|
||||||
Single<Integer> zipResult = Single.zip(duplicateImage, wrongGeoLocation, darkImage, itemTitle,
|
Single<Integer> zipResult = Single.zip(duplicateImage, wrongGeoLocation, darkImage, itemTitle,
|
||||||
(duplicate, wrongGeo, dark, title) -> {
|
(duplicate, wrongGeo, dark, title) -> {
|
||||||
Timber.d("Result for duplicate: %d, geo: %d, dark: %d, title: %d", duplicate, wrongGeo, dark, title);
|
Timber.d("Result for duplicate: %d, geo: %d, dark: %d, title: %d", duplicate, wrongGeo, dark, title);
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import android.annotation.SuppressLint;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import com.google.android.material.textfield.TextInputLayout;
|
import com.google.android.material.textfield.TextInputLayout;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
|
@ -67,7 +66,6 @@ import fr.free.nrw.commons.utils.PermissionUtils;
|
||||||
import fr.free.nrw.commons.utils.ViewUtil;
|
import fr.free.nrw.commons.utils.ViewUtil;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.disposables.CompositeDisposable;
|
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
|
@ -134,7 +132,6 @@ public class UploadActivity extends BaseActivity implements UploadView, SimilarI
|
||||||
|
|
||||||
private DescriptionsAdapter descriptionsAdapter;
|
private DescriptionsAdapter descriptionsAdapter;
|
||||||
private RVRendererAdapter<CategoryItem> categoriesAdapter;
|
private RVRendererAdapter<CategoryItem> categoriesAdapter;
|
||||||
private CompositeDisposable compositeDisposable;
|
|
||||||
private ProgressDialog progressDialog;
|
private ProgressDialog progressDialog;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -145,7 +142,6 @@ public class UploadActivity extends BaseActivity implements UploadView, SimilarI
|
||||||
|
|
||||||
setContentView(R.layout.activity_upload);
|
setContentView(R.layout.activity_upload);
|
||||||
ButterKnife.bind(this);
|
ButterKnife.bind(this);
|
||||||
compositeDisposable = new CompositeDisposable();
|
|
||||||
|
|
||||||
configureLayout();
|
configureLayout();
|
||||||
configureTopCard();
|
configureTopCard();
|
||||||
|
|
@ -211,8 +207,6 @@ public class UploadActivity extends BaseActivity implements UploadView, SimilarI
|
||||||
@Override
|
@Override
|
||||||
protected void onPause() {
|
protected void onPause() {
|
||||||
presenter.removeView();
|
presenter.removeView();
|
||||||
compositeDisposable.dispose();
|
|
||||||
compositeDisposable = new CompositeDisposable();
|
|
||||||
super.onPause();
|
super.onPause();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -571,7 +565,7 @@ public class UploadActivity extends BaseActivity implements UploadView, SimilarI
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
private void updateCategoryList(String filter) {
|
private void updateCategoryList(String filter) {
|
||||||
List<String> imageTitleList = presenter.getImageTitleList();
|
List<String> imageTitleList = presenter.getImageTitleList();
|
||||||
Observable.fromIterable(categoriesModel.getSelectedCategories())
|
compositeDisposable.add(Observable.fromIterable(categoriesModel.getSelectedCategories())
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.doOnSubscribe(disposable -> {
|
.doOnSubscribe(disposable -> {
|
||||||
|
|
@ -602,7 +596,7 @@ public class UploadActivity extends BaseActivity implements UploadView, SimilarI
|
||||||
categoriesSearchContainer.setError("No categories found");
|
categoriesSearchContainer.setError("No categories found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void receiveSharedItems() {
|
private void receiveSharedItems() {
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ import fr.free.nrw.commons.utils.ImageUtils;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.Single;
|
import io.reactivex.Single;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
import io.reactivex.disposables.Disposable;
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
import io.reactivex.functions.Consumer;
|
import io.reactivex.functions.Consumer;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import io.reactivex.subjects.BehaviorSubject;
|
import io.reactivex.subjects.BehaviorSubject;
|
||||||
|
|
@ -45,6 +45,7 @@ public class UploadModel {
|
||||||
};
|
};
|
||||||
private final JsonKvStore store;
|
private final JsonKvStore store;
|
||||||
private final List<String> licenses;
|
private final List<String> licenses;
|
||||||
|
private final Context context;
|
||||||
private String license;
|
private String license;
|
||||||
private final Map<String, String> licensesByName;
|
private final Map<String, String> licensesByName;
|
||||||
private List<UploadItem> items = new ArrayList<>();
|
private List<UploadItem> items = new ArrayList<>();
|
||||||
|
|
@ -52,8 +53,7 @@ public class UploadModel {
|
||||||
private boolean bottomCardState = true;
|
private boolean bottomCardState = true;
|
||||||
private boolean rightCardState = true;
|
private boolean rightCardState = true;
|
||||||
private int currentStepIndex = 0;
|
private int currentStepIndex = 0;
|
||||||
public static Context context;
|
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||||
private Disposable badImageSubscription;
|
|
||||||
|
|
||||||
private SessionManager sessionManager;
|
private SessionManager sessionManager;
|
||||||
private FileProcessor fileProcessor;
|
private FileProcessor fileProcessor;
|
||||||
|
|
@ -77,6 +77,11 @@ public class UploadModel {
|
||||||
this.imageProcessingService = imageProcessingService;
|
this.imageProcessingService = imageProcessingService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cleanup() {
|
||||||
|
compositeDisposable.clear();
|
||||||
|
fileProcessor.cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
Observable<UploadItem> preProcessImages(List<UploadableFile> uploadableFiles,
|
Observable<UploadItem> preProcessImages(List<UploadableFile> uploadableFiles,
|
||||||
Place place,
|
Place place,
|
||||||
|
|
@ -219,8 +224,7 @@ public class UploadModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void previous() {
|
public void previous() {
|
||||||
if (badImageSubscription != null)
|
cleanup();
|
||||||
badImageSubscription.dispose();
|
|
||||||
markCurrentUploadVisited();
|
markCurrentUploadVisited();
|
||||||
if (currentStepIndex > 0) {
|
if (currentStepIndex > 0) {
|
||||||
currentStepIndex--;
|
currentStepIndex--;
|
||||||
|
|
@ -305,16 +309,16 @@ public class UploadModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
void deletePicture() {
|
void deletePicture() {
|
||||||
badImageSubscription.dispose();
|
cleanup();
|
||||||
updateItemState();
|
updateItemState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void subscribeBadPicture(Consumer<Integer> consumer, boolean checkTitle) {
|
void subscribeBadPicture(Consumer<Integer> consumer, boolean checkTitle) {
|
||||||
if (isShowingItem()) {
|
if (isShowingItem()) {
|
||||||
badImageSubscription = getImageQuality(getCurrentItem(), checkTitle)
|
compositeDisposable.add(getImageQuality(getCurrentItem(), checkTitle)
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(consumer, Timber::e);
|
.subscribe(consumer, Timber::e));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -432,10 +436,6 @@ public class UploadModel {
|
||||||
public Uri getContentUri() {
|
public Uri getContentUri() {
|
||||||
return originalContentUri;
|
return originalContentUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Context getContext(){
|
|
||||||
return UploadModel.context;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -21,6 +21,7 @@ import fr.free.nrw.commons.settings.Prefs;
|
||||||
import fr.free.nrw.commons.utils.StringUtils;
|
import fr.free.nrw.commons.utils.StringUtils;
|
||||||
import io.reactivex.Observable;
|
import io.reactivex.Observable;
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||||
|
import io.reactivex.disposables.CompositeDisposable;
|
||||||
import io.reactivex.schedulers.Schedulers;
|
import io.reactivex.schedulers.Schedulers;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
|
@ -52,6 +53,7 @@ public class UploadPresenter {
|
||||||
private final UploadController uploadController;
|
private final UploadController uploadController;
|
||||||
private final Context context;
|
private final Context context;
|
||||||
private final JsonKvStore directKvStore;
|
private final JsonKvStore directKvStore;
|
||||||
|
private CompositeDisposable compositeDisposable = new CompositeDisposable();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
UploadPresenter(UploadModel uploadModel,
|
UploadPresenter(UploadModel uploadModel,
|
||||||
|
|
@ -77,12 +79,12 @@ public class UploadPresenter {
|
||||||
Observable<UploadItem> uploadItemObservable = uploadModel
|
Observable<UploadItem> uploadItemObservable = uploadModel
|
||||||
.preProcessImages(media, place, source, similarImageInterface);
|
.preProcessImages(media, place, source, similarImageInterface);
|
||||||
|
|
||||||
uploadItemObservable
|
compositeDisposable.add(uploadItemObservable
|
||||||
.toList()
|
.toList()
|
||||||
.subscribeOn(Schedulers.io())
|
.subscribeOn(Schedulers.io())
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
.subscribe(uploadItems -> onImagesProcessed(uploadItems, place),
|
.subscribe(uploadItems -> onImagesProcessed(uploadItems, place),
|
||||||
throwable -> Timber.e(throwable, "Error occurred in processing images"));
|
throwable -> Timber.e(throwable, "Error occurred in processing images")));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onImagesProcessed(List<UploadItem> uploadItems, Place place) {
|
private void onImagesProcessed(List<UploadItem> uploadItems, Place place) {
|
||||||
|
|
@ -211,9 +213,9 @@ public class UploadPresenter {
|
||||||
@SuppressLint("CheckResult")
|
@SuppressLint("CheckResult")
|
||||||
void handleSubmit(CategoriesModel categoriesModel) {
|
void handleSubmit(CategoriesModel categoriesModel) {
|
||||||
if (view.checkIfLoggedIn())
|
if (view.checkIfLoggedIn())
|
||||||
uploadModel.buildContributions(categoriesModel.getCategoryStringList())
|
compositeDisposable.add(uploadModel.buildContributions(categoriesModel.getCategoryStringList())
|
||||||
.observeOn(Schedulers.io())
|
.observeOn(Schedulers.io())
|
||||||
.subscribe(uploadController::startUpload);
|
.subscribe(uploadController::startUpload));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -286,6 +288,8 @@ public class UploadPresenter {
|
||||||
}
|
}
|
||||||
|
|
||||||
void cleanup() {
|
void cleanup() {
|
||||||
|
compositeDisposable.clear();
|
||||||
|
uploadModel.cleanup();
|
||||||
uploadController.cleanup();
|
uploadController.cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue