103 lines
3.1 KiB
JavaScript

(function () {
let currentProfilePromise = null;
let currentProfile = null;
async function fetchJson(url) {
const response = await fetch(url, { credentials: "same-origin" });
if (response.status === 401) {
location.href = "/login";
return null;
}
if (!response.ok) throw new Error(`${url} returned ${response.status}`);
return response.json();
}
async function loadCurrentProfile(force = false) {
if (!force && currentProfilePromise) return currentProfilePromise;
currentProfilePromise = Promise.all([
fetchJson("/api/v1/profiles/self"),
fetchJson("/api/v1/auth/me"),
]).then(([profile, user]) => {
currentProfile = { ...profile, user };
return currentProfile;
});
return currentProfilePromise;
}
function applyTopbarProfile(profile) {
const avatar = document.getElementById("topbarAvatar");
if (!avatar || !profile) return;
if (profile.avatarUrl) avatar.src = profile.avatarUrl;
avatar.alt = profile.displayName || profile.user?.userName || "Profile";
avatar.title = profile.displayName || profile.user?.userName || "Profile";
}
function wireTopbarSearch() {
const input = document.getElementById("topbarSearchInput");
if (!input || input.dataset.searchReady === "true") return;
input.dataset.searchReady = "true";
const params = new URLSearchParams(location.search);
if (location.pathname.includes("community") && params.has("search")) {
input.value = params.get("search") || "";
}
let searchTimeout;
input.addEventListener("input", () => {
if (!location.pathname.includes("community")) return;
clearTimeout(searchTimeout);
searchTimeout = setTimeout(() => {
if (typeof window.applyCreatorSearch === "function") {
window.applyCreatorSearch(input.value);
}
}, 300);
});
input.addEventListener("keydown", (event) => {
if (event.key !== "Enter") return;
if (location.pathname.includes("marketplace")) return;
const search = input.value.trim();
location.href = search
? `/community?search=${encodeURIComponent(search)}`
: "/community";
});
}
async function hydrateTopbarProfile() {
try {
const profile = currentProfile || (await loadCurrentProfile());
applyTopbarProfile(profile);
} catch {
// Keep the fallback avatar if the profile cannot be loaded.
}
}
function setCurrentProfile(profile) {
currentProfile = profile;
currentProfilePromise = Promise.resolve(profile);
applyTopbarProfile(profile);
}
window.loadCurrentProfile = loadCurrentProfile;
window.hydrateTopbarProfile = hydrateTopbarProfile;
window.setCurrentProfile = setCurrentProfile;
const observer = new MutationObserver(() => {
if (document.getElementById("topbarAvatar")) hydrateTopbarProfile();
wireTopbarSearch();
});
if (document.body) {
observer.observe(document.body, { childList: true, subtree: true });
} else {
document.addEventListener("DOMContentLoaded", () => {
observer.observe(document.body, { childList: true, subtree: true });
});
}
})();