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

@ -2,11 +2,9 @@ package fr.free.nrw.commons.media;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.DataSetObserver;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.Html;
@ -25,37 +23,34 @@ import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
import javax.inject.Inject;
import javax.inject.Provider;
import androidx.annotation.Nullable;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import fr.free.nrw.commons.License;
import fr.free.nrw.commons.LicenseList;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.MediaDataExtractor;
import fr.free.nrw.commons.MediaWikiImageView;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.Utils;
import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.category.CategoryDetailsActivity;
import fr.free.nrw.commons.contributions.ContributionsFragment;
import fr.free.nrw.commons.delete.DeleteTask;
import fr.free.nrw.commons.delete.DeleteHelper;
import fr.free.nrw.commons.delete.ReasonBuilder;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.ui.widget.CompatTextView;
import fr.free.nrw.commons.ui.widget.HtmlTextView;
import fr.free.nrw.commons.utils.DateUtils;
import fr.free.nrw.commons.utils.StringUtils;
import fr.free.nrw.commons.utils.ViewUtil;
import fr.free.nrw.commons.utils.ViewUtilWrapper;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import timber.log.Timber;
@ -88,13 +83,13 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
}
@Inject
Provider<MediaDataExtractor> mediaDataExtractorProvider;
@Inject
MediaWikiApi mwApi;
@Inject
SessionManager sessionManager;
MediaDataExtractor mediaDataExtractor;
@Inject
ReasonBuilder reasonBuilder;
@Inject
DeleteHelper deleteHelper;
@Inject
ViewUtilWrapper viewUtil;
private int initialListTop = 0;
@ -105,7 +100,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
@BindView(R.id.mediaDetailTitle)
TextView title;
@BindView(R.id.mediaDetailDesc)
TextView desc;
HtmlTextView desc;
@BindView(R.id.mediaDetailAuthor)
TextView author;
@BindView(R.id.mediaDetailLicense)
@ -135,8 +130,6 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
private ViewTreeObserver.OnGlobalLayoutListener layoutListener; // for layout stuff, only used once!
private ViewTreeObserver.OnScrollChangedListener scrollListener;
private DataSetObserver dataObserver;
private AsyncTask<Void, Void, Boolean> detailFetchTask;
private LicenseList licenseList;
//Had to make this class variable, to implement various onClicks, which access the media, also I fell why make separate variables when one can serve the purpose
private Media media;
@ -198,8 +191,6 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
authorLayout.setVisibility(GONE);
}
licenseList = new LicenseList(getActivity());
// Progressively darken the image in the background when we scroll detail pane up
scrollListener = this::updateTheDarkness;
view.getViewTreeObserver().addOnScrollChangedListener(scrollListener);
@ -269,62 +260,19 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
private void displayMediaDetails() {
//Always load image from Internet to allow viewing the desc, license, and cats
image.setMedia(media);
// FIXME: For transparent images
// FIXME: keep the spinner going while we load data
// FIXME: cache this data
// Load image metadata: desc, license, categories
detailFetchTask = new AsyncTask<Void, Void, Boolean>() {
private MediaDataExtractor extractor;
@Override
protected void onPreExecute() {
extractor = mediaDataExtractorProvider.get();
}
@Override
protected Boolean doInBackground(Void... voids) {
// Local files have no filename yet
if (media.getFilename() == null) {
return Boolean.FALSE;
}
try {
extractor.fetch(media.getFilename(), licenseList);
return Boolean.TRUE;
} catch (IOException e) {
Timber.d(e);
}
return Boolean.FALSE;
}
@Override
protected void onPostExecute(Boolean success) {
detailFetchTask = null;
if (!isAdded()) {
return;
}
if (success) {
extractor.fill(media);
setTextFields(media);
} else {
Timber.d("Failed to load photo details.");
}
}
};
detailFetchTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
title.setText(media.getDisplayTitle());
desc.setText(""); // fill in from network...
license.setText(""); // fill in from network...
desc.setHtmlText(media.getDescription());
license.setText(media.getLicense());
Disposable disposable = mediaDataExtractor.fetchMediaDetails(media.getFilename())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::setTextFields);
compositeDisposable.add(disposable);
}
@Override
public void onDestroyView() {
if (detailFetchTask != null) {
detailFetchTask.cancel(true);
detailFetchTask = null;
}
if (layoutListener != null && getView() != null) {
getView().getViewTreeObserver().removeGlobalOnLayoutListener(layoutListener); // old Android was on crack. CRACK IS WHACK
layoutListener = null;
@ -341,7 +289,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
}
private void setTextFields(Media media) {
desc.setText(prettyDescription(media));
this.media = media;
desc.setHtmlText(prettyDescription(media));
license.setText(prettyLicense(media));
coordinates.setText(prettyCoordinates(media));
uploadedDate.setText(prettyUploadedDate(media));
@ -369,16 +318,11 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
@OnClick(R.id.mediaDetailLicense)
public void onMediaDetailLicenceClicked(){
String url = licenseLink(media);
String url = media.getLicenseUrl();
if (!StringUtils.isNullOrWhiteSpace(url) && getActivity() != null) {
Utils.handleWebUrl(getActivity(), Uri.parse(url));
} else {
if (isCategoryImage) {
Timber.d("Unable to fetch license URL for %s", media.getLicense());
} else {
Toast toast = Toast.makeText(getContext(), getString(R.string.null_url), Toast.LENGTH_SHORT);
toast.show();
}
viewUtil.showShortToast(getActivity(), getString(R.string.null_url));
}
}
@ -425,18 +369,13 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
final EditText input = new EditText(getActivity());
alert.setView(input);
input.requestFocus();
alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String reason = input.getText().toString();
alert.setPositiveButton(R.string.ok, (dialog1, whichButton) -> {
String reason = input.getText().toString();
DeleteTask deleteTask = new DeleteTask(getActivity(), media, reason);
deleteTask.execute();
enableDeleteButton(false);
}
deleteHelper.makeDeletion(getContext(), media, reason);
enableDeleteButton(false);
});
alert.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
alert.setNegativeButton(R.string.cancel, (dialog12, whichButton) -> {
});
AlertDialog d = alert.create();
input.addTextChangedListener(new TextWatcher() {
@ -469,13 +408,12 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
@SuppressLint("CheckResult")
private void onDeleteClicked(Spinner spinner) {
String reason = spinner.getSelectedItem().toString();
Single<String> deletionReason = reasonBuilder.getReason(media, reason);
compositeDisposable.add(deletionReason
Single<Boolean> resultSingle = reasonBuilder.getReason(media, reason)
.flatMap(reasonString -> deleteHelper.makeDeletion(getContext(), media, reason));
compositeDisposable.add(resultSingle
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(s -> {
DeleteTask deleteTask = new DeleteTask(getActivity(), media, reason);
deleteTask.execute();
isDeleted = true;
enableDeleteButton(false);
}));
@ -570,12 +508,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
if (licenseKey == null || licenseKey.equals("")) {
return getString(R.string.detail_license_empty);
}
License licenseObj = licenseList.get(licenseKey);
if (licenseObj == null) {
return licenseKey;
} else {
return licenseObj.getName();
}
return licenseKey;
}
private String prettyUploadedDate(Media media) {
@ -607,19 +540,4 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
nominatedForDeletion.setVisibility(GONE);
}
}
private @Nullable
String licenseLink(Media media) {
String licenseKey = media.getLicense();
if (licenseKey == null || licenseKey.equals("")) {
return null;
}
License licenseObj = licenseList.get(licenseKey);
if (licenseObj == null) {
return null;
} else {
return licenseObj.getUrl(Locale.getDefault().getLanguage());
}
}
}

View file

@ -1,49 +0,0 @@
package fr.free.nrw.commons.media;
import java.util.List;
import java.util.Random;
import javax.annotation.Nullable;
import fr.free.nrw.commons.mwapi.model.RecentChange;
public class RecentChangesImageUtils {
private static final String[] imageExtensions = new String[]
{".jpg", ".jpeg", ".png"};
@Nullable
public static 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;
}
}

View file

@ -13,7 +13,10 @@ public class ExtMetadata {
@SuppressWarnings("unused") @SerializedName("CommonsMetadataExtension") @Nullable private Values commonsMetadataExtension;
@SuppressWarnings("unused") @SerializedName("Categories") @Nullable private Values categories;
@SuppressWarnings("unused") @SerializedName("Assessments") @Nullable private Values assessments;
@SuppressWarnings("unused") @SerializedName("ImageDescription") @Nullable private Values imageDescription;
@SuppressWarnings("unused")
@SerializedName("ImageDescription")
@Nullable
private Values imageDescription;
@SuppressWarnings("unused") @SerializedName("GPSLatitude") @Nullable private Values gpsLatitude;
@SuppressWarnings("unused") @SerializedName("GPSLongitude") @Nullable private Values gpsLongitude;
@SuppressWarnings("unused") @SerializedName("DateTimeOriginal") @Nullable private Values dateTimeOriginal;
@ -49,7 +52,8 @@ public class ExtMetadata {
return license != null ? license : new Values();
}
@NonNull public Values imageDescription() {
@NonNull
public Values imageDescription() {
return imageDescription != null ? imageDescription : new Values();
}