diff --git a/package-lock.json b/package-lock.json
index ccda070..1dade87 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6296,6 +6296,11 @@
"invert-kv": "1.0.0"
}
},
+ "leaflet": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/leaflet/-/leaflet-1.3.1.tgz",
+ "integrity": "sha512-adQOIzh+bfdridLM1xIgJ9VnJbAUY3wqs/ueF+ITla+PLQ1z47USdBKUf+iD9FuUA8RtlT6j6hZBfZoA6mW+XQ=="
+ },
"levn": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
diff --git a/package.json b/package.json
index 6b2371b..9d0460b 100644
--- a/package.json
+++ b/package.json
@@ -32,6 +32,7 @@
"hh-mm-ss": "^1.2.0",
"humanize-duration": "^3.13.0",
"jquery": "^3.3.1",
+ "leaflet": "^1.3.1",
"lodash": "^4.17.5",
"log4js": "^2.5.3",
"loggy": "^1.0.2",
diff --git a/server.js b/server.js
index 2d7c503..b33367e 100644
--- a/server.js
+++ b/server.js
@@ -77,14 +77,18 @@ app.get('/weatheralert', cache('15 minutes'), (req, res) => {
});
app.get('/fsexplore', cache('15 minutes'), (req, res) => {
- if (req.query.hasOwnProperty('ll'))
- foursquare.doGetFourSquareExplore(req.query.ll)
+ if (req.query.hasOwnProperty('ll')) {
+ const ll = req.query.ll;
+ const limit = req.query.hasOwnProperty('ll') ? req.query.limit : 3;
+ const section = req.query.hasOwnProperty('section') ? req.query.section : 'topPicks';
+ foursquare.doGetFourSquareExplore(ll, limit, section)
.then((d) => {
res.send(d);
}).catch((e) => {
logger.error(e);
res.status(500).send('There was an error!');
});
+ }
else {
// throw new Error('Weather: LL missing');
@@ -110,7 +114,7 @@ app.get('/rightbyme', cache('15 minutes'), (req, res) => {
}
});
-app.get('/nearbydetail'/*, cache('15 minutes')*/, (req, res) => {
+app.get('/nearbydetail', cache('15 minutes'), (req, res) => {
if (req.query.hasOwnProperty('id'))
rightbyme.doGetMoreDetail(req.query.id)
.then((d) => {
@@ -173,7 +177,7 @@ app.get('/agenda', cache('15 minutes'), (req, res) => {
app.get('/traffic', cache('5 minutes'), (req, res) => {
logger.debug(req.query);
- if (req.query.hasOwnProperty('olat')) {
+ if (req.query.hasOwnProperty('olat'))
directions.getTraffic(req.query.olat, req.query.olon, req.query.dlat, req.query.dlon)
.then((d) => {
@@ -182,7 +186,7 @@ app.get('/traffic', cache('5 minutes'), (req, res) => {
logger.error(e);
res.status(500).send('There was an error!');
});
- }
+
else {
// throw new Error('Weather: LL missing');
logger.warn('FS: oLat missing');
diff --git a/server/directions.js b/server/directions.js
index 6b19ec2..d84eab5 100644
--- a/server/directions.js
+++ b/server/directions.js
@@ -25,6 +25,7 @@ function doGetEstDirections(olat, olon, dlat, dlon) {
// Throw err;
const output = reduceEstDirections(body);
+ output.fullBody = JSON.parse(body);
output.timestamp = new Date().getTime();
console.log(output);
diff --git a/server/foursquare.js b/server/foursquare.js
index 3f0fa3f..842ad38 100644
--- a/server/foursquare.js
+++ b/server/foursquare.js
@@ -3,15 +3,15 @@ const foursquare = require('node-foursquare-venues')('IXXFUGW3NC3DEVS2V5EU4NV4CL
logger.level = 'debug';
-function doGetFourSquareExplore(ll) {
+function doGetFourSquareExplore(ll, limit = 3, section = 'topPicks') {
const [lat, long ] = ll.split(',');
return new Promise((resolve, reject) => {
const fsObj = {
'll': ll,
- 'section': 'topPicks',
+ 'section': section,
'v': '20170801',
- 'limit': 3,
+ 'limit': limit,
'radius': 800
};
diff --git a/src/css/custom.scss b/src/css/custom.scss
index 6890a6a..1127573 100644
--- a/src/css/custom.scss
+++ b/src/css/custom.scss
@@ -419,4 +419,10 @@ li {
color: #fba010;
}
+#map { height: 180px; }
+
+#bymeImages {
+ margin-bottom: 3px;
+}
+
@import "./src/css/weather";
diff --git a/src/service-worker.js b/src/service-worker.js
index bf0a6a9..26683e5 100644
--- a/src/service-worker.js
+++ b/src/service-worker.js
@@ -11,7 +11,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
-const CACHE_VERSION = { 'version': '0.0.541' };
+const CACHE_VERSION = { 'version': '0.0.644' };
const dataCacheName = 'jubileeData-v1';
const cacheName = 'jubilee-final-1';
const filesToCache = [
@@ -51,7 +51,19 @@ const filesToCache = [
'/gfx/snow_d.jpg',
'/gfx/snow_n.jpg',
'/gfx/storm_d.jpg',
- '/gfx/storm_n.jpg'
+ '/gfx/storm_n.jpg',
+ '/fonts/fonts.css',
+ '/fonts/fujicons.css',
+ '/fonts/fujicons.ttf',
+ '/fonts/Roboto-normal-100.woff',
+ '/fonts/Roboto-normal-300.woff',
+ '/fonts/Roboto-normal-400.woff',
+ '/fonts/Roboto-normal-500.woff',
+ '/fonts/Roboto-normal-600.woff',
+ '/fonts/Roboto-normal-900.woff',
+ '/fonts/Roboto_Condensed-normal-300.woff',
+ '/fonts/Roboto_Condensed-normal-400.woff'
+
];
self.addEventListener('install', function(e) {
diff --git a/src/v1/index.html b/src/v1/index.html
index 3067ec0..7644653 100644
--- a/src/v1/index.html
+++ b/src/v1/index.html
@@ -10,6 +10,9 @@
+
diff --git a/src/v1/js/Nearby.js b/src/v1/js/Nearby.js
index 68fb729..f811c6c 100644
--- a/src/v1/js/Nearby.js
+++ b/src/v1/js/Nearby.js
@@ -8,39 +8,10 @@ const { toHour } = require('./libs/utils');
const TimeFormat = require('hh-mm-ss');
const { FSDetailView } = require('./Foursquare');
-
-// console.notificationsTitle = 'Nearby';
-
-const fsItem = Backbone.Model.extend({
-
-});
-
-const FSCollection = Backbone.Collection.extend({
- 'model': fsItem
-});
+const { fsItem, FSCollection, FSItemView } = require('./libs/fsbits');
const fsCollection = new FSCollection();
-const fsItemView = Backbone.View.extend({
- 'tagName': 'div',
- 'className': 'itemRow mui--align-middle',
- 'template': _.template(`
-
<%= name %> <%= category %> `),
- 'initialize': function() {
- this.render();
- },
- 'attributes': function() {
- return {
- 'data-id': this.model.id
- };
- },
-
- 'render': function() {
- console.log(this.model.attributes);
- this.$el.html(this.template(this.model.toJSON()));
- }
-});
-
const NearbyModel = Backbone.Model.extend({
'defaults' : function (obj) {
// return a new object
@@ -128,6 +99,8 @@ const NearbyView = Backbone.View.extend({
this.location = options.location;
this.fsCollection = fsCollection;
+ _.bindAll(this, 'doMoreClick');
+
// this.model.bind('change', this.render, this);
this.location.bind('change:llFixed', this.updateLocation, this);
this.location.bind('change:atHome', this.atHome, this);
@@ -140,7 +113,8 @@ const NearbyView = Backbone.View.extend({
this.other = $('
Other locations
');
},
'events': {
- 'click .itemRow': 'doClick'
+ 'click .itemRow': 'doClick',
+ 'click #nearbyOther': 'doMoreClick'
},
'updateLocation': function(l) {
console.log('>> Nearby Location has changed...');
@@ -162,7 +136,7 @@ const NearbyView = Backbone.View.extend({
console.log('>> totalResults', totalResults);
this.$el.empty();
this.fsCollection.each(function(item) {
- const fsView = new fsItemView({ 'model': item });
+ const fsView = new FSItemView({ 'model': item });
this.$el.append(fsView.el);
// this.$el.append(personView.el); // adding all the person objects.
}, this);
@@ -183,6 +157,7 @@ const NearbyView = Backbone.View.extend({
console.log('>> Nearby received focus msg');
if (!this.model.has('time')) {
console.log('No time yet');
+
return ;
}
if (this.location.get('atHome')) {
@@ -201,6 +176,17 @@ const NearbyView = Backbone.View.extend({
}, 'atHome': function() {
if (this.location.get('atHome'))
this.$el.parent().hide();
+ },
+ 'doMoreClick': function(d) {
+ console.log('Do more click', d);
+
+ const llFixed = this.model.get('llFixed');
+ const section = this.model.get('section');
+ const data = { llFixed, section, 'limit':20 };
+
+ // console.log('Data', data);
+
+ this.eventBus.trigger('showNearbyList', data);
}
});
diff --git a/src/v1/js/NearbyList.js b/src/v1/js/NearbyList.js
new file mode 100644
index 0000000..948fdbf
--- /dev/null
+++ b/src/v1/js/NearbyList.js
@@ -0,0 +1,149 @@
+const $ = require('jquery');
+const _ = require('underscore');
+const Backbone = require('backbone');
+const request = require('request');
+const { get } = require('lodash');
+const { reduceNearby } = require('./libs/reducers');
+const { createPanel, addPanel } = require('./libs/panel');
+const TimeFormat = require('hh-mm-ss');
+
+const { FSCollection, FSItemView } = require('./libs/fsbits');
+
+const fsCollection = new FSCollection();
+
+const NearbyListModel = Backbone.Model.extend({
+ 'defaults' : function (obj) {
+ // return a new object
+ return {
+ 'update' : new Date().getTime()
+ };
+ }, 'initialize': function() {
+ this.fsCollection = fsCollection;
+ this.listenTo(this, 'change:update', this.onChange);
+ },
+ 'onChange': function() {
+ this.getNearby();
+ },
+ 'getNearby': function() {
+ const llFixed = this.get('llFixed');
+
+ const hour = parseInt((new Date()).getHours().toString(), 10);
+ const section = this.get('section');
+ const limit = this.get('limit');
+ const time = new Date().getTime() ;
+
+ const lastUpdate = time - (this.get('time') || 0);
+
+ console.log('>> Nearby section:', hour, section);
+ console.info('>> Nearby:request');
+ console.log(`>> Nearby last fetch: ${TimeFormat.fromMs(lastUpdate, 'hh:mm')} ago`);
+
+ if (lastUpdate > 120000)
+ request({
+ 'url': `${window.loc}/fsexplore`,
+ 'method': 'GET',
+ 'qs': {
+ 'll': llFixed,
+ 'section': section,
+ 'limit': limit
+ }
+ }, function(err, res, body) {
+ if (err)
+ console.error(err);
+ else {
+ console.log('statusCode', res.statusCode);
+ const fsJSON = JSON.parse(body);
+ const groups = get(fsJSON, 'response.groups');
+ const items = groups[0].items;
+ const newItems = [];
+ this.set('totalResults', get(fsJSON, 'response.totalResults'));
+ for(const item of items)
+ newItems.push(reduceNearby(item));
+
+ this.fsCollection.reset(newItems);
+ this.logUpdate();
+ }
+ }.bind(this));
+ }, 'logUpdate': function() {
+ console.log('NearyList logging:');
+
+ const time = new Date().getTime() ;
+
+ this.set('time', time);
+
+ this.timerID = setTimeout(
+ () => this.tick(),
+ 3.6e+6 + 1000
+ );
+ },
+ 'tick': function() {
+ console.log('Set update');
+ this.set('update', new Date().getTime());
+ }
+
+});
+
+const NearbyListView = Backbone.View.extend({
+ 'initialize': function(options) {
+ this.eventBus = options.eventBus;
+
+ _.bindAll(this, 'doClick');
+
+ this.model.fsCollection.bind('reset', this.render, this);
+ this.eventBus.on('showNearbyList', this.showNearbyListPanel, this);
+ },
+ 'showNearbyListPanel': function(data) {
+ console.log('Showing nearby list', data);
+
+ const prevll = this.model.get('llFixed');
+ const lastTime = this.model.get('last');
+ const now = new Date().getTime();
+
+ this.model.set(data);
+
+ this.model.set('update', new Date().getTime());
+ this.$newPanel = createPanel({ 'title':'Nearby', 'divId':'NearbyListP' });
+
+ this.$el = addPanel(this.$newPanel);
+
+ this.$el.empty();
+ this.$newPanel.show();
+
+ // console.log(this.model);
+ if (prevll === data.llFixed)
+ if (now > lastTime + (60 * 1000 * 60)) {
+ this.model.set('update', now);
+ }
+ else {
+ this.render();
+ }
+ }, 'events': {
+ 'click': 'doClick'
+
+ }, 'doClick': function(d) {
+ console.log('Do click', d);
+ const id = get(d, 'currentTarget.dataset.id', '');
+ console.log(id);
+ this.eventBus.trigger('showVenueDetail', id);
+ },
+ 'render' : function() {
+ console.log('>> Do render');
+
+ console.info('>> Nearby:Render');
+ const totalResults = this.model.get('totalResults');
+ console.log('>> totalResults', totalResults);
+ this.$el.empty();
+ this.model.fsCollection.each(function(item) {
+ const fsView = new FSItemView({ 'model': item });
+ this.$el.append(fsView.el);
+ // this.$el.append(personView.el); // adding all the person objects.
+ }, this);
+
+ this.$el.append(this.other);
+
+ this.$el.find('.itemRow').on('click', this.doClick);
+ }
+
+});
+
+module.exports = { NearbyListModel, NearbyListView };
diff --git a/src/v1/js/RightByMe.js b/src/v1/js/RightByMe.js
index 8ba8fa3..4dec709 100644
--- a/src/v1/js/RightByMe.js
+++ b/src/v1/js/RightByMe.js
@@ -42,7 +42,7 @@ const ByMeModel = Backbone.Model.extend({
clearInterval(this.timerID);
this.timerID = 0;
- console.log(this.toJSON());
+ // console.log(this.toJSON());
// const section = (partOfDay >= 11 && partOfDay <= 14) ? 'food' : 'topPicks';
request({
'url': `${window.loc}/rightbyme`,
diff --git a/src/v1/js/Traffic.js b/src/v1/js/Traffic.js
index 8a54631..fa43525 100644
--- a/src/v1/js/Traffic.js
+++ b/src/v1/js/Traffic.js
@@ -174,4 +174,21 @@ const TrafficView = Backbone.View.extend({
});
+const parts = new Map(
+ [
+ ['0', 'Depart'],
+ ['9', 'left_turn'],
+ ['13', 'right_turn'],
+ ['11', 'continue'],
+ ['23','right_fork'],
+ ['17','left_exit'],
+ ['19', 'left_ramp'],
+ ['29', 'turn'],
+ ['','']
+
+ ]
+
+
+);
+
module.exports = { TrafficModel, TrafficView };
diff --git a/src/v1/js/VenueDetail.js b/src/v1/js/VenueDetail.js
index 1f38fcf..b35b843 100644
--- a/src/v1/js/VenueDetail.js
+++ b/src/v1/js/VenueDetail.js
@@ -4,6 +4,7 @@ const Backbone = require('backbone');
const request = require('request');
const { get, isEmpty } = require('lodash');
const { createPanel, addPanel } = require('./libs/panel');
+const L = require('leaflet');
const templates = require('./libs/templates');
@@ -43,6 +44,7 @@ const VenueDetailModel = Backbone.Model.extend({
const VenueDetailView = Backbone.View.extend({
'initialize': function(options) {
this.eventBus = options.eventBus;
+ this.location = options.location;
this.model.bind('change:details', this.doRender, this);
this.eventBus.on('showVenueDetail', this.showNewsPanel, this);
@@ -81,11 +83,16 @@ const VenueDetailView = Backbone.View.extend({
const m = this.model.get('details');
// this.imagesTemplate(this.model.toJSON()), this.yelpTemplate(this.model.toJSON()), this.tipsTemplate(this.model.toJSON())
+ // console.log(this.model.attributes);
contents.push(templates.venueTitle(m));
+ const $map = $('#map');
+
if (!isEmpty(m.images))
contents.push(templates.imagesTemplate(m));
+ contents.push(templates.map());
+
if (!isEmpty(m.yelp))
contents.push(templates.yelpTemplate(m));
@@ -97,7 +104,29 @@ const VenueDetailView = Backbone.View.extend({
contents.push(templates.openInFS(m));
this.$el.html(contents.join(''));
+ this.$el.append($map);
+ this.map = L.map('map', {
+ 'center': [m.latitude, m.longitude],
+ 'zoom': 15
+ });
+
+ L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
+ 'attribution': 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
+ 'maxZoom': 18,
+ 'id': 'mapbox.streets',
+ 'accessToken': 'pk.eyJ1IjoibWFydGluZDIwMDAiLCJhIjoiY2pmNnlnc3F1MGpoYzJ5bXpscGFwaTlueiJ9.sx1ToptfsUf5HF3-0VVC-Q'
+ }).addTo(this.map);
+
+ /* const marker =*/ L.marker([m.latitude, m.longitude]).addTo(this.map);
+ /* var circle =*/ L.circle(this.location.get('ll').split(','), {
+ 'color': 'blue',
+ 'fillColor': '#00a6ff',
+ 'fillOpacity': 0.5,
+ 'radius': 10
+ }).addTo(this.map);
+
+ // console.log(this.location.attributes);
}
});
diff --git a/src/v1/js/app.js b/src/v1/js/app.js
index 2ec489a..9f0f641 100644
--- a/src/v1/js/app.js
+++ b/src/v1/js/app.js
@@ -17,6 +17,7 @@ const { ByMeModel, ByMeView } = require('./RightByMe');
const { VenueDetailModel, VenueDetailView } = require('./VenueDetail');
const { AgendaModel, AgendaView } = require('./Agenda');
const { TrafficModel, TrafficView } = require('./Traffic');
+const { NearbyListModel, NearbyListView } = require('./NearbyList');
var app = app || {};
const live = true;
@@ -71,7 +72,9 @@ else
app.traffic = new TrafficView({ 'model': new TrafficModel(), 'eventBus': app.eventBus, 'location': app.locationModel, 'el':'#traffic' });
- app.newsCard = new VenueDetailView({ 'model': new VenueDetailModel(), 'eventBus': app.eventBus });
+ app.newsCard = new VenueDetailView({ 'model': new VenueDetailModel(), 'eventBus': app.eventBus, 'location': app.locationModel });
+
+ app.nearbyList = new NearbyListView({ 'model': new NearbyListModel(), 'eventBus' : app.eventBus });
app.updateOnlineStatus = function(event) {
if (navigator.onLine)
diff --git a/src/v1/js/libs/fsbits.js b/src/v1/js/libs/fsbits.js
new file mode 100644
index 0000000..8cf89b2
--- /dev/null
+++ b/src/v1/js/libs/fsbits.js
@@ -0,0 +1,34 @@
+const Backbone = require('backbone');
+const _ = require('underscore');
+
+const fsItem = Backbone.Model.extend({
+
+});
+
+const FSCollection = Backbone.Collection.extend({
+ 'model': fsItem
+});
+
+// const fsCollection = new FSCollection();
+
+const FSItemView = Backbone.View.extend({
+ 'tagName': 'div',
+ 'className': 'itemRow mui--align-middle',
+ 'template': _.template(`
+
<%= name %> <%= category %> `),
+ 'initialize': function() {
+ this.render();
+ },
+ 'attributes': function() {
+ return {
+ 'data-id': this.model.id
+ };
+ },
+
+ 'render': function() {
+ // console.log(this.model.attributes);
+ this.$el.html(this.template(this.model.toJSON()));
+ }
+});
+
+module.exports = { fsItem, FSCollection, FSItemView };
diff --git a/src/v1/js/libs/templates.js b/src/v1/js/libs/templates.js
index 0092f0b..bbe24f8 100644
--- a/src/v1/js/libs/templates.js
+++ b/src/v1/js/libs/templates.js
@@ -59,9 +59,10 @@ const templates = {
'venueTitle' : _.template(`
<%=name %>
`),
- 'openInFS' : _.template(`
+ 'openInFS' : _.template(`
- `)
+ `),
+ 'map': _.template('')
};
module.exports = templates;