/* Author Chat v1.9.0 */
/**************************/
/* global localize */
var authorChat = function ()
{
/* Creates a reference to this variable to be used within the functions */
var $this = this;
/* init the vars */
$this.count = 0;
$this.title = document.title;
$this.interval_id = null;
$this.interval_secs = parseInt(localize.set_interval); /* interval time in seconds to check for some new message */
$this.last_date = '';
$this.today_date = new Date(Date.now());
$this.last_id = 0;
$this.total_rows = 0;
$this.scroll_id = null;
$this.win_is_focus = true;
$this.truncate = [35, 10]; /* to truncate the length of url text */
$this.uid_list = '';
$this.uid_colors = {};
$this.uid_last_color = 1;
$this.room_changed = false;
$this.room_pressed_button_id = '0';
$this.curent_user_room_owner = false;
/* list of ASCII Emoticons to detect */
$this.emoticons = [
[/(^|\s)(0:\)|0:\-\)|O:\))/gi, 'angel'],
[/(^|\s)(>:\(|>:\-\()/gi, 'angry'],
[/(^|\s)(:S|:'\-S)/gi, 'confused'],
[/(^|\s)(:ยด\(|:\'\()/gi, 'cry'],
[/(^|\s)(\(6\)|>:\)|>:\-\))/gi, 'devil'],
[/(^|\s)(:\||:\-\|)/gi, 'disappont'],
[/(^|\s)(^|\s)(:\/|:\-\/)/gi, 'doubt'],
[/(^|\s)(:D|:\-D)/gi, 'happy'],
[/(^|\s)(XD|X\-D|=D)/gi, 'happy-x'],
[/(^|\s)(:\{|:\-\{)/gi, 'pain'],
[/(^|\s)(:\(|:\-\()/gi, 'sad'],
[/(^|\s)(:\)|:\-\))/gi, 'smiley'],
[/(^|\s)(=\)|=\-\))/gi, 'smiley-x'],
[/(^|\s)(:o|:\-o)/gi, 'suprice'],
[/(^|\s)(:P|:\-P)/gi, 'tongle'],
[/(^|\s)(XP|X\-P|=P)/gi, 'tongle-x'],
[/(^|\s)(;\)|;\-\))/gi, 'wink']
];
/* list of text url to parse */
$this.parse_urls = [
/* images */
[
/(^|\s)(https?\:\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|]\.)(jpg|jpeg|png|gif|webp)/gim,
' '
],
/* complete url */
[
/(^|\s)((https?|ftp?):\/\/[a-z0-9-+&@#\/%?=~_|!:,.;]*[a-z0-9-+&@#\/%=~_|])/gim,
function (str, p1, p2) {
return ' ' + truncateString(p2, $this.truncate[0], $this.truncate[1]) + '';
}
],
/* pseudo-url */
[
/(^|\s)(www\.[\S]+(\b|$))/gim,
function (str, p1, p2) {
return ' ' + truncateString(p2, $this.truncate[0], $this.truncate[1]) + '';
}
]
];
var $_chatArea = jQuery('#author-chat-area');
var $_dialogContent = jQuery('#author-chat-window');
//var $_topDate = $_chatArea.find('.ac-top-date');
/* hide the current date label of the top */
//$_topDate.hide();
/* display name on page */
//jQuery('#author-chat .ac-user').html(localize.you_are + ' ' + localize.nickname + '');
/* Click event of the Button to change room */
var $_btnToPrivateConversation = jQuery('#author-chat #ac-rooms');
$_btnToPrivateConversation.click(function (event)
{
if (!$this.room_changed) {
$this.room_changed = true;
jQuery('#author-chat #ac-rooms #' + $this.room_pressed_button_id).removeClass('active'); // remove acive class button when another room button was pressed
$this.room_pressed_button_id = event.target.id; //get id of clicked room button
$this.getRoomsForUser();
}
});
/* watch textarea for key presses */
jQuery('#author-chat .ac-textarea').keydown(function (event)
{
var key = event.which;
/* all keys including return */
if (key >= 33)
{
var maxLength = jQuery(this).attr("maxlength");
var length = this.value.length;
/* don't allow new content if length is maxed out */
if (length >= maxLength)
{
event.preventDefault();
}
}
});
/* watch textarea for release of key press */
jQuery('#author-chat .ac-textarea').keyup(function (event)
{
var $me = jQuery(this);
/* only send in case of press Enter, not if we press Shift + Enter */
if (event.keyCode === 13 && !event.shiftKey)
{
var text = $me.val();
var maxLength = jQuery(this).attr("maxlength");
var length = text.length;
/* send */
if (length <= maxLength + 1)
{
$this.send();
$me.val('');
} else
{
$me.val(text.substring(0, maxLength));
}
}
});
/* Set focus on textarea with just click inside the Chat Area */
$_chatArea.mouseup(function (event) {
/* don't make focus on right click or if we select some text */
if (event.which === 1 && window.getSelection().toString() === '')
{
jQuery('#author-chat .ac-textarea').focus();
}
});
/* Set onBlur event of current window */
jQuery(window).blur(function ()
{
$this.win_is_focus = false;
});
/* Set onFocus event of current window */
jQuery(window).focus(function ()
{
$this.win_is_focus = true;
if ($this.count)
{
/* check if we have the floating window */
if ($_dialogContent.length)
{
/* check if the floating window is minimized */
if ($_dialogContent.is(":hidden") === false)
{
$this.clearCount();
}
} else
{
$this.clearCount();
}
document.title = $this.title;
}
});
/* Click event of the Button to Scroll to Bottom */
// var $_btnToBottom = $_chatArea.find('.ac-tobottom');
// $_btnToBottom.click(function ()
// {
// $_chatArea.scrollTop($_chatArea.prop('scrollHeight'));
// $_btnToBottom.addClass('ac-hidden');
// //$_topDate.hide();
// });
/* MouseWheel event */
$_chatArea.on('DOMMouseScroll mousewheel', function (ev) {
var $me = jQuery(this),
scroll_top = this.scrollTop,
scroll_height = this.scrollHeight,
height = $me.innerHeight(),
delta = ev.originalEvent.wheelDelta,
up = delta > 0;
clearTimeout($this.scroll_id);
/* show the button to go to bottom */
// if ($_btnToBottom.hasClass('ac-hidden'))
// {
// $_btnToBottom.removeClass('ac-hidden');
// }
/* displays the current date of visible messages at the top as does Whatsapp */
/* Note: we set a timeout to check the position of the elements after the scroll is finished */
// $this.scroll_id = setTimeout(function () {
// var $_prevDate = $me.find('.ac-date').first();
// $me.find('.ac-date').each(function () {
// var top = jQuery(this).position().top;
// if (top < 0)
// {
// if (top > $_prevDate.position().top)
// {
// $_prevDate = jQuery(this);
// }
// }
// });
// if ($_prevDate.text() !== $_topDate.text())
// {
// $_topDate.text($_prevDate.text());
// }
// }, 250);
/* prevent MouseWheel Scrolling of parent elements if we are on the chat-area */
var prevent = function () {
ev.stopPropagation();
ev.preventDefault();
ev.returnValue = false;
return false;
};
if (!up && -delta >= scroll_height - height - scroll_top)
{
//$_btnToBottom.addClass('ac-hidden');
// Scrolling down, but this will take us past the bottom.
$me.scrollTop(scroll_height);
//$_topDate.hide();
return prevent();
} else if (up && delta > scroll_top)
{
// Scrolling up, but this will take us past the top.
$me.scrollTop(0);
//$_topDate.hide();
return prevent();
}
// else
// {
// if ($_topDate.is(':hidden'))
// {
// $_topDate.show();
// }
// }
});
};
/* Creates a short reference to the prototype */
var _proto_ = authorChat.prototype;
/* Get/Set the seconds for the getState interval */
_proto_.intervalSecs = function (seconds)
{
this.interval_secs = seconds || this.interval_secs;
return this.interval_secs;
};
/* Start the getState interval */
_proto_.start = function (seconds)
{
var $this = this;
/* set the new interval time, if we define one in the arguments */
$this.intervalSecs(seconds);
/* stop the current interval, if we have one */
$this.stop();
/* start a new interval time */
$this.interval_id = setInterval(function ()
{
$this.getState();
},
$this.interval_secs * 1000);
};
/* Stop the getState interval */
_proto_.stop = function ()
{
var $this = this;
clearInterval($this.interval_id);
};
/* Clear the Counter */
_proto_.clearCount = function ()
{
this.count = 0;
};
/* Update chat if needed */
_proto_.getState = function ()
{
var $this = this;
var path = document.location.href.replace(/^https?:\/\/[^\/]+/, '');
var master_path = $this.getLocalData('ac_master_path');
/* check if this window is the master or will be the new master in case there is none */
if (master_path === null || master_path === path)
{
/* save the master path to localstorage with a lifetime relative to the current refresh time interval */
$this.setLocalData('ac_master_path', path, $this.interval_secs * 3);
jQuery.ajax(
{
type: 'POST',
data:
{
'function': 'getState'
},
dataType: 'json',
success: function (data)
{
if (data !== null)
{
if (data !== $this.total_rows)
{
$this.setLocalData('ac_total_rows', data);
$this.total_rows = data;
$this.update();
}
}
}
});
/* if room was changed empty chat msgs and initiate new chat with desired room */
if ($this.room_changed === true) {
jQuery('#author-chat-area ul').empty();
$this.initiate();
$this.room_changed = false;
if ($this.room_pressed_button_id !== '0') {
$this.showSearchUserBar(); //show search user bar if not visible
$this.whoIsChannelOwner(); //check who is channel owner
} else {
jQuery('#author-chat #ac-search-user').empty(); //remove search user bar
}
}
/* add room buttons (if user participating in some channels/rooms) */
$this.getRoomsForUser();
/* add users list for current room (not main) */
if ($this.room_pressed_button_id !== '0') {
$this.getUsersForRoom();
} else {
/* remove user list if main channel is visible */
jQuery('#author-chat #ac-room-users-list').empty();
}
}
/* we are not the master window so.. */
else
{
var total_rows = $this.getLocalData('ac_total_rows');
if (total_rows !== null && parseInt(total_rows) !== $this.total_rows)
{
$this.total_rows = total_rows;
$this.update();
}
}
};
/* Send the message */
_proto_.send = function ()
{
var $this = this;
var message = jQuery('#author-chat .ac-textarea').val();
jQuery.ajax(
{
type: 'POST',
data:
{
'function': 'send',
'message': message.slice(0, -1),
'nickname': localize.nickname,
'user_id': localize.user_id,
'room_pressed_button_id': $this.room_pressed_button_id
},
dataType: 'json',
success: function (data)
{
$this.update();
}
});
};
/* Updates the chat */
_proto_.update = function ()
{
var $this = this;
$this.today_date = new Date(Date.now());
jQuery.ajax(
{
type: 'POST',
data:
{
'function': 'update',
'room_pressed_button_id': $this.room_pressed_button_id,
'user_time_zone': -(new Date().getTimezoneOffset() / 60)
},
dataType: 'json',
success: function (data)
{
if (data !== null)
{
/* get the total rows of the database */
var rows = data.id.length;
for (var i = 0; i < rows; i++)
{
/* only show new message */
if (parseInt(data.id[i]) <= $this.last_id)
continue;
/* add the message to the chat-area */
$this.showMsg(data.uid[i], data.nick[i], data.msg[i], data.date[i], true);
/* check if we are in the floating window */
var $_dialogContent = jQuery('#author-chat-window');
/* Increments the counter if the current window is not active or if the floating window is minimized */
if ($this.win_is_focus === false || ($_dialogContent.length && $_dialogContent.is(":hidden")))
{
$this.count++;
/* yeap, we check again this */
if ($_dialogContent.length && $_dialogContent.is(":hidden"))
{
var DialogTitleBar = $_dialogContent.parent().find('.ui-dialog-titlebar');
/* we make the titlebar brink if it's not */
if (DialogTitleBar.hasClass('ac-bg-blink') === false)
{
DialogTitleBar.addClass('ac-bg-blink');
}
/* and show the counter */
jQuery('#author-chat-count').text($this.count).show();
}
document.title = '(' + $this.count + ')' + $this.title;
/* playing alert sound */
document.getElementById('author-chat-sound').play();
}
}
/* save the last menssage id */
$this.last_id = parseInt(data.id[ rows - 1 ]);
/* set the last_day with today date */
$this.last_date = (data.date[ rows - 1 ].split(','))[0];
}
/* scroll the chat area to the bottom */
$this.scrollToBottom();
}
});
};
/* Initiate the chat */
_proto_.initiate = function (seconds)
{
var $this = this;
$this.today_date = new Date(Date.now());
jQuery.ajax(
{
type: 'POST',
data:
{
'function': 'initiate',
'room_pressed_button_id': $this.room_pressed_button_id,
'user_time_zone': -(new Date().getTimezoneOffset() / 60)
},
dataType: 'json',
success: function (data)
{
if (data !== null && data.id.length)
{
var rows = data.id.length;
for (var i = 0; i < rows; i++)
{
$this.showMsg(data.uid[i], data.nick[i], data.msg[i], data.date[i]);
}
/* save the last menssage id */
$this.last_id = parseInt(data.id[ rows - 1 ]);
/* set the last_day */
$this.last_date = (data.date[ rows - 1 ].split(','))[0];
}
/* scroll the chat area to the bottom */
$this.scrollToBottom();
}
});
jQuery('#author-chat').show();
$this.start(seconds);
};
/* Scroll to the bottom the chat area */
_proto_.scrollToBottom = function ()
{
var $this = this,
$_charArea = jQuery('#author-chat-area'),
scroll_top = $_charArea.scrollTop(),
scroll_height = $_charArea.prop('scrollHeight'),
height = $_charArea.innerHeight();
$this.scroll_id = null;
if (scroll_top !== scroll_height - height)
{
/* add a timeout to check again in case of some attached images have not been loaded */
$this.scroll_id = setTimeout(function () {
$this.scrollToBottom();
}, 2000);
}
/* scroll the chat area to the bottom */
$_charArea.scrollTop(scroll_height);
//$_charArea.find('.ac-top-date').hide();
};
/* Add the menssage to chat area */
_proto_.showMsg = function (uid, nick, msg, date, is_new)
{
var $this = this;
var full_date = date.split(',');
/* add the date label of current message if it's different from the last */
if (full_date[0] !== $this.last_date)
{
$this.last_date = full_date[0];
var msg_date = stringToDate($this.last_date);
var show_date = msg_date.toLocaleDateString().replace(/\//g, '-').replace(/\-(\d)\-/g, '-0$1-');
/* change the recent dates to weekday names */
if (localize.set_weekdays === 1)
{
var days = dayDiff($this.today_date, msg_date);
if (days === 0)
{
show_date = localize.today;
} else if (days === 1)
{
show_date = localize.yesterday;
} else if (days > 1 && days < 7)
{
switch (msg_date.getDay())
{
case 0:
show_date = localize.sunday;
break;
case 1:
show_date = localize.monday;
break;
case 2:
show_date = localize.tuesday;
break;
case 3:
show_date = localize.wednesday;
break;
case 4:
show_date = localize.thursday;
break;
case 5:
show_date = localize.friday;
break;
case 6:
show_date = localize.saturday;
break;
}
}
}
jQuery('#author-chat-area ul').append(jQuery('