forked from organicmaps/organicmaps
Compare commits
4 commits
master
...
github/for
Author | SHA1 | Date | |
---|---|---|---|
59c569a022 | |||
5cd6340616 | |||
445dbc8264 | |||
6557471697 |
23 changed files with 398 additions and 15 deletions
|
@ -67,7 +67,9 @@ public class Metadata implements Parcelable
|
|||
FMD_WEBSITE_MENU(46),
|
||||
FMD_SELF_SERVICE(47),
|
||||
FMD_OUTDOOR_SEATING(48),
|
||||
FMD_NETWORK(49);
|
||||
FMD_NETWORK(49),
|
||||
FMD_CONTACT_FEDIVERSE(50),
|
||||
FMD_CONTACT_BLUESKY(51);
|
||||
private final int mMetaType;
|
||||
|
||||
MetadataType(int metadataType)
|
||||
|
|
|
@ -189,11 +189,13 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||
initMetadataEntry(Metadata.MetadataType.FMD_WEBSITE, R.string.error_enter_correct_web);
|
||||
initMetadataEntry(Metadata.MetadataType.FMD_WEBSITE_MENU, R.string.error_enter_correct_web);
|
||||
initMetadataEntry(Metadata.MetadataType.FMD_EMAIL, R.string.error_enter_correct_email);
|
||||
initMetadataEntry(Metadata.MetadataType.FMD_CONTACT_FEDIVERSE, R.string.error_enter_correct_fediverse_page);
|
||||
initMetadataEntry(Metadata.MetadataType.FMD_CONTACT_FACEBOOK, R.string.error_enter_correct_facebook_page);
|
||||
initMetadataEntry(Metadata.MetadataType.FMD_CONTACT_INSTAGRAM, R.string.error_enter_correct_instagram_page);
|
||||
initMetadataEntry(Metadata.MetadataType.FMD_CONTACT_TWITTER, R.string.error_enter_correct_twitter_page);
|
||||
initMetadataEntry(Metadata.MetadataType.FMD_CONTACT_VK, R.string.error_enter_correct_vk_page);
|
||||
initMetadataEntry(Metadata.MetadataType.FMD_CONTACT_LINE, R.string.error_enter_correct_line_page);
|
||||
initMetadataEntry(Metadata.MetadataType.FMD_CONTACT_BLUESKY, R.string.error_enter_correct_bluesky_page);
|
||||
|
||||
mCuisine.setText(Editor.nativeGetFormattedCuisine());
|
||||
String selfServiceMetadata = Editor.nativeGetMetadata(Metadata.MetadataType.FMD_SELF_SERVICE.toInt());
|
||||
|
@ -444,6 +446,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||
R.drawable.ic_website_menu, R.string.website_menu, InputType.TYPE_TEXT_VARIATION_URI);
|
||||
View emailBlock = initBlock(view, Metadata.MetadataType.FMD_EMAIL, R.id.block_email,
|
||||
R.drawable.ic_email, R.string.email, InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
|
||||
View fediverseContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_FEDIVERSE, R.id.block_fediverse,
|
||||
R.drawable.ic_mastodon_white, R.string.mastodon, InputType.TYPE_TEXT_VARIATION_URI);
|
||||
View facebookContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_FACEBOOK, R.id.block_facebook,
|
||||
R.drawable.ic_facebook_white, R.string.facebook, InputType.TYPE_TEXT_VARIATION_URI);
|
||||
View instagramContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_INSTAGRAM, R.id.block_instagram,
|
||||
|
@ -454,6 +458,8 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||
R.drawable.ic_vk_white, R.string.vk, InputType.TYPE_TEXT_VARIATION_URI);
|
||||
View lineContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_LINE, R.id.block_line,
|
||||
R.drawable.ic_line_white, R.string.editor_line_social_network, InputType.TYPE_TEXT_VARIATION_URI);
|
||||
View blueskyContactBlock = initBlock(view, Metadata.MetadataType.FMD_CONTACT_BLUESKY, R.id.block_bluesky,
|
||||
R.drawable.ic_bluesky_white, R.string.bluesky, InputType.TYPE_TEXT_VARIATION_URI);
|
||||
View operatorBlock = initBlock(view, Metadata.MetadataType.FMD_OPERATOR, R.id.block_operator,
|
||||
R.drawable.ic_operator, R.string.editor_operator, 0);
|
||||
|
||||
|
@ -499,11 +505,13 @@ public class EditorFragment extends BaseMwmFragment implements View.OnClickListe
|
|||
mDetailsBlocks.put(Metadata.MetadataType.FMD_EMAIL, emailBlock);
|
||||
mDetailsBlocks.put(Metadata.MetadataType.FMD_OPERATOR, operatorBlock);
|
||||
|
||||
mSocialMediaBlocks.put(Metadata.MetadataType.FMD_CONTACT_FEDIVERSE, fediverseContactBlock);
|
||||
mSocialMediaBlocks.put(Metadata.MetadataType.FMD_CONTACT_FACEBOOK, facebookContactBlock);
|
||||
mSocialMediaBlocks.put(Metadata.MetadataType.FMD_CONTACT_INSTAGRAM, instagramContactBlock);
|
||||
mSocialMediaBlocks.put(Metadata.MetadataType.FMD_CONTACT_TWITTER, twitterContactBlock);
|
||||
mSocialMediaBlocks.put(Metadata.MetadataType.FMD_CONTACT_VK, vkContactBlock);
|
||||
mSocialMediaBlocks.put(Metadata.MetadataType.FMD_CONTACT_LINE, lineContactBlock);
|
||||
mSocialMediaBlocks.put(Metadata.MetadataType.FMD_CONTACT_BLUESKY, blueskyContactBlock);
|
||||
}
|
||||
|
||||
private static TextInputEditText findInput(View blockWithInput)
|
||||
|
|
|
@ -41,6 +41,10 @@ public class PlacePageLinksFragment extends Fragment implements Observer<MapObje
|
|||
private TextView mTvInstagramPage;
|
||||
private View mTwitterPage;
|
||||
private TextView mTvTwitterPage;
|
||||
private View mFediversePage;
|
||||
private TextView mTvFediversePage;
|
||||
private View mBlueskyPage;
|
||||
private TextView mTvBlueskyPage;
|
||||
private View mVkPage;
|
||||
private TextView mTvVkPage;
|
||||
private View mLinePage;
|
||||
|
@ -81,7 +85,8 @@ public class PlacePageLinksFragment extends Fragment implements Observer<MapObje
|
|||
mMapObject.getWebsiteUrl(false /* strip */, Metadata.MetadataType.FMD_WEBSITE);
|
||||
case FMD_WEBSITE_MENU ->
|
||||
mMapObject.getWebsiteUrl(false /* strip */, Metadata.MetadataType.FMD_WEBSITE_MENU);
|
||||
case FMD_CONTACT_FACEBOOK, FMD_CONTACT_INSTAGRAM, FMD_CONTACT_TWITTER, FMD_CONTACT_VK, FMD_CONTACT_LINE ->
|
||||
case FMD_CONTACT_FACEBOOK, FMD_CONTACT_INSTAGRAM, FMD_CONTACT_TWITTER,
|
||||
FMD_CONTACT_FEDIVERSE, FMD_CONTACT_BLUESKY, FMD_CONTACT_VK, FMD_CONTACT_LINE ->
|
||||
{
|
||||
if (TextUtils.isEmpty(mMapObject.getMetadata(type)))
|
||||
yield "";
|
||||
|
@ -153,6 +158,16 @@ public class PlacePageLinksFragment extends Fragment implements Observer<MapObje
|
|||
mInstagramPage.setOnClickListener((v) -> openUrl(Metadata.MetadataType.FMD_CONTACT_INSTAGRAM));
|
||||
mInstagramPage.setOnLongClickListener((v) -> copyUrl(mInstagramPage, Metadata.MetadataType.FMD_CONTACT_INSTAGRAM));
|
||||
|
||||
mFediversePage = mFrame.findViewById(R.id.ll__place_fediverse);
|
||||
mTvFediversePage = mFrame.findViewById(R.id.tv__place_fediverse_page);
|
||||
mFediversePage.setOnClickListener((v) -> openUrl(Metadata.MetadataType.FMD_CONTACT_FEDIVERSE));
|
||||
mFediversePage.setOnLongClickListener((v) -> copyUrl(mFediversePage, Metadata.MetadataType.FMD_CONTACT_FEDIVERSE));
|
||||
|
||||
mBlueskyPage = mFrame.findViewById(R.id.ll__place_bluesky);
|
||||
mTvBlueskyPage = mFrame.findViewById(R.id.tv__place_bluesky_page);
|
||||
mBlueskyPage.setOnClickListener((v) -> openUrl(Metadata.MetadataType.FMD_CONTACT_BLUESKY));
|
||||
mBlueskyPage.setOnLongClickListener((v) -> copyUrl(mBlueskyPage, Metadata.MetadataType.FMD_CONTACT_BLUESKY));
|
||||
|
||||
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));
|
||||
|
@ -216,6 +231,12 @@ public class PlacePageLinksFragment extends Fragment implements Observer<MapObje
|
|||
final String instagram = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_INSTAGRAM);
|
||||
refreshMetadataOrHide(instagram, mInstagramPage, mTvInstagramPage);
|
||||
|
||||
final String fediverse = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_FEDIVERSE);
|
||||
refreshMetadataOrHide(fediverse, mFediversePage, mTvFediversePage);
|
||||
|
||||
final String bluesky = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_BLUESKY);
|
||||
refreshMetadataOrHide(bluesky, mBlueskyPage, mTvBlueskyPage);
|
||||
|
||||
final String twitter = mMapObject.getMetadata(Metadata.MetadataType.FMD_CONTACT_TWITTER);
|
||||
refreshMetadataOrHide(twitter, mTwitterPage, mTvTwitterPage);
|
||||
|
||||
|
|
10
android/app/src/main/res/drawable/ic_bluesky_white.xml
Normal file
10
android/app/src/main/res/drawable/ic_bluesky_white.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="72dp"
|
||||
android:height="72dp"
|
||||
android:viewportWidth="72"
|
||||
android:viewportHeight="72">
|
||||
<path
|
||||
android:pathData="m15.607,8.57c8.255,6.197 17.133,18.762 20.393,25.505 3.26,-6.743 12.138,-19.308 20.393,-25.505 5.956,-4.471 15.607,-7.931 15.607,3.078 0,2.199 -1.261,18.47 -2,21.112 -2.57,9.184 -11.935,11.527 -20.265,10.109 14.561,2.478 18.266,10.687 10.266,18.896 -15.193,15.59 -21.837,-3.912 -23.54,-8.909 -0.312,-0.916 -0.458,-1.345 -0.46,-0.98 -0.002,-0.364 -0.148,0.064 -0.46,0.98 -1.702,4.997 -8.346,24.5 -23.54,8.909 -8,-8.209 -4.296,-16.418 10.266,-18.896 -8.331,1.418 -17.696,-0.925 -20.265,-10.109 -0.739,-2.642 -2,-18.914 -2,-21.112 0,-11.009 9.651,-7.549 15.607,-3.078z"
|
||||
android:strokeWidth=".12414"
|
||||
android:fillColor="#fff"/>
|
||||
</vector>
|
10
android/app/src/main/res/drawable/ic_mastodon_white.xml
Normal file
10
android/app/src/main/res/drawable/ic_mastodon_white.xml
Normal file
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="72dp"
|
||||
android:height="72dp"
|
||||
android:viewportWidth="72"
|
||||
android:viewportHeight="72">
|
||||
<path
|
||||
android:pathData="m35.355,-0c-11.839,0 -14.38,0.726 -15.728,0.926 -7.77,1.149 -14.866,6.626 -16.587,14.454 -0.828,3.855 -0.915,8.13 -0.762,12.051 0.219,5.622 0.262,11.233 0.772,16.832 0.353,3.719 0.969,7.41 1.843,11.042 1.637,6.709 8.26,12.291 14.751,14.569 6.949,2.375 14.422,2.769 21.583,1.138 0.788,-0.183 1.566,-0.396 2.334,-0.638 1.741,-0.553 3.78,-1.17 5.279,-2.257 0.021,-0.015 0.038,-0.036 0.05,-0.058 0.012,-0.023 0.019,-0.048 0.019,-0.074v-5.426c-0,-0.024 -0.007,-0.046 -0.017,-0.067 -0.011,-0.021 -0.027,-0.042 -0.045,-0.056s-0.042,-0.025 -0.065,-0.03c-0.023,-0.005 -0.046,-0.005 -0.069,0 -4.588,1.096 -9.29,1.646 -14.006,1.638 -8.117,0 -10.3,-3.853 -10.926,-5.456 -0.503,-1.386 -0.82,-2.83 -0.948,-4.299 -0.001,-0.025 0.003,-0.051 0.013,-0.074 0.01,-0.022 0.024,-0.043 0.043,-0.058 0.019,-0.016 0.043,-0.025 0.067,-0.03 0.024,-0.005 0.047,-0.006 0.071,0 4.511,1.088 9.136,1.639 13.777,1.638 1.116,0 2.229,-0.001 3.345,-0.03 4.667,-0.131 9.587,-0.369 14.179,-1.266 0.115,-0.023 0.229,-0.044 0.327,-0.074 7.243,-1.391 14.137,-5.756 14.837,-16.81 0.026,-0.435 0.091,-4.559 0.091,-5.011 0.003,-1.535 0.495,-10.886 -0.071,-16.633 -1.041,-7.736 -7.783,-13.833 -15.776,-15.015 -1.349,-0.2 -6.457,-0.926 -18.292,-0.926zM25.479,11.78c3.898,0 6.846,1.499 8.81,4.494l1.893,3.18 1.9,-3.18c1.964,-2.994 4.909,-4.494 8.801,-4.494 3.365,0 6.079,1.185 8.154,3.492 2.003,2.31 3.003,5.43 3.001,9.359v19.22h-7.618v-18.654c0,-3.927 -1.636,-5.93 -4.965,-5.93 -3.659,0 -5.491,2.369 -5.491,7.049v10.212h-7.57v-10.212c0,-4.68 -1.838,-7.049 -5.497,-7.049 -3.309,0 -4.961,2.003 -4.961,5.93v18.654h-7.613v-19.22c0,-3.927 1.002,-7.047 3.007,-9.359 2.069,-2.307 4.782,-3.492 8.15,-3.492z"
|
||||
android:strokeWidth="1.1077"
|
||||
android:fillColor="#fff"/>
|
||||
</vector>
|
|
@ -331,6 +331,9 @@
|
|||
android:textAppearance="@style/MwmTextAppearance.Body3"
|
||||
tools:ignore="UnusedAttribute"/>
|
||||
|
||||
<include
|
||||
android:id="@+id/block_fediverse"
|
||||
layout="@layout/item_editor_input"/>
|
||||
<include
|
||||
android:id="@+id/block_facebook"
|
||||
layout="@layout/item_editor_input"/>
|
||||
|
@ -346,6 +349,9 @@
|
|||
<include
|
||||
android:id="@+id/block_line"
|
||||
layout="@layout/item_editor_input"/>
|
||||
<include
|
||||
android:id="@+id/block_bluesky"
|
||||
layout="@layout/item_editor_input"/>
|
||||
</LinearLayout>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
|
|
25
android/app/src/main/res/layout/place_page_bluesky.xml
Normal file
25
android/app/src/main/res/layout/place_page_bluesky.xml
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/ll__place_bluesky"
|
||||
style="@style/PlacePageItemFrame"
|
||||
android:tag="website"
|
||||
tools:background="#20FF0000"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv__place_bluesky"
|
||||
style="@style/PlacePageMetadataIcon"
|
||||
app:srcCompat="@drawable/ic_bluesky_white"
|
||||
app:tint="?colorAccent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__place_bluesky_page"
|
||||
android:textAlignment="viewStart"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/MwmTextAppearance.PlacePage.Accent"
|
||||
tools:text="@string/bluesky"/>
|
||||
</LinearLayout>
|
25
android/app/src/main/res/layout/place_page_fediverse.xml
Normal file
25
android/app/src/main/res/layout/place_page_fediverse.xml
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/ll__place_fediverse"
|
||||
style="@style/PlacePageItemFrame"
|
||||
android:tag="website"
|
||||
tools:background="#20FF0000"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iv__place_fediverse"
|
||||
style="@style/PlacePageMetadataIcon"
|
||||
app:srcCompat="@drawable/ic_mastodon_white"
|
||||
app:tint="?colorAccent"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv__place_fediverse_page"
|
||||
android:textAlignment="viewStart"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/MwmTextAppearance.PlacePage.Accent"
|
||||
tools:text="@string/mastodon"/>
|
||||
</LinearLayout>
|
|
@ -13,11 +13,13 @@
|
|||
android:layout_height="wrap_content"
|
||||
tools:layout="@layout/place_page_phone_fragment" />
|
||||
<include layout="@layout/place_page_email" />
|
||||
<include layout="@layout/place_page_fediverse" />
|
||||
<include layout="@layout/place_page_facebook" />
|
||||
<include layout="@layout/place_page_instagram" />
|
||||
<include layout="@layout/place_page_twitter" />
|
||||
<include layout="@layout/place_page_vk" />
|
||||
<include layout="@layout/place_page_line" />
|
||||
<include layout="@layout/place_page_bluesky" />
|
||||
<include layout="@layout/place_page_wikimedia" />
|
||||
<include layout="@layout/place_page_kayak" />
|
||||
</LinearLayout>
|
|
@ -286,6 +286,8 @@
|
|||
<string name="instagram">Instagram</string>
|
||||
<!-- Text in the editor -->
|
||||
<string name="vk">VK</string>
|
||||
<!-- Text in menu -->
|
||||
<string name="bluesky">Bluesky</string>
|
||||
<!-- Text in the editor -->
|
||||
<string name="editor_line_social_network">LINE</string>
|
||||
<!-- Text in menu -->
|
||||
|
@ -613,6 +615,8 @@
|
|||
<string name="error_enter_correct_twitter_page">Enter a valid Twitter username or web address</string>
|
||||
<string name="error_enter_correct_vk_page">Enter a valid VK username or web address</string>
|
||||
<string name="error_enter_correct_line_page">Enter a valid LINE ID or web address</string>
|
||||
<string name="error_enter_correct_fediverse_page">Enter a valid Mastodon username or web address</string>
|
||||
<string name="error_enter_correct_bluesky_page">Enter a valid Bluesky username or web address</string>
|
||||
<string name="placepage_add_place_button">Add Place to OpenStreetMap</string>
|
||||
<!-- Displayed when saving some edits to the map to warn against publishing personal data -->
|
||||
<string name="editor_share_to_all_dialog_title">Do you want to send it to all users?</string>
|
||||
|
|
|
@ -81,6 +81,12 @@
|
|||
<field name="contact_instagram">
|
||||
<tag k="contact:instagram" />
|
||||
</field>
|
||||
<field name="contact_fediverse">
|
||||
<tag k="contact:mastodon" />
|
||||
</field>
|
||||
<field name="contact_bluesky">
|
||||
<tag k="contact:bluesky" />
|
||||
</field>
|
||||
<field name="contact_twitter">
|
||||
<tag k="contact:twitter" />
|
||||
</field>
|
||||
|
@ -181,6 +187,8 @@
|
|||
<field_ref name="website" />
|
||||
<field_ref name="contact_facebook" />
|
||||
<field_ref name="contact_instagram" />
|
||||
<field_ref name="contact_fediverse" />
|
||||
<field_ref name="contact_bluesky" />
|
||||
<field_ref name="contact_twitter" />
|
||||
<field_ref name="contact_vk" />
|
||||
<field_ref name="contact_line" />
|
||||
|
@ -197,6 +205,8 @@
|
|||
<field_ref name="website" />
|
||||
<field_ref name="contact_facebook" />
|
||||
<field_ref name="contact_instagram" />
|
||||
<field_ref name="contact_fediverse" />
|
||||
<field_ref name="contact_bluesky" />
|
||||
<field_ref name="contact_twitter" />
|
||||
<field_ref name="contact_vk" />
|
||||
<field_ref name="contact_line" />
|
||||
|
|
|
@ -22,6 +22,8 @@ static std::unordered_map<std::string, EType> const kNamesToFMD = {
|
|||
{"website", EType::FMD_WEBSITE},
|
||||
{"contact_facebook", EType::FMD_CONTACT_FACEBOOK},
|
||||
{"contact_instagram", EType::FMD_CONTACT_INSTAGRAM},
|
||||
{"contact_fediverse", EType::FMD_CONTACT_FEDIVERSE},
|
||||
{"contact_bluesky", EType::FMD_CONTACT_BLUESKY},
|
||||
{"contact_twitter", EType::FMD_CONTACT_TWITTER},
|
||||
{"contact_vk", EType::FMD_CONTACT_VK},
|
||||
{"contact_line", EType::FMD_CONTACT_LINE},
|
||||
|
|
|
@ -22,6 +22,8 @@ UNIT_TEST(EditorConfig_TypeDescription)
|
|||
EType::FMD_CONTACT_TWITTER,
|
||||
EType::FMD_CONTACT_VK,
|
||||
EType::FMD_CONTACT_LINE,
|
||||
EType::FMD_CONTACT_FEDIVERSE,
|
||||
EType::FMD_CONTACT_BLUESKY,
|
||||
};
|
||||
|
||||
pugi::xml_document doc;
|
||||
|
|
|
@ -261,6 +261,8 @@ public:
|
|||
string const contact_twitter(meta.Get(feature::Metadata::FMD_CONTACT_TWITTER));
|
||||
string const contact_vk(meta.Get(feature::Metadata::FMD_CONTACT_VK));
|
||||
string const contact_line(meta.Get(feature::Metadata::FMD_CONTACT_LINE));
|
||||
string const contact_fediverse(meta.Get(feature::Metadata::FMD_CONTACT_FEDIVERSE));
|
||||
string const contact_bluesky(meta.Get(feature::Metadata::FMD_CONTACT_BLUESKY));
|
||||
string const stars(meta.Get(feature::Metadata::FMD_STARS));
|
||||
string const internet(meta.Get(feature::Metadata::FMD_INTERNET));
|
||||
string const denomination(meta.Get(feature::Metadata::FMD_DENOMINATION));
|
||||
|
@ -276,7 +278,7 @@ public:
|
|||
osmId, uid, lat, lon, mwmName, category, name, std::string(city),
|
||||
addrStreet, addrHouse, phone, website, stars, std::string(metaOperator), internet,
|
||||
denomination, wheelchair, opening_hours, wikipedia, floor, fee, atm, contact_facebook,
|
||||
contact_instagram, contact_twitter, contact_vk, contact_line, wikimedia_commons};
|
||||
contact_instagram, contact_twitter, contact_vk, contact_line, contact_fediverse, contact_bluesky, wikimedia_commons};
|
||||
|
||||
AppendNames(f, columns);
|
||||
PrintAsCSV(columns, ';', cout);
|
||||
|
@ -290,7 +292,7 @@ void PrintHeader()
|
|||
"phone", "website", "cuisines", "stars", "operator",
|
||||
"internet", "denomination", "wheelchair", "opening_hours", "wikipedia",
|
||||
"floor", "fee", "atm", "contact_facebook", "contact_instagram",
|
||||
"contact_twitter", "contact_vk", "contact_line", "wikimedia_commons"};
|
||||
"contact_twitter", "contact_vk", "contact_line", "contact_fediverse", "contact_bluesky", "wikimedia_commons"};
|
||||
// Append all supported name languages in order.
|
||||
for (uint8_t idx = 1; idx < kLangCount; idx++)
|
||||
columns.push_back("name_" + string(StringUtf8Multilang::GetLangByCode(idx)));
|
||||
|
|
|
@ -534,6 +534,8 @@ void MetadataTagProcessor::operator()(std::string const & k, std::string const &
|
|||
case Metadata::FMD_CONTACT_TWITTER: valid = osm::ValidateAndFormat_twitter(v); break;
|
||||
case Metadata::FMD_CONTACT_VK: valid = osm::ValidateAndFormat_vk(v); break;
|
||||
case Metadata::FMD_CONTACT_LINE: valid = osm::ValidateAndFormat_contactLine(v); break;
|
||||
case Metadata::FMD_CONTACT_FEDIVERSE: valid = osm::ValidateAndFormat_fediverse(v); break;
|
||||
case Metadata::FMD_CONTACT_BLUESKY: valid = osm::ValidateAndFormat_bluesky(v); break;
|
||||
case Metadata::FMD_INTERNET: valid = ValidateAndFormat_internet(v); break;
|
||||
case Metadata::FMD_ELE: valid = ValidateAndFormat_ele(v); break;
|
||||
case Metadata::FMD_DESTINATION: valid = ValidateAndFormat_destination(v); break;
|
||||
|
|
|
@ -249,6 +249,8 @@ bool EditableMapObject::IsValidMetadata(MetadataID type, std::string const & val
|
|||
case MetadataID::FMD_CONTACT_TWITTER: return ValidateTwitterPage(value);
|
||||
case MetadataID::FMD_CONTACT_VK: return ValidateVkPage(value);
|
||||
case MetadataID::FMD_CONTACT_LINE: return ValidateLinePage(value);
|
||||
case MetadataID::FMD_CONTACT_FEDIVERSE: return ValidateFediversePage(value);
|
||||
case MetadataID::FMD_CONTACT_BLUESKY: return ValidateBlueskyPage(value);
|
||||
|
||||
case MetadataID::FMD_STARS:
|
||||
{
|
||||
|
@ -284,6 +286,8 @@ void EditableMapObject::SetMetadata(MetadataID type, std::string value)
|
|||
case MetadataID::FMD_CONTACT_TWITTER: value = ValidateAndFormat_twitter(value); break;
|
||||
case MetadataID::FMD_CONTACT_VK: value = ValidateAndFormat_vk(value); break;
|
||||
case MetadataID::FMD_CONTACT_LINE: value = ValidateAndFormat_contactLine(value); break;
|
||||
case MetadataID::FMD_CONTACT_FEDIVERSE: value = ValidateAndFormat_fediverse(value); break;
|
||||
case MetadataID::FMD_CONTACT_BLUESKY: value = ValidateAndFormat_bluesky(value); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
|
|
@ -95,6 +95,10 @@ bool Metadata::TypeFromString(string_view k, Metadata::EType & outType)
|
|||
outType = Metadata::FMD_CONTACT_VK;
|
||||
else if (k == "contact:line")
|
||||
outType = Metadata::FMD_CONTACT_LINE;
|
||||
else if (k == "contact:mastodon")
|
||||
outType = Metadata::FMD_CONTACT_FEDIVERSE;
|
||||
else if (k == "contact:bluesky")
|
||||
outType = Metadata::FMD_CONTACT_BLUESKY;
|
||||
else if (k == "internet_access" || k == "wifi")
|
||||
outType = Metadata::FMD_INTERNET;
|
||||
else if (k == "ele")
|
||||
|
@ -264,6 +268,8 @@ string ToString(Metadata::EType type)
|
|||
case Metadata::FMD_CONTACT_TWITTER: return "contact:twitter";
|
||||
case Metadata::FMD_CONTACT_VK: return "contact:vk";
|
||||
case Metadata::FMD_CONTACT_LINE: return "contact:line";
|
||||
case Metadata::FMD_CONTACT_FEDIVERSE: return "contact:mastodon";
|
||||
case Metadata::FMD_CONTACT_BLUESKY: return "contact:bluesky";
|
||||
case Metadata::FMD_DESTINATION: return "destination";
|
||||
case Metadata::FMD_DESTINATION_REF: return "destination:ref";
|
||||
case Metadata::FMD_JUNCTION_REF: return "junction:ref";
|
||||
|
|
|
@ -155,6 +155,8 @@ public:
|
|||
FMD_SELF_SERVICE = 47,
|
||||
FMD_OUTDOOR_SEATING = 48,
|
||||
FMD_NETWORK = 49,
|
||||
FMD_CONTACT_FEDIVERSE = 50,
|
||||
FMD_CONTACT_BLUESKY = 51,
|
||||
FMD_COUNT
|
||||
};
|
||||
|
||||
|
|
|
@ -108,6 +108,39 @@ UNIT_TEST(EditableMapObject_ValidateAndFormat_contactLine)
|
|||
TEST_EQUAL(osm::ValidateAndFormat_contactLine("https://line.com/ti/p/invalid-domain"), "", ());
|
||||
}
|
||||
|
||||
UNIT_TEST(EditableMapObject_ValidateAndFormat_fediverse)
|
||||
{
|
||||
TEST_EQUAL(osm::ValidateAndFormat_fediverse("https://fosstodon.org/@organicmaps"), "organicmaps@fosstodon.org", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_fediverse("https://fosstodon.org/users/organicmaps"), "organicmaps@fosstodon.org", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_fediverse("http://fosstodon.org/users/organicmaps"), "organicmaps@fosstodon.org", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_fediverse("fosstodon.org/users/organicmaps"), "organicmaps@fosstodon.org", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_fediverse("organicmaps@fosstodon.org"), "organicmaps@fosstodon.org", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_fediverse("@organicmaps@fosstodon.org"), "organicmaps@fosstodon.org", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_fediverse("@organicmaps@fosstodon.org.uk"), "organicmaps@fosstodon.org.uk", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_fediverse("pub.mastodon.org.uk/@organicmaps"), "organicmaps@pub.mastodon.org.uk", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_fediverse("pub.mastodon.org.uk/users/@organicmaps"), "organicmaps@pub.mastodon.org.uk", ());
|
||||
|
||||
TEST_EQUAL(osm::ValidateAndFormat_fediverse("organicmaps@fosstodon@mastodon.org"), "", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_fediverse("orga$nicmaps@mastodon.social"), "", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_fediverse("pub.mastodon.org.uk/organicmaps"), "", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_fediverse("pub.mastodon.org.uk/users/"), "", ());
|
||||
}
|
||||
|
||||
UNIT_TEST(EditableMapObject_ValidateAndFormat_bluesky)
|
||||
{
|
||||
TEST_EQUAL(osm::ValidateAndFormat_bluesky("organicmaps.bsky.social"), "organicmaps.bsky.social", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_bluesky("@organicmaps.bsky.social"), "organicmaps.bsky.social", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_bluesky("https://bsky.app/profile/organicmaps.bsky.social"), "organicmaps.bsky.social", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_bluesky("https://bsky.app/profile/@organicmaps.bsky.social"), "organicmaps.bsky.social", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_bluesky("http://bsky.app/profile/organicmaps.bsky.social"), "organicmaps.bsky.social", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_bluesky("bsky.app/profile/organicmaps.bsky.social"), "organicmaps.bsky.social", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_bluesky("https://bsky.app/profile/organicmaps.bsky.social"), "organicmaps.bsky.social", ());
|
||||
|
||||
TEST_EQUAL(osm::ValidateAndFormat_bluesky("https://bsky.app/profile/organicmap$.bsky.social"), "", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_bluesky("https://bsky.app/profile/organicmaps.bsky.social$"), "", ());
|
||||
TEST_EQUAL(osm::ValidateAndFormat_bluesky("https://bsky.app/pineapple/organicmaps.bsky.social"), "", ());
|
||||
}
|
||||
|
||||
UNIT_TEST(EditableMapObject_ValidateFacebookPage)
|
||||
{
|
||||
TEST(osm::ValidateFacebookPage(""), ());
|
||||
|
@ -262,6 +295,39 @@ UNIT_TEST(EditableMapObject_ValidateLinePage)
|
|||
TEST(!osm::ValidateLinePage("https://line.com/ti/p/invalid-domain"), ());
|
||||
}
|
||||
|
||||
UNIT_TEST(EditableMapObject_ValidateFediversePage)
|
||||
{
|
||||
TEST(osm::ValidateFediversePage("https://fosstodon.org/@organicmaps"), ());
|
||||
TEST(osm::ValidateFediversePage("https://fosstodon.org/users/organicmaps"), ());
|
||||
TEST(osm::ValidateFediversePage("http://fosstodon.org/users/organicmaps"), ());
|
||||
TEST(osm::ValidateFediversePage("fosstodon.org/users/organicmaps"), ());
|
||||
TEST(osm::ValidateFediversePage("organicmaps@fosstodon.org"), ());
|
||||
TEST(osm::ValidateFediversePage("@organicmaps@fosstodon.org"), ());
|
||||
TEST(osm::ValidateFediversePage("@organicmaps@fosstodon.org.uk"), ());
|
||||
TEST(osm::ValidateFediversePage("pub.mastodon.org.uk/@organicmaps"), ());
|
||||
TEST(osm::ValidateFediversePage("pub.mastodon.org.uk/users/@organicmaps"), ());
|
||||
|
||||
TEST(!osm::ValidateFediversePage("organicmaps@fosstodon@mastodon.org"), ());
|
||||
TEST(!osm::ValidateFediversePage("orga$nicmaps@mastodon.social"), ());
|
||||
TEST(!osm::ValidateFediversePage("pub.mastodon.org.uk/organicmaps"), ());
|
||||
TEST(!osm::ValidateFediversePage("pub.mastodon.org.uk/users/"), ());
|
||||
}
|
||||
|
||||
UNIT_TEST(EditableMapObject_ValidateBlueskyPage)
|
||||
{
|
||||
TEST(osm::ValidateBlueskyPage("organicmaps.bsky.social"), ());
|
||||
TEST(osm::ValidateBlueskyPage("@organicmaps.bsky.social"), ());
|
||||
TEST(osm::ValidateBlueskyPage("https://bsky.app/profile/organicmaps.bsky.social"), ());
|
||||
TEST(osm::ValidateBlueskyPage("https://bsky.app/profile/@organicmaps.bsky.social"), ());
|
||||
TEST(osm::ValidateBlueskyPage("http://bsky.app/profile/organicmaps.bsky.social"), ());
|
||||
TEST(osm::ValidateBlueskyPage("bsky.app/profile/organicmaps.bsky.social"), ());
|
||||
TEST(osm::ValidateBlueskyPage("https://bsky.app/profile/organicmaps.bsky.social"), ());
|
||||
|
||||
TEST(!osm::ValidateBlueskyPage("https://bsky.app/profile/organicmap$.bsky.social"), ());
|
||||
TEST(!osm::ValidateBlueskyPage("https://bsky.app/profile/organicmaps.bsky.social$"), ());
|
||||
TEST(!osm::ValidateBlueskyPage("https://bsky.app/pineapple/organicmaps.bsky.social"), ());
|
||||
}
|
||||
|
||||
UNIT_TEST(EditableMapObject_socialContactToURL)
|
||||
{
|
||||
TEST_EQUAL(osm::socialContactToURL(osm::MapObject::MetadataID::FMD_CONTACT_INSTAGRAM, "some_page_name"), "https://instagram.com/some_page_name", ());
|
||||
|
|
|
@ -16,12 +16,16 @@ static auto const s_twitterRegex = regex(R"(^@?[A-Za-z0-9_]{1,15}$)");
|
|||
static auto const s_badVkRegex = regex(R"(^\d\d\d.+$)");
|
||||
static auto const s_goodVkRegex = regex(R"(^[A-Za-z0-9_.]{5,32}$)");
|
||||
static auto const s_lineRegex = regex(R"(^[a-z0-9-_.]{4,20}$)");
|
||||
static auto const s_fediverseRegex = regex(R"(^@?[a-zA-Z0-9_]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$)");
|
||||
static auto const s_blueskyRegex = regex(R"(^@?[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)+$)");
|
||||
|
||||
constexpr string_view kFacebook{"contact:facebook"};
|
||||
constexpr string_view kInstagram{"contact:instagram"};
|
||||
constexpr string_view kTwitter{"contact:twitter"};
|
||||
constexpr string_view kVk{"contact:vk"};
|
||||
constexpr string_view kLine{"contact:line"};
|
||||
constexpr string_view kFediverse{"contact:mastodon"};
|
||||
constexpr string_view kBluesky{"contact:bluesky"};
|
||||
|
||||
constexpr string_view kProfilePhp{"profile.php"};
|
||||
|
||||
|
@ -41,6 +45,7 @@ constexpr string_view kDotVkontakteRu{".vkontakte.ru"};
|
|||
constexpr string_view kLineMe{"line.me"};
|
||||
constexpr string_view kPageLineMe{"page.line.me"};
|
||||
constexpr string_view kDotLineMe{".line.me"};
|
||||
constexpr string_view kBskyApp{"bsky.app"};
|
||||
|
||||
// URLs constants
|
||||
constexpr string_view kUrlFacebook{"https://facebook.com/"};
|
||||
|
@ -48,6 +53,7 @@ constexpr string_view kUrlInstagram{"https://instagram.com/"};
|
|||
constexpr string_view kUrlTwitter{"https://twitter.com/"};
|
||||
constexpr string_view kUrlVk{"https://vk.com/"};
|
||||
constexpr string_view kUrlLine{"https://line.me/R/ti/p/@"};
|
||||
constexpr string_view kUrlBluesky{"https://bsky.app/profile/"};
|
||||
constexpr string_view kHttp{"http://"};
|
||||
constexpr string_view kHttps{"https://"};
|
||||
|
||||
|
@ -65,6 +71,13 @@ bool IsProtocolSpecified(string const & website)
|
|||
return 0 != GetProtocolNameLength(website);
|
||||
}
|
||||
|
||||
string fediverseHandleToUrl(string_view handle)
|
||||
{
|
||||
// Convert stored username@domain.name to https://domain.name/username
|
||||
vector<string_view> const handleElements = strings::Tokenize(handle, "@");
|
||||
return string{kHttps}.append(handleElements[1]).append("/@").append(handleElements[0]);
|
||||
}
|
||||
|
||||
// TODO: Current implementation looks only for restricted symbols from ASCII block ignoring
|
||||
// unicode. Need to find all restricted *Unicode* symbols
|
||||
// from https://www.facebook.com/pages/create page and verify those symbols
|
||||
|
@ -239,16 +252,16 @@ string ValidateAndFormat_vk(string const & vkPage)
|
|||
return {};
|
||||
}
|
||||
|
||||
// Strip '%40' and `@` chars from Line ID start.
|
||||
string stripAtSymbol(string const & lineId)
|
||||
// Strip '%40' and `@` chars from string start if they exist.
|
||||
string stripAtSymbol(string const & inputString)
|
||||
{
|
||||
if (lineId.empty())
|
||||
return lineId;
|
||||
if (lineId.front() == '@')
|
||||
return lineId.substr(1);
|
||||
if (lineId.starts_with("%40"))
|
||||
return lineId.substr(3);
|
||||
return lineId;
|
||||
if (inputString.empty())
|
||||
return inputString;
|
||||
if (inputString.front() == '@')
|
||||
return inputString.substr(1);
|
||||
if (inputString.starts_with("%40"))
|
||||
return inputString.substr(3);
|
||||
return inputString;
|
||||
}
|
||||
|
||||
string ValidateAndFormat_contactLine(string const & linePage)
|
||||
|
@ -318,6 +331,79 @@ string ValidateAndFormat_contactLine(string const & linePage)
|
|||
return {};
|
||||
}
|
||||
|
||||
string ValidateAndFormat_fediverse(string const & fediPage)
|
||||
{
|
||||
if (fediPage.empty())
|
||||
return {};
|
||||
|
||||
// Parse {@?}{username}@{domain.name} format
|
||||
if (regex_match(fediPage, s_fediverseRegex))
|
||||
return stripAtSymbol(fediPage);
|
||||
|
||||
// If it doesn't match the above format, it can only be an URL format.
|
||||
if (!ValidateWebsite(fediPage))
|
||||
return {};
|
||||
|
||||
// Parse https://{domain.name}{@ || /users/}{username} formats
|
||||
url::Url const parsedUrl = url::Url::FromString(fediPage);
|
||||
string const parsedDomain = strings::MakeLowerCase(parsedUrl.GetHost());
|
||||
string path = parsedUrl.GetPath();
|
||||
path.erase(path.find_last_not_of('/') + 1); // Strip any trailing '/' symbol
|
||||
|
||||
// Could be /users/ type - check and remove to be left with just username.
|
||||
if (path.starts_with("users/")) // first slash is already removed by GetPath()
|
||||
{
|
||||
path.erase(0, 6);
|
||||
path = stripAtSymbol(path); // handle technically wrong but parseable domain/users/@username
|
||||
}
|
||||
// domain.name/@username - username has to start with @
|
||||
else if (path.starts_with("@"))
|
||||
path = stripAtSymbol(path);
|
||||
// unknown/invalid format
|
||||
else
|
||||
return {};
|
||||
|
||||
// Then construct the final username@domain.name format
|
||||
path.append("@").append(parsedDomain);
|
||||
// and make sure it's valid
|
||||
if (regex_match(path, s_fediverseRegex))
|
||||
return path;
|
||||
else
|
||||
return {};
|
||||
}
|
||||
|
||||
string ValidateAndFormat_bluesky(string const & bskyPage)
|
||||
{
|
||||
if (bskyPage.empty())
|
||||
return {};
|
||||
|
||||
// Try matching {@?}{user/domain.name} format to avoid doing the other stuff
|
||||
if (regex_match(bskyPage, s_blueskyRegex))
|
||||
return stripAtSymbol(bskyPage);
|
||||
|
||||
// If not, it must match the URL format
|
||||
if (ValidateWebsite(bskyPage))
|
||||
{
|
||||
// Match https://bsky.app/profile/{username/domain.name}
|
||||
url::Url const pageUrl = url::Url::FromString(bskyPage);
|
||||
string_view const domain = pageUrl.GetHost();
|
||||
string path = pageUrl.GetPath();
|
||||
|
||||
// First remove url bits if they exist
|
||||
if (domain.starts_with(kBskyApp) && path.starts_with("profile/"))
|
||||
{
|
||||
path.erase(0, 8); // Strip "profile/" part
|
||||
path.erase(path.find_last_not_of('/') + 1); // Strip last '/' symbol if exists
|
||||
|
||||
// Then make sure it matches {@?}{user/domain.name}
|
||||
if (regex_match(path, s_blueskyRegex))
|
||||
return stripAtSymbol(path);
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool ValidateWebsite(string const & site)
|
||||
{
|
||||
if (site.empty())
|
||||
|
@ -449,9 +535,79 @@ bool ValidateLinePage(string const & page)
|
|||
return (domain == kLineMe || domain.ends_with(kDotLineMe));
|
||||
}
|
||||
|
||||
bool ValidateFediversePage(string const & page)
|
||||
{
|
||||
if (page.empty())
|
||||
return true;
|
||||
|
||||
// Match @username@instance.name format
|
||||
if (regex_match(page, s_fediverseRegex))
|
||||
return true;
|
||||
|
||||
// If it doesn't match the above format, it can only be an URL format.
|
||||
if (!ValidateWebsite(page))
|
||||
return false;
|
||||
|
||||
// Try to match https://{domain.name}{@ || /users/}{username} formats
|
||||
url::Url const pageUrl = url::Url::FromString(page);
|
||||
string_view const domain = pageUrl.GetHost();
|
||||
string path = pageUrl.GetPath();
|
||||
|
||||
// Could be /users/ type - check and remove to be left with just username.
|
||||
if (path.starts_with("users/")) // first slash is already removed by GetPath()
|
||||
{
|
||||
path.erase(0, 6);
|
||||
path = stripAtSymbol(path); // handle technically wrong but parseable domain/users/@username
|
||||
}
|
||||
// domain.name/@username - username has to start with @
|
||||
else if (path.starts_with("@"))
|
||||
path = stripAtSymbol(path);
|
||||
// unknown/invalid format
|
||||
else
|
||||
return false;
|
||||
|
||||
path.erase(path.find_last_not_of('/') + 1); // Strip any trailing '/' symbol
|
||||
// Then construct the username@domain.name format
|
||||
path.append("@").append(domain);
|
||||
// And return if it's valid or not
|
||||
return regex_match(path, s_fediverseRegex);
|
||||
}
|
||||
|
||||
bool ValidateBlueskyPage(string const & page)
|
||||
{
|
||||
// A valid username can be any domain name, so the username rules don't apply.
|
||||
if (page.empty())
|
||||
return true;
|
||||
|
||||
// Match {@?}{user/domain.name} format
|
||||
if (regex_match(page, s_blueskyRegex))
|
||||
return true;
|
||||
|
||||
// Has to be an url format now
|
||||
if (!ValidateWebsite(page))
|
||||
return false;
|
||||
|
||||
// Match https://bsky.app/profile/{username/domain.name}
|
||||
url::Url const pageUrl = url::Url::FromString(page);
|
||||
string_view const domain = pageUrl.GetHost();
|
||||
string path = pageUrl.GetPath();
|
||||
|
||||
// First remove url bits if they exist
|
||||
if (domain.starts_with(kBskyApp) && path.starts_with("profile/"))
|
||||
{
|
||||
path.erase(0, 8); // Strip "profile/" part
|
||||
path.erase(path.find_last_not_of('/') + 1); // Strip last '/' symbol if exists
|
||||
// Then try to parse the remaining text as a username again
|
||||
if (regex_match(path, s_blueskyRegex))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isSocialContactTag(string_view tag)
|
||||
{
|
||||
return tag == kInstagram || tag == kFacebook || tag == kTwitter || tag == kVk || tag == kLine;
|
||||
return tag == kInstagram || tag == kFacebook || tag == kTwitter || tag == kVk || tag == kLine || tag == kFediverse || tag == kBluesky;
|
||||
}
|
||||
|
||||
bool isSocialContactTag(MapObject::MetadataID const metaID)
|
||||
|
@ -460,7 +616,9 @@ bool isSocialContactTag(MapObject::MetadataID const metaID)
|
|||
metaID == MapObject::MetadataID::FMD_CONTACT_FACEBOOK ||
|
||||
metaID == MapObject::MetadataID::FMD_CONTACT_TWITTER ||
|
||||
metaID == MapObject::MetadataID::FMD_CONTACT_VK ||
|
||||
metaID == MapObject::MetadataID::FMD_CONTACT_LINE;
|
||||
metaID == MapObject::MetadataID::FMD_CONTACT_LINE ||
|
||||
metaID == MapObject::MetadataID::FMD_CONTACT_FEDIVERSE ||
|
||||
metaID == MapObject::MetadataID ::FMD_CONTACT_BLUESKY;
|
||||
}
|
||||
|
||||
// Functions ValidateAndFormat_{facebook,instagram,twitter,vk}(...) by default strip domain name
|
||||
|
@ -477,6 +635,10 @@ string socialContactToURL(string_view tag, string_view value)
|
|||
return string{kUrlTwitter}.append(value);
|
||||
if (tag == kVk)
|
||||
return string{kUrlVk}.append(value);
|
||||
if (tag == kFediverse)
|
||||
return fediverseHandleToUrl(value);
|
||||
if (tag == kBluesky) // In future
|
||||
return string{kUrlBluesky}.append(value);
|
||||
if (tag == kLine)
|
||||
{
|
||||
if (value.find('/') == string::npos) // 'value' is a username.
|
||||
|
@ -502,6 +664,10 @@ string socialContactToURL(MapObject::MetadataID metaID, string_view value)
|
|||
return string{kUrlTwitter}.append(value);
|
||||
case MapObject::MetadataID::FMD_CONTACT_VK:
|
||||
return string{kUrlVk}.append(value);
|
||||
case MapObject::MetadataID::FMD_CONTACT_FEDIVERSE:
|
||||
return fediverseHandleToUrl(value);
|
||||
case MapObject::MetadataID::FMD_CONTACT_BLUESKY:
|
||||
return string{kUrlBluesky}.append(value);
|
||||
case MapObject::MetadataID::FMD_CONTACT_LINE:
|
||||
if (value.find('/') == string::npos) // 'value' is a username.
|
||||
return string{kUrlLine}.append(value);
|
||||
|
|
|
@ -12,6 +12,8 @@ std::string ValidateAndFormat_instagram(std::string const & v);
|
|||
std::string ValidateAndFormat_twitter(std::string const & v);
|
||||
std::string ValidateAndFormat_vk(std::string const & v);
|
||||
std::string ValidateAndFormat_contactLine(std::string const & v);
|
||||
std::string ValidateAndFormat_fediverse(std::string const & v);
|
||||
std::string ValidateAndFormat_bluesky(std::string const & v);
|
||||
|
||||
bool ValidateWebsite(std::string const & site);
|
||||
bool ValidateFacebookPage(std::string const & v);
|
||||
|
@ -19,6 +21,8 @@ bool ValidateInstagramPage(std::string const & v);
|
|||
bool ValidateTwitterPage(std::string const & v);
|
||||
bool ValidateVkPage(std::string const & v);
|
||||
bool ValidateLinePage(std::string const & v);
|
||||
bool ValidateFediversePage(std::string const & v);
|
||||
bool ValidateBlueskyPage(std::string const & v);
|
||||
|
||||
bool isSocialContactTag(std::string_view tag);
|
||||
bool isSocialContactTag(osm::MapObject::MetadataID const metaID);
|
||||
|
|
|
@ -113,6 +113,8 @@ PlacePageDialogDeveloper::PlacePageDialogDeveloper(QWidget * parent, place_page:
|
|||
case PropID::FMD_CONTACT_TWITTER:
|
||||
case PropID::FMD_CONTACT_VK:
|
||||
case PropID::FMD_CONTACT_LINE:
|
||||
case PropID::FMD_CONTACT_FEDIVERSE:
|
||||
case PropID::FMD_CONTACT_BLUESKY:
|
||||
case PropID::FMD_WIKIPEDIA:
|
||||
case PropID::FMD_WIKIMEDIA_COMMONS:
|
||||
isLink = true;
|
||||
|
|
|
@ -218,6 +218,8 @@ PlacePageDialogUser::PlacePageDialogUser(QWidget * parent, place_page::Info cons
|
|||
addSocialNetworkWidget("Twitter", feature::Metadata::EType::FMD_CONTACT_TWITTER);
|
||||
addSocialNetworkWidget("VK", feature::Metadata::EType::FMD_CONTACT_VK);
|
||||
addSocialNetworkWidget("Line", feature::Metadata::EType::FMD_CONTACT_LINE);
|
||||
addSocialNetworkWidget("Mastodon", feature::Metadata::EType::FMD_CONTACT_FEDIVERSE);
|
||||
addSocialNetworkWidget("Bluesky", feature::Metadata::EType::FMD_CONTACT_BLUESKY);
|
||||
}
|
||||
|
||||
if (auto wikimedia_commons = info.GetMetadata(feature::Metadata::EType::FMD_WIKIMEDIA_COMMONS); !wikimedia_commons.empty())
|
||||
|
|
Loading…
Add table
Reference in a new issue