Skip to content

[WIP] Review: don't dump whole RC list when first nominated for delete #1544

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 54 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
80a97a4
Add new activity to manifest
neslihanturan May 19, 2018
0f35fc5
Create review activity layout base
neslihanturan May 19, 2018
35d9603
Add a new menu item to drawer for peer review
neslihanturan May 19, 2018
7510d30
Add a top menu with randomizer icon to review activity
neslihanturan May 19, 2018
1067097
Add strings for review button
neslihanturan May 19, 2018
d16d6e9
Add activity to ActivityBuilderModule for injection
neslihanturan May 19, 2018
a2c3cba
Add a new drawer item to start review acitivty
neslihanturan May 19, 2018
67a4534
Create base of the Review Activity
neslihanturan May 19, 2018
02a066f
Add fragment pager
neslihanturan May 19, 2018
f3d0be1
Add new fragment for injection
neslihanturan May 19, 2018
9f01161
Create a fragment pager layout
neslihanturan May 19, 2018
f7156f5
Wikimedia hackathon 2018 (#1533)
ejegg May 19, 2018
0013895
Add ReviewController class
neslihanturan May 19, 2018
3ff64d0
Fix fragments
neslihanturan May 19, 2018
922e124
Wmhack2018 (#1534)
ejegg May 19, 2018
e71b4fa
Re-use same class for all review fragments (#1537)
ejegg May 19, 2018
e282bd8
[WIP] category check
whym May 19, 2018
589c9fb
[WIP] add on-click actions to ReviewActivity
whym May 19, 2018
b24f4d5
[WIP] add SendThankTask
whym May 19, 2018
0ca6eb0
Make it beautiful
neslihanturan May 19, 2018
27cbe1d
Merge remote-tracking branch 'upstream/wikimedia-hackathon-2018' into…
neslihanturan May 19, 2018
5cff7ee
Add some category stuff back in to review (#1538)
ejegg May 19, 2018
11b485a
Change category question text sizes
neslihanturan May 19, 2018
5acd668
Call randomizer whenever the activity is ready
neslihanturan May 20, 2018
103754e
Add progressbar
neslihanturan May 20, 2018
9d779b9
[WIP] add DeleteTask.askReasonAndExecute
whym May 19, 2018
a5bab42
Merge branch 'wikimedia-hackathon-2018' of https://github.com/commons…
whym May 20, 2018
95868eb
Fix refresh button string
neslihanturan May 20, 2018
7809979
Typo: "nominate *for* deletion"
whym May 20, 2018
f353c01
Add formatting to categories and put them in the same textView
neslihanturan May 20, 2018
7672720
Merge remote-tracking branch 'upstream/wikimedia-hackathon-2018' into…
neslihanturan May 20, 2018
11f7014
Pass context and adapters as parameters to controller
neslihanturan May 20, 2018
397652e
Add actions to controller
neslihanturan May 20, 2018
2ea9581
Make everyting work
neslihanturan May 20, 2018
c054fc6
Merge branch 'wikimedia-hackathon-2018' of https://github.com/commons…
whym May 20, 2018
f870b48
Add another fragment to thank
neslihanturan May 20, 2018
1eb800a
Fix npe
neslihanturan May 20, 2018
cefe9b7
Add missing execute method
neslihanturan May 20, 2018
73ffd11
Some codes
neslihanturan May 20, 2018
3e7d25a
Add a funy text
neslihanturan May 20, 2018
7fcd6b9
Merge branch 'wikimedia-hackathon-2018' of https://github.com/commons…
whym May 20, 2018
d7cbcb9
More random recent image selection (#1542)
ejegg May 20, 2018
719564b
Create Revision class
whym May 20, 2018
2294774
Merge branch 'wikimedia-hackathon-2018' of https://github.com/commons…
whym May 20, 2018
9e02031
Add meaningluf strings
neslihanturan May 20, 2018
751edac
Merge remote-tracking branch 'upstream/wikimedia-hackathon-2018' into…
neslihanturan May 20, 2018
235d1c7
Error handling for review image/category fetch (#1543)
ejegg May 20, 2018
4e75c4a
Add information layout for username and filename
neslihanturan May 20, 2018
417d5a3
Merge remote-tracking branch 'upstream/wikimedia-hackathon-2018' into…
neslihanturan May 20, 2018
5e8359d
Use Single to get firstRevision
whym May 20, 2018
1c5d5bb
Review: don't dump whole RC list when first nominated for delete
ejegg May 20, 2018
b5621d7
Fix typos
ejegg May 20, 2018
040415e
Select default delete text for easy replacement
ejegg May 20, 2018
b308aa3
extend selection further, reword a thing
ejegg May 20, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@
android:label="@string/title_activity_featured_images"
android:parentActivityName=".contributions.ContributionsActivity" />

<activity
android:name=".review.ReviewActivity"
android:label="@string/title_activity_review" />

<service android:name=".upload.UploadService" />

<service
Expand Down
18 changes: 2 additions & 16 deletions app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import fr.free.nrw.commons.location.LatLng;
import fr.free.nrw.commons.mwapi.MediaResult;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.utils.MediaDataExtractorUtil;
import timber.log.Timber;

/**
Expand Down Expand Up @@ -71,28 +72,13 @@ public void fetch(String filename, LicenseList licenseList) throws IOException {
MediaResult result = mediaWikiApi.fetchMediaByFilename(filename);

// In-page category links are extracted from source, as XML doesn't cover [[links]]
extractCategories(result.getWikiSource());
categories = MediaDataExtractorUtil.extractCategories(result.getWikiSource());

// Description template info is extracted from preprocessor XML
processWikiParseTree(result.getParseTreeXmlSource(), licenseList);
fetched = true;
}

/**
* We could fetch all category links from API, but we actually only want the ones
* directly in the page source so they're editable. In the future this may change.
*
* @param source wikitext source code
*/
private void extractCategories(String source) {
Pattern regex = Pattern.compile("\\[\\[\\s*Category\\s*:([^]]*)\\s*\\]\\]", Pattern.CASE_INSENSITIVE);
Matcher matcher = regex.matcher(source);
while (matcher.find()) {
String cat = matcher.group(1).trim();
categories.add(cat);
}
}

private void processWikiParseTree(String source, LicenseList licenseList) throws IOException {
Document doc;
try {
Expand Down
103 changes: 76 additions & 27 deletions app/src/main/java/fr/free/nrw/commons/delete/DeleteTask.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
package fr.free.nrw.commons.delete;

import android.app.AlertDialog;
import android.app.NotificationManager;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationCompat.Builder;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.Gravity;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import java.text.SimpleDateFormat;
Expand All @@ -14,11 +20,13 @@

import javax.inject.Inject;

import butterknife.OnClick;
import fr.free.nrw.commons.Media;
import fr.free.nrw.commons.R;
import fr.free.nrw.commons.auth.SessionManager;
import fr.free.nrw.commons.di.ApplicationlessInjection;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.review.ReviewActivity;
import timber.log.Timber;

import static android.support.v4.app.NotificationCompat.DEFAULT_ALL;
Expand Down Expand Up @@ -54,7 +62,7 @@ protected void onPreExecute(){
notificationBuilder = new NotificationCompat.Builder(context);
Toast toast = new Toast(context);
toast.setGravity(Gravity.CENTER,0,0);
toast = Toast.makeText(context,"Trying to nominate "+media.getDisplayTitle()+ " for deletion",Toast.LENGTH_SHORT);
toast = Toast.makeText(context,"Trying to nominate "+media.getDisplayTitle()+ " for deletion", Toast.LENGTH_SHORT);
toast.show();
}

Expand All @@ -64,7 +72,7 @@ protected Boolean doInBackground(Void ...voids) {

String editToken;
String authCookie;
String summary = "Nominating " + media.getFilename() +" for deletion.";
String summary = context.getString(R.string.nominating_file_for_deletion, media.getFilename());

authCookie = sessionManager.getAuthCookie();
mwApi.setAuthCookie(authCookie);
Expand Down Expand Up @@ -97,19 +105,19 @@ protected Boolean doInBackground(Void ...voids) {
publishProgress(1);

mwApi.prependEdit(editToken,fileDeleteString+"\n",
media.getFilename(),summary);
media.getFilename(), summary);
publishProgress(2);

mwApi.edit(editToken,subpageString+"\n",
"Commons:Deletion_requests/"+media.getFilename(),summary);
"Commons:Deletion_requests/"+media.getFilename(), summary);
publishProgress(3);

mwApi.appendEdit(editToken,logPageString+"\n",
"Commons:Deletion_requests/"+date,summary);
"Commons:Deletion_requests/"+date, summary);
publishProgress(4);

mwApi.appendEdit(editToken,userPageString+"\n",
"User_Talk:"+sessionManager.getCurrentAccount().name,summary);
"User_Talk:"+sessionManager.getCurrentAccount().name, summary);
publishProgress(5);
}
catch (Exception e) {
Expand All @@ -123,29 +131,21 @@ protected Boolean doInBackground(Void ...voids) {
protected void onProgressUpdate (Integer... values){
super.onProgressUpdate(values);

int[] messages = new int[]{
R.string.getting_edit_token,
R.string.nominate_for_deletion_edit_file_page,
R.string.nominate_for_deletion_create_deletion_request,
R.string.nominate_for_deletion_edit_deletion_request_log,
R.string.nominate_for_deletion_notify_user,
R.string.nominate_for_deletion_done
};

String message = "";
switch (values[0]){
case 0:
message = "Getting token";
break;
case 1:
message = "Adding delete message to file";
break;
case 2:
message = "Creating Delete requests sub-page";
break;
case 3:
message = "Adding file to Delete requests log";
break;
case 4:
message = "Notifying User on Talk page";
break;
case 5:
message = "Done";
break;
if (0 < values[0] && values[0] < messages.length) {
message = context.getString(messages[values[0]]);
}

notificationBuilder.setContentTitle("Nominating "+media.getDisplayTitle()+" for deletion")
notificationBuilder.setContentTitle(context.getString(R.string.nominating_file_for_deletion, media.getFilename()))
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(message))
.setSmallIcon(R.drawable.ic_launcher)
Expand All @@ -161,7 +161,7 @@ protected void onPostExecute(Boolean result) {

if (result){
title += ": Success";
message = "Successfully nominated " + media.getDisplayTitle() + " deletion.";
message = "Successfully nominated " + media.getDisplayTitle() + " for deletion.";
}
else {
title += ": Failed";
Expand All @@ -178,4 +178,53 @@ protected void onPostExecute(Boolean result) {
.setPriority(PRIORITY_HIGH);
notificationManager.notify(NOTIFICATION_DELETE, notificationBuilder.build());
}

// TODO: refactor; see MediaDetailsFragment.onDeleteButtonClicked
// ReviewActivity will use this
public static void askReasonAndExecute(Media media, Context context, String question, String defaultValue) {
AlertDialog.Builder alert = new AlertDialog.Builder(context);
alert.setMessage(question);
final EditText input = new EditText(context);
input.setText(defaultValue);
input.setSelection(0, defaultValue.length());
alert.setView(input);
input.requestFocus();
alert.setPositiveButton(R.string.ok, (dialog, whichButton) -> {
String reason = input.getText().toString();

((ReviewActivity)context).reviewController.swipeToNext();
((ReviewActivity)context).runRandomizer();

DeleteTask deleteTask = new DeleteTask(context, media, reason);
deleteTask.execute();
});
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);
}
}

@Override
public void afterTextChanged(Editable arg0) {
handleText();
}

@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();
d.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(defaultValue.length() > 0);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import fr.free.nrw.commons.category.CategoryImagesActivity;
import fr.free.nrw.commons.nearby.NearbyActivity;
import fr.free.nrw.commons.notification.NotificationActivity;
import fr.free.nrw.commons.review.ReviewActivity;
import fr.free.nrw.commons.settings.SettingsActivity;
import fr.free.nrw.commons.upload.MultipleShareActivity;
import fr.free.nrw.commons.upload.ShareActivity;
Expand Down Expand Up @@ -50,4 +51,7 @@ public abstract class ActivityBuilderModule {

@ContributesAndroidInjector
abstract CategoryImagesActivity bindFeaturedImagesActivity();

@ContributesAndroidInjector
abstract ReviewActivity bindReviewActivity();
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
import fr.free.nrw.commons.CommonsApplication;
import fr.free.nrw.commons.MediaWikiImageView;
import fr.free.nrw.commons.auth.LoginActivity;
import fr.free.nrw.commons.contributions.Contribution;
import fr.free.nrw.commons.contributions.ContributionsActivity;
import fr.free.nrw.commons.contributions.ContributionsSyncAdapter;
import fr.free.nrw.commons.delete.DeleteTask;
import fr.free.nrw.commons.modifications.ModificationsSyncAdapter;
import fr.free.nrw.commons.review.CheckCategoryTask;
import fr.free.nrw.commons.review.SendThankTask;
import fr.free.nrw.commons.settings.SettingsFragment;
import fr.free.nrw.commons.nearby.PlaceRenderer;

Expand All @@ -40,6 +40,10 @@ public interface CommonsApplicationComponent extends AndroidInjector<Application

void inject(DeleteTask deleteTask);

void inject(CheckCategoryTask checkCategoryTask);

void inject(SendThankTask sendThankTask);

void inject(SettingsFragment fragment);

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import fr.free.nrw.commons.nearby.NearbyListFragment;
import fr.free.nrw.commons.nearby.NearbyMapFragment;
import fr.free.nrw.commons.nearby.NoPermissionsFragment;
import fr.free.nrw.commons.review.ReviewImageFragment;
import fr.free.nrw.commons.settings.SettingsFragment;
import fr.free.nrw.commons.upload.MultipleUploadListFragment;
import fr.free.nrw.commons.upload.SingleUploadFragment;
Expand Down Expand Up @@ -51,4 +52,7 @@ public abstract class FragmentBuilderModule {
@ContributesAndroidInjector
abstract CategoryImagesListFragment bindFeaturedImagesListFragment();

@ContributesAndroidInjector
abstract ReviewImageFragment bindReviewOutOfContextFragment();

}
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
import fr.free.nrw.commons.location.LatLng;
import fr.free.nrw.commons.mwapi.MediaWikiApi;
import fr.free.nrw.commons.review.CheckCategoryTask;
import fr.free.nrw.commons.review.SendThankTask;
import fr.free.nrw.commons.ui.widget.CompatTextView;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import timber.log.Timber;

import static android.view.View.GONE;
Expand Down Expand Up @@ -344,6 +349,7 @@ public void onMediaDetailCoordinatesClicked(){
}
}

// TODO: refactor; see DeleteTask.askReasonAndExecute
@OnClick(R.id.nominateDeletion)
public void onDeleteButtonClicked(){
//Reviewer correct me if i have misunderstood something over here
Expand All @@ -357,6 +363,7 @@ public void onDeleteButtonClicked(){
alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String reason = input.getText().toString();

DeleteTask deleteTask = new DeleteTask(getActivity(), media, reason);
deleteTask.execute();
enableDeleteButton(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package fr.free.nrw.commons.media;

import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import java.util.ArrayList;
import java.util.Random;

import android.support.annotation.NonNull;

public class RecentChangesImageUtils {

private static final String[] imageExtensions = new String[]
{".jpg", ".jpeg", ".png"};

@NonNull
public static ArrayList<String> findImagesInRecentChanges(NodeList childNodes) {
ArrayList<String> imageTitles = new ArrayList<>();
Random r = new Random();
int count = childNodes.getLength();
// 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];
Element e = (Element) childNodes.item(randomIndex);
if (e.getAttribute("type").equals("log") && !e.getAttribute("old_revid").equals("0")) {
// For log entries, we only want ones where old_revid is zero, indicating a new file
continue;
}
String imageTitle = e.getAttribute("title");

for (String imageExtension : imageExtensions) {
if (imageTitle.toLowerCase().endsWith(imageExtension)) {
imageTitles.add(imageTitle);
}
}
}
return imageTitles;
}
}
Loading