├── public ├── index.html ├── tracker.html ├── js │ ├── tracker.js │ └── viewer.js └── viewer.html ├── README.md ├── package.json ├── .gitignore ├── index.js └── LICENSE /public/index.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # twitch-track-all-the-things -------------------------------------------------------------------------------- /public/tracker.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Tracker 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "track-all-the-things", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "keywords": [], 10 | "author": "Eddie Zaneski", 11 | "license": "MIT", 12 | "dependencies": { 13 | "body-parser": "^1.15.2", 14 | "express": "^4.14.0", 15 | "socket.io": "^1.4.8" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /public/js/tracker.js: -------------------------------------------------------------------------------- 1 | document.addEventListener('DOMContentLoaded', () => { 2 | const socket = io('/') 3 | 4 | const positionOptions = { 5 | enableHighAccuracy: true, 6 | maximumAge: 0 7 | } 8 | 9 | setInterval(() => { 10 | navigator.geolocation.getCurrentPosition(pos => { 11 | const { latitude: lat, longitude: lng } = pos.coords 12 | socket.emit('updateLocation', { lat, lng }) 13 | }, err => { 14 | console.error(err) 15 | }, positionOptions) 16 | }, 2000) 17 | 18 | }) 19 | -------------------------------------------------------------------------------- /public/viewer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 16 | Map Viewer 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const http = require('http') 4 | const path = require('path') 5 | const express = require('express') 6 | const bodyParser = require('body-parser') 7 | const socketIo = require('socket.io') 8 | 9 | const app = express() 10 | const server = http.createServer(app) 11 | const io = socketIo(server) 12 | 13 | const locationMap = new Map() 14 | 15 | app.use(express.static(path.join(__dirname, 'public'))) 16 | 17 | app.get('/', (req, res) => { 18 | res.send('Hello!') 19 | }) 20 | 21 | io.on('connection', socket => { 22 | socket.on('updateLocation', pos => { 23 | locationMap.set(socket.id, pos) 24 | }) 25 | 26 | socket.on('requestLocations', () => { 27 | socket.emit('locationsUpdate', Array.from(locationMap)) 28 | }) 29 | 30 | socket.on('disconnect', () => { 31 | locationMap.delete(socket.id) 32 | }) 33 | }) 34 | 35 | server.listen(3000, err => { 36 | if (err) { 37 | throw err 38 | } 39 | 40 | console.log('server started on port 3000') 41 | }) 42 | -------------------------------------------------------------------------------- /public/js/viewer.js: -------------------------------------------------------------------------------- 1 | let map 2 | let markers = new Map() 3 | 4 | document.addEventListener('DOMContentLoaded', () => { 5 | const socket = io('/') 6 | 7 | socket.on('locationsUpdate', locations => { 8 | markers.forEach((marker, id) => { 9 | marker.setMap(null) 10 | markers.delete(id) 11 | }) 12 | 13 | locations.forEach(([id, position]) => { 14 | if (position.lat && position.lng) { 15 | const marker = new google.maps.Marker({ 16 | position, 17 | map 18 | }) 19 | markers.set(id, marker) 20 | } 21 | }) 22 | }) 23 | 24 | setInterval(() => { 25 | socket.emit('requestLocations') 26 | }, 2000) 27 | }) 28 | 29 | function initMap() { 30 | navigator.geolocation.getCurrentPosition(pos => { 31 | const { latitude: lat, longitude: lng } = pos.coords 32 | map = new google.maps.Map(document.getElementById('map'), { 33 | center: { lat, lng }, 34 | zoom: 2 35 | }) 36 | }, err => { 37 | console.error(err) 38 | }) 39 | } 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Eddie Zaneski 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | --------------------------------------------------------------------------------