diff --git a/fluent-animated.css b/fluent-animated.css deleted file mode 120000 index 909ad5d..0000000 --- a/fluent-animated.css +++ /dev/null @@ -1 +0,0 @@ -./weblog/B0. Template/fluent-animated.css.md \ No newline at end of file diff --git a/weblog/B0. Template/js/fediverse.js.md b/weblog/B0. Template/js/fediverse.js.md index 92b017d..7335f0f 100644 --- a/weblog/B0. Template/js/fediverse.js.md +++ b/weblog/B0. Template/js/fediverse.js.md @@ -119,48 +119,106 @@ class FediSocial extends HTMLElement { customElements.define('fedi-social', FediSocial) +function renderReplies(status, replies, replyContainer, template) { + const repliesToThis = replies.filter(d => d.in_reply_to_id == status.id); + + repliesToThis.forEach(reply => { + const article = template.content.cloneNode(true); + + article.querySelector('.avatar').src = reply.account.avatar + article.querySelector('a.name').href = reply.account.url + article.querySelector('.name').innerText = reply.account.display_name + article.querySelector('a.source').href = reply.url + article.querySelector('time.dt-published').datetime = reply.created_at + article.querySelector('time.dt-published').innerText = luxon.DateTime.fromISO(reply.created_at).toRelative() + + article.querySelector('.reply-content').innerHTML = reply.content + + article.querySelector('.application').innerText = reply.application.name + article.querySelector('.replies-count').innerText = reply.replies_count + article.querySelector('.favourites-count').innerText = reply.favourites_count + article.querySelector('.reblogs-count').innerText = reply.reblogs_count + + if(reply.replies_count > 0) { + const section = document.createElement('section') + section.classList.add('replies') + renderReplies(reply, replies, section, template) + article.querySelector('article').appendChild(section) + } + + replyContainer.appendChild(article) + }) +} + +async function loadContext(status, replyContainer, template) { + try{ + const res = await fetch(`https://monrepos.casa/api/v1/statuses/${status.id}/context`, { + headers: { + 'Authorization': 'Basic Ym90OjJuUmZhTGJ1c3cyaFhA' + } + }) + const json = await res.json() + + if(json && json.descendants && json.descendants.length > 0){ + const h1 = document.createElement('h1') + h1.innerText = "Replies" + replyContainer.appendChild(h1) + + renderReplies(status, json.descendants, replyContainer, template) + } + } + catch(ex){ + console.error(ex) + } +} + function fediverse() { const data = JSON.parse(localStorage.getItem('fedi-social') || '{}') - document.querySelectorAll("a.external_url:not([href='{external_url}'])").forEach(async (el) => { - if(data.template){ - const orig_href = el.href - let href = data.template.replace("{uri}", orig_href) - el.href = href + document.querySelectorAll("a.external_url:not([href='{external_url}'])").forEach(async (el) => { - try{ - const res = await fetch(`https://monrepos.casa/api/v2/search?type=statuses&q=${orig_href}`, { - headers: { - 'Authorization': 'Basic Ym90OjJuUmZhTGJ1c3cyaFhA' - } - }) - const json = await res.json() - const status = json?.statuses?.find(s => s.uri == orig_href) + const orig_href = el.href + let href = data.template ? data.template.replace("{uri}", orig_href) : orig_href + el.href = href - if(status) { - const innerHTML = ` - ${status?.replies_count} - ${status?.favourites_count} - ${status?.reblogs_count} - ` - - const span = document.createElement('span') - span.classList.add('fediverse') - span.innerHTML = innerHTML - - el.insertAdjacentElement('afterend', span) - el.remove() + try{ + const res = await fetch(`https://monrepos.casa/api/v2/search?type=statuses&q=${orig_href}`, { + headers: { + 'Authorization': 'Basic Ym90OjJuUmZhTGJ1c3cyaFhA' } + }) + const json = await res.json() + const status = json?.statuses?.find(s => s.uri == orig_href) + + if(status) { + const innerHTML = ` + ${status?.replies_count} + ${status?.favourites_count} + ${status?.reblogs_count} + ` + + const span = document.createElement('span') + span.classList.add('fedi-social') + span.innerHTML = innerHTML + + el.insertAdjacentElement('afterend', span) + el.remove() + el = span + + const replyContainer = document.getElementById('fedi-social-replies') + const template = document.getElementById('fedi-social-reply') + if(replyContainer && template && status.replies_count > 0) loadContext(status, replyContainer, template) } - catch(ex){ - console.error(ex) - } - } - else { - el.addEventListener('click', ev =>{ - ev.preventDefault() - window.scrollTo({ top: 0, behavior: 'smooth' }) - document.querySelector('fedi-social summary').click() - }) - } - }) + } + catch(ex){ + console.error(ex) + } + + if(!data.template) { + el.addEventListener('click', ev =>{ + ev.preventDefault() + window.scrollTo({ top: 0, behavior: 'smooth' }) + document.querySelector('fedi-social summary').click() + }) + } + }) } \ No newline at end of file diff --git a/weblog/B0. Template/styles.css.md b/weblog/B0. Template/styles.css.md index 8d85bde..cf70c6e 100644 --- a/weblog/B0. Template/styles.css.md +++ b/weblog/B0. Template/styles.css.md @@ -97,6 +97,8 @@ main.page { margin-top: -1rem; margin-right: -1rem; width: 100%; + margin-bottom: 0.5rem; + z-index: 0; } .post-info, @@ -204,9 +206,16 @@ footer { padding: 0 1em; } +.avatar { + max-width: 40px; + max-height: 40px; + border-radius: 50%; + vertical-align: bottom; + margin-right: 8px; +} header>.avatar { max-width: 60px; - border-radius: 50%; + max-height: 60px; } .header { @@ -286,6 +295,69 @@ header nav ul { padding: 0; } +section.replies { + padding-left:1em; + border-left: 5px solid var(--accent); +} +.replies .replies { + border-color: oklch(from var(--accent) l c calc(h + 90)); +} +.replies .replies .replies { + border-color: oklch(from var(--accent) l c calc(h + 180)); +} +.replies .replies .replies .replies { + border-color: oklch(from var(--accent) l c calc(h + 270)); +} + +.fedi-social-reply { + background:none; + border:none; + box-shadow:none; + margin:1em 0; + padding:0; + .reply-header { + width: 100%; + display:flex; + flex-direction: row; + .post-info{ + margin: 0; + margin-top:auto; + } + .author{ + width: 100%; + a.name{ + font-family: var(--font-head); + font-weight: var(--font-head-weight); + font-size: 1.5em; + line-height: 80%; + z-index: 2; + } + } + } + .reply-content { + margin:1.2em 0; + padding: 1em; + background-color: color-mix(in srgb, var(--accent) 25%, var(--background)); + /* background-image: var(--paper-texture-svg); */ + border-radius: 1em; + box-shadow: var(--shadow); + position: relative; + &::after { + content: ''; + position: absolute; + top: 0; + left: 1em; + width: 0; + height: 0; + border: 1em solid transparent; + border-bottom-color: color-mix(in srgb, var(--accent) 25%, var(--background)); + border-top: 0; + border-left: 0; + margin-top: -0.9em; + } + } +} + header nav li { display: inline-block; }