function formatDate(d) { return d.toLocaleTimeString([], {hour: '2-digit', minute:'2-digit'}) } for (const e of timestamps) { e.innerHTML = formatDate(new Date(e.dataset.time*1000)); }; const ua = window.navigator.userAgent const socket = io() const chatline = document.getElementsByClassName('chat-line')[0] const box = document.getElementById('chat-window') const ta = document.getElementById('input-text-chat') const vid = document.getElementById('vid').value const slurreplacer = document.getElementById('slurreplacer').value let is_typing = false; const blocked_user_ids = document.getElementById('blocked_user_ids').value.split(', ') socket.on('speak', function(json) { if (blocked_user_ids.includes(json.user_id.toString())) { return } let text let text_html if (slurreplacer != '0') { text = json.text_censored text_html = json.text_html_censored } else { text = json.text text_html = json.text_html } chatline.classList.remove('chat-mention'); if (text_html.includes(` ${u[1]}` } const online_el = document.getElementById('online') if (online_el) { online_el.innerHTML = online bs_trigger(online_el) } document.getElementById('online3').innerHTML = online bs_trigger(document.getElementById('online3')) }) let timer_id; function remove_typing() { is_typing = false; socket.emit('typing', false); } ta.addEventListener("input", function() { text = ta.value if (!text && is_typing) { is_typing = false; socket.emit('typing', false); } else if (text && !is_typing) { is_typing = true; socket.emit('typing', true); clearTimeout(timer_id) timer_id = setTimeout(remove_typing, 2000); } }) socket.on('typing', function(users) { if (users.length==0) { document.getElementById('typing-indicator').innerHTML = ''; } else if (users.length==1) { document.getElementById('typing-indicator').innerHTML = ''+users[0]+" is typing..."; } else if (users.length==2) { document.getElementById('typing-indicator').innerHTML = ''+users[0]+" and "+users[1]+" are typing..."; } else { document.getElementById('typing-indicator').innerHTML = ''+users[0]+", "+users[1]+", and "+users[2]+" are typing..."; } }) function del(t) { const chatline = t.parentElement.parentElement.parentElement.parentElement socket.emit('delete', chatline.id); chatline.remove() } socket.on('delete', function(text) { const text_spans = document.getElementsByClassName('text') for (const span of text_spans) { if (span.innerHTML == text) { span.parentElement.parentElement.parentElement.parentElement.parentElement.remove() } } }) socket.on('refresh_chat', () => { location.reload() }) document.addEventListener('click', function(e) { if (e.target.classList.contains('delconfirm')) { e.target.nextElementSibling.classList.remove('d-none'); e.target.classList.add('d-none'); } else { for (const btn of document.querySelectorAll('.delmsg:not(.d-none)')) { btn.classList.add('d-none'); btn.previousElementSibling.classList.remove('d-none'); } } if (e.target.id == "cancel") { document.getElementById("quotes").classList.add("d-none"); document.getElementById('quotes_id').value = null; } }); const input = document.getElementById('file') function handle_files() { if (!input.files.length) return const char_limit = screen_width >= 768 ? 50 : 5; input.previousElementSibling.className = ""; input.previousElementSibling.textContent = input.files[0].name.substr(0, char_limit); } input.onchange = handle_files document.onpaste = function(event) { input.files = structuredClone(event.clipboardData.files); handle_files() } function send_hearbeat() { socket.emit('heartbeat') } send_hearbeat() setInterval(send_hearbeat, 20000); box.scrollTo(0, box.scrollHeight) setTimeout(function() { box.scrollTo(0, box.scrollHeight) }, 200); setTimeout(function() { box.scrollTo(0, box.scrollHeight) }, 500); setTimeout(function() { box.scrollTo(0, box.scrollHeight) }, 1000); setTimeout(function() { box.scrollTo(0, box.scrollHeight) }, 1500); document.addEventListener('DOMContentLoaded', function() { box.scrollTo(0, box.scrollHeight) });