Merge pull request #1824 from tanvidadu/addedReasonList

Provide a selectable list of reasons when requesting deletion of a file
This commit is contained in:
Vivek Maskara 2018-11-20 21:26:31 +05:30 committed by GitHub
commit c4d6cec433
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 171 additions and 38 deletions

View file

@ -0,0 +1,101 @@
package fr.free.nrw.commons.delete;
import android.accounts.Account;
import android.content.Context;
import android.util.Log;
import com.google.gson.JsonObject;
import org.json.JSONException;
import org.json.JSONObject;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import javax.inject.Inject;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.achievements.FeedbackResponse;
import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.utils.ViewUtil;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
import timber.log.Timber;
public class ReasonBuilder {
private SessionManager sessionManager;
private MediaWikiApi mediaWikiApi;
private CompositeDisposable compositeDisposable = new CompositeDisposable();
private String reason;
private Context context;
private Media media;
public ReasonBuilder(String reason,
Context context,
Media media,
SessionManager sessionManager,
MediaWikiApi mediaWikiApi){
this.reason = reason;
this.context = context;
this.media = media;
this.sessionManager = sessionManager;
this.mediaWikiApi = mediaWikiApi;
}
private String prettyUploadedDate(Media media) {
Date date = media.getDateUploaded();
if (date == null || date.toString() == null || date.toString().isEmpty()) {
return "Uploaded date not available";
}
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy", Locale.getDefault());
return formatter.format(date);
}
private void fetchArticleNumber() {
if (checkAccount()) {
compositeDisposable.add(mediaWikiApi
.getAchievements(sessionManager.getCurrentAccount().name)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
jsonObject -> appendArticlesUsed(jsonObject),
t -> Timber.e(t, "Fetching achievements statistics failed")
));
}
}
private void appendArticlesUsed(FeedbackResponse object){
reason += context.getString(R.string.uploaded_by_myself).toString() + prettyUploadedDate(media);
reason += context.getString(R.string.used_by).toString()
+ object.getArticlesUsingImages()
+ context.getString(R.string.articles).toString();
Log.i("New Reason", reason);
}
public String getReason(){
fetchArticleNumber();
return reason;
}
/**
* check to ensure that user is logged in
* @return
*/
private boolean checkAccount(){
Account currentAccount = sessionManager.getCurrentAccount();
if(currentAccount == null) {
Timber.d("Current account is null");
ViewUtil.showLongToast(context, context.getResources().getString(R.string.user_not_logged_in));
sessionManager.forceLogin(context);
return false;
}
return true;
}
}

View file

