$(document).ready(function() {
$(document).on("input", ".msg-textarea-input", function() {
const msg_input = $(this);
clearTimeout(msg_input.data('timer'));
const timer = setTimeout(() => {
const parentMsg = (isMobile) ? '.l-replyItem__main' : '.l-leaveMsg__msg';
const sendBtn = msg_input.closest(parentMsg).find('.send_msg, .send_edit_msg');
const currentTags = sendBtn.data('tags') || [];
if (currentTags.length >= 10) {
close_tag_user();
return;
}
const msg_input_val = msg_input.val();
const caretPos = msg_input[0].selectionStart;
const match_tag = msg_input_val.substring(0, caretPos).match(/(?:^|\s)@([^@\s\r\t\n\f]*)$/);
if (match_tag == null || match_tag[1].length > 60) {
close_tag_user();
return;
}
const coordinates = get_CaretOffest(msg_input[0], caretPos);
show_taguser_list(msg_input, coordinates, match_tag[1]);
}, 500);
msg_input.data('timer', timer);
});
$(document).on("keydown", ".msg-textarea-input", function(e) {
const msg_input = $(this);
const caretPos = msg_input[0].selectionStart;
if (msg_input[0].selectionStart != msg_input[0].selectionEnd) {
return;
}
if (e.key === 'Escape' && ($('.msg_taguser_list.is-active, .search_all_user_list.is-active, .tag_search_box.is-active').length)) {
close_tag_user();
return;
}
remove_tag_info(e, msg_input, caretPos);
})
$(document).on('click', function(e) {
const $target = $(e.target);
const isInsideList = $target.closest('.msg_taguser_list.is-active, .search_all_user_list.is-active, .tag_search_box.is-active').length > 0;
if (!isInsideList) {
close_tag_user();
}
})
$(document).on('click', '.msg_taguser_link', function() {
$(".msg_taguser_list, .search_all_user_list").removeClass('is-active');
const $this = $(this);
const uid = $this.data('id');
const uname = $this.data("uname");
const parentMsg = (isMobile) ? '.l-replyItem__main' : '.l-leaveMsg__msg';
const msg_input = $this.closest(parentMsg).find('.msg-textarea-input');
const sendBtn = $this.closest(parentMsg).find('.send_msg, .send_edit_msg');
const caretPos = msg_input[0].selectionStart;
const currentValue = msg_input.val();
const match_tag = currentValue.substring(0, caretPos).match(/(?:^|\s)@([^@\s\r\t\n\f]*)$/);
const insertText = `@${uname} `;
msg_input.val(currentValue.substring(0, caretPos - (match_tag[1].length + 1)) + insertText + currentValue.substring(caretPos));
msg_input[0].setSelectionRange(caretPos - (match_tag[1].length + 1) + insertText.length, caretPos - (match_tag[1].length + 1) + insertText.length);
msg_input.focus();
let currentTags = sendBtn.data('tags') || [];
const isExist = currentTags.some(function(tag) {
return tag.uid === uid;
});
if (!isExist) {
currentTags.push({ uid: uid, uname: uname });
sendBtn.data('tags', currentTags);
}
});
$(document).on('click', '.tag_search_box', function() {
$(".tag_search_box").removeClass('is-active');
const msg_input = $(this).siblings('.msg-textarea-input');
const msg_input_val = msg_input.val();
const caretPos = msg_input[0].selectionStart;
const match_tag = msg_input_val.substring(0, caretPos).match(/(?:^|\s)@([^@\s\r\t\n\f]*)$/);
if (match_tag == null || match_tag[1].length > 60) {
return;
}
const coordinates = get_CaretOffest(msg_input[0], caretPos);
show_taguser_list(msg_input, coordinates, match_tag[1], true);
msg_input.focus();
});
});
function remove_tag_info(event, msg_input, caretPos) {
const msg_input_val = msg_input.val();
const parentSelector = (isMobile) ? '.l-replyItem__main' : '.l-leaveMsg__msg';
const sendBtn = msg_input.closest(parentSelector).find('.send_msg, .send_edit_msg');
let currentTags = sendBtn.data('tags') || [];
if (currentTags.length === 0) return;
let match = null;
let newText = '';
let newCaretPos = caretPos;
let deletedUname = null;
if (event.key === 'Backspace' && caretPos > 0) {
const beforeCaret = msg_input_val.substring(0, caretPos);
for (let i = 0; i < currentTags.length; i++) {
const tag = currentTags[i];
const escapedUname = tag.uname.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const regex = new RegExp(`@${escapedUname}\\s?$`);
const m = beforeCaret.match(regex);
if (m) {
match = m;
deletedUname = tag.uname;
const matchLength = match[0].length;
newText = msg_input_val.substring(0, caretPos - matchLength) + msg_input_val.substring(caretPos);
newCaretPos = caretPos - matchLength;
break;
}
}
} else if (event.key === 'Delete' && caretPos < msg_input_val.length) {
const afterCaret = msg_input_val.substring(caretPos);
for (let i = 0; i < currentTags.length; i++) {
const tag = currentTags[i];
const escapedUname = tag.uname.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const regex = new RegExp(`^@${escapedUname}\\s?`);
const m = afterCaret.match(regex);
if (m) {
match = m;
deletedUname = tag.uname;
const matchLength = match[0].length;
newText = msg_input_val.substring(0, caretPos) + msg_input_val.substring(caretPos + matchLength);
break;
}
}
}
if (!match) return;
event.preventDefault();
msg_input.val(newText);
msg_input[0].setSelectionRange(newCaretPos, newCaretPos);
const escapedDeletedUname = deletedUname.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const stillExists = new RegExp(`@${escapedDeletedUname}(?:\\s|$)`).test(newText);
if (!stillExists) {
currentTags = currentTags.filter(function(tag) { return tag.uname !== deletedUname; });
sendBtn.data('tags', currentTags);
}
}
async function show_taguser_list(msg_input, coordinates, match_name, search_all_user = false) {
match_name = match_name.replace(/[\s\u00A0]/g, ' ');
if (msg_input.siblings('.msg_taguser_list').length == 0 || search_all_user) {
const post_obj = {
'pid' : msg_input.data('pid'),
'search_all_user' : (search_all_user) ? match_name : '',
}
const result = await $.post('/ajax/forum/message_users.php', post_obj, null, 'json');
if (result.status === 'success' && result.data.length > 0) {
let list_class = 'msg_taguser_list';
if (search_all_user) {
list_class = 'search_all_user_list';
$('.search_all_user_list').remove();
}
renderTagUserList(msg_input, result.data, coordinates, list_class);
} else if (search_all_user && result.status === 'no data') {
showTagUserEmpty(msg_input, coordinates);
return;
}
} else {
msg_input.siblings('.msg_taguser_list').addClass('is-active').css({'margin-left' : ((coordinates.width_limit) ? coordinates.left - msg_input.siblings('.msg_taguser_list .c-group__options')[0].offsetWidth + 'px' : coordinates.left + 'px')});
}
if (msg_input.siblings('.msg_taguser_list').length == 0 || search_all_user) return;
$('.msg_taguser_list .c-group__options').scrollTop(0);
if (search_match_name(msg_input, match_name) == 0) {
$(".msg_taguser_list").removeClass('is-active');
if (match_name.trim().length <= 0 || match_name.trim().length > 60) return;
showSearchBox(msg_input, coordinates);
}
}
function get_CaretOffest(element, position) {
let div = document.createElement('div');
div.id = 'input-textarea-position-div';
document.body.appendChild(div);
const properties = [
'font-family', 'font-size', 'font-weight', 'letter-spacing', 'line-height',
'text-transform', 'text-indent', 'text-align', 'direction',
'white-space', 'word-spacing', 'word-wrap',
'box-sizing', 'width', 'height',
'padding-top', 'padding-right', 'padding-bottom', 'padding-left',
'border-top-width', 'border-right-width', 'border-bottom-width', 'border-left-width'
];
const style = div.style;
const computed = window.getComputedStyle(element);
properties.forEach(prop => style[prop] = computed[prop]);
div.innerHTML = element.value.substring(0, position)
.replace(/&/g, "&")
.replace(//g, ">")
.replace(/"/g, """)
.replace(/'/g, "'")
.replace(/\n$/g, '\n ')
.replace(/\r\n|\r|\n/g, '
');
var span = document.createElement('span');
span.textContent = '.';
div.appendChild(span);
var coordinates = {
width_limit: div.clientWidth * 0.8 - span.offsetLeft < 0,
left: span.offsetLeft,
};
document.body.removeChild(div);
return coordinates;
}
function renderTagUserList(msg_input, data, coordinates, list_class) {
const items = data
.map(
(v) => `
${v.uname}
`
)
.join('');
const html = `