diff --git a/.re-natal b/.re-natal
index bf1cc9c8e9..52acfba22c 100644
--- a/.re-natal
+++ b/.re-natal
@@ -41,7 +41,8 @@
"instabug-reactnative",
"nfc-react-native",
"react-native-http-bridge",
- "emojilib"
+ "emojilib",
+ "react-native-mapbox-gl"
],
"imageDirs": [
"images"
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 1d0e8daf83..18f9010bd3 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -107,6 +107,7 @@ android {
applicationId "im.status.ethereum"
minSdkVersion 18
targetSdkVersion 23
+ multiDexEnabled true
versionCode getVersionCode()
versionName getVersionName()
ndk {
@@ -115,6 +116,7 @@ android {
}
dexOptions {
jumboMode true
+ javaMaxHeapSize "4g"
}
signingConfigs {
release {
@@ -180,6 +182,7 @@ dependencies {
compile project(':react-native-fs')
compile project(':react-native-image-crop-picker')
compile project(':react-native-webview-bridge')
+ compile project(':reactnativemapboxgl')
compile 'testfairy:testfairy-android-sdk:1.+@aar'
compile fileTree(dir: "node_modules/realm/android/libs", include: ["*.jar"])
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index e21a7b75b0..d285a9efc0 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -52,6 +52,7 @@
android:enabled="true"
android:exported="true"/>
+
diff --git a/android/app/src/main/java/im/status/ethereum/MainApplication.java b/android/app/src/main/java/im/status/ethereum/MainApplication.java
index c5d65a18dc..2e6dc607a2 100644
--- a/android/app/src/main/java/im/status/ethereum/MainApplication.java
+++ b/android/app/src/main/java/im/status/ethereum/MainApplication.java
@@ -24,6 +24,7 @@ import fr.bamlab.rnimageresizer.ImageResizerPackage;
import im.status.ethereum.module.StatusPackage;
import io.realm.react.RealmReactPackage;
import me.alwx.HttpServer.HttpServerReactPackage;
+import com.mapbox.reactnativemapboxgl.ReactNativeMapboxGLPackage;
import java.util.ArrayList;
import java.util.Arrays;
@@ -58,7 +59,8 @@ public class MainApplication extends Application implements ReactApplication {
new ReactNativeDialogsPackage(),
new ImageResizerPackage(),
new PickerPackage(),
- new WebViewBridgePackage(BuildConfig.DEBUG)
+ new WebViewBridgePackage(BuildConfig.DEBUG),
+ new ReactNativeMapboxGLPackage()
));
if (!BuildConfig.DEBUG) {
diff --git a/android/settings.gradle b/android/settings.gradle
index 928c18f584..806e75fc6c 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -40,4 +40,7 @@ include ':react-native-image-crop-picker'
project(':react-native-image-crop-picker').projectDir = new File(settingsDir, '../node_modules/react-native-image-crop-picker/android')
include ':react-native-webview-bridge'
-project(':react-native-webview-bridge').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview-bridge/android')
\ No newline at end of file
+project(':react-native-webview-bridge').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview-bridge/android')
+
+include ':reactnativemapboxgl'
+project(':reactnativemapboxgl').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-mapbox-gl/android')
diff --git a/bots/mailman/bot.js b/bots/mailman/bot.js
index 75f9df04cc..ae579d773f 100644
--- a/bots/mailman/bot.js
+++ b/bots/mailman/bot.js
@@ -1,44 +1,91 @@
+function locationsSuggestions (params) {
+ var result = {title: "Send location"};
+ var seqArg = params["seq-arg"] ? params["seq-arg"] : "";
+
+ if (seqArg === "Dropped pin")
+ {
+ result.showBack = true;
+ result.height = "max";
+ result.markup = ['view', {},
+ ['dropped-pin']];
+ }
+ else if (seqArg != "")
+ {
+ result.showBack = true;
+ result.markup = ['scroll-view', {keyboardShouldPersistTaps: "always"},
+ ['view', {},
+ ['places-search']]];
+ }
+ else
+ {
+ result.markup = ['scroll-view', {keyboardShouldPersistTaps: "always"},
+ ['view', {},
+ ['current-location-map'],
+ ['current-location'],
+ ['separator'],
+ ['places-nearby']]];
+ }
+
+ return result;
+}
+
status.command({
name: "location",
- icon: "location",
title: I18n.t('location_title'),
description: I18n.t('location_description'),
- color: "#a187d5",
sequentialParams: true,
- registeredOnly: true,
+ hideSendButton: true,
params: [{
name: "address",
type: status.types.TEXT,
- placeholder: I18n.t('location_address')
+ placeholder: I18n.t('location_address'),
+ suggestions: locationsSuggestions
}],
preview: function (params) {
+ var address = params.address.split("&");
var text = status.components.text(
{
style: {
- marginTop: 5,
+ marginTop: 0,
marginHorizontal: 0,
- fontSize: 14,
+ fontSize: 15,
+ lineHeight: 23,
fontFamily: "font",
color: "black"
}
- }, params.address);
- var uri = "https://maps.googleapis.com/maps/api/staticmap?center="
- + params.address
- + "&size=100x100&maptype=roadmap&key=AIzaSyBNsj1qoQEYPb3IllmWMAscuXW0eeuYqAA&language=en"
- + "&markers=size:mid%7Ccolor:0xff0000%7Clabel:%7C"
- + params.address;
+ }, address[0]);
+ var uri = "https://api.mapbox.com/styles/v1/mapbox/streets-v10/static/" +
+ address[1] + "," + address[2] + ",10,20" +
+ "/175x58?access_token=pk.eyJ1Ijoic3RhdHVzaW0iLCJhIjoiY2oydmtnZjRrMDA3czMzcW9kemR4N2lxayJ9.Rz8L6xdHBjfO8cR3CDf3Cw";
var image = status.components.image(
{
source: {uri: uri},
style: {
- width: 100,
- height: 100
+ borderRadius: 5
+ marginTop: 12
+ height: 58
}
}
);
- return {markup: status.components.view({}, [text, image])};
+ return {markup: ['view', {},
+ text,
+ ['view', {},
+ image,
+ ['view', {style: {position: "absolute",
+ top: 0,
+ right: 0,
+ bottom: 0,
+ left: 0,
+ justifyContent: "center",
+ alignItems: "center"}},
+ ['view', {style: {borderColor: "#628fe3",
+ backgroundColor: "#FFFFFF",
+ borderWidth: 4,
+ borderRadius: 8,
+ height: 15,
+ width: 15}}]]]]};
},
shortPreview: function (params) {
return {
@@ -48,4 +95,4 @@ status.command({
)
};
}
-});
+});
\ No newline at end of file
diff --git a/bots/mailman/translations.js b/bots/mailman/translations.js
index 3ebb67c6f0..7d6af988c5 100644
--- a/bots/mailman/translations.js
+++ b/bots/mailman/translations.js
@@ -1,8 +1,9 @@
I18n.translations = {
en: {
location_title: 'Location',
+ location_suggestions_title: 'Send location',
location_description: 'Share your location',
- location_address: 'Address'
+ location_address: 'address'
},
ru: {
location_title: 'Местоположение',
diff --git a/ios/Mapbox.framework b/ios/Mapbox.framework
new file mode 120000
index 0000000000..a9b2ed5381
--- /dev/null
+++ b/ios/Mapbox.framework
@@ -0,0 +1 @@
+../node_modules/react-native-mapbox-gl/ios/Mapbox.framework
\ No newline at end of file
diff --git a/ios/StatusIm.xcodeproj/project.pbxproj b/ios/StatusIm.xcodeproj/project.pbxproj
index 330758aedf..425dd5d257 100644
--- a/ios/StatusIm.xcodeproj/project.pbxproj
+++ b/ios/StatusIm.xcodeproj/project.pbxproj
@@ -7,24 +7,24 @@
objects = {
/* Begin PBXBuildFile section */
- 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
- 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };
- 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; };
- 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; };
- 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };
+ 00C302E51ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302AC1ABCB8CE00DB3ED1 /* libRCTActionSheet.a */; };
+ 00C302E71ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302BA1ABCB90400DB3ED1 /* libRCTGeolocation.a */; };
+ 00C302E81ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302C01ABCB91800DB3ED1 /* libRCTImage.a */; };
+ 00C302E91ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302DC1ABCB9D200DB3ED1 /* libRCTNetwork.a */; };
+ 00C302EA1ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; };
00E356F31AD99517003FC87E /* StatusImTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* StatusImTests.m */; };
0F942CF509F74CCDB5CB35B0 /* MaterialIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 54E2B86FB12D4CC49DA05C69 /* MaterialIcons.ttf */; };
- 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; };
- 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; };
- 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; };
+ 133E29F31AD74F7200F7D852 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; };
+ 139105C61AF99C1200B5F7CC /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; };
+ 139FDEF61B0652A700C62182 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 139FDEF41B06529B00C62182 /* libRCTWebSocket.a */; };
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
- 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
+ 146834051AC3E58100842450 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; };
2028DFF91D4275B600227DCD /* SF-UI-Display-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2028DFF51D4275B600227DCD /* SF-UI-Display-Medium.otf */; };
2028DFFA1D4275B600227DCD /* SF-UI-Display-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2028DFF61D4275B600227DCD /* SF-UI-Display-Regular.otf */; };
2028DFFB1D4275B600227DCD /* SF-UI-Display-Semibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2028DFF71D4275B600227DCD /* SF-UI-Display-Semibold.otf */; };
2028DFFC1D4275B600227DCD /* SF-UI-Display-Thin.otf in Resources */ = {isa = PBXBuildFile; fileRef = 2028DFF81D4275B600227DCD /* SF-UI-Display-Thin.otf */; };
- 20AB9EC61D47CC0300E7FD9C /* libRCTStatus.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 201067C41D4789F700FA83B6 /* libRCTStatus.a */; };
+ 20AB9EC61D47CC0300E7FD9C /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 201067C41D4789F700FA83B6 /* libRCTStatus.a */; };
20B6B6841D92C42600CC5C6A /* RSKImageCropper.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20B6B6831D92C42600CC5C6A /* RSKImageCropper.framework */; };
20B6B6851D92C42600CC5C6A /* RSKImageCropper.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 20B6B6831D92C42600CC5C6A /* RSKImageCropper.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20B6B6871D92C42600CC5C6A /* QBImagePicker.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20B6B6861D92C42600CC5C6A /* QBImagePicker.framework */; };
@@ -41,24 +41,27 @@
74242ACAF37A48D0BFACDE82 /* Zocial.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 2756305FAFF144C4A6B0A039 /* Zocial.ttf */; };
81C6E6AE0AA739BE9D87C1D0 /* libPods-StatusImTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = FC1CBCFE6C906043D6CCEEE1 /* libPods-StatusImTests.a */; };
82E689BAF9FB43C8AC6FF1CA /* EvilIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = CEB0E2659D1A4F5FA842057A /* EvilIcons.ttf */; };
- 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
+ 832341BD1AAA6AB300B99B32 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
8E55E6877F950B81C8D711C5 /* libPods-StatusIm.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 101A4045637A2ADF57D28EF5 /* libPods-StatusIm.a */; };
9E0B01A11DDC5DA7002B0359 /* SF-UI-Text-Light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 9E0B01A01DDC5DA7002B0359 /* SF-UI-Text-Light.otf */; };
- 9E3AB6D01D87DB2B008846B4 /* libReact-Native-Webview-Bridge.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E3AB6C61D87DA2B008846B4 /* libReact-Native-Webview-Bridge.a */; };
- 9E7C64731E03FDDE004C7042 /* libRCTCamera.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 20B7D1151D3F74CD00B70F14 /* libRCTCamera.a */; };
- 9E7C64991E03FDE5004C7042 /* libRCTContacts.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 20B7D10A1D3F74CD00B70F14 /* libRCTContacts.a */; };
+ 9E3AB6D01D87DB2B008846B4 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E3AB6C61D87DA2B008846B4 /* libReact-Native-Webview-Bridge.a */; };
+ 9E7C64731E03FDDE004C7042 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 20B7D1151D3F74CD00B70F14 /* libRCTCamera.a */; };
+ 9E7C64991E03FDE5004C7042 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 20B7D10A1D3F74CD00B70F14 /* libRCTContacts.a */; };
9ED2F45E1D9D535A00B36508 /* SF-UI-Text-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 9ED2F45D1D9D52DD00B36508 /* SF-UI-Text-Regular.otf */; };
9ED2F45F1D9D535A00B36508 /* SF-UI-Text-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 9ED2F45C1D9D52C100B36508 /* SF-UI-Text-Medium.otf */; };
9ED2F4611D9D579900B36508 /* SF-UI-Text-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 9ED2F4601D9D577B00B36508 /* SF-UI-Text-Bold.otf */; };
- 9EE89E271E03FCB7007D3C25 /* libSplashScreen.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B24FC7F21DE718EF00D694FF /* libSplashScreen.a */; };
- 9EE89E2D1E03FD9F007D3C25 /* libimageCropPicker.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 20A5C9531D927137002C4965 /* libimageCropPicker.a */; };
+ 9EE470511ED0079E0048FD10 /* Mapbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EE470501ED0079E0048FD10 /* Mapbox.framework */; };
+ 9EE470521ED0079E0048FD10 /* Mapbox.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9EE470501ED0079E0048FD10 /* Mapbox.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
+ 9EE470541ED007E10048FD10 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 9EE4702F1ED0071A0048FD10 /* libRCTMapboxGL.a */; };
+ 9EE89E271E03FCB7007D3C25 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = B24FC7F21DE718EF00D694FF /* libSplashScreen.a */; };
+ 9EE89E2D1E03FD9F007D3C25 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = 20A5C9531D927137002C4965 /* libimageCropPicker.a */; };
A6AF670051B842249D520C7B /* Foundation.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 7ED174A34D7D42358313368B /* Foundation.ttf */; };
AE97D4B08C9F4821B8E9C50B /* Ionicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 359B076A658B4FBAB5128B03 /* Ionicons.ttf */; };
B23B48FF1E76917B006D4535 /* RobotoMono-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = B23B48FE1E76917B006D4535 /* RobotoMono-Medium.ttf */; };
B24FC7FD1DE7195700D694FF /* Social.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B24FC7FC1DE7195700D694FF /* Social.framework */; };
B24FC7FF1DE7195F00D694FF /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B24FC7FE1DE7195F00D694FF /* MessageUI.framework */; };
- B2A5F45C1DEC36BB00174F4D /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B2A5F4381DEC36B200174F4D /* libRCTAnimation.a */; };
- B2DEA0D01E49E33300FA28D6 /* libRCTHttpServer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B2DEA0B11E49E32000FA28D6 /* libRCTHttpServer.a */; };
+ B2A5F45C1DEC36BB00174F4D /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = B2A5F4381DEC36B200174F4D /* libRCTAnimation.a */; };
+ B2DEA0D01E49E33300FA28D6 /* ReferenceProxy in Frameworks */ = {isa = PBXBuildFile; fileRef = B2DEA0B11E49E32000FA28D6 /* libRCTHttpServer.a */; };
B2F2D1BC1D9D531B00B7B453 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B2F2D1BB1D9D531B00B7B453 /* Images.xcassets */; };
BA68A2377A20496EA737000D /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 4E586E1B0E544F64AA9F5BD1 /* libz.tbd */; };
C3EE9AEA6F77464588FBAA64 /* FontAwesome.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 7B5870D9ED504F32B6A09C35 /* FontAwesome.ttf */; };
@@ -309,6 +312,20 @@
remoteGlobalIDString = 0974579A1D2A440A000D9368;
remoteInfo = RCTWKWebView;
};
+ 9EE4702E1ED0071A0048FD10 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 9EE4701B1ED007190048FD10 /* RCTMapboxGL.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = C5DBB3401AF2EF2B00E611A9;
+ remoteInfo = RCTMapboxGL;
+ };
+ 9EE470301ED0071A0048FD10 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 9EE4701B1ED007190048FD10 /* RCTMapboxGL.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = C5DBB34B1AF2EF2B00E611A9;
+ remoteInfo = RCTMapboxGLTests;
+ };
B24FC7F11DE718EF00D694FF /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 3A7EB0491DD9CABC00A4FCC8 /* SplashScreen.xcodeproj */;
@@ -397,6 +414,7 @@
files = (
20B6B6851D92C42600CC5C6A /* RSKImageCropper.framework in Embed Frameworks */,
20B6B6881D92C42600CC5C6A /* QBImagePicker.framework in Embed Frameworks */,
+ 9EE470521ED0079E0048FD10 /* Mapbox.framework in Embed Frameworks */,
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
@@ -467,6 +485,8 @@
9ED2F45C1D9D52C100B36508 /* SF-UI-Text-Medium.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SF-UI-Text-Medium.otf"; sourceTree = ""; };
9ED2F45D1D9D52DD00B36508 /* SF-UI-Text-Regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SF-UI-Text-Regular.otf"; sourceTree = ""; };
9ED2F4601D9D577B00B36508 /* SF-UI-Text-Bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "SF-UI-Text-Bold.otf"; sourceTree = ""; };
+ 9EE4701B1ED007190048FD10 /* RCTMapboxGL.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTMapboxGL.xcodeproj; path = "../node_modules/react-native-mapbox-gl/ios/RCTMapboxGL.xcodeproj"; sourceTree = ""; };
+ 9EE470501ED0079E0048FD10 /* Mapbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = Mapbox.framework; sourceTree = ""; };
9F1854E6D9654226B1FC8308 /* RCTCamera.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = RCTCamera.xcodeproj; path = "../node_modules/react-native-camera/ios/RCTCamera.xcodeproj"; sourceTree = ""; };
ACA66A8F16CD2FE21F38738B /* Pods-StatusIm.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-StatusIm.debug.xcconfig"; path = "Pods/Target Support Files/Pods-StatusIm/Pods-StatusIm.debug.xcconfig"; sourceTree = ""; };
B23B48FE1E76917B006D4535 /* RobotoMono-Medium.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "RobotoMono-Medium.ttf"; sourceTree = ""; };
@@ -501,29 +521,29 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
- B2DEA0D01E49E33300FA28D6 /* libRCTHttpServer.a in Frameworks */,
- 9EE89E271E03FCB7007D3C25 /* libSplashScreen.a in Frameworks */,
- B2A5F45C1DEC36BB00174F4D /* libRCTAnimation.a in Frameworks */,
+ B2DEA0D01E49E33300FA28D6 /* ReferenceProxy in Frameworks */,
+ 9EE89E271E03FCB7007D3C25 /* ReferenceProxy in Frameworks */,
+ B2A5F45C1DEC36BB00174F4D /* ReferenceProxy in Frameworks */,
B24FC7FF1DE7195F00D694FF /* MessageUI.framework in Frameworks */,
B24FC7FD1DE7195700D694FF /* Social.framework in Frameworks */,
- 9EE89E2D1E03FD9F007D3C25 /* libimageCropPicker.a in Frameworks */,
- 9E3AB6D01D87DB2B008846B4 /* libReact-Native-Webview-Bridge.a in Frameworks */,
+ 9EE89E2D1E03FD9F007D3C25 /* ReferenceProxy in Frameworks */,
+ 9E3AB6D01D87DB2B008846B4 /* ReferenceProxy in Frameworks */,
20B6B6841D92C42600CC5C6A /* RSKImageCropper.framework in Frameworks */,
CE4E31B31D8695250033ED64 /* Statusgo.framework in Frameworks */,
- 20AB9EC61D47CC0300E7FD9C /* libRCTStatus.a in Frameworks */,
+ 20AB9EC61D47CC0300E7FD9C /* ReferenceProxy in Frameworks */,
20B6B6871D92C42600CC5C6A /* QBImagePicker.framework in Frameworks */,
- 146834051AC3E58100842450 /* libReact.a in Frameworks */,
- 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */,
- 00C302E71ABCBA2D00DB3ED1 /* libRCTGeolocation.a in Frameworks */,
- 00C302E81ABCBA2D00DB3ED1 /* libRCTImage.a in Frameworks */,
- 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */,
- 00C302E91ABCBA2D00DB3ED1 /* libRCTNetwork.a in Frameworks */,
- 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */,
- 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
- 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */,
- 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */,
- 9E7C64731E03FDDE004C7042 /* libRCTCamera.a in Frameworks */,
- 9E7C64991E03FDE5004C7042 /* libRCTContacts.a in Frameworks */,
+ 146834051AC3E58100842450 /* ReferenceProxy in Frameworks */,
+ 00C302E51ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */,
+ 00C302E71ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */,
+ 00C302E81ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */,
+ 133E29F31AD74F7200F7D852 /* ReferenceProxy in Frameworks */,
+ 00C302E91ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */,
+ 139105C61AF99C1200B5F7CC /* ReferenceProxy in Frameworks */,
+ 832341BD1AAA6AB300B99B32 /* ReferenceProxy in Frameworks */,
+ 00C302EA1ABCBA2D00DB3ED1 /* ReferenceProxy in Frameworks */,
+ 139FDEF61B0652A700C62182 /* ReferenceProxy in Frameworks */,
+ 9E7C64731E03FDDE004C7042 /* ReferenceProxy in Frameworks */,
+ 9E7C64991E03FDE5004C7042 /* ReferenceProxy in Frameworks */,
FD4F213C3873473CB703B1D2 /* libRNFS.a in Frameworks */,
213311F38CA74CE280FD09AD /* libRNI18n.a in Frameworks */,
4D3D740D5EFA4F8592B048D7 /* libBVLinearGradient.a in Frameworks */,
@@ -537,6 +557,9 @@
E0AD9E8F495A4907B65104BF /* libRCTImageResizer.a in Frameworks */,
5F8585D411844E5981B94F40 /* libRNInstabug.a in Frameworks */,
8E55E6877F950B81C8D711C5 /* libPods-StatusIm.a in Frameworks */,
+ EC8998BFE2C04023A860C065 /* libRNNetworkInfo.a in Frameworks */,
+ 9EE470511ED0079E0048FD10 /* Mapbox.framework in Frameworks */,
+ 9EE470541ED007E10048FD10 /* ReferenceProxy in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -846,6 +869,8 @@
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
+ 9EE470501ED0079E0048FD10 /* Mapbox.framework */,
+ 9EE4701B1ED007190048FD10 /* RCTMapboxGL.xcodeproj */,
20B6B6861D92C42600CC5C6A /* QBImagePicker.framework */,
20B6B6831D92C42600CC5C6A /* RSKImageCropper.framework */,
13B07FAE1A68108700A75B9A /* StatusIm */,
@@ -893,6 +918,15 @@
name = Products;
sourceTree = "";
};
+ 9EE4701C1ED007190048FD10 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 9EE4702F1ED0071A0048FD10 /* libRCTMapboxGL.a */,
+ 9EE470311ED0071A0048FD10 /* RCTMapboxGLTests.xctest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
A97BA941B2FB44B4B66EE6D3 /* Frameworks */ = {
isa = PBXGroup;
children = (
@@ -979,6 +1013,7 @@
9E71BA90038083A3D24E18E9 /* [CP] Embed Pods Frameworks */,
E883D1F9B22B8292CC879292 /* [CP] Copy Pods Resources */,
E3914A731DF919ED00EBB515 /* Run Script */,
+ 9EE470531ED007A80048FD10 /* ShellScript */,
);
buildRules = (
);
@@ -1065,6 +1100,10 @@
ProductGroup = 78C398B11ACF4ADC00677621 /* Products */;
ProjectRef = 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */;
},
+ {
+ ProductGroup = 9EE4701C1ED007190048FD10 /* Products */;
+ ProjectRef = 9EE4701B1ED007190048FD10 /* RCTMapboxGL.xcodeproj */;
+ },
{
ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */;
ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */;
@@ -1378,6 +1417,20 @@
remoteRef = 9EC013781E06FB1900155B5C /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
+ 9EE4702F1ED0071A0048FD10 /* libRCTMapboxGL.a */ = {
+ isa = PBXReferenceProxy;
+ fileType = archive.ar;
+ path = libRCTMapboxGL.a;
+ remoteRef = 9EE4702E1ED0071A0048FD10 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+ 9EE470311ED0071A0048FD10 /* RCTMapboxGLTests.xctest */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.cfbundle;
+ path = RCTMapboxGLTests.xctest;
+ remoteRef = 9EE470301ED0071A0048FD10 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
B24FC7F21DE718EF00D694FF /* libSplashScreen.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
@@ -1583,6 +1636,19 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-StatusIm/Pods-StatusIm-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
+ 9EE470531ED007A80048FD10 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/Mapbox.framework/strip-frameworks.sh\"";
+ };
E3914A731DF919ED00EBB515 /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -1736,6 +1802,7 @@
"$(PROJECT_DIR)/../modules/react-native-status/ios/RCTStatus",
"$(inherited)",
"$(PROJECT_DIR)/Pods/**",
+ "$(PROJECT_DIR)",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
@@ -1784,6 +1851,7 @@
"$(PROJECT_DIR)/../modules/react-native-status/ios/RCTStatus",
"$(inherited)",
"$(PROJECT_DIR)/Pods/**",
+ "$(PROJECT_DIR)",
);
HEADER_SEARCH_PATHS = (
"$(inherited)",
diff --git a/package.json b/package.json
index cdfe098dad..86f893d207 100644
--- a/package.json
+++ b/package.json
@@ -64,6 +64,7 @@
"react-native-invertible-scroll-view": "^1.0.0",
"react-native-level-fs": "^2.0.1",
"react-native-linear-gradient": "2.0.0",
+ "react-native-mapbox-gl": "github:mapbox/react-native-mapbox-gl#master",
"react-native-orientation": "github:youennPennarun/react-native-orientation",
"react-native-popup-menu": "^0.7.1",
"react-native-qrcode": "^0.2.2",
diff --git a/postinstall.sh b/postinstall.sh
index a933169e9e..767631bc02 100755
--- a/postinstall.sh
+++ b/postinstall.sh
@@ -5,10 +5,11 @@
./node_modules/.bin/rn-nodeify --install "assert,zlib,buffer,inherits,console,constants,crypto,dns,domain,events,http,https,os,path,process,punycode,querystring,fs,stream,string_decoder,timers,tty,url,util,net,vm" --hack;
npm install --save react@16.0.0-alpha.6;
npm install --save react-native-tcp@3.2.1;
+ln -s ../node_modules/react-native-mapbox-gl/ios/Mapbox.framework ios;
# symlink for re-natal
if ! [ -f re-natal ]; then
ln -s ./node_modules/re-natal/index.js re-natal;
else
echo "re-natal exists"
-fi
\ No newline at end of file
+fi
diff --git a/resources/status.js b/resources/status.js
index 4ccc139e45..a917113788 100644
--- a/resources/status.js
+++ b/resources/status.js
@@ -40,6 +40,7 @@ Command.prototype.create = function (com) {
this.request = com.request;
this["execute-immediately?"] = com.executeImmediately;
this["sequential-params"] = com.sequentialParams;
+ this["hide-send-button"] = com.hideSendButton;
this.addToCatalog();
return this;
@@ -186,6 +187,30 @@ function chooseContact(titleText, botDbKey, argumentIndex) {
}];
}
+function droppedPin() {
+ return ['dropped-pin'];
+}
+
+function placesSearch() {
+ return ['places-search'];
+}
+
+function currentLocationMap() {
+ return ['current-location-map'];
+}
+
+function currentLocation() {
+ return ['current-location'];
+}
+
+function placesNearby() {
+ return ['places-nearby'];
+}
+
+function separator() {
+ return ['separator'];
+}
+
var status = {
command: function (h) {
var command = new Command();
@@ -245,7 +270,13 @@ var status = {
bridgedWebView: bridgedWebView,
chooseContact: chooseContact,
subscribe: subscribe,
- dispatch: dispatch
+ dispatch: dispatch,
+ droppedPin: droppedPin,
+ placesSearch: placesSearch,
+ currentLocationMap: currentLocationMap,
+ currentLocation: currentLocation,
+ placesNearby: placesNearby,
+ separator: separator
},
showSuggestions: function (view) {
statusSignals.showSuggestions(JSON.stringify(view));
diff --git a/src/status_im/chat/handlers/input.cljs b/src/status_im/chat/handlers/input.cljs
index dc522c63bf..83f1287e9b 100644
--- a/src/status_im/chat/handlers/input.cljs
+++ b/src/status_im/chat/handlers/input.cljs
@@ -26,13 +26,13 @@
;; TODO(alwx): need to understand the need in this
#_(if-let [{command :command} (input-model/selected-chat-command db chat-id text)]
- (let [{old-args :args} (input-model/selected-chat-command db chat-id)
- text-splitted (input-model/split-command-args text)
- new-input-text (input-model/make-input-text text-splitted old-args)]
- (assoc-in db [:chats chat-id :input-text] new-input-text))
- (->> text
- (input-model/text->emoji)
- (assoc-in db [:chats chat-id :input-text]))))))
+ (let [{old-args :args} (input-model/selected-chat-command db chat-id)
+ text-splitted (input-model/split-command-args text)
+ new-input-text (input-model/make-input-text text-splitted old-args)]
+ (assoc-in db [:chats chat-id :input-text] new-input-text))
+ (->> text
+ (input-model/text->emoji)
+ (assoc-in db [:chats chat-id :input-text]))))))
(handlers/register-handler
:add-to-chat-input-text
@@ -108,6 +108,16 @@
(catch :default e
(log/debug "Cannot focus the reference"))))))
+(handlers/register-handler
+ :chat-input-blur
+ (handlers/side-effect!
+ (fn [{:keys [current-chat-id chat-ui-props] :as db} [_ ref]]
+ (try
+ (when-let [ref (get-in chat-ui-props [current-chat-id ref])]
+ (.blur ref))
+ (catch :default e
+ (log/debug "Cannot blur the reference"))))))
+
(handlers/register-handler
:update-suggestions
(fn [{:keys [current-chat-id] :as db} [_ chat-id text]]
@@ -146,9 +156,11 @@
args (-> (get-in db [:chats current-chat-id :input-text])
(input-model/split-command-args)
(rest))
+ seq-arg (get-in db [:chats current-chat-id :seq-argument-input-text])
to (get-in db [:contacts current-chat-id :address])
- params {:parameters {:args args
- :bot-db bot-db}
+ params {:parameters {:args args
+ :bot-db bot-db
+ :seq-arg seq-arg}
:context (merge {:data data
:from current-account-id
:to to}
@@ -382,16 +394,23 @@
:select-prev-argument
(handlers/side-effect!
(fn [{:keys [chat-ui-props current-chat-id] :as db} _]
- (let [arg-pos (input-model/argument-position db current-chat-id)]
- (when (pos? arg-pos)
- (let [input-text (get-in db [:chats current-chat-id :input-text])
- new-sel (->> (input-model/split-command-args input-text)
- (take (inc arg-pos))
- (input-model/join-command-args)
- (count))
- ref (get-in chat-ui-props [current-chat-id :input-ref])]
- (.setNativeProps ref (clj->js {:selection {:start new-sel :end new-sel}}))
- (dispatch [:update-text-selection new-sel])))))))
+ (let [input-text (get-in db [:chats current-chat-id :input-text])
+ command (input-model/selected-chat-command db current-chat-id input-text)]
+ (if (get-in command [:command :sequential-params])
+ (do
+ (dispatch [:set-command-argument [0 "" false]])
+ (dispatch [:set-chat-seq-arg-input-text ""])
+ (dispatch [:load-chat-parameter-box (:command command)]))
+ (let [arg-pos (input-model/argument-position db current-chat-id)]
+ (when (pos? arg-pos)
+ (let [input-text (get-in db [:chats current-chat-id :input-text])
+ new-sel (->> (input-model/split-command-args input-text)
+ (take (inc arg-pos))
+ (input-model/join-command-args)
+ (count))
+ ref (get-in chat-ui-props [current-chat-id :input-ref])]
+ (.setNativeProps ref (clj->js {:selection {:start new-sel :end new-sel}}))
+ (dispatch [:update-text-selection new-sel])))))))))
(handlers/register-handler
:select-next-argument
diff --git a/src/status_im/chat/views/geolocation/styles.cljs b/src/status_im/chat/views/geolocation/styles.cljs
new file mode 100644
index 0000000000..3d3d48d25d
--- /dev/null
+++ b/src/status_im/chat/views/geolocation/styles.cljs
@@ -0,0 +1,91 @@
+(ns status-im.chat.views.geolocation.styles
+ (:require [status-im.components.styles :as common]))
+
+(defn place-item-container [address]
+ {:height (if address 74 52)
+ :justify-content :center})
+
+(def place-item-title-container
+ {:flex-direction :row
+ :align-items :center})
+
+(defn place-item-circle-icon [pin-style]
+ (merge {:border-color common/color-light-blue
+ :border-width 3
+ :border-radius 7
+ :height 13
+ :width 13}
+ pin-style))
+
+(def black-pin
+ {:border-color common/color-black})
+
+(def place-item-title
+ {:font-size 15
+ :padding-left 9
+ :padding-right 16
+ :color common/color-black
+ :line-height 23})
+
+(def place-item-address
+ {:font-size 15
+ :padding-left 22
+ :padding-right 16
+ :color common/color-black
+ :line-height 23})
+
+(def map-activity-indicator-container
+ {:align-items :center
+ :justify-content :center
+ :height 100})
+
+(def map-view
+ {:height 100})
+
+(def location-container
+ {:margin-top 11
+ :margin-horizontal 16})
+
+(def location-container-title
+ {:font-size 14
+ :color common/color-gray4
+ :letter-spacing -0.2})
+
+(def location-container-title-count
+ (merge location-container-title
+ {:opacity 0.5}))
+
+(def separator
+ {:height 1
+ :opacity 0.5
+ :background-color "#c1c7cbb7"})
+
+(def item-separator
+ (merge separator
+ {:margin-left 22}))
+
+(def pin-container
+ {:position :absolute
+ :top 0
+ :right 0
+ :bottom 0
+ :left 0
+ :justify-content :center
+ :align-items :center
+ :pointer-events :none})
+
+(def pin-component
+ {:align-items :center})
+
+(def pin-circle
+ {:border-color common/color-black
+ :background-color common/color-white
+ :border-width 3
+ :border-radius 7
+ :height 13
+ :width 13})
+
+(def pin-leg
+ {:height 7
+ :width 2
+ :background-color common/color-black})
\ No newline at end of file
diff --git a/src/status_im/chat/views/geolocation/views.cljs b/src/status_im/chat/views/geolocation/views.cljs
new file mode 100644
index 0000000000..e025fec19e
--- /dev/null
+++ b/src/status_im/chat/views/geolocation/views.cljs
@@ -0,0 +1,173 @@
+(ns status-im.chat.views.geolocation.views
+ (:require-macros [status-im.utils.views :refer [defview letsubs]]
+ [reagent.ratom :refer [reaction]])
+ (:require [status-im.components.react :refer [view image text touchable-highlight]]
+ [reagent.core :as r]
+ [goog.string :as gstr]
+ [status-im.utils.utils :refer [http-get]]
+ [status-im.utils.types :refer [json->clj]]
+ [status-im.chat.views.geolocation.styles :as st]
+ [status-im.components.mapbox :refer [mapview]]
+ [re-frame.core :refer [dispatch subscribe]]
+ [status-im.i18n :refer [label]]
+ [status-im.components.react :as components]))
+
+(def mapbox-api "https://api.mapbox.com/geocoding/v5/mapbox.places/")
+(def access-token "pk.eyJ1Ijoic3RhdHVzaW0iLCJhIjoiY2oydmtnZjRrMDA3czMzcW9kemR4N2lxayJ9.Rz8L6xdHBjfO8cR3CDf3Cw")
+
+(defn get-places [coords cur-loc-geocoded & [poi?]]
+ (let [{:keys [latitude longitude]} coords]
+ (when (and latitude longitude)
+ (http-get (str mapbox-api longitude "," latitude
+ ".json?" (when poi? "types=poi&") "access_token=" access-token)
+ #(reset! cur-loc-geocoded (json->clj %))
+ #(reset! cur-loc-geocoded nil))
+ true)))
+
+(defn place-item [{:keys [title address pin-style] [latitude longitude] :center}]
+ [touchable-highlight {:on-press #(do
+ (dispatch [:set-command-argument [0
+ (str (or address title)
+ "&" latitude
+ "&" longitude)
+ false]])
+ (dispatch [:send-seq-argument]))}
+ [view (st/place-item-container address)
+ [view st/place-item-title-container
+ [view (st/place-item-circle-icon pin-style)]
+ [text {:style st/place-item-title
+ :number-of-lines 1
+ :font :medium}
+ title]]
+ (when address
+ [text {:style st/place-item-address
+ :number-of-lines 1}
+ address])]])
+
+(defview current-location-map-view []
+ (letsubs [geolocation [:get :geolocation]
+ command [:selected-chat-command]]
+ {:component-will-mount #(dispatch [:request-geolocation-update])
+ :component-did-mount (fn [_] (js/setTimeout #(dispatch [:chat-input-focus :seq-input-ref]) 400))}
+ (let [coord (select-keys (:coords geolocation) [:latitude :longitude])]
+ [view
+ (if (not (empty? coord))
+ [view
+ [mapview {:onTap #(do
+ (dispatch [:set-command-argument [0 "Dropped pin" false]])
+ (dispatch [:set-chat-seq-arg-input-text "Dropped pin"])
+ (dispatch [:chat-input-blur :seq-input-ref])
+ (dispatch [:load-chat-parameter-box (:command command)]))
+ :initialCenterCoordinate coord
+ :showsUserLocation true
+ :initialZoomLevel 10
+ :logoIsHidden true
+ :rotateEnabled false
+ :scrollEnabled false
+ :zoomEnabled false
+ :pitchEnabled false
+ :style st/map-view}]]
+ [view st/map-activity-indicator-container
+ [components/activity-indicator {:animating true}]])])))
+
+(defn current-location-view []
+ (let [geolocation (subscribe [:get :geolocation])
+ cur-loc-geocoded (r/atom nil)
+ result (reaction (when @geolocation (get-places (:coords @geolocation) cur-loc-geocoded)))]
+ (r/create-class
+ {:component-will-mount #(dispatch [:request-geolocation-update])
+ :render
+ (fn []
+ (let [_ @result]
+ (when (and @cur-loc-geocoded (> (count (:features @cur-loc-geocoded)) 0))
+ [view st/location-container
+ [text {:style st/location-container-title}
+ (label :t/your-current-location)]
+ (let [{:keys [place_name center] :as feature} (get-in @cur-loc-geocoded [:features 0])]
+ [place-item {:title (:text feature) :address place_name :center center}])])))})))
+
+(defn places-nearby-view []
+ (let [geolocation (subscribe [:get :geolocation])
+ cur-loc-geocoded (r/atom nil)
+ result (reaction (when @geolocation (get-places (:coords @geolocation) cur-loc-geocoded true)))]
+ (r/create-class
+ {:component-will-mount #(dispatch [:request-geolocation-update])
+ :render
+ (fn []
+ (let [_ @result]
+ (when (and @cur-loc-geocoded (> (count (:features @cur-loc-geocoded)) 0))
+ [view st/location-container
+ [text {:style st/location-container-title}
+ (label :t/places-nearby)]
+ (doall
+ (map (fn [{:keys [text place_name center] :as feature}]
+ ^{:key feature}
+ [view
+ [place-item {:title text :address place_name :center center}]
+ (when (not= feature (last (:features @cur-loc-geocoded)))
+ [view st/item-separator])])
+ (:features @cur-loc-geocoded)))])))})))
+
+(defn places-search []
+ (let [seq-arg-input-text (subscribe [:chat :seq-argument-input-text])
+ places (r/atom nil)
+ result (reaction (http-get (str mapbox-api @seq-arg-input-text
+ ".json?access_token=" access-token)
+ #(reset! places (json->clj %))
+ #(reset! places nil)))]
+ (fn []
+ (let [_ @result]
+ (when @places
+ (let [features-count (count (:features @places))]
+ [view st/location-container
+ [text {:style st/location-container-title}
+ (label :t/search-results) " " [text {:style st/location-container-title-count} features-count]]
+ (doall
+ (map (fn [{:keys [place_name center] :as feature}]
+ ^{:key feature}
+ [view
+ [place-item {:title place_name :center center}]
+ (when (not= feature (last (:features @places)))
+ [view st/item-separator])])
+ (:features @places)))]))))))
+
+(defn dropped-pin []
+ (let [geolocation @(subscribe [:get :geolocation])
+ pin-location (r/atom nil)
+ pin-geolocation (r/atom nil)
+ pin-nearby (r/atom nil)
+ result (reaction (when @pin-location (get-places @pin-location pin-geolocation)))
+ result2 (reaction (when @pin-location (get-places @pin-location pin-nearby true)))]
+ (fn []
+ (let [_ @result _ @result2]
+ [view
+ [view
+ [mapview {:initial-center-coordinate (select-keys (:coords geolocation) [:latitude :longitude])
+ :initialZoomLevel 10
+ :onRegionDidChange #(reset! pin-location (js->clj % :keywordize-keys true))
+ :logoIsHidden true
+ :style {:height 265}}]
+ [view st/pin-container
+ [view st/pin-component
+ [view st/pin-circle]
+ [view st/pin-leg]]]]
+ (when (and @pin-geolocation (> (count (:features @pin-geolocation)) 0))
+ [view
+ [view st/location-container
+ [text {:style st/location-container-title}
+ (label :t/dropped-pin)]
+ (let [{:keys [place_name center] :as feature} (get-in @pin-geolocation [:features 0])]
+ [place-item {:title place_name :pin-style st/black-pin :center center}])]
+ [view st/separator]])
+ (when (and @pin-nearby (> (count (:features @pin-nearby)) 0))
+ [view st/location-container
+ [text {:style st/location-container-title}
+ (label :t/places-nearby)]
+ (doall
+ (map (fn [{:keys [text place_name center] :as feature}]
+ ^{:key feature}
+ [view
+ [place-item {:title text :address place_name :center center}]
+ (when (not= feature (last (:features @pin-nearby)))
+ [view st/item-separator])])
+ (:features @pin-nearby)))])]))))
\ No newline at end of file
diff --git a/src/status_im/chat/views/input/input.cljs b/src/status_im/chat/views/input/input.cljs
index 086437f432..ba1a6bcbb1 100644
--- a/src/status_im/chat/views/input/input.cljs
+++ b/src/status_im/chat/views/input/input.cljs
@@ -167,13 +167,15 @@
:style (style/seq-input-text command-width)
:default-value (or @seq-arg-input-text "")
:on-change-text #(do (dispatch [:set-chat-seq-arg-input-text %])
+ (dispatch [:load-chat-parameter-box (:command @command)])
(dispatch [:set-chat-ui-props {:validation-messages nil}]))
:placeholder placeholder
:blur-on-submit false
:editable (not @sending-in-progress?)
:on-focus #(dispatch [:set-chat-ui-props {:show-emoji? false}])
:on-submit-editing (fn []
- (when-not (str/blank? @seq-arg-input-text)
+ (when-not (or (str/blank? @seq-arg-input-text)
+ (get-in @command [:command :hide-send-button]))
(dispatch [:send-seq-argument]))
(js/setTimeout
#(dispatch [:chat-input-focus :seq-input-ref])
@@ -222,7 +224,8 @@
input-text [:chat :input-text]
seq-arg-input-text [:chat :seq-argument-input-text]
result-box [:chat-ui-props :result-box]]
- (let [single-line-input? (:singleLineInput result-box)]
+ (let [single-line-input? (:singleLineInput result-box)
+ {:keys [hide-send-button sequential-params]} (:command selected-command)]
[view style/input-container
[input-view {:anim-margin anim-margin
:single-line-input? single-line-input?}]
@@ -230,8 +233,9 @@
[input-actions/input-actions-view]
(when (and (not (str/blank? input-text))
(or (not selected-command)
- (some #{:complete :less-than-needed} [command-completion])))
- [touchable-highlight {:on-press #(if (get-in selected-command [:command :sequential-params])
+ (some #{:complete :less-than-needed} [command-completion]))
+ (not hide-send-button))
+ [touchable-highlight {:on-press #(if sequential-params
(do
(when-not (str/blank? seq-arg-input-text)
(dispatch [:send-seq-argument]))
diff --git a/src/status_im/chat/views/message/message.cljs b/src/status_im/chat/views/message/message.cljs
index 09a2f9f635..9db8b5cdeb 100644
--- a/src/status_im/chat/views/message/message.cljs
+++ b/src/status_im/chat/views/message/message.cljs
@@ -16,7 +16,7 @@
dismiss-keyboard!]]
[status-im.components.animation :as anim]
[status-im.chat.constants :as chat-consts]
- [status-im.components.list-selection :refer [share browse]]
+ [status-im.components.list-selection :refer [share browse share-or-open-map]]
[status-im.chat.views.message.request-message :refer [message-content-command-request]]
[status-im.chat.styles.message.message :as st]
[status-im.chat.styles.message.command-pill :as pill-st]
@@ -139,11 +139,12 @@
{:keys [name type]
icon-path :icon} command]
[view st/content-command-view
- [view st/command-container
- [view (pill-st/pill command)
- [text {:style pill-st/pill-text
- :font :default}
- (str (if (= :command type) chat-consts/command-char "?") name)]]]
+ (when (:color command)
+ [view st/command-container
+ [view (pill-st/pill command)
+ [text {:style pill-st/pill-text
+ :font :default}
+ (str (if (= :command type) chat-consts/command-char "?") name)]]])
(when icon-path
[view st/command-image-view
[icon icon-path st/command-image]])
@@ -402,8 +403,12 @@
(fn [{:keys [outgoing group-chat content-type content] :as message}]
[message-container message
[touchable-highlight {:on-press #(when platform/ios? (dismiss-keyboard!))
- :on-long-press (when (= content-type text-content-type)
- #(share content (label :t/message)))}
+ :on-long-press #(cond (= content-type text-content-type)
+ (share content (label :t/message))
+ (and (= content-type content-type-command) (= "location" (:content-command content)))
+ (let [params (str/split (get-in content [:params "address"]) #"&")
+ latlong (rest params)]
+ (share-or-open-map (first params) (first latlong) (second latlong))))}
[view
(let [incoming-group (and group-chat (not outgoing))]
[message-content message-body (merge message
diff --git a/src/status_im/commands/handlers/jail.cljs b/src/status_im/commands/handlers/jail.cljs
index 1e8cacd3ab..ea4c9c78ec 100644
--- a/src/status_im/commands/handlers/jail.cljs
+++ b/src/status_im/commands/handlers/jail.cljs
@@ -38,12 +38,12 @@
(defn suggestions-handler!
[{:keys [contacts chats] :as db} [{:keys [chat-id default-db command parameter-index result]}]]
- (let [{:keys [markup] :as returned} (get-in result [:result :returned])
+ (let [{:keys [markup height] :as returned} (get-in result [:result :returned])
contains-markup? (contains? returned :markup)
path (if command
[:chats chat-id :parameter-boxes (:name command) parameter-index]
[:chats chat-id :parameter-boxes :message])]
- (dispatch [:choose-predefined-expandable-height :parameter-box :default])
+ (dispatch [:choose-predefined-expandable-height :parameter-box (or (keyword height) :default)])
(when (and contains-markup? (not= (get-in db path) markup))
(dispatch [:set-in path returned])
(when default-db
diff --git a/src/status_im/commands/handlers/loading.cljs b/src/status_im/commands/handlers/loading.cljs
index 4d2f3f3c10..7f23ee370b 100644
--- a/src/status_im/commands/handlers/loading.cljs
+++ b/src/status_im/commands/handlers/loading.cljs
@@ -140,16 +140,16 @@
commands' (filter-commands account chat commands)
responses' (filter-commands account chat responses)
global-command (:global commands')
- commands'' (apply dissoc commands' [:init :global])
+ commands'' (each-merge (apply dissoc commands' [:init :global])
+ {:type :command
+ :owner-id id})
mailman-commands (get-mailmans-commands db)]
(cond-> db
true
(update-in [:contacts id] assoc
:commands-loaded? true
- :commands (-> (merge mailman-commands commands'')
- (each-merge {:type :command
- :owner-id id}))
+ :commands (merge mailman-commands commands'')
:responses (each-merge responses' {:type :response
:owner-id id})
:subscriptions subscriptions)
diff --git a/src/status_im/commands/utils.cljs b/src/status_im/commands/utils.cljs
index 25df4c3c82..4cfa1a38ed 100644
--- a/src/status_im/commands/utils.cljs
+++ b/src/status_im/commands/utils.cljs
@@ -1,12 +1,13 @@
(ns status-im.commands.utils
(:require [clojure.set :as set]
[clojure.walk :as w]
- [re-frame.core :refer [dispatch trim-v debug]]
+ [re-frame.core :refer [dispatch trim-v]]
[status-im.components.react :as components]
[status-im.chat.views.input.web-view :as chat-web-view]
[status-im.chat.views.input.validation-messages :as chat-validation-messages]
[status-im.chat.views.choosers.choose-contact :as choose-contact]
[status-im.components.qr-code :as qr]
+ [status-im.chat.views.geolocation.views :as geolocation]
[status-im.utils.handlers :refer [register-handler]]
[taoensso.timbre :as log]))
@@ -14,21 +15,30 @@
(when-not (= json "undefined")
(js->clj (.parse js/JSON json) :keywordize-keys true)))
+(defn parameter-box-separator []
+ [components/view {:height 1 :background-color "#c1c7cbb7" :opacity 0.5}])
+
(def elements
- {:view components/view
- :text components/text
- :text-input components/text-input
- :image components/image
- :qr-code qr/qr-code
- :linking components/linking
- :slider components/slider
- :scroll-view components/scroll-view
- :web-view components/web-view
- :touchable components/touchable-highlight
- :activity-indicator components/activity-indicator
- :bridged-web-view chat-web-view/bridged-web-view
- :validation-message chat-validation-messages/validation-message
- :choose-contact choose-contact/choose-contact-view})
+ {:view components/view
+ :text components/text
+ :text-input components/text-input
+ :image components/image
+ :qr-code qr/qr-code
+ :linking components/linking
+ :slider components/slider
+ :scroll-view components/scroll-view
+ :web-view components/web-view
+ :touchable components/touchable-highlight
+ :activity-indicator components/activity-indicator
+ :bridged-web-view chat-web-view/bridged-web-view
+ :validation-message chat-validation-messages/validation-message
+ :choose-contact choose-contact/choose-contact-view
+ :separator parameter-box-separator
+ :current-location-map geolocation/current-location-map-view
+ :current-location geolocation/current-location-view
+ :places-nearby geolocation/places-nearby-view
+ :places-search geolocation/places-search
+ :dropped-pin geolocation/dropped-pin})
(defn get-element [n]
(elements (keyword (.toLowerCase n))))
@@ -40,7 +50,7 @@
#(dispatch [:suggestions-event! (update event 0 keyword) %])))
(defn check-events [m]
- (let [ks (set (keys m))
+ (let [ks (set (keys m))
evs (set/intersection ks events)]
(reduce #(update %1 %2 wrap-event) m evs)))
diff --git a/src/status_im/components/list_selection.cljs b/src/status_im/components/list_selection.cljs
index cf9b9d4caf..a4d4ae69a6 100644
--- a/src/status_im/components/list_selection.cljs
+++ b/src/status_im/components/list_selection.cljs
@@ -3,7 +3,7 @@
[status-im.components.react :refer [copy-to-clipboard
sharing
linking]]
- [status-im.utils.platform :refer [platform-specific]]
+ [status-im.utils.platform :refer [platform-specific ios?]]
[status-im.i18n :refer [label]]))
(defn open-share [content]
@@ -44,3 +44,18 @@
:default))
:cancel-text (label :t/browsing-cancel)})))
+(defn share-or-open-map [address lat lng]
+ (let [list-selection-fn (:list-selection-fn platform-specific)]
+ (list-selection-fn {:title (label :t/location)
+ :options [{:text (label :t/sharing-copy-to-clipboard-address)}
+ {:text (label :t/sharing-copy-to-clipboard-coordinates)}
+ {:text (label :t/open-map)}]
+ :callback (fn [index]
+ (case index
+ 0 (copy-to-clipboard address)
+ 1 (copy-to-clipboard (str lng "," lat))
+ 2 (.openURL linking (if ios?
+ (str "http://maps.apple.com/?ll=" lng "," lat)
+ (str "geo:" lng "," lat)))
+ :default))
+ :cancel-text (label :t/cancel)})))
diff --git a/src/status_im/components/mapbox.cljs b/src/status_im/components/mapbox.cljs
new file mode 100644
index 0000000000..0b021ff556
--- /dev/null
+++ b/src/status_im/components/mapbox.cljs
@@ -0,0 +1,23 @@
+(ns status-im.components.mapbox
+ (:require [reagent.core :as r]
+ [status-im.components.styles :as common]
+ [status-im.i18n :refer [label]]
+ [status-im.utils.platform :refer [platform-specific ios?]]
+ [re-frame.core :refer [dispatch]]
+ [status-im.components.react :refer [view touchable-highlight text]]))
+
+(def react-native-mapbox-gl (js/require "react-native-mapbox-gl"))
+
+(defn get-property [name]
+ (aget react-native-mapbox-gl name))
+
+(defn adapt-class [class]
+ (when class
+ (r/adapt-react-class class)))
+
+(defn get-class [name]
+ (adapt-class (get-property name)))
+
+(.setAccessToken react-native-mapbox-gl "pk.eyJ1Ijoic3RhdHVzaW0iLCJhIjoiY2oydmtnZjRrMDA3czMzcW9kemR4N2lxayJ9.Rz8L6xdHBjfO8cR3CDf3Cw")
+
+(def mapview (get-class "MapView"))
diff --git a/src/status_im/contacts/handlers.cljs b/src/status_im/contacts/handlers.cljs
index 3a54d7bda3..c2c83db60a 100644
--- a/src/status_im/contacts/handlers.cljs
+++ b/src/status_im/contacts/handlers.cljs
@@ -260,9 +260,9 @@
:bot-url bot-url
:global-command global-command
:dapp-hash dapp-hash}]
- (dispatch [:add-contacts [contact]])
- (when bot-url
- (dispatch [:load-commands! id']))))))))))
+ (dispatch [:add-contacts [contact]])))
+ (when bot-url
+ (dispatch [:load-commands! id']))))))))
(register-handler :add-contacts
diff --git a/src/status_im/handlers.cljs b/src/status_im/handlers.cljs
index 222c83d51c..49b321a975 100644
--- a/src/status_im/handlers.cljs
+++ b/src/status_im/handlers.cljs
@@ -199,6 +199,32 @@
then
else))))
+(register-handler :request-geolocation-update
+ (u/side-effect!
+ (fn [_ _]
+ (dispatch [:request-permissions [:geolocation]
+ (fn []
+ (let [watch-id (atom nil)]
+ (.getCurrentPosition
+ navigator.geolocation
+ #(dispatch [:update-geolocation (js->clj % :keywordize-keys true)])
+ #(dispatch [:update-geolocation (js->clj % :keywordize-keys true)])
+ (clj->js {:enableHighAccuracy true :timeout 20000 :maximumAge 1000}))
+ (when p/android?
+ (reset! watch-id
+ (.watchPosition
+ navigator.geolocation
+ #(do
+ (.clearWatch
+ navigator.geolocation
+ @watch-id)
+ (dispatch [:update-geolocation (js->clj % :keywordize-keys true)]))))
+ (dispatch [:set-in [:debug :watch-id] @watch-id]))))]))))
+
+(register-handler :update-geolocation
+ (fn [db [_ geolocation]]
+ (assoc db :geolocation geolocation)))
+
;; -- User data --------------------------------------------------------------
(register-handler :load-user-phone-number
(fn [db [_]]
diff --git a/src/status_im/translations/en.cljs b/src/status_im/translations/en.cljs
index 17999ee94d..943e35dd59 100644
--- a/src/status_im/translations/en.cljs
+++ b/src/status_im/translations/en.cljs
@@ -211,6 +211,16 @@
:chat-send-eth-to "{{amount}} ETH to {{chat-name}}"
:chat-send-eth-from "{{amount}} ETH from {{chat-name}}"
+ ;location command
+ :your-current-location "Your current location"
+ :places-nearby "Places nearby"
+ :search-results "Search results"
+ :dropped-pin "Dropped pin"
+ :location "Location"
+ :open-map "Open Map"
+ :sharing-copy-to-clipboard-address "Copy the Address"
+ :sharing-copy-to-clipboard-coordinates "Copy coordinates"
+
;new-group
:group-chat-name "Chat name"
:empty-group-chat-name "Please enter a name"
diff --git a/src/status_im/utils/views.clj b/src/status_im/utils/views.clj
index 28527a512a..92b7120e33 100644
--- a/src/status_im/utils/views.clj
+++ b/src/status_im/utils/views.clj
@@ -34,7 +34,7 @@
[form `(deref ~sym)]))
pairs))]))
-(defmacro letsubs [args body])
+(defmacro letsubs [args & body])
(defmacro defview
[n params & rest-body]