2026-06-24 11:37:57 +08:00

1231 lines
40 KiB
JavaScript
Raw Permalink 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 () {
var HOST_SALARY_USD = 'HOST_SALARY_USD';
var state = emptyHostState();
var policyAutoScrollPending = false;
function $(id) {
return document.getElementById(id);
}
function emptyHostState() {
return {
profile: {
loading: true,
name: '',
uid: '',
avatar: '',
},
agency: {
loading: true,
shortId: '',
name: '',
avatar: '',
},
salary: {
loading: true,
available: 0,
monthKey: '',
month: '',
currencyKey: '',
currency: '',
useCurrentMonth: false,
},
level: {
loading: true,
current: 0,
nextLevelNo: 0,
currentRequired: 0,
currentValue: 0,
nextValue: 0,
needed: 0,
},
policy: {
loading: true,
loaded: false,
found: false,
policy: null,
},
messages: [],
processingMessages: {},
};
}
function setSkeleton(element, loading, text) {
if (!element) return;
element.classList.toggle('skeleton-line', !!loading);
if (loading) {
element.textContent = '';
return;
}
element.textContent = text || '';
}
function avatarData(text, background, foreground) {
var value =
String(text || 'Y')
.trim()
.charAt(0) || 'Y';
var letter = value.replace(/[<>&"']/g, '');
var svg =
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 96 96">' +
'<rect width="96" height="96" rx="48" fill="' +
background +
'"/>' +
'<text x="50%" y="54%" text-anchor="middle" dominant-baseline="middle" fill="' +
foreground +
'" font-family="Arial, sans-serif" font-size="38" font-weight="800">' +
letter +
'</text>' +
'</svg>';
return 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(svg);
}
function t(key, fallback) {
return window.HyAppI18n && window.HyAppI18n.t
? window.HyAppI18n.t(key, fallback)
: fallback || key;
}
function money(value) {
var number = Number(value || 0);
return number.toLocaleString('en-US', {
minimumFractionDigits: 2,
maximumFractionDigits: 2,
});
}
function integer(value) {
var number = Number(value || 0);
return number.toLocaleString('en-US', {
maximumFractionDigits: 0,
});
}
function initial(text) {
return String(text || '')
.trim()
.charAt(0)
.toUpperCase();
}
function hasAccessToken() {
return (
window.HyAppAPI &&
window.HyAppAPI.getAccessToken &&
!!window.HyAppAPI.getAccessToken()
);
}
function unwrapData(payload) {
if (!payload || typeof payload !== 'object') return payload;
return Object.prototype.hasOwnProperty.call(payload, 'data')
? payload.data
: payload;
}
function firstValue(source, keys) {
if (!source) return '';
for (var i = 0; i < keys.length; i += 1) {
var value = source[keys[i]];
if (value !== undefined && value !== null && value !== '') {
return value;
}
}
return '';
}
function toNumber(value) {
var number = Number(value);
return Number.isFinite(number) ? number : 0;
}
function safeRequest(factory) {
return factory().catch(function (error) {
if (window.console && window.console.warn) {
window.console.warn('[host-center] api failed', error);
}
return null;
});
}
function currentLocale() {
var lang =
window.HyAppI18n && window.HyAppI18n.lang
? window.HyAppI18n.lang()
: 'en';
var map = {
en: 'en-US',
ar: 'ar',
tr: 'tr-TR',
es: 'es-ES',
zh: 'zh-CN',
id: 'id-ID',
};
return map[lang] || 'en-US';
}
function currentMonthName() {
try {
return new Date().toLocaleString(currentLocale(), {
month: 'long',
});
} catch (_) {
return 'June';
}
}
function salaryMonthLabel(salary) {
if (salary.monthKey) return t(salary.monthKey, salary.month);
if (salary.useCurrentMonth) return currentMonthName();
return salary.month || currentMonthName();
}
function salaryCurrencyLabel(salary) {
if (salary.currencyKey) return t(salary.currencyKey, salary.currency);
return salary.currency || t('host_center.currency_usd', 'USD');
}
function formatMode(value) {
var text = String(value || '')
.replace(/[_-]+/g, ' ')
.trim();
if (!text) return '-';
return text.replace(/\b\w/g, function (letter) {
return letter.toUpperCase();
});
}
function formatDate(ms) {
var value = toNumber(ms);
if (!value) return '';
try {
return new Date(value).toLocaleDateString(currentLocale(), {
year: 'numeric',
month: 'short',
day: 'numeric',
});
} catch (_) {
return '';
}
}
function commandID(prefix, id) {
return [
prefix,
id || '0',
Date.now(),
Math.random().toString(16).slice(2),
].join('-');
}
function normalizeInvitationMessage(item) {
var invitation = (item && item.invitation) || item || {};
var inviter = (item && item.inviter) || {};
var id = String(
invitation.invitation_id || invitation.invitationId || ''
);
var type = firstValue(invitation, [
'invitation_type',
'invitationType',
]);
var agencyName = firstValue(invitation, ['agency_name', 'agencyName']);
var inviterName =
firstValue(inviter, ['username', 'name', 'display_user_id']) ||
firstValue(invitation, ['inviter_user_id', 'inviterUserId']) ||
t('host_center.inviter', 'Inviter');
return {
id: id,
type: type,
name: inviterName,
account:
firstValue(inviter, ['display_user_id', 'displayUserID']) ||
firstValue(inviter, ['user_id', 'userId']) ||
firstValue(invitation, ['inviter_user_id', 'inviterUserId']),
avatar: firstValue(inviter, ['avatar']),
title: invitationMessageTitle(type, inviterName, agencyName),
};
}
function invitationMessageTitle(type, inviterName, agencyName) {
if (type === 'host') {
return t(
'host_center.host_invitation',
'{name} invited you to join {agency}'
)
.replace('{name}', inviterName)
.replace(
'{agency}',
agencyName || t('host_center.agency', 'Agency')
);
}
if (type === 'agency') {
return t(
'host_center.agency_invitation',
'{name} invited you to create agency {agency}'
)
.replace('{name}', inviterName)
.replace(
'{agency}',
agencyName || t('host_center.agency', 'Agency')
);
}
if (type === 'bd') {
return t(
'host_center.bd_invitation',
'{name} invited you to become BD'
).replace('{name}', inviterName);
}
return t(
'host_center.role_invitation',
'{name} sent you an invitation'
).replace('{name}', inviterName);
}
function renderUnread() {
var dot = $('messageUnreadDot');
if (dot) dot.hidden = state.messages.length <= 0;
}
function createMessageAvatar(message) {
var avatar = document.createElement('div');
avatar.className = 'message-avatar';
if (!message.avatar) {
avatar.textContent = initial(message.name || 'M') || 'M';
return avatar;
}
var img = document.createElement('img');
img.src = message.avatar;
img.alt = '';
img.addEventListener('error', function () {
avatar.textContent = initial(message.name || 'M') || 'M';
});
avatar.appendChild(img);
return avatar;
}
function renderMessages() {
var list = $('messageList');
var empty = $('messageEmpty');
if (!list || !empty) return;
list.textContent = '';
empty.hidden = state.messages.length > 0;
empty.textContent = t('host_center.no_messages', 'No messages');
state.messages.forEach(function (message) {
var card = document.createElement('article');
var user = document.createElement('div');
var copy = document.createElement('div');
var title = document.createElement('div');
var meta = document.createElement('div');
var actions = document.createElement('div');
var agree = document.createElement('button');
var refuse = document.createElement('button');
card.className = 'message-card';
user.className = 'message-user';
copy.className = 'message-copy';
title.className = 'message-name';
meta.className = 'message-id';
actions.className = 'message-actions';
agree.className = 'message-action agree';
refuse.className = 'message-action refuse';
agree.type = 'button';
refuse.type = 'button';
agree.disabled = Boolean(state.processingMessages[message.id]);
refuse.disabled = Boolean(state.processingMessages[message.id]);
title.textContent = message.title;
meta.textContent = message.account ? 'ID: ' + message.account : '';
agree.textContent = t('host_center.agree', 'Agree');
refuse.textContent = t('host_center.refuse', 'Refuse');
agree.addEventListener('click', function () {
processInvitationMessage(message, 'accept');
});
refuse.addEventListener('click', function () {
processInvitationMessage(message, 'reject');
});
user.appendChild(createMessageAvatar(message));
copy.appendChild(title);
copy.appendChild(meta);
user.appendChild(copy);
actions.appendChild(agree);
actions.appendChild(refuse);
card.appendChild(user);
card.appendChild(actions);
list.appendChild(card);
});
renderUnread();
}
function policyAmount(minor) {
return '$' + money(toNumber(minor) / 100);
}
function renderProfile() {
var image = $('profileAvatar');
var fallback = $('profileAvatarFallback');
var badge = $('profileBadge');
var profile = state.profile;
var agency = state.agency;
var loading = !!profile.loading;
setSkeleton($('profileName'), loading, profile.name || '');
setSkeleton(
$('profileUID'),
loading,
profile.uid ? 'UID: ' + profile.uid : ''
);
fallback.classList.toggle('avatar-skeleton', loading);
if (loading) {
image.hidden = true;
image.removeAttribute('src');
fallback.hidden = false;
fallback.textContent = '';
badge.hidden = true;
badge.replaceChildren();
badge.classList.remove('skeleton-line');
return;
}
fallback.textContent = initial(profile.name || profile.uid) || 'Y';
if (agency.loading) {
badge.hidden = false;
setSkeleton(badge, true, '');
} else if (agency.shortId) {
badge.hidden = false;
badge.classList.remove('skeleton-line');
renderAgencyBadge(badge, agency);
} else {
badge.hidden = true;
badge.classList.remove('skeleton-line');
badge.replaceChildren();
}
if (!profile.avatar) {
image.hidden = true;
image.removeAttribute('src');
fallback.hidden = false;
return;
}
image.onload = function () {
image.hidden = false;
fallback.hidden = true;
};
image.onerror = function () {
image.hidden = true;
fallback.hidden = false;
};
image.src = profile.avatar;
}
function renderAgencyBadge(container, agency) {
container.replaceChildren();
var avatar = document.createElement('span');
avatar.className = 'agency-badge-avatar';
var fallbackText =
initial(agency.name || agency.shortId) ||
t('host_center.agency', 'Agency').charAt(0);
if (agency.avatar) {
var img = document.createElement('img');
img.src = agency.avatar;
img.alt = '';
img.addEventListener('error', function () {
avatar.textContent = fallbackText;
});
avatar.appendChild(img);
} else {
avatar.textContent = fallbackText;
}
var text = document.createElement('span');
text.className = 'agency-badge-id';
text.textContent = t(
'host_center.agency_short_id',
'Agency ID: {id}'
).replace('{id}', agency.shortId);
container.appendChild(avatar);
container.appendChild(text);
}
function renderIncome() {
var salary = state.salary;
var loading = !!salary.loading;
setSkeleton($('availableSalary'), loading, money(salary.available));
setSkeleton(
$('incomeFoot'),
loading,
t(
'host_center.salary_month_note',
'{month} settlement · {currency}'
)
.replace('{month}', salaryMonthLabel(salary))
.replace('{currency}', salaryCurrencyLabel(salary))
);
var coinIcon = document.querySelector('.coin-icon');
if (coinIcon) coinIcon.classList.toggle('skeleton-coin', loading);
}
function renderLevel() {
var level = state.level;
var loading = !!level.loading;
if (loading) {
setSkeleton($('currentLevel'), true, '');
setSkeleton($('nextLevelNeed'), true, '');
setSkeleton($('levelStatus'), true, '');
$('levelProgress').style.width = '38%';
$('levelProgress').classList.add('skeleton-fill');
return;
}
var currentRequired = toNumber(level.currentRequired);
var currentValue = toNumber(level.currentValue);
var nextValue = toNumber(level.nextValue);
var need =
level.needed !== undefined && level.needed !== null
? toNumber(level.needed)
: Math.max(0, nextValue - currentValue);
var denominator = Math.max(1, nextValue - currentRequired);
var currentInLevel = Math.max(0, currentValue - currentRequired);
var percent =
nextValue > currentRequired
? Math.min(
100,
Math.round((currentInLevel / denominator) * 100)
)
: 100;
$('currentLevel').textContent = t(
'host_center.level_value',
'Lv. {level}'
).replace('{level}', String(level.current || 0));
$('nextLevelNeed').textContent = money(need);
$('currentLevel').classList.remove('skeleton-line');
$('nextLevelNeed').classList.remove('skeleton-line');
$('levelStatus').classList.remove('skeleton-line');
$('levelProgress').style.width = percent + '%';
$('levelProgress').classList.remove('skeleton-fill');
$('levelStatus').textContent = t(
'host_center.current_diamonds',
'Current diamonds: {value}'
).replace('{value}', integer(currentValue));
}
function appendPolicyCell(parent, label, value) {
var cell = document.createElement('div');
cell.className = 'policy-cell';
var labelNode = document.createElement('span');
labelNode.className = 'policy-cell-label';
labelNode.textContent = label;
var valueNode = document.createElement('strong');
valueNode.className = 'policy-cell-value';
valueNode.textContent = value;
cell.appendChild(labelNode);
cell.appendChild(valueNode);
parent.appendChild(cell);
}
function policyHighlightLevelNo() {
var current = toNumber(state.level && state.level.current);
return current > 0 ? current : 0;
}
function isPolicyOpen() {
var modal = $('policyModal');
return !!modal && !modal.hidden;
}
function scrollPolicyLevelIntoView(row) {
if (!policyAutoScrollPending || !row || !isPolicyOpen()) return;
policyAutoScrollPending = false;
var run = window.requestAnimationFrame || window.setTimeout;
run(function () {
try {
row.scrollIntoView({
behavior: 'smooth',
block: 'center',
inline: 'nearest',
});
} catch (_) {
var container = row.closest('.policy-sheet-body');
if (container) {
container.scrollTop =
row.offsetTop -
Math.max(
0,
(container.clientHeight - row.offsetHeight) / 2
);
}
}
});
}
function renderPolicy() {
var summary = state.policy || {};
var policy = summary.policy || {};
var list = $('policyLevelList');
var empty = $('policyEmpty');
if (!list || !empty) return;
list.textContent = '';
if (summary.loading) {
setSkeleton($('policyName'), true, '');
setSkeleton($('policyMeta'), true, '');
empty.hidden = false;
empty.textContent = '';
empty.classList.add('policy-skeleton-block');
return;
}
$('policyName').classList.remove('skeleton-line');
$('policyMeta').classList.remove('skeleton-line');
empty.classList.remove('policy-skeleton-block');
if (!summary.found || !policy || !policy.name) {
$('policyName').textContent = 'Platform policy';
$('policyMeta').textContent = '';
empty.hidden = false;
empty.textContent = 'No platform policy configured.';
policyAutoScrollPending = false;
return;
}
var from = formatDate(policy.effective_from_ms);
var to = formatDate(policy.effective_to_ms);
var meta = [
'Mode: ' + formatMode(policy.settlement_mode),
'Trigger: ' + formatMode(policy.settlement_trigger_mode),
];
if (from || to) {
meta.push('Effective: ' + (from || '-') + ' - ' + (to || 'No end'));
}
$('policyName').textContent = policy.name || 'Current policy';
$('policyMeta').textContent = meta.join(' / ');
empty.hidden = true;
empty.textContent = '';
var levels = Array.isArray(policy.levels) ? policy.levels : [];
if (!levels.length) {
empty.hidden = false;
empty.textContent = 'No policy levels configured.';
policyAutoScrollPending = false;
return;
}
var highlightedRow = null;
var activeLevelNo = policyHighlightLevelNo();
levels.forEach(function (level) {
var row = document.createElement('div');
row.className = 'policy-level-row';
var levelNo = toNumber(level.level_no);
row.dataset.levelNo = String(levelNo || '');
if (levelNo > 0 && levelNo === activeLevelNo) {
row.className += ' is-current-level';
highlightedRow = row;
}
var head = document.createElement('div');
head.className = 'policy-row-head';
var title = document.createElement('strong');
title.className = 'policy-level';
title.textContent = 'Lv. ' + (levelNo || '-');
var required = document.createElement('span');
required.className = 'policy-effective';
required.textContent =
integer(level.required_diamonds) + ' diamonds';
head.appendChild(title);
head.appendChild(required);
var grid = document.createElement('div');
grid.className = 'policy-grid';
appendPolicyCell(
grid,
'Host salary',
policyAmount(level.host_salary_usd_minor)
);
var hostCoinReward = toNumber(level.host_coin_reward);
// Host 端只展示主播能直接获得的有效奖励;为 0 或缺失时隐藏,避免把无收益项误读成待完成权益。
if (hostCoinReward > 0) {
appendPolicyCell(
grid,
'Host coin reward',
integer(hostCoinReward)
);
}
row.appendChild(head);
row.appendChild(grid);
list.appendChild(row);
});
if (highlightedRow) {
scrollPolicyLevelIntoView(highlightedRow);
} else {
policyAutoScrollPending = false;
}
}
function render() {
renderProfile();
renderIncome();
renderLevel();
renderPolicy();
renderMessages();
}
function applyProfile(payload) {
var profile = unwrapData(payload);
if (!profile) return;
var name = firstValue(profile, [
'username',
'nickname',
'name',
'display_name',
]);
var uid = firstValue(profile, [
'display_user_id',
'default_display_user_id',
'uid',
'user_id',
]);
var avatar = firstValue(profile, ['avatar', 'avatar_url', 'avatarUrl']);
state.profile = {
loading: false,
name: name || state.profile.name,
uid: uid || state.profile.uid,
avatar:
avatar ||
avatarData(
initial(name || uid || state.profile.name),
'#dbc8ff',
'#7d57c7'
),
};
}
function applyAgency(payload) {
var data = unwrapData(payload);
var agency = data && data.agency ? data.agency : data;
if (!agency) {
return;
}
var shortId = firstValue(agency, [
'short_id',
'shortId',
'display_user_id',
'displayUserId',
'agency_id',
'agencyId',
]);
state.agency = {
loading: false,
shortId: shortId ? String(shortId) : '',
name: firstValue(agency, ['name', 'agency_name', 'agencyName']),
avatar: firstValue(agency, ['avatar', 'avatar_url', 'avatarUrl']),
};
}
function displayAmountForAsset(assetType, amount) {
if (assetType === HOST_SALARY_USD) return toNumber(amount) / 100;
return toNumber(amount);
}
function findBalance(payload, assetType) {
var data = unwrapData(payload);
var balances =
data && Array.isArray(data.balances) ? data.balances : [];
for (var i = 0; i < balances.length; i += 1) {
if (
balances[i].asset_type === assetType ||
balances[i].assetType === assetType
) {
return balances[i];
}
}
return null;
}
function applyWallet(payload) {
var balance = findBalance(payload, HOST_SALARY_USD);
if (!balance) {
state.salary = Object.assign({}, state.salary, {
loading: false,
available: 0,
monthKey: '',
month: '',
currencyKey: 'host_center.currency_usd',
currency: 'USD',
useCurrentMonth: true,
});
return;
}
var amount = firstValue(balance, [
'available_amount',
'availableAmount',
]);
state.salary = Object.assign({}, state.salary, {
loading: false,
available: displayAmountForAsset(HOST_SALARY_USD, amount),
monthKey: '',
month: '',
currencyKey: 'host_center.currency_usd',
currency: 'USD',
useCurrentMonth: true,
});
}
function applyLevelProgress(progress) {
if (!progress) return;
state.level = {
loading: false,
current: toNumber(
firstValue(progress, ['current_level', 'currentLevel'])
),
nextLevelNo: toNumber(
firstValue(progress, ['next_level', 'nextLevel'])
),
currentRequired: toNumber(
firstValue(progress, [
'current_required_diamonds',
'currentRequiredDiamonds',
])
),
currentValue: toNumber(
firstValue(progress, ['current_value', 'currentValue'])
),
nextValue: toNumber(
firstValue(progress, [
'next_required_diamonds',
'nextRequiredDiamonds',
'current_value',
'currentValue',
])
),
needed: toNumber(
firstValue(progress, [
'needed_for_next_level',
'neededForNextLevel',
])
),
};
}
function fallbackLevelProgress() {
return {
loading: false,
current: 0,
nextLevelNo: 0,
currentRequired: 0,
currentValue: 0,
nextValue: 1,
needed: 0,
};
}
function levelProgressFromPolicy(policy, progress) {
var levels =
policy && Array.isArray(policy.levels) ? policy.levels : [];
var currentValue = toNumber(
firstValue(progress, [
'total_diamonds',
'totalDiamonds',
'gift_diamond_total',
'giftDiamondTotal',
])
);
if (!levels.length) {
return Object.assign(fallbackLevelProgress(), {
currentValue: currentValue,
});
}
var current = null;
var next = null;
levels.forEach(function (level) {
if (!level) return;
var required = toNumber(
firstValue(level, ['required_diamonds', 'requiredDiamonds'])
);
if (required <= currentValue) {
if (
!current ||
required >
toNumber(
firstValue(current, [
'required_diamonds',
'requiredDiamonds',
])
)
) {
current = level;
}
return;
}
if (
!next ||
required <
toNumber(
firstValue(next, [
'required_diamonds',
'requiredDiamonds',
])
)
) {
next = level;
}
});
var currentRequired = current
? toNumber(
firstValue(current, ['required_diamonds', 'requiredDiamonds'])
)
: 0;
var nextRequired = next
? toNumber(
firstValue(next, ['required_diamonds', 'requiredDiamonds'])
)
: currentRequired;
var currentLevel = current
? toNumber(firstValue(current, ['level_no', 'levelNo', 'level']))
: 0;
var nextLevel = next
? toNumber(firstValue(next, ['level_no', 'levelNo', 'level']))
: currentLevel;
return {
current_level: currentLevel,
current_required_diamonds: currentRequired,
current_value: currentValue,
next_level: nextLevel,
next_required_diamonds: nextRequired,
needed_for_next_level: next
? Math.max(0, nextRequired - currentValue)
: 0,
};
}
function applyPolicy(payload) {
var data = unwrapData(payload);
if (!data || !data.found || !data.policy) {
// 线上策略未配置或旧网关返回空数据时,等级区域不能停在骨架态;展示空进度比持续 loading 更能说明真实状态。
state.level = fallbackLevelProgress();
state.policy = {
loading: false,
loaded: true,
found: false,
policy: null,
};
return;
}
// 新网关直接返回 level_progress旧网关只有 policy/progress 时H5 按同一套档位和当前钻石累计计算目标进度。
applyLevelProgress(
firstValue(data, ['level_progress', 'levelProgress']) ||
levelProgressFromPolicy(
data.policy,
firstValue(data, [
'progress',
'salary_progress',
'salaryProgress',
])
)
);
state.policy = {
loading: false,
loaded: true,
found: true,
policy: data.policy,
};
}
function toast(message) {
if (!message) return;
if (window.HyAppToast && window.HyAppToast.show) {
window.HyAppToast.show(message);
}
}
function loadPolicy() {
if (!window.HyAppAPI || !window.HyAppAPI.hostCenter) {
renderPolicy();
return Promise.resolve(false);
}
if (!hasAccessToken()) {
renderPolicy();
return Promise.resolve(false);
}
state.policy = Object.assign({}, state.policy, { loading: true });
renderPolicy();
return safeRequest(function () {
return window.HyAppAPI.hostCenter.platformPolicy();
}).then(function (payload) {
if (payload) {
applyPolicy(payload);
} else {
// 失败分支同样要结束主卡片 loading否则页面会像线上截图一样一直显示紫色骨架条。
state.level = fallbackLevelProgress();
state.policy = {
loading: false,
loaded: false,
found: false,
policy: null,
};
toast(
t(
'host_center.load_failed',
'Load failed. Try again later.'
)
);
}
renderPolicy();
return !!payload;
});
}
function loadRoleInvitations() {
if (
!window.HyAppAPI ||
!window.HyAppAPI.roleInvitations ||
!window.HyAppAPI.roleInvitations.list ||
!hasAccessToken()
) {
state.messages = [];
renderMessages();
return Promise.resolve(false);
}
return window.HyAppAPI.roleInvitations
.list('pending', 50)
.then(function (payload) {
var items =
(payload && (payload.items || payload.invitations)) || [];
state.messages = items
.map(normalizeInvitationMessage)
.filter(function (item) {
return !!item.id;
});
renderMessages();
return true;
})
.catch(function (error) {
if (window.console && window.console.warn) {
window.console.warn('[host-center] messages failed', error);
}
state.messages = [];
renderMessages();
return false;
});
}
function processInvitationMessage(message, action) {
if (
!message ||
!message.id ||
!window.HyAppAPI ||
!window.HyAppAPI.roleInvitations ||
!window.HyAppAPI.roleInvitations.process
) {
return;
}
state.processingMessages[message.id] = true;
renderMessages();
window.HyAppAPI.roleInvitations
.process(message.id, {
command_id: commandID('role-invite-' + action, message.id),
action: action,
reason: 'h5_message_center',
})
.then(function () {
state.messages = state.messages.filter(function (item) {
return item.id !== message.id;
});
toast(
t(
action === 'accept'
? 'host_center.invitation_accepted'
: 'host_center.invitation_rejected',
action === 'accept'
? 'Invitation accepted.'
: 'Invitation rejected.'
)
);
renderMessages();
return loadRealData();
})
.catch(function (error) {
toast(
(error && error.message) ||
t(
'host_center.process_failed',
'Process failed. Try again later.'
)
);
})
.finally(function () {
delete state.processingMessages[message.id];
renderMessages();
});
}
function openMessages() {
var modal = $('messageModal');
if (!modal) return;
renderMessages();
modal.hidden = false;
modal.setAttribute('aria-hidden', 'false');
document.body.classList.add('modal-open');
}
function closeMessages() {
var modal = $('messageModal');
if (!modal) return;
modal.hidden = true;
modal.setAttribute('aria-hidden', 'true');
document.body.classList.remove('modal-open');
}
function requestPolicy() {
if (!window.HyAppAPI || !window.HyAppAPI.hostCenter) {
return Promise.resolve(null);
}
return safeRequest(function () {
return window.HyAppAPI.hostCenter.platformPolicy();
});
}
function loadRealData() {
if (!window.HyAppAPI) return Promise.resolve(false);
if (window.HyAppParams && window.HyAppParams.parse) {
window.HyAppParams.parse();
}
if (!hasAccessToken()) return Promise.resolve(false);
return Promise.all([
safeRequest(function () {
return window.HyAppAPI.user.me();
}),
safeRequest(function () {
return window.HyAppAPI.hostCenter.agency();
}),
safeRequest(function () {
return window.HyAppAPI.wallet.balances([HOST_SALARY_USD]);
}),
requestPolicy(),
]).then(function (results) {
applyProfile(results[0]);
applyAgency(results[1]);
applyWallet(results[2]);
if (results[3]) {
applyPolicy(results[3]);
} else {
applyPolicy(null);
}
render();
var hasAnyData = results.some(function (item) {
return !!item;
});
if (!hasAnyData) {
toast(
t(
'host_center.load_failed',
'Load failed. Try again later.'
)
);
}
return hasAnyData;
});
}
function openWithdrawExchange() {
var params = new URLSearchParams(window.location.search);
params.set('identity', 'HOST');
params.set('salaryType', HOST_SALARY_USD);
params.set('asset_type', HOST_SALARY_USD);
if (!params.has('mode')) params.set('mode', 'withdraw');
window.location.href =
'../withdraw-exchange/index.html?' + params.toString();
}
function openPolicy() {
var modal = $('policyModal');
if (!modal) return;
policyAutoScrollPending = true;
modal.hidden = false;
modal.setAttribute('aria-hidden', 'false');
document.body.classList.add('modal-open');
renderPolicy();
policyAutoScrollPending = true;
loadPolicy();
}
function closePolicy() {
var modal = $('policyModal');
if (!modal) return;
modal.hidden = true;
modal.setAttribute('aria-hidden', 'true');
document.body.classList.remove('modal-open');
policyAutoScrollPending = false;
}
function bindEvents() {
$('backButton').addEventListener('click', function () {
if (window.HyAppBridge) window.HyAppBridge.back();
});
$('incomeWithdrawExchangeButton').addEventListener(
'click',
openWithdrawExchange
);
document
.querySelectorAll('[data-action="policy"]')
.forEach(function (button) {
button.addEventListener('click', openPolicy);
});
document
.querySelectorAll('[data-action="messages"]')
.forEach(function (button) {
button.addEventListener('click', openMessages);
});
document
.querySelectorAll('[data-close-policy]')
.forEach(function (button) {
button.addEventListener('click', closePolicy);
});
$('messageBackdrop').addEventListener('click', closeMessages);
$('messageCloseButton').addEventListener('click', closeMessages);
document.addEventListener('keydown', function (event) {
if (event.key === 'Escape') {
closePolicy();
closeMessages();
}
});
}
var initialized = false;
function init() {
if (initialized) return;
initialized = true;
render();
bindEvents();
loadRealData().then(function (loaded) {
loadRoleInvitations();
if (window.HyAppBridge) {
window.HyAppBridge.ready({
page: 'host-center',
mock: false,
});
}
});
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
window.addEventListener('hyapp:i18n-ready', function () {
render();
});
window.addEventListener('hyapp:role-invitation-processed', function () {
loadRealData();
});
})();