define(['sugar-web/activity/activity', 'webL10n', 'activity/progress', 'activity/stopwatch', 'sugar-web/env'], function (activity, l10n, Progress, Stopwatch, env) {
|
|
|
|
// Manipulate the DOM only when it is ready.
|
|
requirejs(['domReady!'], function (doc) {
|
|
|
|
// Initialize the activity.
|
|
activity.setup();
|
|
env.getEnvironment(function(err, environment) {
|
|
currentenv = environment;
|
|
var defaultLanguage = (typeof chrome != 'undefined' && chrome.app && chrome.app.runtime) ? chrome.i18n.getUILanguage() : navigator.language;
|
|
var language = environment.user ? environment.user.language : defaultLanguage;
|
|
l10n.language.code = language;
|
|
var datastore = activity.getDatastoreObject();
|
|
main(Progress, Stopwatch, l10n, currentenv.user.colorvalue, datastore);
|
|
});
|
|
});
|
|
});
|
|
|
|
function convertReadableMS(timeInMs) {
|
|
var parsedTime = parseMs(timeInMs);
|
|
var timeStr = parsedTime.hours ? parsedTime.hours + parsedTime.days * 24 + ':' + parsedTime.minutes + ':' + parsedTime.seconds : parsedTime.minutes + ':' + parsedTime.seconds;
|
|
return timeStr.split(':').map(function (num) {
|
|
return ('' + num).padStart(2, '0');
|
|
}).join(':');
|
|
}
|
|
|
|
var defaultWorkTimerLimit = 1;
|
|
var defaultBreakTimerLimit = 1;
|
|
function main(Progress, Stopwatch, l10n, color, datastore) {
|
|
var _this = this;
|
|
this.state = {
|
|
status: 'work',
|
|
workTimerLimit: defaultWorkTimerLimit,
|
|
breakTimerLimit: defaultBreakTimerLimit,
|
|
progress: 1,
|
|
currentWorkText: convertReadableMS(defaultWorkTimerLimit * 1000 * 60),
|
|
currentBreakText: convertReadableMS(defaultBreakTimerLimit * 1000 * 60),
|
|
themeColor: '#FF0060',
|
|
isButtonsDisable: false,
|
|
timerLeftAt: false,
|
|
progressLeftAt: false
|
|
};
|
|
datastore.loadAsText(function (err, metadata, data) {
|
|
if (err) console.error(err)
|
|
if (data) {
|
|
_this.state = data.state;
|
|
}
|
|
enableButtons()
|
|
afterDataLoad()
|
|
});
|
|
// this.state.progress = 1
|
|
function afterDataLoad() {
|
|
this.state.status === 'work'
|
|
? startWork()
|
|
: startBreak();
|
|
|
|
renderPomodoroText();
|
|
renderStatusText(l10n.get(this.state.status));
|
|
var pomodoroContainer = document.getElementById('pomodoro-container');
|
|
this.pomodoro = new Progress(280, color.stroke, this.state.progress, pomodoroContainer);
|
|
this.pomodoro.draw();
|
|
this.state.status === 'work'
|
|
? renderTheme(color.stroke)
|
|
: renderTheme(color.fill);
|
|
}
|
|
|
|
function mapRange(obj, num) {
|
|
return (num - obj.from[0]) * (obj.to[1] - obj.to[0]) / (obj.from[1] - obj.from[0]) + obj.to[0];
|
|
}
|
|
|
|
function parseMs(ms) {
|
|
if (typeof ms !== 'number') {
|
|
throw new TypeError('Expected a number');
|
|
}
|
|
|
|
var roundTowardZero = ms > 0 ? Math.floor : Math.ceil;
|
|
|
|
return {
|
|
days: roundTowardZero(ms / 86400000),
|
|
hours: roundTowardZero(ms / 3600000) % 24,
|
|
minutes: roundTowardZero(ms / 60000) % 60,
|
|
seconds: roundTowardZero(ms / 1000) % 60,
|
|
milliseconds: roundTowardZero(ms) % 1000
|
|
};
|
|
}
|
|
|
|
function saveInDataStore() {
|
|
datastore.setDataAsText({
|
|
state: this.state
|
|
});
|
|
datastore.save(function (err) {
|
|
if (err) {
|
|
console.errror(err);
|
|
}
|
|
});
|
|
}
|
|
|
|
function convertReadableMS(timeInMs) {
|
|
var parsedTime = parseMs(timeInMs);
|
|
var timeStr = parsedTime.hours
|
|
? parsedTime.hours + parsedTime.days * 24 + ':' + parsedTime.minutes + ':' + parsedTime.seconds
|
|
: parsedTime.minutes + ':' + parsedTime.seconds;
|
|
return timeStr.split(':').map(function (num) {
|
|
return ('' + num).padStart(2, '0');
|
|
}).join(':');
|
|
}
|
|
|
|
this.handlePausePlay = function () {
|
|
var playPauseButton = document.getElementById('play-button');
|
|
if (this.state.status === 'work') {
|
|
if (this.workTimer.state === 1) {
|
|
//if timer is running
|
|
this.workTimer.stop();
|
|
enableButtons();
|
|
playPauseButton.classList.remove('pause');
|
|
playPauseButton.classList.add('play');
|
|
} else {
|
|
this.workTimer.start();
|
|
disableButtons();
|
|
playPauseButton.classList.remove('play');
|
|
playPauseButton.classList.add('pause');
|
|
}
|
|
} else {
|
|
if (this.breakTimer.state === 1) {
|
|
this.breakTimer.stop();
|
|
enableButtons();
|
|
playPauseButton.classList.remove('pause');
|
|
playPauseButton.classList.add('play');
|
|
} else {
|
|
disableButtons();
|
|
this.breakTimer.start();
|
|
playPauseButton.classList.remove('play');
|
|
playPauseButton.classList.add('pause');
|
|
}
|
|
}
|
|
};
|
|
|
|
function startWork() {
|
|
var _this2 = this;
|
|
|
|
var timerInMS = (this.state.timerLeftAt === false)
|
|
? (this.state.workTimerLimit * 60 * 1000)
|
|
: this.state.timerLeftAt
|
|
|
|
this.workTimer = new Stopwatch(timerInMS);
|
|
this.state.status = 'work';
|
|
const progressToStart = (this.state.progressLeftAt === false)
|
|
? 1
|
|
: this.state.progressLeftAt
|
|
this.workTimer.onTime(function (time) {
|
|
var progress = mapRange({
|
|
from: [timerInMS, 0],
|
|
to: [progressToStart, 0]
|
|
}, time.ms);
|
|
setProgress(progress, time.ms);
|
|
saveInDataStore()
|
|
});
|
|
this.workTimer.onDone(function () {
|
|
renderTheme(color.fill);
|
|
setTimeout(function () {
|
|
this.state.timerLeftAt = false
|
|
this.state.progressLeftAt = false
|
|
renderStatusText(l10n.get('break'));
|
|
startBreak();
|
|
_this2.breakTimer.start();
|
|
}, 1000);
|
|
});
|
|
}
|
|
|
|
function startBreak() {
|
|
var _this3 = this;
|
|
|
|
var timerInMS = (this.state.timerLeftAt === false)
|
|
? this.state.breakTimerLimit * 60 * 1000
|
|
: this.state.timerLeftAt
|
|
this.breakTimer = new Stopwatch(timerInMS);
|
|
this.state.status = 'break';
|
|
|
|
const progressToStart = (this.state.progressLeftAt === false)
|
|
? 1
|
|
: this.state.progressLeftAt
|
|
this.breakTimer.onTime(function (time) {
|
|
var progress = mapRange({
|
|
from: [timerInMS, 0],
|
|
to: [progressToStart, 0]
|
|
}, time.ms);
|
|
setProgress(progress, time.ms);
|
|
saveInDataStore()
|
|
});
|
|
this.breakTimer.onDone(function () {
|
|
renderTheme(color.stroke);
|
|
setTimeout(function () {
|
|
this.state.timerLeftAt = false
|
|
this.state.progressLeftAt = false
|
|
renderStatusText(l10n.get('work'));
|
|
startWork();
|
|
_this3.workTimer.start();
|
|
}, 1000);
|
|
});
|
|
}
|
|
|
|
function renderStatusText(text) {
|
|
document.querySelector('.status').innerText = text;
|
|
}
|
|
|
|
function setProgress(progress, currentTimeMS) {
|
|
this.state.progress = progress;
|
|
if (this.state.status === 'work') {
|
|
this.state.currentWorkText = convertReadableMS(currentTimeMS);
|
|
} else {
|
|
this.state.currentBreakText = convertReadableMS(currentTimeMS);
|
|
}
|
|
this.state.timerLeftAt = currentTimeMS
|
|
this.state.progressLeftAt = progress
|
|
renderPomodoro();
|
|
renderPomodoroText();
|
|
}
|
|
|
|
function renderPomodoro() {
|
|
this.pomodoro.update(this.state.progress);
|
|
}
|
|
|
|
function renderPomodoroText() {
|
|
var timerTextElem = document.querySelector('.info-circle span');
|
|
if (this.state.status === 'work') {
|
|
timerTextElem.innerText = this.state.currentWorkText;
|
|
} else {
|
|
timerTextElem.innerText = this.state.currentBreakText;
|
|
}
|
|
}
|
|
|
|
function renderTheme(themeColor) {
|
|
this.state.themeColor = themeColor;
|
|
document.querySelector('.info-circle').style.backgroundColor = themeColor;
|
|
document.querySelector('.base-circle').style.backgroundColor = themeColor + '2b';
|
|
this.pomodoro.updateColor(themeColor, this.state.progress);
|
|
renderButtons();
|
|
}
|
|
|
|
function renderButtons() {
|
|
var _this4 = this;
|
|
|
|
document.querySelectorAll('.button').forEach(function (elem) {
|
|
elem.style.background = _this4.state.themeColor;
|
|
});
|
|
|
|
document.querySelectorAll('.button-label, .button-time').forEach(function (elem) {
|
|
elem.style.color = _this4.state.themeColor;
|
|
});
|
|
}
|
|
|
|
function disableButtons() {
|
|
this.state.isButtonsDisable = true;
|
|
document.querySelectorAll('.button, .button-time, .button-label').forEach(function (elem) {
|
|
elem.classList.add('disable');
|
|
});
|
|
}
|
|
function enableButtons() {
|
|
this.state.isButtonsDisable = false;
|
|
document.querySelectorAll('.button, .button-time, .button-label').forEach(function (elem) {
|
|
elem.classList.remove('disable');
|
|
});
|
|
}
|
|
|
|
function updateWorkPomodoro() {
|
|
this.state.currentWorkText = convertReadableMS(this.state.workTimerLimit * 60 * 1000);
|
|
document.querySelector('.button-time.work').innerText = this.state.workTimerLimit;
|
|
this.pomodoro.update(1);
|
|
renderPomodoroText();
|
|
if (this.state.status === 'work') {
|
|
startWork();
|
|
}
|
|
}
|
|
|
|
function updateBreakPomodoro() {
|
|
this.state.currentBreakText = convertReadableMS(this.state.breakTimerLimit * 60 * 1000);
|
|
document.querySelector('.button-time.break').innerText = this.state.breakTimerLimit;
|
|
renderPomodoroText();
|
|
if (this.state.status === 'break') {
|
|
startBreak();
|
|
}
|
|
}
|
|
|
|
this.handleWorkPlusClick = function () {
|
|
if (!this.state.isButtonsDisable) {
|
|
this.state.workTimerLimit = this.state.workTimerLimit + 1;
|
|
resetTimer()
|
|
updateWorkPomodoro();
|
|
saveInDataStore()
|
|
}
|
|
};
|
|
|
|
this.handleWorkMinusClick = function () {
|
|
if (!this.state.isButtonsDisable && this.state.workTimerLimit > 1) {
|
|
this.state.workTimerLimit = this.state.workTimerLimit - 1;
|
|
resetTimer()
|
|
updateWorkPomodoro();
|
|
saveInDataStore()
|
|
}
|
|
};
|
|
|
|
this.handleBreakPlusClick = function () {
|
|
if (!this.state.isButtonsDisable) {
|
|
this.state.breakTimerLimit = this.state.breakTimerLimit + 1;
|
|
resetTimer()
|
|
updateBreakPomodoro();
|
|
saveInDataStore()
|
|
}
|
|
};
|
|
|
|
this.handleBreakMinusClick = function () {
|
|
if (!this.state.isButtonsDisable && this.state.breakTimerLimit > 1) {
|
|
this.state.breakTimerLimit = this.state.breakTimerLimit - 1;
|
|
resetTimer()
|
|
updateBreakPomodoro();
|
|
saveInDataStore()
|
|
}
|
|
};
|
|
|
|
function resetTimer() {
|
|
setProgress(1, this.state.workTimerLimit * 60 * 1000)
|
|
this.state.timerLeftAt = false
|
|
this.state.progressLeftAt = false
|
|
}
|
|
|
|
function initTimerText() {
|
|
document.querySelector('.button-time.work').innerText = this.state.workTimerLimit;
|
|
document.querySelector('.button-time.break').innerText = this.state.breakTimerLimit;
|
|
}
|
|
|
|
initTimerText();
|
|
document.querySelector('.plus-button.work').addEventListener('click', handleWorkPlusClick.bind(this));
|
|
document.querySelector('.minus-button.work').addEventListener('click', handleWorkMinusClick.bind(this));
|
|
document.querySelector('.plus-button.break').addEventListener('click', handleBreakPlusClick.bind(this));
|
|
document.querySelector('.minus-button.break').addEventListener('click', handleBreakMinusClick.bind(this));
|
|
document.querySelector('#play-button').addEventListener('click', function () {
|
|
_this.handlePausePlay();
|
|
});
|
|
document.querySelector('#replay-button').addEventListener('click', function () {
|
|
var shouldPlay
|
|
if (_this.workTimer && _this.breakTimer) {
|
|
shouldPlay = _this.workTimer.state === 1 || _this.breakTimer.state === 1
|
|
} else if (_this.workTimer) {
|
|
shouldPlay = _this.workTimer.state === 1
|
|
} else {
|
|
shouldPlay = _this.breakTimer.state === 1
|
|
}
|
|
|
|
if (shouldPlay) {
|
|
this.handlePausePlay()
|
|
}
|
|
resetTimer()
|
|
startWork()
|
|
if (_this.breakTimer) {
|
|
_this.breakTimer.stop();
|
|
}
|
|
renderTheme(color.stroke)
|
|
renderStatusText(l10n.get('work'));
|
|
_this.pomodoro.update(1)
|
|
}.bind(this));
|
|
}
|