mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-29 05:43:55 +01:00
Replace remaining AsyncTask with RxAndroid (#2681)
This commit is contained in:
parent
a62aaadf90
commit
0bf63f50b3
28 changed files with 1096 additions and 1153 deletions
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue