var SCRIPTS_URL = '/ajax/mail/',
SEND_MSG_URL = SCRIPTS_URL + 'send_message.php',
GET_MESSAGES_URL = SCRIPTS_URL + 'get_messages.php',
CHECK_READ_URL = SCRIPTS_URL + 'check_read.php',
CHECK_TYPING_URL = SCRIPTS_URL + 'check_typing.php',
UPDATE_TYPING_URL = SCRIPTS_URL + 'update_typing.php';
var GET_MESSAGES_TIMEOUT = 2000,
CHECK_READ_TIMEOUT = 2000,
CHECK_TYPING_TIMEOUT = 2000;
var window_focus = true;
$(window).focus(function () {
window_focus = true;
}).blur(function () {
window_focus = false;
});
function handleJsonErrors(json) {
if (json == undefined || json.error != undefined) {
showError(json == undefined ? 'Произошла ошибка' : json.error);
return true;
}
return false;
}
function showError(error) {
alert(error);
}
var Mail = function (id_user) {0;
var self = this;
var $btnSend, $inputMsg, $loading, $messages, $typingElement, $typingDotsElement;
// handlers
var typingHandler, dotsHandler;
var getMessagesTimeout, checkReadTimeout, checkTypingTimeout;
// jqXHR
var checkReadXHR, sendMessageXHR, longPollingXHR, checkTypingXHR, typingXHR;
var isTyping = false,
isUserTyping = false;
$(document).ready(function () {
$btnSend = $('#btnSend');
$inputMsg = $('#inputMsg');
// for altername_post_form.php
if ($inputMsg.length == 0)
$inputMsg = $('textarea[name="msg"]');
$loading = $('#loading');
$messages = $('#messages');
$typingElement = $('#typing');
$typingDotsElement = $('#typingDots');
self.initListeners();
});
this.initListeners = function () {
$btnSend.on('click', function (e) {
e.preventDefault();
if (sendMessageXHR != undefined) {
// showError('Не так быстро...');
return;
}
var msg = $inputMsg.val().trim();
if (msg.length == 0) {
showError('Введите сообщение');
return;
}
self.sendMessage(msg);
});
$inputMsg.on('input', function () {
if (!isTyping) {
isTyping = true;
if (typingXHR != undefined)
typingXHR.abort();
self.updateTyping();
}
if (typingHandler != undefined)
clearInterval(typingHandler);
typingHandler = setTimeout(function () {
isTyping = false;
if (typingXHR != undefined)
typingXHR.abort();
self.updateTyping();
}, 1000);
});
self.setCheckTypingTimeout();
self.setGetMessagesTimeout(function () {
self.setCheckReadTimeout();
});
self.reloadNavigationOnClicks();
}
this.setGetMessagesTimeout = function (completeCallback) {
self.abortGetMessages();
getMessagesTimeout = setTimeout(function () {
self.startLongPollingMessages(function () {
if ($.isFunction(completeCallback)) {
completeCallback();
completeCallback = undefined;
}
self.setGetMessagesTimeout();
});
}, GET_MESSAGES_TIMEOUT);
}
this.abortGetMessages = function () {
if (getMessagesTimeout != undefined)
clearInterval(getMessagesTimeout);
if (longPollingXHR != undefined)
longPollingXHR.abort();
}
this.setCheckReadTimeout = function (completeCallback) {
self.abortCheckRead();
checkReadTimeout = setTimeout(function () {
self.checkRead(function () {
self.setCheckReadTimeout();
});
}, CHECK_READ_TIMEOUT);
}
this.abortCheckRead = function () {
if (checkReadTimeout != undefined)
clearInterval(checkReadTimeout);
if (checkReadXHR != undefined)
checkReadXHR.abort();
}
this.setCheckTypingTimeout = function () {
self.abortCheckTyping();
checkTypingTimeout = setTimeout(function () {
self.checkTyping(function () {
self.setCheckTypingTimeout();
});
}, CHECK_TYPING_TIMEOUT);
}
this.abortCheckTyping = function () {
if (checkTypingTimeout != undefined)
clearInterval(checkTypingTimeout);
if (checkTypingXHR != undefined)
checkTypingXHR.abort();
}
this.updateTyping = function () {
typingXHR = $.ajax({
url: UPDATE_TYPING_URL,
type: 'post',
data: {
id_user: id_user,
is_typing: isTyping
},
success: function (json) {
handleJsonErrors(json);
}
});
}
this.checkTyping = function (completeCallback) {
checkTypingXHR = $.ajax({
url: CHECK_TYPING_URL,
type: 'post',
data: {
id_user: id_user,
is_typing: isUserTyping
},
success: function (json) {
if (handleJsonErrors(json))
return;
isUserTyping = json.is_typing;
if (dotsHandler != undefined)
clearInterval(dotsHandler);
if (isUserTyping) {
dotsHandler = setInterval(function () {
self.updateDots();
}, 200);
$typingElement.show(100);
}
else
$typingElement.hide(100);
},
complete: function () {
if ($.isFunction(completeCallback))
completeCallback();
}
});
}
self.updateDots = function () {
var dots = $typingDotsElement.text();
var objs = {'': '.', '.': '..', '..': '...', '...': ''};
$typingDotsElement.text(objs[dots]);
}
this.reloadNavigationOnClicks = function() {
var $navigationElement = $('#navigation .c2');
$('a', $navigationElement).on('click', function (e) {
e.preventDefault();
var href = $(this).attr('href');
self.goToPage(href.match(/page=end$/) ? count_pages : parseInt($(this).text()));
});
}
this.buildNavigation = function () {
var $navigationElement = $('#navigation');
var $c2Element = $('.c2', $navigationElement);
if (count_pages == 1) {
if ($c2Element.length) {
$c2Element.remove();
return;
}
} else if ($c2Element.length == 0)
$c2Element = $('<div>', {class: 'c2'}).appendTo($navigationElement);
$c2Element.empty();
if (current_page != 1)
$c2Element.append("<span class='page'><a href=\"" + navigation_link + "page=1\" title='Первая страница'><</a></span> ");
if (current_page != 1)
$c2Element.append("<span class='page'><a href=\"" + navigation_link + "page=1\" title='Страница №1'>1</a></span>");
else
$c2Element.append(" <span class='str'><b>1</b></span>");
for (var ot =- 3; ot<=3; ot++) {
if (current_page + ot > 1 && current_page + ot < count_pages) {
if (ot == -3 && current_page+ot>2)
$c2Element.append("<span class='page'> ..");
if (ot != 0)
$c2Element.append(" <span class='page'><a href=\"" + navigation_link + "page=" + (current_page + ot) + "\" title='Страница №" + (current_page + ot) + "'>" + (current_page + ot) + "</a></span>");
else
$c2Element.append(" <span class='str'><b>" + (current_page + ot) + "</b></span>");
if (ot == 3 && current_page + ot < count_pages - 1)
$c2Element.append("<span class='page'> ..");
}
}
if (current_page != count_pages)
$c2Element.append(" <span class='page'><a href=\"" + navigation_link + "page=end\" title='Страница №" + count_pages + "'>" + count_pages + "</a></span>");
else if (count_pages > 1)
$c2Element.append(" <span class='str'><b>" + count_pages + "</b></span>");
if (current_page != count_pages)
$c2Element.append(" <span class='page'><a href=\"" + navigation_link + "page=end\" title='Последняя страница'>></a></span>");
self.reloadNavigationOnClicks();
}
this.startLongPollingMessages = function (completeCallback, successCallback) {
var existing = [];
var $allMessages = $('.message', $messages);
$.each($allMessages, function (k, v) {
var m_id = $(v).attr('data-id');
if ($.inArray(m_id, existing) == -1)
existing.push(m_id);
});
longPollingXHR = $.ajax({
url: GET_MESSAGES_URL,
type: 'post',
data: {
id_user: id_user,
existing: existing.join(','),
page: current_page
},
timeout: 0,
success: function (json) {
if ($.isFunction(successCallback)) {
successCallback();
}
if (handleJsonErrors(json))
return;
count_pages = json.count_pages;
self.removeMessages(json.removed);
self.showMessages(json.messages);
},
complete: function () {
longPollingXHR = undefined;
if ($.isFunction(completeCallback))
completeCallback();
}
});
}
this.removeMessages = function (removed_ids) {
$.each(removed_ids, function (k, v) {
$message = $('[data-id=' + v + ']', $messages);
$message.remove();
});
}
this.showMessages = function (messages) {
var countMessages = getKeyCount(messages);
$.each(messages, function (k, message) {
self.showMessage(message);
});
self.updateMessages();
self.buildNavigation();
}
this.showMessage = function (message) {
var $message = $('<div>', {class: 'nav1 message', 'data-id': message.id});
if (message.read == 0 && message.id_kont == id_user)
$message.addClass('unread');
$message.append(message.user.nick_form);
$message.append("(" + message.time + ")<br>");
var $ur_word = $('<span>', {class: 'ur_word'}).appendTo($message);
$ur_word.append("(не прочитано)<br>");
$message.append(message.msg);
var $right = $('<div>', {style: 'text-align:right'}).appendTo($message);
if (message.id_user == id_user)
$right.append("<a href='/mail.php?id=" + id_user + "&spam=" + message.id + "'><img src='/style/icons/blicon.gif'></a>");
$right.append("<a href='/mail.php?id=" + id_user + "&delete=" + message.id + "'><img src='/style/icons/delete.gif'></a>");
if (message.id_after != undefined && message.id_after != false) {
var $af = $('[data-id=' + message.id_after + ']', $messages);
console.log($af);
$af.after($message);
}
else
$message.prependTo($messages);
}
this.updateMessages = function () {
var $allMessages = $('.message', $messages);
if ($allMessages.length == 0) {
$('#empty').removeClass('hidden');
return;
}
$('#empty').addClass('hidden');
var num = 0;
var c_messages = 0;
$.each($allMessages, function (k, v) {
var $messageElement = $(v);
if (c_messages >= results_on_page)
$messageElement.remove();
$messageElement.removeClass('nav1');
$messageElement.removeClass('nav2');
$messageElement.addClass('nav' + (num++ % 2 ? 2 : 1));
c_messages++;
});
}
this.sendMessage = function (msg) {
self.showLoading();
sendMessageXHR = $.ajax({
url: SEND_MSG_URL,
type: 'post',
data: {
id_user: id_user,
msg: msg
},
success: function (json) {
$inputMsg.val('');
},
error: function (error) {
showError('Произошла ошибка');
},
complete: function () {
self.hideLoading();
sendMessageXHR = undefined;
}
});
}
this.showLoading = function () {
$loading.show(100);
}
this.hideLoading = function () {
$loading.hide(100);
}
this.checkRead = function (completeCallback) {
var $unread = $('.unread', $messages);
if ($unread.length == 0 || checkReadXHR != undefined) {
if ($.isFunction(completeCallback))
completeCallback();
return;
}
var from_id = parseInt($($unread[0]).attr('data-id'));
checkReadXHR = $.ajax({
url: CHECK_READ_URL,
type: 'post',
data: {
id_user: id_user,
from_id: from_id
},
success: function (json) {
if (handleJsonErrors(json))
return;
if (json.read == 0)
return;
self.setRead();
},
complete: function () {
checkReadXHR = undefined;
if ($.isFunction(completeCallback))
completeCallback();
}
});
}
this.setRead = function () {
var $unread = $('.unread', $messages);
if ($unread.length == 0)
return;
$.each($unread, function (k, value) {
var $value = $(value);
$value.removeClass('unread');
});
}
this.goToPage = function (page) {
current_page = page;
self.abortGetMessages();
self.startLongPollingMessages(function () {
self.setGetMessagesTimeout();
}, function () {
$messages.empty();
moveToTop();
});
}
}