-
-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/add contributions to map #742
Changes from 11 commits
63d1b23
b12c8a1
af4fc35
b7765fd
e4f0c6c
263874b
e406b3e
a325c53
a906762
96008f9
3efb600
52424e9
355b694
531fd80
c507216
70662d8
376b8e3
f124060
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#map { | ||
width: 100%; | ||
height: 500px; | ||
} | ||
|
||
.marker { | ||
background-size: cover; | ||
width: 50px; | ||
height: 50px; | ||
border-radius: 50%; | ||
cursor: pointer; | ||
} | ||
|
||
.ask-marker { | ||
background-image: url('~./../images/ask.png'); | ||
} | ||
|
||
.offer-marker { | ||
background-image: url('~./../images/offer.png'); | ||
} | ||
|
||
.mapboxgl-popup { | ||
max-width: 200px; | ||
} | ||
|
||
.mapboxgl-popup-content { | ||
text-align: center; | ||
font-family: 'Open Sans', sans-serif; | ||
h3 { font-weight: bold; } | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
class ServiceAreaBlueprint < Blueprinter::Base | ||
identifier :id | ||
|
||
fields :name, :description | ||
fields :name, :description, :location | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We probably don't want There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, that was a minor oversight by us while we were learning our way around Blueprint |
||
|
||
view :with_location do | ||
association :location, blueprint: LocationBlueprint | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,7 +18,7 @@ | |
<section> | ||
<BrowserSelector :browser="browser" @clicked="browser = $event" /> | ||
</section> | ||
<component :is="browser" :contributions="activeContributions" class="row" /> | ||
<component :is="browser" :contributions="activeContributions" class="row" accessToken="pk.eyJ1IjoibXV0dWFsLWFpZC1hcHAiLCJhIjoiY2tmZTBvd3UwMDBhbTJ4cDlic2JmMWZoaiJ9.rWscBjdl1SMT5N0yekIJYg"/> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A series of questions:
EDIT: Next time, I shall read the full PR description first...
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This also seems to be copy-pasta'd in Had you considered the case where we need to change the Map API credential? It seems likely that we might miss one or more instances with the current design. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @indiebrain yup, i believe we agreed to go with this path for this week, but that there's a ticket to move this out asap There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @indiebrain I agree that this should be DRYed up a bit. Given the time we've spent thus far and familiarity with given clientside tech, I think everyone did a fantastic job!
|
||
</section> | ||
</div> | ||
</template> | ||
|
@@ -28,6 +28,7 @@ import BrowserSelector from './browse/BrowserSelector' | |
import Filters from './browse/Filters' | ||
import ListBrowser from './browse/ListBrowser' | ||
import TileBrowser from './browse/TileBrowser' | ||
import MapBrowser from './browse/MapBrowser' | ||
import ContributionFetcher from './browse/ContributionFetcher' | ||
|
||
export default { | ||
|
@@ -36,6 +37,7 @@ export default { | |
Filters, | ||
ListBrowser, | ||
TileBrowser, | ||
MapBrowser, | ||
}, | ||
props: { | ||
contributions: {type: Array}, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,105 +2,131 @@ | |
<section class="MapBrowser"> | ||
<!-- FIXME Pull access-token via environment variable --> | ||
<mapbox | ||
access-token="pk.eyJ1IjoibXV0dWFsLWFpZC1hcHAiLCJhIjoiY2tmZTBvd3UwMDBhbTJ4cDlic2JmMWZoaiJ9.rWscBjdl1SMT5N0yekIJYg" | ||
:map-options="{ | ||
style: 'mapbox://styles/mapbox/streets-v11', | ||
center: [-75.1635262, 39.9527237], | ||
zoom: 9, | ||
}" | ||
:geolocate-control="{ | ||
show: true, | ||
position: 'top-left', | ||
}" | ||
@map-load="loaded" | ||
@map-zoomend="zoomend" | ||
@map-click:points="clicked" | ||
@geolocate-error="geolocateError" | ||
@geolocate-geolocate="geolocate" | ||
/> | ||
:access-token= this.accessToken | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nitpick: i don't think |
||
:map-options="{ | ||
style: 'mapbox://styles/mapbox/streets-v11', | ||
center: [-96, 37.8], | ||
zoom: 4, | ||
}" | ||
:geolocate-control="{ | ||
show: true, | ||
position: 'top-left', | ||
}" | ||
@map-load="loaded" | ||
@map-zoomend="zoomend" | ||
@map-click:points="clicked" | ||
@geolocate-error="geolocateError" | ||
@geolocate-geolocate="geolocate" | ||
/> | ||
</section> | ||
</template> | ||
|
||
<script> | ||
import Mapbox from 'mapbox-gl-vue' | ||
import Mapbox from 'mapbox-gl-vue' | ||
const mbxClient = require('@mapbox/mapbox-sdk'); | ||
const geoCoding = require('@mapbox/mapbox-sdk/services/geocoding'); | ||
// FIXME Attempt to pass accessToken in script tag as seen in line 6 | ||
const baseClient = mbxClient({ accessToken: "pk.eyJ1IjoibXV0dWFsLWFpZC1hcHAiLCJhIjoiY2tmZTBvd3UwMDBhbTJ4cDlic2JmMWZoaiJ9.rWscBjdl1SMT5N0yekIJYg"}); | ||
const geoCodingService = geoCoding(baseClient) | ||
|
||
export default { | ||
components: { Mapbox }, | ||
methods: { | ||
loaded(map) { | ||
var geojson = { | ||
'type': 'FeatureCollection', | ||
'features': [ | ||
{ | ||
'type': 'Feature', | ||
'properties': { | ||
'message': 'Foo', | ||
'icon': 'harbor', | ||
'iconSize': [60, 60] | ||
}, | ||
'geometry': { | ||
'type': 'Point', | ||
'coordinates': [-75.1635262, 39.9527237] | ||
} | ||
}, | ||
] | ||
} | ||
export default { | ||
props: { | ||
accessToken: String, | ||
contributions: {type: Array, default: () => []}, | ||
filters: Object, | ||
}, | ||
components: { Mapbox }, | ||
methods: { | ||
loaded(map) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks great. On a second pass in the future, it could be worth trying to extract some of the sdk functions out into a separate module. There's a bit going on in this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
let geojson = { | ||
'type': 'FeatureCollection', | ||
'features': [] | ||
} | ||
|
||
map.addLayer({ | ||
id: 'points', | ||
type: 'symbol', | ||
source: { | ||
type: 'geojson', | ||
data: geojson, | ||
}, | ||
layout: { | ||
'icon-image': '{icon}-15', | ||
'text-field': '{title}', | ||
'text-font': ['Open Sans Semibold', 'Arial Unicode MS Bold'], | ||
'text-offset': [0, 0.6], | ||
'text-anchor': 'top', | ||
}, | ||
}) | ||
const buildGeoJson = () => { | ||
return new Promise((resolve) => { | ||
let forwarded = 0 | ||
|
||
geojson.features.forEach(function (marker) { | ||
var el = document.createElement('div'); | ||
el.className = 'marker'; | ||
el.style.backgroundImage = | ||
'url(https://placekitten.com/g/5/5/)'; | ||
el.style.width = marker.properties.iconSize[0] + 'px'; | ||
el.style.height = marker.properties.iconSize[1] + 'px'; | ||
this.contributions.forEach(contribution => { | ||
geoCodingService.forwardGeocode({ | ||
query: `${contribution.location.street_address} ${contribution.service_area.location.city} ${contribution.service_area.location.state} ${contribution.service_area.location.zip_code}`, | ||
limit: 1 | ||
}).send() | ||
.then(response => { | ||
++forwarded | ||
|
||
el.addEventListener('click', function () { | ||
window.alert(marker.properties.message); | ||
}); | ||
const match = response.body; | ||
|
||
new mapboxgl.Marker(el) | ||
.setLngLat(marker.geometry.coordinates) | ||
.addTo(map); | ||
}); | ||
}, | ||
zoomend(map, e) { | ||
console.log('Map zoomed') | ||
}, | ||
clicked(map, e) { | ||
const title = e.features[0].properties.title | ||
console.log(title) | ||
}, | ||
geolocateError(control, positionError) { | ||
console.log(positionError) | ||
}, | ||
geolocate(control, position) { | ||
console.log( | ||
`User position: ${position.coords.latitude}, ${position.coords.longitude}` | ||
) | ||
}, | ||
}, | ||
} | ||
</script> | ||
geojson.features = [ ...geojson.features, { | ||
'type': 'Feature', | ||
'properties': { | ||
'title': contribution.name, | ||
'description': contribution.description ? contribution.description : "", | ||
'categoryTag': contribution.category_tags[0].name, | ||
'urgency': contribution.urgency ? contribution.urgency : "", | ||
'icon': 'harbor', | ||
'iconSize': [50, 50], | ||
'contributionType': contribution.contribution_type, | ||
}, | ||
'geometry': { | ||
'type': 'Point', | ||
'coordinates': match.features[0].center | ||
} | ||
} ] | ||
}) | ||
.then(() => { | ||
if (forwarded === this.contributions.length) resolve() | ||
}) | ||
}) | ||
}) | ||
} | ||
|
||
buildGeoJson() | ||
.then(() => { | ||
map.addLayer({ | ||
id: 'points', | ||
type: 'symbol', | ||
source: { | ||
type: 'geojson', | ||
data: geojson, | ||
}, | ||
layout: { | ||
'text-font': ['Open Sans Semibold', 'Arial Unicode MS Bold'], | ||
'text-offset': [0, 0.6], | ||
'text-anchor': 'top', | ||
}, | ||
}) | ||
|
||
geojson.features.forEach(function (marker) { | ||
var el = document.createElement('div'); | ||
el.className = 'marker ' + marker.properties.contributionType.toLowerCase() + '-marker'; | ||
el.style.width = marker.properties.iconSize[0] + 'px'; | ||
el.style.height = marker.properties.iconSize[1] + 'px'; | ||
|
||
<style> | ||
#map { | ||
width: 100%; | ||
height: 500px; | ||
const newMarker = new mapboxgl.Marker(el) | ||
.setLngLat(marker.geometry.coordinates) | ||
.setPopup(new mapboxgl.Popup({ offset: 35 }) | ||
.setHTML('<h3>' + marker.properties.title + '</h3><p>' + marker.properties.categoryTag + '</p><p>' + marker.properties.description + '</p>')) | ||
|
||
newMarker.addTo(map) | ||
}) | ||
}) | ||
}, | ||
zoomend(map, e) { | ||
console.log('Map zoomed') | ||
}, | ||
clicked(map, e) { | ||
const title = e.features[0].properties.title | ||
console.log(title) | ||
}, | ||
geolocateError(control, positionError) { | ||
console.log(positionError) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we might want to remove these |
||
}, | ||
geolocate(control, position) { | ||
console.log( | ||
`User position: ${position.coords.latitude}, ${position.coords.longitude}` | ||
) | ||
}, | ||
}, | ||
} | ||
</style> | ||
</script> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -69,6 +69,7 @@ def peer_to_peer? | |
# confirmation_page_text_footer :string | ||
# confirmation_page_text_header :string | ||
# confirmation_page_text_link_header :string | ||
# display_navbar :boolean default(FALSE) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are these supposed to be checked in? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, we have a gem that automatically inserts these comments and keeps them up to date with new migrations. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the clarification @exbinary ! |
||
# donations_module :boolean default(TRUE), not null | ||
# exchange_type :string default("peer_to_peer"), not null | ||
# landing_page_text_how :text | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ | |
# confirmation_page_text_footer :string | ||
# confirmation_page_text_header :string | ||
# confirmation_page_text_link_header :string | ||
# display_navbar :boolean default(FALSE) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Check this in or no? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @thestephenmarshall Looks like this was inserted automatically. We didn't add the change manually so we should probably defer to @maebeale @exbinary @h-m-m for this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Annotate adds these schema details for both models and factories after migrations are applied. I think it's okay to check this in unless mutual-aid folks say otherwise. |
||
# donations_module :boolean default(TRUE), not null | ||
# exchange_type :string default("peer_to_peer"), not null | ||
# landing_page_text_how :text | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@maebeale as time goes on, we will want to consider splitting packs up and this would likely be either: a) it's own pack or b) imported on a more view-specific pack. /randomthoughts