Skip to content

Commit 7c700b9

Browse files
committed
heavy rewrite because I realized setInterval is not accurate. Still needs alot of refactoring
1 parent dea18ed commit 7c700b9

File tree

6 files changed

+117
-103
lines changed

6 files changed

+117
-103
lines changed

app/index.js

Lines changed: 106 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
/*
2-
* Entry point for the watch app
2+
* Terminology:
3+
* 1 Session is made up for 4 Sets
4+
* 1 Set is made up of 2 Sprints
5+
* Each Sprint is either a Flow Sprint of a Break Sprint
36
*/
47
import document from "document";
58
import * as messaging from "messaging";
@@ -11,33 +14,35 @@ clock.granularity = "minutes";
1114
import { preferences } from "user-settings";
1215
import { vibration } from "haptics";
1316
import { style, stopStyle } from "./style.js"
17+
import { format } from "path";
1418

1519
//grab screen elements
1620
const time = document.getElementById("time");
1721
const progressArc = document.getElementById("progressArc");
18-
const countdown = document.getElementById("countdown");
19-
const sprintCounter = document.getElementById("sprintCounter");
20-
const currentIntervalText = document.getElementById("currentIntervalText");
22+
const countdownText = document.getElementById("countdown");
23+
const setCounter = document.getElementById("setCounter");
24+
const currentSprintText = document.getElementById("currentSprintText");
2125
const playPauseButton = document.getElementById("playPauseButton");
2226
const playPauseIcon = playPauseButton.getElementById("combo-button-icon");
2327
const playPauseIconPressed = playPauseButton.getElementById("combo-button-icon-press");
2428
const restartSkipButton = document.getElementById("restartSkipButton");
2529
const restartSkipIcon = restartSkipButton.getElementById("combo-button-icon");
2630

27-
2831
//Default these incase they haven't setup custom times on mobile app
29-
const totalFlowInSeconds = 1500;
32+
const totalFlowInSeconds = 5;//1500;
3033
const totalShortBreakInSeconds = 10;//300;
3134
const totalLongBreakInSeconds = 15;//900;
32-
const totalSprints = 4;
35+
const totalSets = 4;
3336
const flowText = "Flow";
3437
const breakText = "Break";
3538

36-
let counting = false;
37-
let countdownSeconds = totalFlowInSeconds;
39+
let paused = true;
3840
let flow = true; //used to toggle between flow intervals and breaks
39-
let currentIntervalTime;
40-
let currentSprint = 1;
41+
let currentSprintTotalTime;
42+
let currentSet = 1;
43+
let deadlineInSeconds;
44+
let timeLeft = totalFlowInSeconds;
45+
var countdown;
4146

