103 lines
3.1 KiB
JavaScript
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 });
|
|
});
|
|
}
|
|
})();
|