Commit 0199f7b2 authored by System Administrator's avatar System Administrator Committed by Vitaly Lipatov

Split common timer code into separate file

parent 6524623b
//Номер потока
var timeout_id = 0;
//Регистр нажатия на кнопку пауза/старт
var control_timer = 0;
//Разница времени для паузы
var diff_time_pause = 0;
//Время нажатия паузы
var time_pause = 0;
//Номер баги
var bug_id = getBugIdFromUrl() || getBugIdFromField();
var bugId = getIdFromUrl() || getBugIdFromField();
// Если id нет, то мы имеем дело с новой багой
if(!bugId) {
// Присвоим текущее время, чтобы при создании следующей баги значения не сохранились
bugId = 'c'+(new Date().getTime());
}
//Ключ для сохранения в storage (зависит от bug_id)
var storage_key = "bug:"+window.location.protocol+bug_id;
var protocol = window.location.protocol;
//Изменение баги
var changed_remain = 0;
......@@ -23,139 +15,52 @@ var changed_remain = 0;
//Создание баги
var etersoft_create = 0;
// Время начала работы над багом
var startTime;
// Объект таймера, создается при инициализации
// Подробнее про таймер см. timer_common.js
var timer;
// Время, когда таймер поставили на паузу
var pauseStartTime;
// Интервал обновления таймера в мс, на точность не влияет
var UPDATE_INTERVAL = 1000;
function initTimer(){
var storedValue = parseInt(getStorage(storage_key));
var storedPauseValue = parseInt(getStorage(storage_key+'p'));
if(storedValue){
startTime = storedValue;
if(storedPauseValue){
control_timer = 1;
pauseStartTime = storedPauseValue;
setPauseDisplay(true);
}
} else {
// Если сохраненного значения нет, то принимаем текущее время за начало работы
startTime = new Date().getTime();
// Запишем его
setStorage(storage_key, startTime);
}
updateTimer();
// Поставим обновление таймера каждую секунду
setInterval(updateTimer, 1000);
}
// Показываем время только сотрудникам Etersoft
if(!isetersoft()) return;
//Возращает прошедшее время в секундах с учетом пауз
// TODO: переименовать
function initStopwatch() {
if(control_timer){
return (pauseStartTime - startTime)/1000;
} else {
return (new Date() - startTime)/1000;
}
document.getElementById("timerblock").style.display = 'block';
timer = new Timer('bug:'+protocol+bugId, updateTimer);
timer.setAutoUpdate(UPDATE_INTERVAL);
}
function updateTimer() {
var mySecs = initStopwatch();
var myMinutes = Math.floor(mySecs/60);
var myHours = Math.floor(myMinutes/60);
var myMinutes1 = myMinutes - myHours*60;
var mySecs1 = parseInt(mySecs - myMinutes*60);
if (mySecs1 < 10) {
mySecs1 = "0"+mySecs1;
}
if (myMinutes1 < 10) {
myMinutes1 = "0"+myMinutes1;
}
if (myHours < 10) {
myHours = "0"+myHours;
}
document.querySelector("#timerblock #timespent").value = myHours + ":" + myMinutes1 + ":" + mySecs1;
// this при вызове - объект таймера
function updateTimer(){
setPauseDisplay(this.isPaused());
document.querySelector('#timespent').value = this.getFormattedString();
}
//Установка в поле отработанного времени в минутах
function setWorkTime(manualTime) {
var secs = initStopwatch();
var minutes = Math.ceil(secs/60);
var minutes = Math.ceil(timer.getElapsedSeconds()/60);
document.querySelector("#timeQuestionDiv #realworktime").value = (!manualTime) ? minutes : manualTime;
document.querySelector("#realworktime").value = manualTime ? manualTime : minutes;
}
function setPauseDisplay(pause){
document.querySelector("#timerblock #timespent").style.color = pause ? "gray" : "black";
document.querySelector("#timerblock #timer_pause").style.visibility = pause ? "hidden" : "visible";
document.querySelector("#timerblock #timer_play").style.visibility = pause ? "visible" : "hidden";
document.querySelector("#timespent").style.color = pause ? "gray" : "black";
document.querySelector("#timer_pause").style.visibility = pause ? "hidden" : "visible";
document.querySelector("#timer_play").style.visibility = pause ? "visible" : "hidden";
}
//Пауза/продолжить
function controlTimer() {
if (control_timer === 0) {
pauseStartTime = new Date().getTime();
setStorage(storage_key+'p', pauseStartTime);
control_timer = 1;
setPauseDisplay(true);
} else {
setStorage(storage_key+'p', 'unknown');
startTime += (new Date() - pauseStartTime);
setStorage(storage_key, startTime);
control_timer = 0;
setPauseDisplay(false);
}
}
//Сброс таймера
function resetTimer() {
setStorage(storage_key, new Date().getTime());
setStorage(storage_key+'p', control_timer ? new Date().getTime() : 'unknown');
pauseStartTime = startTime = new Date().getTime();
updateTimer();
}
/////////////////////////////////////////////////////
function showDiv(){
document.querySelector("#timeQuestionDiv").style.display = "block";
document.querySelector("#timeQuestionDiv #realworktime").focus();
document.querySelector("#realworktime").focus();
}
function closeDiv() {
document.querySelector("#timeQuestionDiv").style.display = "none";
}
function getStorage(key) {
if (window['sessionStorage'] != null) {
if (!sessionStorage.getItem(key)) {
return 0;
} else {
var data = sessionStorage.getItem(key);
return data;
}
} else {
return 0;
}
}
function setStorage(key, data) {
if (window['sessionStorage'] != null) {
try {
sessionStorage.setItem(key, data);
} catch(e) {
return false;
}
}
return false;
}
/* Получение номера баги из поля */
function getBugIdFromField() {
var field = document.querySelector("#changeform input[name=id]");
......@@ -165,29 +70,7 @@ function getBugIdFromField() {
return false;
}
/* Получение номера баги из урлу */
function getBugIdFromUrl() {
var get_id = window.location.search.split('id='); //номер баги (через URL)
if (get_id[1]) {
var id = get_id[1].split('&');
try {
return parseInt(id[0]);
} catch(e) {
return false;
}
}
return false;
}
////////////////////////////////////////////
//timer-splash
//Показываем прошедшее время только для сотрудников Etersoft
function istimer() {
if (isetersoft()) {
document.getElementById("timerblock").style.display = 'block';
}
}
//Является ли пользователь сотрудником Etersoft
function isetersoft() {
......@@ -242,6 +125,7 @@ function premysubmit(realworktime) {
}
document.querySelector("#Create #work_time").value = wt;
mysubmitnew();
timer.clear();
return;
}
......@@ -255,9 +139,9 @@ function premysubmit(realworktime) {
document.querySelector("#changeform #work_time").value = wt;
document.querySelector("#changeform #remaining_time").value = document.querySelector("#timeQuestionDiv #realremaintime").value;
}
setStorage(storage_key, 'unknown');
mysubmit();
timer.clear();
}
function mysubmit() {
......@@ -284,7 +168,7 @@ function mysubmit() {
function mysubmitnew() {
if (document.querySelector("#Create #work_time").value > 0 || !isetersoft()) {
document.Create.submit();
setStorage(storage_key, 'unknown');
timer.reset();
return;
}
etersoft_create = 1;
......@@ -293,7 +177,6 @@ function mysubmitnew() {
}
//////////////////////////////////////////////////////////////
window.setTimeout('istimer()', 500);
if (typeof (window.addEventListener) != 'undefined') {
//gecko, safari, konqueror and standard
......
// В этом файле содержится общий код таймера, который можно применять в любом месте.
// Код не привязан к DOM и реализует общий алгоритм работы таймера.
// Для обновления DOM в каждом случае будет разный код.
// Для получения значений таймера см. список методов объекта.
// Свойства, имена которых начинаются с подчеркивания, являются служебными и
// не должны использоваться как API.
// Получаем GET-параметр id из адресной строки.
// Если параметра нет, или он не является числом, то возвращаем undefined.
function getIdFromUrl(){
var id = window.location.search.split('id=');
if (id[1]) {
id = id[1].split('&');
id = parseInt(id[0]);
return isNaN(id) ? undefined : id;
}
return undefined;
}
// Конструктор таймера
// id - некий уникальный идентификатор, например, номер баги или тикета
// onUpdate - функция, вызываемая при обновлении таймера. Опциональна.
function Timer(id, onUpdate){
this._storageKey = id;
this.onUpdate = onUpdate;
var storedValue = parseInt(Timer.storage.get(this._storageKey));
var storedPauseValue = parseInt(Timer.storage.get(this._storageKey + Timer.PAUSE_SUFFIX));
var startTime, pauseStartTime;
// Определяем геттеры/сеттеры, чтобы при записи свойства автоматически обновлялся storage
Object.defineProperty(this, '_startTime', {
get: function(){
return startTime;
},
set: function(value){
startTime = value;
if(value === null){
Timer.storage.remove(this._storageKey);
} else {
Timer.storage.set(this._storageKey, value);
}
}
});
Object.defineProperty(this, '_pauseStartTime', {
get: function(){
return pauseStartTime;
},
set: function(value){
pauseStartTime = value;
if(value === null){
Timer.storage.remove(this._storageKey + Timer.PAUSE_SUFFIX);
} else {
Timer.storage.set(this._storageKey + Timer.PAUSE_SUFFIX, value);
}
}
});
// Если есть сохраненные значения, то используем их
if(!isNaN(storedValue)){
startTime = storedValue;
pauseStartTime = isNaN(storedPauseValue) ? null : storedPauseValue;
} else {
// Если сохраненного значения нет, то принимаем текущее время за начало работы
this._startTime = new Date().getTime();
this._pauseStartTime = null;
}
this.update();
}
// Очищаем сохраненные значения
// Используем, когда делаем submit задачи
Timer.prototype.clear = function(){
Timer.storage.remove(this._storageKey);
Timer.storage.remove(this._storageKey + Timer.PAUSE_SUFFIX);
}
// Возвращает количество секунд с момента старта с вычетом пауз.
// Не изменяет состояния таймера, лишь считывает текущее значение
Timer.prototype.getElapsedSeconds = function(){
if(this.isPaused()){
return Math.floor((this._pauseStartTime - this._startTime)/1000);
} else {
return Math.floor((new Date() - this._startTime)/1000);
}
}
// Возвращает отформатированную строку, которую можно выводить на экран
// Не изменяет состояния таймера, лишь считывает текущее значение
Timer.prototype.getFormattedString = function(){
var seconds = this.getElapsedSeconds();
var minutes = Math.floor(seconds/60);
var hours = Math.floor(minutes/60);
var minutes = minutes - hours*60;
var seconds = seconds - minutes*60;
if (seconds < 10) {
seconds = "0"+seconds;
}
if (minutes < 10) {
minutes = "0"+minutes;
}
if (hours < 10) {
hours = "0"+hours;
}
return hours + ":" + minutes + ":" + seconds;
}
// Таймер на паузе?
Timer.prototype.isPaused = function(){
return this._pauseStartTime !== null;
}
// Сброс таймера. Если таймер стоял на паузе, то после сброса он останется на паузе.
// Новые значения автоматически записываются в storage.
Timer.prototype.reset = function(){
this._startTime = new Date().getTime();
// Если таймер был на паузе, то после сброса оставляем его на паузе
this._pauseStartTime = this.isPaused() ? new Date().getTime() : null;
this.update();
}
// Включить автообноление с заданным интервалом
// Функция onUpdate будет вызываться при каждом обновлении
Timer.prototype.setAutoUpdate = function(interval){
interval = interval || 1000;
if(this._updateIntervalId){
clearInterval(this._updateIntervalId);
}
this._updateIntervalId = setInterval(this.update.bind(this), interval);
}
// Изменяет состояние паузы. Если нет изменений, то ничего не произойдет.
// При изменении состояния, новые значения автоматически запишутся в storage.
Timer.prototype.setPause = function(state){
// Ничего не делаем, если нет изменений
if(state === this.isPaused()) return;
if(state){
this._pauseStartTime = new Date().getTime();
} else {
this._startTime += (new Date().getTime() - this._pauseStartTime);
this._pauseStartTime = null;
}
this.update();
}
// Выключает автообновление, если включено
Timer.prototype.stopAutoUpdate = function(){
if(this._updateIntervalId){
clearInterval(this._updateIntervalId);
this._updateIntervalId = null;
}
}
// Включает/выключает паузу
Timer.prototype.togglePause = function(){
this.setPause(!this.isPaused());
}
// Вызывает onUpdate, если определена.
// Используется при автообнолении и при изменении состояния таймера
Timer.prototype.update = function(){
if(typeof this.onUpdate === 'function'){
this.onUpdate();
}
}
// Суффикс, с которым сохраняется время паузы
Timer.PAUSE_SUFFIX = 'p';
// Не используется, чтобы не ломать обратную совместимость с уже сохраненными сессиями
Timer.PREFIX = 'timer_';
// Обертка над sessionStorage
// При необходимости, можно будет заменить на другое хранилище
Timer.storage = {
get: function(key){
if (!window.sessionStorage) {
// Ведем себя, будто ключ не найден
return null;
} else {
return sessionStorage.getItem(key);
}
},
remove: function(key){
if(!window.sessionStorage){
return false;
} else {
sessionStorage.removeItem(key);
return true;
}
},
set: function(key, data) {
if (window.sessionStorage) {
try {
sessionStorage.setItem(key, data);
return true;
} catch(e) {
return false;
}
}
return false;
}
};
......@@ -5,9 +5,9 @@
<!-- Таймер -->
<div id="timerblock" title="Время на странице">
<img src="js/etersoft/control_pause.gif" id="timer_pause" onclick="controlTimer()" title="Пауза" />
<img src="js/etersoft/control_right.gif" id="timer_play" onclick="controlTimer()" title="Продолжить" />
<img src="js/etersoft/control_stop.gif" id="timer_stop" onclick="if (confirm('Вы точно хотите сбросить таймер?')) {resetTimer();}" title="Сбросить таймер" />
<img src="js/etersoft/control_pause.gif" id="timer_pause" onclick="timer.togglePause()" title="Пауза" />
<img src="js/etersoft/control_right.gif" id="timer_play" onclick="timer.togglePause()" title="Продолжить" />
<img src="js/etersoft/control_stop.gif" id="timer_stop" onclick="if (confirm('Вы точно хотите сбросить таймер?')) {timer.reset();}" title="Сбросить таймер" />
<input type="text" size="10" title="Время на странице" id='timespent' name="timespent" value="" readonly="readonly">
</div>
......@@ -42,4 +42,6 @@
</div>
</div>
<script language="javascript" type="text/javascript" src="js/etersoft/timer_common.js"></script>
<script language="javascript" type="text/javascript" src="js/etersoft/timer.js"></script>
......@@ -5,9 +5,9 @@
<!-- Таймер -->
<div id="timerblock" title="Время на странице">
<img src="js/etersoft/control_pause.gif" id="timer_pause" onclick="controlTimer()" title="Пауза" />
<img src="js/etersoft/control_right.gif" id="timer_play" onclick="controlTimer()" title="Продолжить" />
<img src="js/etersoft/control_stop.gif" id="timer_stop" onclick="if (confirm('Вы точно хотите сбросить таймер?')) {resetTimer();}" title="Сбросить таймер" />
<img src="js/etersoft/control_pause.gif" id="timer_pause" onclick="timer.togglePause()" title="Пауза" />
<img src="js/etersoft/control_right.gif" id="timer_play" onclick="timer.togglePause()" title="Продолжить" />
<img src="js/etersoft/control_stop.gif" id="timer_stop" onclick="if (confirm('Вы точно хотите сбросить таймер?')) {timer.reset();}" title="Сбросить таймер" />
<input type="text" size="10" title="Время на странице" id='timespent' name="timespent" value="" readonly="readonly">
</div>
......@@ -42,4 +42,5 @@
</div>
</div>
<script language="javascript" type="text/javascript" src="js/etersoft/timer_common.js"></script>
<script language="javascript" type="text/javascript" src="js/etersoft/timer.js"></script>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment