-
Notifications
You must be signed in to change notification settings - Fork 6.3k
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
Comprehensive Events Page #378
Merged
Changes from 7 commits
Commits
Show all changes
16 commits
Select commit
Hold shift + click to select a range
9c1ec66
Code for pulling in event data and intial, terrible, display code.
mikeal f3b4328
change events lists to three column layout
rnsloan 0839d95
Fixing data, adding the rest of meetup.com
mikeal 0f9e896
Adding a map to the top of the events page. Also formatting fixes to …
mikeal a0c7ebf
Moving to basic streets.
mikeal f68aaaa
Improved map views with legend.
mikeal e3f17e3
Defaulting map to near where you are.
mikeal 912a629
move events map css to .styl . Adapt for mobile. Move JS to bottom of…
rnsloan dd94b03
add has-js class to html element for css targeting
rnsloan efbad69
add toggle display of events
rnsloan e203d04
replace hard-coded event numbers
rnsloan 54690a0
Better tooltips in map and real counts.
mikeal 83aff10
Fixing merge conflict.
mikeal 13e19e3
consistent JS semi-colons. css cleanup.
rnsloan 12a23cf
More data and information on being listed.
mikeal f796fbf
Adding image for Node.js Interactive.
mikeal File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
var request = require('request').defaults({json: true, headers: {'user-agent': 'pull-meeting-0.1'}}), | ||
url = 'https://api.meetup.com/2/groups', | ||
auth = process.env.MEETUP_TOKEN, | ||
qs = require('querystring'), | ||
yml = require('./yaml-sync'), | ||
opts = | ||
{ topic: 'nodejs', category: 34, upcoming_events: true, key: auth | ||
}, | ||
allresults = [], | ||
u = url + '?' + qs.stringify(opts) | ||
|
||
var countryMap = | ||
{ ES: 'Africa', MU: 'Africa', NG: 'Africa', KE: 'Africa', ZA: 'Africa', MA: 'Africa', EG: 'Africa', IL: 'Asia', TH: 'Asia', KR: 'Asia', RU: 'Asia', ID: 'Asia', PH: 'Asia', IN: 'Asia', HK: 'Asia', CN: 'Asia', VN: 'Asia', TW: 'Asia', LK: 'Asia', NP: 'Asia', JP: 'Asia', AE: 'Asia', BD: 'Asia', LT: 'Europe', RS: 'Europe', HR: 'Europe', CZ: 'Europe', PT: 'Europe', TR: 'Europe', GR: 'Europe', DE: 'Europe', RO: 'Europe', MT: 'Europe', GH: 'Europe', IE: 'Europe', FI: 'Europe', SE: 'Europe', UA: 'Europe', AT: 'Europe', HU: 'Europe', CH: 'Europe', IS: 'Europe', GB: 'Europe', DK: 'Europe', EE: 'Europe', BE: 'Europe', NO: 'Europe', NL: 'Europe', FR: 'Europe', PL: 'Europe', SK: 'Europe', IT: 'Europe', SI: 'Europe', LU: 'Europe', BY: 'Europe', ME: 'Europe', CA: 'North America', US: 'North America', DO: 'Latin America', AR: 'Latin America', PE: 'Latin America', MX: 'Latin America', BR: 'Latin America', VE: 'Latin America', CL: 'Latin America', CO: 'Latin America', UY: 'Latin America', PA: 'Latin America', GT: 'Latin America', EC: 'Latin America', AU: 'South Pacific', SG: 'South Pacific', NZ: 'South Pacific' | ||
} | ||
|
||
function clean (event) { | ||
delete event.topics | ||
delete event.urlname | ||
delete event.category | ||
delete event.id | ||
} | ||
|
||
function finish (events) { | ||
// return console.log(JSON.stringify(events)) | ||
events.forEach(function (event) { | ||
if (!countryMap[event.country]) { | ||
console.log(event) | ||
throw new Error('Do not have map for ' + event.country) | ||
} | ||
var region = yml.getRegion(countryMap[event.country]) | ||
if (!region.meetups) region.meetups = [] | ||
clean(event) | ||
yml.replace(region.meetups, 'name', event.name, event) | ||
}) | ||
yml.save() | ||
} | ||
// This is nice when testing if you cache the response | ||
// finish(JSON.parse(require('fs').readFileSync('./meetup.json').toString())) | ||
|
||
function _go (u) { | ||
request(u, function (e, resp, body) { | ||
var results = body.results | ||
results.forEach(function (result) { | ||
var title = result.name.toLowerCase() | ||
if (title.indexOf('nodeschool') !== -1) return | ||
if (title.indexOf('mongodb') !== -1 && title.indexOf('node') === -1) return | ||
if (title.indexOf('find a tech job') !== -1 && title.indexOf('node') === -1) return | ||
// if (title.indexOf('node') !== -1) return allresults.push(result) | ||
allresults.push(result) | ||
}) | ||
if (body.meta.next) { | ||
_go(body.meta.next) | ||
} else { | ||
finish(allresults) | ||
} | ||
}) | ||
} | ||
_go(u) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
var request = require('request'), | ||
yml = require('./yaml-sync'), | ||
nodeGeocoder = require('node-geocoder'), | ||
geoOpts = | ||
{ apiKey: process.env.MAPS_TOKEN, formatter: null | ||
}, | ||
geocoder = nodeGeocoder('google', 'https', geoOpts) | ||
|
||
request('http://nodeschool.io/chapters/list.json', {json: true}, function (e, resp, list) { | ||
if (e || resp.statusCode !== 200) throw (e || new Error('response not 200' + resp.statusCode)) | ||
var count = 0 | ||
var chapters = [] | ||
|
||
list.regions.forEach(function (reg) { | ||
var store = yml.getRegion(reg.region) | ||
if (!store.nodeschools) { | ||
store.nodeschools = [] | ||
} | ||
|
||
reg.chapters.forEach(function (chapter) { | ||
delete chapter.region | ||
chapter.location = chapter.location + ', ' + chapter.country | ||
delete chapter.country | ||
yml.replace(store.nodeschools, 'name', chapter.name, chapter) | ||
count += 1 | ||
chapters.push(chapter) | ||
}) | ||
}) | ||
|
||
function _geo () { | ||
if (chapters.length === 0) return yml.save() | ||
var chapter = chapters.shift() | ||
geocoder.geocode(chapter.location, function (err, res) { | ||
console.log(err, res) | ||
if (err || !res.length) return _geo() | ||
chapter.lat = res[0].latitude | ||
chapter.lon = res[0].longitude | ||
_geo() | ||
}) | ||
} | ||
_geo() | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
var yaml = require('js-yaml'), | ||
fs = require('fs'), | ||
path = require('path'), | ||
p = path.join(__dirname, '..', 'locale', 'en', 'get-involved', 'events.md'), | ||
buf = fs.readFileSync(p), | ||
lines = buf.toString().split('\n'), | ||
str = lines.slice(lines.indexOf('---') + 1, lines.indexOf('---', lines.indexOf('---') + 1)).join('\n'), | ||
store = yaml.safeLoad(str) | ||
|
||
exports.getRegion = function (region) { | ||
for (var reg in store.regions) { | ||
if (store.regions[reg].region === region) return store.regions[reg] | ||
} | ||
var reg = {region: region} | ||
store.regions.push(reg) | ||
return reg | ||
} | ||
|
||
exports.removeEmpty = function (dict) { | ||
for (var i in dict) { | ||
if (!dict[i]) delete dict[i] | ||
} | ||
} | ||
|
||
exports.replace = function (list, key, keyValue, value) { | ||
exports.removeEmpty(value) | ||
for (var i = 0;i < list.length;i++) { | ||
if (list[i][key] === keyValue) { | ||
list[i] = value | ||
return | ||
} | ||
} | ||
list.push(value) | ||
} | ||
|
||
exports.save = function () { | ||
var str = ['---', yaml.dump(store), '---'].join('\n') | ||
fs.writeFileSync(p, str) | ||
} | ||
|
||
function rebalance () { | ||
store.regions = store.regions.slice(0, 6) | ||
exports.save() | ||
} | ||
|
||
function clearMeetups () { | ||
store.regions.forEach(function (reg) { | ||
delete reg.meetups | ||
}) | ||
exports.save() | ||
} | ||
// clearMeetups() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
.events-list | ||
display flex | ||
flex-wrap wrap | ||
list-style none | ||
padding 0 | ||
margin 0 | ||
|
||
li | ||
width 31% | ||
padding 0 | ||
margin 0 2% 1rem 0 | ||
|
||
@media screen and (max-width: 600px) | ||
li | ||
width 100% |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
<!DOCTYPE html> | ||
<html lang="{{site.locale}}"> | ||
{{> html-head }} | ||
|
||
<body> | ||
{{> header }} | ||
|
||
<div id="main"> | ||
<div class="container has-side-nav"> | ||
|
||
<aside> | ||
<ul> | ||
<li{{#equals path site.getinvolved.link}} class="active"{{/equals}}> | ||
<a href="/{{site.locale}}/{{site.getinvolved.link}}/">{{site.getinvolved.text}}</a> | ||
</li> | ||
<li{{#equals path site.getinvolved.code-and-learn.link}} class="active"{{/equals}}> | ||
<a href="/{{site.locale}}/{{site.getinvolved.code-and-learn.link}}/">{{site.getinvolved.code-and-learn.text}}</a> | ||
</li> | ||
<li{{#equals path site.getinvolved.contribute.link}} class="active"{{/equals}}> | ||
<a href="/{{site.locale}}/{{site.getinvolved.contribute.link}}/">{{site.getinvolved.contribute.text}}</a> | ||
</li> | ||
<li{{#equals path site.getinvolved.development.link}} class="active"{{/equals}}> | ||
<a href="/{{site.locale}}/{{site.getinvolved.development.link}}/">{{site.getinvolved.development.text}}</a> | ||
</li> | ||
<li{{#equals path site.getinvolved.events.link}} class="active"{{/equals}}> | ||
<a href="/{{site.locale}}/{{site.getinvolved.events.link}}/">{{site.getinvolved.events.text}}</a> | ||
</li> | ||
<li> | ||
<a href="https://github.com/nodejs/node/blob/master/CONTRIBUTING.md#code-of-conduct">{{site.getinvolved.conduct.text}}</a> | ||
</li> | ||
</ul> | ||
</aside> | ||
|
||
<article> | ||
<script src='https://api.mapbox.com/mapbox.js/v2.2.3/mapbox.js'></script> | ||
<link href='https://api.mapbox.com/mapbox.js/v2.2.3/mapbox.css' rel='stylesheet' /> | ||
<style> | ||
div.map { | ||
height: 400px; | ||
width:100%; | ||
margin-top:10px; | ||
} | ||
.key { | ||
padding: 8px 0; | ||
text-align: center; | ||
} | ||
.key span {padding-right: 12px;} | ||
.key-meetup::before { | ||
content: ""; | ||
width: 12px; | ||
height: 12px; | ||
background: #80bd01; | ||
display: inline-block; | ||
border-radius: 3px; | ||
margin-right: 8px; | ||
} | ||
.key-nodeschool::before { | ||
content: ""; | ||
width: 12px; | ||
height: 12px; | ||
background: #f7da03; | ||
display: inline-block; | ||
border-radius: 3px; | ||
margin-right: 8px; | ||
} | ||
.key-conference::before { | ||
content: ""; | ||
width: 12px; | ||
height: 12px; | ||
background: #3887be; | ||
display: inline-block; | ||
border-radius: 3px; | ||
margin-right: 8px; | ||
} | ||
.events #map { | ||
margin: 0; | ||
padding: 0; | ||
} | ||
</style> | ||
<div id="map" class="map"></div> | ||
<div class="key"> | ||
<span class="key-meetup" data-i18n="events-meetu">Meetup</span> | ||
<span class="key-nodeschool" data-i18n="events-nodeschool">NodeSchool</span> | ||
<span class="key-conference" data-i18n="events-conference">Conference</span> | ||
</div> | ||
<script> | ||
function haversine() { | ||
var radians = Array.prototype.map.call(arguments, function(deg) { return deg/180.0 * Math.PI; }); | ||
var lat1 = radians[0], lon1 = radians[1], lat2 = radians[2], lon2 = radians[3]; | ||
var R = 6372.8; // km | ||
var dLat = lat2 - lat1; | ||
var dLon = lon2 - lon1; | ||
var a = Math.sin(dLat / 2) * Math.sin(dLat /2) + Math.sin(dLon / 2) * Math.sin(dLon /2) * Math.cos(lat1) * Math.cos(lat2); | ||
var c = 2 * Math.asin(Math.sqrt(a)); | ||
return R * c; | ||
} | ||
|
||
L.mapbox.accessToken = 'pk.eyJ1IjoibWlrZWFsIiwiYSI6ImNpaGY5ajk5ZTA0ZTN0cmo3MzZ5NnV5eHIifQ.YBfpOTUwcbaZrNvAfDaDcQ'; | ||
var map = L.mapbox.map('map', 'mapbox.streets-basic') | ||
var featureLayer = L.mapbox.featureLayer() | ||
|
||
featureLayer.on('ready', function () { | ||
if ("geolocation" in navigator) { | ||
/* geolocation is available */ | ||
navigator.geolocation.getCurrentPosition(function(position) { | ||
var lat = position.coords.latitude | ||
, lon = position.coords.longitude | ||
; | ||
|
||
var points = featureLayer.getGeoJSON().features.map(function (feature) { | ||
var _lat = feature.geometry.coordinates[1] | ||
, _lon = feature.geometry.coordinates[0] | ||
; | ||
return [feature.geometry.coordinates[0], feature.geometry.coordinates[1], haversine(lat, lon, _lat, _lon)] | ||
}) | ||
.sort(function (a, b) { | ||
return a[2] > b[2] | ||
}) | ||
|
||
function _bounds () { | ||
for (var i=0;i<points.length;i++) { | ||
var hav = points[i][2] | ||
if (i > 10 && hav > .1) { | ||
return [points[i][1], points[i][0]] | ||
} | ||
} | ||
} | ||
|
||
map.fitBounds([[lat, lon], _bounds()]) | ||
map.setView([lat, lon], map.getZoom()-1) | ||
}) | ||
} | ||
}) | ||
|
||
featureLayer.loadURL('/static/event-geo.json').addTo(map) | ||
</script> | ||
|
||
{{#each regions}} | ||
<div class="region"> | ||
<h1>{{region}}</h1> | ||
{{#if conferences}}<h2>Conferences</h2>{{/if}} | ||
{{#each conferences}} | ||
<div class="conference"> | ||
<h3><a href="{{link}}">{{name}}</a> | ||
{{#if location}} | ||
- <small class="map-link"><a href="https://www.google.com/maps/place/{{location}}">map</a></small> | ||
{{/if}} | ||
</h3> | ||
{{#if desc}} | ||
<div class="conference-description">{{desc}}</div> | ||
{{/if}} | ||
</div> | ||
{{/each}} | ||
|
||
<h2>NodeSchools</h2> | ||
<ul class="events-list"> | ||
{{#each nodeschools}} | ||
<li> | ||
{{#if website}} | ||
<a href="{{website}}">{{name}}</a> | ||
{{else}} | ||
{{#if repo}} | ||
<a href="{{repo}}">{{name}}</a> | ||
{{else}} | ||
{{name}} | ||
{{/if}} | ||
{{/if}} | ||
</li> | ||
{{/each}} | ||
</ul> | ||
|
||
<h2>Meetups</h2> | ||
<ul class="events-list"> | ||
{{#each meetups}} | ||
<li><a href="{{link}}">{{name}}</a></li> | ||
{{/each}} | ||
</ul> | ||
|
||
</div> | ||
{{/each}} | ||
</article> | ||
|
||
</div> | ||
</div> | ||
|
||
{{> footer }} | ||
</body> | ||
</html> |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Why is the 10th point the one to return?
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.
Here's how I do bounds detection, it could be a regular
for
loop as well, though where is the fun in that?