2026-04-28 15:07:12 +08:00

828 lines
28 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(function () {
const supportedLanguages = ["en", "ar", "tr", "id"];
const languageLabels = {
en: "EN",
ar: "AR",
tr: "TR",
id: "ID"
};
const API_BASE_URL = "https://jvapi.haiyihy.com";
const fallbackMessages = {
en: {
document_title: "Stream Center",
page_label: "Stream Center",
back: "Back",
title: "Stream Center",
language_button_aria: "Change language",
uid: "UID: 1234567890",
agency: "Agency: Bilibili(101013)",
streaming_duration: "Streaming Duration<br />(Minutes)",
target: "Target",
my_income: "My Income",
withdraw_exchange: "Withdraw/Exchange",
open_withdraw_exchange: "Open withdraw and exchange page",
open_anchor_policy: "Open anchor policy",
anchor_policy: "Anchor Policy",
policy_loading: "Loading policy...",
policy_empty: "No policy data",
policy_missing_token: "Missing token",
policy_load_failed: "Failed to load policy",
policy_level: "Level",
policy_online: "Online (Hour)",
policy_effective_day: "Valid days",
policy_target: "Target",
policy_host_salary: "Host salary",
policy_agent_salary: "Agent salary",
policy_total_salary: "Total salary"
},
ar: {
document_title: "مركز البث",
page_label: "مركز البث",
back: "رجوع",
title: "مركز البث",
language_button_aria: "تغيير اللغة",
uid: "معرّف المستخدم: 1234567890",
agency: "الوكالة: Bilibili(101013)",
streaming_duration: "مدة البث<br />(بالدقائق)",
target: "الهدف",
my_income: "دخلي",
withdraw_exchange: "سحب/استبدال",
open_withdraw_exchange: "فتح صفحة السحب والاستبدال",
open_anchor_policy: "فتح سياسة المضيف",
anchor_policy: "سياسة المضيف",
policy_loading: "جار تحميل السياسة...",
policy_empty: "لا توجد بيانات سياسة",
policy_missing_token: "رمز الدخول مفقود",
policy_load_failed: "فشل تحميل السياسة",
policy_level: "المستوى",
policy_online: "الاتصال (ساعة)",
policy_effective_day: "الأيام الصالحة",
policy_target: "الهدف",
policy_host_salary: "راتب المضيف",
policy_agent_salary: "راتب الوكيل",
policy_total_salary: "إجمالي الراتب"
},
tr: {
document_title: "Yayın Merkezi",
page_label: "Yayın Merkezi",
back: "Geri",
title: "Yayın Merkezi",
language_button_aria: "Dili değiştir",
uid: "UID: 1234567890",
agency: "Ajans: Bilibili(101013)",
streaming_duration: "Yayın Süresi<br />(Dakika)",
target: "Hedef",
my_income: "Gelirim",
withdraw_exchange: "Çek/Değiştir",
open_withdraw_exchange: "Çekme ve değişim sayfasını aç",
open_anchor_policy: "Host politikasını aç",
anchor_policy: "Host Politikası",
policy_loading: "Politika yükleniyor...",
policy_empty: "Politika verisi yok",
policy_missing_token: "Token eksik",
policy_load_failed: "Politika yüklenemedi",
policy_level: "Seviye",
policy_online: "Online (Saat)",
policy_effective_day: "Geçerli gün",
policy_target: "Hedef",
policy_host_salary: "Host maaşı",
policy_agent_salary: "Ajans maaşı",
policy_total_salary: "Toplam maaş"
},
id: {
document_title: "Pusat Streaming",
page_label: "Pusat Streaming",
back: "Kembali",
title: "Pusat Streaming",
language_button_aria: "Ubah bahasa",
uid: "UID: 1234567890",
agency: "Agensi: Bilibili(101013)",
streaming_duration: "Durasi Streaming<br />(Menit)",
target: "Target",
my_income: "Penghasilan Saya",
withdraw_exchange: "Tarik/Tukar",
open_withdraw_exchange: "Buka halaman tarik dan tukar",
open_anchor_policy: "Buka kebijakan host",
anchor_policy: "Kebijakan Host",
policy_loading: "Memuat kebijakan...",
policy_empty: "Tidak ada data kebijakan",
policy_missing_token: "Token tidak ditemukan",
policy_load_failed: "Gagal memuat kebijakan",
policy_level: "Level",
policy_online: "Online (Jam)",
policy_effective_day: "Hari valid",
policy_target: "Target",
policy_host_salary: "Gaji host",
policy_agent_salary: "Gaji agensi",
policy_total_salary: "Total gaji"
}
};
const params = readURLParams();
let currentLang = normalizeLanguage(params.get("lang"));
let currentMessages = fallbackMessages[currentLang] || fallbackMessages.en;
let currentProfile = null;
let currentAgencyProfile = null;
let currentTeamId = "";
let currentIdentity = null;
let currentSalary = "0.00";
let currentStreamingDuration = "0";
let nextTargetValue = "-";
function readURLParams() {
const result = new URLSearchParams(window.location.search);
const hashQuery = window.location.hash.includes("?") ? window.location.hash.split("?")[1] : "";
const hashParams = new URLSearchParams(hashQuery);
hashParams.forEach((value, key) => {
if (!result.has(key)) result.set(key, value);
});
return result;
}
function readRawParam(name) {
const queries = [window.location.search.replace(/^\?/, "")];
if (window.location.hash.includes("?")) queries.push(window.location.hash.split("?")[1]);
for (const query of queries) {
for (const part of query.split("&")) {
if (!part) continue;
const equalIndex = part.indexOf("=");
const rawKey = equalIndex >= 0 ? part.slice(0, equalIndex) : part;
const rawValue = equalIndex >= 0 ? part.slice(equalIndex + 1) : "";
let decodedKey = "";
try {
decodedKey = decodeURIComponent(rawKey);
} catch (error) {
continue;
}
if (decodedKey !== name) continue;
try {
return decodeURIComponent(rawValue.replace(/\+/g, "%2B"));
} catch (error) {
return rawValue;
}
}
}
return "";
}
function normalizeLanguage(lang) {
const value = String(lang || "en").toLowerCase();
return supportedLanguages.includes(value) ? value : "en";
}
async function loadMessages(lang) {
const normalizedLang = normalizeLanguage(lang);
if (window.location.protocol === "file:") return fallbackMessages[normalizedLang];
try {
const response = await fetch(`./locales/${normalizedLang}.json`, { cache: "no-store" });
if (response.ok) return await response.json();
} catch (error) {
return fallbackMessages[normalizedLang];
}
return fallbackMessages[normalizedLang];
}
function renderMessages(messages) {
document.querySelectorAll("[data-i18n]").forEach((node) => {
const value = messages[node.dataset.i18n];
if (value) node.textContent = value;
});
document.querySelectorAll("[data-i18n-html]").forEach((node) => {
const value = messages[node.dataset.i18nHtml];
if (value) node.innerHTML = value;
});
document.querySelectorAll("[data-i18n-aria]").forEach((node) => {
const value = messages[node.dataset.i18nAria];
if (value) node.setAttribute("aria-label", value);
});
}
function apiBaseURL() {
const override = window.HYAPP_API_BASE_URL || params.get("apiBase");
if (override) return String(override).replace(/\/+$/, "");
return API_BASE_URL.replace(/\/+$/, "");
}
function normalizeAuthorization(token) {
const value = String(token || "").trim();
if (!value) return "";
return /^bearer\s+/i.test(value) ? value : `Bearer ${value}`;
}
function authHeadersFromToken(token) {
return {
Authorization: normalizeAuthorization(token),
"req-lang": currentLang,
"req-client": "H5",
"req-version": "V2",
"req-zone": Intl.DateTimeFormat().resolvedOptions().timeZone || "Asia/Shanghai",
"req-app-intel": "version=1.0.0;build=1;model=H5;sysVersion=Web;channel=Web",
"req-sys-origin": "origin=ATYOU;originChild=ATYOU"
};
}
function profileUidPrefix(messages) {
const template = messages.uid || fallbackMessages.en.uid;
const marker = "1234567890";
return template.includes(marker) ? template.replace(marker, "").trim() : "UID:";
}
function pickProfileName(profile) {
return profile?.userNickname || profile?.name || "Oscar";
}
function pickProfileAccount(profile) {
return profile?.ownSpecialId?.account || profile?.account || profile?.id || "1234567890";
}
function agencyPrefix(messages) {
const template = messages.agency || fallbackMessages.en.agency;
const marker = "Bilibili(101013)";
return template.includes(marker) ? template.replace(marker, "").trim() : "Agency:";
}
function pickAgencyName(profile) {
return profile?.userNickname || profile?.name || profile?.teamName || "-";
}
function pickAgencyAccount(profile) {
return profile?.ownSpecialId?.account || profile?.account || profile?.id || "";
}
function formatAgencyText(profile, messages = currentMessages) {
const prefix = agencyPrefix(messages);
if (!profile) return `${prefix} -`;
const name = pickAgencyName(profile);
const account = pickAgencyAccount(profile);
return account ? `${prefix} ${name}(${account})` : `${prefix} ${name}`;
}
function renderAgencyProfile(profile, messages = currentMessages) {
const agencyButton = document.querySelector(".agency");
const agencyTextNode = document.querySelector(".agency span:first-child");
if (!agencyButton || !agencyTextNode) return;
agencyTextNode.textContent = formatAgencyText(profile, messages);
agencyButton.dataset.teamId = String(currentTeamId || pickAgencyTeamId(profile) || "");
agencyButton.dataset.account = String(profile?.account || "");
agencyButton.dataset.specialAccount = String(profile?.ownSpecialId?.account || "");
syncPolicyLink();
}
function pickAgencyTeamId(profile) {
return profile?.teamId || profile?.teamProfile?.id || profile?.id || "";
}
function pickTeamEntryId(entry) {
return entry?.teamProfile?.id || entry?.teamId || entry?.id || "";
}
function removeAvatarFallback() {
document.querySelector("#profileAvatarFallback")?.remove();
}
function ensureAvatarFallback(displayName) {
const avatarShell = document.querySelector(".avatar-shell");
if (!avatarShell) return null;
let avatarFallback = document.querySelector("#profileAvatarFallback");
if (avatarFallback) {
avatarFallback.hidden = false;
avatarFallback.setAttribute("aria-label", `${displayName} avatar`);
return avatarFallback;
}
const template = document.createElement("template");
template.innerHTML = `
<svg class="avatar-fallback" id="profileAvatarFallback" viewBox="0 0 72 72" role="img">
<defs>
<linearGradient id="avatarBg" x1="12" y1="8" x2="60" y2="64">
<stop stop-color="#5AF6E4"></stop>
<stop offset="1" stop-color="#D9FFF5"></stop>
</linearGradient>
</defs>
<circle cx="36" cy="36" r="35" fill="url(#avatarBg)"></circle>
<path d="M22 30 20 18l10 7M50 30l2-12-10 7" fill="#101820"></path>
<path d="M20 31c3-9 28-9 32 0 4 10-3 21-16 21S16 41 20 31Z" fill="#F7FBF7"></path>
<circle cx="29" cy="36" r="4" fill="#101820"></circle>
<circle cx="46" cy="36" r="4" fill="#101820"></circle>
<circle cx="25" cy="41" r="5" fill="#F0B64A" opacity=".9"></circle>
<path d="M35 42h3l-1.5 2Z" fill="#101820"></path>
<path d="M36 45c-2 2-5 3-8 2M38 45c2 2 5 3 8 2" fill="none" stroke="#101820" stroke-width="2" stroke-linecap="round"></path>
</svg>
`;
avatarFallback = template.content.firstElementChild;
avatarFallback.setAttribute("aria-label", `${displayName} avatar`);
avatarShell.appendChild(avatarFallback);
return avatarFallback;
}
function renderProfile(profile, messages = currentMessages) {
if (!profile) return;
const profileCard = document.querySelector(".profile-card");
const nameNode = document.querySelector("#profileName");
const uidNode = document.querySelector("#profileUid");
const avatarImage = document.querySelector("#profileAvatar");
const displayName = pickProfileName(profile);
const displayAccount = pickProfileAccount(profile);
if (profileCard) {
profileCard.dataset.userId = String(profile.id || "");
profileCard.dataset.account = String(profile.account || "");
profileCard.dataset.specialAccount = String(profile?.ownSpecialId?.account || "");
}
if (nameNode) nameNode.textContent = displayName;
if (uidNode) uidNode.textContent = `${profileUidPrefix(messages)} ${displayAccount}`.trim();
if (!avatarImage) return;
const avatar = profile.userAvatar ? String(profile.userAvatar) : "";
avatarImage.alt = displayName;
if (!avatar) {
avatarImage.hidden = true;
avatarImage.onerror = null;
avatarImage.removeAttribute("src");
ensureAvatarFallback(displayName);
return;
}
avatarImage.hidden = false;
removeAvatarFallback();
avatarImage.onerror = () => {
avatarImage.hidden = true;
avatarImage.removeAttribute("src");
ensureAvatarFallback(displayName);
};
avatarImage.src = avatar;
}
function hasOwn(object, key) {
return Boolean(object && Object.prototype.hasOwnProperty.call(object, key));
}
function isTruthyIdentityValue(value) {
if (typeof value === "boolean") return value;
if (typeof value === "number") return value === 1;
if (typeof value === "string") return ["true", "1", "yes"].includes(value.toLowerCase());
return false;
}
function shouldOpenJoinAgency(identity) {
if (!hasOwn(identity, "anchor")) return false;
return !isTruthyIdentityValue(identity.anchor);
}
function buildPageURL(path) {
const url = new URL(path, window.location.href);
const nextParams = new URLSearchParams(params);
const token = readRawParam("token");
if (token) nextParams.set("token", token);
if (currentLang) nextParams.set("lang", currentLang);
url.search = nextParams.toString();
return url.toString();
}
function openJoinAgencyPage() {
window.location.replace(buildPageURL("../join-agency/index.html"));
}
function formatCurrentSalary(value) {
const numericValue = Number(value);
if (Number.isFinite(numericValue)) return numericValue.toFixed(2);
return "0.00";
}
function pickCurrentSalary(body) {
if (typeof body === "number") return body;
if (body && typeof body === "object") {
return body.currentSalary ?? body.availableBalance ?? body.balance ?? 0;
}
return 0;
}
function renderCurrentSalary(value) {
currentSalary = formatCurrentSalary(value);
const salaryNode = document.querySelector("#currentSalary");
if (salaryNode) salaryNode.textContent = currentSalary;
}
function formatStreamingDuration(value) {
const numericValue = Number(value);
if (!Number.isFinite(numericValue)) return "0";
const safeValue = Math.max(0, numericValue);
return Number.isInteger(safeValue) ? String(safeValue) : String(Number(safeValue.toFixed(2)));
}
function pickStreamingDuration(body) {
const workTarget = pickFirstMemberWorkTarget(body);
return body?.onlineTime ?? body?.target?.onlineTime ?? workTarget?.target?.onlineTime ?? workTarget?.onlineTime ?? 0;
}
function renderStreamingDuration(value) {
currentStreamingDuration = formatStreamingDuration(value);
const durationNode = document.querySelector("#streamingDuration");
if (durationNode) durationNode.textContent = currentStreamingDuration;
}
function formatTargetValue(value) {
if (value === null || value === undefined || value === "") return "-";
const number = Number(value);
if (Number.isFinite(number) && Number.isInteger(number)) return String(number);
return String(value);
}
function renderNextTargetValue(value) {
nextTargetValue = formatTargetValue(value);
const targetNode = document.querySelector("#nextTargetValue");
if (targetNode) targetNode.textContent = nextTargetValue;
}
function pickFirstMemberWorkTarget(body) {
const targets = Array.isArray(body?.targets) ? body.targets : [];
return targets[0] || body?.target || null;
}
function pickGiftValue(workTarget) {
const target = workTarget?.target || workTarget || {};
return target.acceptGiftValue ?? target.giftValue ?? target.giftScore ?? target.currentGiftValue ?? null;
}
function pickDirectNextTargetValue(workTarget) {
const target = workTarget?.target || workTarget || {};
return target.nextTarget ?? target.nextLevelTarget ?? target.nextTargetValue ?? workTarget?.nextTarget ?? null;
}
function pickPolicyRows(policyBody) {
if (Array.isArray(policyBody?.policy)) return policyBody.policy;
if (Array.isArray(policyBody?.policies)) return policyBody.policies;
return [];
}
function calculateNextTargetValue(giftValue, policyRows) {
const giftNumber = Number(giftValue);
if (!Number.isFinite(giftNumber) || !policyRows.length) return null;
const rows = policyRows
.map((row) => ({
target: Number(row.target),
rawTarget: row.target
}))
.filter((row) => Number.isFinite(row.target))
.sort((a, b) => a.target - b.target);
if (!rows.length) return null;
const next = rows.find((row) => giftNumber < row.target);
return next ? next.rawTarget : null;
}
async function fetchUserProfile() {
const token = readRawParam("token");
if (!token) {
console.warn("Missing token for /team/member/profile");
return null;
}
try {
const url = new URL("/team/member/profile", `${apiBaseURL()}/`);
const response = await fetch(url.toString(), {
cache: "no-store",
headers: authHeadersFromToken(token)
});
const data = await response.json().catch(() => ({}));
if (!response.ok || data.status === false) {
throw new Error(data.errorMsg || data.message || `Request failed: ${response.status}`);
}
currentProfile = data.body || data.data || {};
renderProfile(currentProfile);
return currentProfile;
} catch (error) {
console.error("Failed to load user profile:", error);
return null;
}
}
async function fetchIdentity() {
const token = readRawParam("token");
if (!token) {
console.warn("Missing token for /app/h5/identity");
return null;
}
try {
const url = new URL("/app/h5/identity", `${apiBaseURL()}/`);
const response = await fetch(url.toString(), {
cache: "no-store",
headers: authHeadersFromToken(token)
});
const data = await response.json().catch(() => ({}));
if (!response.ok || data.status === false) {
throw new Error(data.errorMsg || data.message || `Request failed: ${response.status}`);
}
currentIdentity = data.body || data.data || {};
return currentIdentity;
} catch (error) {
console.error("Failed to load H5 identity:", error);
return null;
}
}
async function fetchAgencyProfile() {
const token = readRawParam("token");
if (!token) {
console.warn("Missing token for /team/team-own/profile");
renderAgencyProfile(null);
return null;
}
try {
const url = new URL("/team/team-own/profile", `${apiBaseURL()}/`);
const response = await fetch(url.toString(), {
cache: "no-store",
headers: authHeadersFromToken(token)
});
const data = await response.json().catch(() => ({}));
if (!response.ok || data.status === false) {
throw new Error(data.errorMsg || data.message || `Request failed: ${response.status}`);
}
currentAgencyProfile = data.body || data.data || null;
renderAgencyProfile(currentAgencyProfile);
return currentAgencyProfile;
} catch (error) {
console.error("Failed to load agency profile:", error);
renderAgencyProfile(null);
return null;
}
}
async function fetchTeamEntry() {
const token = readRawParam("token");
if (!token) {
console.warn("Missing token for /team/entry");
return "";
}
try {
const url = new URL("/team/entry", `${apiBaseURL()}/`);
const response = await fetch(url.toString(), {
cache: "no-store",
headers: authHeadersFromToken(token)
});
const data = await response.json().catch(() => ({}));
if (!response.ok || data.status === false) {
throw new Error(data.errorMsg || data.message || `Request failed: ${response.status}`);
}
currentTeamId = pickTeamEntryId(data.body || data.data || {});
renderAgencyProfile(currentAgencyProfile);
syncPolicyLink();
return currentTeamId;
} catch (error) {
console.error("Failed to load team entry:", error);
return "";
}
}
async function fetchBankBalance() {
const token = readRawParam("token");
if (!token) {
console.warn("Missing token for /wallet/bank/balance");
return;
}
try {
const url = new URL("/wallet/bank/balance", `${apiBaseURL()}/`);
const response = await fetch(url.toString(), {
cache: "no-store",
headers: authHeadersFromToken(token)
});
const data = await response.json().catch(() => ({}));
if (!response.ok || data.status === false) {
throw new Error(data.errorMsg || data.message || `Request failed: ${response.status}`);
}
renderCurrentSalary(pickCurrentSalary(data.body ?? data.data));
} catch (error) {
console.error("Failed to load bank balance:", error);
renderCurrentSalary(0);
}
}
async function fetchStreamingDuration(memberId) {
const memberWork = await fetchMemberWork(memberId);
renderStreamingDuration(pickStreamingDuration(memberWork));
return memberWork;
}
async function fetchMemberWork(memberId) {
if (!memberId) {
console.warn("Missing memberId for /team/member-work");
return null;
}
try {
const url = new URL("/team/member-work", `${apiBaseURL()}/`);
url.searchParams.set("userId", String(memberId));
const token = readRawParam("token");
if (!token) {
console.warn("Missing token for /team/member-work");
return null;
}
const response = await fetch(url.toString(), {
cache: "no-store",
headers: authHeadersFromToken(token)
});
const data = await response.json().catch(() => ({}));
if (!response.ok || data.status === false) {
throw new Error(data.errorMsg || data.message || `Request failed: ${response.status}`);
}
return data.body || data.data || null;
} catch (error) {
console.error("Failed to load member work:", error);
return null;
}
}
async function fetchAnchorPolicyForTarget() {
const token = readRawParam("token");
if (!token) {
console.warn("Missing token for /team/release/policy");
return null;
}
try {
const teamId = currentTeamId || await fetchTeamEntry();
if (!teamId) {
console.warn("Missing teamId for /team/release/policy");
return null;
}
const url = new URL("/team/release/policy", `${apiBaseURL()}/`);
url.searchParams.set("id", teamId);
const response = await fetch(url.toString(), {
cache: "no-store",
headers: authHeadersFromToken(token)
});
const data = await response.json().catch(() => ({}));
if (!response.ok || data.status === false) {
throw new Error(data.errorMsg || data.message || `Request failed: ${response.status}`);
}
return data.body || data.data || null;
} catch (error) {
console.error("Failed to load team policy for next target:", error);
return null;
}
}
async function fetchNextTargetValue(memberId, memberWork = null) {
const work = memberWork || await fetchMemberWork(memberId);
const workTarget = pickFirstMemberWorkTarget(work);
if (!workTarget) {
renderNextTargetValue("-");
return;
}
const directNextTarget = pickDirectNextTargetValue(workTarget);
const giftValue = pickGiftValue(workTarget);
const policy = await fetchAnchorPolicyForTarget();
const calculatedNextTarget = calculateNextTargetValue(giftValue, pickPolicyRows(policy));
renderNextTargetValue(calculatedNextTarget ?? directNextTarget ?? "-");
}
function syncLocalizedLinks() {
const nextParams = new URLSearchParams(params);
const token = readRawParam("token");
if (token) nextParams.set("token", token);
if (currentLang) nextParams.set("lang", currentLang);
const query = nextParams.toString();
document.querySelectorAll('a[href^="../withdraw-exchange/index.html"]').forEach((link) => {
link.setAttribute("href", `../withdraw-exchange/index.html${query ? `?${query}` : ""}`);
});
}
function syncPolicyLink() {
const link = document.querySelector("#anchorPolicyLink");
if (!link) return;
const nextParams = new URLSearchParams(params);
const token = readRawParam("token");
const teamId = currentTeamId;
if (token) nextParams.set("token", token);
if (currentLang) nextParams.set("lang", currentLang);
if (teamId) nextParams.set("teamId", teamId);
const query = nextParams.toString();
link.setAttribute("href", `./policy.html${query ? `?${query}` : ""}`);
}
function setLanguageMenuOpen(open) {
const languageButton = document.querySelector(".language-button");
const languageMenu = document.querySelector(".language-menu");
if (!languageButton || !languageMenu) return;
languageMenu.hidden = !open;
languageButton.setAttribute("aria-expanded", String(open));
}
function renderLanguageControls(messages) {
const languageButton = document.querySelector(".language-button");
if (languageButton) {
languageButton.textContent = languageLabels[currentLang];
languageButton.setAttribute("aria-label", messages.language_button_aria || "Change language");
}
document.querySelectorAll(".language-menu [data-lang]").forEach((button) => {
const isActive = button.dataset.lang === currentLang;
button.classList.toggle("is-active", isActive);
button.setAttribute("aria-pressed", String(isActive));
});
}
async function applyLanguage(lang) {
currentLang = normalizeLanguage(lang);
const messages = await loadMessages(currentLang);
currentMessages = messages;
document.documentElement.lang = currentLang;
document.documentElement.dir = currentLang === "ar" ? "rtl" : "ltr";
document.title = messages.document_title || messages.title || "Stream Center";
renderMessages(messages);
renderLanguageControls(messages);
syncLocalizedLinks();
syncPolicyLink();
renderProfile(currentProfile, messages);
renderAgencyProfile(currentAgencyProfile, messages);
}
document.querySelector(".language-button")?.addEventListener("click", (event) => {
event.stopPropagation();
const languageMenu = document.querySelector(".language-menu");
setLanguageMenuOpen(Boolean(languageMenu?.hidden));
});
document.querySelectorAll(".language-menu [data-lang]").forEach((button) => {
button.addEventListener("click", (event) => {
event.stopPropagation();
setLanguageMenuOpen(false);
applyLanguage(button.dataset.lang);
});
});
document.addEventListener("click", () => {
setLanguageMenuOpen(false);
});
document.querySelector(".back-button")?.addEventListener("click", () => {
if (window.history.length > 1) window.history.back();
});
document.querySelector(".agency")?.addEventListener("click", () => {
if (currentIdentity && shouldOpenJoinAgency(currentIdentity)) openJoinAgencyPage();
});
ensureAvatarFallback("Oscar");
applyLanguage(currentLang).then(async () => {
const identity = await fetchIdentity();
if (shouldOpenJoinAgency(identity)) {
openJoinAgencyPage();
return;
}
fetchAgencyProfile();
fetchTeamEntry();
fetchUserProfile().then(async (profile) => {
const memberId = profile?.id || profile?.account;
if (memberId) {
const memberWork = await fetchStreamingDuration(memberId);
fetchNextTargetValue(memberId, memberWork);
}
});
fetchBankBalance();
});
})();