diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1af2cc7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Aaron Tan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..a024837 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Fitbit Pomodoro +A Pomodoro app for the Fitbit Ionic. diff --git a/app/index.js b/app/index.js new file mode 100644 index 0000000..655e69f --- /dev/null +++ b/app/index.js @@ -0,0 +1,101 @@ +'use strict'; + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var document = _interopDefault(require('document')); +var haptics = require('haptics'); + +var backgroundRect = document.getElementById("backgroundRect"); +var backgroundRectResting = document.getElementById("backgroundRectResting"); +var backgroundRectLongResting = document.getElementById("backgroundRectLongResting"); + +var btnBR = document.getElementById("btn-br"); +var stateText = document.getElementById("stateText"); +var minuteText = document.getElementById("minuteText"); +var unitText = document.getElementById("unitText"); +var times = 0; + +btnBR.onactivate = function (evt) { + btnBR.style.display = "none"; + haptics.vibration.start("confirmation"); + minuteText.text = "24:59"; + unitText.style.display = "none"; + backgroundRect.animate("disable"); + setTimeout(function() { + startWorkTimer(times); + }, 300); +}; + +function startWorkTimer(times) { + stateText.text = "Get to work!"; + backgroundRect.animate("enable"); + var end = new Date(new Date().getTime() + 25 * 60000); + minuteText.text = "24:59"; + var timer = setInterval(function () { + var now = new Date().getTime(); + var distance = end - now; + var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); + var seconds = Math.floor((distance % (1000 * 60)) / 1000); + minutes = (minutes < 10) ? ("0" + minutes) : minutes; + seconds = (seconds < 10) ? ("0" + seconds) : seconds; + minuteText.text = minutes + ":" + seconds; + if (distance < 1) { + clearInterval(timer); + haptics.vibration.start("ping"); + backgroundRect.animate("disable"); + times++; + if (times < 2) { + backgroundRectResting.animate("enable"); + startShortBreakTimer(times); + } else { + times = 0; + backgroundRectLongResting.animate("enable"); + startLongBreakTimer(times); + } + } + }, 1000); +}; + +function startShortBreakTimer(times) { + stateText.text = "Take a short break"; + var end = new Date(new Date().getTime() + 5 * 60000); + minuteText.text = "04:59"; + var timer = setInterval(function () { + var now = new Date().getTime(); + var distance = end - now; + var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); + var seconds = Math.floor((distance % (1000 * 60)) / 1000); + minutes = (minutes < 10) ? ("0" + minutes) : minutes; + seconds = (seconds < 10) ? ("0" + seconds) : seconds; + minuteText.text = minutes + ":" + seconds; + if (distance < 1) { + clearInterval(timer); + haptics.vibration.start("ping"); + backgroundRectResting.animate("disable"); + backgroundRect.animate("enable"); + startWorkTimer(times); + } + }, 1000); +} + +function startLongBreakTimer(times) { + stateText.text = "Take a long break"; + var end = new Date(new Date().getTime() + 15 * 60000); + minuteText.text = "14:59"; + var timer = setInterval(function () { + var now = new Date().getTime(); + var distance = end - now; + var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); + var seconds = Math.floor((distance % (1000 * 60)) / 1000); + minutes = (minutes < 10) ? ("0" + minutes) : minutes; + seconds = (seconds < 10) ? ("0" + seconds) : seconds; + minuteText.text = minutes + ":" + seconds; + if (distance < 1) { + clearInterval(timer); + haptics.vibration.start("ping"); + backgroundRectLongResting.animate("disable"); + backgroundRect.animate("enable"); + startWorkTimer(times); + } + }, 1000); +} \ No newline at end of file diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..364ce85 --- /dev/null +++ b/manifest.json @@ -0,0 +1 @@ +{"appManifestVersion":1,"main":"app/index.js","svgMain":"resources/index.gui","svgWidgets":"resources/widgets.gui","appType":"app","i18n":{"en":{"name":"Tomatina"}},"buildId":"0x0730781e263c063b","uuid":"4c0f5346-6d11-4494-a04f-731b152e6c1e","name":"Tomatina","bundleDate":"2018-01-09T22:46:27.359Z","requestedPermissions":[],"wipeColor":"#f44336"} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..cc7dda3 --- /dev/null +++ b/package.json @@ -0,0 +1,33 @@ +{ + "fitbit": { + "appUUID": "55d5be9a-1571-4987-b5e7-cda00dc7d56b", + "appType": "app", + "appDisplayName": "Tomatina", + "iconFile": "resources/icon.png", + "wipeColor": "#f44336", + "requestedPermissions": [], + "i18n": { + "en": { + "name": "Tomatina" + }, + "zh-cn": { + "name": "番茄工作计时器" + }, + "zh-tw": { + "name": "番茄工作計時器" + }, + "fr": { + "name": "Tomatina" + }, + "es": { + "name": "Tomatina" + }, + "ja": { + "name": "トマティーナ" + }, + "ko": { + "name": "토마티나" + } + } + } +} \ No newline at end of file diff --git a/resources/icon.png b/resources/icon.png new file mode 100644 index 0000000..2f22147 Binary files /dev/null and b/resources/icon.png differ diff --git a/resources/icon.svg b/resources/icon.svg new file mode 100644 index 0000000..ae76bc7 --- /dev/null +++ b/resources/icon.svg @@ -0,0 +1,144 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff --git a/resources/index.gui b/resources/index.gui new file mode 100644 index 0000000..416e639 --- /dev/null +++ b/resources/index.gui @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Start a Pomodoro + 25 + min + + + + + + + + + \ No newline at end of file diff --git a/resources/play.png.txi b/resources/play.png.txi new file mode 100644 index 0000000..58dc78e Binary files /dev/null and b/resources/play.png.txi differ diff --git a/resources/play_press.png.txi b/resources/play_press.png.txi new file mode 100644 index 0000000..6f747c8 Binary files /dev/null and b/resources/play_press.png.txi differ diff --git a/resources/styles.css b/resources/styles.css new file mode 100644 index 0000000..e318867 --- /dev/null +++ b/resources/styles.css @@ -0,0 +1,27 @@ +#backgroundRectResting { + display: inline; +} + +#backgroundRect { + display: inline; +} + +.minutesBigText { + fill: #FFFFFF; + font-family: Seville-Book; + font-size: 105; +} + +.stateText { + display: inline; + fill: #D3D3D3; + font-family: Seville-Book; + font-size: 35; +} + +.unitText { + display: inline; + fill: #C0C0C0; + font-family: Seville-Book; + font-size: 40; +} \ No newline at end of file diff --git a/resources/widgets.gui b/resources/widgets.gui new file mode 100644 index 0000000..ee90e99 --- /dev/null +++ b/resources/widgets.gui @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file