mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-27 12:53:55 +01:00
Merge remote-tracking branch 'refs/remotes/commons-app/master'
This commit is contained in:
commit
3b42daa5f1
16 changed files with 336 additions and 395 deletions
|
|
@ -43,6 +43,7 @@ public class Media implements Parcelable {
|
||||||
protected String license;
|
protected String license;
|
||||||
protected String creator;
|
protected String creator;
|
||||||
protected ArrayList<String> categories; // as loaded at runtime?
|
protected ArrayList<String> categories; // as loaded at runtime?
|
||||||
|
protected boolean requestedDeletion;
|
||||||
private Map<String, String> descriptions; // multilingual descriptions as loaded
|
private Map<String, String> descriptions; // multilingual descriptions as loaded
|
||||||
private HashMap<String, Object> tags = new HashMap<>();
|
private HashMap<String, Object> tags = new HashMap<>();
|
||||||
private @Nullable LatLng coordinates;
|
private @Nullable LatLng coordinates;
|
||||||
|
|
@ -416,4 +417,12 @@ public class Media implements Parcelable {
|
||||||
parcel.writeStringList(categories);
|
parcel.writeStringList(categories);
|
||||||
parcel.writeMap(descriptions);
|
parcel.writeMap(descriptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setRequestedDeletion(){
|
||||||
|
requestedDeletion = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getRequestedDeletion(){
|
||||||
|
return requestedDeletion;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ import timber.log.Timber;
|
||||||
public class MediaDataExtractor {
|
public class MediaDataExtractor {
|
||||||
private final MediaWikiApi mediaWikiApi;
|
private final MediaWikiApi mediaWikiApi;
|
||||||
private boolean fetched;
|
private boolean fetched;
|
||||||
|
private boolean deletionStatus;
|
||||||
private ArrayList<String> categories;
|
private ArrayList<String> categories;
|
||||||
private Map<String, String> descriptions;
|
private Map<String, String> descriptions;
|
||||||
private String license;
|
private String license;
|
||||||
|
|
@ -59,6 +60,14 @@ public class MediaDataExtractor {
|
||||||
throw new IllegalStateException("Tried to call MediaDataExtractor.fetch() again.");
|
throw new IllegalStateException("Tried to call MediaDataExtractor.fetch() again.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
Timber.d("Nominated for deletion: " + mediaWikiApi.pageExists("Commons:Deletion_requests/"+filename));
|
||||||
|
deletionStatus = mediaWikiApi.pageExists("Commons:Deletion_requests/"+filename);
|
||||||
|
}
|
||||||
|
catch (Exception e){
|
||||||
|
Timber.d(e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
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]]
|
||||||
|
|
@ -296,6 +305,9 @@ public class MediaDataExtractor {
|
||||||
if (license != null) {
|
if (license != null) {
|
||||||
media.setLicense(license);
|
media.setLicense(license);
|
||||||
}
|
}
|
||||||
|
if (deletionStatus){
|
||||||
|
media.setRequestedDeletion();
|
||||||
|
}
|
||||||
|
|
||||||
// add author, date, etc fields
|
// add author, date, etc fields
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
package fr.free.nrw.commons.delete;
|
package fr.free.nrw.commons.delete;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.NotificationManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
|
import android.support.v4.app.NotificationCompat;
|
||||||
|
import android.support.v4.app.NotificationCompat.Builder;
|
||||||
|
import android.view.Gravity;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
@ -18,17 +21,18 @@ import fr.free.nrw.commons.di.ApplicationlessInjection;
|
||||||
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
import static android.support.v4.content.ContextCompat.startActivity;
|
import static android.support.v4.app.NotificationCompat.DEFAULT_ALL;
|
||||||
|
import static android.support.v4.app.NotificationCompat.PRIORITY_HIGH;
|
||||||
|
|
||||||
public class DeleteTask extends AsyncTask<Void, Void, Integer> {
|
public class DeleteTask extends AsyncTask<Void, Integer, Boolean> {
|
||||||
|
|
||||||
private static final int SUCCESS = 0;
|
|
||||||
private static final int FAILED = -1;
|
|
||||||
private static final int ALREADY_DELETED = -2;
|
|
||||||
|
|
||||||
@Inject MediaWikiApi mwApi;
|
@Inject MediaWikiApi mwApi;
|
||||||
@Inject SessionManager sessionManager;
|
@Inject SessionManager sessionManager;
|
||||||
|
|
||||||
|
public static final int NOTIFICATION_DELETE = 1;
|
||||||
|
|
||||||
|
private NotificationManager notificationManager;
|
||||||
|
private Builder notificationBuilder;
|
||||||
private Context context;
|
private Context context;
|
||||||
private Media media;
|
private Media media;
|
||||||
private String reason;
|
private String reason;
|
||||||
|
|
@ -45,10 +49,19 @@ public class DeleteTask extends AsyncTask<Void, Void, Integer> {
|
||||||
.getInstance(context.getApplicationContext())
|
.getInstance(context.getApplicationContext())
|
||||||
.getCommonsApplicationComponent()
|
.getCommonsApplicationComponent()
|
||||||
.inject(this);
|
.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,"Trying to nominate "+media.getDisplayTitle()+ " for deletion",Toast.LENGTH_SHORT);
|
||||||
|
toast.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Integer doInBackground(Void ...voids) {
|
protected Boolean doInBackground(Void ...voids) {
|
||||||
|
publishProgress(0);
|
||||||
|
|
||||||
String editToken;
|
String editToken;
|
||||||
String authCookie;
|
String authCookie;
|
||||||
String summary = "Nominating " + media.getFilename() +" for deletion.";
|
String summary = "Nominating " + media.getFilename() +" for deletion.";
|
||||||
|
|
@ -56,27 +69,6 @@ public class DeleteTask extends AsyncTask<Void, Void, Integer> {
|
||||||
authCookie = sessionManager.getAuthCookie();
|
authCookie = sessionManager.getAuthCookie();
|
||||||
mwApi.setAuthCookie(authCookie);
|
mwApi.setAuthCookie(authCookie);
|
||||||
|
|
||||||
try{
|
|
||||||
if (mwApi.pageExists("Commons:Deletion_requests/"+media.getFilename())){
|
|
||||||
return ALREADY_DELETED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
Timber.d(e.getMessage());
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
editToken = mwApi.getEditToken();
|
|
||||||
}
|
|
||||||
catch (Exception e){
|
|
||||||
Timber.d(e.getMessage());
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
if (editToken.equals("+\\")) {
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
Calendar calendar = Calendar.getInstance();
|
Calendar calendar = Calendar.getInstance();
|
||||||
String fileDeleteString = "{{delete|reason=" + reason +
|
String fileDeleteString = "{{delete|reason=" + reason +
|
||||||
"|subpage=" +media.getFilename() +
|
"|subpage=" +media.getFilename() +
|
||||||
|
|
@ -84,91 +76,106 @@ public class DeleteTask extends AsyncTask<Void, Void, Integer> {
|
||||||
"|month=" + calendar.getDisplayName(Calendar.MONTH,Calendar.LONG, Locale.getDefault()) +
|
"|month=" + calendar.getDisplayName(Calendar.MONTH,Calendar.LONG, Locale.getDefault()) +
|
||||||
"|year=" + calendar.get(Calendar.YEAR) +
|
"|year=" + calendar.get(Calendar.YEAR) +
|
||||||
"}}";
|
"}}";
|
||||||
try{
|
|
||||||
mwApi.prependEdit(editToken,fileDeleteString+"\n",
|
|
||||||
media.getFilename(),summary);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
Timber.d(e.getMessage());
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
String subpageString = "=== [[:" + media.getFilename() + "]] ===\n" +
|
String subpageString = "=== [[:" + media.getFilename() + "]] ===\n" +
|
||||||
reason +
|
reason +
|
||||||
" ~~~~";
|
" ~~~~";
|
||||||
try{
|
|
||||||
mwApi.edit(editToken,subpageString+"\n",
|
|
||||||
"Commons:Deletion_requests/"+media.getFilename(),summary);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
Timber.d(e.getMessage());
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
String logPageString = "\n{{Commons:Deletion requests/" + media.getFilename() +
|
String logPageString = "\n{{Commons:Deletion requests/" + media.getFilename() +
|
||||||
"}}\n";
|
"}}\n";
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
|
||||||
String date = sdf.format(calendar.getTime());
|
String date = sdf.format(calendar.getTime());
|
||||||
try{
|
|
||||||
mwApi.appendEdit(editToken,logPageString+"\n",
|
|
||||||
"Commons:Deletion_requests/"+date,summary);
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
Timber.d(e.getMessage());
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
|
|
||||||
String userPageString = "\n{{subst:idw|" + media.getFilename() +
|
String userPageString = "\n{{subst:idw|" + media.getFilename() +
|
||||||
"}} ~~~~";
|
"}} ~~~~";
|
||||||
try{
|
|
||||||
|
try {
|
||||||
|
editToken = mwApi.getEditToken();
|
||||||
|
if (editToken.equals("+\\")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
publishProgress(1);
|
||||||
|
|
||||||
|
mwApi.prependEdit(editToken,fileDeleteString+"\n",
|
||||||
|
media.getFilename(),summary);
|
||||||
|
publishProgress(2);
|
||||||
|
|
||||||
|
mwApi.edit(editToken,subpageString+"\n",
|
||||||
|
"Commons:Deletion_requests/"+media.getFilename(),summary);
|
||||||
|
publishProgress(3);
|
||||||
|
|
||||||
|
mwApi.appendEdit(editToken,logPageString+"\n",
|
||||||
|
"Commons:Deletion_requests/"+date,summary);
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
Timber.d(e.getMessage());
|
Timber.d(e.getMessage());
|
||||||
return FAILED;
|
return false;
|
||||||
}
|
}
|
||||||
return SUCCESS;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(Integer result) {
|
protected void onProgressUpdate (Integer... values){
|
||||||
|
super.onProgressUpdate(values);
|
||||||
|
|
||||||
String message = "";
|
String message = "";
|
||||||
String title = "";
|
switch (values[0]){
|
||||||
switch (result){
|
case 0:
|
||||||
case SUCCESS:
|
message = "Getting token";
|
||||||
title = "Success";
|
|
||||||
message = "Successfully nominated " + media.getDisplayTitle() + " deletion.\n" +
|
|
||||||
"Check the webpage for more details";
|
|
||||||
break;
|
break;
|
||||||
case FAILED:
|
case 1:
|
||||||
title = "Failed";
|
message = "Adding delete message to file";
|
||||||
message = "Could not request deletion. Something went wrong.";
|
|
||||||
break;
|
break;
|
||||||
case ALREADY_DELETED:
|
case 2:
|
||||||
title = "Already Nominated";
|
message = "Creating Delete requests sub-page";
|
||||||
message = media.getDisplayTitle() + " has already been nominated for deletion.\n" +
|
break;
|
||||||
"Check the webpage for more details";
|
case 3:
|
||||||
|
message = "Adding file to Delete requests log";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
message = "Notifying User on Talk page";
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
message = "Done";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
AlertDialog alert;
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
notificationBuilder.setContentTitle("Nominating "+media.getDisplayTitle()+" for deletion")
|
||||||
builder.setTitle(title);
|
.setStyle(new NotificationCompat.BigTextStyle()
|
||||||
builder.setMessage(message);
|
.bigText(message))
|
||||||
builder.setCancelable(true);
|
.setSmallIcon(R.drawable.ic_launcher)
|
||||||
builder.setPositiveButton(
|
.setProgress(5, values[0], false)
|
||||||
R.string.ok,
|
.setOngoing(true);
|
||||||
new DialogInterface.OnClickListener() {
|
notificationManager.notify(NOTIFICATION_DELETE, notificationBuilder.build());
|
||||||
public void onClick(DialogInterface dialog, int id) {}
|
}
|
||||||
});
|
|
||||||
builder.setNeutralButton(R.string.view_browser,
|
@Override
|
||||||
new DialogInterface.OnClickListener() {
|
protected void onPostExecute(Boolean result) {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
String message = "";
|
||||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, media.getFilePageTitle().getMobileUri());
|
String title = "Nominating for Deletion";
|
||||||
startActivity(context,browserIntent,null);
|
|
||||||
}
|
if (result){
|
||||||
});
|
title += ": Success";
|
||||||
alert = builder.create();
|
message = "Successfully nominated " + media.getDisplayTitle() + " deletion.";
|
||||||
alert.show();
|
}
|
||||||
|
else {
|
||||||
|
title += ": Failed";
|
||||||
|
message = "Could not request deletion.";
|
||||||
|
}
|
||||||
|
|
||||||
|
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_DELETE, notificationBuilder.build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -15,7 +15,6 @@ import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.ViewTreeObserver;
|
import android.view.ViewTreeObserver;
|
||||||
import android.view.WindowManager;
|
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
|
@ -42,6 +41,7 @@ import fr.free.nrw.commons.R;
|
||||||
import fr.free.nrw.commons.delete.DeleteTask;
|
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.ui.widget.CompatTextView;
|
import fr.free.nrw.commons.ui.widget.CompatTextView;
|
||||||
import timber.log.Timber;
|
import timber.log.Timber;
|
||||||
|
|
||||||
|
|
@ -69,6 +69,9 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
Provider<MediaDataExtractor> mediaDataExtractorProvider;
|
Provider<MediaDataExtractor> mediaDataExtractorProvider;
|
||||||
|
@Inject
|
||||||
|
MediaWikiApi mwApi;
|
||||||
|
|
||||||
|
|
||||||
private MediaWikiImageView image;
|
private MediaWikiImageView image;
|
||||||
private MediaDetailSpacer spacer;
|
private MediaDetailSpacer spacer;
|
||||||
|
|
@ -79,6 +82,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
||||||
private TextView license;
|
private TextView license;
|
||||||
private TextView coordinates;
|
private TextView coordinates;
|
||||||
private TextView uploadedDate;
|
private TextView uploadedDate;
|
||||||
|
private TextView seeMore;
|
||||||
|
private LinearLayout nominatedforDeletion;
|
||||||
private LinearLayout categoryContainer;
|
private LinearLayout categoryContainer;
|
||||||
private Button delete;
|
private Button delete;
|
||||||
private ScrollView scrollView;
|
private ScrollView scrollView;
|
||||||
|
|
@ -133,6 +138,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
||||||
license = (TextView) view.findViewById(R.id.mediaDetailLicense);
|
license = (TextView) view.findViewById(R.id.mediaDetailLicense);
|
||||||
coordinates = (TextView) view.findViewById(R.id.mediaDetailCoordinates);
|
coordinates = (TextView) view.findViewById(R.id.mediaDetailCoordinates);
|
||||||
uploadedDate = (TextView) view.findViewById(R.id.mediaDetailuploadeddate);
|
uploadedDate = (TextView) view.findViewById(R.id.mediaDetailuploadeddate);
|
||||||
|
seeMore = (TextView) view.findViewById(R.id.seeMore);
|
||||||
|
nominatedforDeletion = (LinearLayout) view.findViewById(R.id.nominatedDeletionBanner);
|
||||||
delete = (Button) view.findViewById(R.id.nominateDeletion);
|
delete = (Button) view.findViewById(R.id.nominateDeletion);
|
||||||
categoryContainer = (LinearLayout) view.findViewById(R.id.mediaDetailCategoryContainer);
|
categoryContainer = (LinearLayout) view.findViewById(R.id.mediaDetailCategoryContainer);
|
||||||
|
|
||||||
|
|
@ -231,7 +238,6 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
extractor.fill(media);
|
extractor.fill(media);
|
||||||
|
|
||||||
setTextFields(media);
|
setTextFields(media);
|
||||||
setOnClickListeners(media);
|
setOnClickListeners(media);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -284,21 +290,23 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
||||||
}
|
}
|
||||||
rebuildCatList();
|
rebuildCatList();
|
||||||
|
|
||||||
delete.setVisibility(View.VISIBLE);
|
checkDeletion(media);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setOnClickListeners(final Media media) {
|
private void setOnClickListeners(final Media media) {
|
||||||
if (licenseLink(media) != null) {
|
if (licenseLink(media) != null) {
|
||||||
license.setOnClickListener(v -> openWebBrowser(licenseLink(media)));
|
license.setOnClickListener(v -> openWebBrowser(licenseLink(media)));
|
||||||
} else {
|
} else {
|
||||||
Toast toast = Toast.makeText(getContext(), getString(R.string.null_url), Toast.LENGTH_SHORT);
|
Toast toast = Toast.makeText(getContext(), getString(R.string.null_url), Toast.LENGTH_SHORT);
|
||||||
toast.show();
|
toast.show();
|
||||||
}
|
}
|
||||||
if (media.getCoordinates() != null) {
|
if (media.getCoordinates() != null) {
|
||||||
coordinates.setOnClickListener(v -> openMap(media.getCoordinates()));
|
coordinates.setOnClickListener(v -> openMap(media.getCoordinates()));
|
||||||
}
|
}
|
||||||
if (delete.getVisibility()==View.VISIBLE){
|
if (delete.getVisibility() == View.VISIBLE) {
|
||||||
delete.setOnClickListener(v -> {
|
delete.setOnClickListener(v -> {
|
||||||
|
delete.setEnabled(false);
|
||||||
|
delete.setTextColor(getResources().getColor(R.color.deleteButtonLight));
|
||||||
AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
|
AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
|
||||||
alert.setMessage("Why should this file be deleted?");
|
alert.setMessage("Why should this file be deleted?");
|
||||||
final EditText input = new EditText(getActivity());
|
final EditText input = new EditText(getActivity());
|
||||||
|
|
@ -343,6 +351,11 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
||||||
d.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
|
d.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (nominatedforDeletion.getVisibility() == View.VISIBLE){
|
||||||
|
seeMore.setOnClickListener(v -> {
|
||||||
|
openWebBrowser(media.getFilePageTitle().getMobileUri().toString());
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rebuildCatList() {
|
private void rebuildCatList() {
|
||||||
|
|
@ -366,7 +379,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
||||||
viewIntent.setAction(Intent.ACTION_VIEW);
|
viewIntent.setAction(Intent.ACTION_VIEW);
|
||||||
viewIntent.setData(new PageTitle(selectedCategoryTitle).getCanonicalUri());
|
viewIntent.setData(new PageTitle(selectedCategoryTitle).getCanonicalUri());
|
||||||
//check if web browser available
|
//check if web browser available
|
||||||
if(viewIntent.resolveActivity(getActivity().getPackageManager()) != null){
|
if (viewIntent.resolveActivity(getActivity().getPackageManager()) != null) {
|
||||||
startActivity(viewIntent);
|
startActivity(viewIntent);
|
||||||
} else {
|
} else {
|
||||||
Toast toast = Toast.makeText(getContext(), getString(R.string.no_web_browser), LENGTH_SHORT);
|
Toast toast = Toast.makeText(getContext(), getString(R.string.no_web_browser), LENGTH_SHORT);
|
||||||
|
|
@ -434,6 +447,16 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
||||||
return media.getCoordinates().getPrettyCoordinateString();
|
return media.getCoordinates().getPrettyCoordinateString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkDeletion(Media media){
|
||||||
|
if (media.getRequestedDeletion()){
|
||||||
|
delete.setVisibility(View.GONE);
|
||||||
|
nominatedforDeletion.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
delete.setVisibility(View.VISIBLE);
|
||||||
|
nominatedforDeletion.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private @Nullable
|
private @Nullable
|
||||||
String licenseLink(Media media) {
|
String licenseLink(Media media) {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
package fr.free.nrw.commons.nearby;
|
package fr.free.nrw.commons.nearby;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
|
@ -10,6 +13,7 @@ import android.support.design.widget.BottomSheetBehavior;
|
||||||
|
|
||||||
import android.support.v4.app.FragmentTransaction;
|
import android.support.v4.app.FragmentTransaction;
|
||||||
import android.support.v7.app.AlertDialog;
|
import android.support.v7.app.AlertDialog;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
@ -33,6 +37,7 @@ import fr.free.nrw.commons.location.LatLng;
|
||||||
import fr.free.nrw.commons.location.LocationServiceManager;
|
import fr.free.nrw.commons.location.LocationServiceManager;
|
||||||
import fr.free.nrw.commons.location.LocationUpdateListener;
|
import fr.free.nrw.commons.location.LocationUpdateListener;
|
||||||
import fr.free.nrw.commons.theme.NavigationBaseActivity;
|
import fr.free.nrw.commons.theme.NavigationBaseActivity;
|
||||||
|
import fr.free.nrw.commons.utils.NetworkUtils;
|
||||||
import fr.free.nrw.commons.utils.UriSerializer;
|
import fr.free.nrw.commons.utils.UriSerializer;
|
||||||
|
|
||||||
import fr.free.nrw.commons.utils.ViewUtil;
|
import fr.free.nrw.commons.utils.ViewUtil;
|
||||||
|
|
@ -69,11 +74,14 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
||||||
private boolean lockNearbyView; //Determines if the nearby places needs to be refreshed
|
private boolean lockNearbyView; //Determines if the nearby places needs to be refreshed
|
||||||
private BottomSheetBehavior bottomSheetBehavior; // Behavior for list bottom sheet
|
private BottomSheetBehavior bottomSheetBehavior; // Behavior for list bottom sheet
|
||||||
private BottomSheetBehavior bottomSheetBehaviorForDetails; // Behavior for details bottom sheet
|
private BottomSheetBehavior bottomSheetBehaviorForDetails; // Behavior for details bottom sheet
|
||||||
private NearbyMapFragment nearbyMapFragment;
|
public NearbyMapFragment nearbyMapFragment;
|
||||||
private NearbyListFragment nearbyListFragment;
|
private NearbyListFragment nearbyListFragment;
|
||||||
private static final String TAG_RETAINED_MAP_FRAGMENT = NearbyMapFragment.class.getSimpleName();
|
private static final String TAG_RETAINED_MAP_FRAGMENT = NearbyMapFragment.class.getSimpleName();
|
||||||
private static final String TAG_RETAINED_LIST_FRAGMENT = NearbyListFragment.class.getSimpleName();
|
private static final String TAG_RETAINED_LIST_FRAGMENT = NearbyListFragment.class.getSimpleName();
|
||||||
|
|
||||||
|
private final String NETWORK_INTENT_ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
|
||||||
|
private BroadcastReceiver broadcastReceiver;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
@ -271,6 +279,7 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
||||||
super.onResume();
|
super.onResume();
|
||||||
lockNearbyView = false;
|
lockNearbyView = false;
|
||||||
checkGps();
|
checkGps();
|
||||||
|
addNetworkBroadcastReceiver();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -283,9 +292,28 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
||||||
// to the retained fragment object to perform its own cleanup.
|
// to the retained fragment object to perform its own cleanup.
|
||||||
removeMapFragment();
|
removeMapFragment();
|
||||||
removeListFragment();
|
removeListFragment();
|
||||||
|
unregisterReceiver(broadcastReceiver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addNetworkBroadcastReceiver() {
|
||||||
|
IntentFilter intentFilter = new IntentFilter(NETWORK_INTENT_ACTION);
|
||||||
|
|
||||||
|
broadcastReceiver = new BroadcastReceiver() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
if (NetworkUtils.isInternetConnectionEstablished(NearbyActivity.this)) {
|
||||||
|
refreshView(LocationServiceManager
|
||||||
|
.LocationChangeType.LOCATION_SIGNIFICANTLY_CHANGED);
|
||||||
|
} else {
|
||||||
|
ViewUtil.showLongToast(NearbyActivity.this, getString(R.string.no_internet));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.registerReceiver(broadcastReceiver, intentFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -297,6 +325,12 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
||||||
if (lockNearbyView) {
|
if (lockNearbyView) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!NetworkUtils.isInternetConnectionEstablished(this)) {
|
||||||
|
hideProgressBar();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
locationManager.registerLocationManager();
|
locationManager.registerLocationManager();
|
||||||
LatLng lastLocation = locationManager.getLastLocation();
|
LatLng lastLocation = locationManager.getLastLocation();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -394,11 +394,9 @@ public class NearbyMapFragment extends DaggerFragment {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Remove texts if it doesnt fit
|
// Remove button text if they exceed 1 line or if internal layout has not been built
|
||||||
if (wikipediaButtonText.getLineCount() > 1
|
// Only need to check for directions button because it is the longest
|
||||||
|| wikidataButtonText.getLineCount() > 1
|
if (directionsButtonText.getLineCount() > 1 || directionsButtonText.getLineCount() == 0) {
|
||||||
|| commonsButtonText.getLineCount() > 1
|
|
||||||
|| directionsButtonText.getLineCount() > 1) {
|
|
||||||
wikipediaButtonText.setVisibility(View.GONE);
|
wikipediaButtonText.setVisibility(View.GONE);
|
||||||
wikidataButtonText.setVisibility(View.GONE);
|
wikidataButtonText.setVisibility(View.GONE);
|
||||||
commonsButtonText.setVisibility(View.GONE);
|
commonsButtonText.setVisibility(View.GONE);
|
||||||
|
|
@ -583,7 +581,7 @@ public class NearbyMapFragment extends DaggerFragment {
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add amnchors back before making them visible again.
|
* Add anchors back before making them visible again.
|
||||||
* */
|
* */
|
||||||
private void addAnchorToBigFABs(FloatingActionButton floatingActionButton, int anchorID) {
|
private void addAnchorToBigFABs(FloatingActionButton floatingActionButton, int anchorID) {
|
||||||
CoordinatorLayout.LayoutParams params = new CoordinatorLayout.LayoutParams
|
CoordinatorLayout.LayoutParams params = new CoordinatorLayout.LayoutParams
|
||||||
|
|
@ -594,7 +592,7 @@ public class NearbyMapFragment extends DaggerFragment {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add amnchors back before making them visible again. Big and small fabs have different anchor
|
* Add anchors back before making them visible again. Big and small fabs have different anchor
|
||||||
* gravities, therefore the are two methods.
|
* gravities, therefore the are two methods.
|
||||||
* */
|
* */
|
||||||
private void addAnchorToSmallFABs(FloatingActionButton floatingActionButton, int anchorID) {
|
private void addAnchorToSmallFABs(FloatingActionButton floatingActionButton, int anchorID) {
|
||||||
|
|
@ -651,9 +649,6 @@ public class NearbyMapFragment extends DaggerFragment {
|
||||||
DirectUpload directUpload = new DirectUpload(this, controller);
|
DirectUpload directUpload = new DirectUpload(this, controller);
|
||||||
storeSharedPrefs();
|
storeSharedPrefs();
|
||||||
directUpload.initiateGalleryUpload();
|
directUpload.initiateGalleryUpload();
|
||||||
|
|
||||||
//TODO: App crashes after image upload completes
|
|
||||||
//TODO: Handle onRequestPermissionsResult
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
package fr.free.nrw.commons.utils;
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.net.ConnectivityManager;
|
||||||
|
import android.net.NetworkInfo;
|
||||||
|
|
||||||
|
public class NetworkUtils {
|
||||||
|
|
||||||
|
public static boolean isInternetConnectionEstablished(Context context) {
|
||||||
|
ConnectivityManager cm =
|
||||||
|
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
|
|
||||||
|
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
|
||||||
|
return activeNetwork != null &&
|
||||||
|
activeNetwork.isConnectedOrConnecting();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
package fr.free.nrw.commons.utils;
|
package fr.free.nrw.commons.utils;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.support.design.widget.Snackbar;
|
import android.support.design.widget.Snackbar;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
public class ViewUtil {
|
public class ViewUtil {
|
||||||
|
|
||||||
|
|
@ -9,4 +11,9 @@ public class ViewUtil {
|
||||||
Snackbar.make(view, messageResourceId, Snackbar.LENGTH_SHORT).show();
|
Snackbar.make(view, messageResourceId, Snackbar.LENGTH_SHORT).show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void showLongToast(Context context, String text) {
|
||||||
|
Toast.makeText(context, text,
|
||||||
|
Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
32
app/src/main/res/drawable/bg_delete_button.xml
Normal file
32
app/src/main/res/drawable/bg_delete_button.xml
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:state_enabled="true" >
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid
|
||||||
|
android:color="@color/deleteButton"/>
|
||||||
|
<corners
|
||||||
|
android:radius="3dp" />
|
||||||
|
<stroke
|
||||||
|
android:width="5px"
|
||||||
|
android:color="@color/deleteRed" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:state_enabled="false" >
|
||||||
|
<shape
|
||||||
|
android:shape="rectangle">
|
||||||
|
<solid
|
||||||
|
android:color="@color/deleteButtonDark"/>
|
||||||
|
<corners
|
||||||
|
android:radius="3dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
|
||||||
|
</selector>
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<android.support.design.widget.CoordinatorLayout
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:id="@+id/coordinator_layout"
|
android:id="@+id/coordinator_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|
@ -21,9 +21,10 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content" />
|
android:layout_height="wrap_content" />
|
||||||
|
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:layout_below="@id/toolbar"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
|
@ -37,33 +38,14 @@
|
||||||
android:id="@+id/container"
|
android:id="@+id/container"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
<android.support.design.widget.FloatingActionButton
|
|
||||||
android:id="@+id/fab_list"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:fabSize="mini"
|
|
||||||
android:layout_alignBottom="@id/toolbar"
|
|
||||||
android:layout_alignParentRight="true"
|
|
||||||
android:layout_marginRight="28dp"
|
|
||||||
android:layout_marginBottom="-96dp"
|
|
||||||
android:visibility="invisible"
|
|
||||||
app:elevation="6dp"
|
|
||||||
app:pressedTranslationZ="12dp"
|
|
||||||
app:backgroundTint="@color/button_blue"
|
|
||||||
android:clickable="true"
|
|
||||||
app:srcCompat="@drawable/ic_list_white_24dp"
|
|
||||||
android:scaleType="center"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<View
|
<View
|
||||||
android:id="@+id/transparentView"
|
android:id="@+id/transparentView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_alignParentLeft="true"
|
android:layout_alignParentLeft="true"
|
||||||
android:layout_alignParentStart="true"
|
android:layout_below="@id/toolbar"
|
||||||
android:layout_alignParentTop="true"
|
|
||||||
android:layout_marginTop="18dp"
|
|
||||||
android:background="#aa969696"
|
android:background="#aa969696"
|
||||||
android:elevation="6dp">
|
android:elevation="6dp">
|
||||||
|
|
||||||
|
|
@ -88,7 +70,7 @@
|
||||||
|
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
<include layout="@layout/bottom_sheet_nearby" />
|
<include layout="@layout/bottom_sheet_nearby" />
|
||||||
|
|
||||||
<include
|
<include
|
||||||
|
|
|
||||||
|
|
@ -251,10 +251,38 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/small_gap" />
|
android:layout_height="@dimen/small_gap" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/nominatedDeletionBanner"
|
||||||
|
android:background="@color/deleteRed"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="@dimen/standard_gap"
|
||||||
|
android:visibility="gone">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/nominated_for_deletion"
|
||||||
|
android:textColor="@color/primaryTextColor"
|
||||||
|
android:textSize="@dimen/normal_text"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/seeMore"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/nominated_see_more"
|
||||||
|
android:paddingTop="@dimen/standard_gap"
|
||||||
|
android:textColor="@color/primaryTextColor"
|
||||||
|
android:textSize="@dimen/normal_text"
|
||||||
|
android:textStyle="bold"/>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/nominateDeletion"
|
android:id="@+id/nominateDeletion"
|
||||||
style="?android:attr/buttonBarButtonStyle"
|
android:background="@drawable/bg_delete_button"
|
||||||
android:textColor="@color/deleteTextColor"
|
android:textColor="@color/primaryTextColor"
|
||||||
android:layout_margin="@dimen/standard_gap"
|
android:layout_margin="@dimen/standard_gap"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
|
||||||
|
|
@ -1,43 +1,50 @@
|
||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<group android:id="@+id/drawer_main">
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_home"
|
||||||
|
android:icon="@drawable/ic_home_black_24dp"
|
||||||
|
android:title="@string/navigation_item_home" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_home"
|
android:id="@+id/action_nearby"
|
||||||
android:icon="@drawable/ic_home_black_24dp"
|
android:icon="@drawable/ic_location_black_24dp"
|
||||||
android:title="@string/navigation_item_home"/>
|
android:title="@string/navigation_item_nearby" />
|
||||||
|
</group>
|
||||||
|
<group android:id="@+id/drawer_account">
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_notifications"
|
||||||
|
android:icon="@drawable/ic_notifications_black_24dp"
|
||||||
|
android:title="@string/navigation_item_notification" />
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_nearby"
|
|
||||||
android:icon="@drawable/ic_location_black_24dp"
|
|
||||||
android:title="@string/navigation_item_nearby"/>
|
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_notifications"
|
android:id="@+id/action_settings"
|
||||||
android:icon="@drawable/ic_notifications_black_24dp"
|
android:icon="@drawable/ic_settings_black_24dp"
|
||||||
android:title="@string/navigation_item_notification"/>
|
android:title="@string/navigation_item_settings" />
|
||||||
|
|
||||||
<item
|
</group>
|
||||||
android:id="@+id/action_about"
|
<group android:id="@+id/drawer_contact">
|
||||||
android:icon="@drawable/ic_info_outline_black_24dp"
|
<item
|
||||||
android:title="@string/navigation_item_about"/>
|
android:id="@+id/action_about"
|
||||||
|
android:icon="@drawable/ic_info_outline_black_24dp"
|
||||||
|
android:title="@string/navigation_item_about" />
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_introduction"
|
||||||
|
android:icon="@drawable/ic_help_black_24dp"
|
||||||
|
android:title="@string/navigation_item_info" />
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_settings"
|
android:id="@+id/action_feedback"
|
||||||
android:icon="@drawable/ic_settings_black_24dp"
|
android:icon="@drawable/ic_feedback_black_24dp"
|
||||||
android:title="@string/navigation_item_settings"/>
|
android:title="@string/navigation_item_feedback" />
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_introduction"
|
|
||||||
android:icon="@drawable/ic_help_black_24dp"
|
|
||||||
android:title="@string/navigation_item_info"/>
|
|
||||||
|
|
||||||
<item
|
</group>
|
||||||
android:id="@+id/action_feedback"
|
|
||||||
android:icon="@drawable/ic_feedback_black_24dp"
|
|
||||||
android:title="@string/navigation_item_feedback"/>
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_logout"
|
|
||||||
android:icon="@drawable/ic_exit_to_app_black_24dp"
|
|
||||||
android:title="@string/navigation_item_logout"/>
|
|
||||||
|
|
||||||
|
<group android:id="@+id/drawer_logout">
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_logout"
|
||||||
|
android:icon="@drawable/ic_exit_to_app_black_24dp"
|
||||||
|
android:title="@string/navigation_item_logout" />
|
||||||
|
</group>
|
||||||
</menu>
|
</menu>
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,10 @@
|
||||||
<color name="primaryTextColor">#ffffff</color>
|
<color name="primaryTextColor">#ffffff</color>
|
||||||
<color name="secondaryTextColor">#000000</color>
|
<color name="secondaryTextColor">#000000</color>
|
||||||
|
|
||||||
<color name="deleteTextColor">#d50000</color>
|
<color name="deleteRed">#90960a0a</color>
|
||||||
|
<color name="deleteButton">#44000000</color>
|
||||||
|
<color name="deleteButtonDark">#88000000</color>
|
||||||
|
<color name="deleteButtonLight">#44ffffff</color>
|
||||||
|
|
||||||
<!-- Some colours are same for dark/light themes. They are written two times in case
|
<!-- Some colours are same for dark/light themes. They are written two times in case
|
||||||
we want to change light ones later.
|
we want to change light ones later.
|
||||||
|
|
|
||||||
|
|
@ -233,6 +233,8 @@
|
||||||
<string name="no_web_browser">No web browser found to open URL</string>
|
<string name="no_web_browser">No web browser found to open URL</string>
|
||||||
<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_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>
|
||||||
|
|
||||||
<string name="nearby_location_has_not_changed">Location has not changed.</string>
|
<string name="nearby_location_has_not_changed">Location has not changed.</string>
|
||||||
|
|
@ -250,15 +252,19 @@
|
||||||
<string name="nearby_wikidata">WIKIDATA</string>
|
<string name="nearby_wikidata">WIKIDATA</string>
|
||||||
<string name="nearby_wikipedia">WIKIPEDIA</string>
|
<string name="nearby_wikipedia">WIKIPEDIA</string>
|
||||||
<string name="nearby_commons">COMMONS</string>
|
<string name="nearby_commons">COMMONS</string>
|
||||||
<string name="about_rate_us"><u>Rate Us</u></string>
|
|
||||||
<string name="about_faq">Frequently Asked Questions</string>
|
|
||||||
<string name="welcome_skip_button">Skip Tutorial</string>
|
|
||||||
|
|
||||||
|
<string name="about_rate_us"><u>Rate us</u></string>
|
||||||
|
<string name="about_faq">FAQ</string>
|
||||||
|
<string name="welcome_skip_button">Skip Tutorial</string>
|
||||||
|
|
||||||
|
<string name="no_internet">Internet unavailable</string>
|
||||||
|
<string name="internet_established">Internet available</string>
|
||||||
<string name="error_notifications">Error fetching notifications</string>
|
<string name="error_notifications">Error fetching notifications</string>
|
||||||
<string name="no_notifications">No notifications found</string>
|
<string name="no_notifications">No notifications found</string>
|
||||||
|
|
||||||
<string name="about_translate"><u>Translate</u></string>
|
<string name="about_translate"><u>Translate</u></string>
|
||||||
<string name="about_translate_title">Languages</string>
|
<string name="about_translate_title">Languages</string>
|
||||||
<string name="about_translate_message">Select the langauge you want translations for ?</string>
|
<string name="about_translate_message">Select the language that you would like to submit translations for</string>
|
||||||
<string name="about_translate_proceed">Proceed</string>
|
<string name="about_translate_proceed">Proceed</string>
|
||||||
<string name="about_translate_cancel">Cancel</string>
|
<string name="about_translate_cancel">Cancel</string>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,93 +0,0 @@
|
||||||
package fr.free.nrw.commons.nearby;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.support.v7.widget.RecyclerView;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.mockito.InjectMocks;
|
|
||||||
import org.mockito.Mock;
|
|
||||||
import org.mockito.MockitoAnnotations;
|
|
||||||
import org.robolectric.Robolectric;
|
|
||||||
import org.robolectric.RobolectricTestRunner;
|
|
||||||
import org.robolectric.annotation.Config;
|
|
||||||
|
|
||||||
import edu.emory.mathcs.backport.java.util.Collections;
|
|
||||||
import fr.free.nrw.commons.BuildConfig;
|
|
||||||
import fr.free.nrw.commons.R;
|
|
||||||
import fr.free.nrw.commons.TestCommonsApplication;
|
|
||||||
import fr.free.nrw.commons.location.LatLng;
|
|
||||||
import fr.free.nrw.commons.location.LocationServiceManager;
|
|
||||||
import io.reactivex.android.plugins.RxAndroidPlugins;
|
|
||||||
import io.reactivex.plugins.RxJavaPlugins;
|
|
||||||
import io.reactivex.schedulers.Schedulers;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.mockito.Matchers.any;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
import static org.mockito.Mockito.when;
|
|
||||||
import static org.robolectric.Shadows.shadowOf;
|
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
|
||||||
@Config(constants = BuildConfig.class, sdk = 21, application = TestCommonsApplication.class)
|
|
||||||
public class NearbyActivityTest {
|
|
||||||
|
|
||||||
private static final LatLng ST_LOUIS_MO_LAT_LNG
|
|
||||||
= new LatLng(38.627003, -90.199402, 0);
|
|
||||||
private static final Place AIRPORT = new Place(
|
|
||||||
"name", Place.Label.AIRPORT,
|
|
||||||
"desc", null,
|
|
||||||
new LatLng(38.6270, -90.1994, 0),
|
|
||||||
null, null);
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private LocationServiceManager locationManager;
|
|
||||||
|
|
||||||
@Mock
|
|
||||||
private NearbyController nearbyController;
|
|
||||||
|
|
||||||
@InjectMocks
|
|
||||||
private NearbyActivity nearbyActivity;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
// ensure waiting all threads to complete
|
|
||||||
RxJavaPlugins.setIoSchedulerHandler(
|
|
||||||
scheduler -> Schedulers.trampoline());
|
|
||||||
RxJavaPlugins.setComputationSchedulerHandler(
|
|
||||||
scheduler -> Schedulers.trampoline());
|
|
||||||
RxJavaPlugins.setNewThreadSchedulerHandler(
|
|
||||||
scheduler -> Schedulers.trampoline());
|
|
||||||
RxAndroidPlugins.setInitMainThreadSchedulerHandler(
|
|
||||||
scheduler -> Schedulers.trampoline());
|
|
||||||
|
|
||||||
nearbyActivity = Robolectric.setupActivity(NearbyActivity.class);
|
|
||||||
|
|
||||||
// replace methods and fields with mocks
|
|
||||||
MockitoAnnotations.initMocks(this);
|
|
||||||
when(locationManager.getLastLocation()).thenReturn(ST_LOUIS_MO_LAT_LNG);
|
|
||||||
when(locationManager.isProviderEnabled()).thenReturn(true);
|
|
||||||
when(nearbyController.loadAttractionsFromLocation(any(LatLng.class)))
|
|
||||||
.thenReturn(mock(NearbyController.NearbyPlacesInfo.class));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void pressRefreshAndShowList() {
|
|
||||||
// MenuItem refresh = shadowOf(nearbyActivity).getOptionsMenu().findItem(R.id.action_refresh);
|
|
||||||
// nearbyActivity.onOptionsItemSelected(refresh);
|
|
||||||
//
|
|
||||||
// Fragment nearbyListFragment = nearbyActivity.getSupportFragmentManager()
|
|
||||||
// .findFragmentByTag(NearbyListFragment.class.getSimpleName());
|
|
||||||
// assertNotNull(nearbyListFragment);
|
|
||||||
//
|
|
||||||
// // one element (AIRPORT) exists in the list
|
|
||||||
// RecyclerView view = nearbyListFragment.getView().findViewById(R.id.listView);
|
|
||||||
// assertNotNull(view.findViewHolderForAdapterPosition(0));
|
|
||||||
// assertNull(view.findViewHolderForAdapterPosition(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,129 +0,0 @@
|
||||||
package fr.free.nrw.commons.nearby;
|
|
||||||
|
|
||||||
import android.support.annotation.NonNull;
|
|
||||||
import android.widget.FrameLayout;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
|
||||||
import com.pedrogomez.renderers.RendererViewHolder;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
import org.robolectric.RobolectricTestRunner;
|
|
||||||
import org.robolectric.RuntimeEnvironment;
|
|
||||||
import org.robolectric.Shadows;
|
|
||||||
import org.robolectric.annotation.Config;
|
|
||||||
import org.robolectric.shadows.ShadowDrawable;
|
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
import fr.free.nrw.commons.BuildConfig;
|
|
||||||
import fr.free.nrw.commons.R;
|
|
||||||
import fr.free.nrw.commons.TestCommonsApplication;
|
|
||||||
import fr.free.nrw.commons.location.LatLng;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
|
|
||||||
@RunWith(RobolectricTestRunner.class)
|
|
||||||
@Config(constants = BuildConfig.class, sdk = 21, application = TestCommonsApplication.class)
|
|
||||||
public class NearbyAdapterFactoryTest {
|
|
||||||
|
|
||||||
private static final Place PLACE = new Place("name", Place.Label.AIRPORT,
|
|
||||||
"desc", null, new LatLng(38.6270, -90.1994, 0), null, null);
|
|
||||||
|
|
||||||
private static final Place UNKNOWN_PLACE = new Place("name", Place.Label.UNKNOWN,
|
|
||||||
"desc", null, new LatLng(39.7392, -104.9903, 0), null, null);
|
|
||||||
|
|
||||||
private Place clickedPlace;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void factoryHandlesNullListAndNullListener() {
|
|
||||||
NearbyAdapterFactory testObject = new NearbyAdapterFactory();
|
|
||||||
RVRendererAdapter<Place> result = testObject.create(null);
|
|
||||||
assertNotNull(result);
|
|
||||||
assertEquals(0, result.getItemCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void factoryHandlesEmptyListAndNullListener() {
|
|
||||||
NearbyAdapterFactory testObject = new NearbyAdapterFactory();
|
|
||||||
RVRendererAdapter<Place> result = testObject.create(Collections.<Place>emptyList());
|
|
||||||
assertNotNull(result);
|
|
||||||
assertEquals(0, result.getItemCount());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void factoryHandlesNonEmptyListAndNullListener() {
|
|
||||||
NearbyAdapterFactory testObject = new NearbyAdapterFactory();
|
|
||||||
RVRendererAdapter<Place> result = testObject.create(Collections.singletonList(PLACE));
|
|
||||||
assertNotNull(result);
|
|
||||||
assertEquals(1, result.getItemCount());
|
|
||||||
assertEquals(PLACE, result.getItem(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void rendererCorrectlyBound() {
|
|
||||||
NearbyAdapterFactory testObject = new NearbyAdapterFactory();
|
|
||||||
RVRendererAdapter<Place> result = testObject.create(Collections.singletonList(PLACE));
|
|
||||||
|
|
||||||
RendererViewHolder viewHolder = renderComponent(result);
|
|
||||||
|
|
||||||
// test that the values we gave are actually rendered
|
|
||||||
assertNotNull(viewHolder.itemView.findViewById(R.id.tvName));
|
|
||||||
assertEquals(PLACE.name,
|
|
||||||
((TextView) viewHolder.itemView.findViewById(R.id.tvName)).getText().toString());
|
|
||||||
|
|
||||||
assertNotNull(viewHolder.itemView.findViewById(R.id.tvDesc));
|
|
||||||
assertEquals(PLACE.getLongDescription(),
|
|
||||||
((TextView) viewHolder.itemView.findViewById(R.id.tvDesc)).getText().toString());
|
|
||||||
|
|
||||||
assertNotNull(viewHolder.itemView.findViewById(R.id.distance));
|
|
||||||
assertEquals("",
|
|
||||||
((TextView) viewHolder.itemView.findViewById(R.id.distance)).getText().toString());
|
|
||||||
|
|
||||||
assertNotNull(viewHolder.itemView.findViewById(R.id.icon));
|
|
||||||
ImageView imageView = (ImageView) viewHolder.itemView.findViewById(R.id.icon);
|
|
||||||
ShadowDrawable shadow = Shadows.shadowOf(imageView.getDrawable());
|
|
||||||
assertEquals(R.drawable.round_icon_airport, shadow.getCreatedFromResId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void rendererCorrectlyBoundForUnknownPlace() {
|
|
||||||
NearbyAdapterFactory testObject = new NearbyAdapterFactory();
|
|
||||||
RVRendererAdapter<Place> result = testObject.create(Collections.singletonList(UNKNOWN_PLACE));
|
|
||||||
|
|
||||||
RendererViewHolder viewHolder = renderComponent(result);
|
|
||||||
|
|
||||||
assertNotNull(viewHolder.itemView.findViewById(R.id.tvDesc));
|
|
||||||
assertEquals(RuntimeEnvironment.application.getString(R.string.no_description_found),
|
|
||||||
((TextView) viewHolder.itemView.findViewById(R.id.tvDesc)).getText().toString());
|
|
||||||
|
|
||||||
assertNotNull(viewHolder.itemView.findViewById(R.id.icon));
|
|
||||||
ImageView imageView = (ImageView) viewHolder.itemView.findViewById(R.id.icon);
|
|
||||||
ShadowDrawable shadow = Shadows.shadowOf(imageView.getDrawable());
|
|
||||||
assertEquals(R.drawable.round_icon_unknown, shadow.getCreatedFromResId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void clickView() {
|
|
||||||
NearbyAdapterFactory testObject = new NearbyAdapterFactory();
|
|
||||||
RVRendererAdapter<Place> result = testObject.create(Collections.singletonList(PLACE));
|
|
||||||
RendererViewHolder viewHolder = renderComponent(result);
|
|
||||||
|
|
||||||
viewHolder.itemView.performClick();
|
|
||||||
|
|
||||||
assertEquals(PLACE, clickedPlace);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NonNull
|
|
||||||
private RendererViewHolder renderComponent(RVRendererAdapter<Place> result) {
|
|
||||||
FrameLayout viewGroup = new FrameLayout(RuntimeEnvironment.application);
|
|
||||||
int itemViewType = result.getItemViewType(0);
|
|
||||||
RendererViewHolder viewHolder = result.onCreateViewHolder(viewGroup, itemViewType);
|
|
||||||
assertNotNull(viewHolder);
|
|
||||||
result.bindViewHolder(viewHolder, 0);
|
|
||||||
return viewHolder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue