/** * The chat histories (chat_history.jinja2): one guild's chat (mode guild), team chat by team (mode teams) and one * character's whispers by conversation (mode whispers). Conversations load newest page first; Older loads the page * before. #team= and #with= open that team or conversation (links from the Chat Log). */ (function () { 'use strict'; var page = document.getElementById('chatHistoryPage'); var mode = page.dataset.mode; var id = page.dataset.id; var PAGE = 100, LIST_PAGE = 50; var nf = new Intl.NumberFormat(); var rows = document.getElementById('threadRows'); var flagging = ChatFlagging.create(document.getElementById('threadTable'), document.getElementById('flagBar'), function () { reloadThread(); }); var thread = null; // {url, oldest, messages} var list = { offset: 0, items: [], selected: null }; function hashValue(name) { var m = location.hash.match(new RegExp('[#&]' + name + '=([^&]*)')); return m ? decodeURIComponent(m[1]) : ''; } // ---- the conversation ---- function line(m) { var where = m.zone_id ? '
' + esc(m.zone_name || ('Zone ' + m.zone_id)) + '
' : ''; return '' + ChatFlagging.checkbox(m) + '' + '' + esc(fmt.unix(m.time)) + '' + '' + (m.sender_id !== '0' ? fmt.character(m.sender_id, m.sender_name) : esc(m.sender_name)) + where + '' + '' + ChatFlagging.text(m) + ChatFlagging.flagLink(m) + '' + '' + (m.account_id ? 'Account' : '') + ''; } function render() { if (!thread) return; rows.innerHTML = thread.messages.length ? thread.messages.map(line).join('') : 'No messages (chat is kept for log_chat_days).'; document.getElementById('olderBox').classList.toggle('d-none', !thread.more); flagging.sync(); } function load(url, older) { var query = '?limit=' + PAGE + (older && thread && thread.messages.length ? '&before=' + thread.messages[0].id : ''); return api.get(url + query).then(function (d) { if (!d.success) { rows.innerHTML = '' + esc(d.error || 'Could not load the chat') + ''; return d; } flagging.remember(d.messages); if (older && thread && thread.url === url) thread.messages = d.messages.concat(thread.messages); else thread = { url: url, messages: d.messages }; thread.more = d.has_more; render(); if (!older) window.scrollTo({ top: document.getElementById('threadTable').getBoundingClientRect().bottom + window.scrollY - window.innerHeight + 80 }); return d; }); } function reloadThread() { if (thread) load(thread.url, false); } document.getElementById('older').addEventListener('click', function () { if (thread) load(thread.url, true); }); function setLinks(html) { document.getElementById('threadLinks').innerHTML = html; } // ---- guild ---- if (mode === 'guild') { load('/api/chat/guild/' + encodeURIComponent(id), false).then(function (d) { if (!d || !d.success) return; document.getElementById('threadTitle').textContent = d.guild.exists ? d.guild.name : 'Guild ' + id + ' (disbanded)'; setLinks(d.guild.exists && DASH.can('guilds_manage') ? 'Members and history' : ''); }).catch(function () {}); return; } // ---- teams and whisper conversations: the list on the left ---- var listEl = document.getElementById('threadList'); function itemHtml(item) { var active = list.selected === item.key; return '' + '
' + esc(item.title) + '' + '' + nf.format(item.messages) + '
' + '
' + esc(item.meta) + '
'; } function renderList(total) { listEl.innerHTML = list.items.length ? list.items.map(itemHtml).join('') : '
None found.
'; document.getElementById('listCount').textContent = nf.format(total); document.getElementById('listMoreBox').classList.toggle('d-none', list.items.length >= total); } function span(first, last) { return fmt.unix(first) + (last !== first ? ' to ' + fmt.unix(last) : ''); } function loadList(more) { if (!more) { list.offset = 0; list.items = []; } var url = mode === 'teams' ? '/api/chat/teams?limit=' + LIST_PAGE + '&offset=' + list.offset + '&character=' + encodeURIComponent(document.getElementById('teamCharacter').value.trim()) : '/api/characters/' + encodeURIComponent(id) + '/whispers?limit=' + LIST_PAGE + '&offset=' + list.offset; return api.get(url).then(function (d) { if (!d.success) { listEl.innerHTML = '
' + esc(d.error || 'Could not load') + '
'; return; } var items = mode === 'teams' ? d.teams.map(function (t) { return { key: t.team_id, title: t.senders.join(', ') || 'Team', messages: t.messages, meta: span(t.first_time, t.last_time), team: t }; }) : d.partners.map(function (p) { return { key: p.character_id, title: p.name || p.character_id, messages: p.messages, meta: span(p.first_time, p.last_time), partner: p }; }); list.items = list.items.concat(items); list.offset += items.length; renderList(d.total); }); } function open(key) { list.selected = key; listEl.querySelectorAll('[data-key]').forEach(function (el) { el.classList.toggle('active', el.getAttribute('data-key') === key); }); var item = list.items.filter(function (i) { return i.key === key; })[0]; flagging.clear(); try { history.replaceState(null, '', '#' + (mode === 'teams' ? 'team' : 'with') + '=' + key); } catch (e) {} if (mode === 'teams') { document.getElementById('threadTitle').textContent = item ? 'Team: ' + item.title : 'Team ' + key; setLinks(''); return load('/api/chat/team/' + encodeURIComponent(key), false).catch(function () {}); } var name = item ? item.title : key; document.getElementById('threadTitle').textContent = 'With ' + name; setLinks('' + esc(name) + '' + 'Their whispers'); return load('/api/characters/' + encodeURIComponent(id) + '/whispers/' + encodeURIComponent(key), false).catch(function () {}); } listEl.addEventListener('click', function (e) { var item = e.target.closest('[data-key]'); if (item) open(item.getAttribute('data-key')); }); document.getElementById('listMore').addEventListener('click', function () { loadList(true).catch(function () {}); }); var teamCharacter = document.getElementById('teamCharacter'); if (teamCharacter && hashValue('character')) teamCharacter.value = hashValue('character'); if (teamCharacter) teamCharacter.addEventListener('change', function () { loadList(false).catch(function () {}); }); var start = hashValue(mode === 'teams' ? 'team' : 'with'); loadList(false).then(function () { if (start) open(start); // Whispers are only opened on purpose: each one opened is audited else if (list.items.length && mode === 'teams') open(list.items[0].key); }).catch(function () {}); })();