diff --git a/README.md b/README.md index bd55ebf8094..1f4c42e60f1 100644 --- a/README.md +++ b/README.md @@ -306,11 +306,29 @@ To learn more about the Nightscout API, visit https://YOUR-SITE.com/api-docs/ or ### Views - There are a few alternate web views available from the main menu that display a simplified BG stream. (If you launch one of these in a fullscreen view in iOS, you can use a left-to-right swipe gesture to exit the view.) + Nightscout allows to create custom, simplified views using a predefined set of elements. This option is available under `[+]` link in the main menu. + + List of available items: + * `SGV` - Sensor Glucose Value + * `SGV age` - time since the last SGV read + * `SGV delta` - change of SGV in the last 5 minutes + * `Trend arrow` - icon of the SG trend + * `Time` - current time + * `Line break` - invisible item that will move following items to the next line (by default all are showing on the same level) + + All visible items have `Size` property which allows to customize the view even more. Also, all items may appear multiple times on the view. + + Apart from adding items, it is possible to customize other aspects of the views, like selecting `Color` or `Black` background. The first one will indicate current BG threshold (green = in range; blue = below range; yellow = above range; red = urgent below/above). + `Show SGV age` option will make `SGV age` item appear `Always` or only if the predefined threshold is reached: `Only after threshold`. Breaching `SGV age threshold` will also make `Color` background turn grey and strike through `SGV`. + `Clock view configurator` will generate an URL (available under `Open my clock view!` link) that could be bookmarked. + + There are a few default views available from the main menu: * `Clock` - Shows current BG, trend arrow, and time of day. Grey text on a black background. - * `Color` - Shows current BG and trend arrow. White text on a background that changes color to indicate current BG threshold (green = in range; blue = below range; yellow = above range; red = urgent below/above). Set `SHOW_CLOCK_DELTA` to `true` to show BG change in the last 5 minutes, set `SHOW_CLOCK_LAST_TIME` to `true` to always show BG age. + * `Color` - Shows current BG and trend arrow. White text on a color background. * `Simple` - Shows current BG. Grey text on a black background. + If you launch one of these views in a fullscreen view in iOS, you can use a left-to-right swipe gesture to exit the view. + ### Split View Some users will need easy access to multiple Nightscout views at the same time. We have a special view for this case, accessed on /split path on your Nightscout URL. The view supports any number of sites between 1 to 8 way split, where the content for the screen can be loaded from multiple Nightscout instances. Note you still need to host separate instances for each Nightscout being monitored including the one that hosts the split view page - these variables only add the ability to load multiple views into one browser page. To set the URLs from which the content is loaded, set: diff --git a/lib/client/clock-client.js b/lib/client/clock-client.js index e6eec7190c6..891f10d57d5 100644 --- a/lib/client/clock-client.js +++ b/lib/client/clock-client.js @@ -6,7 +6,7 @@ var client = {}; client.settings = browserSettings(client, window.serverSettings, $); -// console.log('settings', client.settings); +//console.log('settings', client.settings); // client.settings now contains all settings client.query = function query () { @@ -20,7 +20,7 @@ client.query = function query () { }); var secret = localStorage.getItem('apisecrethash'); - var src = '/api/v1/entries.json?count=3&t=' + new Date().getTime(); + var src = '/api/v1/entries.json?find[type]=sgv&count=3&t=' + new Date().getTime(); if (secret) { src += '&secret=' + secret; @@ -39,6 +39,7 @@ client.render = function render (xhr) { let rec; let delta; + // Get SGV, calculate DELTA xhr.forEach(element => { if (element.sgv && !rec) { rec = element; @@ -49,28 +50,65 @@ client.render = function render (xhr) { }); let $errorMessage = $('#errorMessage'); + let $inner = $('#inner'); // If no one measured value found => show "-?-" if (!rec) { if (!$errorMessage.length) { - $('#arrowDiv').append('
-?-
'); - $('#arrow').hide(); + $inner.after('
-?-
') } else { $errorMessage.show(); } + $inner.hide(); return; } else { $errorMessage.length && $errorMessage.hide(); - $('#arrow').show(); + $inner.show(); + } + + //Parse face parameters + let face = $inner.data('face').toLowerCase(); + + // Backward compatible + if (face === 'clock-color') { + face = 'c' + (window.serverSettings.settings.showClockLastTime ? 'y' : 'n') + '13-sg40-' + (window.serverSettings.settings.showClockDelta ? 'dt14-' : '') + 'nl-ar30-nl-ag6'; + } + else if (face === 'clock') { + face = 'bn0-sg40'; + } + else if (face === 'bgclock') { + face = 'bn0-sg30-ar18-nl-nl-tm26'; + } + else if (face === 'config') { + face = $inner.attr('data-face-config'); + $inner.empty(); + } + + let faceParams = face.split('-'); + let bgColor = false; + let staleMinutes = 13; + let alwaysShowTime = false; + + let clockCreated = ($inner.children().length > 0); + + for (let param in faceParams) { + if (param === '0') { + bgColor = (faceParams[param].substr(0, 1) === 'c'); // do we want colorful background? + alwaysShowTime = (faceParams[param].substr(1, 1) === 'y'); // always show "stale time" text? + staleMinutes = (faceParams[param].substr(2,2) - 0 >= 0) ? faceParams[param].substr(2,2) : 13; // threshold value (0=never) + } else if (!clockCreated){ + let div = '
0) ? ' style="' + ((faceParams[param].substr(0,2) === 'ar') ? 'height' : 'font-size') + ':' + faceParams[param].substr(2,2) + 'vmin"' : '') + '>
'; + $inner.append(div); + } } - - let last = new Date(rec.date); - let now = new Date(); // Convert BG to mmol/L if necessary. + let displayValue; + let deltaDisplayValue; + if (window.serverSettings.settings.units === 'mmol') { - var displayValue = window.Nightscout.units.mgdlToMMOL(rec.sgv); - var deltaDisplayValue = window.Nightscout.units.mgdlToMMOL(delta); + displayValue = window.Nightscout.units.mgdlToMMOL(rec.sgv); + deltaDisplayValue = window.Nightscout.units.mgdlToMMOL(delta); } else { displayValue = rec.sgv; deltaDisplayValue = Math.round(delta); @@ -80,18 +118,8 @@ client.render = function render (xhr) { deltaDisplayValue = '+' + deltaDisplayValue; } - // Insert the BG value text. - $('#bgnow').html(displayValue); - - // Insert the trend arrow. - $('#arrow').attr('src', '/images/' + (!rec.direction || rec.direction === 'NOT COMPUTABLE' ? 'NONE' : rec.direction) + '.svg'); - - // Time before data considered stale. - let staleMinutes = 13; - let threshold = 1000 * 60 * staleMinutes; - - // Toggle stale if necessary. - $('#bgnow').toggleClass('stale', (now - last > threshold)); + // Insert the delta value text. + $('.dt').html(deltaDisplayValue); // Generate and insert the clock. let timeDivisor = parseInt(client.settings.timeFormat ? client.settings.timeFormat : 12, 10); @@ -105,51 +133,24 @@ client.render = function render (xhr) { } let m = today.getMinutes(); if (m < 10) m = "0" + m; - $('#clock').text(h + ":" + m); - - /* global clockFace */ - if (clockFace === 'clock-color') { - - var bgHigh = window.serverSettings.settings.thresholds.bgHigh; - var bgLow = window.serverSettings.settings.thresholds.bgLow; - var bgTargetBottom = window.serverSettings.settings.thresholds.bgTargetBottom; - var bgTargetTop = window.serverSettings.settings.thresholds.bgTargetTop; + $('.tm').html(h + ":" + m); - var bgNum = parseFloat(rec.sgv); + // Color background + if (bgColor) { // These are the particular shades of red, yellow, green, and blue. - var red = 'rgba(213,9,21,1)'; - var yellow = 'rgba(234,168,0,1)'; - var green = 'rgba(134,207,70,1)'; - var blue = 'rgba(78,143,207,1)'; - - var elapsedMins = Math.round(((now - last) / 1000) / 60); - - // Insert the BG stale time text. - let staleTimeText; - if (elapsedMins == 0) { - staleTimeText = 'Just now'; - } - else if (elapsedMins == 1) { - staleTimeText = '1 minute ago'; - } - else { - staleTimeText = elapsedMins + ' minutes ago'; - } - $('#staleTime').text(staleTimeText); - - // Force NS to always show 'x minutes ago' - if (window.serverSettings.settings.showClockLastTime) { - $('#staleTime').css('display', 'block'); - } + let red = 'rgba(213,9,21,1)'; + let yellow = 'rgba(234,168,0,1)'; + let green = 'rgba(134,207,70,1)'; + let blue = 'rgba(78,143,207,1)'; - // Insert the delta value text. - $('#delta').html(deltaDisplayValue); + // Threshold values + let bgHigh = client.settings.thresholds.bgHigh; + let bgLow = client.settings.thresholds.bgLow; + let bgTargetBottom = client.settings.thresholds.bgTargetBottom; + let bgTargetTop = client.settings.thresholds.bgTargetTop; - // Show delta - if (window.serverSettings.settings.showClockDelta) { - $('#delta').css('display', 'inline-block'); - } + let bgNum = parseFloat(rec.sgv); // Threshold background coloring. if (bgNum < bgLow) { @@ -168,25 +169,52 @@ client.render = function render (xhr) { $('body').css('background-color', red); } - // Restyle body bg, and make the "x minutes ago" visible too. - if (now - last > threshold) { - $('body').css('background-color', 'grey'); - $('body').css('color', 'black'); - $('#arrow').css('filter', 'brightness(0%)'); + } + else { + $('body').css('background-color', 'black'); + } - if (!window.serverSettings.settings.showClockLastTime) { - $('#staleTime').css('display', 'block'); - } + // Time before data considered stale. + let threshold = 1000 * 60 * staleMinutes; - } else { - $('body').css('color', 'white'); - $('#arrow').css('filter', 'brightness(100%)'); + let last = new Date(rec.date); + let now = new Date(); + + let elapsedMins = Math.round(((now - last) / 1000) / 60); + + let thresholdReached = (now - last > threshold) && threshold > 0; - if (!window.serverSettings.settings.showClockLastTime) { - $('#staleTime').css('display', 'none'); - } + // Insert the BG value text, toggle stale if necessary. + $('.sg').toggleClass('stale', thresholdReached).html(displayValue); + if (thresholdReached || alwaysShowTime) { + let staleTimeText; + if (elapsedMins === 0) { + staleTimeText = 'Just now'; + } + else if (elapsedMins === 1) { + staleTimeText = '1 minute ago'; + } + else { + staleTimeText = elapsedMins + ' minutes ago'; } + + $('.ag').html(staleTimeText); + } + else { + $('.ag').html(''); + } + + // Insert the trend arrow. + let arrow = $('arrow').attr('src', '/images/' + (!rec.direction || rec.direction === 'NOT COMPUTABLE' ? 'NONE' : rec.direction) + '.svg'); + + // Restyle body bg + if (thresholdReached) { + $('body').css('background-color', 'grey').css('color', 'black'); + $('.ar').css('filter', 'brightness(0%)').html(arrow); + } else { + $('body').css('color', bgColor ? 'white' : 'grey'); + $('.ar').css('filter', bgColor ? 'brightness(100%)' : 'brightness(50%)').html(arrow); } }; diff --git a/lib/server/clocks.js b/lib/server/clocks.js index 56bce7b6f13..9926eefcf82 100644 --- a/lib/server/clocks.js +++ b/lib/server/clocks.js @@ -17,7 +17,7 @@ function clockviews() { const face = req.params.face; console.log('Clockface requested:', face); - res.render('shared.html', { + res.render('clock.html', { face, locals }); diff --git a/views/clockviews/bgclock.css b/views/clockviews/bgclock.css deleted file mode 100644 index 3e2cbef246f..00000000000 --- a/views/clockviews/bgclock.css +++ /dev/null @@ -1,28 +0,0 @@ -.inner { - -webkit-transform: translateY(-2%); -} - -#bgnow, #arrowDiv { - display: flex; - flex-grow: 0; - font-weight: 700; - font-size: 30vmin; - padding: 0 20px; - margin: 0; -} - -img#arrow { - height: 18vmin; - filter: brightness(50%); - -webkit-transform: translateY(5%); -} - -#clock { - font-weight: 700; - font-size: 25vmin; - display: inline; -} - -.stale { - text-decoration: line-through; -} \ No newline at end of file diff --git a/views/clockviews/clock-color.css b/views/clockviews/clock-color.css deleted file mode 100644 index 6a6796ef823..00000000000 --- a/views/clockviews/clock-color.css +++ /dev/null @@ -1,32 +0,0 @@ -body { - color: white; -} - -#trend { - -webkit-transform: translateX(1%); - -webkit-flex-direction: column; - flex-direction: column; -} - -#bgnow { - display: inline-block; - vertical-align: middle; -} - -#delta { - font-size: 16vmin; - vertical-align: middle; -} - -#innerTrend { - word-spacing: 2em; -} - -#arrowDiv { - flex-grow: 1; - text-align: center; -} - -img#arrow { - height: 30vmin; -} \ No newline at end of file diff --git a/views/clockviews/clock-config.css b/views/clockviews/clock-config.css new file mode 100644 index 00000000000..0d5f2b8b912 --- /dev/null +++ b/views/clockviews/clock-config.css @@ -0,0 +1,39 @@ +#config-form { + position: fixed; + top: 10px; + left: 10px; + width: 250px; + min-width: 220px; + background: white; + color: black; + opacity: 0.8; + padding: 1%; + font-size: 10px; +} +#config-form p { + margin: 15px; + text-align: left; +} +input.elmt { + width: 120px; +} +select { + width: 100%; +} +#facename { + font-size: 7px; +} +#clocklink { + font-size: 18px; +} +#clocklink:link, #clocklink:visited { + background-color: #f44336; + color: white; + padding: 14px 25px; + text-align: center; + text-decoration: none; + display: inline-block; +} +#clocklink:hover, #clocklink:active { + background-color: red; +} \ No newline at end of file diff --git a/views/clockviews/clock-config.html b/views/clockviews/clock-config.html new file mode 100644 index 00000000000..fff92bb65cb --- /dev/null +++ b/views/clockviews/clock-config.html @@ -0,0 +1,65 @@ +
+