4247
//setup clock
4348
clock.ontick = (evt) => {
@@ -52,31 +57,27 @@ clock.ontick = (evt) => {
5257
}
5358

5459
setupWithUserSettings();
55-
style(display);
56-
//clock.tick does not run in background so use setInterval instead
57-
setInterval(() => progress(), 1000)
60+
style();
61+
progress();
62+
5863
playPauseButton.onactivate = (evt) => {
59-
counting ? pause() : play();
64+
paused ? play() : pause();
6065
}
61-
6266
restartSkipButton.onactivate = (evt) => {
63-
counting ? restart() : skip();
67+
paused ? skip() : restart();
6468
}
65-
6669
display.onchange = () => { // optimize battery life
6770
display.on ? style() : stopStyle();
6871
}
69-
7072
messaging.peerSocket.onmessage = (evt)=>{
7173
//persist
7274
writeToFile(evt.data, "flowSettings.txt");
7375
setupWithUserSettings();
7476
}
75-
7677
me.onunload = () => {
7778
//save data on exit
7879
let text = flow ? flowText : breakText;
79-
writeToFile({closeTime: Date.now(), timeLeft: countdownSeconds, text: text, state: currentIntervalTime, flow: flow, sprint: currentSprint, counting: counting},"saveState.txt");
80+
writeToFile({deadlineInSeconds: deadlineInSeconds, timeLeft: timeLeft, state: currentSprintTotalTime, flow: flow, set: currentSet, paused: paused}, "saveState.txt");
8081
}
8182

8283

@@ -92,26 +93,27 @@ function writeToFile(data, fileName){
9293

9394
function secondsToAngle(seconds){
9495
//degree per second * elapsedseconds
95-
return (360/currentIntervalTime) * seconds;
96+
return (360/currentSprintTotalTime) * seconds;
9697
}
9798

9899
function progress(){
99-
if (counting){
100-
if( !isSprintOver(countdownSeconds) ) {
101-
countdownSeconds--;
102-
}
100+
if( !isSprintOver(deadlineInSeconds) ) {
101+
let t = calculateRemainingTimeInSeconds(deadlineInSeconds);
103102
if (display.on) {
103+
formatCountdown(t);
104104
//calculate and update angle
105-
progressArc.sweepAngle = secondsToAngle(currentIntervalTime - countdownSeconds);
105+
progressArc.sweepAngle = secondsToAngle(currentSprintTotalTime - t);
106106
}
107107
}
108-
if (display.on) {
109-
formatCountdown(countdownSeconds);
110-
}
111108
}
112109

113-
function isSprintOver(seconds){
114-
if(seconds === 0){
110+
function calculateRemainingTimeInSeconds(deadlineInSeconds){
111+
let t = deadlineInSeconds - (Date.now()/1000);
112+
return t;
113+
}
114+
115+
function isSprintOver(deadlineInSeconds){
116+
if(Date.now()/1000 >= deadlineInSeconds){
115117
pause();
116118
nextSprint();
117119
return true;
@@ -124,25 +126,69 @@ function nextSprint(){
124126
flow = !flow;
125127

126128
if (flow){
127-
currentSprint < totalSprints ? currentSprint++ : currentSprint = 1;
128-
setupNextInterval(totalFlowInSeconds, totalFlowInSeconds, flowText, 0, currentSprint);
129+
currentSet < totalSets ? currentSet++ : currentSet = 1;
130+
setupSprint(totalFlowInSeconds, totalFlowInSeconds, flowText, 0, (Date.now()/1000) + totalFlowInSeconds);
129131

130132
}
131133
else {
132-
if(currentSprint < totalSprints){
133-
setupNextInterval(totalShortBreakInSeconds, totalShortBreakInSeconds, breakText, 0, currentSprint);
134+
if(currentSet < totalSets){
135+
setupSprint(totalShortBreakInSeconds, totalShortBreakInSeconds, breakText, 0, (Date.now()/1000) + totalShortBreakInSeconds);
134136
}
135137
else{
136-
setupNextInterval(totalLongBreakInSeconds, totalLongBreakInSeconds, breakText, 0, currentSprint);
138+
setupSprint(totalLongBreakInSeconds, totalLongBreakInSeconds, breakText, 0, (Date.now()/1000) + totalLongBreakInSeconds);
137139
}
138140
}
139141

140142
vibration.start("nudge");
141143
}
142144

145+
function setupSprint(sprintTotalTime, left, text, angleLeft, deadline){
146+
progressArc.sweepAngle = angleLeft;
147+
currentSprintText.text = text;
148+
149+
currentSprintTotalTime = sprintTotalTime;
150+
timeLeft = left;
151+
deadlineInSeconds = deadline;
152+
153+
formatCountdown(timeLeft);
154+
setCounter.text = `${currentSet} of ${totalSets}`;
155+
}
156+
157+
function play(){
158+
paused = false;
159+
deadlineInSeconds = (Date.now()/1000) + timeLeft;
160+
timeLeft = 0;
161+
playPauseIcon.image = "pause.png";
162+
playPauseIconPressed.image = "pause_press.png";
163+
restartSkipIcon.image = "reset.png";
164+
//clock.tick does not run in background so use setInterval instead
165+
countdown = setInterval(() => progress(), 1000);
166+
}
167+
168+
function pause(){
169+
paused = true;
170+
//stop the clock
171+
clearInterval(countdown);
172+
timeLeft = calculateRemainingTimeInSeconds(deadlineInSeconds);
173+
playPauseIcon.image = "play.png";
174+
playPauseIconPressed.image = "play_press.png";
175+
restartSkipIcon.image = "skip.png";
176+
}
177+
178+
function skip(){
179+
pause();
180+
timeLeft = 0;
181+
nextSprint();
182+
}
183+
184+
function restart(){
185+
pause();
186+
setupSprint(currentSprintTotalTime, currentSprintTotalTime, flow ? flowText : breakText, 0, (Date.now()/1000) + currentSprintTotalTime);
187+
}
188+
143189
function setupWithUserSettings(){
144190
let settings;
145-
try {
191+
try { //read settings about time intervals
146192
settings = fs.readFileSync("flowSettings.txt", "cbor");
147193
}
148194
catch(err){
@@ -155,67 +201,35 @@ function setupWithUserSettings(){
155201
totalLongBreakInSeconds = settings.longBreakTime == 0 ? totalLongBreakInSeconds : parseInt(settings.longBreakTime)*60;
156202

157203
//pick up where the user ended
158-
try {
159-
//{closeTime: Date.now(), timeLeft: countdownSeconds, text: text, state: currentIntervalTime, sprint: currentSprint, counting: counting}
160-
let saveState = fs.readFileSync("saveState.txt", "cbor");
161-
//secondsLeft when app closed - seconds passed since exit
162-
let secondsLeft = saveState.timeLeft - ((Date.now() - parseInt(saveState.closeTime))/1000);
163-
secondsLeft <= 0 ? 0 : Math.ceil(secondsLeft);
164-
countdownSeconds = secondsLeft;
165-
flow = saveState.flow;
166-
currentIntervalTime = saveState.state;
167-
currentSprint = saveState.sprint;
168-
if (secondsLeft <= 0){
169-
pause();
170-
nextSprint();
171-
}
172-
else{
173-
saveState.counting ? play() : pause();
174-
setupNextInterval(currentIntervalTime, countdownSeconds, saveState.text, secondsToAngle(currentIntervalTime - countdownSeconds), currentSprint);
175-
}
204+
try { //read settings about past states
205+
restorePreviousSession(fs.readFileSync("saveState.txt", "cbor"));
176206
}
177207
catch (err) {
178208
console.log(err);
179-
setupNextInterval(totalFlowInSeconds, totalFlowInSeconds, flowText, 0, currentSprint);
209+
setupSprint(totalFlowInSeconds, totalFlowInSeconds, flowText, 0, (Date.now()/1000) + totalFlowInSeconds);
180210
}
181211
}
182212

183-
function setupNextInterval(nextIntervalSeconds, secondsLeft, text, angleLeft, currentSprint){
184-
//change the arc back to 0
185-
progressArc.sweepAngle = angleLeft;
186-
//update interval text
187-
currentIntervalText.text = text;
188-
//set the correct seconds for progress
189-
currentIntervalTime = nextIntervalSeconds;
190-
countdownSeconds = secondsLeft;
191-
currentIntervalText.text = text;
192-
sprintCounter.text = `${currentSprint} of ${totalSprints}`;
193-
}
213+
function restorePreviousSession(saveState){
214+
timeLeft = calculateRemainingTimeInSeconds(saveState.deadlineInSeconds);
194215

195-
function play(){
196-
counting = true;
197-
playPauseIcon.image = "pause.png";
198-
playPauseIconPressed.image = "pause_press.png";
199-
200-
restartSkipIcon.image = "reset.png";
201-
}
216+
//set state variables
217+
deadlineInSeconds = saveState.deadlineInSeconds;
202218

203-
function pause(){
204-
counting = false;
205-
playPauseIcon.image = "play.png";
206-
playPauseIconPressed.image = "play_press.png";
207-
208-
restartSkipIcon.image = "skip.png";
209-
}
210219

211-
function skip(){
212-
counting = false;
213-
nextSprint();
214-
}
215-
216-
function restart(){
217-
pause();
218-
setupNextInterval(currentIntervalTime, currentIntervalTime, flow ? flowText : breakText, 0, currentSprint);
220+
flow = saveState.flow;
221+
currentSprintTotalTime = saveState.state;
222+
currentSet = saveState.set;
223+
224+
let text = flow ? flowText : breakText;
225+
deadlineInSeconds = saveState.paused ? (Date.now()/1000) + saveState.timeLeft : saveState.deadlineInSeconds;
226+
saveState.paused ? pause() : play();
227+
if ( deadlineInSeconds >= (Date.now()/1000) || saveState.paused){
228+
setupSprint(currentSprintTotalTime, timeLeft, text, secondsToAngle(currentSprintTotalTime - deadlineInSeconds), deadlineInSeconds);
229+
}
230+
else{ //finished sprint while our of app, so move to the next
231+
skip();
232+
}
219233
}
220234

221235
function formatCountdown(seconds){
@@ -230,5 +244,5 @@ function formatCountdown(seconds){
230244
formattedSeconds = formattedSeconds < 10 ? "0" + formattedSeconds : formattedSeconds;
231245

232246
//update countdown text
233-
countdown.text = `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
234-
}
247+
countdownText.text = `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
248+
}

app/style.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@ import document from "document";
44

55
//grab screen elements
66
const background = document.getElementById("background");
7-
const backgroundColor = document.getElementsByClassName("backgroundColor")
7+
const backgroundColor = document.getElementsByClassName("backgroundColor");
88
const progressArc = document.getElementById("progressArc");
99
const backgroundArc = document.getElementById("backgroundArc");
1010
const countdown = document.getElementById("countdown");
11-
const sprintCounter = document.getElementById("sprintCounter");
11+
const setCounter = document.getElementById("setCounter");
1212
const playPauseButton = document.getElementById("playPauseButton");
1313
const restartSkipButton = document.getElementById("restartSkipButton");
1414
const oldBackground = background.value;
@@ -39,7 +39,7 @@ function applyStyle(value){
3939
countdown.style.fill = colorProfile.accentColor;
4040
playPauseButton.style.fill = colorProfile.accentColor;
4141
restartSkipButton.style.fill = colorProfile.accentColor;
42-
sprintCounter.style.fill = colorProfile.baseColor;
42+
setCounter.style.fill = colorProfile.baseColor;
4343
}
4444

4545
const styleProfiles = [

resources/index~300x300.gui

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@
3939
<arc id="backgroundArc" class="backgroundArcColor" x="30" y="30" height="240" width="240" arc-width="20" start-angle="0" sweep-angle="360"/>
4040
<arc id="progressArc" class="accentColor" x="30" y="30" height="240" width="240" arc-width="20" start-angle="0" sweep-angle="0"/>
4141

42-
<text id="currentIntervalText" class="baseColor" x="150" y="100">Flow</text>
42+
<text id="currentSprintText" class="baseColor" x="150" y="100">Flow</text>
4343
<text id="countdown" class="accentColor" x="150" y="160">00:00:00</text>
44-
<text id="sprintCounter" class="baseColor" x="150" y="210">1 of 4</text>
44+
<text id="setCounter" class="baseColor" x="150" y="210">1 of 4</text>
4545

4646
<use id="playPauseButton" class="accentColor" href="#combo-button-lower-right">
4747
<set href="combo-button-icon" attributeName="href" to="play.png"/>

resources/index~348x250.gui

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,9 @@
4141
<arc id="backgroundArc" class="backgroundArcColor" x="64" y="23" height="220" width="220" arc-width="20" start-angle="0" sweep-angle="360"/>
4242
<arc id="progressArc" class="accentColor" x="64" y="23" height="220" width="220" arc-width="20" start-angle="0" sweep-angle="0"/>
4343

44-
<text id="currentIntervalText" class="baseColor" x="174" y="93">Flow</text>
44+
<text id="currentSprintText" class="baseColor" x="174" y="93">Flow</text>
4545
<text id="countdown" class="accentColor" x="174" y="143">00:00:00</text>
46-
<text id="sprintCounter" class="baseColor" x="174" y="183">1 of 4</text>
46+
<text id="setCounter" class="baseColor" x="174" y="183">1 of 4</text>
4747

4848
<use id="playPauseButton" class="accentColor" href="#combo-button-lower-right">
4949
<set href="combo-button-icon" attributeName="href" to="play.png"/>

resources/styles~300x300.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@
2121
text-length: "12";
2222
}
2323

24-
#sprintCounter{
24+
#setCounter{
2525
font-family: "System-Regular";
2626
font-size: "30";
2727
text-anchor: "middle";
2828
}
2929

30-
#currentIntervalText{
30+
#currentSprintText{
3131
font-family: "System-Regular";
3232
font-size: "30";
3333
text-anchor: "middle";

resources/styles~348x250.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@
2121
text-length: "12";
2222
}
2323

24-
#sprintCounter{
24+
#setCounter{
2525
font-family: "System-Regular";
2626
font-size: "30";
2727
text-anchor: "middle";
2828
}
2929

30-
#currentIntervalText{
30+
#currentSprintText{
3131
font-family: "System-Regular";
3232
font-size: "30";
3333
text-anchor: "middle";

0 commit comments

Comments
 (0)