diff --git a/android/res/layout/place_page_details.xml b/android/res/layout/place_page_details.xml index d50113d60e..0305dbb36a 100644 --- a/android/res/layout/place_page_details.xml +++ b/android/res/layout/place_page_details.xml @@ -47,26 +47,16 @@ - - + + - - - - - - - - - - - - - - diff --git a/android/res/layout/place_page_links_fragment.xml b/android/res/layout/place_page_links_fragment.xml new file mode 100644 index 0000000000..b573f86064 --- /dev/null +++ b/android/res/layout/place_page_links_fragment.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/android/src/app/organicmaps/widget/placepage/PlacePageController.java b/android/src/app/organicmaps/widget/placepage/PlacePageController.java index fd3e4d0ab8..afff9750da 100644 --- a/android/src/app/organicmaps/widget/placepage/PlacePageController.java +++ b/android/src/app/organicmaps/widget/placepage/PlacePageController.java @@ -20,9 +20,12 @@ import androidx.lifecycle.ViewModelProvider; import app.organicmaps.Framework; import app.organicmaps.MwmActivity; import app.organicmaps.R; +import app.organicmaps.api.ParsedMwmRequest; import app.organicmaps.base.Initializable; import app.organicmaps.base.Savable; import app.organicmaps.bookmarks.data.MapObject; +import app.organicmaps.bookmarks.data.RoadWarningMarkType; +import app.organicmaps.routing.RoutingController; import app.organicmaps.settings.RoadType; import app.organicmaps.util.UiUtils; import app.organicmaps.util.bottomsheet.MenuBottomSheetFragment; @@ -143,6 +146,22 @@ public class PlacePageController implements Initializable, }); } + @NonNull + private static PlacePageButtons.ButtonType toPlacePageButton(@NonNull RoadWarningMarkType type) + { + switch (type) + { + case DIRTY: + return PlacePageButtons.ButtonType.ROUTE_AVOID_UNPAVED; + case FERRY: + return PlacePageButtons.ButtonType.ROUTE_AVOID_FERRY; + case TOLL: + return PlacePageButtons.ButtonType.ROUTE_AVOID_TOLL; + default: + throw new AssertionError("Unsupported road warning type: " + type); + } + } + private void stopCustomPeekHeightAnimation() { if (mCustomPeekHeightAnimator != null && mCustomPeekHeightAnimator.isStarted()) @@ -402,12 +421,61 @@ public class PlacePageController implements Initializable, } } + private void updateButtons(boolean showBackButton, boolean showRoutingButton) + { + List buttons = new ArrayList<>(); + if (mMapObject.getRoadWarningMarkType() != RoadWarningMarkType.UNKNOWN) + { + RoadWarningMarkType markType = mMapObject.getRoadWarningMarkType(); + PlacePageButtons.ButtonType roadType = toPlacePageButton(markType); + buttons.add(roadType); + } + else if (RoutingController.get().isRoutePoint(mMapObject)) + { + buttons.add(PlacePageButtons.ButtonType.ROUTE_REMOVE); + } + else + { + final ParsedMwmRequest request = ParsedMwmRequest.getCurrentRequest(); + if (showBackButton || (request != null && request.isPickPointMode())) + buttons.add(PlacePageButtons.ButtonType.BACK); + + boolean needToShowRoutingButtons = RoutingController.get().isPlanning() || showRoutingButton; + + if (needToShowRoutingButtons) + buttons.add(PlacePageButtons.ButtonType.ROUTE_FROM); + + // If we can show the add route button, put it in the place of the bookmark button + // And move the bookmark button at the end + if (needToShowRoutingButtons && RoutingController.get().isStopPointAllowed()) + buttons.add(PlacePageButtons.ButtonType.ROUTE_ADD); + else + buttons.add(mMapObject.getMapObjectType() == MapObject.BOOKMARK + ? PlacePageButtons.ButtonType.BOOKMARK_DELETE + : PlacePageButtons.ButtonType.BOOKMARK_SAVE); + + if (needToShowRoutingButtons) + { + buttons.add(PlacePageButtons.ButtonType.ROUTE_TO); + if (RoutingController.get().isStopPointAllowed()) + buttons.add(mMapObject.getMapObjectType() == MapObject.BOOKMARK + ? PlacePageButtons.ButtonType.BOOKMARK_DELETE + : PlacePageButtons.ButtonType.BOOKMARK_SAVE); + } + buttons.add(PlacePageButtons.ButtonType.SHARE); + } + viewModel.setCurrentButtons(buttons); + } + @Override public void onChanged(MapObject mapObject) { mMapObject = mapObject; createPlacePageFragments(); + updateButtons( + MapObject.isOfType(MapObject.API_POINT, mMapObject), + !MapObject.isOfType(MapObject.MY_POSITION, mMapObject)); } @Override diff --git a/android/src/app/organicmaps/widget/placepage/PlacePageLinksFragment.java b/android/src/app/organicmaps/widget/placepage/PlacePageLinksFragment.java new file mode 100644 index 0000000000..bc70897337 --- /dev/null +++ b/android/src/app/organicmaps/widget/placepage/PlacePageLinksFragment.java @@ -0,0 +1,276 @@ +package app.organicmaps.widget.placepage; + +import android.os.Bundle; +import android.text.TextUtils; +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.Fragment; +import androidx.lifecycle.Observer; +import androidx.lifecycle.ViewModelProvider; +import app.organicmaps.R; +import app.organicmaps.bookmarks.data.MapObject; +import app.organicmaps.bookmarks.data.Metadata; +import app.organicmaps.util.Utils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static android.view.View.GONE; +import static android.view.View.VISIBLE; + +public class PlacePageLinksFragment extends Fragment implements Observer +{ + static final List supportedLinks = Arrays.asList( + Metadata.MetadataType.FMD_WEBSITE, + Metadata.MetadataType.FMD_EMAIL, + Metadata.MetadataType.FMD_WIKIMEDIA_COMMONS, + Metadata.MetadataType.FMD_CONTACT_FACEBOOK, + Metadata.MetadataType.FMD_CONTACT_INSTAGRAM, + Metadata.MetadataType.FMD_CONTACT_TWITTER, + Metadata.MetadataType.FMD_CONTACT_VK, + Metadata.MetadataType.FMD_CONTACT_LINE); + + private View mFrame; + private View mFacebookPage; + private TextView mTvFacebookPage; + private View mInstagramPage; + private TextView mTvInstagramPage; + private View mTwitterPage; + private TextView mTvTwitterPage; + private View mVkPage; + private TextView mTvVkPage; + private View mLinePage; + private TextView mTvLinePage; + + private View mWebsite; + private TextView mTvWebsite; + private View mEmail; + private TextView mTvEmail; + private View mWikimedia; + private TextView mTvWikimedia; + + private PlacePageViewModel viewModel; + private MapObject mMapObject; + + private static void refreshMetadataOrHide(String metadata, View metaLayout, TextView metaTv) + { + if (!TextUtils.isEmpty(metadata)) + { + metaLayout.setVisibility(VISIBLE); + if (metaTv != null) + metaTv.setText(metadata); + } + else + metaLayout.setVisibility(GONE); + } + + public static boolean hasLinkAvailable(MapObject mapObject) + { + for (Metadata.MetadataType type: supportedLinks) { + final String metadata = type == Metadata.MetadataType.FMD_WEBSITE ? getWebsiteUrl(mapObject) : mapObject.getMetadata(type); + if (!TextUtils.isEmpty(metadata)) + return true; + } + return false; + } + + @Nullable + @Override + public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) + { + return inflater.inflate(R.layout.place_page_links_fragment, container, false); + } + + @Override + public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) + { + super.onViewCreated(view, savedInstanceState); + mFrame = view; + + mWebsite = mFrame.findViewById(R.id.ll__place_website); + mTvWebsite = mFrame.findViewById(R.id.tv__place_website); + mWebsite.setOnClickListener((v) -> openUrl(Metadata.MetadataType.FMD_WEBSITE)); + mWebsite.setOnLongClickListener((v) -> copyUrl(mWebsite, Metadata.MetadataType.FMD_WEBSITE)); + + mEmail = mFrame.findViewById(R.id.ll__place_email); + mTvEmail = mFrame.findViewById(R.id.tv__place_email); + mEmail.setOnClickListener((v) -> openUrl(Metadata.MetadataType.FMD_EMAIL)); + mEmail.setOnLongClickListener((v) -> copyUrl(mEmail, Metadata.MetadataType.FMD_EMAIL)); + + mWikimedia = mFrame.findViewById(R.id.ll__place_wikimedia); + mTvWikimedia = mFrame.findViewById(R.id.tv__place_wikimedia); + mWikimedia.setOnClickListener((v) -> openUrl(Metadata.MetadataType.FMD_WIKIMEDIA_COMMONS)); + mWikimedia.setOnLongClickListener((v) -> copyUrl(mWikimedia, Metadata.MetadataType.FMD_WIKIMEDIA_COMMONS)); + + mFacebookPage = mFrame.findViewById(R.id.ll__place_facebook); + mTvFacebookPage = mFrame.findViewById(R.id.tv__place_facebook_page); + mFacebookPage.setOnClickListener((v) -> openUrl(Metadata.MetadataType.FMD_CONTACT_FACEBOOK)); + mFacebookPage.setOnLongClickListener((v) -> copyUrl(mFacebookPage, Metadata.MetadataType.FMD_CONTACT_FACEBOOK)); + + mInstagramPage = mFrame.findViewById(R.id.ll__place_instagram); + mTvInstagramPage = mFrame.findViewById(R.id.tv__place_instagram_page); + mInstagramPage.setOnClickListener((v) -> openUrl(Metadata.MetadataType.FMD_CONTACT_INSTAGRAM)); + mInstagramPage.setOnLongClickListener((v) -> copyUrl(mInstagramPage, Metadata.MetadataType.FMD_CONTACT_INSTAGRAM)); + + mTwitterPage = mFrame.findViewById(R.id.ll__place_twitter); + mTvTwitterPage = mFrame.findViewById(R.id.tv__place_twitter_page); + mTwitterPage.setOnClickListener((v) -> openUrl(Metadata.MetadataType.FMD_CONTACT_TWITTER)); + mTwitterPage.setOnLongClickListener((v) -> copyUrl(mTwitterPage, Metadata.MetadataType.FMD_CONTACT_TWITTER)); + + mVkPage = mFrame.findViewById(R.id.ll__place_vk); + mTvVkPage = mFrame.findViewById(R.id.tv__place_vk_page); + mVkPage.setOnClickListener((v) -> openUrl(Metadata.MetadataType.FMD_CONTACT_VK)); + mVkPage.setOnLongClickListener((v) -> copyUrl(mVkPage, Metadata.MetadataType.FMD_CONTACT_VK)); + + mLinePage = mFrame.findViewById(R.id.ll__place_line); + mTvLinePage = mFrame.findViewById(R.id.tv__place_line_page); + mLinePage.setOnClickListener((v) -> openUrl(Metadata.MetadataType.FMD_CONTACT_LINE)); + mLinePage.setOnLongClickListener((v) -> copyUrl(mLinePage, Metadata.MetadataType.FMD_CONTACT_LINE)); + + viewModel = new ViewModelProvider(requireActivity()).get(PlacePageViewModel.class); + viewModel.getMapObject().observe(requireActivity(), this); + } + + private boolean isSocialUsername(Metadata.MetadataType type) + { + return !mMapObject.getMetadata(type).contains("/"); + } + + private void openUrl(Metadata.MetadataType type) + { + final String url = getLink(type); + if (type != Metadata.MetadataType.FMD_CONTACT_LINE || !isSocialUsername(type)) + Utils.openUrl(requireContext(), url); + } + + private String getLink(Metadata.MetadataType type) + { + final String metadata = mMapObject.getMetadata(type); + if (TextUtils.isEmpty(metadata)) + { + return ""; + } + String path = ""; + String domain = ""; + switch (type) + { + case FMD_WEBSITE: + path = getWebsiteUrl(mMapObject); + break; + case FMD_CONTACT_FACEBOOK: + domain = "https://m.facebook.com/"; + break; + case FMD_CONTACT_INSTAGRAM: + domain = "https://instagram.com/"; + break; + case FMD_CONTACT_TWITTER: + domain = "https://mobile.twitter.com/"; + break; + case FMD_CONTACT_VK: + domain = "https://vk.com/"; + break; + case FMD_CONTACT_LINE: + path = getLineUrl(); + break; + } + if (TextUtils.isEmpty(path)) + path = metadata; + return domain + path; + } + + private boolean copyUrl(View view, Metadata.MetadataType type) + { + final String url = getLink(type); + final List items = new ArrayList<>(); + items.add(url); + + final String metadata = type == Metadata.MetadataType.FMD_WEBSITE ? getWebsiteUrl(mMapObject) : mMapObject.getMetadata(type); + // Add user names for social media if available + if (!metadata.equals(url) && isSocialUsername(type)) + items.add(metadata); + + if (items.size() == 1) + PlacePageUtils.copyToClipboard(requireContext(), mFrame, items.get(0)); + else + PlacePageUtils.showCopyPopup(requireContext(), view, mFrame, items); + return true; + } + + private void refreshSocialPageLink(View view, TextView tvSocialPage, String socialPage, String webDomain) + { + if (TextUtils.isEmpty(socialPage)) + view.setVisibility(GONE); + else if (socialPage.indexOf('/') >= 0) + refreshMetadataOrHide("https://" + webDomain + "/" + socialPage, view, tvSocialPage); + else + refreshMetadataOrHide("@" + socialPage, view, tvSocialPage); + } + + private void refreshSocialPageLink(View view, TextView tvSocialPage, String socialPage) + { + if (TextUtils.isEmpty(socialPage)) + view.setVisibility(GONE); + else if (socialPage.indexOf('/') >= 0) + refreshMetadataOrHide("https://" + socialPage, view, tvSocialPage); + else + refreshMetadataOrHide("@" + socialPage, view, tvSocialPage); + } + + private static String getWebsiteUrl(MapObject mapObject) + { + String website = mapObject.getMetadata(Metadata.MetadataType.FMD_WEBSITE); + String url = mapObject.getMetadata(Metadata.MetadataType.FMD_URL); + return TextUtils.isEmpty(website) ? url : website; + } + + private String getLineUrl() + { + final String metadata = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_LINE); + if (isSocialUsername(Metadata.MetadataType.FMD_CONTACT_LINE)) + return "https://line.me/R/ti/p/@" + metadata; + else + return "https://" + metadata; + } + + private void refreshLinks() + { + refreshMetadataOrHide(getWebsiteUrl(mMapObject), mWebsite, mTvWebsite); + String wikimedia_commons = mMapObject.getMetadata(Metadata.MetadataType.FMD_WIKIMEDIA_COMMONS); + String wikimedia_commons_text = TextUtils.isEmpty(wikimedia_commons) ? "" : getResources().getString(R.string.wikimedia_commons); + refreshMetadataOrHide(wikimedia_commons_text, mWikimedia, mTvWikimedia); + refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_EMAIL), mEmail, mTvEmail); + + final String facebookPageLink = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_FACEBOOK); + refreshSocialPageLink(mFacebookPage, mTvFacebookPage, facebookPageLink, "facebook.com"); + final String instagramPageLink = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_INSTAGRAM); + refreshSocialPageLink(mInstagramPage, mTvInstagramPage, instagramPageLink, "instagram.com"); + final String twitterPageLink = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_TWITTER); + refreshSocialPageLink(mTwitterPage, mTvTwitterPage, twitterPageLink, "twitter.com"); + final String vkPageLink = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_VK); + refreshSocialPageLink(mVkPage, mTvVkPage, vkPageLink, "vk.com"); + final String linePageLink = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_LINE); + // Tag `contact:line` could contain urls from domains: line.me, liff.line.me, page.line.me, etc. + // And `socialPage` should not be prepended with domain, but only with "https://" protocol. + refreshSocialPageLink(mLinePage, mTvLinePage, linePageLink); + } + + @Override + public void onDestroy() + { + super.onDestroy(); + viewModel.getMapObject().removeObserver(this); + } + + @Override + public void onChanged(MapObject mapObject) + { + mMapObject = mapObject; + refreshLinks(); + } +} diff --git a/android/src/app/organicmaps/widget/placepage/PlacePageView.java b/android/src/app/organicmaps/widget/placepage/PlacePageView.java index e11af4f63a..95f7f96c12 100644 --- a/android/src/app/organicmaps/widget/placepage/PlacePageView.java +++ b/android/src/app/organicmaps/widget/placepage/PlacePageView.java @@ -34,7 +34,6 @@ import app.organicmaps.bookmarks.data.BookmarkManager; import app.organicmaps.bookmarks.data.DistanceAndAzimut; import app.organicmaps.bookmarks.data.MapObject; import app.organicmaps.bookmarks.data.Metadata; -import app.organicmaps.bookmarks.data.RoadWarningMarkType; import app.organicmaps.downloader.CountryItem; import app.organicmaps.downloader.DownloaderStatusIcon; import app.organicmaps.downloader.MapManager; @@ -49,7 +48,6 @@ import app.organicmaps.settings.RoadType; import app.organicmaps.util.SharingUtils; import app.organicmaps.util.StringUtils; import app.organicmaps.util.UiUtils; -import app.organicmaps.util.Utils; import app.organicmaps.util.concurrency.UiThread; import app.organicmaps.widget.ArrowView; @@ -74,6 +72,7 @@ public class PlacePageView extends Fragment implements View.OnClickListener, private static final String WIKIPEDIA_FRAGMENT_TAG = "WIKIPEDIA_FRAGMENT_TAG"; private static final String PHONE_FRAGMENT_TAG = "PHONE_FRAGMENT_TAG"; private static final String OPENING_HOURS_FRAGMENT_TAG = "OPENING_HOURS_FRAGMENT_TAG"; + private static final String LINKS_FRAGMENT_TAG = "LINKS_FRAGMENT_TAG"; private static final List visibleCoordsFormat = Arrays.asList(CoordinatesFormat.LatLonDMS, @@ -92,26 +91,9 @@ public class PlacePageView extends Fragment implements View.OnClickListener, private TextView mTvAddress; // Details. private ViewGroup mDetails; - private View mWebsite; - private TextView mTvWebsite; private TextView mTvLatlon; - //Social links - private View mFacebookPage; - private TextView mTvFacebookPage; - private View mInstagramPage; - private TextView mTvInstagramPage; - private View mTwitterPage; - private TextView mTvTwitterPage; - private View mVkPage; - private TextView mTvVkPage; - private View mLinePage; - private TextView mTvLinePage; private View mWifi; private TextView mTvWiFi; - private View mEmail; - private TextView mTvEmail; - private View mWikimedia; - private TextView mTvWikimedia; private View mOperator; private TextView mTvOperator; private View mLevel; @@ -191,22 +173,6 @@ public class PlacePageView extends Fragment implements View.OnClickListener, private PlacePageViewModel viewModel; private MapObject mMapObject; - @NonNull - private static PlacePageButtons.ButtonType toPlacePageButton(@NonNull RoadWarningMarkType type) - { - switch (type) - { - case DIRTY: - return PlacePageButtons.ButtonType.ROUTE_AVOID_UNPAVED; - case FERRY: - return PlacePageButtons.ButtonType.ROUTE_AVOID_FERRY; - case TOLL: - return PlacePageButtons.ButtonType.ROUTE_AVOID_TOLL; - default: - throw new AssertionError("Unsupported road warning type: " + type); - } - } - private static void refreshMetadataOrHide(String metadata, View metaLayout, TextView metaTv) { if (!TextUtils.isEmpty(metadata)) @@ -277,46 +243,12 @@ public class PlacePageView extends Fragment implements View.OnClickListener, mDetails = mFrame.findViewById(R.id.pp__details_frame); RelativeLayout address = mFrame.findViewById(R.id.ll__place_name); - mWebsite = mFrame.findViewById(R.id.ll__place_website); - mWebsite.setOnClickListener(this); - mTvWebsite = mFrame.findViewById(R.id.tv__place_website); - // Wikimedia Commons link - mWikimedia = mFrame.findViewById(R.id.ll__place_wikimedia); - mTvWikimedia = mFrame.findViewById(R.id.tv__place_wikimedia); - mWikimedia.setOnClickListener(this); - //Social links - mFacebookPage = mFrame.findViewById(R.id.ll__place_facebook); - mFacebookPage.setOnClickListener(this); - mFacebookPage.setOnLongClickListener(this); - mTvFacebookPage = mFrame.findViewById(R.id.tv__place_facebook_page); - mInstagramPage = mFrame.findViewById(R.id.ll__place_instagram); - mInstagramPage.setOnClickListener(this); - mInstagramPage.setOnLongClickListener(this); - mTvInstagramPage = mFrame.findViewById(R.id.tv__place_instagram_page); - - mTwitterPage = mFrame.findViewById(R.id.ll__place_twitter); - mTwitterPage.setOnClickListener(this); - mTwitterPage.setOnLongClickListener(this); - mTvTwitterPage = mFrame.findViewById(R.id.tv__place_twitter_page); - - mVkPage = mFrame.findViewById(R.id.ll__place_vk); - mVkPage.setOnClickListener(this); - mVkPage.setOnLongClickListener(this); - mTvVkPage = mFrame.findViewById(R.id.tv__place_vk_page); - - mLinePage = mFrame.findViewById(R.id.ll__place_line); - mLinePage.setOnClickListener(this); - mLinePage.setOnLongClickListener(this); - mTvLinePage = mFrame.findViewById(R.id.tv__place_line_page); LinearLayout latlon = mFrame.findViewById(R.id.ll__place_latlon); latlon.setOnClickListener(this); mTvLatlon = mFrame.findViewById(R.id.tv__place_latlon); mWifi = mFrame.findViewById(R.id.ll__place_wifi); mTvWiFi = mFrame.findViewById(R.id.tv__place_wifi); - mEmail = mFrame.findViewById(R.id.ll__place_email); - mEmail.setOnClickListener(this); - mTvEmail = mFrame.findViewById(R.id.tv__place_email); mOperator = mFrame.findViewById(R.id.ll__place_operator); mOperator.setOnClickListener(this); mTvOperator = mFrame.findViewById(R.id.tv__place_operator); @@ -335,9 +267,6 @@ public class PlacePageView extends Fragment implements View.OnClickListener, mEditTopSpace = mFrame.findViewById(R.id.edit_top_space); latlon.setOnLongClickListener(this); address.setOnLongClickListener(this); - mWebsite.setOnLongClickListener(this); - mWikimedia.setOnLongClickListener(this); - mEmail.setOnLongClickListener(this); mOperator.setOnLongClickListener(this); mLevel.setOnLongClickListener(this); @@ -516,33 +445,11 @@ public class PlacePageView extends Fragment implements View.OnClickListener, { refreshPreview(); refreshDetails(); - refreshViewsInternal(); - updateBookmarkView(); - updatePhoneView(); - } - - private void refreshViewsInternal() - { final Location loc = LocationHelper.INSTANCE.getSavedLocation(); - boolean showBackButton = false; - boolean showRoutingButton = true; - switch (mMapObject.getMapObjectType()) - { - case MapObject.BOOKMARK: - case MapObject.POI: - case MapObject.SEARCH: - refreshDistanceToObject(loc); - break; - case MapObject.API_POINT: - refreshDistanceToObject(loc); - showBackButton = true; - break; - case MapObject.MY_POSITION: - refreshMyPosition(loc); - showRoutingButton = false; - break; - } - updateButtons(showBackButton, showRoutingButton); + if (mMapObject.getMapObjectType() == MapObject.MY_POSITION) + refreshMyPosition(loc); + else + refreshDistanceToObject(loc); } private void updateViewFragment(Class controllerClass, String fragmentTag, @IdRes int containerId, boolean enabled) @@ -563,6 +470,12 @@ public class PlacePageView extends Fragment implements View.OnClickListener, } } + private void updateLinksView() + { + final boolean hasLinkAvailable = PlacePageLinksFragment.hasLinkAvailable(mMapObject); + updateViewFragment(PlacePageLinksFragment.class, LINKS_FRAGMENT_TAG, R.id.place_page_links_fragment, hasLinkAvailable); + } + private void updateOpeningHoursView() { final String ohStr = mMapObject.getMetadata(Metadata.MetadataType.FMD_OPEN_HOURS); @@ -621,20 +534,12 @@ public class PlacePageView extends Fragment implements View.OnClickListener, { refreshLatLon(); - String website = mMapObject.getMetadata(Metadata.MetadataType.FMD_WEBSITE); - String url = mMapObject.getMetadata(Metadata.MetadataType.FMD_URL); - refreshMetadataOrHide(TextUtils.isEmpty(website) ? url : website, mWebsite, mTvWebsite); - String wikimedia_commons = mMapObject.getMetadata(Metadata.MetadataType.FMD_WIKIMEDIA_COMMONS); - String wikimedia_commons_text = TextUtils.isEmpty(wikimedia_commons) ? "" : getResources().getString(R.string.wikimedia_commons); - refreshMetadataOrHide(wikimedia_commons_text, mWikimedia, mTvWikimedia); - refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_EMAIL), mEmail, mTvEmail); refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_OPERATOR), mOperator, mTvOperator); /// @todo I don't like it when we take all data from mapObject, but for cuisines, we should /// go into JNI Framework and rely on some "active object". refreshMetadataOrHide(Framework.nativeGetActiveObjectFormattedCuisine(), mCuisine, mTvCuisine); refreshWiFi(); refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_FLATS), mEntrance, mTvEntrance); - refreshSocialLinks(); refreshMetadataOrHide(mMapObject.getMetadata(Metadata.MetadataType.FMD_LEVEL), mLevel, mTvLevel); // showTaxiOffer(mapObject); @@ -652,8 +557,11 @@ public class PlacePageView extends Fragment implements View.OnClickListener, || UiUtils.isVisible(mAddOrganisation) || UiUtils.isVisible(mAddPlace), mEditTopSpace); } + updateLinksView(); updateOpeningHoursView(); updateWikipediaView(); + updateBookmarkView(); + updatePhoneView(); } private void refreshWiFi() @@ -669,123 +577,6 @@ public class PlacePageView extends Fragment implements View.OnClickListener, mWifi.setVisibility(GONE); } - private void refreshSocialLinks() - { - final String facebookPageLink = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_FACEBOOK); - refreshSocialPageLink(mFacebookPage, mTvFacebookPage, facebookPageLink, "facebook.com"); - final String instagramPageLink = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_INSTAGRAM); - refreshSocialPageLink(mInstagramPage, mTvInstagramPage, instagramPageLink, "instagram.com"); - final String twitterPageLink = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_TWITTER); - refreshSocialPageLink(mTwitterPage, mTvTwitterPage, twitterPageLink, "twitter.com"); - final String vkPageLink = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_VK); - refreshSocialPageLink(mVkPage, mTvVkPage, vkPageLink, "vk.com"); - final String linePageLink = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_LINE); - refreshLinePageLink(mLinePage, mTvLinePage, linePageLink); - } - - private void refreshSocialPageLink(View view, TextView tvSocialPage, String socialPage, String webDomain) - { - if (TextUtils.isEmpty(socialPage)) - { - view.setVisibility(GONE); - } - else - { - view.setVisibility(VISIBLE); - if (socialPage.indexOf('/') >= 0) - tvSocialPage.setText("https://" + webDomain + "/" + socialPage); - else - tvSocialPage.setText("@" + socialPage); - } - } - - // Tag `contact:line` could contain urls from domains: line.me, liff.line.me, page.line.me, etc. - // And `socialPage` should not be prepended with domain, but only with "https://" protocol. - private void refreshLinePageLink(View view, TextView tvSocialPage, String socialPage) - { - if (TextUtils.isEmpty(socialPage)) - { - view.setVisibility(GONE); - } - else - { - view.setVisibility(VISIBLE); - if (socialPage.indexOf('/') >= 0) - tvSocialPage.setText("https://" + socialPage); - else - tvSocialPage.setText("@" + socialPage); - } - } - - private void updateBookmarkButton() - { - final List currentButtons = viewModel.getCurrentButtons() - .getValue(); - PlacePageButtons.ButtonType oldType = PlacePageButtons.ButtonType.BOOKMARK_DELETE; - PlacePageButtons.ButtonType newType = PlacePageButtons.ButtonType.BOOKMARK_SAVE; - if (mMapObject.getMapObjectType() == MapObject.BOOKMARK) - { - oldType = PlacePageButtons.ButtonType.BOOKMARK_SAVE; - newType = PlacePageButtons.ButtonType.BOOKMARK_DELETE; - } - if (currentButtons != null) - { - final List newList = new ArrayList<>(currentButtons); - final int index = newList.indexOf(oldType); - if (index >= 0) - { - newList.set(index, newType); - viewModel.setCurrentButtons(newList); - } - } - } - - private void updateButtons(boolean showBackButton, boolean showRoutingButton) - { - List buttons = new ArrayList<>(); - if (mMapObject.getRoadWarningMarkType() != RoadWarningMarkType.UNKNOWN) - { - RoadWarningMarkType markType = mMapObject.getRoadWarningMarkType(); - PlacePageButtons.ButtonType roadType = toPlacePageButton(markType); - buttons.add(roadType); - } - else if (RoutingController.get().isRoutePoint(mMapObject)) - { - buttons.add(PlacePageButtons.ButtonType.ROUTE_REMOVE); - } - else - { - final ParsedMwmRequest request = ParsedMwmRequest.getCurrentRequest(); - if (showBackButton || (request != null && request.isPickPointMode())) - buttons.add(PlacePageButtons.ButtonType.BACK); - - boolean needToShowRoutingButtons = RoutingController.get().isPlanning() || showRoutingButton; - - if (needToShowRoutingButtons) - buttons.add(PlacePageButtons.ButtonType.ROUTE_FROM); - - // If we can show the add route button, put it in the place of the bookmark button - // And move the bookmark button at the end - if (needToShowRoutingButtons && RoutingController.get().isStopPointAllowed()) - buttons.add(PlacePageButtons.ButtonType.ROUTE_ADD); - else - buttons.add(mMapObject.getMapObjectType() == MapObject.BOOKMARK - ? PlacePageButtons.ButtonType.BOOKMARK_DELETE - : PlacePageButtons.ButtonType.BOOKMARK_SAVE); - - if (needToShowRoutingButtons) - { - buttons.add(PlacePageButtons.ButtonType.ROUTE_TO); - if (RoutingController.get().isStopPointAllowed()) - buttons.add(mMapObject.getMapObjectType() == MapObject.BOOKMARK - ? PlacePageButtons.ButtonType.BOOKMARK_DELETE - : PlacePageButtons.ButtonType.BOOKMARK_SAVE); - } - buttons.add(PlacePageButtons.ButtonType.SHARE); - } - viewModel.setCurrentButtons(buttons); - } - private void refreshMyPosition(Location l) { UiUtils.hide(mTvDistance); @@ -844,8 +635,6 @@ public class PlacePageView extends Fragment implements View.OnClickListener, /// @todo /// - Why ll__place_editor and ll__place_latlon check if (mMapObject == null) - /// - Unify urls processing: fb, twitter, instagram, .. add prefix here while - /// wiki, website, wikimedia, ... already have full url. Better to make it in the same way and in Core. @Override public void onClick(View v) @@ -873,42 +662,8 @@ public class PlacePageView extends Fragment implements View.OnClickListener, .apply(); refreshLatLon(); } - else if (id == R.id.ll__place_website) - Utils.openUrl(context, mTvWebsite.getText().toString()); - else if (id == R.id.ll__place_wikimedia) - Utils.openUrl(context, mMapObject.getMetadata(Metadata.MetadataType.FMD_WIKIMEDIA_COMMONS)); - else if (id == R.id.ll__place_facebook) - { - final String facebookPage = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_FACEBOOK); - Utils.openUrl(context, "https://m.facebook.com/" + facebookPage); - } - else if (id == R.id.ll__place_instagram) - { - final String instagramPage = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_INSTAGRAM); - Utils.openUrl(context, "https://instagram.com/" + instagramPage); - } - else if (id == R.id.ll__place_twitter) - { - final String twitterPage = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_TWITTER); - Utils.openUrl(context, "https://mobile.twitter.com/" + twitterPage); - } - else if (id == R.id.ll__place_vk) - { - final String vkPage = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_VK); - Utils.openUrl(context, "https://vk.com/" + vkPage); - } - else if (id == R.id.ll__place_line) - { - final String linePage = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_LINE); - if (linePage.indexOf('/') >= 0) - Utils.openUrl(context, "https://" + linePage); - else - Utils.openUrl(context, "https://line.me/R/ti/p/@" + linePage); - } else if (id == R.id.direction_frame) showBigDirection(); - else if (id == R.id.ll__place_email) - Utils.sendTo(context, mTvEmail.getText().toString()); } private void showBigDirection() @@ -920,9 +675,6 @@ public class PlacePageView extends Fragment implements View.OnClickListener, fragment.show(fragmentManager, null); } - /// @todo Unify urls processing (fb, twitter, instagram, ...). - /// onLongClick behaviour differs even from onClick function several lines above. - @Override public boolean onLongClick(View v) { @@ -941,51 +693,6 @@ public class PlacePageView extends Fragment implements View.OnClickListener, for (CoordinatesFormat format : visibleCoordsFormat) items.add(Framework.nativeFormatLatLon(lat, lon, format.getId())); } - else if (id == R.id.ll__place_website) - items.add(mTvWebsite.getText().toString()); - else if (id == R.id.ll__place_wikimedia) - items.add(mMapObject.getMetadata(Metadata.MetadataType.FMD_WIKIMEDIA_COMMONS)); - else if (id == R.id.ll__place_facebook) - { - final String facebookPage = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_FACEBOOK); - if (facebookPage.indexOf('/') == -1) - items.add(facebookPage); // Show username along with URL. - items.add("https://m.facebook.com/" + facebookPage); - } - else if (id == R.id.ll__place_instagram) - { - final String instagramPage = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_INSTAGRAM); - if (instagramPage.indexOf('/') == -1) - items.add(instagramPage); // Show username along with URL. - items.add("https://instagram.com/" + instagramPage); - } - else if (id == R.id.ll__place_twitter) - { - final String twitterPage = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_TWITTER); - if (twitterPage.indexOf('/') == -1) - items.add(twitterPage); // Show username along with URL. - items.add("https://mobile.twitter.com/" + twitterPage); - } - else if (id == R.id.ll__place_vk) - { - final String vkPage = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_VK); - if (vkPage.indexOf('/') == -1) - items.add(vkPage); // Show username along with URL. - items.add("https://vk.com/" + vkPage); - } - else if (id == R.id.ll__place_line) - { - final String linePage = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_LINE); - if (linePage.indexOf('/') >= 0) - items.add("https://" + linePage); - else - { - items.add(linePage); // Show username along with URL. - items.add("https://line.me/R/ti/p/@" + linePage); - } - } - else if (id == R.id.ll__place_email) - items.add(mTvEmail.getText().toString()); else if (id == R.id.ll__place_operator) items.add(mTvOperator.getText().toString()); else if (id == R.id.ll__place_level) @@ -1066,7 +773,6 @@ public class PlacePageView extends Fragment implements View.OnClickListener, detachCountry(); setCurrentCountry(); - updateBookmarkButton(); refreshViews(); // In case the place page has already some data, make sure to call the onPlacePageContentChanged callback // to catch cases where the new data has the exact same height as the previous one (eg 2 address nodes)