From 08abd93a3111d250dbb83627a32e51a6006b2d84 Mon Sep 17 00:00:00 2001 From: Elan Trybuch Date: Sun, 19 Apr 2020 16:59:36 -0400 Subject: [PATCH] GIT-19: Countdown Timer for Trains leaving within walking distance time. (#31) * GIT-19: Patch bump * GIT-19: Add countdown time for train Adds a countdown timer to the view if the train is departing within walking time Co-authored-by: Trybuche --- MMM-nyc-transit.js | 258 ++++++++++++++++++++++++++++++++++++++------- node_helper.js | 24 +++-- package.json | 2 +- 3 files changed, 233 insertions(+), 51 deletions(-) diff --git a/MMM-nyc-transit.js b/MMM-nyc-transit.js index ee14ff3..f4cfb40 100644 --- a/MMM-nyc-transit.js +++ b/MMM-nyc-transit.js @@ -5,30 +5,33 @@ * MIT Licensed. */ -Module.register('MMM-nyc-transit', { /*eslint-disable-line*/ +Module.register('MMM-nyc-transit', { /*eslint-disable-line*/ // Default module config. defaults: { displayType: 'marquee', + header: 'Next Train', + module: 'MMM-nyc-transit', mtaType: 'train', + position: 'top_bar', stations: [ { - stationId: 237, - walkingTime: 5, dir: { upTown: true, - downTown: true - } + downTown: true, + }, + stationId: 237, + walkingTime: 5, }, { - stationId: 238, - walkingTime: 5, dir: { upTown: true, - downTown: true - } - } + downTown: true, + }, + stationId: 238, + walkingTime: 5, + }, ], - updateInterval: 300000 // every 5 min + updateInterval: 300000, // every 5 min }, getStyles: function () { @@ -39,8 +42,50 @@ Module.register('MMM-nyc-transit', { /*eslint-disable-line*/ this.getDepartures(); this.scheduleUpdate(); }, - getDom: function () { + // Set up targetnode based on position set in config + var targetNode = document.querySelector( + '.region.' + this.config.position.split('_').join('.') + ' .container' + ); + // set up mutation observer config options + var config = { attributes: true, childList: true, subtree: true }; + // call back function for mutation observer + var callback = function (mutationsList, observer) { /*eslint-disable-line*/ + // Use traditional 'for loops' for IE 11 + for (let mutation of mutationsList) { + if (mutation.type === 'childList') { + var trainTimes = document.querySelectorAll( + '.mta__train--time span' + ); + trainTimes.forEach((train) => { + // Get the train time as a Number type + var duration = Number(train.textContent + .split(' ')[1] + .split('min')[0]); + var timer = duration * 60; + var minutes; + var seconds; + + // Compare duration to walkingtime + if( duration <= Number(train.dataset.walkingTime)){ + setInterval(function () { + minutes = parseInt(timer / 60, 10); + seconds = parseInt(timer % 60, 10); + + // minutes = minutes < 10 ? minutes : minutes; + seconds = seconds < 10 ? '0' + seconds : seconds; + train.textContent = minutes + ':' + seconds + 'min'; + + if (--timer < 0) { + timer = duration; + } + }, 1000); + } + }); + } + } + }; + var observer = new MutationObserver(callback); var data = this.result; // the data is not ready var wrapper = document.createElement('div'); var marquee = document.createElement('marquee'); @@ -54,26 +99,26 @@ Module.register('MMM-nyc-transit', { /*eslint-disable-line*/ if (data) { var downTown = data[0].downTown; var upTown = data[1].upTown; - if (Object.keys(data).length === 0 && data.constructor === Object) { return wrapper; } - if(isList){ + if (isList) { var trainHashMap = { downTown: [], - upTown: [] + upTown: [], }; - downTown.forEach((train) => { if (!trainHashMap.downTown[train.routeId]) { trainHashMap.downTown[train.routeId] = { time: [train.time], - dest: train.destination + dest: train.destination, + walkingTime: train.walkingTime }; - } else { - trainHashMap.downTown[train.routeId].time.push(train.time); + trainHashMap.downTown[train.routeId].time.push( + train.time + ); } }); @@ -81,8 +126,32 @@ Module.register('MMM-nyc-transit', { /*eslint-disable-line*/ var dHtml = ''; var downTownListItem = document.createElement('li'); - dHtml = dHtml + '' + trainHashMap.downTown[dKey].dest + ' ' + trainHashMap.downTown[dKey].time.slice(0,3).map((trainTime) => ' ' + trainTime + 'min') + ' '; /*eslint-disable-line*/ - + dHtml = + dHtml + + '' + + trainHashMap.downTown[dKey].dest + + ' ' + + trainHashMap.downTown[dKey].time + .slice(0, 3) + .map( + (trainTime, i) => + ' ' + + trainTime + + 'min' + ) + + " "; /*eslint-disable-line*/ downTownListItem.className = 'mta__train--item'; downTownListItem.innerHTML = dHtml; @@ -93,11 +162,13 @@ Module.register('MMM-nyc-transit', { /*eslint-disable-line*/ if (!trainHashMap.upTown[train.routeId]) { trainHashMap.upTown[train.routeId] = { time: [train.time], - dest: train.destination + dest: train.destination, + walkingTime: train.walkingTime }; - } else { - trainHashMap.upTown[train.routeId].time.push(train.time); + trainHashMap.upTown[train.routeId].time.push( + train.time + ); } }); @@ -105,7 +176,32 @@ Module.register('MMM-nyc-transit', { /*eslint-disable-line*/ var uHtml = ''; var upTownListItem = document.createElement('li'); - uHtml = uHtml + '' + trainHashMap.upTown[uKey].dest + ' ' + trainHashMap.upTown[uKey].time.slice(0, 3).map((trainTime) => ' ' + trainTime + 'min') + ''; /*eslint-disable-line*/ + uHtml = + uHtml + + '' + + trainHashMap.upTown[uKey].dest + + ' ' + + trainHashMap.upTown[uKey].time + .slice(0, 3) + .map( + (trainTime, i) => + ' ' + + trainTime + + 'min' + ) + + " "; /*eslint-disable-line*/ upTownListItem.className = 'mta__train--item'; upTownListItem.innerHTML = uHtml; @@ -114,18 +210,41 @@ Module.register('MMM-nyc-transit', { /*eslint-disable-line*/ } wrapper.appendChild(list); - return wrapper; - } else{ - + } else { for (var upMarKey in upTown) { - - if (!Object.prototype.hasOwnProperty.call(upTown, upMarKey)) { continue; } + if ( + !Object.prototype.hasOwnProperty.call(upTown, upMarKey) + ) { + continue; + } var upMarHtml = ''; var upTownMarListItem = document.createElement('span'); - upMarHtml = upMarHtml + '' + upTown[upMarKey].time + 'min | ' + upTown[upMarKey].destination + ''; /*eslint-disable-line*/ + upMarHtml = + upMarHtml + + '' + + ' ' + + ' ' + + upTown[upMarKey].time + + 'min'; + + (" "); /*eslint-disable-line*/ upTownMarListItem.className = 'mta__train--item'; upTownMarListItem.innerHTML = upMarHtml; @@ -133,12 +252,39 @@ Module.register('MMM-nyc-transit', { /*eslint-disable-line*/ } for (var downMarKey in downTown) { - - if (!Object.prototype.hasOwnProperty.call(downTown, downMarKey)) { continue; } + if ( + !Object.prototype.hasOwnProperty.call( + downTown, + downMarKey + ) + ) { + continue; + } var downMarHtml = ''; var downTownMarListItem = document.createElement('span'); - - downMarHtml = downMarHtml + '' + downTown[downMarKey].time + 'min | ' + downTown[downMarKey].destination + ''; /*eslint-disable-line*/ + downMarHtml = + downMarHtml + + '' + + ' ' + + ' ' + + downTown[downMarKey].time + + 'min'; + + " "; /*eslint-disable-line*/ downTownMarListItem.className = 'mta__train--item'; downTownMarListItem.innerHTML = downMarHtml; @@ -150,11 +296,12 @@ Module.register('MMM-nyc-transit', { /*eslint-disable-line*/ return wrapper; } } - + // observer mutation on targetNode with config obj + observer.observe(targetNode, config); return wrapper; }, - getDepartures: function() { + getDepartures: function () { var config = this.config; this.sendSocketNotification('GET_DEPARTURES', config); @@ -173,12 +320,43 @@ Module.register('MMM-nyc-transit', { /*eslint-disable-line*/ }, loadTime); }, + startTimer: function (duration, display) { + var timer = duration, + minutes, + seconds; + + setInterval(function () { + minutes = parseInt(timer / 60, 10); + seconds = parseInt(timer % 60, 10); + + minutes = minutes < 10 ? '0' + minutes : minutes; + seconds = seconds < 10 ? '0' + seconds : seconds; + + display.textContent = minutes + ':' + seconds; + + if (--timer < 0) { + timer = duration; + } + }, 1000); + }, + socketNotificationReceived: function (notification, payload) { if (notification === 'TRAIN_TABLE') { - console.log('socketNotificationReceived: "TRAIN_TABLE": ', this.result); /*eslint-disable-line*/ + // eslint-disable-next-line no-console + console.log( + 'socketNotificationReceived: "TRAIN_TABLE": ', + this.result + ); this.result = payload; - this.updateDom(self.config.fadeSpeed); + this.updateDom( + self.config.fadeSpeed + ); + } else if (notification === 'DOM_OBJECTS_CREATED') { + // eslint-disable-next-line no-console + console.log( + 'Dom Objects Created' + ); } - } + }, }); diff --git a/node_helper.js b/node_helper.js index 2eada36..2ffc78b 100644 --- a/node_helper.js +++ b/node_helper.js @@ -57,11 +57,13 @@ module.exports = NodeHelper.create({ if(i.destinationStationId !== undefined && dirUpTown[n]) { upTown.push({ - 'routeId': i.routeId, - 'time': this.getDate(i.time, walkingTime[n]), - 'destination': (i.destinationStationId === '281') ? - stationIds['606'].name : - stationIds[i.destinationStationId].name + routeId: i.routeId, + time: this.getDate(i.time, walkingTime[n]), + destination: + i.destinationStationId === '281' + ? stationIds['606'].name + : stationIds[i.destinationStationId].name, + walkingTime: walkingTime[n], }); } @@ -78,11 +80,13 @@ module.exports = NodeHelper.create({ if (i.destinationStationId !== undefined && dirDownTown[n]) { downTown.push({ - 'routeId': i.routeId, - 'time': this.getDate(i.time, walkingTime[n]), - 'destination': (i.destinationStationId === '281') ? - stationIds['606'].name : - stationIds[i.destinationStationId].name + routeId: i.routeId, + time: this.getDate(i.time, walkingTime[n]), + destination: + i.destinationStationId === '281' + ? stationIds['606'].name + : stationIds[i.destinationStationId].name, + walkingTime: walkingTime[n], }); } diff --git a/package.json b/package.json index 8ac0d70..9825d2c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "mmm-nyc-transit", - "version": "3.0.0", + "version": "3.0.1", "description": "New York City realtime transit module for magic mirror", "main": "MMM-nyc-transit.js", "publishConfig": {