@ -14,15 +14,18 @@ import android.text.Editable;
import android.text.Html; import android.text.Html;
import android.text.TextUtils; import android.text.TextUtils;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.ViewTreeObserver; import android.view.ViewTreeObserver;
import android.widget.ArrayAdapter;
import android.widget.Button; import android.widget.Button;
import android.widget.EditText; import android.widget.EditText;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.ScrollView; import android.widget.ScrollView;
import android.widget.Spinner;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
@ -44,9 +47,11 @@ import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.MediaDataExtractor; import fr.free.nrw.commons.MediaDataExtractor;
import fr.free.nrw.commons.MediaWikiImageView; import fr.free.nrw.commons.MediaWikiImageView;
import fr.free.nrw.commons.R; import fr.free.nrw.commons.R;
import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.category.CategoryDetailsActivity; import fr.free.nrw.commons.category.CategoryDetailsActivity;
import fr.free.nrw.commons.contributions.ContributionsFragment; import fr.free.nrw.commons.contributions.ContributionsFragment;
import fr.free.nrw.commons.delete.DeleteTask; import fr.free.nrw.commons.delete.DeleteTask;
import fr.free.nrw.commons.delete.ReasonBuilder;
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment; import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.location.LatLng; import fr.free.nrw.commons.location.LatLng;
import fr.free.nrw.commons.mwapi.MediaWikiApi; import fr.free.nrw.commons.mwapi.MediaWikiApi;
@ -65,6 +70,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
private MediaDetailPagerFragment.MediaDetailProvider detailProvider; private MediaDetailPagerFragment.MediaDetailProvider detailProvider;
private int index; private int index;
private Locale locale; private Locale locale;
private boolean isDeleted = false;
public static MediaDetailFragment forMedia(int index, boolean editable, boolean isCategoryImage) { public static MediaDetailFragment forMedia(int index, boolean editable, boolean isCategoryImage) {
MediaDetailFragment mf = new MediaDetailFragment(); MediaDetailFragment mf = new MediaDetailFragment();
@ -85,6 +92,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
Provider<MediaDataExtractor> mediaDataExtractorProvider; Provider<MediaDataExtractor> mediaDataExtractorProvider;
@Inject @Inject
MediaWikiApi mwApi; MediaWikiApi mwApi;
@Inject
SessionManager sessionManager;
private int initialListTop = 0; private int initialListTop = 0;
@ -128,6 +137,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
//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 //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; private Media media;
private ArrayList<String> reasonList;
@Override @Override
public void onSaveInstanceState(Bundle outState) { public void onSaveInstanceState(Bundle outState) {
@ -160,6 +171,13 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
initialListTop = 0; initialListTop = 0;
} }
reasonList = new ArrayList<>();
reasonList.add(getString(R.string.deletion_reason_uploaded_by_mistake));
reasonList.add(getString(R.string.deletion_reason_publicly_visible));
reasonList.add(getString(R.string.deletion_reason_not_interesting));
reasonList.add(getString(R.string.deletion_reason_no_longer_want_public));
reasonList.add(getString(R.string.deletion_reason_bad_for_my_privacy));
categoryNames = new ArrayList<>(); categoryNames = new ArrayList<>();
categoryNames.add(getString(R.string.detail_panel_cats_loading)); categoryNames.add(getString(R.string.detail_panel_cats_loading));
@ -371,48 +389,43 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
@OnClick(R.id.nominateDeletion) @OnClick(R.id.nominateDeletion)
public void onDeleteButtonClicked(){ public void onDeleteButtonClicked(){
//Reviewer correct me if i have misunderstood something over here final ArrayAdapter<String> languageAdapter = new ArrayAdapter<String>(getActivity(),
//But how does this if (delete.getVisibility() == View.VISIBLE) { R.layout.simple_spinner_dropdown_list, reasonList);
// enableDeleteButton(true); makes sense ? final Spinner spinner = new Spinner(getActivity());
AlertDialog.Builder alert = new AlertDialog.Builder(getActivity()); spinner.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.WRAP_CONTENT));
alert.setMessage("Why should this file be deleted?"); spinner.setAdapter(languageAdapter);
final EditText input = new EditText(getActivity()); spinner.setGravity(17);
alert.setView(input);
input.requestFocus();
alert.setPositiveButton(R.string.ok, (dialog, whichButton) -> {
String reason = input.getText().toString();
DeleteTask deleteTask = new DeleteTask(getActivity(), media, reason);
deleteTask.execute();
enableDeleteButton(false);
});
alert.setNegativeButton(R.string.cancel, (dialog, whichButton) -> {
});
AlertDialog d = alert.create();
input.addTextChangedListener(new TextWatcher() {
private void handleText() {
final Button okButton = d.getButton(AlertDialog.BUTTON_POSITIVE);
if (input.getText().length() == 0) {
okButton.setEnabled(false);
} else {
okButton.setEnabled(true);
}
}
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(spinner);
builder.setTitle(R.string.nominate_delete)
.setPositiveButton(R.string.about_translate_proceed, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
String reason = spinner.getSelectedItem().toString();
ReasonBuilder reasonBuilder = new ReasonBuilder(reason,
getActivity(),
media,
sessionManager,
mwApi);
reason = reasonBuilder.getReason();
DeleteTask deleteTask = new DeleteTask(getActivity(), media, reason);
deleteTask.execute();
isDeleted = true;
enableDeleteButton(false);
}
});
builder.setNegativeButton(R.string.about_translate_cancel, new DialogInterface.OnClickListener() {
@Override @Override
public void afterTextChanged(Editable arg0) { public void onClick(DialogInterface dialog, int which) {
handleText(); dialog.dismiss();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
} }
}); });
d.show(); AlertDialog dialog = builder.create();
d.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false); dialog.show();
if(isDeleted) {
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
}
} }
@OnClick(R.id.seeMore) @OnClick(R.id.seeMore)

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
style="?android:attr/spinnerDropDownItemStyle"
android:singleLine="false"
android:layout_width="match_parent"
android:layout_height="?android:attr/listPreferredItemHeight"
android:ellipsize="marquee" />

View file

@ -345,6 +345,7 @@
<string name="delete_recent_searches_dialog">Are you sure you want to clear your search history?</string> <string name="delete_recent_searches_dialog">Are you sure you want to clear your search history?</string>
<string name="search_history_deleted">Search history deleted</string> <string name="search_history_deleted">Search history deleted</string>
<string name="nominate_delete">Nominate For Deletion</string>
<string name="Achievements">Achievements</string> <string name="Achievements">Achievements</string>
<string name="statistics">STATISTICS</string> <string name="statistics">STATISTICS</string>
@ -396,6 +397,16 @@
<string name="bookmark_empty">You haven\'t added any bookmarks</string> <string name="bookmark_empty">You haven\'t added any bookmarks</string>
<string name="provider_bookmarks_location">Bookmarks</string> <string name="provider_bookmarks_location">Bookmarks</string>
<string name="log_collection_started">Log collection started. Please RESTART the app, perform action that you wish to log, and then tap \'Send log file\' again</string> <string name="log_collection_started">Log collection started. Please RESTART the app, perform action that you wish to log, and then tap \'Send log file\' again</string>
<string name="deletion_reason_uploaded_by_mistake">I uploaded it by mistake</string>
<string name="deletion_reason_publicly_visible">I did not know it would be publicly visible</string>
<string name="deletion_reason_bad_for_my_privacy">I realized it is bad for my privacy</string>
<string name="deletion_reason_no_longer_want_public">I changed my mind, I don\'t want it to be publicly visible anymore</string>
<string name="deletion_reason_not_interesting">Sorry this picture is not interesting for an encyclopedia</string>
<string name="uploaded_by_myself">Uploaded by myself on</string>
<string name="used_by">,used in</string>
<string name="articles">articles</string>
<string name="no_uploads">Welcome to Commons!\n <string name="no_uploads">Welcome to Commons!\n
Upload your first media by touching the camera or gallery icon above.</string> Upload your first media by touching the camera or gallery icon above.</string>