Clock view configurator

+
+

+ + +

+

+ + +

+

SGV age threshold: minutes

+

+

Size:

+

Size:

+

Size:

+

Size:

+

Size:

+

+ Open my clock view! +
cy10
+
+
+ \ No newline at end of file diff --git a/views/clockviews/clock-shared.css b/views/clockviews/clock-shared.css index 83328fe4114..fc624a52c00 100644 --- a/views/clockviews/clock-shared.css +++ b/views/clockviews/clock-shared.css @@ -3,57 +3,50 @@ body { margin: 0 0; padding: 0; overflow: hidden; - font-family: 'Open Sans'; + font-family: 'Open Sans', Arial, Helvetica, sans-serif; color: grey; background-color: black; } main { + height: 100vh; +} + +#inner { display: -webkit-box; display: -ms-flexbox; display: -webkit-flex; display: flex; - -webkit-box-align: center; - -ms-flex-align: center; - -webkit-align-items: center; align-items: center; - height: 100vh; -} - -.inner { + justify-content: center; + align-content: center; + flex-flow: wrap; + height: 100%; width: 100%; - -webkit-transform: translateY(-5%); } -#bgnow { - font-weight: 700; - font-size: 40vmin; +#inner div { + margin-right: 2vmin; + margin-left: 2vmin; + line-height: 1em; } -#trend { - display: -ms-flexbox; - display: -webkit-flex; - display: flex; - -ms-flex-align: center; - -webkit-align-items: center; - align-items: center; - justify-content: center; - -webkit-flex-direction: row; - flex-direction: row; +#inner div img { + height: 100%; } -#staleTime { - flex-grow: 1; - font-size: 6vmin; - display: none; +#inner div.nl { + width: 100%; + margin: 0; + height: 3vmin; } -#clock { - display: none; +#errorMessage { + font-size: 25em; } -#delta { - display: none; +.stale { + text-decoration: line-through; } .close { diff --git a/views/clockviews/clock.css b/views/clockviews/clock.css deleted file mode 100644 index 96ffe68b84a..00000000000 --- a/views/clockviews/clock.css +++ /dev/null @@ -1,5 +0,0 @@ -#trend { - -webkit-transform: translateX(1%); - -webkit-flex-direction: column; - flex-direction: column; -} \ No newline at end of file diff --git a/views/clockviews/shared.html b/views/clockviews/clock.html similarity index 88% rename from views/clockviews/shared.html rename to views/clockviews/clock.html index beac7dc0f2e..2893aec3612 100644 --- a/views/clockviews/shared.html +++ b/views/clockviews/clock.html @@ -1,5 +1,5 @@ - + @@ -21,23 +21,16 @@
-
-
-
- - -
-
arrow
-
-
-
+
>
@@ -69,7 +62,7 @@ script.src = src; document.head.appendChild(script); //or something of the likes - + <%if (face !== 'config') { %> var buttonVisible = true; function hideClose () { @@ -99,8 +92,11 @@ window.addEventListener('click', function() { showClose(); }); - + <% } %> + <%if (face == 'config') { %> + <%- include('clock-config.html', {}); %> + <% } %> diff --git a/views/index.html b/views/index.html index 6ef0dc2cce6..617d7dd8e67 100644 --- a/views/index.html +++ b/views/index.html @@ -174,6 +174,7 @@ Clock Color Simple + [+]