141 lines
5.7 KiB
JavaScript
141 lines
5.7 KiB
JavaScript
(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);
|
|
})();
|