2026-06-06 13:42:01 +08:00

258 lines
8.5 KiB
JavaScript

(function () {
var viewport = document.getElementById('appViewport');
var table = document.getElementById('tierTable');
var currentData = null;
var mockData = {
targetReward: '1000',
user: {
name: 'Namename...',
id: '123456789',
avatar: './assets/294_8091.png',
contributionReward: '100',
weeklyReward: '100',
canClaimContribution: true,
canClaimWeeklyReward: false,
},
tiers: [
{ turnover: '7M', reward: '350k' },
{ turnover: '7M', reward: '350k' },
{ turnover: '7M', reward: '350k' },
{ turnover: '7M', reward: '350k' },
{ turnover: '7M', reward: '350k' },
{ turnover: '7M', reward: '350k' },
{ turnover: '7M', reward: '350k' },
],
};
function escapeHTML(value) {
return String(value == null ? '' : value)
.replace(/&/g, '&')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;');
}
function t(key, fallback) {
if (window.HyAppI18n && window.HyAppI18n.t) {
return window.HyAppI18n.t(key, fallback);
}
return fallback;
}
function syncStaticText() {
document.title = t('roomReward.pageTitle', 'Room Reward Event');
}
function userIDText(value) {
return t('roomReward.idPrefix', 'ID:') + ' ' + value;
}
function renderTable(data) {
data = data || mockData;
var rows = [
'<div class="tier-row is-head">',
'<div data-i18n="roomReward.turnover">',
t('roomReward.turnover', 'Room turnover'),
'</div>',
'<div data-i18n="roomReward.receiveReward">',
t('roomReward.receiveReward', 'Receive a reward'),
'</div>',
'</div>',
];
(data.tiers || []).forEach(function (item) {
rows.push(
[
'<div class="tier-row">',
'<div>',
escapeHTML(item.turnover),
'</div>',
'<div class="tier-reward">',
'<span>',
escapeHTML(item.reward),
'</span>',
'<img class="mini-coin" src="./assets/296_8275.png" alt="" aria-hidden="true" />',
'</div>',
'</div>',
].join('')
);
});
table.innerHTML = rows.join('');
if (window.HyAppI18n && window.HyAppI18n.apply) {
window.HyAppI18n.apply(table);
}
}
function renderUser(data) {
data = data || mockData;
document.getElementById('targetReward').textContent = data.targetReward;
document.getElementById('userAvatar').src = data.user.avatar;
document.getElementById('userName').textContent =
data.user.name || t('roomReward.roomOwner', 'Room owner');
document.getElementById('userId').textContent = userIDText(data.user.id);
document.getElementById('contributionValue').textContent =
data.user.contributionReward;
document.getElementById('weeklyRewardValue').textContent =
data.user.weeklyReward;
var contributionButton = document.getElementById('contributionButton');
var rewardsButton = document.getElementById('rewardsButton');
setButtonState(
contributionButton,
Boolean(data.user.canClaimContribution)
);
setButtonState(rewardsButton, Boolean(data.user.canClaimWeeklyReward));
}
function setButtonState(button, enabled) {
var img = button.querySelector('img');
button.disabled = !enabled;
button.classList.toggle('is-disabled', !enabled);
button.classList.toggle('is-active', enabled);
if (img) {
img.src = enabled
? button.getAttribute('data-active-src')
: button.getAttribute('data-inactive-src');
}
}
function updateBodyHeight() {
var scale = Math.min(window.innerWidth / 375, 1);
document.documentElement.style.setProperty('--app-scale', String(scale));
document.body.style.minHeight = viewport.offsetHeight * scale + 'px';
}
function readQuery(name) {
return new URLSearchParams(window.location.search).get(name);
}
function shouldUseMock() {
return (
readQuery('mock') === '1' ||
window.location.protocol === 'file:' ||
!window.HyAppAPI
);
}
function compactNumber(value) {
var number = Number(value || 0);
if (!Number.isFinite(number)) return '0';
if (number >= 1000000) return trimFixed(number / 1000000) + 'M';
if (number >= 1000) return trimFixed(number / 1000) + 'k';
return String(Math.floor(number));
}
function trimFixed(value) {
var fixed = value >= 10 ? value.toFixed(0) : value.toFixed(1);
return fixed.replace(/\.0$/, '');
}
function valueFrom(source) {
for (var index = 1; index < arguments.length; index += 1) {
var key = arguments[index];
if (
source &&
source[key] !== undefined &&
source[key] !== null &&
source[key] !== ''
) {
return source[key];
}
}
return '';
}
function normalizeAPIData(payload) {
var data = payload || {};
var user = data.user || {};
var room = data.room || {};
var tiers = Array.isArray(data.tiers) ? data.tiers : [];
var currentCoinSpent = Number(
valueFrom(data, 'currentCoinSpent', 'current_coin_spent') || 0
);
var expectedReward = Number(
valueFrom(
data,
'expectedRewardCoinAmount',
'expected_reward_coin_amount'
) || 0
);
return {
targetReward: compactNumber(expectedReward),
user: {
name:
valueFrom(user, 'username', 'name') ||
valueFrom(room, 'title'),
id:
valueFrom(user, 'displayUserId', 'display_user_id') ||
valueFrom(user, 'userId', 'user_id') ||
valueFrom(room, 'ownerUserId', 'owner_user_id') ||
'-',
avatar:
valueFrom(user, 'avatar') ||
valueFrom(room, 'coverUrl', 'cover_url') ||
'./assets/294_8091.png',
contributionReward: compactNumber(currentCoinSpent),
weeklyReward: compactNumber(expectedReward),
canClaimContribution: currentCoinSpent > 0,
canClaimWeeklyReward: expectedReward > 0,
},
tiers: tiers.map(function (tier) {
return {
turnover: compactNumber(
valueFrom(
tier,
'thresholdCoinSpent',
'threshold_coin_spent'
)
),
reward: compactNumber(
valueFrom(tier, 'rewardCoinAmount', 'reward_coin_amount')
),
};
}),
};
}
function loadData() {
if (shouldUseMock()) {
return Promise.resolve(mockData);
}
return window.HyAppAPI.get('/api/v1/activities/room-turnover-reward')
.then(normalizeAPIData)
.catch(function (error) {
console.warn('[room-reward] api fallback', error);
return mockData;
});
}
function render(data) {
currentData = data || mockData;
renderTable(currentData);
renderUser(currentData);
}
function init() {
syncStaticText();
render(mockData);
loadData().then(render);
window.addEventListener('resize', updateBodyHeight);
window.addEventListener('hyapp:i18n-ready', function () {
syncStaticText();
renderTable(currentData || mockData);
renderUser(currentData || mockData);
});
updateBodyHeight();
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();