(function friends() { "use strict"; // Each friend is rendered as a full — but smaller — presence card, built by // the shared factory in discord.js (window.PresenceCard). Cards pull live // presence (status, activity, badges, banner, bio, connections, wishlist…) // from the same Doughmination Restful API the /discord card uses. // NOTE: discord.js must be loaded BEFORE this file (see cool-people/index.html). var FRIENDS = [ { title: "Fiancée", members: [ { name: "Aria", tier: "wife", discordId: "1305215902685597797", link: null } ] }, { title: "Close Friends", members: [ // { name: "Lilly", tier: "close", discordId: "908055723659898902", link: null }, { name: "Ria", tier: "close", discordId: "1513506390088618145", link: null }, { name: "Camilla", tier: "close", discordId: "1110542429838397471", link: "https://cammy-the-cat.com" }, { name: "Saphie", tier: "close", discordId: "527709099186716673", link: null }, { name: "Ari", tier: "close", discordId: "1474568910736199825", link: "https://a.stupid.cat" } ] }, { title: "Friends", members: [ { name: "Fin", tier: "friend", discordId: "867818211574808607", link: null }, { name: "Meme", tier: "friend", discordId: "812998699667161098", link: null }, { name: "N", tier: "friend", discordId: "639399972407869450", link: null }, { name: "Lylla", tier: "friend", discordId: "1009889543878611016", link: null }, { name: "Simon", tier: "friend", discordId: "758466783354814514", link: null } ] }, { title: "Other Peeps", subtitle: "You can request to be added here!", members: [ { name: "furi", tier: "known", discordId: "781445370177126401", link: "https://furina.is-a.dev"}, { name: "pokemon", tier: "known", discordId: "784443338627612673", link: "https://devmatei.com/" } ] }, { title: "Alts", subtitle: "My other accounts, dead or alive", members: [ { name: "J", img: "/assets/alts/j.png", tier: "active-alt", discordId: "1500197577336033301", link: null}, { name: "Uzi", img: "/assets/alts/uzi.png", tier: "active-alt", discordId: "526626867973849123", link: null }, { name: "clovetwilight3", img: "/assets/alts/clovetwilight3.png", tier: "dead-alt", discordId: null, link: null }, { name: "estrogenhrt", img: "/assets/alts/estrogenhrt.png", tier: "dead-alt", discordId: null, link: null }, { name: "Clove <3", img: "/assets/alts/clove.png", tier: "dead-alt", discordId: "1125844710511104030", link: null}, { name: "Clove ⛤", img: "/assets/alts/butterfly.png", tier: "dead-alt", discordId: "514994021970739201", link: null }, { name: "Mrow", img: "/assets/alts/mrow.png", tier: "dead-alt", discordId: "219480349053288450", link: null } ] } ]; var FRIEND_POLL_MS = 60000; // re-poll each live friend once a minute var root = document.getElementById("friends-root"); if (!root) return; // title → URL-safe anchor id, e.g. "Close Friends" -> "close-friends" function slugify(str) { return String(str == null ? "" : str) .toLowerCase() .trim() .replace(/[^a-z0-9]+/g, "-") .replace(/^-+|-+$/g, ""); } var make = window.PresenceCard; if (typeof make !== "function") { console.error("friends.js: window.PresenceCard is missing — load /js/discord.js before /js/friends.js"); } // ---- render --------------------------------------------------------- FRIENDS.forEach(function (group) { var section = document.createElement("section"); section.className = "section"; section.id = slugify(group.title); // anchor target, e.g. #alts // gg sans (Discord's font) as the default for the whole friends widget — // group headers, subtitles and the cards inside — over the page's Comic Code. section.style.fontFamily = "'DDN gg sans', sans-serif"; var h2 = document.createElement("h2"); h2.className = "section-title"; h2.textContent = group.title; section.appendChild(h2); if (group.subtitle) { var sub = document.createElement("p"); sub.className = "section-subtitle"; sub.textContent = group.subtitle; section.appendChild(sub); } var grid = document.createElement("div"); grid.className = "friend-grid"; group.members.forEach(function (m) { // placeholder slot — the factory replaces it with the finished card var slot = document.createElement("div"); grid.appendChild(slot); if (typeof make === "function") { make({ mount: slot, userId: m.discordId || null, // null → static placeholder card (dead alts) mini: true, // smaller styling + keeps page accent local pollMs: FRIEND_POLL_MS, tier: m.tier || null, link: m.link || null, fallbackName: m.name, // shown instantly + kept if the API has no data fallbackImg: m.img || null }); } else { // hard fallback: at least show the name if the factory didn't load slot.className = "presence-card is-mini" + (m.tier ? " tier-" + m.tier : ""); slot.dataset.status = "offline"; slot.textContent = m.name; } }); section.appendChild(grid); root.appendChild(section); }); // ---- jump to anchor (sections are built after page load) ------------ function scrollToHash() { var id = (location.hash || "").slice(1); if (!id) return; var target = document.getElementById(id); if (target) target.scrollIntoView(); } scrollToHash(); window.addEventListener("hashchange", scrollToHash); })();