1712 lines
48 KiB
JavaScript
1712 lines
48 KiB
JavaScript
/**
|
|
*-------------------------------------------------------------
|
|
* Global variables
|
|
*-------------------------------------------------------------
|
|
*/
|
|
var messenger,
|
|
typingTimeout,
|
|
typingNow = 0,
|
|
temporaryMsgId = 0,
|
|
defaultAvatarInSettings = null,
|
|
messengerColor,
|
|
dark_mode,
|
|
messages_page = 1;
|
|
|
|
const messagesContainer = $(".messenger-messagingView .m-body"),
|
|
messengerTitleDefault = $(".messenger-headTitle").text(),
|
|
messageInputContainer = $(".messenger-sendCard"),
|
|
messageInput = $("#message-form .m-send"),
|
|
auth_id = $("meta[name=url]").attr("data-user"),
|
|
url = $("meta[name=url]").attr("content"),
|
|
messengerTheme = $("meta[name=messenger-theme]").attr("content"),
|
|
defaultMessengerColor = $("meta[name=messenger-color]").attr("content"),
|
|
csrfToken = $('meta[name="csrf-token"]').attr("content");
|
|
|
|
const getMessengerId = () => $("meta[name=id]").attr("content");
|
|
const setMessengerId = (id) => $("meta[name=id]").attr("content", id);
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Pusher initialization
|
|
*-------------------------------------------------------------
|
|
*/
|
|
Pusher.logToConsole = chatify.pusher.debug;
|
|
const pusher = new Pusher(chatify.pusher.key, {
|
|
encrypted: chatify.pusher.options.encrypted,
|
|
cluster: chatify.pusher.options.cluster,
|
|
wsHost: chatify.pusher.options.host,
|
|
wsPort: chatify.pusher.options.port,
|
|
wssPort: chatify.pusher.options.port,
|
|
forceTLS: chatify.pusher.options.useTLS,
|
|
authEndpoint: chatify.pusherAuthEndpoint,
|
|
auth: {
|
|
headers: {
|
|
"X-CSRF-TOKEN": csrfToken,
|
|
},
|
|
},
|
|
});
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Re-usable methods
|
|
*-------------------------------------------------------------
|
|
*/
|
|
const escapeHtml = (unsafe) => {
|
|
return unsafe
|
|
.replace(/&/g, "&")
|
|
.replace(/</g, "<")
|
|
.replace(/>/g, ">");
|
|
};
|
|
function actionOnScroll(selector, callback, topScroll = false) {
|
|
$(selector).on("scroll", function () {
|
|
let element = $(this).get(0);
|
|
const condition = topScroll
|
|
? element.scrollTop == 0
|
|
: element.scrollTop + element.clientHeight >= element.scrollHeight;
|
|
if (condition) {
|
|
callback();
|
|
}
|
|
});
|
|
}
|
|
function routerPush(title, url) {
|
|
$("meta[name=url]").attr("content", url);
|
|
return window.history.pushState({}, title || document.title, url);
|
|
}
|
|
function updateSelectedContact(user_id) {
|
|
$(document).find(".messenger-list-item").removeClass("m-list-active");
|
|
$(document)
|
|
.find(
|
|
".messenger-list-item[data-contact=" + (user_id || getMessengerId()) + "]"
|
|
)
|
|
.addClass("m-list-active");
|
|
}
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Global Templates
|
|
*-------------------------------------------------------------
|
|
*/
|
|
// Loading svg
|
|
function loadingSVG(size = "25px", className = "", style = "") {
|
|
return `
|
|
<svg style="${style}" class="loadingSVG ${className}" xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 40 40" stroke="#ffffff">
|
|
<g fill="none" fill-rule="evenodd">
|
|
<g transform="translate(2 2)" stroke-width="3">
|
|
<circle stroke-opacity=".1" cx="18" cy="18" r="18"></circle>
|
|
<path d="M36 18c0-9.94-8.06-18-18-18" transform="rotate(349.311 18 18)">
|
|
<animateTransform attributeName="transform" type="rotate" from="0 18 18" to="360 18 18" dur=".8s" repeatCount="indefinite"></animateTransform>
|
|
</path>
|
|
</g>
|
|
</g>
|
|
</svg>
|
|
`;
|
|
}
|
|
function loadingWithContainer(className) {
|
|
return `<div class="${className}" style="text-align:center;padding:15px">${loadingSVG(
|
|
"25px",
|
|
"",
|
|
"margin:auto"
|
|
)}</div>`;
|
|
}
|
|
|
|
// loading placeholder for users list item
|
|
function listItemLoading(items) {
|
|
let template = "";
|
|
for (let i = 0; i < items; i++) {
|
|
template += `
|
|
<div class="loadingPlaceholder">
|
|
<div class="loadingPlaceholder-wrapper">
|
|
<div class="loadingPlaceholder-body">
|
|
<table class="loadingPlaceholder-header">
|
|
<tr>
|
|
<td style="width: 45px;"><div class="loadingPlaceholder-avatar"></div></td>
|
|
<td>
|
|
<div class="loadingPlaceholder-name"></div>
|
|
<div class="loadingPlaceholder-date"></div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
return template;
|
|
}
|
|
|
|
// loading placeholder for avatars
|
|
function avatarLoading(items) {
|
|
let template = "";
|
|
for (let i = 0; i < items; i++) {
|
|
template += `
|
|
<div class="loadingPlaceholder">
|
|
<div class="loadingPlaceholder-wrapper">
|
|
<div class="loadingPlaceholder-body">
|
|
<table class="loadingPlaceholder-header">
|
|
<tr>
|
|
<td style="width: 45px;">
|
|
<div class="loadingPlaceholder-avatar" style="margin: 2px;"></div>
|
|
</td>
|
|
</tr>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
return template;
|
|
}
|
|
|
|
// While sending a message, show this temporary message card.
|
|
function sendTempMessageCard(message, id) {
|
|
return `
|
|
<div class="message-card mc-sender" data-id="${id}">
|
|
<div class="message-card-content">
|
|
<div class="message">
|
|
${message}
|
|
<sub>
|
|
<span class="far fa-clock"></span>
|
|
</sub>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
}
|
|
// upload image preview card.
|
|
function attachmentTemplate(fileType, fileName, imgURL = null) {
|
|
if (fileType != "image") {
|
|
return (
|
|
`
|
|
<div class="attachment-preview">
|
|
<span class="fas fa-times cancel"></span>
|
|
<p style="padding:0px 30px;"><span class="fas fa-file"></span> ` +
|
|
escapeHtml(fileName) +
|
|
`</p>
|
|
</div>
|
|
`
|
|
);
|
|
} else {
|
|
return (
|
|
`
|
|
<div class="attachment-preview">
|
|
<span class="fas fa-times cancel"></span>
|
|
<div class="image-file chat-image" style="background-image: url('` +
|
|
imgURL +
|
|
`');"></div>
|
|
<p><span class="fas fa-file-image"></span> ` +
|
|
escapeHtml(fileName) +
|
|
`</p>
|
|
</div>
|
|
`
|
|
);
|
|
}
|
|
}
|
|
|
|
// Active Status Circle
|
|
function activeStatusCircle() {
|
|
return `<span class="activeStatus"></span>`;
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Css Media Queries [For responsive design]
|
|
*-------------------------------------------------------------
|
|
*/
|
|
$(window).resize(function () {
|
|
cssMediaQueries();
|
|
});
|
|
function cssMediaQueries() {
|
|
if (window.matchMedia("(min-width: 980px)").matches) {
|
|
$(".messenger-listView").removeAttr("style");
|
|
}
|
|
if (window.matchMedia("(max-width: 980px)").matches) {
|
|
$("body")
|
|
.find(".messenger-list-item")
|
|
.find("tr[data-action]")
|
|
.attr("data-action", "1");
|
|
$("body").find(".favorite-list-item").find("div").attr("data-action", "1");
|
|
} else {
|
|
$("body")
|
|
.find(".messenger-list-item")
|
|
.find("tr[data-action]")
|
|
.attr("data-action", "0");
|
|
$("body").find(".favorite-list-item").find("div").attr("data-action", "0");
|
|
}
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* App Modal
|
|
*-------------------------------------------------------------
|
|
*/
|
|
let app_modal = function ({
|
|
show = true,
|
|
name,
|
|
data = 0,
|
|
buttons = true,
|
|
header = null,
|
|
body = null,
|
|
}) {
|
|
const modal = $(".app-modal[data-name=" + name + "]");
|
|
// header
|
|
header ? modal.find(".app-modal-header").html(header) : "";
|
|
|
|
// body
|
|
body ? modal.find(".app-modal-body").html(body) : "";
|
|
|
|
// buttons
|
|
buttons == true
|
|
? modal.find(".app-modal-footer").show()
|
|
: modal.find(".app-modal-footer").hide();
|
|
|
|
// show / hide
|
|
if (show == true) {
|
|
modal.show();
|
|
$(".app-modal-card[data-name=" + name + "]").addClass("app-show-modal");
|
|
$(".app-modal-card[data-name=" + name + "]").attr("data-modal", data);
|
|
} else {
|
|
modal.hide();
|
|
$(".app-modal-card[data-name=" + name + "]").removeClass("app-show-modal");
|
|
$(".app-modal-card[data-name=" + name + "]").attr("data-modal", data);
|
|
}
|
|
};
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Slide to bottom on [action] - e.g. [message received, sent, loaded]
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function scrollToBottom(container) {
|
|
$(container)
|
|
.stop()
|
|
.animate({
|
|
scrollTop: $(container)[0].scrollHeight,
|
|
});
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* click and drag to scroll - function
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function hScroller(scroller) {
|
|
const slider = document.querySelector(scroller);
|
|
let isDown = false;
|
|
let startX;
|
|
let scrollLeft;
|
|
|
|
slider.addEventListener("mousedown", (e) => {
|
|
isDown = true;
|
|
startX = e.pageX - slider.offsetLeft;
|
|
scrollLeft = slider.scrollLeft;
|
|
});
|
|
slider.addEventListener("mouseleave", () => {
|
|
isDown = false;
|
|
});
|
|
slider.addEventListener("mouseup", () => {
|
|
isDown = false;
|
|
});
|
|
slider.addEventListener("mousemove", (e) => {
|
|
if (!isDown) return;
|
|
e.preventDefault();
|
|
const x = e.pageX - slider.offsetLeft;
|
|
const walk = (x - startX) * 1;
|
|
slider.scrollLeft = scrollLeft - walk;
|
|
});
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Disable/enable message form fields, messaging container...
|
|
* on load info or if needed elsewhere.
|
|
*
|
|
* Default : true
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function disableOnLoad(disable = true) {
|
|
if (disable) {
|
|
// hide star button
|
|
$(".add-to-favorite").hide();
|
|
// hide send card
|
|
$(".messenger-sendCard").hide();
|
|
// add loading opacity to messages container
|
|
messagesContainer.css("opacity", ".5");
|
|
// disable message form fields
|
|
messageInput.attr("readonly", "readonly");
|
|
$("#message-form button").attr("disabled", "disabled");
|
|
$(".upload-attachment").attr("disabled", "disabled");
|
|
} else {
|
|
// show star button
|
|
if (getMessengerId() != auth_id) {
|
|
$(".add-to-favorite").show();
|
|
}
|
|
// show send card
|
|
$(".messenger-sendCard").show();
|
|
// remove loading opacity to messages container
|
|
messagesContainer.css("opacity", "1");
|
|
// enable message form fields
|
|
messageInput.removeAttr("readonly");
|
|
$("#message-form button").removeAttr("disabled");
|
|
$(".upload-attachment").removeAttr("disabled");
|
|
}
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Error message card
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function errorMessageCard(id) {
|
|
messagesContainer
|
|
.find(".message-card[data-id=" + id + "]")
|
|
.addClass("mc-error");
|
|
messagesContainer
|
|
.find(".message-card[data-id=" + id + "]")
|
|
.find("svg.loadingSVG")
|
|
.remove();
|
|
messagesContainer
|
|
.find(".message-card[data-id=" + id + "] p")
|
|
.prepend('<span class="fas fa-exclamation-triangle"></span>');
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Fetch id data (user/group) and update the view
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function IDinfo(id) {
|
|
// clear temporary message id
|
|
temporaryMsgId = 0;
|
|
// clear typing now
|
|
typingNow = 0;
|
|
// show loading bar
|
|
NProgress.start();
|
|
// disable message form
|
|
disableOnLoad();
|
|
if (messenger != 0) {
|
|
// get shared photos
|
|
getSharedPhotos(id);
|
|
// Get info
|
|
$.ajax({
|
|
url: url + "/idInfo",
|
|
method: "POST",
|
|
data: { _token: csrfToken, id },
|
|
dataType: "JSON",
|
|
success: (data) => {
|
|
if (!data?.fetch) {
|
|
NProgress.done();
|
|
NProgress.remove();
|
|
return;
|
|
}
|
|
// avatar photo
|
|
$(".messenger-infoView")
|
|
.find(".avatar")
|
|
.css("background-image", 'url("' + data.user_avatar + '")');
|
|
$(".header-avatar").css(
|
|
"background-image",
|
|
'url("' + data.user_avatar + '")'
|
|
);
|
|
// Show shared and actions
|
|
$(".messenger-infoView-btns .delete-conversation").show();
|
|
$(".messenger-infoView-shared").show();
|
|
// fetch messages
|
|
fetchMessages(id, true);
|
|
// focus on messaging input
|
|
messageInput.focus();
|
|
// update info in view
|
|
$(".messenger-infoView .info-name").text(data.fetch.name);
|
|
$(".m-header-messaging .user-name").text(data.fetch.name);
|
|
// Star status
|
|
data.favorite > 0
|
|
? $(".add-to-favorite").addClass("favorite")
|
|
: $(".add-to-favorite").removeClass("favorite");
|
|
// form reset and focus
|
|
$("#message-form").trigger("reset");
|
|
cancelAttachment();
|
|
messageInput.focus();
|
|
},
|
|
error: () => {
|
|
console.error("Couldn't fetch user data!");
|
|
// remove loading bar
|
|
NProgress.done();
|
|
NProgress.remove();
|
|
},
|
|
});
|
|
} else {
|
|
// remove loading bar
|
|
NProgress.done();
|
|
NProgress.remove();
|
|
}
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Send message function
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function sendMessage() {
|
|
temporaryMsgId += 1;
|
|
let tempID = `temp_${temporaryMsgId}`;
|
|
let hasFile = !!$(".upload-attachment").val();
|
|
const inputValue = $.trim(messageInput.val());
|
|
if (inputValue.length > 0 || hasFile) {
|
|
const formData = new FormData($("#message-form")[0]);
|
|
formData.append("id", getMessengerId());
|
|
formData.append("temporaryMsgId", tempID);
|
|
formData.append("_token", csrfToken);
|
|
$.ajax({
|
|
url: $("#message-form").attr("action"),
|
|
method: "POST",
|
|
data: formData,
|
|
dataType: "JSON",
|
|
processData: false,
|
|
contentType: false,
|
|
beforeSend: () => {
|
|
// remove message hint
|
|
$(".messages").find(".message-hint").hide();
|
|
// append a temporary message card
|
|
if (hasFile) {
|
|
messagesContainer
|
|
.find(".messages")
|
|
.append(
|
|
sendTempMessageCard(
|
|
inputValue + "\n" + loadingSVG("28px"),
|
|
tempID
|
|
)
|
|
);
|
|
} else {
|
|
messagesContainer
|
|
.find(".messages")
|
|
.append(sendTempMessageCard(inputValue, tempID));
|
|
}
|
|
// scroll to bottom
|
|
scrollToBottom(messagesContainer);
|
|
messageInput.css({ height: "42px" });
|
|
// form reset and focus
|
|
$("#message-form").trigger("reset");
|
|
cancelAttachment();
|
|
messageInput.focus();
|
|
},
|
|
success: (data) => {
|
|
if (data.error > 0) {
|
|
// message card error status
|
|
errorMessageCard(tempID);
|
|
console.error(data.error_msg);
|
|
} else {
|
|
// update contact item
|
|
updateContactItem(getMessengerId());
|
|
// temporary message card
|
|
const tempMsgCardElement = messagesContainer.find(
|
|
`.message-card[data-id=${data.tempID}]`
|
|
);
|
|
// add the message card coming from the server before the temp-card
|
|
tempMsgCardElement.before(data.message);
|
|
// then, remove the temporary message card
|
|
tempMsgCardElement.remove();
|
|
// scroll to bottom
|
|
scrollToBottom(messagesContainer);
|
|
// send contact item updates
|
|
sendContactItemUpdates(true);
|
|
}
|
|
},
|
|
error: () => {
|
|
// message card error status
|
|
errorMessageCard(tempID);
|
|
// error log
|
|
console.error(
|
|
"Failed sending the message! Please, check your server response."
|
|
);
|
|
},
|
|
});
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Fetch messages from database
|
|
*-------------------------------------------------------------
|
|
*/
|
|
let messagesPage = 1;
|
|
let noMoreMessages = false;
|
|
let messagesLoading = false;
|
|
function setMessagesLoading(loading = false) {
|
|
if (!loading) {
|
|
messagesContainer.find(".messages").find(".loading-messages").remove();
|
|
NProgress.done();
|
|
NProgress.remove();
|
|
} else {
|
|
messagesContainer
|
|
.find(".messages")
|
|
.prepend(loadingWithContainer("loading-messages"));
|
|
}
|
|
messagesLoading = loading;
|
|
}
|
|
function fetchMessages(id, newFetch = false) {
|
|
if (newFetch) {
|
|
messagesPage = 1;
|
|
noMoreMessages = false;
|
|
}
|
|
if (messenger != 0 && !noMoreMessages && !messagesLoading) {
|
|
const messagesElement = messagesContainer.find(".messages");
|
|
setMessagesLoading(true);
|
|
$.ajax({
|
|
url: url + "/fetchMessages",
|
|
method: "POST",
|
|
data: {
|
|
_token: csrfToken,
|
|
id: id,
|
|
page: messagesPage,
|
|
},
|
|
dataType: "JSON",
|
|
success: (data) => {
|
|
setMessagesLoading(false);
|
|
if (messagesPage == 1) {
|
|
messagesElement.html(data.messages);
|
|
scrollToBottom(messagesContainer);
|
|
} else {
|
|
const lastMsg = messagesElement.find(
|
|
messagesElement.find(".message-card")[0]
|
|
);
|
|
const curOffset =
|
|
lastMsg.offset().top - messagesContainer.scrollTop();
|
|
messagesElement.prepend(data.messages);
|
|
messagesContainer.scrollTop(lastMsg.offset().top - curOffset);
|
|
}
|
|
// trigger seen event
|
|
makeSeen(true);
|
|
// Pagination lock & messages page
|
|
noMoreMessages = messagesPage >= data?.last_page;
|
|
if (!noMoreMessages) messagesPage += 1;
|
|
// Enable message form if messenger not = 0; means if data is valid
|
|
if (messenger != 0) {
|
|
disableOnLoad(false);
|
|
}
|
|
},
|
|
error: (error) => {
|
|
setMessagesLoading(false);
|
|
console.error(error);
|
|
},
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Cancel file attached in the message.
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function cancelAttachment() {
|
|
$(".messenger-sendCard").find(".attachment-preview").remove();
|
|
$(".upload-attachment").replaceWith(
|
|
$(".upload-attachment").val("").clone(true)
|
|
);
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Cancel updating avatar in settings
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function cancelUpdatingAvatar() {
|
|
$(".upload-avatar-preview").css("background-image", defaultAvatarInSettings);
|
|
$(".upload-avatar").replaceWith($(".upload-avatar").val("").clone(true));
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Pusher channels and event listening..
|
|
*-------------------------------------------------------------
|
|
*/
|
|
|
|
// subscribe to the channel
|
|
const channelName = "private-chatify";
|
|
var channel = pusher.subscribe(`${channelName}.${auth_id}`);
|
|
var clientSendChannel;
|
|
var clientListenChannel;
|
|
|
|
function initClientChannel() {
|
|
if (getMessengerId()) {
|
|
clientSendChannel = pusher.subscribe(`${channelName}.${getMessengerId()}`);
|
|
clientListenChannel = pusher.subscribe(`${channelName}.${auth_id}`);
|
|
}
|
|
}
|
|
initClientChannel();
|
|
|
|
// Listen to messages, and append if data received
|
|
channel.bind("messaging", function (data) {
|
|
if (data.from_id == getMessengerId() && data.to_id == auth_id) {
|
|
$(".messages").find(".message-hint").remove();
|
|
messagesContainer.find(".messages").append(data.message);
|
|
scrollToBottom(messagesContainer);
|
|
makeSeen(true);
|
|
// remove unseen counter for the user from the contacts list
|
|
$(".messenger-list-item[data-contact=" + getMessengerId() + "]")
|
|
.find("tr>td>b")
|
|
.remove();
|
|
}
|
|
|
|
playNotificationSound(
|
|
"new_message",
|
|
!(data.from_id == getMessengerId() && data.to_id == auth_id)
|
|
);
|
|
});
|
|
|
|
// listen to typing indicator
|
|
clientListenChannel.bind("client-typing", function (data) {
|
|
if (data.from_id == getMessengerId() && data.to_id == auth_id) {
|
|
data.typing == true
|
|
? messagesContainer.find(".typing-indicator").show()
|
|
: messagesContainer.find(".typing-indicator").hide();
|
|
}
|
|
// scroll to bottom
|
|
scrollToBottom(messagesContainer);
|
|
});
|
|
|
|
// listen to seen event
|
|
clientListenChannel.bind("client-seen", function (data) {
|
|
if (data.from_id == getMessengerId() && data.to_id == auth_id) {
|
|
if (data.seen == true) {
|
|
$(".message-time")
|
|
.find(".fa-check")
|
|
.before('<span class="fas fa-check-double seen"></span> ');
|
|
$(".message-time").find(".fa-check").remove();
|
|
}
|
|
}
|
|
});
|
|
|
|
// listen to contact item updates event
|
|
clientListenChannel.bind("client-contactItem", function (data) {
|
|
if (data.to == auth_id) {
|
|
if (data.update) {
|
|
updateContactItem(data.from);
|
|
} else {
|
|
console.error("Can not update contact item!");
|
|
}
|
|
}
|
|
});
|
|
|
|
// listen on message delete event
|
|
clientListenChannel.bind("client-messageDelete", function (data) {
|
|
$("body").find(`.message-card[data-id=${data.id}]`).remove();
|
|
});
|
|
// listen on delete conversation event
|
|
clientListenChannel.bind("client-deleteConversation", function (data) {
|
|
if (data.from == getMessengerId() && data.to == auth_id) {
|
|
$("body").find(`.messages`).html("");
|
|
$(".messages").find(".message-hint").show();
|
|
}
|
|
});
|
|
// -------------------------------------
|
|
// presence channel [User Active Status]
|
|
var activeStatusChannel = pusher.subscribe("presence-activeStatus");
|
|
|
|
// Joined
|
|
activeStatusChannel.bind("pusher:member_added", function (member) {
|
|
setActiveStatus(1);
|
|
$(".messenger-list-item[data-contact=" + member.id + "]")
|
|
.find(".activeStatus")
|
|
.remove();
|
|
$(".messenger-list-item[data-contact=" + member.id + "]")
|
|
.find(".avatar")
|
|
.before(activeStatusCircle());
|
|
});
|
|
|
|
// Leaved
|
|
activeStatusChannel.bind("pusher:member_removed", function (member) {
|
|
setActiveStatus(0);
|
|
$(".messenger-list-item[data-contact=" + member.id + "]")
|
|
.find(".activeStatus")
|
|
.remove();
|
|
});
|
|
|
|
function handleVisibilityChange() {
|
|
if (!document.hidden) {
|
|
makeSeen(true);
|
|
}
|
|
}
|
|
|
|
document.addEventListener("visibilitychange", handleVisibilityChange, false);
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Trigger typing event
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function isTyping(status) {
|
|
return clientSendChannel.trigger("client-typing", {
|
|
from_id: auth_id, // Me
|
|
to_id: getMessengerId(), // Messenger
|
|
typing: status,
|
|
});
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Trigger seen event
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function makeSeen(status) {
|
|
if (document?.hidden) {
|
|
return;
|
|
}
|
|
// remove unseen counter for the user from the contacts list
|
|
$(".messenger-list-item[data-contact=" + getMessengerId() + "]")
|
|
.find("tr>td>b")
|
|
.remove();
|
|
// seen
|
|
$.ajax({
|
|
url: url + "/makeSeen",
|
|
method: "POST",
|
|
data: { _token: csrfToken, id: getMessengerId() },
|
|
dataType: "JSON",
|
|
});
|
|
return clientSendChannel.trigger("client-seen", {
|
|
from_id: auth_id, // Me
|
|
to_id: getMessengerId(), // Messenger
|
|
seen: status,
|
|
});
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Trigger contact item updates
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function sendContactItemUpdates(status) {
|
|
return clientSendChannel.trigger("client-contactItem", {
|
|
from: auth_id, // Me
|
|
to: getMessengerId(), // Messenger
|
|
update: status,
|
|
});
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Trigger message delete
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function sendMessageDeleteEvent(messageId) {
|
|
return clientSendChannel.trigger("client-messageDelete", {
|
|
id: messageId,
|
|
});
|
|
}
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Trigger delete conversation
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function sendDeleteConversationEvent() {
|
|
return clientSendChannel.trigger("client-deleteConversation", {
|
|
from: auth_id,
|
|
to: getMessengerId(),
|
|
});
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Check internet connection using pusher states
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function checkInternet(state, selector) {
|
|
let net_errs = 0;
|
|
const messengerTitle = $(".messenger-headTitle");
|
|
switch (state) {
|
|
case "connected":
|
|
if (net_errs < 1) {
|
|
messengerTitle.text(messengerTitleDefault);
|
|
selector.addClass("successBG-rgba");
|
|
selector.find("span").hide();
|
|
selector.slideDown("fast", function () {
|
|
selector.find(".ic-connected").show();
|
|
});
|
|
setTimeout(function () {
|
|
$(".internet-connection").slideUp("fast");
|
|
}, 3000);
|
|
}
|
|
break;
|
|
case "connecting":
|
|
messengerTitle.text($(".ic-connecting").text());
|
|
selector.removeClass("successBG-rgba");
|
|
selector.find("span").hide();
|
|
selector.slideDown("fast", function () {
|
|
selector.find(".ic-connecting").show();
|
|
});
|
|
net_errs = 1;
|
|
break;
|
|
// Not connected
|
|
default:
|
|
messengerTitle.text($(".ic-noInternet").text());
|
|
selector.removeClass("successBG-rgba");
|
|
selector.find("span").hide();
|
|
selector.slideDown("fast", function () {
|
|
selector.find(".ic-noInternet").show();
|
|
});
|
|
net_errs = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Get contacts
|
|
*-------------------------------------------------------------
|
|
*/
|
|
let contactsPage = 1;
|
|
let contactsLoading = false;
|
|
let noMoreContacts = false;
|
|
function setContactsLoading(loading = false) {
|
|
if (!loading) {
|
|
$(".listOfContacts").find(".loading-contacts").remove();
|
|
} else {
|
|
$(".listOfContacts").append(
|
|
`<div class="loading-contacts">${listItemLoading(4)}</div>`
|
|
);
|
|
}
|
|
contactsLoading = loading;
|
|
}
|
|
function getContacts() {
|
|
if (!contactsLoading && !noMoreContacts) {
|
|
setContactsLoading(true);
|
|
$.ajax({
|
|
url: url + "/getContacts",
|
|
method: "GET",
|
|
data: { _token: csrfToken, page: contactsPage },
|
|
dataType: "JSON",
|
|
success: (data) => {
|
|
setContactsLoading(false);
|
|
if (contactsPage < 2) {
|
|
$(".listOfContacts").html(data.contacts);
|
|
} else {
|
|
$(".listOfContacts").append(data.contacts);
|
|
}
|
|
updateSelectedContact();
|
|
// update data-action required with [responsive design]
|
|
cssMediaQueries();
|
|
// Pagination lock & messages page
|
|
noMoreContacts = contactsPage >= data?.last_page;
|
|
if (!noMoreContacts) contactsPage += 1;
|
|
},
|
|
error: (error) => {
|
|
setContactsLoading(false);
|
|
console.error(error);
|
|
},
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Update contact item
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function updateContactItem(user_id) {
|
|
if (user_id != auth_id) {
|
|
$.ajax({
|
|
url: url + "/updateContacts",
|
|
method: "POST",
|
|
data: {
|
|
_token: csrfToken,
|
|
user_id,
|
|
},
|
|
dataType: "JSON",
|
|
success: (data) => {
|
|
$(".listOfContacts")
|
|
.find(".messenger-list-item[data-contact=" + user_id + "]")
|
|
.remove();
|
|
if (data.contactItem) $(".listOfContacts").prepend(data.contactItem);
|
|
if (user_id == getMessengerId()) updateSelectedContact(user_id);
|
|
// show/hide message hint (empty state message)
|
|
const totalContacts =
|
|
$(".listOfContacts").find(".messenger-list-item")?.length || 0;
|
|
if (totalContacts > 0) {
|
|
$(".listOfContacts").find(".message-hint").hide();
|
|
} else {
|
|
$(".listOfContacts").find(".message-hint").show();
|
|
}
|
|
// update data-action required with [responsive design]
|
|
cssMediaQueries();
|
|
},
|
|
error: (error) => {
|
|
console.error(error);
|
|
},
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Star
|
|
*-------------------------------------------------------------
|
|
*/
|
|
|
|
function star(user_id) {
|
|
if (getMessengerId() != auth_id) {
|
|
$.ajax({
|
|
url: url + "/star",
|
|
method: "POST",
|
|
data: { _token: csrfToken, user_id: user_id },
|
|
dataType: "JSON",
|
|
success: (data) => {
|
|
data.status > 0
|
|
? $(".add-to-favorite").addClass("favorite")
|
|
: $(".add-to-favorite").removeClass("favorite");
|
|
},
|
|
error: () => {
|
|
console.error("Server error, check your response");
|
|
},
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Get favorite list
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function getFavoritesList() {
|
|
$(".messenger-favorites").html(avatarLoading(4));
|
|
$.ajax({
|
|
url: url + "/favorites",
|
|
method: "POST",
|
|
data: { _token: csrfToken },
|
|
dataType: "JSON",
|
|
success: (data) => {
|
|
if (data.count > 0) {
|
|
$(".favorites-section").show();
|
|
$(".messenger-favorites").html(data.favorites);
|
|
} else {
|
|
$(".favorites-section").hide();
|
|
}
|
|
// update data-action required with [responsive design]
|
|
cssMediaQueries();
|
|
},
|
|
error: () => {
|
|
console.error("Server error, check your response");
|
|
},
|
|
});
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Get shared photos
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function getSharedPhotos(user_id) {
|
|
$.ajax({
|
|
url: url + "/shared",
|
|
method: "POST",
|
|
data: { _token: csrfToken, user_id: user_id },
|
|
dataType: "JSON",
|
|
success: (data) => {
|
|
$(".shared-photos-list").html(data.shared);
|
|
},
|
|
error: () => {
|
|
console.error("Server error, check your response");
|
|
},
|
|
});
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Search in messenger
|
|
*-------------------------------------------------------------
|
|
*/
|
|
let searchPage = 1;
|
|
let noMoreDataSearch = false;
|
|
let searchLoading = false;
|
|
let searchTempVal = "";
|
|
function setSearchLoading(loading = false) {
|
|
if (!loading) {
|
|
$(".search-records").find(".loading-search").remove();
|
|
} else {
|
|
$(".search-records").append(
|
|
`<div class="loading-search">${listItemLoading(4)}</div>`
|
|
);
|
|
}
|
|
searchLoading = loading;
|
|
}
|
|
function messengerSearch(input) {
|
|
if (input != searchTempVal) {
|
|
searchPage = 1;
|
|
noMoreDataSearch = false;
|
|
searchLoading = false;
|
|
}
|
|
searchTempVal = input;
|
|
if (!searchLoading && !noMoreDataSearch) {
|
|
if (searchPage < 2) {
|
|
$(".search-records").html("");
|
|
}
|
|
setSearchLoading(true);
|
|
$.ajax({
|
|
url: url + "/search",
|
|
method: "GET",
|
|
data: { _token: csrfToken, input: input, page: searchPage },
|
|
dataType: "JSON",
|
|
success: (data) => {
|
|
setSearchLoading(false);
|
|
if (searchPage < 2) {
|
|
$(".search-records").html(data.records);
|
|
} else {
|
|
$(".search-records").append(data.records);
|
|
}
|
|
// update data-action required with [responsive design]
|
|
cssMediaQueries();
|
|
// Pagination lock & messages page
|
|
noMoreDataSearch = searchPage >= data?.last_page;
|
|
if (!noMoreDataSearch) searchPage += 1;
|
|
},
|
|
error: (error) => {
|
|
setSearchLoading(false);
|
|
console.error(error);
|
|
},
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Delete Conversation
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function deleteConversation(id) {
|
|
$.ajax({
|
|
url: url + "/deleteConversation",
|
|
method: "POST",
|
|
data: { _token: csrfToken, id: id },
|
|
dataType: "JSON",
|
|
beforeSend: () => {
|
|
// hide delete modal
|
|
app_modal({
|
|
show: false,
|
|
name: "delete",
|
|
});
|
|
// Show waiting alert modal
|
|
app_modal({
|
|
show: true,
|
|
name: "alert",
|
|
buttons: false,
|
|
body: loadingSVG("32px", null, "margin:auto"),
|
|
});
|
|
},
|
|
success: (data) => {
|
|
// delete contact from the list
|
|
$(".listOfContacts")
|
|
.find(".messenger-list-item[data-contact=" + id + "]")
|
|
.remove();
|
|
// refresh info
|
|
IDinfo(id);
|
|
|
|
if (!data.deleted)
|
|
return alert("Error occurred, messages can not be deleted!");
|
|
|
|
// Hide waiting alert modal
|
|
app_modal({
|
|
show: false,
|
|
name: "alert",
|
|
buttons: true,
|
|
body: "",
|
|
});
|
|
|
|
sendDeleteConversationEvent();
|
|
|
|
// update contact list item
|
|
sendContactItemUpdates(true);
|
|
},
|
|
error: () => {
|
|
console.error("Server error, check your response");
|
|
},
|
|
});
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Delete Message By ID
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function deleteMessage(id) {
|
|
$.ajax({
|
|
url: url + "/deleteMessage",
|
|
method: "POST",
|
|
data: { _token: csrfToken, id: id },
|
|
dataType: "JSON",
|
|
beforeSend: () => {
|
|
// hide delete modal
|
|
app_modal({
|
|
show: false,
|
|
name: "delete",
|
|
});
|
|
// Show waiting alert modal
|
|
app_modal({
|
|
show: true,
|
|
name: "alert",
|
|
buttons: false,
|
|
body: loadingSVG("32px", null, "margin:auto"),
|
|
});
|
|
},
|
|
success: (data) => {
|
|
$(".messages").find(`.message-card[data-id=${id}]`).remove();
|
|
if (!data.deleted)
|
|
console.error("Error occurred, message can not be deleted!");
|
|
|
|
sendMessageDeleteEvent(id);
|
|
|
|
// Hide waiting alert modal
|
|
app_modal({
|
|
show: false,
|
|
name: "alert",
|
|
buttons: true,
|
|
body: "",
|
|
});
|
|
},
|
|
error: () => {
|
|
console.error("Server error, check your response");
|
|
},
|
|
});
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Update Settings
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function updateSettings() {
|
|
const formData = new FormData($("#update-settings")[0]);
|
|
if (messengerColor) {
|
|
formData.append("messengerColor", messengerColor);
|
|
}
|
|
if (dark_mode) {
|
|
formData.append("dark_mode", dark_mode);
|
|
}
|
|
$.ajax({
|
|
url: url + "/updateSettings",
|
|
method: "POST",
|
|
data: formData,
|
|
dataType: "JSON",
|
|
processData: false,
|
|
contentType: false,
|
|
beforeSend: () => {
|
|
// close settings modal
|
|
app_modal({
|
|
show: false,
|
|
name: "settings",
|
|
});
|
|
// Show waiting alert modal
|
|
app_modal({
|
|
show: true,
|
|
name: "alert",
|
|
buttons: false,
|
|
body: loadingSVG("32px", null, "margin:auto"),
|
|
});
|
|
},
|
|
success: (data) => {
|
|
if (data.error) {
|
|
// Show error message in alert modal
|
|
app_modal({
|
|
show: true,
|
|
name: "alert",
|
|
buttons: true,
|
|
body: data.msg,
|
|
});
|
|
} else {
|
|
// Hide alert modal
|
|
app_modal({
|
|
show: false,
|
|
name: "alert",
|
|
buttons: true,
|
|
body: "",
|
|
});
|
|
|
|
// reload the page
|
|
location.reload(true);
|
|
}
|
|
},
|
|
error: () => {
|
|
console.error("Server error, check your response");
|
|
},
|
|
});
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Set Active status
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function setActiveStatus(status) {
|
|
$.ajax({
|
|
url: url + "/setActiveStatus",
|
|
method: "POST",
|
|
data: { _token: csrfToken, status: status },
|
|
dataType: "JSON",
|
|
success: (data) => {
|
|
// Nothing to do
|
|
},
|
|
error: () => {
|
|
console.error("Server error, check your response");
|
|
},
|
|
});
|
|
}
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* On DOM ready
|
|
*-------------------------------------------------------------
|
|
*/
|
|
$(document).ready(function () {
|
|
// get contacts list
|
|
getContacts();
|
|
|
|
// get contacts list
|
|
getFavoritesList();
|
|
|
|
// Clear typing timeout
|
|
clearTimeout(typingTimeout);
|
|
|
|
// NProgress configurations
|
|
NProgress.configure({ showSpinner: false, minimum: 0.7, speed: 500 });
|
|
|
|
// make message input autosize.
|
|
autosize($(".m-send"));
|
|
|
|
// check if pusher has access to the channel [Internet status]
|
|
pusher.connection.bind("state_change", function (states) {
|
|
let selector = $(".internet-connection");
|
|
checkInternet(states.current, selector);
|
|
// listening for pusher:subscription_succeeded
|
|
channel.bind("pusher:subscription_succeeded", function () {
|
|
// On connection state change [Updating] and get [info & msgs]
|
|
if (getMessengerId() != 0) {
|
|
if (
|
|
$(".messenger-list-item")
|
|
.find("tr[data-action]")
|
|
.attr("data-action") == "1"
|
|
) {
|
|
$(".messenger-listView").hide();
|
|
}
|
|
IDinfo(getMessengerId());
|
|
}
|
|
});
|
|
});
|
|
|
|
// tabs on click, show/hide...
|
|
$(".messenger-listView-tabs a").on("click", function () {
|
|
var dataView = $(this).attr("data-view");
|
|
$(".messenger-listView-tabs a").removeClass("active-tab");
|
|
$(this).addClass("active-tab");
|
|
$(".messenger-tab").hide();
|
|
$(".messenger-tab[data-view=" + dataView + "]").show();
|
|
});
|
|
|
|
// set item active on click
|
|
$("body").on("click", ".messenger-list-item", function () {
|
|
$(".messenger-list-item").removeClass("m-list-active");
|
|
$(this).addClass("m-list-active");
|
|
const userID = $(this).attr("data-contact");
|
|
routerPush(document.title, `${url}/${userID}`);
|
|
updateSelectedContact(userID);
|
|
});
|
|
|
|
// show info side button
|
|
$(".messenger-infoView nav a , .show-infoSide").on("click", function () {
|
|
$(".messenger-infoView").toggle();
|
|
});
|
|
|
|
// make favorites card dragable on click to slide.
|
|
hScroller(".messenger-favorites");
|
|
|
|
// click action for list item [user/group]
|
|
$("body").on("click", ".messenger-list-item", function () {
|
|
if ($(this).find("tr[data-action]").attr("data-action") == "1") {
|
|
$(".messenger-listView").hide();
|
|
}
|
|
const dataId = $(this).find("p[data-id]").attr("data-id");
|
|
setMessengerId(dataId);
|
|
IDinfo(dataId);
|
|
});
|
|
|
|
// click action for favorite button
|
|
$("body").on("click", ".favorite-list-item", function () {
|
|
if ($(this).find("div").attr("data-action") == "1") {
|
|
$(".messenger-listView").hide();
|
|
}
|
|
const uid = $(this).find("div.avatar").attr("data-id");
|
|
setMessengerId(uid);
|
|
IDinfo(uid);
|
|
updateSelectedContact(uid);
|
|
routerPush(document.title, `${url}/${uid}`);
|
|
});
|
|
|
|
// list view buttons
|
|
$(".listView-x").on("click", function () {
|
|
$(".messenger-listView").hide();
|
|
});
|
|
$(".show-listView").on("click", function () {
|
|
routerPush(document.title, `${url}/`);
|
|
$(".messenger-listView").show();
|
|
});
|
|
|
|
// click action for [add to favorite] button.
|
|
$(".add-to-favorite").on("click", function () {
|
|
star(getMessengerId());
|
|
});
|
|
|
|
// calling Css Media Queries
|
|
cssMediaQueries();
|
|
|
|
// message form on submit.
|
|
$("#message-form").on("submit", (e) => {
|
|
e.preventDefault();
|
|
sendMessage();
|
|
});
|
|
|
|
// message input on keyup [Enter to send, Enter+Shift for new line]
|
|
$("#message-form .m-send").on("keyup", (e) => {
|
|
// if enter key pressed.
|
|
if (e.which == 13 || e.keyCode == 13) {
|
|
// if shift + enter key pressed, do nothing (new line).
|
|
// if only enter key pressed, send message.
|
|
if (!e.shiftKey) {
|
|
triggered = isTyping(false);
|
|
sendMessage();
|
|
}
|
|
}
|
|
});
|
|
|
|
// On [upload attachment] input change, show a preview of the image/file.
|
|
$("body").on("change", ".upload-attachment", (e) => {
|
|
let file = e.target.files[0];
|
|
if (!attachmentValidate(file)) return false;
|
|
let reader = new FileReader();
|
|
let sendCard = $(".messenger-sendCard");
|
|
reader.readAsDataURL(file);
|
|
reader.addEventListener("loadstart", (e) => {
|
|
$("#message-form").before(loadingSVG());
|
|
});
|
|
reader.addEventListener("load", (e) => {
|
|
$(".messenger-sendCard").find(".loadingSVG").remove();
|
|
if (!file.type.match("image.*")) {
|
|
// if the file not image
|
|
sendCard.find(".attachment-preview").remove(); // older one
|
|
sendCard.prepend(attachmentTemplate("file", file.name));
|
|
} else {
|
|
// if the file is an image
|
|
sendCard.find(".attachment-preview").remove(); // older one
|
|
sendCard.prepend(
|
|
attachmentTemplate("image", file.name, e.target.result)
|
|
);
|
|
}
|
|
});
|
|
});
|
|
|
|
function attachmentValidate(file) {
|
|
const fileElement = $(".upload-attachment");
|
|
const { name: fileName, size: fileSize } = file;
|
|
const fileExtension = fileName.split(".").pop();
|
|
if (
|
|
!chatify.allAllowedExtensions.includes(
|
|
fileExtension.toString().toLowerCase()
|
|
)
|
|
) {
|
|
alert("file type not allowed");
|
|
fileElement.val("");
|
|
return false;
|
|
}
|
|
// Validate file size.
|
|
if (fileSize > chatify.maxUploadSize) {
|
|
alert("File is too large!");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
// Attachment preview cancel button.
|
|
$("body").on("click", ".attachment-preview .cancel", () => {
|
|
cancelAttachment();
|
|
});
|
|
|
|
// typing indicator on [input] keyDown
|
|
$("#message-form .m-send").on("keydown", () => {
|
|
if (typingNow < 1) {
|
|
isTyping(true);
|
|
typingNow = 1;
|
|
}
|
|
clearTimeout(typingTimeout);
|
|
typingTimeout = setTimeout(function () {
|
|
isTyping(false);
|
|
typingNow = 0;
|
|
}, 1000);
|
|
});
|
|
|
|
// Image modal
|
|
$("body").on("click", ".chat-image", function () {
|
|
let src = $(this).css("background-image").split(/"/)[1];
|
|
$("#imageModalBox").show();
|
|
$("#imageModalBoxSrc").attr("src", src);
|
|
});
|
|
$(".imageModal-close").on("click", function () {
|
|
$("#imageModalBox").hide();
|
|
});
|
|
|
|
// Search input on focus
|
|
$(".messenger-search").on("focus", function () {
|
|
$(".messenger-tab").hide();
|
|
$('.messenger-tab[data-view="search"]').show();
|
|
});
|
|
$(".messenger-search").on("blur", function () {
|
|
setTimeout(function () {
|
|
$(".messenger-tab").hide();
|
|
$('.messenger-tab[data-view="users"]').show();
|
|
}, 200);
|
|
});
|
|
// Search action on keyup
|
|
const debouncedSearch = debounce(function () {
|
|
const value = $(".messenger-search").val();
|
|
messengerSearch(value);
|
|
}, 500);
|
|
$(".messenger-search").on("keyup", function (e) {
|
|
const value = $(this).val();
|
|
if ($.trim(value).length > 0) {
|
|
$(".messenger-search").trigger("focus");
|
|
debouncedSearch();
|
|
} else {
|
|
$(".messenger-tab").hide();
|
|
$('.messenger-listView-tabs a[data-view="users"]').trigger("click");
|
|
}
|
|
});
|
|
|
|
// Delete Conversation button
|
|
$(".messenger-infoView-btns .delete-conversation").on("click", function () {
|
|
app_modal({
|
|
name: "delete",
|
|
});
|
|
});
|
|
// Delete Message Button
|
|
$("body").on("click", ".message-card .actions .delete-btn", function () {
|
|
app_modal({
|
|
name: "delete",
|
|
data: $(this).data("id"),
|
|
});
|
|
});
|
|
// Delete modal [on delete button click]
|
|
$(".app-modal[data-name=delete]")
|
|
.find(".app-modal-footer .delete")
|
|
.on("click", function () {
|
|
const id = $("body")
|
|
.find(".app-modal[data-name=delete]")
|
|
.find(".app-modal-card")
|
|
.attr("data-modal");
|
|
if (id == 0) {
|
|
deleteConversation(getMessengerId());
|
|
} else {
|
|
deleteMessage(id);
|
|
}
|
|
app_modal({
|
|
show: false,
|
|
name: "delete",
|
|
});
|
|
});
|
|
// delete modal [cancel button]
|
|
$(".app-modal[data-name=delete]")
|
|
.find(".app-modal-footer .cancel")
|
|
.on("click", function () {
|
|
app_modal({
|
|
show: false,
|
|
name: "delete",
|
|
});
|
|
});
|
|
|
|
// Settings button action to show settings modal
|
|
$("body").on("click", ".settings-btn", function (e) {
|
|
e.preventDefault();
|
|
app_modal({
|
|
show: true,
|
|
name: "settings",
|
|
});
|
|
});
|
|
|
|
// on submit settings' form
|
|
$("#update-settings").on("submit", (e) => {
|
|
e.preventDefault();
|
|
updateSettings();
|
|
});
|
|
// Settings modal [cancel button]
|
|
$(".app-modal[data-name=settings]")
|
|
.find(".app-modal-footer .cancel")
|
|
.on("click", function () {
|
|
app_modal({
|
|
show: false,
|
|
name: "settings",
|
|
});
|
|
cancelUpdatingAvatar();
|
|
});
|
|
// upload avatar on change
|
|
$("body").on("change", ".upload-avatar", (e) => {
|
|
// store the original avatar
|
|
if (defaultAvatarInSettings == null) {
|
|
defaultAvatarInSettings = $(".upload-avatar-preview").css(
|
|
"background-image"
|
|
);
|
|
}
|
|
let file = e.target.files[0];
|
|
if (!attachmentValidate(file)) return false;
|
|
let reader = new FileReader();
|
|
reader.readAsDataURL(file);
|
|
reader.addEventListener("loadstart", (e) => {
|
|
$(".upload-avatar-preview").append(
|
|
loadingSVG("42px", "upload-avatar-loading")
|
|
);
|
|
});
|
|
reader.addEventListener("load", (e) => {
|
|
$(".upload-avatar-preview").find(".loadingSVG").remove();
|
|
if (!file.type.match("image.*")) {
|
|
// if the file is not an image
|
|
console.error("File you selected is not an image!");
|
|
} else {
|
|
// if the file is an image
|
|
$(".upload-avatar-preview").css(
|
|
"background-image",
|
|
'url("' + e.target.result + '")'
|
|
);
|
|
}
|
|
});
|
|
});
|
|
// change messenger color button
|
|
$("body").on("click", ".update-messengerColor .color-btn", function () {
|
|
messengerColor = $(this).attr("data-color");
|
|
$(".update-messengerColor .color-btn").removeClass("m-color-active");
|
|
$(this).addClass("m-color-active");
|
|
});
|
|
// Switch to Dark/Light mode
|
|
$("body").on("click", ".dark-mode-switch", function () {
|
|
if ($(this).attr("data-mode") == "0") {
|
|
$(this).attr("data-mode", "1");
|
|
$(this).removeClass("far");
|
|
$(this).addClass("fas");
|
|
dark_mode = "dark";
|
|
} else {
|
|
$(this).attr("data-mode", "0");
|
|
$(this).removeClass("fas");
|
|
$(this).addClass("far");
|
|
dark_mode = "light";
|
|
}
|
|
});
|
|
|
|
//Messages pagination
|
|
actionOnScroll(
|
|
".m-body.messages-container",
|
|
function () {
|
|
fetchMessages(getMessengerId());
|
|
},
|
|
true
|
|
);
|
|
//Contacts pagination
|
|
actionOnScroll(".messenger-tab.users-tab", function () {
|
|
getContacts();
|
|
});
|
|
//Search pagination
|
|
actionOnScroll(".messenger-tab.search-tab", function () {
|
|
messengerSearch($(".messenger-search").val());
|
|
});
|
|
});
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Observer on DOM changes
|
|
*-------------------------------------------------------------
|
|
*/
|
|
let previousMessengerId = getMessengerId();
|
|
const observer = new MutationObserver(function (mutations) {
|
|
if (getMessengerId() !== previousMessengerId) {
|
|
previousMessengerId = getMessengerId();
|
|
initClientChannel();
|
|
}
|
|
});
|
|
const config = { subtree: true, childList: true };
|
|
|
|
// start listening to changes
|
|
observer.observe(document, config);
|
|
|
|
// stop listening to changes
|
|
// observer.disconnect();
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Resize messaging area when resize the viewport.
|
|
* on mobile devices when the keyboard is shown, the viewport
|
|
* height is changed, so we need to resize the messaging area
|
|
* to fit the new height.
|
|
*-------------------------------------------------------------
|
|
*/
|
|
var resizeTimeout;
|
|
window.visualViewport.addEventListener("resize", (e) => {
|
|
clearTimeout(resizeTimeout);
|
|
resizeTimeout = setTimeout(function () {
|
|
const h = e.target.height;
|
|
if (h) {
|
|
$(".messenger-messagingView").css({ height: h + "px" });
|
|
}
|
|
}, 100);
|
|
});
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Emoji Picker
|
|
*-------------------------------------------------------------
|
|
*/
|
|
const emojiButton = document.querySelector(".emoji-button");
|
|
|
|
const emojiPicker = new EmojiButton({
|
|
theme: messengerTheme,
|
|
autoHide: false,
|
|
position: "top-start",
|
|
});
|
|
|
|
emojiButton.addEventListener("click", (e) => {
|
|
e.preventDefault();
|
|
emojiPicker.togglePicker(emojiButton);
|
|
});
|
|
|
|
emojiPicker.on("emoji", (emoji) => {
|
|
const el = messageInput[0];
|
|
const startPos = el.selectionStart;
|
|
const endPos = el.selectionEnd;
|
|
const value = messageInput.val();
|
|
const newValue =
|
|
value.substring(0, startPos) +
|
|
emoji +
|
|
value.substring(endPos, value.length);
|
|
messageInput.val(newValue);
|
|
el.selectionStart = el.selectionEnd = startPos + emoji.length;
|
|
el.focus();
|
|
});
|
|
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Notification sounds
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function playNotificationSound(soundName, condition = false) {
|
|
if ((document.hidden || condition) && chatify.sounds.enabled) {
|
|
const sound = new Audio(
|
|
`/${chatify.sounds.public_path}/${chatify.sounds[soundName]}`
|
|
);
|
|
sound.play();
|
|
}
|
|
}
|
|
/**
|
|
*-------------------------------------------------------------
|
|
* Update and format dates to time ago.
|
|
*-------------------------------------------------------------
|
|
*/
|
|
function updateElementsDateToTimeAgo() {
|
|
$(".message-time").each(function () {
|
|
const time = $(this).attr("data-time");
|
|
$(this).find(".time").text(dateStringToTimeAgo(time));
|
|
});
|
|
$(".contact-item-time").each(function () {
|
|
const time = $(this).attr("data-time");
|
|
$(this).text(dateStringToTimeAgo(time));
|
|
});
|
|
}
|
|
setInterval(() => {
|
|
updateElementsDateToTimeAgo();
|
|
}, 60000);
|