(function () { function fail(el, text) { el.innerHTML = 'Loading fail =(' console.error(text, el) } function required(el, field) { const val = el.dataset[field] if (val) { return val } fail(el, `Missing data-${field} attribut`) } function h(classes, content, tag = 'div') { return `<${tag} class="${classes}">${content}${tag}>` } const TIMES = new Map([ ['second', 1000], ['minute', 60], ['hour', 60], ['day', 24], ['month', 30.5], ['year', 12], ['century', 100] ]) function ago(date) { const now = Date.now() const target = Number(new Date(date)) const prefix = target > now ? 'in ' : '' const milliseconds = Math.floor(Math.abs(target - now)) let cur = 0 let divider = 1 let name = 'millisecond' for (const time of TIMES) { divider *= time[1] const next = Math.floor(milliseconds / divider) if (next <= 0) { return `${prefix}${cur} ${name}${cur > 1 ? 's' : ''} ago` } name = time[0] cur = next } return `${prefix}a long time ago` } function moji(text, emojis) { for (const emoji of emojis) { text = text.split(`:${emoji.shortcode}:`).join( `` ) } return text } function tree(statuses, parent, limit) { const [replies, others] = statuses.reduce(([c, o], s) => (s.in_reply_to_id == parent.id ? [[...c, s], o] : [c, [...o, s]]), [[], []]) parent.replies = limit ? replies.map(r => tree(others, r, limit - 1)) : [] return parent } function html(statuses, domain) { return statuses.map(({ account, created_at, content, id, emojis, sensitive, spoiler_text, replies }) => h('status', h('date', ago(created_at), 'p') + h('author" target="_blank" target="_blank" href="' + account.url, `` + h('name', moji(account.display_name, account.emojis), 'span') + h('acct', account.acct, 'span'), 'a') + (spoiler_text || sensitive ? h('spoiler', spoiler_text || h('spoiler-empty', 'Sensitive', 'span')) : '') + h('status-content' + (spoiler_text || sensitive ? ' sensitive' : ''), moji(content, emojis)) + (replies ? h('replies', html(replies, domain)) : '') + h(`reply" target="_blank" href="https://${domain}/notice/${id}`, 'Reply', 'a'))).join('') } function moderate(statuses, id) { if (!id) { return statuses } const valids = statuses.filter(s => s.account.id == id).map(s => s.in_reply_to_id) return statuses.filter(s => valids.includes(s.id)) } for (const el of document.getElementsByClassName('comtodon')) { el.innerHTML = '