mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 12:23:58 +01:00
Send thanks button in more details fragment (#5424)
* Send thanks button in more details fragment * failing test fix * suggested fix
This commit is contained in:
parent
3c1cdf18a1
commit
495d001dc9
5 changed files with 109 additions and 6 deletions
|
|
@ -12,7 +12,6 @@ import static fr.free.nrw.commons.description.EditDescriptionConstants.WIKITEXT;
|
||||||
import static fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailFragment.LAST_LOCATION;
|
import static fr.free.nrw.commons.upload.mediaDetails.UploadMediaDetailFragment.LAST_LOCATION;
|
||||||
import static fr.free.nrw.commons.utils.LangCodeUtils.getLocalizedResources;
|
import static fr.free.nrw.commons.utils.LangCodeUtils.getLocalizedResources;
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
@ -23,6 +22,7 @@ import android.graphics.drawable.Animatable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
|
import android.text.TextUtils;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
|
@ -64,6 +64,7 @@ import fr.free.nrw.commons.Media;
|
||||||
import fr.free.nrw.commons.MediaDataExtractor;
|
import fr.free.nrw.commons.MediaDataExtractor;
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.Utils;
|
import fr.free.nrw.commons.Utils;
|
||||||
|
import fr.free.nrw.commons.actions.ThanksClient;
|
||||||
import fr.free.nrw.commons.auth.AccountUtil;
|
import fr.free.nrw.commons.auth.AccountUtil;
|
||||||
import fr.free.nrw.commons.auth.SessionManager;
|
import fr.free.nrw.commons.auth.SessionManager;
|
||||||
import fr.free.nrw.commons.category.CategoryClient;
|
import fr.free.nrw.commons.category.CategoryClient;
|
||||||
|
|
@ -75,12 +76,15 @@ import fr.free.nrw.commons.delete.DeleteHelper;
|
||||||
import fr.free.nrw.commons.delete.ReasonBuilder;
|
import fr.free.nrw.commons.delete.ReasonBuilder;
|
||||||
import fr.free.nrw.commons.description.DescriptionEditActivity;
|
import fr.free.nrw.commons.description.DescriptionEditActivity;
|
||||||
import fr.free.nrw.commons.description.DescriptionEditHelper;
|
import fr.free.nrw.commons.description.DescriptionEditHelper;
|
||||||
|
import fr.free.nrw.commons.di.ApplicationlessInjection;
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
||||||
import fr.free.nrw.commons.explore.depictions.WikidataItemDetailsActivity;
|
import fr.free.nrw.commons.explore.depictions.WikidataItemDetailsActivity;
|
||||||
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
import fr.free.nrw.commons.kvstore.JsonKvStore;
|
||||||
import fr.free.nrw.commons.location.LocationServiceManager;
|
import fr.free.nrw.commons.location.LocationServiceManager;
|
||||||
import fr.free.nrw.commons.media.ZoomableActivity.ZoomableActivityConstants;
|
import fr.free.nrw.commons.media.ZoomableActivity.ZoomableActivityConstants;
|
||||||
import fr.free.nrw.commons.profile.ProfileActivity;
|
import fr.free.nrw.commons.profile.ProfileActivity;
|
||||||
|
import fr.free.nrw.commons.review.ReviewController;
|
||||||
|
import fr.free.nrw.commons.review.ReviewHelper;
|
||||||
import fr.free.nrw.commons.settings.Prefs;
|
import fr.free.nrw.commons.settings.Prefs;
|
||||||
import fr.free.nrw.commons.ui.widget.HtmlTextView;
|
import fr.free.nrw.commons.ui.widget.HtmlTextView;
|
||||||
import fr.free.nrw.commons.upload.categories.UploadCategoriesFragment;
|
import fr.free.nrw.commons.upload.categories.UploadCategoriesFragment;
|
||||||
|
|
@ -88,9 +92,13 @@ import fr.free.nrw.commons.upload.depicts.DepictsFragment;
|
||||||
import fr.free.nrw.commons.upload.UploadMediaDetail;
|
import fr.free.nrw.commons.upload.UploadMediaDetail;
|
||||||
import fr.free.nrw.commons.utils.DialogUtil;
|
import fr.free.nrw.commons.utils.DialogUtil;
|
||||||
import fr.free.nrw.commons.utils.PermissionUtils;
|
import fr.free.nrw.commons.utils.PermissionUtils;
|
||||||
|
import fr.free.nrw.commons.utils.ViewUtil;
|
||||||
import fr.free.nrw.commons.utils.ViewUtilWrapper;
|
import fr.free.nrw.commons.utils.ViewUtilWrapper;
|
||||||
|
import io.reactivex.Observable;
|
||||||
|
import io.reactivex.ObservableSource;
|
||||||
import io.reactivex.Single;
|
import io.reactivex.Single;
|
||||||
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 java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
@ -101,11 +109,13 @@ import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.wikipedia.dataclient.mwapi.MwQueryPage;
|
||||||
import org.wikipedia.language.AppLanguageLookUpTable;
|
import org.wikipedia.language.AppLanguageLookUpTable;
|
||||||
import org.wikipedia.util.DateUtil;
|
import org.wikipedia.util.DateUtil;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
@ -154,6 +164,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements
|
||||||
@Inject
|
@Inject
|
||||||
DeleteHelper deleteHelper;
|
DeleteHelper deleteHelper;
|
||||||
@Inject
|
@Inject
|
||||||
|
ReviewHelper reviewHelper;
|
||||||
|
@Inject
|
||||||
CategoryEditHelper categoryEditHelper;
|
CategoryEditHelper categoryEditHelper;
|
||||||
@Inject
|
@Inject
|
||||||
CoordinateEditHelper coordinateEditHelper;
|
CoordinateEditHelper coordinateEditHelper;
|
||||||
|
|
@ -164,6 +176,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements
|
||||||
@Inject
|
@Inject
|
||||||
CategoryClient categoryClient;
|
CategoryClient categoryClient;
|
||||||
@Inject
|
@Inject
|
||||||
|
ThanksClient thanksClient;
|
||||||
|
@Inject
|
||||||
@Named("default_preferences")
|
@Named("default_preferences")
|
||||||
JsonKvStore applicationKvStore;
|
JsonKvStore applicationKvStore;
|
||||||
|
|
||||||
|
|
@ -241,6 +255,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements
|
||||||
ProgressBar progressBarEditCategory;
|
ProgressBar progressBarEditCategory;
|
||||||
@BindView(R.id.description_edit)
|
@BindView(R.id.description_edit)
|
||||||
Button editDescription;
|
Button editDescription;
|
||||||
|
@BindView(R.id.sendThanks)
|
||||||
|
Button sendThanksButton;
|
||||||
|
|
||||||
private ArrayList<String> categoryNames = new ArrayList<>();
|
private ArrayList<String> categoryNames = new ArrayList<>();
|
||||||
private String categorySearchQuery;
|
private String categorySearchQuery;
|
||||||
|
|
@ -431,6 +447,13 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements
|
||||||
enableProgressBar();
|
enableProgressBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (AccountUtil.getUserName(getContext()) != null && media != null
|
||||||
|
&& AccountUtil.getUserName(getContext()).equals(media.getAuthor())) {
|
||||||
|
sendThanksButton.setVisibility(GONE);
|
||||||
|
} else {
|
||||||
|
sendThanksButton.setVisibility(VISIBLE);
|
||||||
|
}
|
||||||
|
|
||||||
scrollView.getViewTreeObserver().addOnGlobalLayoutListener(
|
scrollView.getViewTreeObserver().addOnGlobalLayoutListener(
|
||||||
new OnGlobalLayoutListener() {
|
new OnGlobalLayoutListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -780,12 +803,77 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment implements
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.copyWikicode)
|
@OnClick(R.id.copyWikicode)
|
||||||
public void onCopyWikicodeClicked(){
|
public void onCopyWikicodeClicked() {
|
||||||
String data = "[[" + media.getFilename() + "|thumb|" + media.getFallbackDescription() + "]]";
|
String data =
|
||||||
Utils.copy("wikiCode",data,getContext());
|
"[[" + media.getFilename() + "|thumb|" + media.getFallbackDescription() + "]]";
|
||||||
|
Utils.copy("wikiCode", data, getContext());
|
||||||
Timber.d("Generated wikidata copy code: %s", data);
|
Timber.d("Generated wikidata copy code: %s", data);
|
||||||
|
|
||||||
Toast.makeText(getContext(), getString(R.string.wikicode_copied), Toast.LENGTH_SHORT).show();
|
Toast.makeText(getContext(), getString(R.string.wikicode_copied), Toast.LENGTH_SHORT)
|
||||||
|
.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends thanks to author if the author is not the user
|
||||||
|
*/
|
||||||
|
@OnClick(R.id.sendThanks)
|
||||||
|
public void sendThanksToAuthor() {
|
||||||
|
String fileName = media.getFilename();
|
||||||
|
if (TextUtils.isEmpty(fileName)) {
|
||||||
|
Toast.makeText(getContext(), getString(R.string.error_sending_thanks),
|
||||||
|
Toast.LENGTH_SHORT).show();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
compositeDisposable.add(reviewHelper.getFirstRevisionOfFile(fileName)
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe(revision -> sendThanks(getContext(), revision)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Api call for sending thanks to the author when the author is not the user
|
||||||
|
* and display toast depending on the result
|
||||||
|
* @param context context
|
||||||
|
* @param firstRevision the revision id of the image
|
||||||
|
*/
|
||||||
|
@SuppressLint({"CheckResult", "StringFormatInvalid"})
|
||||||
|
void sendThanks(Context context, MwQueryPage.Revision firstRevision) {
|
||||||
|
ViewUtil.showShortToast(context,
|
||||||
|
context.getString(R.string.send_thank_toast, media.getDisplayTitle()));
|
||||||
|
|
||||||
|
if (firstRevision == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Observable.defer((Callable<ObservableSource<Boolean>>) () -> thanksClient.thank(
|
||||||
|
firstRevision.getRevisionId()))
|
||||||
|
.subscribeOn(Schedulers.io())
|
||||||
|
.observeOn(AndroidSchedulers.mainThread())
|
||||||
|
.subscribe((result) -> {
|
||||||
|
displayThanksToast(context, result);
|
||||||
|
}, Timber::e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method to display toast when api call to thank the author is completed
|
||||||
|
* @param context context
|
||||||
|
* @param result true if success, false otherwise
|
||||||
|
*/
|
||||||
|
@SuppressLint("StringFormatInvalid")
|
||||||
|
private void displayThanksToast(final Context context, final boolean result) {
|
||||||
|
final String message;
|
||||||
|
final String title;
|
||||||
|
if (result) {
|
||||||
|
title = context.getString(R.string.send_thank_success_title);
|
||||||
|
message = context.getString(R.string.send_thank_success_message,
|
||||||
|
media.getDisplayTitle());
|
||||||
|
} else {
|
||||||
|
title = context.getString(R.string.send_thank_failure_title);
|
||||||
|
message = context.getString(R.string.send_thank_failure_message,
|
||||||
|
media.getDisplayTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
ViewUtil.showShortToast(context, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@OnClick(R.id.categoryEditButton)
|
@OnClick(R.id.categoryEditButton)
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ public class ReviewHelper {
|
||||||
* @param filename
|
* @param filename
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
Observable<MwQueryPage.Revision> getFirstRevisionOfFile(String filename) {
|
public Observable<MwQueryPage.Revision> getFirstRevisionOfFile(String filename) {
|
||||||
return reviewInterface.getFirstRevisionOfFile(filename)
|
return reviewInterface.getFirstRevisionOfFile(filename)
|
||||||
.map(response -> response.query().firstPage().revisions().get(0));
|
.map(response -> response.query().firstPage().revisions().get(0));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -464,6 +464,16 @@
|
||||||
android:text="@string/copy_wikicode"
|
android:text="@string/copy_wikicode"
|
||||||
android:textColor="@color/primaryTextColor" />
|
android:textColor="@color/primaryTextColor" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/sendThanks"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="@dimen/standard_gap"
|
||||||
|
android:layout_marginEnd="@dimen/standard_gap"
|
||||||
|
android:background="@drawable/bg_copy_wikitext_button"
|
||||||
|
android:text="@string/send_thanks_to_author"
|
||||||
|
android:textColor="@color/primaryTextColor" />
|
||||||
|
|
||||||
<FrameLayout
|
<FrameLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
|
||||||
|
|
@ -787,6 +787,8 @@ Upload your first media by tapping on the add button.</string>
|
||||||
<string name="learn_how_to_write_a_useful_description">Learn how to write a useful description</string>
|
<string name="learn_how_to_write_a_useful_description">Learn how to write a useful description</string>
|
||||||
<string name="learn_how_to_write_a_useful_caption">Learn how to write a useful caption</string>
|
<string name="learn_how_to_write_a_useful_caption">Learn how to write a useful caption</string>
|
||||||
<string name="see_your_achievements">See your achievements</string>
|
<string name="see_your_achievements">See your achievements</string>
|
||||||
|
<string name="send_thanks_to_author">Thank the author</string>
|
||||||
|
<string name="error_sending_thanks">Error sending thanks to author.</string>
|
||||||
<plurals name="custom_picker_images_selected_title_appendix">
|
<plurals name="custom_picker_images_selected_title_appendix">
|
||||||
<item quantity="one">%d image selected</item>
|
<item quantity="one">%d image selected</item>
|
||||||
<item quantity="other">%d images selected</item>
|
<item quantity="other">%d images selected</item>
|
||||||
|
|
|
||||||
|
|
@ -316,6 +316,9 @@ class MediaDetailFragmentUnitTests {
|
||||||
@Test
|
@Test
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
fun testOnResume() {
|
fun testOnResume() {
|
||||||
|
Whitebox.setInternalState(fragment, "applicationKvStore", applicationKvStore)
|
||||||
|
`when`(applicationKvStore.getBoolean("login_skipped")).thenReturn(true)
|
||||||
|
fragment.onCreateView(layoutInflater, null, savedInstanceState)
|
||||||
fragment.onResume()
|
fragment.onResume()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue