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 protocol = window.location.protocol;
var storage_key = "bug:"+window.location.protocol+bug_id;
//Изменение баги //Изменение баги
var changed_remain = 0; var changed_remain = 0;
...@@ -23,139 +15,52 @@ var changed_remain = 0; ...@@ -23,139 +15,52 @@ var changed_remain = 0;
//Создание баги //Создание баги
var etersoft_create = 0; var etersoft_create = 0;
// Время начала работы над багом // Объект таймера, создается при инициализации
var startTime; // Подробнее про таймер см. timer_common.js
var timer;
// Время, когда таймер поставили на паузу // Интервал обновления таймера в мс, на точность не влияет
var pauseStartTime; var UPDATE_INTERVAL = 1000;
function initTimer(){ function initTimer(){
var storedValue = parseInt(getStorage(storage_key)); // Показываем время только сотрудникам Etersoft
var storedPauseValue = parseInt(getStorage(storage_key+'p')); if(!isetersoft()) return;
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);
}
//Возращает прошедшее время в секундах с учетом пауз document.getElementById("timerblock").style.display = 'block';
// TODO: переименовать timer = new Timer('bug:'+protocol+bugId, updateTimer);
function initStopwatch() { timer.setAutoUpdate(UPDATE_INTERVAL);
if(control_timer){
return (pauseStartTime - startTime)/1000;
} else {
return (new Date() - startTime)/1000;
}
} }
function updateTimer() { // this при вызове - объект таймера
var mySecs = initStopwatch(); function updateTimer(){
var myMinutes = Math.floor(mySecs/60); setPauseDisplay(this.isPaused());
var myHours = Math.floor(myMinutes/60); document.querySelector('#timespent').value = this.getFormattedString();
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;
} }
//Установка в поле отработанного времени в минутах //Установка в поле отработанного времени в минутах
function setWorkTime(manualTime) { function setWorkTime(manualTime) {
var secs = initStopwatch(); var minutes = Math.ceil(timer.getElapsedSeconds()/60);
var minutes = Math.ceil(secs/60);
document.querySelector("#timeQuestionDiv #realworktime").value = (!manualTime) ? minutes : manualTime; document.querySelector("#realworktime").value = manualTime ? manualTime : minutes;
} }
function setPauseDisplay(pause){ function setPauseDisplay(pause){
document.querySelector("#timerblock #timespent").style.color = pause ? "gray" : "black"; document.querySelector("#timespent").style.color = pause ? "gray" : "black";
document.querySelector("#timerblock #timer_pause").style.visibility = pause ? "hidden" : "visible"; document.querySelector("#timer_pause").style.visibility = pause ? "hidden" : "visible";
document.querySelector("#timerblock #timer_play").style.visibility = pause ? "visible" : "hidden"; 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(){ function showDiv(){
document.querySelector("#timeQuestionDiv").style.display = "block"; document.querySelector("#timeQuestionDiv").style.display = "block";
document.querySelector("#timeQuestionDiv #realworktime").focus(); document.querySelector("#realworktime").focus();
} }
function closeDiv() { function closeDiv() {
document.querySelector("#timeQuestionDiv").style.display = "none"; 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() { function getBugIdFromField() {
var field = document.querySelector("#changeform input[name=id]"); var field = document.querySelector("#changeform input[name=id]");
...@@ -165,29 +70,7 @@ function getBugIdFromField() { ...@@ -165,29 +70,7 @@ function getBugIdFromField() {
return false; 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 //Является ли пользователь сотрудником Etersoft
function isetersoft() { function isetersoft() {
...@@ -242,6 +125,7 @@ function premysubmit(realworktime) { ...@@ -242,6 +125,7 @@ function premysubmit(realworktime) {
} }
document.querySelector("#Create #work_time").value = wt; document.querySelector("#Create #work_time").value = wt;
mysubmitnew(); mysubmitnew();
timer.clear();
return; return;
} }
...@@ -255,9 +139,9 @@ function premysubmit(realworktime) { ...@@ -255,9 +139,9 @@ function premysubmit(realworktime) {
document.querySelector("#changeform #work_time").value = wt; document.querySelector("#changeform #work_time").value = wt;
document.querySelector("#changeform #remaining_time").value = document.querySelector("#timeQuestionDiv #realremaintime").value; document.querySelector("#changeform #remaining_time").value = document.querySelector("#timeQuestionDiv #realremaintime").value;
} }
setStorage(storage_key, 'unknown');
mysubmit(); mysubmit();
timer.clear();
} }
function mysubmit() { function mysubmit() {
...@@ -284,7 +168,7 @@ function mysubmit() { ...@@ -284,7 +168,7 @@ function mysubmit() {
function mysubmitnew() { function mysubmitnew() {
if (document.querySelector("#Create #work_time").value > 0 || !isetersoft()) { if (document.querySelector("#Create #work_time").value > 0 || !isetersoft()) {
document.Create.submit(); document.Create.submit();
setStorage(storage_key, 'unknown'); timer.reset();
return; return;
} }
etersoft_create = 1; etersoft_create = 1;
...@@ -293,7 +177,6 @@ function mysubmitnew() { ...@@ -293,7 +177,6 @@ function mysubmitnew() {
} }
////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////
window.setTimeout('istimer()', 500);
if (typeof (window.addEventListener) != 'undefined') { if (typeof (window.addEventListener) != 'undefined') {
//gecko, safari, konqueror and standard //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 @@ ...@@ -5,9 +5,9 @@
<!-- Таймер --> <!-- Таймер -->
<div id="timerblock" title="Время на странице"> <div id="timerblock" title="Время на странице">
<img src="js/etersoft/control_pause.gif" id="timer_pause" onclick="controlTimer()" 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="controlTimer()" 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('Вы точно хотите сбросить таймер?')) {resetTimer();}" 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"> <input type="text" size="10" title="Время на странице" id='timespent' name="timespent" value="" readonly="readonly">
</div> </div>
...@@ -42,4 +42,6 @@ ...@@ -42,4 +42,6 @@
</div> </div>
</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> <script language="javascript" type="text/javascript" src="js/etersoft/timer.js"></script>
...@@ -5,9 +5,9 @@ ...@@ -5,9 +5,9 @@
<!-- Таймер --> <!-- Таймер -->
<div id="timerblock" title="Время на странице"> <div id="timerblock" title="Время на странице">
<img src="js/etersoft/control_pause.gif" id="timer_pause" onclick="controlTimer()" 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="controlTimer()" 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('Вы точно хотите сбросить таймер?')) {resetTimer();}" 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"> <input type="text" size="10" title="Время на странице" id='timespent' name="timespent" value="" readonly="readonly">
</div> </div>
...@@ -42,4 +42,5 @@ ...@@ -42,4 +42,5 @@
</div> </div>
</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> <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