diff --git a/apps/clkinfostopw/ChangeLog b/apps/clkinfostopw/ChangeLog new file mode 100644 index 000000000..1f72aa73b --- /dev/null +++ b/apps/clkinfostopw/ChangeLog @@ -0,0 +1 @@ +0.01: New clkinfo! diff --git a/apps/clkinfostopw/README.md b/apps/clkinfostopw/README.md new file mode 100644 index 000000000..bfac58dab --- /dev/null +++ b/apps/clkinfostopw/README.md @@ -0,0 +1,11 @@ +# StopW + +A simple stopwatch widget + +## Usage + +Tap to start, tap again to pause. Tap again to restart + +## Requests + +[Contact Rob](https://www.github.com/bobrippling) for features/bugs diff --git a/apps/clkinfostopw/app.png b/apps/clkinfostopw/app.png new file mode 100644 index 000000000..fb1d74b5c Binary files /dev/null and b/apps/clkinfostopw/app.png differ diff --git a/apps/clkinfostopw/clkinfo.js b/apps/clkinfostopw/clkinfo.js new file mode 100644 index 000000000..370809e15 --- /dev/null +++ b/apps/clkinfostopw/clkinfo.js @@ -0,0 +1,58 @@ +"use strict"; +(function () { + var durationOnPause = "---"; + var redrawInterval; + var startTime; + var unqueueRedraw = function () { + if (redrawInterval) + clearInterval(redrawInterval); + redrawInterval = undefined; + }; + var queueRedraw = function () { + var _this = this; + unqueueRedraw(); + redrawInterval = setInterval(function () { return _this.emit('redraw'); }, 100); + }; + var pad2 = function (s) { return ('0' + s.toFixed(0)).slice(-2); }; + var duration = function (start) { + var seconds = (Date.now() - start) / 1000; + if (seconds < 60) + return seconds.toFixed(1); + var mins = seconds / 60; + seconds %= 60; + if (mins < 60) + return "".concat(pad2(mins), "m").concat(pad2(seconds), "s"); + var hours = mins / 60; + mins %= 60; + return "".concat(Math.round(hours), "h").concat(pad2(mins), "m").concat(pad2(seconds), "s"); + }; + var img = function () { return atob("GBiBAAAAAAB+AAB+AAAAAAB+AAH/sAOB8AcA4A4YcAwYMBgYGBgYGBg8GBg8GBgYGBgAGAwAMA4AcAcA4AOBwAH/gAB+AAAAAAAAAA=="); }; + return { + name: "timer", + img: img(), + items: [ + { + name: "stopw", + get: function () { return ({ + text: startTime + ? duration(startTime) + : durationOnPause, + img: img(), + }); }, + show: queueRedraw, + hide: unqueueRedraw, + run: function () { + if (startTime) { + durationOnPause = duration(startTime); + startTime = undefined; + unqueueRedraw(); + } + else { + queueRedraw.call(this); + startTime = Date.now(); + } + } + } + ] + }; +}); diff --git a/apps/clkinfostopw/clkinfo.ts b/apps/clkinfostopw/clkinfo.ts new file mode 100644 index 000000000..900ecaeba --- /dev/null +++ b/apps/clkinfostopw/clkinfo.ts @@ -0,0 +1,65 @@ +((): ClockInfo.Menu => { + let durationOnPause = "---"; + let redrawInterval: number | undefined; + let startTime: number | undefined; + + const unqueueRedraw = () => { + if (redrawInterval) clearInterval(redrawInterval); + redrawInterval = undefined; + }; + + const queueRedraw = function(this: ClockInfo.MenuItem) { + unqueueRedraw(); + redrawInterval = setInterval(() => this.emit('redraw'), 100); + }; + + const pad2 = (s: number) => ('0' + s.toFixed(0)).slice(-2); + + const duration = (start: number) => { + let seconds = (Date.now() - start) / 1000; + + if (seconds < 60) + return seconds.toFixed(1); + + let mins = seconds / 60; + seconds %= 60; + + if (mins < 60) + return `${pad2(mins)}m${pad2(seconds)}s`; + + let hours = mins / 60; + mins %= 60; + + return `${Math.round(hours)}h${pad2(mins)}m${pad2(seconds)}s`; + }; + + const img = () => atob("GBiBAAAAAAB+AAB+AAAAAAB+AAH/sAOB8AcA4A4YcAwYMBgYGBgYGBg8GBg8GBgYGBgAGAwAMA4AcAcA4AOBwAH/gAB+AAAAAAAAAA=="); + + return { + name: "timer", + img: img(), + items: [ + { + name: "stopw", + get: () => ({ + text: startTime + ? duration(startTime) + : durationOnPause, + img: img(), + }), + show: queueRedraw, + hide: unqueueRedraw, + run: function() { // tapped + if (startTime) { + durationOnPause = duration(startTime); + startTime = undefined; + unqueueRedraw(); + } else { + queueRedraw.call(this); + startTime = Date.now(); + } + } + } + ] + }; +}) diff --git a/apps/clkinfostopw/metadata.json b/apps/clkinfostopw/metadata.json new file mode 100644 index 000000000..c0821b8be --- /dev/null +++ b/apps/clkinfostopw/metadata.json @@ -0,0 +1,14 @@ +{ + "id": "clkinfostopw", + "name": "Stop Watch Clockinfo", + "version":"0.01", + "description": "A simple stopwatch, shown via clockinfo", + "icon": "app.png", + "type": "clkinfo", + "tags": "clkinfo,timer", + "supports" : ["BANGLEJS2"], + "allow_emulator": true, + "storage": [ + {"name":"stopw.clkinfo.js","url":"clkinfo.js"} + ] +} diff --git a/typescript/types/clock_info.d.ts b/typescript/types/clock_info.d.ts index ce8c78d72..9b664a6dc 100644 --- a/typescript/types/clock_info.d.ts +++ b/typescript/types/clock_info.d.ts @@ -20,7 +20,7 @@ declare module ClockInfo { hasRange: true, get(): RangeItem, } | { - hasRange: false, + hasRange?: false, get(): Item, } ); diff --git a/typescript/types/main.d.ts b/typescript/types/main.d.ts index cd7b364a6..1505c6f5a 100644 --- a/typescript/types/main.d.ts +++ b/typescript/types/main.d.ts @@ -10096,11 +10096,11 @@ interface String { /** * * @param {number} start - The start character index, if negative it is from the end of the string - * @param {any} end - The end character index, if negative it is from the end of the string, and if omitted it is the end of the string + * @param {any} [end] - [optional] The end character index, if negative it is from the end of the string, and if omitted it is the end of the string * @returns {any} Part of this string from start for len characters * @url http://www.espruino.com/Reference#l_String_slice */ - slice(start: number, end: any): any; + slice(start: number, end?: any): any; /** * Return an array made by splitting this string up by the separator. e.g.