diff --git a/OsmAnd/AndroidManifest.xml b/OsmAnd/AndroidManifest.xml index 54442ccbf2..85235f8647 100644 --- a/OsmAnd/AndroidManifest.xml +++ b/OsmAnd/AndroidManifest.xml @@ -66,6 +66,7 @@ + + + + + + + + + + + + diff --git a/OsmAnd/res/drawable/ic_sample.xml b/OsmAnd/res/drawable/ic_sample.xml new file mode 100644 index 0000000000..9612304bcf --- /dev/null +++ b/OsmAnd/res/drawable/ic_sample.xml @@ -0,0 +1,13 @@ + + + + diff --git a/OsmAnd/res/layout/activity_opr_webview.xml b/OsmAnd/res/layout/activity_opr_webview.xml new file mode 100644 index 0000000000..9d3f28c67a --- /dev/null +++ b/OsmAnd/res/layout/activity_opr_webview.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/layout/fragment_opr_login.xml b/OsmAnd/res/layout/fragment_opr_login.xml new file mode 100644 index 0000000000..3313679aec --- /dev/null +++ b/OsmAnd/res/layout/fragment_opr_login.xml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/OsmAnd/res/values/strings.xml b/OsmAnd/res/values/strings.xml index 39c78342d6..d79a443143 100644 --- a/OsmAnd/res/values/strings.xml +++ b/OsmAnd/res/values/strings.xml @@ -11,6 +11,11 @@ Thx - Hardy --> + I already have an account + Create new account + Photos are provided by open data project OpenPlaceReviews.org. In order to upload your photos you need to sign up on website. + Register on\nOpenPlaceReviews.org + Add photo You can log in using the safe OAuth method or use your login and password. Comment OSM Note Close OSM Note diff --git a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java index e18beeeb01..45c4864a2a 100644 --- a/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java +++ b/OsmAnd/src/net/osmand/plus/mapcontextmenu/MenuBuilder.java @@ -8,6 +8,7 @@ import android.content.Intent; import android.content.res.ColorStateList; import android.graphics.Color; import android.graphics.PorterDuff; +import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.net.Uri; @@ -25,26 +26,18 @@ import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; - import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.view.ContextThemeWrapper; import androidx.core.content.ContextCompat; import androidx.core.graphics.drawable.DrawableCompat; - import net.osmand.AndroidUtils; -import net.osmand.binary.BinaryMapIndexReader; import net.osmand.data.Amenity; import net.osmand.data.LatLon; import net.osmand.data.PointDescription; import net.osmand.data.QuadRect; -import net.osmand.osm.PoiCategory; -import net.osmand.plus.OsmAndFormatter; -import net.osmand.plus.OsmandApplication; -import net.osmand.plus.OsmandPlugin; -import net.osmand.plus.R; -import net.osmand.plus.UiUtilities; +import net.osmand.plus.*; import net.osmand.plus.activities.MapActivity; import net.osmand.plus.helpers.FontCache; import net.osmand.plus.mapcontextmenu.builders.cards.AbstractCard; @@ -53,6 +46,7 @@ import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard; import net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask; import net.osmand.plus.mapcontextmenu.builders.cards.NoImagesCard; import net.osmand.plus.mapcontextmenu.controllers.TransportStopController; +import net.osmand.plus.openplacereviews.OprStartFragment; import net.osmand.plus.poi.PoiUIFilter; import net.osmand.plus.render.RenderingIcons; import net.osmand.plus.transport.TransportStopRoute; @@ -63,13 +57,7 @@ import net.osmand.plus.widgets.tools.ClickableSpanTouchListener; import net.osmand.util.Algorithms; import net.osmand.util.MapUtils; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import static net.osmand.plus.mapcontextmenu.builders.cards.ImageCard.GetImageCardsTask.GetImageCardsListener; @@ -77,7 +65,7 @@ public class MenuBuilder { public static final float SHADOW_HEIGHT_TOP_DP = 17f; public static final int TITLE_LIMIT = 60; - protected static final String[] arrowChars = new String[]{"=>"," - "}; + protected static final String[] arrowChars = new String[] {"=>", " - "}; protected MapActivity mapActivity; protected MapContextMenu mapContextMenu; @@ -254,7 +242,7 @@ public class MenuBuilder { protected boolean needBuildPlainMenuItems() { return true; } - + protected boolean needBuildCoordinatesRow() { return true; } @@ -282,7 +270,7 @@ public class MenuBuilder { protected void buildNearestWikiRow(View view) { if (processNearestWiki() && nearestWiki.size() > 0) { - buildRow(view, R.drawable.ic_action_wikipedia, null, app.getString(R.string.wiki_around) + " (" + nearestWiki.size()+")", 0, + buildRow(view, R.drawable.ic_action_wikipedia, null, app.getString(R.string.wiki_around) + " (" + nearestWiki.size() + ")", 0, true, getCollapsableWikiView(view.getContext(), true), false, 0, false, null, false); } @@ -296,7 +284,14 @@ public class MenuBuilder { boolean needUpdateOnly = onlinePhotoCardsRow != null && onlinePhotoCardsRow.getMenuBuilder() == this; onlinePhotoCardsRow = new CardsRowBuilder(this, view, false); onlinePhotoCardsRow.build(); - CollapsableView collapsableView = new CollapsableView(onlinePhotoCardsRow.getContentView(), this, + LinearLayout parent = new LinearLayout(view.getContext()); + parent.setLayoutParams( + new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT)); + parent.setOrientation(LinearLayout.VERTICAL); + parent.addView(onlinePhotoCardsRow.getContentView()); + parent.addView(createAddPhotoButton(view.getContext())); + CollapsableView collapsableView = new CollapsableView(parent, this, app.getSettings().ONLINE_PHOTOS_ROW_COLLAPSED); collapsableView.setCollapseExpandListener(new CollapseExpandListener() { @Override @@ -316,15 +311,44 @@ public class MenuBuilder { } } + private View createAddPhotoButton(Context context) { + TextView b = new TextView(context); + b.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View view) { + OprStartFragment.showInstance(mapActivity.getSupportFragmentManager()); + } + }); + b.setTypeface(FontCache.getRobotoRegular(context)); + Drawable d = ContextCompat.getDrawable(context, R.drawable.ic_sample); + b.setCompoundDrawablesWithIntrinsicBounds(d, null, null, null); + LinearLayout.LayoutParams params = new + LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, + LinearLayout.LayoutParams.WRAP_CONTENT); + int dp16 = AndroidUtils.dpToPx(context, 16f); + int dp8 = AndroidUtils.dpToPx(context, 8f); + params.setMargins(dp16, 0, dp16, dp16); + b.setPadding(dp8, dp8, dp16, dp8); + b.setTextAlignment(View.TEXT_ALIGNMENT_CENTER); + b.setLayoutParams(params); + b.setCompoundDrawablePadding(dp8); + b.setGravity(Gravity.CENTER_VERTICAL); + b.setTypeface(null, Typeface.BOLD); + b.setText(context.getResources().getString(R.string.shared_string_add_photo)); + b.setBackgroundResource(R.drawable.btn_border_light); + b.setTextColor(ContextCompat.getColor(context, R.color.preference_category_title)); + return b; + } + private void buildCoordinatesRow(View view) { Map locationData = PointDescription.getLocationData(mapActivity, latLon.getLatitude(), latLon.getLongitude(), true); String title = locationData.get(PointDescription.LOCATION_LIST_HEADER); locationData.remove(PointDescription.LOCATION_LIST_HEADER); CollapsableView cv = getLocationCollapsableView(locationData); buildRow(view, R.drawable.ic_action_get_my_location, null, title, 0, true, cv, false, 1, - false, null, false); + false, null, false); } - + private void startLoadingImages() { if (onlinePhotoCardsRow == null) { return; @@ -379,7 +403,7 @@ public class MenuBuilder { } } - protected void buildDescription(View view){ + protected void buildDescription(View view) { } protected void buildAfter(View view) { @@ -395,8 +419,8 @@ public class MenuBuilder { } public View buildRow(View view, int iconId, String buttonText, String text, int textColor, - boolean collapsable, final CollapsableView collapsableView, - boolean needLinks, int textLinesLimit, boolean isUrl, OnClickListener onClickListener, boolean matchWidthDivider) { + boolean collapsable, final CollapsableView collapsableView, + boolean needLinks, int textLinesLimit, boolean isUrl, OnClickListener onClickListener, boolean matchWidthDivider) { return buildRow(view, iconId == 0 ? null : getRowIcon(iconId), buttonText, text, textColor, null, collapsable, collapsableView, needLinks, textLinesLimit, isUrl, onClickListener, matchWidthDivider); } @@ -480,7 +504,7 @@ public class MenuBuilder { textPrefixView.setLayoutParams(llTextParams); textPrefixView.setTypeface(FontCache.getRobotoRegular(view.getContext())); textPrefixView.setTextSize(12); - textPrefixView.setTextColor(app.getResources().getColor(light ? R.color.text_color_secondary_light: R.color.text_color_secondary_dark)); + textPrefixView.setTextColor(app.getResources().getColor(light ? R.color.text_color_secondary_light : R.color.text_color_secondary_dark)); textPrefixView.setMinLines(1); textPrefixView.setMaxLines(1); textPrefixView.setText(textPrefix); @@ -526,7 +550,7 @@ public class MenuBuilder { textViewSecondary.setLayoutParams(llTextSecondaryParams); textViewSecondary.setTypeface(FontCache.getRobotoRegular(view.getContext())); textViewSecondary.setTextSize(14); - textViewSecondary.setTextColor(app.getResources().getColor(light ? R.color.text_color_secondary_light: R.color.text_color_secondary_dark)); + textViewSecondary.setTextColor(app.getResources().getColor(light ? R.color.text_color_secondary_light : R.color.text_color_secondary_dark)); textViewSecondary.setText(secondaryText); llText.addView(textViewSecondary); } @@ -581,7 +605,7 @@ public class MenuBuilder { } if (collapsableView.getContentView().getParent() != null) { ((ViewGroup) collapsableView.getContentView().getParent()) - .removeView(collapsableView.getContentView()); + .removeView(collapsableView.getContentView()); } baseView.addView(collapsableView.getContentView()); } @@ -682,7 +706,7 @@ public class MenuBuilder { ssb.append("UTM: "); } else if (line.getKey() == OsmAndFormatter.MGRS_FORMAT) { ssb.append("MGRS: "); - } else if (line.getKey() == OsmAndFormatter.OLC_FORMAT){ + } else if (line.getKey() == OsmAndFormatter.OLC_FORMAT) { ssb.append("OLC: "); } ssb.setSpan(new ForegroundColorSpan(app.getResources().getColor(R.color.text_color_secondary_light)), 0, 4, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); @@ -747,8 +771,8 @@ public class MenuBuilder { } public void addPlainMenuItem(int iconId, String text, boolean needLinks, boolean isUrl, - boolean collapsable, CollapsableView collapsableView, - OnClickListener onClickListener) { + boolean collapsable, CollapsableView collapsableView, + OnClickListener onClickListener) { plainMenuItems.add(new PlainMenuItem(iconId, null, text, needLinks, isUrl, collapsable, collapsableView, onClickListener)); } @@ -970,7 +994,7 @@ public class MenuBuilder { button.setTypeface(FontCache.getRobotoRegular(context)); int bg; if (selected) { - bg = light ? R.drawable.context_menu_controller_bg_light_selected: R.drawable.context_menu_controller_bg_dark_selected; + bg = light ? R.drawable.context_menu_controller_bg_light_selected : R.drawable.context_menu_controller_bg_dark_selected; } else if (showAll) { bg = light ? R.drawable.context_menu_controller_bg_light_show_all : R.drawable.context_menu_controller_bg_dark_show_all; } else { @@ -1027,7 +1051,7 @@ public class MenuBuilder { private List getAmenities(QuadRect rect, PoiUIFilter wikiPoiFilter) { return wikiPoiFilter.searchAmenities(rect.top, rect.left, - rect.bottom, rect.right, -1, null); + rect.bottom, rect.right, -1, null); } @SuppressWarnings("unchecked") diff --git a/OsmAnd/src/net/osmand/plus/openplacereviews/OPRWebviewActivity.java b/OsmAnd/src/net/osmand/plus/openplacereviews/OPRWebviewActivity.java new file mode 100644 index 0000000000..ebcf32e4ec --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/openplacereviews/OPRWebviewActivity.java @@ -0,0 +1,97 @@ +package net.osmand.plus.openplacereviews; + + +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.webkit.CookieManager; +import android.webkit.WebView; +import android.webkit.WebViewClient; +import android.widget.TextView; +import androidx.appcompat.widget.Toolbar; +import androidx.core.content.ContextCompat; +import net.osmand.AndroidUtils; +import net.osmand.plus.BuildConfig; +import net.osmand.plus.R; +import net.osmand.plus.activities.OsmandActionBarActivity; + +public class OPRWebviewActivity extends OsmandActionBarActivity { + public static final String KEY_LOGIN = "LOGIN_KEY"; + private static final String url = BuildConfig.OPR_BASE_URL; + private static final String cookieUrl = BuildConfig.OPR_BASE_URL + "profile"; + private static final String loginUrl = BuildConfig.OPR_BASE_URL + "login"; + private static final String registerUrl = BuildConfig.OPR_BASE_URL + "signup"; + private static final String finishUrl = cookieUrl; + public static String KEY_TITLE = "TITLE_KEY"; + private WebView webView; + private boolean isLogin = false; + + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_opr_webview); + Bundle b = getIntent().getExtras(); + setSupportActionBar(this.findViewById(R.id.toolbar)); + if (b != null) { + String title = b.getString(KEY_TITLE, ""); + this.findViewById(R.id.toolbar_text).setText(title); + } + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + final Drawable upArrow = getMyApplication().getUIUtilities().getIcon(AndroidUtils.getNavigationIconResId(this)); + upArrow.setColorFilter(ContextCompat.getColor(this, R.color.color_favorite_gray), PorterDuff.Mode.SRC_ATOP); + getSupportActionBar().setHomeAsUpIndicator(upArrow); + webView = (WebView) findViewById(R.id.printDialogWebview); + webView.setWebViewClient(new CloseOnSuccessWebViewClient()); + webView.getSettings().setJavaScriptEnabled(true); + WebView.setWebContentsDebuggingEnabled(true); + if (b != null) { + isLogin = b.getBoolean(KEY_LOGIN); + if (isLogin) { + webView.loadUrl(loginUrl); + } else { + webView.loadUrl(registerUrl); + } + } + } + + @Override + public boolean onSupportNavigateUp() { + onBackPressed(); + return true; + } + + public static String getPrivateKeyFromCookie() { + return returnCookieByKey("opr-token"); + } + + public static String getUsernameFromCookie() { + return returnCookieByKey("opr-nickname"); + } + + private static String returnCookieByKey(String key) { + String CookieValue = null; + CookieManager cookieManager = CookieManager.getInstance(); + String cookies = cookieManager.getCookie(cookieUrl); + if (cookies == null || cookies.isEmpty()) { + return ""; + } + String[] temp = cookies.split(";"); + for (String ar1 : temp) { + if (ar1.contains(key)) { + String[] temp1 = ar1.split("="); + CookieValue = temp1[1]; + break; + } + } + return CookieValue; + } + + public class CloseOnSuccessWebViewClient extends WebViewClient { + @Override + public void onPageFinished(WebView view, String url) { + if (url.contains(finishUrl) && isLogin) { + finish(); + } + super.onPageFinished(view, url); + } + } +} \ No newline at end of file diff --git a/OsmAnd/src/net/osmand/plus/openplacereviews/OprStartFragment.java b/OsmAnd/src/net/osmand/plus/openplacereviews/OprStartFragment.java new file mode 100644 index 0000000000..eecd0c3f32 --- /dev/null +++ b/OsmAnd/src/net/osmand/plus/openplacereviews/OprStartFragment.java @@ -0,0 +1,93 @@ +package net.osmand.plus.openplacereviews; + +import android.content.Intent; +import android.os.Bundle; +import android.text.SpannableString; +import android.text.Spanned; +import android.text.TextPaint; +import android.text.method.LinkMovementMethod; +import android.text.style.URLSpan; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.fragment.app.FragmentManager; +import net.osmand.PlatformUtil; +import net.osmand.plus.R; +import net.osmand.plus.base.BaseOsmAndFragment; +import org.apache.commons.logging.Log; + +public class OprStartFragment extends BaseOsmAndFragment { + private static final String TAG = "fragment_oprstart"; + private static final Log LOG = PlatformUtil.getLog(OprStartFragment.class); + private static final String openPlaceReviewsUrl = "OpenPlaceReviews.org"; + + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + View v = inflater.inflate(R.layout.fragment_opr_login, container, false); + v.findViewById(R.id.register_opr_create_account).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent i = new Intent(requireContext(), OPRWebviewActivity.class); + i.putExtra(OPRWebviewActivity.KEY_TITLE, getString(R.string.register_opr_create_new_account)); + i.putExtra(OPRWebviewActivity.KEY_LOGIN, false); + startActivity(i); + } + }); + v.findViewById(R.id.back_button).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + getActivity().getSupportFragmentManager().popBackStack(); + } + }); + v.findViewById(R.id.register_opr_have_account).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent i = new Intent(requireContext(), OPRWebviewActivity.class); + i.putExtra(OPRWebviewActivity.KEY_TITLE, getString(R.string.user_login)); + i.putExtra(OPRWebviewActivity.KEY_LOGIN, true); + startActivity(i); + } + }); + setURLSpan(v); + return v; + } + + private void setURLSpan(View v) { + String desc = requireContext().getString(R.string.register_on_openplacereviews_desc); + SpannableString ss = new SpannableString(desc); + ss.setSpan(new URLSpanNoUnderline("https://" + openPlaceReviewsUrl), desc.indexOf(openPlaceReviewsUrl), + desc.indexOf(openPlaceReviewsUrl) + openPlaceReviewsUrl.length(), Spanned.SPAN_INCLUSIVE_INCLUSIVE); + v.findViewById(R.id.start_opr_description).setText(ss); + v.findViewById(R.id.start_opr_description).setMovementMethod(LinkMovementMethod.getInstance()); + } + + + private class URLSpanNoUnderline extends URLSpan { + public URLSpanNoUnderline(String url) { + super(url); + } + + @Override + public void updateDrawState(TextPaint ds) { + super.updateDrawState(ds); + ds.setUnderlineText(false); + } + } + + + public static void showInstance(@NonNull FragmentManager fm) { + try { + if (fm.findFragmentByTag(OprStartFragment.TAG) == null) { + OprStartFragment fragment = new OprStartFragment(); + fm.beginTransaction() + .add(R.id.fragmentContainer, fragment, OprStartFragment.TAG) + .addToBackStack(null).commit(); + } + } catch (RuntimeException e) { + LOG.error("showInstance", e); + } + } +}