mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-28 05:13:53 +01:00
Merge branch 'master' into featuredImages
This commit is contained in:
commit
b108dff460
276 changed files with 4290 additions and 2539 deletions
|
|
@ -6,11 +6,15 @@ import android.content.DialogInterface;
|
|||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.Html;
|
||||
import android.text.SpannableString;
|
||||
import android.text.style.UnderlineSpan;
|
||||
import android.util.Log;
|
||||
import android.support.customtabs.CustomTabsIntent;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.LinearLayout;
|
||||
|
|
@ -62,6 +66,18 @@ public class AboutActivity extends NavigationBaseActivity {
|
|||
content.setSpan(new UnderlineSpan(), 0, content.length(), 0);
|
||||
faqText.setText(content);
|
||||
versionText.setText(BuildConfig.VERSION_NAME);
|
||||
TextView rate_us = findViewById(R.id.about_rate_us);
|
||||
TextView privacy_policy = findViewById(R.id.about_privacy_policy);
|
||||
TextView translate = findViewById(R.id.about_translate);
|
||||
TextView credits = findViewById(R.id.about_credits);
|
||||
TextView faq = findViewById(R.id.about_faq);
|
||||
|
||||
rate_us.setText(Html.fromHtml(getString(R.string.about_rate_us)));
|
||||
privacy_policy.setText(Html.fromHtml(getString(R.string.about_privacy_policy)));
|
||||
translate.setText(Html.fromHtml(getString(R.string.about_translate)));
|
||||
credits.setText(Html.fromHtml(getString(R.string.about_credits)));
|
||||
faq.setText(Html.fromHtml(getString(R.string.about_faq)));
|
||||
|
||||
initDrawer();
|
||||
}
|
||||
|
||||
|
|
@ -108,6 +124,28 @@ public class AboutActivity extends NavigationBaseActivity {
|
|||
Utils.handleWebUrl(this,Uri.parse("https://github.com/commons-app/apps-android-commons/wiki/Frequently-Asked-Questions\\"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.menu_about, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.share_app_icon:
|
||||
Intent sendIntent = new Intent();
|
||||
sendIntent.setAction(Intent.ACTION_SEND);
|
||||
sendIntent.putExtra(Intent.EXTRA_TEXT, "http://play.google.com/store/apps/details?id=fr.free.nrw.commons");
|
||||
sendIntent.setType("text/plain");
|
||||
startActivity(Intent.createChooser(sendIntent, "Share app via..."));
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.about_translate)
|
||||
public void launchTranslate(View view) {
|
||||
final ArrayAdapter<String> languageAdapter = new ArrayAdapter<String>(AboutActivity.this,
|
||||
|
|
|
|||
|
|
@ -54,9 +54,11 @@ public class CommonsApplication extends MultiDexApplication {
|
|||
|
||||
public static final String FEEDBACK_EMAIL = "commons-app-android@googlegroups.com";
|
||||
|
||||
public static final String FEEDBACK_EMAIL_SUBJECT = "Commons Android App (%s) Feedback";
|
||||
|
||||
public static final String LOGS_PRIVATE_EMAIL = "commons-app-android-private@googlegroups.com";
|
||||
|
||||
public static final String FEEDBACK_EMAIL_SUBJECT = "Commons Android App (%s) Feedback";
|
||||
public static final String LOGS_PRIVATE_EMAIL_SUBJECT = "Commons Android App (%s) Logs";
|
||||
|
||||
private RefWatcher refWatcher;
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ public class Media implements Parcelable {
|
|||
protected String license;
|
||||
protected String creator;
|
||||
protected ArrayList<String> categories; // as loaded at runtime?
|
||||
protected boolean requestedDeletion;
|
||||
private Map<String, String> descriptions; // multilingual descriptions as loaded
|
||||
private HashMap<String, Object> tags = new HashMap<>();
|
||||
private @Nullable LatLng coordinates;
|
||||
|
|
@ -416,4 +417,12 @@ public class Media implements Parcelable {
|
|||
parcel.writeStringList(categories);
|
||||
parcel.writeMap(descriptions);
|
||||
}
|
||||
|
||||
public void setRequestedDeletion(){
|
||||
requestedDeletion = true;
|
||||
}
|
||||
|
||||
public boolean getRequestedDeletion(){
|
||||
return requestedDeletion;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import timber.log.Timber;
|
|||
public class MediaDataExtractor {
|
||||
private final MediaWikiApi mediaWikiApi;
|
||||
private boolean fetched;
|
||||
private boolean deletionStatus;
|
||||
private ArrayList<String> categories;
|
||||
private Map<String, String> descriptions;
|
||||
private String license;
|
||||
|
|
@ -59,6 +60,14 @@ public class MediaDataExtractor {
|
|||
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);
|
||||
|
||||
// In-page category links are extracted from source, as XML doesn't cover [[links]]
|
||||
|
|
@ -296,6 +305,9 @@ public class MediaDataExtractor {
|
|||
if (license != null) {
|
||||
media.setLicense(license);
|
||||
}
|
||||
if (deletionStatus){
|
||||
media.setRequestedDeletion();
|
||||
}
|
||||
|
||||
// add author, date, etc fields
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ public class Utils {
|
|||
}
|
||||
}
|
||||
|
||||
public static void handleWebUrl(Context context,Uri url){
|
||||
public static void handleWebUrl(Context context, Uri url) {
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, url);
|
||||
if (browserIntent.resolveActivity(context.getPackageManager()) == null) {
|
||||
Toast toast = Toast.makeText(context, context.getString(R.string.no_web_browser), LENGTH_SHORT);
|
||||
|
|
|
|||
|
|
@ -280,8 +280,11 @@ public class CategorizationFragment extends CommonsDaggerSupportFragment {
|
|||
|
||||
private Observable<CategoryItem> directCategories() {
|
||||
String directCategory = directPrefs.getString("Category", "");
|
||||
// Strip newlines to prevent blank categories, and to tidy existing categories
|
||||
directCategory = directCategory.replace("\n", "");
|
||||
|
||||
List<String> categoryList = new ArrayList<>();
|
||||
Timber.d("Direct category found: " + directCategory);
|
||||
Timber.d("Direct category found: " + "'" + directCategory + "'");
|
||||
|
||||
if (!directCategory.equals("")) {
|
||||
hasDirectCategories = true;
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ public class CategoryDao {
|
|||
return items;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
Category fromCursor(Cursor cursor) {
|
||||
// Hardcoding column positions!
|
||||
return new Category(
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
package fr.free.nrw.commons.delete;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.NotificationManager;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
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.util.Calendar;
|
||||
import java.util.Locale;
|
||||
|
|
@ -18,17 +21,18 @@ import fr.free.nrw.commons.di.ApplicationlessInjection;
|
|||
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
||||
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> {
|
||||
|
||||
private static final int SUCCESS = 0;
|
||||
private static final int FAILED = -1;
|
||||
private static final int ALREADY_DELETED = -2;
|
||||
public class DeleteTask extends AsyncTask<Void, Integer, Boolean> {
|
||||
|
||||
@Inject MediaWikiApi mwApi;
|
||||
@Inject SessionManager sessionManager;
|
||||
|
||||
public static final int NOTIFICATION_DELETE = 1;
|
||||
|
||||
private NotificationManager notificationManager;
|
||||
private Builder notificationBuilder;
|
||||
private Context context;
|
||||
private Media media;
|
||||
private String reason;
|
||||
|
|
@ -45,10 +49,19 @@ public class DeleteTask extends AsyncTask<Void, Void, Integer> {
|
|||
.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,"Trying to nominate "+media.getDisplayTitle()+ " for deletion",Toast.LENGTH_SHORT);
|
||||
toast.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Integer doInBackground(Void ...voids) {
|
||||
protected Boolean doInBackground(Void ...voids) {
|
||||
publishProgress(0);
|
||||
|
||||
String editToken;
|
||||
String authCookie;
|
||||
String summary = "Nominating " + media.getFilename() +" for deletion.";
|
||||
|
|
@ -56,27 +69,6 @@ public class DeleteTask extends AsyncTask<Void, Void, Integer> {
|
|||
authCookie = sessionManager.getAuthCookie();
|
||||
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();
|
||||
String fileDeleteString = "{{delete|reason=" + reason +
|
||||
"|subpage=" +media.getFilename() +
|
||||
|
|
@ -84,91 +76,106 @@ public class DeleteTask extends AsyncTask<Void, Void, Integer> {
|
|||
"|month=" + calendar.getDisplayName(Calendar.MONTH,Calendar.LONG, Locale.getDefault()) +
|
||||
"|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" +
|
||||
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() +
|
||||
"}}\n";
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
|
||||
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() +
|
||||
"}} ~~~~";
|
||||
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",
|
||||
"User_Talk:"+sessionManager.getCurrentAccount().name,summary);
|
||||
publishProgress(5);
|
||||
}
|
||||
catch (Exception e) {
|
||||
Timber.d(e.getMessage());
|
||||
return FAILED;
|
||||
return false;
|
||||
}
|
||||
return SUCCESS;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Integer result) {
|
||||
protected void onProgressUpdate (Integer... values){
|
||||
super.onProgressUpdate(values);
|
||||
|
||||
String message = "";
|
||||
String title = "";
|
||||
switch (result){
|
||||
case SUCCESS:
|
||||
title = "Success";
|
||||
message = "Successfully nominated " + media.getDisplayTitle() + " deletion.\n" +
|
||||
"Check the webpage for more details";
|
||||
switch (values[0]){
|
||||
case 0:
|
||||
message = "Getting token";
|
||||
break;
|
||||
case FAILED:
|
||||
title = "Failed";
|
||||
message = "Could not request deletion. Something went wrong.";
|
||||
case 1:
|
||||
message = "Adding delete message to file";
|
||||
break;
|
||||
case ALREADY_DELETED:
|
||||
title = "Already Nominated";
|
||||
message = media.getDisplayTitle() + " has already been nominated for deletion.\n" +
|
||||
"Check the webpage for more details";
|
||||
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;
|
||||
}
|
||||
AlertDialog alert;
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(context);
|
||||
builder.setTitle(title);
|
||||
builder.setMessage(message);
|
||||
builder.setCancelable(true);
|
||||
builder.setPositiveButton(
|
||||
R.string.ok,
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {}
|
||||
});
|
||||
builder.setNeutralButton(R.string.view_browser,
|
||||
new DialogInterface.OnClickListener() {
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, media.getFilePageTitle().getMobileUri());
|
||||
startActivity(context,browserIntent,null);
|
||||
}
|
||||
});
|
||||
alert = builder.create();
|
||||
alert.show();
|
||||
|
||||
notificationBuilder.setContentTitle("Nominating "+media.getDisplayTitle()+" for deletion")
|
||||
.setStyle(new NotificationCompat.BigTextStyle()
|
||||
.bigText(message))
|
||||
.setSmallIcon(R.drawable.ic_launcher)
|
||||
.setProgress(5, values[0], false)
|
||||
.setOngoing(true);
|
||||
notificationManager.notify(NOTIFICATION_DELETE, notificationBuilder.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result) {
|
||||
String message = "";
|
||||
String title = "Nominating for Deletion";
|
||||
|
||||
if (result){
|
||||
title += ": Success";
|
||||
message = "Successfully nominated " + media.getDisplayTitle() + " deletion.";
|
||||
}
|
||||
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.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
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.di.CommonsDaggerSupportFragment;
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
import fr.free.nrw.commons.mwapi.MediaWikiApi;
|
||||
import fr.free.nrw.commons.ui.widget.CompatTextView;
|
||||
import timber.log.Timber;
|
||||
|
||||
|
|
@ -71,6 +71,9 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
|||
|
||||
@Inject
|
||||
Provider<MediaDataExtractor> mediaDataExtractorProvider;
|
||||
@Inject
|
||||
MediaWikiApi mwApi;
|
||||
|
||||
|
||||
private MediaWikiImageView image;
|
||||
private MediaDetailSpacer spacer;
|
||||
|
|
@ -82,6 +85,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
|||
private TextView license;
|
||||
private TextView coordinates;
|
||||
private TextView uploadedDate;
|
||||
private TextView seeMore;
|
||||
private LinearLayout nominatedforDeletion;
|
||||
private LinearLayout categoryContainer;
|
||||
private LinearLayout authorLayout;
|
||||
private Button delete;
|
||||
|
|
@ -142,6 +147,8 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
|||
license = (TextView) view.findViewById(R.id.mediaDetailLicense);
|
||||
coordinates = (TextView) view.findViewById(R.id.mediaDetailCoordinates);
|
||||
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);
|
||||
categoryContainer = (LinearLayout) view.findViewById(R.id.mediaDetailCategoryContainer);
|
||||
authorLayout = (LinearLayout) view.findViewById(R.id.authorLinearLayout);
|
||||
|
|
@ -247,7 +254,6 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
|||
|
||||
if (success) {
|
||||
extractor.fill(media);
|
||||
|
||||
setTextFields(media);
|
||||
setOnClickListeners(media);
|
||||
} else {
|
||||
|
|
@ -300,21 +306,24 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
|||
}
|
||||
rebuildCatList();
|
||||
|
||||
delete.setVisibility(View.VISIBLE);
|
||||
checkDeletion(media);
|
||||
}
|
||||
|
||||
private void setOnClickListeners(final Media media) {
|
||||
if (licenseLink(media) != null) {
|
||||
license.setOnClickListener(v -> openWebBrowser(licenseLink(media)));
|
||||
} else {
|
||||
} else {
|
||||
Toast toast = Toast.makeText(getContext(), getString(R.string.null_url), Toast.LENGTH_SHORT);
|
||||
toast.show();
|
||||
}
|
||||
}
|
||||
if (media.getCoordinates() != null) {
|
||||
coordinates.setOnClickListener(v -> openMap(media.getCoordinates()));
|
||||
}
|
||||
if (delete.getVisibility()==View.VISIBLE){
|
||||
if (delete.getVisibility() == View.VISIBLE) {
|
||||
enableDeleteButton(true);
|
||||
|
||||
delete.setOnClickListener(v -> {
|
||||
|
||||
AlertDialog.Builder alert = new AlertDialog.Builder(getActivity());
|
||||
alert.setMessage("Why should this file be deleted?");
|
||||
final EditText input = new EditText(getActivity());
|
||||
|
|
@ -325,6 +334,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
|||
String reason = input.getText().toString();
|
||||
DeleteTask deleteTask = new DeleteTask(getActivity(), media, reason);
|
||||
deleteTask.execute();
|
||||
enableDeleteButton(false);
|
||||
}
|
||||
});
|
||||
alert.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
|
|
@ -359,6 +369,20 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
|||
d.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
|
||||
});
|
||||
}
|
||||
if (nominatedforDeletion.getVisibility() == View.VISIBLE){
|
||||
seeMore.setOnClickListener(v -> {
|
||||
openWebBrowser(media.getFilePageTitle().getMobileUri().toString());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void enableDeleteButton(boolean visibility) {
|
||||
delete.setEnabled(visibility);
|
||||
if(visibility) {
|
||||
delete.setTextColor(getResources().getColor(R.color.primaryTextColor));
|
||||
} else {
|
||||
delete.setTextColor(getResources().getColor(R.color.deleteButtonLight));
|
||||
}
|
||||
}
|
||||
|
||||
private void rebuildCatList() {
|
||||
|
|
@ -382,7 +406,7 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
|||
viewIntent.setAction(Intent.ACTION_VIEW);
|
||||
viewIntent.setData(new PageTitle(selectedCategoryTitle).getCanonicalUri());
|
||||
//check if web browser available
|
||||
if(viewIntent.resolveActivity(getActivity().getPackageManager()) != null){
|
||||
if (viewIntent.resolveActivity(getActivity().getPackageManager()) != null) {
|
||||
startActivity(viewIntent);
|
||||
} else {
|
||||
Toast toast = Toast.makeText(getContext(), getString(R.string.no_web_browser), LENGTH_SHORT);
|
||||
|
|
@ -450,6 +474,16 @@ public class MediaDetailFragment extends CommonsDaggerSupportFragment {
|
|||
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
|
||||
String licenseLink(Media media) {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import org.apache.http.params.CoreProtocolPNames;
|
|||
import org.apache.http.util.EntityUtils;
|
||||
import org.mediawiki.api.ApiResult;
|
||||
import org.mediawiki.api.MWApi;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
@ -41,16 +40,12 @@ import java.util.concurrent.Callable;
|
|||
import fr.free.nrw.commons.BuildConfig;
|
||||
import fr.free.nrw.commons.PageTitle;
|
||||
import fr.free.nrw.commons.notification.Notification;
|
||||
import fr.free.nrw.commons.notification.NotificationUtils;
|
||||
import in.yuvi.http.fluent.Http;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.Single;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static fr.free.nrw.commons.notification.NotificationType.UNKNOWN;
|
||||
import static fr.free.nrw.commons.notification.NotificationUtils.getNotificationFromApiResult;
|
||||
import static fr.free.nrw.commons.notification.NotificationUtils.getNotificationType;
|
||||
import static fr.free.nrw.commons.notification.NotificationUtils.isCommonsNotification;
|
||||
|
||||
/**
|
||||
* @author Addshore
|
||||
*/
|
||||
|
|
@ -434,33 +429,25 @@ public class ApacheHttpClientMediaWikiApi implements MediaWikiApi {
|
|||
.param("notprop", "list")
|
||||
.param("format", "xml")
|
||||
.param("meta", "notifications")
|
||||
.param("notfilter", "!read")
|
||||
// .param("meta", "notifications")
|
||||
.param("notformat", "model")
|
||||
.get()
|
||||
.getNode("/api/query/notifications/list");
|
||||
} catch (IOException e) {
|
||||
Timber.e("Failed to obtain searchCategories", e);
|
||||
}
|
||||
|
||||
if (notificationNode == null) {
|
||||
if (notificationNode == null
|
||||
|| notificationNode.getDocument() == null
|
||||
|| notificationNode.getDocument().getChildNodes() == null
|
||||
|| notificationNode.getDocument().getChildNodes().getLength() == 0) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
List<Notification> notifications = new ArrayList<>();
|
||||
|
||||
NodeList childNodes = notificationNode.getDocument().getChildNodes();
|
||||
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node node = childNodes.item(i);
|
||||
if (isCommonsNotification(node)
|
||||
&& !getNotificationType(node).equals(UNKNOWN)) {
|
||||
notifications.add(getNotificationFromApiResult(context, node));
|
||||
}
|
||||
}
|
||||
|
||||
return notifications;
|
||||
return NotificationUtils.getNotificationsFromList(context, childNodes);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean existingFile(String fileSha1) throws IOException {
|
||||
return api.action("query")
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import android.support.v7.app.AlertDialog;
|
|||
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.contributions.ContributionController;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
|
||||
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
|
||||
|
|
@ -23,46 +24,25 @@ class DirectUpload {
|
|||
this.controller = controller;
|
||||
}
|
||||
|
||||
void initiateCameraUpload() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (ContextCompat.checkSelfPermission(fragment.getActivity(), WRITE_EXTERNAL_STORAGE) != PERMISSION_GRANTED) {
|
||||
if (fragment.getActivity().shouldShowRequestPermissionRationale(WRITE_EXTERNAL_STORAGE)) {
|
||||
new AlertDialog.Builder(fragment.getActivity())
|
||||
.setMessage(fragment.getActivity().getString(R.string.write_storage_permission_rationale))
|
||||
.setPositiveButton("OK", (dialog, which) -> {
|
||||
fragment.getActivity().requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE}, 3);
|
||||
dialog.dismiss();
|
||||
})
|
||||
.setNegativeButton("Cancel", null)
|
||||
.create()
|
||||
.show();
|
||||
} else {
|
||||
fragment.getActivity().requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE}, 3);
|
||||
}
|
||||
} else {
|
||||
controller.startCameraCapture();
|
||||
}
|
||||
} else {
|
||||
controller.startCameraCapture();
|
||||
}
|
||||
}
|
||||
|
||||
// These permission requests will be handled by the Fragments.
|
||||
// Do not use requestCode 1 as it will conflict with NearbyActivity's requestCodes
|
||||
void initiateGalleryUpload() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (ContextCompat.checkSelfPermission(fragment.getActivity(), READ_EXTERNAL_STORAGE) != PERMISSION_GRANTED) {
|
||||
if (fragment.getActivity().shouldShowRequestPermissionRationale(READ_EXTERNAL_STORAGE)) {
|
||||
if (fragment.shouldShowRequestPermissionRationale(READ_EXTERNAL_STORAGE)) {
|
||||
new AlertDialog.Builder(fragment.getActivity())
|
||||
.setMessage(fragment.getActivity().getString(R.string.read_storage_permission_rationale))
|
||||
.setPositiveButton("OK", (dialog, which) -> {
|
||||
fragment.getActivity().requestPermissions(new String[]{READ_EXTERNAL_STORAGE}, 1);
|
||||
Timber.d("Requesting permissions for read external storage");
|
||||
fragment.requestPermissions(new String[]{READ_EXTERNAL_STORAGE}, 4);
|
||||
dialog.dismiss();
|
||||
})
|
||||
.setNegativeButton("Cancel", null)
|
||||
.create()
|
||||
.show();
|
||||
} else {
|
||||
fragment.getActivity().requestPermissions(new String[]{READ_EXTERNAL_STORAGE},
|
||||
1);
|
||||
fragment.requestPermissions(new String[]{READ_EXTERNAL_STORAGE},
|
||||
4);
|
||||
}
|
||||
} else {
|
||||
controller.startGalleryPick();
|
||||
|
|
@ -72,4 +52,28 @@ class DirectUpload {
|
|||
controller.startGalleryPick();
|
||||
}
|
||||
}
|
||||
|
||||
void initiateCameraUpload() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (ContextCompat.checkSelfPermission(fragment.getActivity(), WRITE_EXTERNAL_STORAGE) != PERMISSION_GRANTED) {
|
||||
if (fragment.shouldShowRequestPermissionRationale(WRITE_EXTERNAL_STORAGE)) {
|
||||
new AlertDialog.Builder(fragment.getActivity())
|
||||
.setMessage(fragment.getActivity().getString(R.string.write_storage_permission_rationale))
|
||||
.setPositiveButton("OK", (dialog, which) -> {
|
||||
fragment.requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE}, 5);
|
||||
dialog.dismiss();
|
||||
})
|
||||
.setNegativeButton("Cancel", null)
|
||||
.create()
|
||||
.show();
|
||||
} else {
|
||||
fragment.requestPermissions(new String[]{WRITE_EXTERNAL_STORAGE}, 5);
|
||||
}
|
||||
} else {
|
||||
controller.startCameraCapture();
|
||||
}
|
||||
} else {
|
||||
controller.startCameraCapture();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,15 @@
|
|||
package fr.free.nrw.commons.nearby;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.design.widget.BottomSheetBehavior;
|
||||
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.view.Menu;
|
||||
|
|
@ -16,7 +18,6 @@ import android.view.MenuItem;
|
|||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
|
@ -27,20 +28,18 @@ import javax.inject.Inject;
|
|||
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.location.LatLng;
|
||||
import fr.free.nrw.commons.location.LocationServiceManager;
|
||||
import fr.free.nrw.commons.location.LocationUpdateListener;
|
||||
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.ViewUtil;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.disposables.Disposable;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
|
||||
import timber.log.Timber;
|
||||
|
||||
|
||||
|
|
@ -63,17 +62,20 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
|||
@Inject
|
||||
NearbyController nearbyController;
|
||||
|
||||
private LatLng curLatLang;
|
||||
private LatLng curLatLng;
|
||||
private Bundle bundle;
|
||||
private Disposable placesDisposable;
|
||||
private boolean lockNearbyView; //Determines if the nearby places needs to be refreshed
|
||||
private BottomSheetBehavior bottomSheetBehavior; // Behavior for list bottom sheet
|
||||
private BottomSheetBehavior bottomSheetBehaviorForDetails; // Behavior for details bottom sheet
|
||||
private NearbyMapFragment nearbyMapFragment;
|
||||
public NearbyMapFragment nearbyMapFragment;
|
||||
private NearbyListFragment nearbyListFragment;
|
||||
private static final String TAG_RETAINED_MAP_FRAGMENT = NearbyMapFragment.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
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
|
@ -128,11 +130,17 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
|||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
// Handle item selection
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_display_list:
|
||||
bottomSheetBehaviorForDetails.setState(BottomSheetBehavior.STATE_HIDDEN);
|
||||
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
|
||||
if(bottomSheetBehavior.getState()==BottomSheetBehavior.STATE_COLLAPSED || bottomSheetBehavior.getState()==BottomSheetBehavior.STATE_HIDDEN){
|
||||
bottomSheetBehaviorForDetails.setState(BottomSheetBehavior.STATE_HIDDEN);
|
||||
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
|
||||
}else if(bottomSheetBehavior.getState()==BottomSheetBehavior.STATE_EXPANDED){
|
||||
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
|
||||
}
|
||||
|
||||
return true;
|
||||
default:
|
||||
return super.onOptionsItemSelected(item);
|
||||
|
|
@ -157,6 +165,11 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
|||
showLocationPermissionDeniedErrorDialog();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// This is needed to allow the request codes from the Fragments to be routed appropriately
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -254,8 +267,6 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
|||
@Override
|
||||
protected void onStop() {
|
||||
super.onStop();
|
||||
locationManager.removeLocationListener(this);
|
||||
locationManager.unregisterLocationManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -271,6 +282,7 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
|||
super.onResume();
|
||||
lockNearbyView = false;
|
||||
checkGps();
|
||||
addNetworkBroadcastReceiver();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -283,9 +295,33 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
|||
// to the retained fragment object to perform its own cleanup.
|
||||
removeMapFragment();
|
||||
removeListFragment();
|
||||
|
||||
}
|
||||
unregisterReceiver(broadcastReceiver);
|
||||
broadcastReceiver = null;
|
||||
locationManager.removeLocationListener(this);
|
||||
locationManager.unregisterLocationManager();
|
||||
|
||||
}
|
||||
|
||||
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,15 +333,21 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
|||
if (lockNearbyView) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!NetworkUtils.isInternetConnectionEstablished(this)) {
|
||||
hideProgressBar();
|
||||
return;
|
||||
}
|
||||
|
||||
locationManager.registerLocationManager();
|
||||
LatLng lastLocation = locationManager.getLastLocation();
|
||||
|
||||
if (curLatLang != null && curLatLang.equals(lastLocation)) { //refresh view only if location has changed
|
||||
if (curLatLng != null && curLatLng.equals(lastLocation)) { //refresh view only if location has changed
|
||||
return;
|
||||
}
|
||||
curLatLang = lastLocation;
|
||||
curLatLng = lastLocation;
|
||||
|
||||
if (curLatLang == null) {
|
||||
if (curLatLng == null) {
|
||||
Timber.d("Skipping update of nearby places as location is unavailable");
|
||||
return;
|
||||
}
|
||||
|
|
@ -314,7 +356,7 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
|||
.equals(LocationServiceManager.LocationChangeType.LOCATION_SIGNIFICANTLY_CHANGED)) {
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
placesDisposable = Observable.fromCallable(() -> nearbyController
|
||||
.loadAttractionsFromLocation(curLatLang))
|
||||
.loadAttractionsFromLocation(curLatLng))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(this::populatePlaces);
|
||||
|
|
@ -323,7 +365,7 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
|||
Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(Uri.class, new UriSerializer())
|
||||
.create();
|
||||
String gsonCurLatLng = gson.toJson(curLatLang);
|
||||
String gsonCurLatLng = gson.toJson(curLatLng);
|
||||
bundle.putString("CurLatLng", gsonCurLatLng);
|
||||
updateMapFragment(true);
|
||||
}
|
||||
|
|
@ -336,7 +378,7 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
|||
.registerTypeAdapter(Uri.class, new UriSerializer())
|
||||
.create();
|
||||
String gsonPlaceList = gson.toJson(placeList);
|
||||
String gsonCurLatLng = gson.toJson(curLatLang);
|
||||
String gsonCurLatLng = gson.toJson(curLatLng);
|
||||
String gsonBoundaryCoordinates = gson.toJson(boundaryCoordinates);
|
||||
|
||||
if (placeList.size() == 0) {
|
||||
|
|
@ -388,6 +430,7 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
|||
if (nearbyMapFragment != null) {
|
||||
android.support.v4.app.FragmentManager fm = getSupportFragmentManager();
|
||||
fm.beginTransaction().remove(nearbyMapFragment).commit();
|
||||
nearbyMapFragment = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -399,6 +442,7 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
|||
if (nearbyListFragment != null) {
|
||||
android.support.v4.app.FragmentManager fm = getSupportFragmentManager();
|
||||
fm.beginTransaction().remove(nearbyListFragment).commit();
|
||||
nearbyListFragment = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -413,34 +457,34 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
|||
|
||||
NearbyMapFragment nearbyMapFragment = getMapFragment();
|
||||
|
||||
if (nearbyMapFragment != null && curLatLang != null) {
|
||||
if (nearbyMapFragment != null && curLatLng != null) {
|
||||
hideProgressBar(); // In case it is visible (this happens, not an impossible case)
|
||||
/*
|
||||
* If we are close to nearby places boundaries, we need a significant update to
|
||||
* get new nearby places. Check order is south, north, west, east
|
||||
* */
|
||||
if (nearbyMapFragment.boundaryCoordinates != null
|
||||
&& (curLatLang.getLatitude() <= nearbyMapFragment.boundaryCoordinates[0].getLatitude()
|
||||
|| curLatLang.getLatitude() >= nearbyMapFragment.boundaryCoordinates[1].getLatitude()
|
||||
|| curLatLang.getLongitude() <= nearbyMapFragment.boundaryCoordinates[2].getLongitude()
|
||||
|| curLatLang.getLongitude() >= nearbyMapFragment.boundaryCoordinates[3].getLongitude())) {
|
||||
&& (curLatLng.getLatitude() <= nearbyMapFragment.boundaryCoordinates[0].getLatitude()
|
||||
|| curLatLng.getLatitude() >= nearbyMapFragment.boundaryCoordinates[1].getLatitude()
|
||||
|| curLatLng.getLongitude() <= nearbyMapFragment.boundaryCoordinates[2].getLongitude()
|
||||
|| curLatLng.getLongitude() >= nearbyMapFragment.boundaryCoordinates[3].getLongitude())) {
|
||||
// populate places
|
||||
placesDisposable = Observable.fromCallable(() -> nearbyController
|
||||
.loadAttractionsFromLocation(curLatLang))
|
||||
.loadAttractionsFromLocation(curLatLng))
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(this::populatePlaces);
|
||||
nearbyMapFragment.setArguments(bundle);
|
||||
nearbyMapFragment.setBundleForUpdtes(bundle);
|
||||
nearbyMapFragment.updateMapSignificantly();
|
||||
updateListFragment();
|
||||
return;
|
||||
}
|
||||
|
||||
if (isSlightUpdate) {
|
||||
nearbyMapFragment.setArguments(bundle);
|
||||
nearbyMapFragment.setBundleForUpdtes(bundle);
|
||||
nearbyMapFragment.updateMapSlightly();
|
||||
} else {
|
||||
nearbyMapFragment.setArguments(bundle);
|
||||
nearbyMapFragment.setBundleForUpdtes(bundle);
|
||||
nearbyMapFragment.updateMapSignificantly();
|
||||
updateListFragment();
|
||||
}
|
||||
|
|
@ -454,7 +498,7 @@ public class NearbyActivity extends NavigationBaseActivity implements LocationUp
|
|||
}
|
||||
|
||||
private void updateListFragment() {
|
||||
nearbyListFragment.setArguments(bundle);
|
||||
nearbyListFragment.setBundleForUpdates(bundle);
|
||||
nearbyListFragment.updateNearbyListSignificantly();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -54,41 +54,47 @@ public class NearbyController {
|
|||
}
|
||||
List<Place> places = nearbyPlaces.getFromWikidataQuery(curLatLng, Locale.getDefault().getLanguage());
|
||||
|
||||
LatLng[] boundaryCoordinates = {places.get(0).location, // south
|
||||
places.get(0).location, // north
|
||||
places.get(0).location, // west
|
||||
places.get(0).location};// east, init with a random location
|
||||
if (places.size() > 0) {
|
||||
LatLng[] boundaryCoordinates = {places.get(0).location, // south
|
||||
places.get(0).location, // north
|
||||
places.get(0).location, // west
|
||||
places.get(0).location};// east, init with a random location
|
||||
|
||||
if (curLatLng != null) {
|
||||
Timber.d("Sorting places by distance...");
|
||||
final Map<Place, Double> distances = new HashMap<>();
|
||||
for (Place place: places) {
|
||||
distances.put(place, computeDistanceBetween(place.location, curLatLng));
|
||||
// Find boundaries with basic find max approach
|
||||
if (place.location.getLatitude() < boundaryCoordinates[0].getLatitude()) {
|
||||
boundaryCoordinates[0] = place.location;
|
||||
}
|
||||
if (place.location.getLatitude() > boundaryCoordinates[1].getLatitude()) {
|
||||
boundaryCoordinates[1] = place.location;
|
||||
}
|
||||
if (place.location.getLongitude() < boundaryCoordinates[2].getLongitude()) {
|
||||
boundaryCoordinates[2] = place.location;
|
||||
}
|
||||
if (place.location.getLongitude() > boundaryCoordinates[3].getLongitude()) {
|
||||
boundaryCoordinates[3] = place.location;
|
||||
}
|
||||
}
|
||||
Collections.sort(places,
|
||||
(lhs, rhs) -> {
|
||||
double lhsDistance = distances.get(lhs);
|
||||
double rhsDistance = distances.get(rhs);
|
||||
return (int) (lhsDistance - rhsDistance);
|
||||
|
||||
if (curLatLng != null) {
|
||||
Timber.d("Sorting places by distance...");
|
||||
final Map<Place, Double> distances = new HashMap<>();
|
||||
for (Place place : places) {
|
||||
distances.put(place, computeDistanceBetween(place.location, curLatLng));
|
||||
// Find boundaries with basic find max approach
|
||||
if (place.location.getLatitude() < boundaryCoordinates[0].getLatitude()) {
|
||||
boundaryCoordinates[0] = place.location;
|
||||
}
|
||||
);
|
||||
if (place.location.getLatitude() > boundaryCoordinates[1].getLatitude()) {
|
||||
boundaryCoordinates[1] = place.location;
|
||||
}
|
||||
if (place.location.getLongitude() < boundaryCoordinates[2].getLongitude()) {
|
||||
boundaryCoordinates[2] = place.location;
|
||||
}
|
||||
if (place.location.getLongitude() > boundaryCoordinates[3].getLongitude()) {
|
||||
boundaryCoordinates[3] = place.location;
|
||||
}
|
||||
}
|
||||
Collections.sort(places,
|
||||
(lhs, rhs) -> {
|
||||
double lhsDistance = distances.get(lhs);
|
||||
double rhsDistance = distances.get(rhs);
|
||||
return (int) (lhsDistance - rhsDistance);
|
||||
}
|
||||
);
|
||||
}
|
||||
nearbyPlacesInfo.placeList = places;
|
||||
nearbyPlacesInfo.boundaryCoordinates = boundaryCoordinates;
|
||||
return nearbyPlacesInfo;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
nearbyPlacesInfo.placeList = places;
|
||||
nearbyPlacesInfo.boundaryCoordinates = boundaryCoordinates;
|
||||
return nearbyPlacesInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ import static android.app.Activity.RESULT_OK;
|
|||
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
|
||||
|
||||
public class NearbyListFragment extends DaggerFragment {
|
||||
private Bundle bundleForUpdates; // Carry information from activity about changed nearby places and current location
|
||||
|
||||
private static final Type LIST_TYPE = new TypeToken<List<Place>>() {
|
||||
}.getType();
|
||||
private static final Type CUR_LAT_LNG_TYPE = new TypeToken<LatLng>() {
|
||||
|
|
@ -80,8 +82,7 @@ public class NearbyListFragment extends DaggerFragment {
|
|||
}
|
||||
|
||||
public void updateNearbyListSignificantly() {
|
||||
Bundle bundle = this.getArguments();
|
||||
adapterFactory.updateAdapterData(getPlaceListFromBundle(bundle),
|
||||
adapterFactory.updateAdapterData(getPlaceListFromBundle(bundleForUpdates),
|
||||
(RVRendererAdapter<Place>) recyclerView.getAdapter());
|
||||
}
|
||||
|
||||
|
|
@ -106,8 +107,8 @@ public class NearbyListFragment extends DaggerFragment {
|
|||
Timber.d("onRequestPermissionsResult: req code = " + " perm = " + permissions + " grant =" + grantResults);
|
||||
|
||||
switch (requestCode) {
|
||||
// 1 = "Read external storage" allowed when gallery selected
|
||||
case 1: {
|
||||
// 4 = "Read external storage" allowed when gallery selected
|
||||
case 4: {
|
||||
if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) {
|
||||
Timber.d("Call controller.startGalleryPick()");
|
||||
controller.startGalleryPick();
|
||||
|
|
@ -115,8 +116,8 @@ public class NearbyListFragment extends DaggerFragment {
|
|||
}
|
||||
break;
|
||||
|
||||
// 3 = "Write external storage" allowed when camera selected
|
||||
case 3: {
|
||||
// 5 = "Write external storage" allowed when camera selected
|
||||
case 5: {
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
Timber.d("Call controller.startCameraCapture()");
|
||||
controller.startCameraCapture();
|
||||
|
|
@ -140,4 +141,8 @@ public class NearbyListFragment extends DaggerFragment {
|
|||
}
|
||||
}
|
||||
|
||||
public void setBundleForUpdates(Bundle bundleForUpdates) {
|
||||
this.bundleForUpdates = bundleForUpdates;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -53,8 +53,10 @@ import javax.inject.Named;
|
|||
|
||||
import dagger.android.support.DaggerFragment;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.Utils;
|
||||
import fr.free.nrw.commons.contributions.ContributionController;
|
||||
import fr.free.nrw.commons.utils.UriDeserializer;
|
||||
import fr.free.nrw.commons.utils.ViewUtil;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
|
|
@ -97,6 +99,7 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
private Animation fab_open;
|
||||
private Animation rotate_forward;
|
||||
private ContributionController controller;
|
||||
private DirectUpload directUpload;
|
||||
|
||||
private Place place;
|
||||
private Marker selected;
|
||||
|
|
@ -105,7 +108,10 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
private PolygonOptions currentLocationPolygonOptions;
|
||||
|
||||
private boolean isBottomListSheetExpanded;
|
||||
private final double CAMERA_TARGET_SHIFT_FACTOR = 0.06;
|
||||
private final double CAMERA_TARGET_SHIFT_FACTOR_PORTRAIT = 0.06;
|
||||
private final double CAMERA_TARGET_SHIFT_FACTOR_LANDSCAPE = 0.04;
|
||||
|
||||
private Bundle bundleForUpdtes;// Carry information from activity about changed nearby places and current location
|
||||
|
||||
@Inject
|
||||
@Named("prefs")
|
||||
|
|
@ -120,6 +126,10 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
controller = new ContributionController(this);
|
||||
directUpload = new DirectUpload(this, controller);
|
||||
|
||||
Bundle bundle = this.getArguments();
|
||||
Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(Uri.class, new UriDeserializer())
|
||||
|
|
@ -184,14 +194,12 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
}
|
||||
|
||||
public void updateMapSlightly() {
|
||||
// Get arguments from bundle for new location
|
||||
Bundle bundle = this.getArguments();
|
||||
if (mapboxMap != null) {
|
||||
Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(Uri.class, new UriDeserializer())
|
||||
.create();
|
||||
if (bundle != null) {
|
||||
String gsonLatLng = bundle.getString("CurLatLng");
|
||||
if (bundleForUpdtes != null) {
|
||||
String gsonLatLng = bundleForUpdtes.getString("CurLatLng");
|
||||
Type curLatLngType = new TypeToken<fr.free.nrw.commons.location.LatLng>() {}.getType();
|
||||
curLatLng = gson.fromJson(gsonLatLng, curLatLngType);
|
||||
}
|
||||
|
|
@ -201,17 +209,15 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
}
|
||||
|
||||
public void updateMapSignificantly() {
|
||||
|
||||
Bundle bundle = this.getArguments();
|
||||
if (mapboxMap != null) {
|
||||
if (bundle != null) {
|
||||
if (bundleForUpdtes != null) {
|
||||
Gson gson = new GsonBuilder()
|
||||
.registerTypeAdapter(Uri.class, new UriDeserializer())
|
||||
.create();
|
||||
|
||||
String gsonPlaceList = bundle.getString("PlaceList");
|
||||
String gsonLatLng = bundle.getString("CurLatLng");
|
||||
String gsonBoundaryCoordinates = bundle.getString("BoundaryCoord");
|
||||
String gsonPlaceList = bundleForUpdtes.getString("PlaceList");
|
||||
String gsonLatLng = bundleForUpdtes.getString("CurLatLng");
|
||||
String gsonBoundaryCoordinates = bundleForUpdtes.getString("BoundaryCoord");
|
||||
Type listType = new TypeToken<List<Place>>() {}.getType();
|
||||
List<Place> placeList = gson.fromJson(gsonPlaceList, listType);
|
||||
Type curLatLngType = new TypeToken<fr.free.nrw.commons.location.LatLng>() {}.getType();
|
||||
|
|
@ -253,13 +259,28 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
}
|
||||
|
||||
// Make camera to follow user on location change
|
||||
CameraPosition position = new CameraPosition.Builder()
|
||||
.target(isBottomListSheetExpanded ?
|
||||
new LatLng(curMapBoxLatLng.getLatitude()- CAMERA_TARGET_SHIFT_FACTOR,
|
||||
curMapBoxLatLng.getLongitude())
|
||||
: curMapBoxLatLng ) // Sets the new camera position
|
||||
.zoom(mapboxMap.getCameraPosition().zoom) // Same zoom level
|
||||
.build();
|
||||
CameraPosition position ;
|
||||
if(ViewUtil.isPortrait(getActivity())){
|
||||
position = new CameraPosition.Builder()
|
||||
.target(isBottomListSheetExpanded ?
|
||||
new LatLng(curMapBoxLatLng.getLatitude()- CAMERA_TARGET_SHIFT_FACTOR_PORTRAIT,
|
||||
curMapBoxLatLng.getLongitude())
|
||||
: curMapBoxLatLng ) // Sets the new camera position
|
||||
.zoom(isBottomListSheetExpanded ?
|
||||
11 // zoom level is fixed to 11 when bottom sheet is expanded
|
||||
:mapboxMap.getCameraPosition().zoom) // Same zoom level
|
||||
.build();
|
||||
}else {
|
||||
position = new CameraPosition.Builder()
|
||||
.target(isBottomListSheetExpanded ?
|
||||
new LatLng(curMapBoxLatLng.getLatitude()- CAMERA_TARGET_SHIFT_FACTOR_LANDSCAPE,
|
||||
curMapBoxLatLng.getLongitude())
|
||||
: curMapBoxLatLng ) // Sets the new camera position
|
||||
.zoom(isBottomListSheetExpanded ?
|
||||
11 // zoom level is fixed to 11 when bottom sheet is expanded
|
||||
:mapboxMap.getCameraPosition().zoom) // Same zoom level
|
||||
.build();
|
||||
}
|
||||
|
||||
mapboxMap.animateCamera(CameraUpdateFactory
|
||||
.newCameraPosition(position), 1000);
|
||||
|
|
@ -273,12 +294,21 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
if (mapboxMap != null && curLatLng != null) {
|
||||
if (isBottomListSheetExpanded) {
|
||||
// Make camera to follow user on location change
|
||||
position = new CameraPosition.Builder()
|
||||
.target(new LatLng(curLatLng.getLatitude() - CAMERA_TARGET_SHIFT_FACTOR,
|
||||
curLatLng.getLongitude())) // Sets the new camera target above
|
||||
// current to make it visible when sheet is expanded
|
||||
.zoom(11) // Same zoom level
|
||||
.build();
|
||||
if(ViewUtil.isPortrait(getActivity())) {
|
||||
position = new CameraPosition.Builder()
|
||||
.target(new LatLng(curLatLng.getLatitude() - CAMERA_TARGET_SHIFT_FACTOR_PORTRAIT,
|
||||
curLatLng.getLongitude())) // Sets the new camera target above
|
||||
// current to make it visible when sheet is expanded
|
||||
.zoom(11) // Fixed zoom level
|
||||
.build();
|
||||
} else {
|
||||
position = new CameraPosition.Builder()
|
||||
.target(new LatLng(curLatLng.getLatitude() - CAMERA_TARGET_SHIFT_FACTOR_LANDSCAPE,
|
||||
curLatLng.getLongitude())) // Sets the new camera target above
|
||||
// current to make it visible when sheet is expanded
|
||||
.zoom(11) // Fixed zoom level
|
||||
.build();
|
||||
}
|
||||
|
||||
} else {
|
||||
// Make camera to follow user on location change
|
||||
|
|
@ -344,10 +374,29 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
fabRecenter.setOnClickListener(view -> {
|
||||
if (curLatLng != null) {
|
||||
mapView.getMapAsync(mapboxMap -> {
|
||||
CameraPosition position = new CameraPosition.Builder()
|
||||
.target(new LatLng(curLatLng.getLatitude(), curLatLng.getLongitude())) // Sets the new camera position
|
||||
.zoom(11) // Sets the zoom
|
||||
.build(); // Creates a CameraPosition from the builder
|
||||
CameraPosition position;
|
||||
|
||||
if(ViewUtil.isPortrait(getActivity())){
|
||||
position = new CameraPosition.Builder()
|
||||
.target(isBottomListSheetExpanded ?
|
||||
new LatLng(curLatLng.getLatitude()- CAMERA_TARGET_SHIFT_FACTOR_PORTRAIT,
|
||||
curLatLng.getLongitude())
|
||||
: new LatLng(curLatLng.getLatitude(), curLatLng.getLongitude(), 0)) // Sets the new camera position
|
||||
.zoom(isBottomListSheetExpanded ?
|
||||
11 // zoom level is fixed to 11 when bottom sheet is expanded
|
||||
:mapboxMap.getCameraPosition().zoom) // Same zoom level
|
||||
.build();
|
||||
}else {
|
||||
position = new CameraPosition.Builder()
|
||||
.target(isBottomListSheetExpanded ?
|
||||
new LatLng(curLatLng.getLatitude()- CAMERA_TARGET_SHIFT_FACTOR_LANDSCAPE,
|
||||
curLatLng.getLongitude())
|
||||
: new LatLng(curLatLng.getLatitude(), curLatLng.getLongitude(), 0)) // Sets the new camera position
|
||||
.zoom(isBottomListSheetExpanded ?
|
||||
11 // zoom level is fixed to 11 when bottom sheet is expanded
|
||||
:mapboxMap.getCameraPosition().zoom) // Same zoom level
|
||||
.build();
|
||||
}
|
||||
|
||||
mapboxMap.animateCamera(CameraUpdateFactory
|
||||
.newCameraPosition(position), 1000);
|
||||
|
|
@ -394,11 +443,9 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
}
|
||||
});
|
||||
|
||||
// Remove texts if it doesnt fit
|
||||
if (wikipediaButtonText.getLineCount() > 1
|
||||
|| wikidataButtonText.getLineCount() > 1
|
||||
|| commonsButtonText.getLineCount() > 1
|
||||
|| directionsButtonText.getLineCount() > 1) {
|
||||
// Remove button text if they exceed 1 line or if internal layout has not been built
|
||||
// Only need to check for directions button because it is the longest
|
||||
if (directionsButtonText.getLineCount() > 1 || directionsButtonText.getLineCount() == 0) {
|
||||
wikipediaButtonText.setVisibility(View.GONE);
|
||||
wikidataButtonText.setVisibility(View.GONE);
|
||||
commonsButtonText.setVisibility(View.GONE);
|
||||
|
|
@ -408,6 +455,8 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
|
||||
private void setupMapView(Bundle savedInstanceState) {
|
||||
MapboxMapOptions options = new MapboxMapOptions()
|
||||
.compassGravity(Gravity.BOTTOM | Gravity.LEFT)
|
||||
.compassMargins(new int[]{12, 0, 0, 24})
|
||||
.styleUrl(Style.OUTDOORS)
|
||||
.logoEnabled(false)
|
||||
.attributionEnabled(false)
|
||||
|
|
@ -536,7 +585,9 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
transparentView.setAlpha(0);
|
||||
closeFabs(isFabOpen);
|
||||
hideFAB();
|
||||
this.getView().requestFocus();
|
||||
if (this.getView() != null) {
|
||||
this.getView().requestFocus();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -583,7 +634,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) {
|
||||
CoordinatorLayout.LayoutParams params = new CoordinatorLayout.LayoutParams
|
||||
|
|
@ -594,7 +645,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.
|
||||
* */
|
||||
private void addAnchorToSmallFABs(FloatingActionButton floatingActionButton, int anchorID) {
|
||||
|
|
@ -615,7 +666,7 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
|
||||
directionsButton.setOnClickListener(view -> {
|
||||
//Open map app at given position
|
||||
Intent mapIntent = new Intent(Intent.ACTION_VIEW, place.location.getGmmIntentUri());
|
||||
Intent mapIntent = new Intent(Intent.ACTION_VIEW, this.place.location.getGmmIntentUri());
|
||||
if (mapIntent.resolveActivity(getActivity().getPackageManager()) != null) {
|
||||
startActivity(mapIntent);
|
||||
}
|
||||
|
|
@ -635,9 +686,6 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
fabCamera.setOnClickListener(view -> {
|
||||
if (fabCamera.isShown()) {
|
||||
Timber.d("Camera button tapped. Image title: " + place.getName() + "Image desc: " + place.getLongDescription());
|
||||
controller = new ContributionController(this);
|
||||
|
||||
DirectUpload directUpload = new DirectUpload(this, controller);
|
||||
storeSharedPrefs();
|
||||
directUpload.initiateCameraUpload();
|
||||
}
|
||||
|
|
@ -646,14 +694,8 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
fabGallery.setOnClickListener(view -> {
|
||||
if (fabGallery.isShown()) {
|
||||
Timber.d("Gallery button tapped. Image title: " + place.getName() + "Image desc: " + place.getLongDescription());
|
||||
controller = new ContributionController(this);
|
||||
|
||||
DirectUpload directUpload = new DirectUpload(this, controller);
|
||||
storeSharedPrefs();
|
||||
directUpload.initiateGalleryUpload();
|
||||
|
||||
//TODO: App crashes after image upload completes
|
||||
//TODO: Handle onRequestPermissionsResult
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -670,9 +712,10 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
Timber.d("onRequestPermissionsResult: req code = " + " perm = " + permissions + " grant =" + grantResults);
|
||||
|
||||
// Do not use requestCode 1 as it will conflict with NearbyActivity's requestCodes
|
||||
switch (requestCode) {
|
||||
// 1 = "Read external storage" allowed when gallery selected
|
||||
case 1: {
|
||||
// 4 = "Read external storage" allowed when gallery selected
|
||||
case 4: {
|
||||
if (grantResults.length > 0 && grantResults[0] == PERMISSION_GRANTED) {
|
||||
Timber.d("Call controller.startGalleryPick()");
|
||||
controller.startGalleryPick();
|
||||
|
|
@ -680,8 +723,8 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
}
|
||||
break;
|
||||
|
||||
// 3 = "Write external storage" allowed when camera selected
|
||||
case 3: {
|
||||
// 5 = "Write external storage" allowed when camera selected
|
||||
case 5: {
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
Timber.d("Call controller.startCameraCapture()");
|
||||
controller.startCameraCapture();
|
||||
|
|
@ -705,8 +748,7 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
}
|
||||
|
||||
private void openWebView(Uri link) {
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, link);
|
||||
startActivity(browserIntent);
|
||||
Utils.handleWebUrl(getContext(), link);
|
||||
}
|
||||
|
||||
private void animateFAB(boolean isFabOpen) {
|
||||
|
|
@ -729,7 +771,7 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
}
|
||||
}
|
||||
|
||||
private void closeFabs ( boolean isFabOpen){
|
||||
private void closeFabs ( boolean isFabOpen){
|
||||
if (isFabOpen) {
|
||||
fabPlus.startAnimation(rotate_backward);
|
||||
fabCamera.startAnimation(fab_close);
|
||||
|
|
@ -740,6 +782,11 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
}
|
||||
}
|
||||
|
||||
public void setBundleForUpdtes(Bundle bundleForUpdtes) {
|
||||
this.bundleForUpdtes = bundleForUpdtes;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
if (mapView != null) {
|
||||
|
|
@ -781,6 +828,9 @@ public class NearbyMapFragment extends DaggerFragment {
|
|||
if (mapView != null) {
|
||||
mapView.onDestroy();
|
||||
}
|
||||
selected = null;
|
||||
currentLocationMarker = null;
|
||||
|
||||
super.onDestroyView();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ import butterknife.BindView;
|
|||
import butterknife.ButterKnife;
|
||||
import fr.free.nrw.commons.CommonsApplication;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.Utils;
|
||||
import fr.free.nrw.commons.contributions.ContributionController;
|
||||
import fr.free.nrw.commons.di.ApplicationlessInjection;
|
||||
import timber.log.Timber;
|
||||
|
|
@ -200,8 +201,7 @@ public class PlaceRenderer extends Renderer<Place> {
|
|||
}
|
||||
|
||||
private void openWebView(Uri link) {
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, link);
|
||||
view.getContext().startActivity(browserIntent);
|
||||
Utils.handleWebUrl(getContext(), link);
|
||||
}
|
||||
|
||||
private boolean showMenu() {
|
||||
|
|
|
|||
|
|
@ -10,12 +10,14 @@ public class Notification {
|
|||
public String date;
|
||||
public String description;
|
||||
public String link;
|
||||
public String iconUrl;
|
||||
|
||||
public Notification(NotificationType notificationType, String notificationText, String date, String description, String link) {
|
||||
public Notification(NotificationType notificationType, String notificationText, String date, String description, String link, String iconUrl) {
|
||||
this.notificationType = notificationType;
|
||||
this.notificationText = notificationText;
|
||||
this.date = date;
|
||||
this.description = description;
|
||||
this.link = link;
|
||||
this.iconUrl = iconUrl;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,13 +6,18 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.v7.widget.DividerItemDecoration;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.widget.Toast;
|
||||
import android.view.View;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.RelativeLayout;
|
||||
|
||||
import com.pedrogomez.renderers.RVRendererAdapter;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
|
@ -20,14 +25,15 @@ import javax.inject.Inject;
|
|||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.Utils;
|
||||
import fr.free.nrw.commons.theme.NavigationBaseActivity;
|
||||
import fr.free.nrw.commons.utils.NetworkUtils;
|
||||
import fr.free.nrw.commons.utils.ViewUtil;
|
||||
import io.reactivex.Observable;
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers;
|
||||
import io.reactivex.schedulers.Schedulers;
|
||||
import timber.log.Timber;
|
||||
|
||||
import static android.widget.Toast.LENGTH_SHORT;
|
||||
|
||||
/**
|
||||
* Created by root on 18.12.2017.
|
||||
*/
|
||||
|
|
@ -36,6 +42,8 @@ public class NotificationActivity extends NavigationBaseActivity {
|
|||
NotificationAdapterFactory notificationAdapterFactory;
|
||||
|
||||
@BindView(R.id.listView) RecyclerView recyclerView;
|
||||
@BindView(R.id.progressBar) ProgressBar progressBar;
|
||||
@BindView(R.id.container) RelativeLayout relativeLayout;
|
||||
|
||||
@Inject NotificationController controller;
|
||||
|
||||
|
|
@ -57,22 +65,44 @@ public class NotificationActivity extends NavigationBaseActivity {
|
|||
recyclerView.setLayoutManager(new LinearLayoutManager(this));
|
||||
DividerItemDecoration itemDecor = new DividerItemDecoration(recyclerView.getContext(), DividerItemDecoration.VERTICAL);
|
||||
recyclerView.addItemDecoration(itemDecor);
|
||||
addNotifications();
|
||||
refresh();
|
||||
}
|
||||
|
||||
private void refresh() {
|
||||
if (!NetworkUtils.isInternetConnectionEstablished(this)) {
|
||||
progressBar.setVisibility(View.GONE);
|
||||
Snackbar.make(relativeLayout , R.string.no_internet, Snackbar.LENGTH_INDEFINITE)
|
||||
.setAction(R.string.retry, view -> {
|
||||
refresh();
|
||||
}).show();
|
||||
}else {
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
addNotifications();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
private void addNotifications() {
|
||||
Timber.d("Add notifications");
|
||||
|
||||
if(mNotificationWorkerFragment == null){
|
||||
Observable.fromCallable(() -> controller.getNotifications())
|
||||
Observable.fromCallable(() -> {
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
return controller.getNotifications();
|
||||
})
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(notificationList -> {
|
||||
Collections.reverse(notificationList);
|
||||
Timber.d("Number of notifications is %d", notificationList.size());
|
||||
initializeAndSetNotificationList(notificationList);
|
||||
setAdapter(notificationList);
|
||||
}, throwable -> Timber.e(throwable, "Error occurred while loading notifications"));
|
||||
progressBar.setVisibility(View.GONE);
|
||||
}, throwable -> {
|
||||
Timber.e(throwable, "Error occurred while loading notifications");
|
||||
ViewUtil.showSnackbar(relativeLayout, R.string.error_notifications);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
});
|
||||
} else {
|
||||
setAdapter(mNotificationWorkerFragment.getNotificationList());
|
||||
}
|
||||
|
|
@ -82,17 +112,14 @@ public class NotificationActivity extends NavigationBaseActivity {
|
|||
if (url == null || url.equals("")) {
|
||||
return;
|
||||
}
|
||||
Intent browser = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
//check if web browser available
|
||||
if(browser.resolveActivity(this.getPackageManager()) != null){
|
||||
startActivity(browser);
|
||||
} else {
|
||||
Toast toast = Toast.makeText(this, getString(R.string.no_web_browser), LENGTH_SHORT);
|
||||
toast.show();
|
||||
}
|
||||
Utils.handleWebUrl(this, Uri.parse(url));
|
||||
}
|
||||
|
||||
private void setAdapter(List<Notification> notificationList) {
|
||||
if(notificationList == null || notificationList.isEmpty()) {
|
||||
ViewUtil.showSnackbar(relativeLayout, R.string.no_notifications);
|
||||
return;
|
||||
}
|
||||
notificationAdapterFactory = new NotificationAdapterFactory(notification -> {
|
||||
Timber.d("Notification clicked %s", notification.link);
|
||||
handleUrl(notification.link);
|
||||
|
|
@ -114,4 +141,4 @@ public class NotificationActivity extends NavigationBaseActivity {
|
|||
.commit();
|
||||
mNotificationWorkerFragment.setNotificationList(notificationList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ import fr.free.nrw.commons.R;
|
|||
|
||||
public class NotificationRenderer extends Renderer<Notification> {
|
||||
@BindView(R.id.title) ReadMoreTextView title;
|
||||
@BindView(R.id.description) ReadMoreTextView description;
|
||||
@BindView(R.id.time) TextView time;
|
||||
@BindView(R.id.icon) ImageView icon;
|
||||
private NotificationClicked listener;
|
||||
|
|
@ -48,13 +47,10 @@ public class NotificationRenderer extends Renderer<Notification> {
|
|||
@Override
|
||||
public void render() {
|
||||
Notification notification = getContent();
|
||||
StringBuilder str = new StringBuilder(notification.notificationText);
|
||||
str.append(" " );
|
||||
String str = notification.notificationText.trim();
|
||||
str = str.concat(" ");
|
||||
title.setText(str);
|
||||
time.setText(notification.date);
|
||||
StringBuilder desc = new StringBuilder(notification.description);
|
||||
desc.append(" ");
|
||||
description.setText(desc);
|
||||
switch (notification.notificationType) {
|
||||
case THANK_YOU_EDIT:
|
||||
icon.setImageResource(R.drawable.ic_edit_black_24dp);
|
||||
|
|
|
|||
|
|
@ -1,16 +1,24 @@
|
|||
package fr.free.nrw.commons.notification;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import fr.free.nrw.commons.BuildConfig;
|
||||
import fr.free.nrw.commons.R;
|
||||
|
||||
import static fr.free.nrw.commons.notification.NotificationType.THANK_YOU_EDIT;
|
||||
import static fr.free.nrw.commons.notification.NotificationType.UNKNOWN;
|
||||
|
||||
public class NotificationUtils {
|
||||
|
||||
private static final String COMMONS_WIKI = "commonswiki";
|
||||
|
|
@ -29,27 +37,124 @@ public class NotificationUtils {
|
|||
return NotificationType.handledValueOf(type);
|
||||
}
|
||||
|
||||
public static List<Notification> getNotificationsFromBundle(Context context, Node document) {
|
||||
Element bundledNotifications = getBundledNotifications(document);
|
||||
NodeList childNodes = bundledNotifications.getChildNodes();
|
||||
|
||||
List<Notification> notifications = new ArrayList<>();
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node node = childNodes.item(i);
|
||||
if (isUsefulNotification(node)) {
|
||||
notifications.add(getNotificationFromApiResult(context, node));
|
||||
}
|
||||
}
|
||||
return notifications;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static List<Notification> getNotificationsFromList(Context context, NodeList childNodes) {
|
||||
List<Notification> notifications = new ArrayList<>();
|
||||
for (int i = 0; i < childNodes.getLength(); i++) {
|
||||
Node node = childNodes.item(i);
|
||||
if (isUsefulNotification(node)) {
|
||||
if (isBundledNotification(node)) {
|
||||
notifications.addAll(getNotificationsFromBundle(context, node));
|
||||
} else {
|
||||
notifications.add(getNotificationFromApiResult(context, node));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return notifications;
|
||||
}
|
||||
|
||||
private static boolean isUsefulNotification(Node node) {
|
||||
return isCommonsNotification(node)
|
||||
&& !getNotificationType(node).equals(UNKNOWN)
|
||||
&& !getNotificationType(node).equals(THANK_YOU_EDIT);
|
||||
}
|
||||
|
||||
public static boolean isBundledNotification(Node document) {
|
||||
Element bundleElement = getBundledNotifications(document);
|
||||
if (bundleElement == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return bundleElement.getChildNodes().getLength() > 0;
|
||||
}
|
||||
|
||||
private static Element getBundledNotifications(Node document) {
|
||||
return (Element) getNode(document, "bundledNotifications");
|
||||
}
|
||||
|
||||
public static Notification getNotificationFromApiResult(Context context, Node document) {
|
||||
NotificationType type = getNotificationType(document);
|
||||
|
||||
String notificationText = "";
|
||||
String link = getNotificationLink(document);
|
||||
String link = getPrimaryLink(document);
|
||||
String description = getNotificationDescription(document);
|
||||
String iconUrl = getNotificationIconUrl(document);
|
||||
|
||||
switch (type) {
|
||||
case THANK_YOU_EDIT:
|
||||
notificationText = context.getString(R.string.notifications_thank_you_edit);
|
||||
break;
|
||||
case EDIT_USER_TALK:
|
||||
notificationText = getUserTalkMessage(context, document);
|
||||
notificationText = getNotificationText(document);
|
||||
break;
|
||||
case MENTION:
|
||||
notificationText = getMentionMessage(context, document);
|
||||
description = getMentionDescription(document);
|
||||
break;
|
||||
case WELCOME:
|
||||
notificationText = getWelcomeMessage(context, document);
|
||||
break;
|
||||
}
|
||||
return new Notification(type, notificationText, getTimestamp(document), description, link);
|
||||
return new Notification(type, notificationText, getTimestamp(document), description, link, iconUrl);
|
||||
}
|
||||
|
||||
private static String getNotificationText(Node document) {
|
||||
String notificationBody = getNotificationBody(document);
|
||||
if (notificationBody == null || notificationBody.trim().equals("")) {
|
||||
return getNotificationHeader(document);
|
||||
}
|
||||
return notificationBody;
|
||||
}
|
||||
|
||||
private static String getNotificationHeader(Node document) {
|
||||
Node body = getNode(getModel(document), "header");
|
||||
if (body != null) {
|
||||
String textContent = body.getTextContent();
|
||||
return textContent.replace("<strong>", "").replace("</strong>", "");
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static String getNotificationBody(Node document) {
|
||||
Node body = getNode(getModel(document), "body");
|
||||
if (body != null) {
|
||||
String textContent = body.getTextContent();
|
||||
return textContent.replace("<strong>", "").replace("</strong>", "");
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private static String getMentionDescription(Node document) {
|
||||
Node body = getNode(getModel(document), "body");
|
||||
return body != null ? body.getTextContent() : "";
|
||||
}
|
||||
|
||||
private static String getNotificationIconUrl(Node document) {
|
||||
String format = "%s%s";
|
||||
Node iconUrl = getNode(getModel(document), "iconUrl");
|
||||
if(iconUrl == null) {
|
||||
return null;
|
||||
} else {
|
||||
String url = iconUrl.getTextContent();
|
||||
return String.format(format, BuildConfig.COMMONS_URL, url);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getMentionMessage(Context context, Node document) {
|
||||
|
|
@ -57,16 +162,31 @@ public class NotificationUtils {
|
|||
return String.format(format, getAgent(document), getNotificationDescription(document));
|
||||
}
|
||||
|
||||
@SuppressLint("StringFormatMatches")
|
||||
public static String getUserTalkMessage(Context context, Node document) {
|
||||
String format = context.getString(R.string.notifications_talk_page_message);
|
||||
return String.format(format, getAgent(document));
|
||||
}
|
||||
|
||||
@SuppressLint("StringFormatInvalid")
|
||||
public static String getWelcomeMessage(Context context, Node document) {
|
||||
String welcomeMessageFormat = context.getString(R.string.notifications_welcome);
|
||||
return String.format(welcomeMessageFormat, getAgent(document));
|
||||
}
|
||||
|
||||
private static String getPrimaryLink(Node document) {
|
||||
Node links = getNode(getModel(document), "links");
|
||||
Element primaryLink = (Element) getNode(links, "primary");
|
||||
if (primaryLink != null) {
|
||||
return primaryLink.getAttribute("url");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static Node getModel(Node document) {
|
||||
return getNode(document, "_.2A.");
|
||||
}
|
||||
|
||||
private static String getAgent(Node document) {
|
||||
Element agentElement = (Element) getNode(document, "agent");
|
||||
if (agentElement != null) {
|
||||
|
|
@ -83,16 +203,6 @@ public class NotificationUtils {
|
|||
return "";
|
||||
}
|
||||
|
||||
private static String getNotificationLink(Node document) {
|
||||
String format = "%s%s";
|
||||
Element titleElement = (Element) getNode(document, "title");
|
||||
if (titleElement != null) {
|
||||
String fullName = titleElement.getAttribute("full");
|
||||
return String.format(format, BuildConfig.HOME_URL, fullName);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static String getNotificationDescription(Node document) {
|
||||
Element titleElement = (Element) getNode(document, "title");
|
||||
if (titleElement != null) {
|
||||
|
|
|
|||
|
|
@ -151,8 +151,9 @@ public class SettingsFragment extends PreferenceFragment {
|
|||
emailSelectorIntent.setData(Uri.parse("mailto:"));
|
||||
//initialize the emailIntent
|
||||
final Intent emailIntent = new Intent(Intent.ACTION_SEND);
|
||||
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{CommonsApplication.FEEDBACK_EMAIL});
|
||||
emailIntent.putExtra(Intent.EXTRA_SUBJECT, String.format(CommonsApplication.FEEDBACK_EMAIL_SUBJECT, BuildConfig.VERSION_NAME));
|
||||
// Logs must be sent to the PRIVATE email. Please do not modify this without good reason!
|
||||
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{CommonsApplication.LOGS_PRIVATE_EMAIL});
|
||||
emailIntent.putExtra(Intent.EXTRA_SUBJECT, String.format(CommonsApplication.LOGS_PRIVATE_EMAIL_SUBJECT, BuildConfig.VERSION_NAME));
|
||||
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
emailIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
|
||||
emailIntent.setSelector( emailSelectorIntent );
|
||||
|
|
|
|||
|
|
@ -1,12 +1,18 @@
|
|||
package fr.free.nrw.commons.upload;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.BitmapRegionDecoder;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import fr.free.nrw.commons.R;
|
||||
import fr.free.nrw.commons.contributions.ContributionsActivity;
|
||||
import fr.free.nrw.commons.utils.ImageUtils;
|
||||
import timber.log.Timber;
|
||||
|
||||
|
|
@ -21,16 +27,13 @@ import timber.log.Timber;
|
|||
|
||||
public class DetectUnwantedPicturesAsync extends AsyncTask<Void, Void, ImageUtils.Result> {
|
||||
|
||||
interface Callback {
|
||||
void onResult(ImageUtils.Result result);
|
||||
}
|
||||
|
||||
private final Callback callback;
|
||||
private final String imageMediaFilePath;
|
||||
public final WeakReference<Activity> activityWeakReference;
|
||||
|
||||
DetectUnwantedPicturesAsync(String imageMediaFilePath, Callback callback) {
|
||||
this.callback = callback;
|
||||
DetectUnwantedPicturesAsync(WeakReference<Activity> activityWeakReference, String imageMediaFilePath) {
|
||||
//this.callback = callback;
|
||||
this.imageMediaFilePath = imageMediaFilePath;
|
||||
this.activityWeakReference = activityWeakReference;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -53,7 +56,29 @@ public class DetectUnwantedPicturesAsync extends AsyncTask<Void, Void, ImageUtil
|
|||
@Override
|
||||
protected void onPostExecute(ImageUtils.Result result) {
|
||||
super.onPostExecute(result);
|
||||
//callback to UI so that it can take necessary decision based on the result obtained
|
||||
callback.onResult(result);
|
||||
Activity activity = activityWeakReference.get();
|
||||
|
||||
if (result != ImageUtils.Result.IMAGE_OK) {
|
||||
//show appropriate error message
|
||||
String errorMessage = result == ImageUtils.Result.IMAGE_DARK ? activity.getString(R.string.upload_image_too_dark) : activity.getString(R.string.upload_image_blurry);
|
||||
AlertDialog.Builder errorDialogBuilder = new AlertDialog.Builder(activity);
|
||||
errorDialogBuilder.setMessage(errorMessage);
|
||||
errorDialogBuilder.setTitle(activity.getString(R.string.warning));
|
||||
errorDialogBuilder.setPositiveButton(activity.getString(R.string.no), (dialogInterface, i) -> {
|
||||
//user does not wish to upload the picture, take them back to ContributionsActivity
|
||||
Intent intent = new Intent(activity, ContributionsActivity.class);
|
||||
dialogInterface.dismiss();
|
||||
activity.startActivity(intent);
|
||||
});
|
||||
errorDialogBuilder.setNegativeButton(activity.getString(R.string.yes), (dialogInterface, i) -> {
|
||||
//user wishes to go ahead with the upload of this picture, just dismiss this dialog
|
||||
dialogInterface.dismiss();
|
||||
});
|
||||
|
||||
AlertDialog errorDialog = errorDialogBuilder.create();
|
||||
if (!activity.isFinishing()) {
|
||||
errorDialog.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -415,31 +415,9 @@ public class ShareActivity
|
|||
|
||||
private void performUnwantedPictureDetectionProcess() {
|
||||
String imageMediaFilePath = FileUtils.getPath(this,mediaUri);
|
||||
DetectUnwantedPicturesAsync detectUnwantedPicturesAsync = new DetectUnwantedPicturesAsync(imageMediaFilePath, result -> {
|
||||
|
||||
if (result != ImageUtils.Result.IMAGE_OK) {
|
||||
//show appropriate error message
|
||||
String errorMessage = result == ImageUtils.Result.IMAGE_DARK ? getString(R.string.upload_image_too_dark) : getString(R.string.upload_image_blurry);
|
||||
AlertDialog.Builder errorDialogBuilder = new AlertDialog.Builder(this);
|
||||
errorDialogBuilder.setMessage(errorMessage);
|
||||
errorDialogBuilder.setTitle(getString(R.string.warning));
|
||||
errorDialogBuilder.setPositiveButton(getString(R.string.no), (dialogInterface, i) -> {
|
||||
//user does not wish to upload the picture, take them back to ContributionsActivity
|
||||
Intent intent = new Intent(ShareActivity.this, ContributionsActivity.class);
|
||||
dialogInterface.dismiss();
|
||||
startActivity(intent);
|
||||
});
|
||||
errorDialogBuilder.setNegativeButton(getString(R.string.yes), (dialogInterface, i) -> {
|
||||
//user wishes to go ahead with the upload of this picture, just dismiss this dialog
|
||||
dialogInterface.dismiss();
|
||||
});
|
||||
|
||||
AlertDialog errorDialog = errorDialogBuilder.create();
|
||||
if (!isFinishing()) {
|
||||
errorDialog.show();
|
||||
}
|
||||
}
|
||||
});
|
||||
DetectUnwantedPicturesAsync detectUnwantedPicturesAsync
|
||||
= new DetectUnwantedPicturesAsync(new WeakReference<Activity>(this)
|
||||
, imageMediaFilePath);
|
||||
|
||||
detectUnwantedPicturesAsync.execute();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,9 @@ import android.support.annotation.NonNull;
|
|||
import android.support.v4.view.ViewCompat;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.Editable;
|
||||
import android.text.Html;
|
||||
import android.text.TextWatcher;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
|
|
@ -225,18 +227,6 @@ public class SingleUploadFragment extends CommonsDaggerSupportFragment {
|
|||
.commit();
|
||||
}
|
||||
|
||||
@OnTouch(R.id.share_license_summary)
|
||||
boolean showLicence(View view, MotionEvent motionEvent) {
|
||||
if (motionEvent.getActionMasked() == ACTION_DOWN) {
|
||||
Intent intent = new Intent();
|
||||
intent.setAction(Intent.ACTION_VIEW);
|
||||
intent.setData(Uri.parse(licenseUrlFor(license)));
|
||||
startActivity(intent);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@OnClick(R.id.titleDescButton)
|
||||
void setTitleDescButton() {
|
||||
|
|
@ -294,8 +284,10 @@ public class SingleUploadFragment extends CommonsDaggerSupportFragment {
|
|||
|
||||
@SuppressLint("StringFormatInvalid")
|
||||
private void setLicenseSummary(String license) {
|
||||
licenseSummaryView.setText(getString(R.string.share_license_summary, getString(Utils.licenseNameFor(license))));
|
||||
}
|
||||
String licenseHyperLink = "<a href='" + licenseUrlFor(license)+"'>"+ getString(Utils.licenseNameFor(license)) + "</a><br>";
|
||||
licenseSummaryView.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
licenseSummaryView.setText(Html.fromHtml(getString(R.string.share_license_summary, licenseHyperLink)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
|
|
|
|||
|
|
@ -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.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
|
||||
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
|
||||
return activeNetwork != null &&
|
||||
activeNetwork.isConnectedOrConnecting();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,11 @@
|
|||
package fr.free.nrw.commons.utils;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.view.Display;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class ViewUtil {
|
||||
|
||||
|
|
@ -9,4 +13,18 @@ public class ViewUtil {
|
|||
Snackbar.make(view, messageResourceId, Snackbar.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
public static void showLongToast(Context context, String text) {
|
||||
Toast.makeText(context, text,
|
||||
Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
public static boolean isPortrait(Context context) {
|
||||
Display orientation = ((Activity)context).getWindowManager().getDefaultDisplay();
|
||||
if(orientation.getWidth() < orientation.getHeight()){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue