Replace remaining AsyncTask with RxAndroid (#2681)

This commit is contained in:
Vivek Maskara 2019-03-29 02:40:47 +05:30 committed by Adam Jones
parent a62aaadf90
commit 0bf63f50b3
28 changed files with 1096 additions and 1153 deletions

View file

@ -25,20 +25,18 @@ import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.auth.AuthenticatedActivity;
import fr.free.nrw.commons.mwapi.MediaResult;
import fr.free.nrw.commons.delete.DeleteHelper;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.utils.MediaDataExtractorUtil;
import fr.free.nrw.commons.utils.ViewUtil;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import timber.log.Timber;
public class ReviewActivity extends AuthenticatedActivity {
public ReviewPagerAdapter reviewPagerAdapter;
public ReviewController reviewController;
@BindView(R.id.reviewPagerIndicator)
public CirclePageIndicator pagerIndicator;
@BindView(R.id.toolbar)
@ -57,8 +55,16 @@ public class ReviewActivity extends AuthenticatedActivity {
ProgressBar progressBar;
@BindView(R.id.imageCaption)
TextView imageCaption;
public ReviewPagerAdapter reviewPagerAdapter;
public ReviewController reviewController;
@Inject
MediaWikiApi mwApi;
@Inject
ReviewHelper reviewHelper;
@Inject
DeleteHelper deleteHelper;
/**
* Consumers should be simply using this method to use this activity.
@ -70,8 +76,7 @@ public class ReviewActivity extends AuthenticatedActivity {
Intent reviewActivity = new Intent(context, ReviewActivity.class);
context.startActivity(reviewActivity);
}
@Inject
ReviewHelper reviewHelper;
private CompositeDisposable compositeDisposable = new CompositeDisposable();
@ -91,7 +96,7 @@ public class ReviewActivity extends AuthenticatedActivity {
ButterKnife.bind(this);
initDrawer();
reviewController = new ReviewController();
reviewController = new ReviewController(deleteHelper, this);
reviewPagerAdapter = new ReviewPagerAdapter(getSupportFragmentManager());
reviewPager.setAdapter(reviewPagerAdapter);
@ -134,15 +139,15 @@ public class ReviewActivity extends AuthenticatedActivity {
progressBar.setVisibility(View.GONE);
}));
reviewPager.setCurrentItem(0);
compositeDisposable.add(Observable.fromCallable(() -> {
MediaResult media = mwApi.fetchMediaByFilename("File:" + fileName);
return MediaDataExtractorUtil.extractCategories(media.getWikiSource());
})
Disposable disposable = mwApi.fetchMediaByFilename("File:" + fileName)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::updateCategories, this::categoryFetchError));
.subscribe(mediaResult -> {
ArrayList<String> categories = MediaDataExtractorUtil.extractCategories(mediaResult.getWikiSource());
updateCategories(categories);
}, this::categoryFetchError);
compositeDisposable.add(disposable);
}
private void categoryFetchError(Throwable throwable) {

View file

@ -15,10 +15,11 @@ import javax.inject.Singleton;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.viewpager.widget.ViewPager;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.delete.DeleteTask;
import fr.free.nrw.commons.delete.DeleteHelper;
import fr.free.nrw.commons.di.ApplicationlessInjection;
import fr.free.nrw.commons.media.model.MwQueryPage;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
@ -44,6 +45,17 @@ public class ReviewController {
@Inject
SessionManager sessionManager;
private final DeleteHelper deleteHelper;
private ViewPager viewPager;
private ReviewActivity reviewActivity;
ReviewController(DeleteHelper deleteHelper, Context context) {
this.deleteHelper = deleteHelper;
reviewActivity = (ReviewActivity) context;
viewPager = ((ReviewActivity) context).reviewPager;
}
public void onImageRefreshed(String fileName) {
this.fileName = fileName;
media = new Media("File:" + fileName);
@ -54,15 +66,24 @@ public class ReviewController {
ReviewController.categories = categories;
}
public void swipeToNext() {
int nextPos = viewPager.getCurrentItem() + 1;
if (nextPos <= 3) {
viewPager.setCurrentItem(nextPos);
} else {
reviewActivity.runRandomizer();
}
}
public void reportSpam(@NonNull Activity activity) {
DeleteTask.askReasonAndExecute(new Media("File:" + fileName),
deleteHelper.askReasonAndExecute(new Media("File:" + fileName),
activity,
activity.getString(R.string.review_spam_report_question),
activity.getString(R.string.review_spam_report_problem));
activity.getResources().getString(R.string.review_spam_report_question),
activity.getResources().getString(R.string.review_spam_report_problem));
}
public void reportPossibleCopyRightViolation(@NonNull Activity activity) {
DeleteTask.askReasonAndExecute(new Media("File:" + fileName),
deleteHelper.askReasonAndExecute(new Media("File:" + fileName),
activity,
activity.getResources().getString(R.string.review_c_violation_report_question),
activity.getResources().getString(R.string.review_c_violation_report_problem));

View file

@ -1,19 +1,26 @@
package fr.free.nrw.commons.review;
import java.util.List;
import java.util.Random;
import javax.annotation.Nullable;
import javax.inject.Inject;
import javax.inject.Singleton;
import androidx.core.util.Pair;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.media.RecentChangesImageUtils;
import fr.free.nrw.commons.media.model.MwQueryPage;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient;
import fr.free.nrw.commons.mwapi.model.RecentChange;
import io.reactivex.Single;
@Singleton
public class ReviewHelper {
private static final int MAX_RANDOM_TRIES = 5;
private static final String[] imageExtensions = new String[]{".jpg", ".jpeg", ".png"};
private final OkHttpJsonApiClient okHttpJsonApiClient;
private final MediaWikiApi mediaWikiApi;
@ -23,20 +30,63 @@ public class ReviewHelper {
this.mediaWikiApi = mediaWikiApi;
}
public Single<Media> getRandomMedia() {
/**
* Gets a random media file for review.
* - Picks the most recent changes in the last 30 day window
* - Picks a random file from those changes
* - Checks if the file is nominated for deletion
* - Retries upto 5 times for getting a file which is not nominated for deletion
* @return
*/
Single<Media> getRandomMedia() {
return okHttpJsonApiClient.getRecentFileChanges()
.map(RecentChangesImageUtils::findImageInRecentChanges)
.map(title -> {
boolean pageExists = mediaWikiApi.pageExists("Commons:Deletion_requests/" + title);
if (!pageExists) {
title = title.replace("File:", "");
return new Media(title);
.map(this::findImageInRecentChanges)
.flatMap(title -> mediaWikiApi.pageExists("Commons:Deletion_requests/" + title)
.map(pageExists -> new Pair<>(title, pageExists)))
.map((Pair<String, Boolean> pair) -> {
if (pair.second) {
return new Media(pair.first.replace("File:", ""));
}
throw new Exception("Page does not exist");
}).retry(MAX_RANDOM_TRIES);
}
public Single<MwQueryPage.Revision> getFirstRevisionOfFile(String fileName) {
Single<MwQueryPage.Revision> getFirstRevisionOfFile(String fileName) {
return okHttpJsonApiClient.getFirstRevisionOfFile(fileName);
}
@Nullable
public String findImageInRecentChanges(List<RecentChange> recentChanges) {
String imageTitle;
Random r = new Random();
int count = recentChanges.size();
// Build a range array
int[] randomIndexes = new int[count];
for (int i = 0; i < count; i++) {
randomIndexes[i] = i;
}
// Then shuffle it
for (int i = 0; i < count; i++) {
int swapIndex = r.nextInt(count);
int temp = randomIndexes[i];
randomIndexes[i] = randomIndexes[swapIndex];
randomIndexes[swapIndex] = temp;
}
for (int i = 0; i < count; i++) {
int randomIndex = randomIndexes[i];
RecentChange recentChange = recentChanges.get(randomIndex);
if (recentChange.getType().equals("log") && !recentChange.getOldRevisionId().equals("0")) {
// For log entries, we only want ones where old_revid is zero, indicating a new file
continue;
}
imageTitle = recentChange.getTitle();
for (String imageExtension : imageExtensions) {
if (imageTitle.toLowerCase().endsWith(imageExtension)) {
return imageTitle;
}
}
}
return null;
}
}