Skip to content

Commit a32ba45

Browse files
silkypriyaneslihanturan
authored andcommitted
Include previous Wikimedia hackathon (2018) task, peer review, to codebase (commons-app#2602)
* Add new activity to manifest * Create review activity layout base * Add a new menu item to drawer for peer review * Add a top menu with randomizer icon to review activity * Add strings for review button * Add activity to ActivityBuilderModule for injection * Add a new drawer item to start review acitivty * Create base of the Review Activity * Add fragment pager * Add new fragment for injection * Create a fragment pager layout * Wikimedia hackathon 2018 (commons-app#1533) * First draft of fn to get random recent image * Use log entries for requests to beta, try to connect refresh button FIXME: runs http request on main thread, breaks * Tweak button connection * Add ReviewController class * Fix fragments * Wmhack2018 (commons-app#1534) * tiny fixes * Load pictures into activities * Re-use same class for all review fragments (commons-app#1537) And try to add pager indicator * [WIP] category check * [WIP] add on-click actions to ReviewActivity * [WIP] add SendThankTask * Make it beautiful * Add some category stuff back in to review (commons-app#1538) * Use standalone category extraction code in MediaDataExtractor * Add categories to category review page * Change category question text sizes * Call randomizer whenever the activity is ready * Add progressbar * [WIP] add DeleteTask.askReasonAndExecute * Fix refresh button string * Typo: "nominate *for* deletion" * Add formatting to categories and put them in the same textView * Pass context and adapters as parameters to controller * Add actions to controller * Make everyting work * Add another fragment to thank * Fix npe * Add missing execute method * Some codes * Add a funy text * More random recent image selection (commons-app#1542) time-based randomness is biased - if someone uploaded 100 images in hour, one week ago, and I select a random point in time, their last image is way more likely to come up than anything else. With this, there is still bias towards choosing one of the last N in any burst of uploads (where N is the number of recent changes fetched) but it's a bit better than before. * Create Revision class * Add meaningluf strings * Error handling for review image/category fetch (commons-app#1543) * Add information layout for username and filename * Use Single to get firstRevision * try to add username and filename * Ensure caption is shown on every review fragment * Fix build * Fixes missing import * Change button text,show current category, add skip image button * Modify texts, fix night mode issues * Positive Wording * fix landscape issue * Add checkbox popup,rewording * Spelling Correction * Fix merge * Remove commented out code, use lambda * Simplify toolbar include
1 parent a1a65d0 commit a32ba45

33 files changed

+1594
-33
lines changed

app/src/main/AndroidManifest.xml

+4
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@
131131
android:name=".bookmarks.BookmarksActivity"
132132
android:label="@string/title_activity_bookmarks" />
133133

134+
<activity
135+
android:name=".review.ReviewActivity"
136+
android:label="@string/title_activity_review" />
137+
134138
<service android:name=".upload.UploadService" />
135139
<service
136140
android:name=".auth.WikiAccountAuthenticatorService"

app/src/main/java/fr/free/nrw/commons/MediaDataExtractor.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import fr.free.nrw.commons.location.LatLng;
2727
import fr.free.nrw.commons.mwapi.MediaResult;
2828
import fr.free.nrw.commons.mwapi.MediaWikiApi;
29+
import fr.free.nrw.commons.utils.MediaDataExtractorUtil;
2930
import timber.log.Timber;
3031

3132
/**
@@ -78,7 +79,7 @@ public void fetch(String filename, LicenseList licenseList) throws IOException {
7879

7980

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

8384
// Description template info is extracted from preprocessor XML
8485
processWikiParseTree(result.getParseTreeXmlSource(), licenseList);
@@ -107,7 +108,7 @@ private void setDiscussion(String source) {
107108
e.printStackTrace();
108109
}
109110
}
110-
111+
111112
private void processWikiParseTree(String source, LicenseList licenseList) throws IOException {
112113
Document doc;
113114
try {

app/src/main/java/fr/free/nrw/commons/delete/DeleteTask.java

+131-28
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,33 @@
11
package fr.free.nrw.commons.delete;
22

3+
import android.app.AlertDialog;
34
import android.app.NotificationManager;
45
import android.app.PendingIntent;
56
import android.content.Context;
7+
import android.content.DialogInterface;
68
import android.content.Intent;
79
import android.net.Uri;
810
import android.os.AsyncTask;
9-
import androidx.core.app.NotificationCompat;
10-
import androidx.core.app.NotificationCompat.Builder;
1111
import android.view.Gravity;
1212
import android.widget.Toast;
1313

1414
import java.text.SimpleDateFormat;
15+
import java.util.ArrayList;
1516
import java.util.Calendar;
1617
import java.util.Locale;
1718

1819
import javax.inject.Inject;
1920

21+
import androidx.core.app.NotificationCompat;
22+
import androidx.core.app.NotificationCompat.Builder;
2023
import fr.free.nrw.commons.BuildConfig;
2124
import fr.free.nrw.commons.CommonsApplication;
2225
import fr.free.nrw.commons.Media;
2326
import fr.free.nrw.commons.R;
2427
import fr.free.nrw.commons.auth.SessionManager;
2528
import fr.free.nrw.commons.di.ApplicationlessInjection;
2629
import fr.free.nrw.commons.mwapi.MediaWikiApi;
30+
import fr.free.nrw.commons.review.ReviewActivity;
2731
import timber.log.Timber;
2832

2933
import static androidx.core.app.NotificationCompat.DEFAULT_ALL;
@@ -63,7 +67,7 @@ protected void onPreExecute() {
6367
.setOnlyAlertOnce(true);
6468
Toast toast = new Toast(context);
6569
toast.setGravity(Gravity.CENTER,0,0);
66-
toast = Toast.makeText(context,"Trying to nominate "+media.getDisplayTitle()+ " for deletion",Toast.LENGTH_SHORT);
70+
toast = Toast.makeText(context,"Trying to nominate "+media.getDisplayTitle()+ " for deletion", Toast.LENGTH_SHORT);
6771
toast.show();
6872
}
6973

@@ -73,7 +77,7 @@ protected Boolean doInBackground(Void ...voids) {
7377

7478
String editToken;
7579
String authCookie;
76-
String summary = "Nominating " + media.getFilename() +" for deletion.";
80+
String summary = context.getString(R.string.nominating_file_for_deletion, media.getFilename());
7781

7882
authCookie = sessionManager.getAuthCookie();
7983
mwApi.setAuthCookie(authCookie);
@@ -106,15 +110,15 @@ protected Boolean doInBackground(Void ...voids) {
106110
publishProgress(1);
107111

108112
mwApi.prependEdit(editToken,fileDeleteString+"\n",
109-
media.getFilename(),summary);
113+
media.getFilename(), summary);
110114
publishProgress(2);
111115

112116
mwApi.edit(editToken,subpageString+"\n",
113-
"Commons:Deletion_requests/"+media.getFilename(),summary);
117+
"Commons:Deletion_requests/"+media.getFilename(), summary);
114118
publishProgress(3);
115119

116120
mwApi.appendEdit(editToken,logPageString+"\n",
117-
"Commons:Deletion_requests/"+date,summary);
121+
"Commons:Deletion_requests/"+date, summary);
118122
publishProgress(4);
119123

120124
mwApi.appendEdit(editToken,userPageString+"\n",
@@ -132,29 +136,21 @@ protected Boolean doInBackground(Void ...voids) {
132136
protected void onProgressUpdate (Integer... values){
133137
super.onProgressUpdate(values);
134138

139+
int[] messages = new int[]{
140+
R.string.getting_edit_token,
141+
R.string.nominate_for_deletion_edit_file_page,
142+
R.string.nominate_for_deletion_create_deletion_request,
143+
R.string.nominate_for_deletion_edit_deletion_request_log,
144+
R.string.nominate_for_deletion_notify_user,
145+
R.string.nominate_for_deletion_done
146+
};
147+
135148
String message = "";
136-
switch (values[0]){
137-
case 0:
138-
message = "Getting token";
139-
break;
140-
case 1:
141-
message = "Adding delete message to file";
142-
break;
143-
case 2:
144-
message = "Creating Delete requests sub-page";
145-
break;
146-
case 3:
147-
message = "Adding file to Delete requests log";
148-
break;
149-
case 4:
150-
message = "Notifying User on Talk page";
151-
break;
152-
case 5:
153-
message = "Done";
154-
break;
149+
if (0 < values[0] && values[0] < messages.length) {
150+
message = context.getString(messages[values[0]]);
155151
}
156152

157-
notificationBuilder.setContentTitle("Nominating "+media.getDisplayTitle()+" for deletion")
153+
notificationBuilder.setContentTitle(context.getString(R.string.nominating_file_for_deletion, media.getFilename()))
158154
.setStyle(new NotificationCompat.BigTextStyle()
159155
.bigText(message))
160156
.setSmallIcon(R.drawable.ic_launcher)
@@ -170,7 +166,7 @@ protected void onPostExecute(Boolean result) {
170166

171167
if (result){
172168
title += ": Success";
173-
message = "Successfully nominated " + media.getDisplayTitle() + " deletion.";
169+
message = "Successfully nominated " + media.getDisplayTitle() + " for deletion.";
174170
}
175171
else {
176172
title += ": Failed";
@@ -191,4 +187,111 @@ protected void onPostExecute(Boolean result) {
191187
notificationBuilder.setContentIntent(pendingIntent);
192188
notificationManager.notify(NOTIFICATION_DELETE, notificationBuilder.build());
193189
}
190+
191+
// TODO: refactor; see MediaDetailsFragment.onDeleteButtonClicked
192+
// ReviewActivity will use this
193+
public static void askReasonAndExecute(Media media, Context context, String question, String problem) {
194+
AlertDialog.Builder alert = new AlertDialog.Builder(context);
195+
alert.setTitle(question);
196+
197+
boolean[] checkedItems = {false , false, false, false};
198+
ArrayList<Integer> mUserReason = new ArrayList<>();
199+
200+
String[] reasonList= {"Reason 1","Reason 2","Reason 3","Reason 4"};
201+
202+
203+
if(problem.equals("spam")){
204+
reasonList[0] = "A selfie";
205+
reasonList[1] = "Blurry";
206+
reasonList[2] = "Nonsense";
207+
reasonList[3] = "Other";
208+
}
209+
else if(problem.equals("copyRightViolation")){
210+
reasonList[0] = "Press photo";
211+
reasonList[1] = "Random photo from internet";
212+
reasonList[2] = "Logo";
213+
reasonList[3] = "Other";
214+
}
215+
216+
alert.setMultiChoiceItems(reasonList, checkedItems, new DialogInterface.OnMultiChoiceClickListener() {
217+
@Override
218+
public void onClick(DialogInterface dialogInterface, int position, boolean isChecked) {
219+
if(isChecked){
220+
mUserReason.add(position);
221+
}else{
222+
mUserReason.remove((Integer.valueOf(position)));
223+
}
224+
}
225+
});
226+
227+
alert.setPositiveButton("OK", new DialogInterface.OnClickListener() {
228+
@Override
229+
public void onClick(DialogInterface dialogInterface, int i) {
230+
231+
String reason = "Because it is ";
232+
for (int j = 0; j < mUserReason.size(); j++) {
233+
reason = reason + reasonList[mUserReason.get(j)];
234+
if (j != mUserReason.size() - 1) {
235+
reason = reason + ", ";
236+
}
237+
}
238+
239+
((ReviewActivity)context).reviewController.swipeToNext();
240+
((ReviewActivity)context).runRandomizer();
241+
242+
DeleteTask deleteTask = new DeleteTask(context, media, reason);
243+
deleteTask.execute();
244+
}
245+
});
246+
alert.setNegativeButton("Cancel" , null);
247+
248+
249+
AlertDialog d = alert.create();
250+
d.show();
251+
252+
// AlertDialog.Builder alert = new AlertDialog.Builder(context);
253+
// alert.setMessage(question);
254+
// final EditText input = ne
255+
// w EditText(context);
256+
// input.setText(defaultValue);
257+
// alert.setView(input);
258+
// input.requestFocus();
259+
// alert.setPositiveButton(R.string.ok, (dialog, whichButton) -> {
260+
// String reason = input.getText().toString();
261+
//
262+
// ((ReviewActivity)context).reviewController.swipeToNext();
263+
// ((ReviewActivity)context).runRandomizer();
264+
//
265+
// DeleteTask deleteTask = new DeleteTask(context, media, reason);
266+
// deleteTask.execute();
267+
// });
268+
// alert.setNegativeButton(R.string.cancel, (dialog, whichButton) -> {
269+
// });
270+
// AlertDialog d = alert.create();
271+
// input.addTextChangedListener(new TextWatcher() {
272+
// private void handleText() {
273+
// final Button okButton = d.getButton(AlertDialog.BUTTON_POSITIVE);
274+
// if (input.getText().length() == 0) {
275+
// okButton.setEnabled(false);
276+
// } else {
277+
// okButton.setEnabled(true);
278+
// }
279+
// }
280+
//
281+
// @Override
282+
// public void afterTextChanged(Editable arg0) {
283+
// handleText();
284+
// }
285+
//
286+
// @Override
287+
// public void beforeTextChanged(CharSequence s, int start, int count, int after) {
288+
// }
289+
//
290+
// @Override
291+
// public void onTextChanged(CharSequence s, int start, int before, int count) {
292+
// }
293+
// });
294+
// d.show();
295+
// d.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(defaultValue.length() > 0);
296+
}
194297
}

app/src/main/java/fr/free/nrw/commons/di/ActivityBuilderModule.java

+4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import fr.free.nrw.commons.explore.categories.ExploreActivity;
1717
import fr.free.nrw.commons.notification.NotificationActivity;
18+
import fr.free.nrw.commons.review.ReviewActivity;
1819
import fr.free.nrw.commons.settings.SettingsActivity;
1920
import fr.free.nrw.commons.upload.UploadActivity;
2021

@@ -64,4 +65,7 @@ public abstract class ActivityBuilderModule {
6465
@ContributesAndroidInjector
6566
abstract BookmarksActivity bindBookmarksActivity();
6667

68+
69+
@ContributesAndroidInjector
70+
abstract ReviewActivity bindReviewActivity();
6771
}

app/src/main/java/fr/free/nrw/commons/di/CommonsApplicationComponent.java

+7
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
import fr.free.nrw.commons.contributions.ContributionsSyncAdapter;
1313
import fr.free.nrw.commons.delete.DeleteTask;
1414
import fr.free.nrw.commons.modifications.ModificationsSyncAdapter;
15+
import fr.free.nrw.commons.review.CheckCategoryTask;
16+
import fr.free.nrw.commons.review.SendThankTask;
17+
import fr.free.nrw.commons.settings.SettingsFragment;
1518
import fr.free.nrw.commons.nearby.PlaceRenderer;
1619
import fr.free.nrw.commons.settings.SettingsFragment;
1720
import fr.free.nrw.commons.upload.FileProcessor;
@@ -42,6 +45,10 @@ public interface CommonsApplicationComponent extends AndroidInjector<Application
4245

4346
void inject(DeleteTask deleteTask);
4447

48+
void inject(CheckCategoryTask checkCategoryTask);
49+
50+
void inject(SendThankTask sendThankTask);
51+
4552
void inject(SettingsFragment fragment);
4653

4754
@Override

app/src/main/java/fr/free/nrw/commons/di/FragmentBuilderModule.java

+4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import fr.free.nrw.commons.nearby.NearbyFragment;
1717
import fr.free.nrw.commons.nearby.NearbyListFragment;
1818
import fr.free.nrw.commons.nearby.NearbyMapFragment;
19+
import fr.free.nrw.commons.review.ReviewImageFragment;
1920
import fr.free.nrw.commons.settings.SettingsFragment;
2021

2122
@Module
@@ -67,4 +68,7 @@ public abstract class FragmentBuilderModule {
6768
@ContributesAndroidInjector
6869
abstract BookmarkLocationsFragment bindBookmarkLocationListFragment();
6970

71+
@ContributesAndroidInjector
72+
abstract ReviewImageFragment bindReviewOutOfContextFragment();
73+
7074
}

0 commit comments

Comments
 (0)