867 lines
30 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)",
current: "Current",
daily_details: "Daily data",
gift_points: "Gift points",
online_minutes: "Online minutes",
no_daily_data: "No daily data",
close: "Close",
open_daily_data: "Open daily data",
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 />(بالدقائق)",
current: "الحالي",
daily_details: "البيانات اليومية",
gift_points: "نقاط الهدايا",
online_minutes: "دقائق الاتصال",
no_daily_data: "لا توجد بيانات يومية",
close: "إغلاق",
open_daily_data: "فتح البيانات اليومية",
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)",
current: "Mevcut",
daily_details: "Günlük veri",
gift_points: "Hediye puanı",
online_minutes: "Online dakika",
no_daily_data: "Günlük veri yok",
close: "Kapat",
open_daily_data: "Günlük veriyi aç",
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)",
current: "Saat ini",
daily_details: "Data harian",
gift_points: "Poin hadiah",
online_minutes: "Menit online",
no_daily_data: "Tidak ada data harian",
close: "Tutup",
open_daily_data: "Buka data harian",
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 currentGiftValue = "0";
let currentDailyTargets = [];
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?v=20260428-1610`, { 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 formatCountValue(value) {
if (value === null || value === undefined || value === "") return "-";
const number = Number(value);
if (Number.isFinite(number) && Number.isInteger(number)) return String(number);
if (Number.isFinite(number)) return String(Number(number.toFixed(2)));
return String(value);
}
function renderCurrentGiftValue(value) {
currentGiftValue = formatCountValue(value === null || value === undefined || value === "" ? 0 : value);
const giftNode = document.querySelector("#currentGiftValue");
const dailyGiftNode = document.querySelector("#dailyCurrentGift");
if (giftNode) giftNode.textContent = currentGiftValue;
if (dailyGiftNode) dailyGiftNode.textContent = currentGiftValue;
}
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 pickDailyTargets(workTarget) {
const target = workTarget?.target || workTarget || {};
return Array.isArray(target.dailyTargets) ? target.dailyTargets : [];
}
function formatDateNumber(value) {
const text = String(value || "");
if (/^\d{8}$/.test(text)) {
return `${text.slice(0, 4)}.${text.slice(4, 6)}.${text.slice(6, 8)}`;
}
return text || "-";
}
function createDailyRow(item) {
const row = document.createElement("div");
row.className = "daily-row";
const date = document.createElement("div");
date.className = "daily-date";
date.textContent = formatDateNumber(item?.dateNumber);
const values = document.createElement("div");
values.className = "daily-values";
const gift = document.createElement("div");
gift.className = "daily-cell";
gift.innerHTML = `<span>${currentMessages.gift_points || fallbackMessages.en.gift_points}</span><strong>${formatCountValue(item?.acceptGiftValue ?? 0)}</strong>`;
const online = document.createElement("div");
online.className = "daily-cell";
online.innerHTML = `<span>${currentMessages.online_minutes || fallbackMessages.en.online_minutes}</span><strong>${formatCountValue(item?.onlineTime ?? 0)}</strong>`;
values.appendChild(gift);
values.appendChild(online);
row.appendChild(date);
row.appendChild(values);
return row;
}
function replaceNodeChildren(node, children) {
while (node.firstChild) node.removeChild(node.firstChild);
children.forEach((child) => node.appendChild(child));
}
function renderDailyTargets(targets = currentDailyTargets) {
currentDailyTargets = Array.isArray(targets) ? targets : [];
const list = document.querySelector("#dailyList");
if (!list) return;
if (!currentDailyTargets.length) {
const empty = document.createElement("div");
empty.className = "daily-empty";
empty.textContent = currentMessages.no_daily_data || fallbackMessages.en.no_daily_data;
replaceNodeChildren(list, [empty]);
return;
}
replaceNodeChildren(list, currentDailyTargets.map(createDailyRow));
}
function renderMemberWorkSummary(memberWork) {
const workTarget = pickFirstMemberWorkTarget(memberWork);
renderStreamingDuration(pickStreamingDuration(memberWork));
renderCurrentGiftValue(pickGiftValue(workTarget) ?? 0);
renderDailyTargets(pickDailyTargets(workTarget));
}
function setDailyModalOpen(open) {
const modal = document.querySelector("#dailyModal");
if (!modal) return;
modal.hidden = !open;
document.body.classList.toggle("daily-modal-open", open);
if (open) renderDailyTargets();
}
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);
renderMemberWorkSummary(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;
}
}
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);
renderDailyTargets();
}
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();
});
document.querySelector(".gift-value")?.addEventListener("click", () => {
setDailyModalOpen(true);
});
document.querySelectorAll("[data-close-daily]").forEach((node) => {
node.addEventListener("click", () => {
setDailyModalOpen(false);
});
});
document.addEventListener("keydown", (event) => {
if (event.key === "Escape") setDailyModalOpen(false);
});
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) {
await fetchStreamingDuration(memberId);
}
});
fetchBankBalance();
});
})();