Add a map for virtual beacons#340
Conversation
de41e5d to
af888a9
Compare
| dependencies { | ||
| compile project(':react-native-linear-gradient') | ||
| compile project(':magnet-scanner-android') | ||
| compile project(':reactnativemapboxgl') |
There was a problem hiding this comment.
Any reason why we don't use default react-native MapView?
There was a problem hiding this comment.
The default map component is iOS only.
There was a problem hiding this comment.
Also I tried the react-native-maps by Airbnb that the React Native team recommends, but it ended up being a massive mess to set up and configure and it isn't even compatible with our Google Play Service version. So falling back to mapbox was the best solution.
There was a problem hiding this comment.
Interesting, do you have any more info on the google-play-services issue?
| android:name=".notifications.NotificationService" | ||
| android:enabled="true" | ||
| android:exported="false"/> | ||
| <service android:name="com.mapbox.mapboxsdk.telemetry.TelemetryService" /> |
There was a problem hiding this comment.
That's for mapbox telemetry. This is part of the settings process. I'm not sure if deactivating it can have side effects.
From a purely user standpoint the telemetry can be deactivated through the map interface.
Do you want me to enquire it?
There was a problem hiding this comment.
Please do, I'm afraid of what legal reasons we will need to add in our side in order to use this.
lib/store/actions.js
Outdated
| return { | ||
| type: 'LOCATION_CHANGED', | ||
| pos, | ||
| }; |
There was a problem hiding this comment.
Changes look spot on, nice one!
|
|
||
| module.exports = (state, action) => { | ||
| if (!state) return initialState; | ||
| module.exports = (state = initialState, action) => { |
lib/store/reducer.js
Outdated
| case 'UNSUBSCRIBED': return unsubscribed(state, action); | ||
| case 'SUBSCRIPTION_UPDATED': return subscriptionUpdated(state, action); | ||
| case 'LOCATION_UPDATE_STARTED': return startLocationUpdates(state); | ||
| case 'LOCATION_UPDATE_STOPPED': return stopLocationUpdates(state); |
lib/views/item-scene.js
Outdated
| } = ReactNative; | ||
|
|
||
| const accessToken = 'pk.eyJ1IjoiZ21hcnR5IiwiYSI6ImNpdm1lanB1azAwNm8yb3A0OXZ6bmUxM2oifQ.i2HycDMBdPoatAB-ONR6FQ'; | ||
| Mapbox.setAccessToken(accessToken); |
There was a problem hiding this comment.
What are the rate limits for mapbox? We may need to flip to google-maps if we start entering paid usage tiers.
lib/views/item-scene.js
Outdated
|
|
||
| // Distance in km | ||
| return R * c; | ||
| } |
There was a problem hiding this comment.
Can you shove this in utils/compute-distance.js?
lib/views/item-scene.js
Outdated
| }, | ||
|
|
||
| distanceLabel: { | ||
| fontFamily: 'FiraSans-Book', |
There was a problem hiding this comment.
Use config.theme constants.
|
Looks good @gmarty! I haven't been able to test on device yet. Just some questions about the choice of map vendor and some code nits. |
|
Why is this close? Fat fingers? ;) |
|
Shit I always hit the wrong button! |
lib/views/item-scene.js
Outdated
| Linking, | ||
| } = ReactNative; | ||
|
|
||
| const accessToken = 'pk.eyJ1IjoiZ21hcnR5IiwiYSI6ImNpdm1lanB1azAwNm8yb3A0OXZ6bmUxM2oifQ.i2HycDMBdPoatAB-ONR6FQ'; |
There was a problem hiding this comment.
Yeh, this key is fine - it wouldn't be so much if we paid for it - but still not the end of the world. Because we ship this key to the client, we can never really secure it, it's just not best practice to keep keys in the tree.
Will need to think about this, maybe we can use ci.tengam.org to store secrets required during builds, or use Travis's secrets mechanism.
Not sure what the best thing would be, let's figure that out at a later date.
lib/views/item-scene.js
Outdated
|
|
||
| renderDistance(distance = 0) { | ||
| renderDistance() { | ||
| let distance = this.state.distance; |
There was a problem hiding this comment.
Why are we touching this.state? Is it meant to mean this.props?
There was a problem hiding this comment.
Yes, it's a mistake.
| distance = this.computeDistance(this.props.location.pos.coords); | ||
| } | ||
|
|
||
| distance = Math.round(distance); |
There was a problem hiding this comment.
I think all this distance logic should be packaged up into a dedicated .getDistance() (pure) function. Takes required inputs and spits out a distance result.
lib/store/actions.js
Outdated
| return (dispatch) => { | ||
| dispatch(locationUpdateStarted()); | ||
| watchID = navigator.geolocation.watchPosition((pos) => { | ||
| dispatch(locationChanged(pos)); |
There was a problem hiding this comment.
Can we be explicit and only pass lat/lon as that's all we're using right now. If we need other properties at a later date, we can expose them.
lib/views/item-scene.js
Outdated
| if (typeof distance !== 'number' && | ||
| typeof this.props.item.latitude === 'number' && | ||
| typeof this.props.item.longitude === 'number') { | ||
| distance = this.computeDistance(this.props.location.pos.coords); |
| location: { | ||
| pos: null, | ||
| isWatching: false, | ||
| }, |
There was a problem hiding this comment.
A pattern I'm introducing with my pending redux patch is async values having status and value properties. The value property varies depending on the status.
{
location: {
status: 'STARTED' | 'STOPPED' | 'ERROR'?
value: null | { latitude: ..., longitude: ... }
}
}Although I guess this is slightly different as the status doesn't directly map to a corresponding value. For example 'STARTED' doesn't mean that we have a value yet.
|
@gmarty I'm having some difficulty running this patch, not sure what the differences are in our envs, but I'm not able to render the item-scene. I think in some cases we need to protect against the device not having a |
config.js
Outdated
| 'privacy': 'https://trymagnet.org/privacy/', | ||
| 'feedback': 'https://trymagnet.org/#contact', | ||
| }, | ||
| mapboxAccessToken: 'pk.eyJ1IjoiZ21hcnR5IiwiYSI6ImNpdm1lanB1azAwNm8yb3A0OXZ6bmUxM2oifQ.i2HycDMBdPoatAB-ONR6FQ', |
There was a problem hiding this comment.
We will need to remove this key and add it during build time.
There was a problem hiding this comment.
@gmarty sorry this isn't clear: settings is a namespace reserved for the SettingsScene. Please move your key up to the next parent.
lib/views/item/item-detail.js
Outdated
| style={styles.distanceImage} | ||
| source={require('../../images/item-scene-room.png')}/> | ||
| source={{ | ||
| uri: 'ic_place_black_24dp', |
There was a problem hiding this comment.
do we need to indicate the dp?
Or can we just use 'ic_place_black' for devices with different dp, also does this work in ios?
|
Looking gorgeous in ios, but unfortunately we still need to cover in this PR the ios integration. |
7c80bd8 to
80358ce
Compare
@arcturus do you mean android? |
Right :) |
b35cccc to
99f7c41
Compare
| style={styles.distanceImage} | ||
| source={require('../../images/item-scene-room.png')}/> | ||
| source={{ | ||
| uri: 'ic_place', |
There was a problem hiding this comment.
Is there a reason why this image is not loaded using the regular require() mechanism?
There was a problem hiding this comment.
It's not implemented in Mapbox yet. Plus I found working with image assets is really smooth both on iOS and Android. Using Material Design icons, I just had to slide the folders in relevant places.
And of course this support multi screen densities which is good.
| id: 'marker1', | ||
| annotationImage: { | ||
| source: { | ||
| uri: 'ic_place', |
There was a problem hiding this comment.
Again can we use require() to keep all our front-end image assets in one place?
lib/views/item-scene.js
Outdated
| @@ -1,342 +0,0 @@ | |||
| /** | |||
There was a problem hiding this comment.
Where is this file, does this PR need a rebase?
|
@gmarty I really don't want to put the emulator out of action on Android. This is because the emulator makes it possible to test the app across several android versions and mock locations when devs (me) aren't in London. If the problem is related to the mapbox-native-gl version being out of date we have two options:
|
| protected List<ReactPackage> getPackages() { | ||
| return Arrays.<ReactPackage>asList( | ||
| new MainReactPackage(), | ||
| new GoogleAnalyticsBridgePackage(), |
| "feedback": "https://trymagnet.org/#contact" | ||
| } | ||
| }, | ||
| "mapboxAccessToken": "pk.eyJ1IjoiZ21hcnR5IiwiYSI6ImNpdm1lanB1azAwNm8yb3A0OXZ6bmUxM2oifQ.i2HycDMBdPoatAB-ONR6FQ" |
There was a problem hiding this comment.
Move this out of settings.
| }, | ||
| { | ||
| "idiom" : "universal", | ||
| "filename" : "ic_place_2x.png", |
There was a problem hiding this comment.
Isn't the convention ...@2x.png?
|
I don't really like how our front-end image assets are now spread across three directories instead of one. I understand this is a limitation of mapbox API if you want to have custom marker images. |
|
Regarding android image assets: All our android image assets currently have 12 different resolutions automatically generated by Android Studio. Your latest icon only has three different variations. For consistency I think all our icons should be available in the same variations. |
|
Happy for this to land once all comments addressed, most importantly the Android emulator issue. Nice work on this, it looks mega good! |
|
Closing this to continue work at #385 |


No description provided.