mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-27 12:53:55 +01:00
parent
01cb9ccd70
commit
32d36944fc
28 changed files with 45 additions and 1086 deletions
|
|
@ -96,10 +96,6 @@
|
||||||
android:label="@string/title_activity_featured_images"
|
android:label="@string/title_activity_featured_images"
|
||||||
android:parentActivityName=".contributions.ContributionsActivity" />
|
android:parentActivityName=".contributions.ContributionsActivity" />
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".review.ReviewActivity"
|
|
||||||
android:label="@string/title_activity_review" />
|
|
||||||
|
|
||||||
<service android:name=".upload.UploadService" />
|
<service android:name=".upload.UploadService" />
|
||||||
|
|
||||||
<service
|
<service
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import javax.xml.parsers.ParserConfigurationException;
|
||||||
import fr.free.nrw.commons.location.LatLng;
|
import fr.free.nrw.commons.location.LatLng;
|
||||||
import fr.free.nrw.commons.mwapi.MediaResult;
|
import fr.free.nrw.commons.mwapi.MediaResult;
|
||||||
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
||||||
import fr.free.nrw.commons.utils.MediaDataExtractorUtil;
|
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -72,13 +71,28 @@ public class MediaDataExtractor {
|
||||||
MediaResult result = mediaWikiApi.fetchMediaByFilename(filename);
|
MediaResult result = mediaWikiApi.fetchMediaByFilename(filename);
|
||||||
|
|
||||||
// In-page category links are extracted from source, as XML doesn't cover [[links]]
|
// In-page category links are extracted from source, as XML doesn't cover [[links]]
|
||||||
categories = MediaDataExtractorUtil.extractCategories(result.getWikiSource());
|
extractCategories(result.getWikiSource());
|
||||||
|
|
||||||
// Description template info is extracted from preprocessor XML
|
// Description template info is extracted from preprocessor XML
|
||||||
processWikiParseTree(result.getParseTreeXmlSource(), licenseList);
|
processWikiParseTree(result.getParseTreeXmlSource(), licenseList);
|
||||||
fetched = true;
|
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 {
|
private void processWikiParseTree(String source, LicenseList licenseList) throws IOException {
|
||||||
Document doc;
|
Document doc;
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ public class DeleteTask extends AsyncTask<Void, Integer, Boolean> {
|
||||||
notificationBuilder = new NotificationCompat.Builder(context);
|
notificationBuilder = new NotificationCompat.Builder(context);
|
||||||
Toast toast = new Toast(context);
|
Toast toast = new Toast(context);
|
||||||
toast.setGravity(Gravity.CENTER,0,0);
|
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();
|
toast.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -64,7 +64,7 @@ public class DeleteTask extends AsyncTask<Void, Integer, Boolean> {
|
||||||
|
|
||||||
String editToken;
|
String editToken;
|
||||||
String authCookie;
|
String authCookie;
|
||||||
String summary = context.getString(R.string.nominating_file_for_deletion, media.getFilename());
|
String summary = "Nominating " + media.getFilename() +" for deletion.";
|
||||||
|
|
||||||
authCookie = sessionManager.getAuthCookie();
|
authCookie = sessionManager.getAuthCookie();
|
||||||
mwApi.setAuthCookie(authCookie);
|
mwApi.setAuthCookie(authCookie);
|
||||||
|
|
@ -97,19 +97,19 @@ public class DeleteTask extends AsyncTask<Void, Integer, Boolean> {
|
||||||
publishProgress(1);
|
publishProgress(1);
|
||||||
|
|
||||||
mwApi.prependEdit(editToken,fileDeleteString+"\n",
|
mwApi.prependEdit(editToken,fileDeleteString+"\n",
|
||||||
media.getFilename(), summary);
|
media.getFilename(),summary);
|
||||||
publishProgress(2);
|
publishProgress(2);
|
||||||
|
|
||||||
mwApi.edit(editToken,subpageString+"\n",
|
mwApi.edit(editToken,subpageString+"\n",
|
||||||
"Commons:Deletion_requests/"+media.getFilename(), summary);
|
"Commons:Deletion_requests/"+media.getFilename(),summary);
|
||||||
publishProgress(3);
|
publishProgress(3);
|
||||||
|
|
||||||
mwApi.appendEdit(editToken,logPageString+"\n",
|
mwApi.appendEdit(editToken,logPageString+"\n",
|
||||||
"Commons:Deletion_requests/"+date, summary);
|
"Commons:Deletion_requests/"+date,summary);
|
||||||
publishProgress(4);
|
publishProgress(4);
|
||||||
|
|
||||||
mwApi.appendEdit(editToken,userPageString+"\n",
|
mwApi.appendEdit(editToken,userPageString+"\n",
|
||||||
"User_Talk:"+sessionManager.getCurrentAccount().name, summary);
|
"User_Talk:"+sessionManager.getCurrentAccount().name,summary);
|
||||||
publishProgress(5);
|
publishProgress(5);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
|
|
@ -123,21 +123,29 @@ public class DeleteTask extends AsyncTask<Void, Integer, Boolean> {
|
||||||
protected void onProgressUpdate (Integer... values){
|
protected void onProgressUpdate (Integer... values){
|
||||||
super.onProgressUpdate(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 = "";
|
String message = "";
|
||||||
if (0 < values[0] && values[0] < messages.length) {
|
switch (values[0]){
|
||||||
message = context.getString(messages[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;
|
||||||
}
|
}
|
||||||
|
|
||||||
notificationBuilder.setContentTitle(context.getString(R.string.nominating_file_for_deletion, media.getFilename()))
|
notificationBuilder.setContentTitle("Nominating "+media.getDisplayTitle()+" for deletion")
|
||||||
.setStyle(new NotificationCompat.BigTextStyle()
|
.setStyle(new NotificationCompat.BigTextStyle()
|
||||||
.bigText(message))
|
.bigText(message))
|
||||||
.setSmallIcon(R.drawable.ic_launcher)
|
.setSmallIcon(R.drawable.ic_launcher)
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import fr.free.nrw.commons.contributions.ContributionsActivity;
|
||||||
import fr.free.nrw.commons.category.CategoryImagesActivity;
|
import fr.free.nrw.commons.category.CategoryImagesActivity;
|
||||||
import fr.free.nrw.commons.nearby.NearbyActivity;
|
import fr.free.nrw.commons.nearby.NearbyActivity;
|
||||||
import fr.free.nrw.commons.notification.NotificationActivity;
|
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.settings.SettingsActivity;
|
||||||
import fr.free.nrw.commons.upload.MultipleShareActivity;
|
import fr.free.nrw.commons.upload.MultipleShareActivity;
|
||||||
import fr.free.nrw.commons.upload.ShareActivity;
|
import fr.free.nrw.commons.upload.ShareActivity;
|
||||||
|
|
@ -51,7 +50,4 @@ public abstract class ActivityBuilderModule {
|
||||||
|
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
abstract CategoryImagesActivity bindFeaturedImagesActivity();
|
abstract CategoryImagesActivity bindFeaturedImagesActivity();
|
||||||
|
|
||||||
@ContributesAndroidInjector
|
|
||||||
abstract ReviewActivity bindReviewActivity();
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,11 +9,11 @@ import dagger.android.support.AndroidSupportInjectionModule;
|
||||||
import fr.free.nrw.commons.CommonsApplication;
|
import fr.free.nrw.commons.CommonsApplication;
|
||||||
import fr.free.nrw.commons.MediaWikiImageView;
|
import fr.free.nrw.commons.MediaWikiImageView;
|
||||||
import fr.free.nrw.commons.auth.LoginActivity;
|
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.contributions.ContributionsSyncAdapter;
|
||||||
import fr.free.nrw.commons.delete.DeleteTask;
|
import fr.free.nrw.commons.delete.DeleteTask;
|
||||||
import fr.free.nrw.commons.modifications.ModificationsSyncAdapter;
|
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.settings.SettingsFragment;
|
||||||
import fr.free.nrw.commons.nearby.PlaceRenderer;
|
import fr.free.nrw.commons.nearby.PlaceRenderer;
|
||||||
|
|
||||||
|
|
@ -40,10 +40,6 @@ public interface CommonsApplicationComponent extends AndroidInjector<Application
|
||||||
|
|
||||||
void inject(DeleteTask deleteTask);
|
void inject(DeleteTask deleteTask);
|
||||||
|
|
||||||
void inject(CheckCategoryTask checkCategoryTask);
|
|
||||||
|
|
||||||
void inject(SendThankTask sendThankTask);
|
|
||||||
|
|
||||||
void inject(SettingsFragment fragment);
|
void inject(SettingsFragment fragment);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import fr.free.nrw.commons.media.MediaDetailPagerFragment;
|
||||||
import fr.free.nrw.commons.nearby.NearbyListFragment;
|
import fr.free.nrw.commons.nearby.NearbyListFragment;
|
||||||
import fr.free.nrw.commons.nearby.NearbyMapFragment;
|
import fr.free.nrw.commons.nearby.NearbyMapFragment;
|
||||||
import fr.free.nrw.commons.nearby.NoPermissionsFragment;
|
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.settings.SettingsFragment;
|
||||||
import fr.free.nrw.commons.upload.MultipleUploadListFragment;
|
import fr.free.nrw.commons.upload.MultipleUploadListFragment;
|
||||||
import fr.free.nrw.commons.upload.SingleUploadFragment;
|
import fr.free.nrw.commons.upload.SingleUploadFragment;
|
||||||
|
|
@ -52,7 +51,4 @@ public abstract class FragmentBuilderModule {
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
abstract CategoryImagesListFragment bindFeaturedImagesListFragment();
|
abstract CategoryImagesListFragment bindFeaturedImagesListFragment();
|
||||||
|
|
||||||
@ContributesAndroidInjector
|
|
||||||
abstract ReviewImageFragment bindReviewOutOfContextFragment();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,12 +46,7 @@ import fr.free.nrw.commons.delete.DeleteTask;
|
||||||
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;
|
||||||
import fr.free.nrw.commons.review.CheckCategoryTask;
|
|
||||||
import fr.free.nrw.commons.review.SendThankTask;
|
|
||||||
import fr.free.nrw.commons.ui.widget.CompatTextView;
|
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 timber.log.Timber;
|
||||||
|
|
||||||
import static android.view.View.GONE;
|
import static android.view.View.GONE;
|
||||||
|
|
@ -362,7 +357,6 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
||||||
alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
|
alert.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int whichButton) {
|
public void onClick(DialogInterface dialog, int whichButton) {
|
||||||
String reason = input.getText().toString();
|
String reason = input.getText().toString();
|
||||||
|
|
||||||
DeleteTask deleteTask = new DeleteTask(getActivity(), media, reason);
|
DeleteTask deleteTask = new DeleteTask(getActivity(), media, reason);
|
||||||
deleteTask.execute();
|
deleteTask.execute();
|
||||||
enableDeleteButton(false);
|
enableDeleteButton(false);
|
||||||
|
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
package fr.free.nrw.commons.media;
|
|
||||||
|
|
||||||
import org.w3c.dom.Element;
|
|
||||||
import org.w3c.dom.NodeList;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
public class RecentChangesImageUtils {
|
|
||||||
|
|
||||||
private static final String[] imageExtensions = new String[]
|
|
||||||
{".jpg", ".jpeg", ".png"};
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static String findImageInRecentChanges(NodeList childNodes) {
|
|
||||||
String imageTitle;
|
|
||||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
|
||||||
Element e = (Element)childNodes.item(i);
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
imageTitle = e.getAttribute("title");
|
|
||||||
|
|
||||||
for (String imageExtension : imageExtensions) {
|
|
||||||
if (imageTitle.toLowerCase().endsWith(imageExtension)) {
|
|
||||||
return imageTitle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -38,14 +38,12 @@ import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.Random;
|
|
||||||
|
|
||||||
import fr.free.nrw.commons.BuildConfig;
|
import fr.free.nrw.commons.BuildConfig;
|
||||||
import fr.free.nrw.commons.Media;
|
import fr.free.nrw.commons.Media;
|
||||||
import fr.free.nrw.commons.PageTitle;
|
import fr.free.nrw.commons.PageTitle;
|
||||||
import fr.free.nrw.commons.category.CategoryImageUtils;
|
import fr.free.nrw.commons.category.CategoryImageUtils;
|
||||||
import fr.free.nrw.commons.category.QueryContinue;
|
import fr.free.nrw.commons.category.QueryContinue;
|
||||||
import fr.free.nrw.commons.media.RecentChangesImageUtils;
|
|
||||||
import fr.free.nrw.commons.notification.Notification;
|
import fr.free.nrw.commons.notification.Notification;
|
||||||
import fr.free.nrw.commons.notification.NotificationUtils;
|
import fr.free.nrw.commons.notification.NotificationUtils;
|
||||||
import in.yuvi.http.fluent.Http;
|
import in.yuvi.http.fluent.Http;
|
||||||
|
|
@ -62,14 +60,6 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
|
||||||
private String wikiMediaToolforgeUrl = "https://tools.wmflabs.org/";
|
private String wikiMediaToolforgeUrl = "https://tools.wmflabs.org/";
|
||||||
|
|
||||||
private static final String THUMB_SIZE = "640";
|
private static final String THUMB_SIZE = "640";
|
||||||
// Give up if no random recent image found after 5 tries
|
|
||||||
private static final int MAX_RANDOM_TRIES = 5;
|
|
||||||
// Random image request is for some time in the past 30 days
|
|
||||||
private static final int RANDOM_SECONDS = 60 * 60 * 24 * 30;
|
|
||||||
// Assuming MW always gives me UTC
|
|
||||||
private static final SimpleDateFormat isoFormat =
|
|
||||||
new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH);
|
|
||||||
private static final String FILE_NAMESPACE = "6";
|
|
||||||
private AbstractHttpClient httpClient;
|
private AbstractHttpClient httpClient;
|
||||||
private MWApi api;
|
private MWApi api;
|
||||||
private Context context;
|
private Context context;
|
||||||
|
|
@ -233,19 +223,6 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
|
||||||
.getString("/api/query/pages/page/@_idx")) != -1;
|
.getString("/api/query/pages/page/@_idx")) != -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean thank(String editToken, String revision) throws IOException {
|
|
||||||
ApiResult res = api.action("thank")
|
|
||||||
.param("rev", revision)
|
|
||||||
.param("token", editToken)
|
|
||||||
.param("source", getUserAgent())
|
|
||||||
.post();
|
|
||||||
String r = res.getString("/api/result/@success");
|
|
||||||
// Does this correctly check the success/failure?
|
|
||||||
// The docs https://www.mediawiki.org/wiki/Extension:Thanks seems unclear about that.
|
|
||||||
return r.equals("success");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public String edit(String editToken, String processedPageContent, String filename, String summary) throws IOException {
|
public String edit(String editToken, String processedPageContent, String filename, String summary) throws IOException {
|
||||||
|
|
@ -458,20 +435,6 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
|
||||||
.getString("/api/query/pages/page/revisions/rev");
|
.getString("/api/query/pages/page/revisions/rev");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public String firstRevisionOfFile(String filename) throws IOException {
|
|
||||||
String res = api.action("query")
|
|
||||||
.param("prop", "revisions")
|
|
||||||
.param("rvprop", "timestamp|ids")
|
|
||||||
.param("titles", filename)
|
|
||||||
.param("rvdir", "newer")
|
|
||||||
.param("rvlimit", "1")
|
|
||||||
.get()
|
|
||||||
.getString("/api/query/pages/page/revisions/rev/@revid");
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NonNull
|
@NonNull
|
||||||
public List<Notification> getNotifications() {
|
public List<Notification> getNotifications() {
|
||||||
|
|
@ -653,59 +616,11 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Date parseMWDate(String mwDate) {
|
private Date parseMWDate(String mwDate) {
|
||||||
|
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.ENGLISH); // Assuming MW always gives me UTC
|
||||||
try {
|
try {
|
||||||
return isoFormat.parse(mwDate);
|
return isoFormat.parse(mwDate);
|
||||||
} catch (ParseException e) {
|
} catch (ParseException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String formatMWDate(Date date) {
|
|
||||||
return isoFormat.format(date);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Media getRecentRandomImage() throws IOException {
|
|
||||||
Media media = null;
|
|
||||||
int tries = 0;
|
|
||||||
Random r = new Random();
|
|
||||||
|
|
||||||
while (media == null && tries < MAX_RANDOM_TRIES) {
|
|
||||||
Date now = new Date();
|
|
||||||
Date startDate = new Date(now.getTime() - r.nextInt(RANDOM_SECONDS) * 1000L);
|
|
||||||
ApiResult apiResult = null;
|
|
||||||
try {
|
|
||||||
MWApi.RequestBuilder requestBuilder = api.action("query")
|
|
||||||
.param("list", "recentchanges")
|
|
||||||
.param("rcstart", formatMWDate(startDate))
|
|
||||||
.param("rcnamespace", FILE_NAMESPACE)
|
|
||||||
.param("rcprop", "title|ids")
|
|
||||||
.param("rctype", "new|log")
|
|
||||||
.param("rctoponly", "1");
|
|
||||||
|
|
||||||
apiResult = requestBuilder.get();
|
|
||||||
} catch (IOException e) {
|
|
||||||
Timber.e("Failed to obtain recent random", e);
|
|
||||||
}
|
|
||||||
if (apiResult != null) {
|
|
||||||
ApiResult recentChangesNode = apiResult.getNode("/api/query/recentchanges");
|
|
||||||
if (recentChangesNode != null
|
|
||||||
&& recentChangesNode.getDocument() != null
|
|
||||||
&& recentChangesNode.getDocument().getChildNodes() != null
|
|
||||||
&& recentChangesNode.getDocument().getChildNodes().getLength() > 0) {
|
|
||||||
NodeList childNodes = recentChangesNode.getDocument().getChildNodes();
|
|
||||||
String imageTitle = RecentChangesImageUtils.findImageInRecentChanges(childNodes);
|
|
||||||
if (imageTitle != null) {
|
|
||||||
boolean deletionStatus = pageExists("Commons:Deletion_requests/" + imageTitle);
|
|
||||||
if (!deletionStatus) {
|
|
||||||
// strip File: prefix
|
|
||||||
imageTitle = imageTitle.replace("File:", "");
|
|
||||||
media = new Media(imageTitle);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tries++;
|
|
||||||
}
|
|
||||||
return media;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -75,14 +75,7 @@ public interface MediaWikiApi {
|
||||||
@NonNull
|
@NonNull
|
||||||
Single<Integer> getUploadCount(String userName);
|
Single<Integer> getUploadCount(String userName);
|
||||||
|
|
||||||
boolean thank(String editToken, String revision) throws IOException;
|
|
||||||
|
|
||||||
String firstRevisionOfFile(String filename) throws IOException;
|
|
||||||
|
|
||||||
interface ProgressListener {
|
interface ProgressListener {
|
||||||
void onProgress(long transferred, long total);
|
void onProgress(long transferred, long total);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
Media getRecentRandomImage() throws IOException;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,130 +0,0 @@
|
||||||
package fr.free.nrw.commons.review;
|
|
||||||
|
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.support.v4.app.NotificationCompat;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
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 timber.log.Timber;
|
|
||||||
|
|
||||||
import static android.support.v4.app.NotificationCompat.DEFAULT_ALL;
|
|
||||||
import static android.support.v4.app.NotificationCompat.PRIORITY_HIGH;
|
|
||||||
|
|
||||||
// Example code:
|
|
||||||
// CheckCategoryTask deleteTask = new CheckCategoryTask(getActivity(), media);
|
|
||||||
|
|
||||||
public class CheckCategoryTask extends AsyncTask<Void, Integer, Boolean> {
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
MediaWikiApi mwApi;
|
|
||||||
@Inject
|
|
||||||
SessionManager sessionManager;
|
|
||||||
|
|
||||||
public static final int NOTIFICATION_CHECK_CATEGORY = 0x101;
|
|
||||||
|
|
||||||
private NotificationManager notificationManager;
|
|
||||||
private NotificationCompat.Builder notificationBuilder;
|
|
||||||
private Context context;
|
|
||||||
private Media media;
|
|
||||||
|
|
||||||
public CheckCategoryTask(Context context, Media media){
|
|
||||||
this.context = context;
|
|
||||||
this.media = media;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPreExecute(){
|
|
||||||
ApplicationlessInjection
|
|
||||||
.getInstance(context.getApplicationContext())
|
|
||||||
.getCommonsApplicationComponent()
|
|
||||||
.inject(this);
|
|
||||||
|
|
||||||
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
||||||
notificationBuilder = new NotificationCompat.Builder(context);
|
|
||||||
Toast toast = new Toast(context);
|
|
||||||
toast.setGravity(Gravity.CENTER,0,0);
|
|
||||||
toast = Toast.makeText(context, context.getString(R.string.check_category_toast, media.getDisplayTitle()), Toast.LENGTH_SHORT);
|
|
||||||
toast.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Boolean doInBackground(Void ...voids) {
|
|
||||||
publishProgress(0);
|
|
||||||
|
|
||||||
String editToken;
|
|
||||||
String authCookie;
|
|
||||||
String summary = context.getString(R.string.check_category_edit_summary);
|
|
||||||
|
|
||||||
authCookie = sessionManager.getAuthCookie();
|
|
||||||
mwApi.setAuthCookie(authCookie);
|
|
||||||
|
|
||||||
try {
|
|
||||||
editToken = mwApi.getEditToken();
|
|
||||||
if (editToken.equals("+\\")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
publishProgress(1);
|
|
||||||
|
|
||||||
mwApi.appendEdit(editToken, "\n{{subst:chc}}\n", media.getFilename(), summary);
|
|
||||||
publishProgress(2);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
Timber.d(e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onProgressUpdate (Integer... values){
|
|
||||||
super.onProgressUpdate(values);
|
|
||||||
|
|
||||||
int[] messages = new int[]{R.string.getting_edit_token, R.string.check_category_adding_template};
|
|
||||||
String message = "";
|
|
||||||
if (0 < values[0] && values[0] < messages.length) {
|
|
||||||
message = context.getString(messages[values[0]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
notificationBuilder.setContentTitle(context.getString(R.string.check_category_notification_title, media.getDisplayTitle()))
|
|
||||||
.setStyle(new NotificationCompat.BigTextStyle()
|
|
||||||
.bigText(message))
|
|
||||||
.setSmallIcon(R.drawable.ic_launcher)
|
|
||||||
.setProgress(messages.length, values[0], false)
|
|
||||||
.setOngoing(true);
|
|
||||||
notificationManager.notify(NOTIFICATION_CHECK_CATEGORY, notificationBuilder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Boolean result) {
|
|
||||||
String message = "";
|
|
||||||
String title = "";
|
|
||||||
|
|
||||||
if (result){
|
|
||||||
title = context.getString(R.string.check_category_success_title);
|
|
||||||
message = context.getString(R.string.check_category_success_message, media.getDisplayTitle());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
title = context.getString(R.string.check_category_failure_title);
|
|
||||||
message = context.getString(R.string.check_category_failure_message, media.getDisplayTitle());
|
|
||||||
}
|
|
||||||
|
|
||||||
notificationBuilder.setDefaults(DEFAULT_ALL)
|
|
||||||
.setContentTitle(title)
|
|
||||||
.setStyle(new NotificationCompat.BigTextStyle()
|
|
||||||
.bigText(message))
|
|
||||||
.setSmallIcon(R.drawable.ic_launcher)
|
|
||||||
.setProgress(0,0,false)
|
|
||||||
.setOngoing(false)
|
|
||||||
.setPriority(PRIORITY_HIGH);
|
|
||||||
notificationManager.notify(NOTIFICATION_CHECK_CATEGORY, notificationBuilder.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,173 +0,0 @@
|
||||||
package fr.free.nrw.commons.review;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import android.os.Handler;
|
|
||||||
import android.support.design.widget.NavigationView;
|
|
||||||
import android.support.v4.view.ViewPager;
|
|
||||||
import android.support.v4.widget.DrawerLayout;
|
|
||||||
import android.support.v7.widget.Toolbar;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
|
||||||
import android.widget.EditText;
|
|
||||||
|
|
||||||
import com.viewpagerindicator.CirclePageIndicator;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import butterknife.BindView;
|
|
||||||
import butterknife.ButterKnife;
|
|
||||||
import fr.free.nrw.commons.Media;
|
|
||||||
import fr.free.nrw.commons.R;
|
|
||||||
import fr.free.nrw.commons.Utils;
|
|
||||||
import fr.free.nrw.commons.auth.AuthenticatedActivity;
|
|
||||||
import fr.free.nrw.commons.mwapi.MediaResult;
|
|
||||||
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
|
||||||
import fr.free.nrw.commons.utils.MediaDataExtractorUtil;
|
|
||||||
import io.reactivex.Observable;
|
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
|
||||||
import io.reactivex.schedulers.Schedulers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by root on 18.05.2018.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class ReviewActivity extends AuthenticatedActivity {
|
|
||||||
|
|
||||||
@BindView(R.id.toolbar)
|
|
||||||
Toolbar toolbar;
|
|
||||||
@BindView(R.id.navigation_view)
|
|
||||||
NavigationView navigationView;
|
|
||||||
@BindView(R.id.drawer_layout)
|
|
||||||
DrawerLayout drawerLayout;
|
|
||||||
|
|
||||||
@BindView(R.id.reviewPager)
|
|
||||||
ViewPager pager;
|
|
||||||
|
|
||||||
@Inject MediaWikiApi mwApi;
|
|
||||||
|
|
||||||
private ReviewPagerAdapter reviewPagerAdapter;
|
|
||||||
|
|
||||||
//private ReviewCallback reviewCallback;
|
|
||||||
private ReviewController reviewController;
|
|
||||||
|
|
||||||
@BindView(R.id.reviewPagerIndicator)
|
|
||||||
public CirclePageIndicator pagerIndicator;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onAuthCookieAcquired(String authCookie) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onAuthFailure() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
setContentView(R.layout.activity_review);
|
|
||||||
ButterKnife.bind(this);
|
|
||||||
initDrawer();
|
|
||||||
|
|
||||||
reviewController = new ReviewController();
|
|
||||||
|
|
||||||
|
|
||||||
reviewPagerAdapter = new ReviewPagerAdapter(getSupportFragmentManager());
|
|
||||||
pager.setAdapter(reviewPagerAdapter);
|
|
||||||
reviewPagerAdapter.getItem(0);
|
|
||||||
pagerIndicator.setViewPager(pager);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
|
||||||
getMenuInflater().inflate(R.menu.review_randomizer_menu, menu);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
int id = item.getItemId();
|
|
||||||
|
|
||||||
if (id == R.id.action_review_randomizer) {
|
|
||||||
Observable.fromCallable(() -> {
|
|
||||||
Media result = null;
|
|
||||||
try {
|
|
||||||
result = mwApi.getRecentRandomImage();
|
|
||||||
|
|
||||||
//String thumBaseUrl = Utils.makeThumbBaseUrl(result.getFilename());
|
|
||||||
//reviewPagerAdapter.currentThumbBasedUrl = thumBaseUrl;
|
|
||||||
|
|
||||||
//Log.d("review", result.getWikiSource());
|
|
||||||
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.d("review", e.toString());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
})
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(this::updateImage);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateImage(Media result) {
|
|
||||||
reviewController.onImageRefreshed(result.getFilename()); //file name is updated
|
|
||||||
reviewPagerAdapter.updateFilename();
|
|
||||||
pager.setCurrentItem(0);
|
|
||||||
Observable.fromCallable(() -> {
|
|
||||||
MediaResult media = mwApi.fetchMediaByFilename("File:" + result.getFilename());
|
|
||||||
return MediaDataExtractorUtil.extractCategories(media.getWikiSource());
|
|
||||||
})
|
|
||||||
.subscribeOn(Schedulers.io())
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.subscribe(this::updateCategories);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateCategories(ArrayList<String> categories) {
|
|
||||||
reviewController.onCategoriesRefreshed(categories);
|
|
||||||
reviewPagerAdapter.updateCategories();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* References ReviewPagerAdapter to null before the activity is destroyed
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void onDestroy() {
|
|
||||||
//adapter.setCallback(null);
|
|
||||||
super.onDestroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Consumers should be simply using this method to use this activity.
|
|
||||||
* @param context
|
|
||||||
* @param title Page title
|
|
||||||
*/
|
|
||||||
public static void startYourself(Context context, String title) {
|
|
||||||
Intent reviewActivity = new Intent(context, ReviewActivity.class);
|
|
||||||
context.startActivity(reviewActivity);
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ReviewCallback {
|
|
||||||
void onImageRefreshed(String itemTitle);
|
|
||||||
void onQuestionChanged();
|
|
||||||
void onSurveyFinished();
|
|
||||||
void onImproperImageReported();
|
|
||||||
void onLicenceViolationReported();
|
|
||||||
void onWrongCategoryReported();
|
|
||||||
void onThankSent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
package fr.free.nrw.commons.review;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by root on 19.05.2018.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class ReviewController implements ReviewActivity.ReviewCallback {
|
|
||||||
public static String fileName;
|
|
||||||
protected static ArrayList<String> categories;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onImageRefreshed(String fileName) {
|
|
||||||
ReviewController.fileName = fileName;
|
|
||||||
ReviewController.categories = new ArrayList<>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onCategoriesRefreshed(ArrayList<String> categories) {
|
|
||||||
ReviewController.categories = categories;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onQuestionChanged() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSurveyFinished() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onImproperImageReported() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLicenceViolationReported() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onWrongCategoryReported() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onThankSent() {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
||||||
package fr.free.nrw.commons.review;
|
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.facebook.drawee.view.SimpleDraweeView;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import fr.free.nrw.commons.R;
|
|
||||||
import fr.free.nrw.commons.Utils;
|
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerSupportFragment;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by root on 19.05.2018.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class ReviewImageFragment extends CommonsDaggerSupportFragment {
|
|
||||||
|
|
||||||
public static final int SPAM = 0;
|
|
||||||
public static final int COPYRIGHT = 1;
|
|
||||||
public static final int CATEGORY = 2;
|
|
||||||
|
|
||||||
private int position;
|
|
||||||
private String fileName;
|
|
||||||
private String catString;
|
|
||||||
private View catsView;
|
|
||||||
private SimpleDraweeView simpleDraweeView;
|
|
||||||
|
|
||||||
public void update(int position, String fileName) {
|
|
||||||
this.position = position;
|
|
||||||
this.fileName = fileName;
|
|
||||||
|
|
||||||
if (simpleDraweeView!=null) {
|
|
||||||
simpleDraweeView.setImageURI(Utils.makeThumbBaseUrl(fileName));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateCategories(Iterable<String> categories) {
|
|
||||||
catString = TextUtils.join(", ", categories);
|
|
||||||
if (catsView != null) {
|
|
||||||
((TextView) catsView).setText(catString);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
|
||||||
Bundle savedInstanceState) {
|
|
||||||
position = getArguments().getInt("position");
|
|
||||||
View layoutView = inflater.inflate(R.layout.fragment_review_image, container,
|
|
||||||
false);
|
|
||||||
View textView = layoutView.findViewById(R.id.reviewQuestion);
|
|
||||||
catsView = layoutView.findViewById(R.id.reviewCategories);
|
|
||||||
String question;
|
|
||||||
switch(position) {
|
|
||||||
case COPYRIGHT:
|
|
||||||
question = getString(R.string.review_copyright);
|
|
||||||
break;
|
|
||||||
case CATEGORY:
|
|
||||||
question = getString(R.string.review_category);
|
|
||||||
catsView.setVisibility(View.VISIBLE);
|
|
||||||
break;
|
|
||||||
case SPAM:
|
|
||||||
question = getString(R.string.review_spam);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
question = "How did we get here?";
|
|
||||||
}
|
|
||||||
((TextView) textView).setText(question);
|
|
||||||
simpleDraweeView = layoutView.findViewById(R.id.imageView);
|
|
||||||
|
|
||||||
if (fileName != null) {
|
|
||||||
simpleDraweeView.setImageURI(Utils.makeThumbBaseUrl(fileName));
|
|
||||||
}
|
|
||||||
if (catString != null) {
|
|
||||||
((TextView) catsView).setText(catString);
|
|
||||||
}
|
|
||||||
return layoutView;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
package fr.free.nrw.commons.review;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.support.v4.app.FragmentManager;
|
|
||||||
import android.support.v4.app.FragmentStatePagerAdapter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by nes on 19.05.2018.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class ReviewPagerAdapter extends FragmentStatePagerAdapter {
|
|
||||||
private int currentPosition;
|
|
||||||
ReviewImageFragment[] reviewImageFragments;
|
|
||||||
|
|
||||||
|
|
||||||
public ReviewPagerAdapter(FragmentManager fm) {
|
|
||||||
super(fm);
|
|
||||||
reviewImageFragments = new ReviewImageFragment[] {
|
|
||||||
new ReviewImageFragment(),
|
|
||||||
new ReviewImageFragment(),
|
|
||||||
new ReviewImageFragment()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getCount() {
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateFilename() {
|
|
||||||
for (int i = 0; i < getCount(); i++) {
|
|
||||||
ReviewImageFragment fragment = reviewImageFragments[i];
|
|
||||||
fragment.update(i, ReviewController.fileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateCategories() {
|
|
||||||
ReviewImageFragment categoryFragment = reviewImageFragments[ReviewImageFragment.CATEGORY];
|
|
||||||
categoryFragment.updateCategories(ReviewController.categories);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Fragment getItem(int position) {
|
|
||||||
Bundle bundle = new Bundle();
|
|
||||||
bundle.putInt("position", position);
|
|
||||||
reviewImageFragments[position].setArguments(bundle);
|
|
||||||
return reviewImageFragments[position];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,140 +0,0 @@
|
||||||
package fr.free.nrw.commons.review;
|
|
||||||
|
|
||||||
import android.app.NotificationManager;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.support.v4.app.NotificationCompat;
|
|
||||||
import android.view.Gravity;
|
|
||||||
import android.widget.Toast;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
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 timber.log.Timber;
|
|
||||||
|
|
||||||
import static android.support.v4.app.NotificationCompat.DEFAULT_ALL;
|
|
||||||
import static android.support.v4.app.NotificationCompat.PRIORITY_HIGH;
|
|
||||||
|
|
||||||
// example code:
|
|
||||||
//
|
|
||||||
// media = new Media("File:Iru.png");
|
|
||||||
// Observable.fromCallable(() -> mwApi.firstRevisionOfFile(media.getFilename()))
|
|
||||||
// .subscribeOn(Schedulers.io())
|
|
||||||
// .observeOn(AndroidSchedulers.mainThread())
|
|
||||||
// .subscribe(revision -> {
|
|
||||||
// SendThankTask task = new SendThankTask(getActivity(), media, revision);
|
|
||||||
// task.execute();
|
|
||||||
// });
|
|
||||||
|
|
||||||
public class SendThankTask extends AsyncTask<Void, Integer, Boolean> {
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
MediaWikiApi mwApi;
|
|
||||||
@Inject
|
|
||||||
SessionManager sessionManager;
|
|
||||||
|
|
||||||
public static final int NOTIFICATION_SEND_THANK = 0x102;
|
|
||||||
|
|
||||||
private NotificationManager notificationManager;
|
|
||||||
private NotificationCompat.Builder notificationBuilder;
|
|
||||||
private Context context;
|
|
||||||
private Media media;
|
|
||||||
private String revision;
|
|
||||||
|
|
||||||
public SendThankTask(Context context, Media media, String revision){
|
|
||||||
this.context = context;
|
|
||||||
this.media = media;
|
|
||||||
this.revision = revision;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPreExecute(){
|
|
||||||
ApplicationlessInjection
|
|
||||||
.getInstance(context.getApplicationContext())
|
|
||||||
.getCommonsApplicationComponent()
|
|
||||||
.inject(this);
|
|
||||||
|
|
||||||
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
|
|
||||||
notificationBuilder = new NotificationCompat.Builder(context);
|
|
||||||
Toast toast = new Toast(context);
|
|
||||||
toast.setGravity(Gravity.CENTER,0,0);
|
|
||||||
toast = Toast.makeText(context, context.getString(R.string.send_thank_toast, media.getDisplayTitle()), Toast.LENGTH_SHORT);
|
|
||||||
toast.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Boolean doInBackground(Void ...voids) {
|
|
||||||
publishProgress(0);
|
|
||||||
|
|
||||||
String editToken;
|
|
||||||
String authCookie;
|
|
||||||
|
|
||||||
authCookie = sessionManager.getAuthCookie();
|
|
||||||
mwApi.setAuthCookie(authCookie);
|
|
||||||
|
|
||||||
try {
|
|
||||||
editToken = mwApi.getEditToken();
|
|
||||||
if (editToken.equals("+\\")) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
publishProgress(1);
|
|
||||||
|
|
||||||
mwApi.thank(editToken, revision);
|
|
||||||
|
|
||||||
publishProgress(2);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
Timber.d(e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onProgressUpdate (Integer... values){
|
|
||||||
super.onProgressUpdate(values);
|
|
||||||
|
|
||||||
int[] messages = new int[]{R.string.getting_edit_token, R.string.send_thank_send};
|
|
||||||
String message = "";
|
|
||||||
if (0 < values[0] && values[0] < messages.length) {
|
|
||||||
message = context.getString(messages[values[0]]);
|
|
||||||
}
|
|
||||||
|
|
||||||
notificationBuilder.setContentTitle(context.getString(R.string.send_thank_notification_title))
|
|
||||||
.setStyle(new NotificationCompat.BigTextStyle()
|
|
||||||
.bigText(message))
|
|
||||||
.setSmallIcon(R.drawable.ic_launcher)
|
|
||||||
.setProgress(messages.length, values[0], false)
|
|
||||||
.setOngoing(true);
|
|
||||||
notificationManager.notify(NOTIFICATION_SEND_THANK, notificationBuilder.build());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Boolean result) {
|
|
||||||
String message = "";
|
|
||||||
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());
|
|
||||||
}
|
|
||||||
|
|
||||||
notificationBuilder.setDefaults(DEFAULT_ALL)
|
|
||||||
.setContentTitle(title)
|
|
||||||
.setStyle(new NotificationCompat.BigTextStyle()
|
|
||||||
.bigText(message))
|
|
||||||
.setSmallIcon(R.drawable.ic_launcher)
|
|
||||||
.setProgress(0,0,false)
|
|
||||||
.setOngoing(false)
|
|
||||||
.setPriority(PRIORITY_HIGH);
|
|
||||||
notificationManager.notify(NOTIFICATION_SEND_THANK, notificationBuilder.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -30,7 +30,6 @@ import fr.free.nrw.commons.contributions.ContributionsActivity;
|
||||||
import fr.free.nrw.commons.category.CategoryImagesActivity;
|
import fr.free.nrw.commons.category.CategoryImagesActivity;
|
||||||
import fr.free.nrw.commons.nearby.NearbyActivity;
|
import fr.free.nrw.commons.nearby.NearbyActivity;
|
||||||
import fr.free.nrw.commons.notification.NotificationActivity;
|
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.settings.SettingsActivity;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
|
@ -161,11 +160,6 @@ public abstract class NavigationBaseActivity extends BaseActivity
|
||||||
drawerLayout.closeDrawer(navigationView);
|
drawerLayout.closeDrawer(navigationView);
|
||||||
CategoryImagesActivity.startYourself(this, getString(R.string.title_activity_featured_images), FEATURED_IMAGES_CATEGORY);
|
CategoryImagesActivity.startYourself(this, getString(R.string.title_activity_featured_images), FEATURED_IMAGES_CATEGORY);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
case R.id.action_review:
|
|
||||||
drawerLayout.closeDrawer(navigationView);
|
|
||||||
ReviewActivity.startYourself(this, getString(R.string.title_activity_review));
|
|
||||||
return true;
|
|
||||||
default:
|
default:
|
||||||
Timber.e("Unknown option [%s] selected from the navigation menu", itemId);
|
Timber.e("Unknown option [%s] selected from the navigation menu", itemId);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
||||||
|
|
@ -1,28 +0,0 @@
|
||||||
package fr.free.nrw.commons.utils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
public class MediaDataExtractorUtil {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
public static ArrayList<String> extractCategories(String source) {
|
|
||||||
ArrayList<String> categories = new ArrayList<>();
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
return categories;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:viewportWidth="24.0"
|
|
||||||
android:viewportHeight="24.0">
|
|
||||||
<path
|
|
||||||
android:fillColor="#FF000000"
|
|
||||||
android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
|
|
||||||
</vector>
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="24dp"
|
|
||||||
android:height="24dp"
|
|
||||||
android:viewportWidth="24.0"
|
|
||||||
android:viewportHeight="24.0">
|
|
||||||
<path
|
|
||||||
android:fillColor="#FF000000"
|
|
||||||
android:pathData="M17.65,6.35C16.2,4.9 14.21,4 12,4c-4.42,0 -7.99,3.58 -7.99,8s3.57,8 7.99,8c3.73,0 6.84,-2.55 7.73,-6h-2.08c-0.82,2.33 -3.04,4 -5.65,4 -3.31,0 -6,-2.69 -6,-6s2.69,-6 6,-6c1.66,0 3.14,0.69 4.22,1.78L13,11h7V4l-2.35,2.35z"/>
|
|
||||||
</vector>
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<item>
|
|
||||||
<shape
|
|
||||||
android:innerRadius="0dp"
|
|
||||||
android:shape="ring"
|
|
||||||
android:thickness="2dp"
|
|
||||||
android:useLevel="false">
|
|
||||||
<solid android:color="@android:color/darker_gray"/>
|
|
||||||
</shape>
|
|
||||||
</item>
|
|
||||||
</layer-list>
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape android:innerRadius="0dp"
|
|
||||||
android:shape="ring"
|
|
||||||
android:thickness="4dp"
|
|
||||||
android:useLevel="false"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<solid android:color="@color/commons_app_blue_dark"/>
|
|
||||||
</shape>
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
|
|
||||||
<item android:drawable="@drawable/tab_indicator_selected"
|
|
||||||
android:state_selected="true"/>
|
|
||||||
|
|
||||||
<item android:drawable="@drawable/tab_indicator_default"/>
|
|
||||||
</selector>
|
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:id="@+id/drawer_layout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<android.support.design.widget.CoordinatorLayout
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:id="@+id/coordinator_layout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<RelativeLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent">
|
|
||||||
|
|
||||||
<include
|
|
||||||
android:id="@+id/toolbar"
|
|
||||||
layout="@layout/toolbar"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
</include>
|
|
||||||
|
|
||||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_below="@id/toolbar">
|
|
||||||
|
|
||||||
<android.support.v4.view.ViewPager
|
|
||||||
android:id="@+id/reviewPager"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:fadingEdge="none" />
|
|
||||||
|
|
||||||
|
|
||||||
<com.viewpagerindicator.CirclePageIndicator
|
|
||||||
android:id="@+id/reviewPagerIndicator"
|
|
||||||
android:layout_height="@dimen/half_standard_height"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_below="@id/reviewPager"
|
|
||||||
android:layout_gravity="bottom"
|
|
||||||
android:elevation="3dp"
|
|
||||||
android:background="?attr/colorPrimaryDark"
|
|
||||||
/>
|
|
||||||
|
|
||||||
</FrameLayout>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
|
|
||||||
</android.support.design.widget.CoordinatorLayout>
|
|
||||||
|
|
||||||
|
|
||||||
<android.support.design.widget.NavigationView
|
|
||||||
android:id="@+id/navigation_view"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:layout_gravity="start"
|
|
||||||
app:headerLayout="@layout/drawer_header"
|
|
||||||
app:menu="@menu/drawer" />
|
|
||||||
|
|
||||||
</android.support.v4.widget.DrawerLayout>
|
|
||||||
|
|
@ -1,89 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<LinearLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:weightSum="6"
|
|
||||||
android:orientation="vertical"
|
|
||||||
android:gravity="center_horizontal"
|
|
||||||
>
|
|
||||||
|
|
||||||
<com.facebook.drawee.view.SimpleDraweeView
|
|
||||||
android:id="@+id/imageView"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_weight="3"
|
|
||||||
android:src="@drawable/commons_logo_large"
|
|
||||||
/>
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/reviewQuestion"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:textColor="@android:color/black"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_weight="1.1"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:textSize="32sp"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:text="testing1"
|
|
||||||
/>
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/reviewQuestionContext"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_weight="0.7"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:textSize="24sp"
|
|
||||||
android:layout_marginBottom="15dp"
|
|
||||||
android:gravity="center_vertical"
|
|
||||||
android:text="testing2"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/reviewCategories"
|
|
||||||
android:visibility="gone"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_weight="0.7"
|
|
||||||
android:textSize="24sp"
|
|
||||||
android:textAlignment="center"
|
|
||||||
android:text="testing2"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<LinearLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_weight="0.6"
|
|
||||||
android:weightSum="2"
|
|
||||||
android:orientation="horizontal">
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/yesButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:background="@android:color/transparent"
|
|
||||||
android:text="@string/yes"
|
|
||||||
android:textSize="20sp"
|
|
||||||
android:textColor="?attr/colorPrimaryDark"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Button
|
|
||||||
android:id="@+id/noButton"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:background="@android:color/transparent"
|
|
||||||
android:layout_weight="1"
|
|
||||||
android:text="@string/no"
|
|
||||||
android:textSize="20sp"
|
|
||||||
android:textColor="?attr/colorPrimaryDark"
|
|
||||||
/>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
<View
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="0dp"
|
|
||||||
android:layout_weight="0.6"
|
|
||||||
android:background="?attr/colorPrimaryDark"
|
|
||||||
></View>
|
|
||||||
|
|
||||||
</LinearLayout>
|
|
||||||
|
|
@ -15,11 +15,6 @@
|
||||||
android:icon="@drawable/ic_star_black_24dp"
|
android:icon="@drawable/ic_star_black_24dp"
|
||||||
android:title="@string/navigation_item_featured_images"/>
|
android:title="@string/navigation_item_featured_images"/>
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_review"
|
|
||||||
android:icon="@drawable/ic_check_black_24dp"
|
|
||||||
android:title="@string/navigation_item_review"/>
|
|
||||||
|
|
||||||
</group>
|
</group>
|
||||||
<group android:id="@+id/drawer_account">
|
<group android:id="@+id/drawer_account">
|
||||||
<item
|
<item
|
||||||
|
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
<item android:id="@+id/action_review_randomizer"
|
|
||||||
android:title="@string/menu_from_gallery"
|
|
||||||
app:showAsAction="ifRoom|withText"
|
|
||||||
android:icon="@drawable/ic_refresh_white_24dp"
|
|
||||||
/>
|
|
||||||
|
|
||||||
</menu>
|
|
||||||
|
|
@ -83,7 +83,6 @@
|
||||||
<string name="title_activity_settings">Settings</string>
|
<string name="title_activity_settings">Settings</string>
|
||||||
<string name="title_activity_signup">Sign Up</string>
|
<string name="title_activity_signup">Sign Up</string>
|
||||||
<string name="title_activity_featured_images">Featured Images</string>
|
<string name="title_activity_featured_images">Featured Images</string>
|
||||||
<string name="title_activity_review">Peer Review</string>
|
|
||||||
<string name="menu_about">About</string>
|
<string name="menu_about">About</string>
|
||||||
<string name="about_license">The Wikimedia Commons app is an open-source app created and maintained by grantees and volunteers of the Wikimedia community. The Wikimedia Foundation is not involved in the creation, development, or maintenance of the app. </string>
|
<string name="about_license">The Wikimedia Commons app is an open-source app created and maintained by grantees and volunteers of the Wikimedia community. The Wikimedia Foundation is not involved in the creation, development, or maintenance of the app. </string>
|
||||||
<string name="trademarked_name" translatable="false">Wikimedia Commons</string>
|
<string name="trademarked_name" translatable="false">Wikimedia Commons</string>
|
||||||
|
|
@ -220,7 +219,6 @@
|
||||||
<string name="navigation_item_info">Tutorial</string>
|
<string name="navigation_item_info">Tutorial</string>
|
||||||
<string name="navigation_item_notification">Notifications</string>
|
<string name="navigation_item_notification">Notifications</string>
|
||||||
<string name="navigation_item_featured_images">Featured</string>
|
<string name="navigation_item_featured_images">Featured</string>
|
||||||
<string name="navigation_item_review">Review</string>
|
|
||||||
<string name="nearby_needs_permissions">Nearby places cannot be displayed without location permissions</string>
|
<string name="nearby_needs_permissions">Nearby places cannot be displayed without location permissions</string>
|
||||||
<string name="no_description_found">no description found</string>
|
<string name="no_description_found">no description found</string>
|
||||||
<string name="nearby_info_menu_commons_article">Commons file page</string>
|
<string name="nearby_info_menu_commons_article">Commons file page</string>
|
||||||
|
|
@ -241,8 +239,6 @@
|
||||||
<string name="null_url">Error! URL not found</string>
|
<string name="null_url">Error! URL not found</string>
|
||||||
<string name="nominate_deletion">Nominate for Deletion</string>
|
<string name="nominate_deletion">Nominate for Deletion</string>
|
||||||
<string name="nominated_for_deletion">This image has been nominated for deletion.</string>
|
<string name="nominated_for_deletion">This image has been nominated for deletion.</string>
|
||||||
<string name="nominating_file_for_deletion">Nominating %1$s for deletion.</string>
|
|
||||||
<string name="nominating_for_deletion_status">Nominating file for deletion: %1$s</string>
|
|
||||||
<string name="nominated_see_more"><u>See webpage for details</u></string>
|
<string name="nominated_see_more"><u>See webpage for details</u></string>
|
||||||
<string name="view_browser">View in Browser</string>
|
<string name="view_browser">View in Browser</string>
|
||||||
|
|
||||||
|
|
@ -287,31 +283,5 @@
|
||||||
<string name="share_app_title">Share App</string>
|
<string name="share_app_title">Share App</string>
|
||||||
<string name="share_coordinates_not_present">Coordinates were not specified during image selection</string>
|
<string name="share_coordinates_not_present">Coordinates were not specified during image selection</string>
|
||||||
<string name="error_fetching_nearby_places">Error fetching nearby places.</string>
|
<string name="error_fetching_nearby_places">Error fetching nearby places.</string>
|
||||||
<string name="getting_edit_token">Getting token for editing</string>
|
|
||||||
<string name="check_category_adding_template">Adding template for category check</string>
|
|
||||||
<string name="check_category_notification_title">Requesting category check for %1$s</string>
|
|
||||||
<string name="check_category_edit_summary">Requesting category check</string>
|
|
||||||
<string name="check_category_success_title">Requesting category check: Success</string>
|
|
||||||
<string name="check_category_failure_title">Requesting category check: Failed</string>
|
|
||||||
<string name="check_category_success_message">Successfully requested category check for %1$s</string>
|
|
||||||
<string name="check_category_failure_message">Could not request category check for %1$s</string>
|
|
||||||
<string name="check_category_toast">Requesting category check for %1$s</string>
|
|
||||||
<string name="nominate_for_deletion_edit_file_page">Adding delete message to file</string>
|
|
||||||
<string name="nominate_for_deletion_done">Done</string>
|
|
||||||
<string name="nominate_for_deletion_notify_user">Notifying User on Talk page</string>
|
|
||||||
<string name="nominate_for_deletion_edit_deletion_request_log">Adding file to Delete requests log</string>
|
|
||||||
<string name="nominate_for_deletion_create_deletion_request">Creating Delete requests subpage</string>
|
|
||||||
<string name="notsure">Not sure</string>
|
|
||||||
<string name="send_thank_success_title">Sending Thanks: Success</string>
|
|
||||||
<string name="send_thank_success_message">Successfully sent thanks to %1$s</string>
|
|
||||||
<string name="send_thank_failure_message">Failed to send thanks %1$s</string>
|
|
||||||
<string name="send_thank_failure_title">Sending Thanks: Failure</string>
|
|
||||||
<string name="send_thank_send">Sending thanks</string>
|
|
||||||
<string name="send_thank_notification_title">Sending thanks</string>
|
|
||||||
<string name="send_thank_toast">Sending Thanks for %1$s</string>
|
|
||||||
|
|
||||||
<string name="review_copyright">Is this a copyright violation?</string>
|
|
||||||
<string name="review_category">Is this mis-categorized?</string>
|
|
||||||
<string name="review_spam">Is this spam?</string>
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue