mixin guild(guild) span.s-avatar.s-avatar__32.s-user-card--avatar if guild.icon img.s-avatar--image(src=`https://cdn.discordapp.com/icons/${guild.id}/${guild.icon}.png?size=32`) else .s-avatar--letter.bg-silver-400.bar-md(aria-hidden="true")= guild.name[0] .s-user-card--info.ai-start strong= guild.name ul.s-user-card--awards li #{discord.guildChannelMap.get(guild.id).filter(c => [0, 5, 15, 16].includes(discord.channels.get(c).type)).length} channels doctype html html(lang="en") head title Out Of Your Element link(rel="stylesheet" type="text/css" href=rel("/static/stacks.min.css")) meta(name="htmx-config" content='{"requestClass":"is-loading"}') style. .themed { --theme-base-primary-color-h: 266; --theme-base-primary-color-s: 53%; --theme-base-primary-color-l: 63%; --theme-dark-primary-color-h: 266; --theme-dark-primary-color-s: 53%; --theme-dark-primary-color-l: 63%; } .s-toggle-switch.s-toggle-switch__multiple.s-toggle-switch__incremental input[type="radio"]:checked ~ label:not(.s-toggle-switch--label-off) { --_ts-multiple-bg: var(--green-400); --_ts-multiple-fc: var(--white); } .s-btn.s-btn__matrix { --_bu-bg-active: var(--black-300); --_bu-bg-hover: var(--black-200); --_bu-bg-selected: var(--black-300); --_bu-fc: var(--black-500); --_bu-fc-active: var(--_bu-fc); --_bu-fc-hover: var(--black-500); --_bu-fc-selected: var(--black-600); --_bu-filled-bc: transparent; --_bu-filled-bc-selected: var(--_bu-filled-bc); --_bu-filled-bg: var(--black-400); --_bu-filled-bg-active: var(--black-500); --_bu-filled-bg-hover: var(--black-500); --_bu-filled-bg-selected: var(--black-600); --_bu-filled-fc: var(--white); --_bu-filled-fc-active: var(--_bu-filled-fc); --_bu-filled-fc-hover: var(--_bu-filled-fc); --_bu-filled-fc-selected: var(--_bu-filled-fc); --_bu-outlined-bc: var(--black-400); --_bu-outlined-bc-selected: var(--black-500); --_bu-outlined-bg-selected: var(--_bu-bg-selected); --_bu-outlined-fc-selected: var(--_bu-fc-selected); --_bu-number-fc: var(--white); --_bu-number-fc-filled: var(--black); } .s-btn__dropdown:has(+ :popover-open) { background-color: var(--theme-topbar-item-background-hover, var(--black-200)) !important; } body.themed.theme-system header.s-topbar .s-topbar--skip-link(href="#content") Skip to main content .s-topbar--container.wmx9 a.s-topbar--logo(href=rel("/")) img.s-avatar.s-avatar__32(src=rel("/icon.png")) nav.s-topbar--navigation ul.s-topbar--content li.ps-relative.g8 if !session.data.mxid a.s-btn.s-btn__icon.s-btn__matrix.s-btn__outlined.as-center(href=rel("/log-in-with-matrix")) != icons.Icons.IconSpeechBubble = ` Log in with Matrix` if !session.data.userID a.s-btn.s-btn__icon.s-btn__featured.s-btn__outlined.as-center(href=rel("/oauth")) != icons.Icons.IconDiscord = ` Log in with Discord` if guild_id && managed.has(guild_id) && discord.guilds.has(guild_id) button.s-topbar--item.s-btn.s-btn__muted.s-btn__dropdown.pr32.bar0.s-user-card(popovertarget="guilds") +guild(discord.guilds.get(guild_id)) else if managed.size button.s-topbar--item.s-btn.s-btn__muted.s-btn__dropdown.pr24.s-user-card.bar0.fc-black(popovertarget="guilds") | Your servers else if session.data.mxid || session.data.userID .d-flex.ai-center .s-badge.s-badge__bot.py6.px16.bar-md | No servers available #guilds(popover data-popper-placement="bottom" style="display: revert; width: revert;").s-popover.overflow-visible .s-popover--arrow.s-popover--arrow__tc .s-popover--content.overflow-y-auto.overflow-x-hidden ul.s-menu(role="menu") each guild in [...managed].map(id => discord.guilds.get(id)).filter(g => g).sort((a, b) => a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1) li(role="menuitem") a.s-topbar--item.s-user-card.d-flex.p4(href=rel(`/guild?guild_id=${guild.id}`)) +guild(guild) //- Body .mx-auto.w100.wmx9.py24.px8.fs-body1#content block body //- Guild list popover script. document.querySelectorAll("[popovertarget]").forEach(e => { e.addEventListener("click", () => { const rect = e.getBoundingClientRect() const t = `:popover-open { position: absolute; top: ${Math.floor(rect.bottom)}px; left: ${Math.floor(rect.left + rect.width / 2)}px; width: ${Math.floor(rect.width)}px; transform: translateX(-50%); box-sizing: content-box; margin: 0 }` document.styleSheets[0].insertRule(t, document.styleSheets[0].cssRules.length) }) }) script(src=rel("/static/htmx.js")) //- Error dialog aside.s-modal#server-error(aria-hidden="true") .s-modal--dialog h1.s-modal--header Server error pre.overflow-auto#server-error-content button.s-modal--close.s-btn.s-btn__muted(aria-label="Close" type="button" onclick="hideError()")!= icons.Icons.IconClearSm .s-modal--footer button.s-btn.s-btn__outlined.s-btn__muted(type="button" onclick="hideError()") OK script. function hideError() { document.getElementById("server-error").setAttribute("aria-hidden", "true") } document.body.addEventListener("htmx:responseError", event => { document.getElementById("server-error").setAttribute("aria-hidden", "false") document.getElementById("server-error-content").textContent = event.detail.xhr.responseText })