diff --git a/activity/invite/assets/button-active-wide.png b/activity/invite/assets/button-active-wide.png new file mode 100644 index 0000000..a9e4ddb Binary files /dev/null and b/activity/invite/assets/button-active-wide.png differ diff --git a/activity/invite/assets/button-inactive-wide.png b/activity/invite/assets/button-inactive-wide.png new file mode 100644 index 0000000..efc70fe Binary files /dev/null and b/activity/invite/assets/button-inactive-wide.png differ diff --git a/activity/invite/assets/claim-active.png b/activity/invite/assets/claim-active.png new file mode 100644 index 0000000..0e906f6 Binary files /dev/null and b/activity/invite/assets/claim-active.png differ diff --git a/activity/invite/assets/claim-inactive.png b/activity/invite/assets/claim-inactive.png new file mode 100644 index 0000000..c3232e8 Binary files /dev/null and b/activity/invite/assets/claim-inactive.png differ diff --git a/activity/invite/assets/countdown-panel.png b/activity/invite/assets/countdown-panel.png new file mode 100644 index 0000000..15d127a Binary files /dev/null and b/activity/invite/assets/countdown-panel.png differ diff --git a/activity/invite/assets/gold-stack.png b/activity/invite/assets/gold-stack.png new file mode 100644 index 0000000..4aed35a Binary files /dev/null and b/activity/invite/assets/gold-stack.png differ diff --git a/activity/invite/assets/hero-bg.png b/activity/invite/assets/hero-bg.png new file mode 100644 index 0000000..a0f30ae Binary files /dev/null and b/activity/invite/assets/hero-bg.png differ diff --git a/activity/invite/assets/link-input.svg b/activity/invite/assets/link-input.svg new file mode 100644 index 0000000..c021ed4 --- /dev/null +++ b/activity/invite/assets/link-input.svg @@ -0,0 +1,12 @@ + +
+ + + + + + + + + +
diff --git a/activity/invite/assets/medal-1.png b/activity/invite/assets/medal-1.png new file mode 100644 index 0000000..df7b345 Binary files /dev/null and b/activity/invite/assets/medal-1.png differ diff --git a/activity/invite/assets/medal-2.png b/activity/invite/assets/medal-2.png new file mode 100644 index 0000000..67ad74d Binary files /dev/null and b/activity/invite/assets/medal-2.png differ diff --git a/activity/invite/assets/medal-3.png b/activity/invite/assets/medal-3.png new file mode 100644 index 0000000..5ee50f6 Binary files /dev/null and b/activity/invite/assets/medal-3.png differ diff --git a/activity/invite/assets/milestone-row.svg b/activity/invite/assets/milestone-row.svg new file mode 100644 index 0000000..efec76f --- /dev/null +++ b/activity/invite/assets/milestone-row.svg @@ -0,0 +1,3 @@ + + + diff --git a/activity/invite/assets/panel-bottom-a.png b/activity/invite/assets/panel-bottom-a.png new file mode 100644 index 0000000..56478bf Binary files /dev/null and b/activity/invite/assets/panel-bottom-a.png differ diff --git a/activity/invite/assets/panel-bottom-b.png b/activity/invite/assets/panel-bottom-b.png new file mode 100644 index 0000000..56478bf Binary files /dev/null and b/activity/invite/assets/panel-bottom-b.png differ diff --git a/activity/invite/assets/panel-middle-a.png b/activity/invite/assets/panel-middle-a.png new file mode 100644 index 0000000..e5a17d3 Binary files /dev/null and b/activity/invite/assets/panel-middle-a.png differ diff --git a/activity/invite/assets/panel-middle-b.png b/activity/invite/assets/panel-middle-b.png new file mode 100644 index 0000000..e5a17d3 Binary files /dev/null and b/activity/invite/assets/panel-middle-b.png differ diff --git a/activity/invite/assets/panel-top-a.png b/activity/invite/assets/panel-top-a.png new file mode 100644 index 0000000..4d10a57 Binary files /dev/null and b/activity/invite/assets/panel-top-a.png differ diff --git a/activity/invite/assets/panel-top-b.png b/activity/invite/assets/panel-top-b.png new file mode 100644 index 0000000..4d10a57 Binary files /dev/null and b/activity/invite/assets/panel-top-b.png differ diff --git a/activity/invite/assets/plus.svg b/activity/invite/assets/plus.svg new file mode 100644 index 0000000..f14c70c --- /dev/null +++ b/activity/invite/assets/plus.svg @@ -0,0 +1,3 @@ + + + diff --git a/activity/invite/assets/rank-avatar-mask.svg b/activity/invite/assets/rank-avatar-mask.svg new file mode 100644 index 0000000..d352afe --- /dev/null +++ b/activity/invite/assets/rank-avatar-mask.svg @@ -0,0 +1,3 @@ + + + diff --git a/activity/invite/assets/rank-avatar.png b/activity/invite/assets/rank-avatar.png new file mode 100644 index 0000000..6d0410b Binary files /dev/null and b/activity/invite/assets/rank-avatar.png differ diff --git a/activity/invite/assets/rank-row.svg b/activity/invite/assets/rank-row.svg new file mode 100644 index 0000000..4e250ea --- /dev/null +++ b/activity/invite/assets/rank-row.svg @@ -0,0 +1,3 @@ + + + diff --git a/activity/invite/assets/reward-card.png b/activity/invite/assets/reward-card.png new file mode 100644 index 0000000..e9cc2ab Binary files /dev/null and b/activity/invite/assets/reward-card.png differ diff --git a/activity/invite/assets/reward-orb-bg.png b/activity/invite/assets/reward-orb-bg.png new file mode 100644 index 0000000..e9cc2ab Binary files /dev/null and b/activity/invite/assets/reward-orb-bg.png differ diff --git a/activity/invite/assets/reward-panel-bg.png b/activity/invite/assets/reward-panel-bg.png new file mode 100644 index 0000000..f828ecd Binary files /dev/null and b/activity/invite/assets/reward-panel-bg.png differ diff --git a/activity/invite/assets/tab-active-a.png b/activity/invite/assets/tab-active-a.png new file mode 100644 index 0000000..b8fb997 Binary files /dev/null and b/activity/invite/assets/tab-active-a.png differ diff --git a/activity/invite/assets/tab-active-b.png b/activity/invite/assets/tab-active-b.png new file mode 100644 index 0000000..b8fb997 Binary files /dev/null and b/activity/invite/assets/tab-active-b.png differ diff --git a/activity/invite/assets/tab-inactive-a.png b/activity/invite/assets/tab-inactive-a.png new file mode 100644 index 0000000..89481fc Binary files /dev/null and b/activity/invite/assets/tab-inactive-a.png differ diff --git a/activity/invite/assets/tab-inactive-b.png b/activity/invite/assets/tab-inactive-b.png new file mode 100644 index 0000000..89481fc Binary files /dev/null and b/activity/invite/assets/tab-inactive-b.png differ diff --git a/activity/invite/assets/task-row.png b/activity/invite/assets/task-row.png new file mode 100644 index 0000000..92d220d Binary files /dev/null and b/activity/invite/assets/task-row.png differ diff --git a/activity/invite/assets/task-row.svg b/activity/invite/assets/task-row.svg new file mode 100644 index 0000000..b9a5891 --- /dev/null +++ b/activity/invite/assets/task-row.svg @@ -0,0 +1,3 @@ + + + diff --git a/activity/invite/assets/timeline-node-active.png b/activity/invite/assets/timeline-node-active.png new file mode 100644 index 0000000..82a2638 Binary files /dev/null and b/activity/invite/assets/timeline-node-active.png differ diff --git a/activity/invite/assets/timeline-node.png b/activity/invite/assets/timeline-node.png new file mode 100644 index 0000000..f868c99 Binary files /dev/null and b/activity/invite/assets/timeline-node.png differ diff --git a/activity/invite/index.html b/activity/invite/index.html new file mode 100644 index 0000000..1483838 --- /dev/null +++ b/activity/invite/index.html @@ -0,0 +1,351 @@ + + + + + + Invite Friends + + + +
+
+ + +
+ +
+
+
+ 01 + Days +
+
+ 01 + Hours +
+
+ 01 + Minutes +
+
+ 01 + Seconds +
+
+
+ +
+

Your Reward

+

+ (Earn for every friend you invite) +

+
+
+ + + +2000 + + Invitation received + +
+ + +
+ + + +1000 + + Top up via friends + +
+
+
+ +
+

+ Start inviting people now +

+

+ (Copy your invitation link and share it with your friends) +

+
+ + +
+
+ + +
+
+ +
+
+ 168 + + Total number of invitees + +
+
+ 01 + + Number of eligible voters + +
+
+ 01 + + Total amount recharged by invitees + +
+
+ 12354 + My Rewards +
+
+ +
+

Monthly Tasks

+
+ + +
+ +
+
+
+

+ Milestone1:balabalabal +

+

+ Total supply: 49999 coins +

+
+
+

+ Milestone1:balabalabal +

+

+ Total supply: 49999 coins +

+
+
+

+ Milestone1:balabalabal +

+

+ Total supply: 49999 coins +

+
+
+

+ Milestone1:balabalabal +

+

+ Total supply: 49999 coins +

+
+
+

+ Milestone1:balabalabal +

+

+ Total supply: 49999 coins +

+
+
+ +

+ (Only the highest-level bonuses may be awarded) +

+
+ +
+
+
+
+

+ Milestone1:balabalabal +

+

+ Invite 10 friends who have already made a + payment +

+
+ +
+
+
+

+ Milestone1:balabalabal +

+

+ Invite 10 friends who have already made a + payment +

+
+ +
+
+
+

+ Milestone1:balabalabal +

+

+ Invite 10 friends who have already made a + payment +

+
+ +
+
+

+ (You'll receive a reward upon reaching each level) +

+
+
+ + +
+ + + + + + + diff --git a/activity/invite/script.js b/activity/invite/script.js new file mode 100644 index 0000000..500529a --- /dev/null +++ b/activity/invite/script.js @@ -0,0 +1,206 @@ +(function () { + var rankRows = Array.from({ length: 30 }, function (_, index) { + return { + rank: index + 1, + name: "hanneem", + score: "123", + }; + }); + + function $(selector) { + return document.querySelector(selector); + } + + function toast(message) { + if (window.HyToast && window.HyToast.show) { + window.HyToast.show(message); + return; + } + window.alert(message); + } + + function t(key, fallback) { + if (window.HyAppI18n && window.HyAppI18n.t) { + return window.HyAppI18n.t(key, fallback); + } + return fallback || key; + } + + function formatPeople(value) { + return t("invite.peopleSuffix", "{value} people").replace( + "{value}", + value + ); + } + + function pad(value) { + return String(Math.max(0, value)).padStart(2, "0"); + } + + function updateCountdown() { + var now = Date.now(); + var end = new Date(); + end.setDate(end.getDate() + 1); + end.setHours(0, 0, 0, 0); + var diff = Math.max(0, end.getTime() - now); + var totalSeconds = Math.floor(diff / 1000); + var days = Math.floor(totalSeconds / 86400); + var hours = Math.floor((totalSeconds % 86400) / 3600); + var minutes = Math.floor((totalSeconds % 3600) / 60); + var seconds = totalSeconds % 60; + $("#days").textContent = pad(days); + $("#hours").textContent = pad(hours); + $("#minutes").textContent = pad(minutes); + $("#seconds").textContent = pad(seconds); + } + + function renderRank() { + var list = $("#rankList"); + list.textContent = ""; + rankRows.forEach(function (item) { + var row = document.createElement("article"); + var rank = document.createElement("span"); + var medal = document.createElement("img"); + var avatar = document.createElement("img"); + var name = document.createElement("strong"); + var score = document.createElement("span"); + + row.className = "rank-row"; + rank.className = "rank-no"; + medal.className = "rank-medal"; + avatar.className = "rank-avatar"; + name.className = "rank-name"; + score.className = "rank-score"; + + if (item.rank <= 3) { + medal.src = "./assets/medal-" + item.rank + ".png"; + medal.alt = "Rank " + item.rank; + rank.textContent = ""; + } else { + medal.alt = ""; + rank.textContent = item.rank; + } + + avatar.src = "./assets/rank-avatar.png"; + avatar.alt = ""; + name.textContent = item.name; + score.textContent = formatPeople(item.score); + + row.appendChild(rank); + row.appendChild(item.rank <= 3 ? medal : document.createElement("span")); + row.appendChild(avatar); + row.appendChild(name); + row.appendChild(score); + list.appendChild(row); + }); + } + + function setTab(tabName) { + var monthly = $("#monthlyTask"); + var isQuota = tabName === "quota"; + monthly.classList.toggle("is-quota", isQuota); + + document.querySelectorAll(".task-tab").forEach(function (button) { + var active = button.getAttribute("data-tab") === tabName; + button.classList.toggle("is-active", active); + button.setAttribute("aria-selected", String(active)); + }); + + $("#transportPane").classList.toggle("is-active", !isQuota); + $("#quotaPane").classList.toggle("is-active", isQuota); + $("#rankPanel").hidden = !isQuota; + } + + function copyTextFrom(selector) { + var node = $(selector); + var text = node ? node.textContent.trim() : ""; + if (!text) { + toast(t("invite.copyFailed", "Copy failed")); + return; + } + function fallbackCopy() { + var input = document.createElement("textarea"); + input.value = text; + input.setAttribute("readonly", "readonly"); + input.style.position = "fixed"; + input.style.left = "-9999px"; + input.style.top = "0"; + document.body.appendChild(input); + input.select(); + var ok = false; + try { + ok = document.execCommand("copy"); + } catch (error) { + ok = false; + } + document.body.removeChild(input); + toast( + ok + ? t("invite.copied", "Copied") + : t("invite.copyFailed", "Copy failed") + ); + } + if (navigator.clipboard && navigator.clipboard.writeText) { + navigator.clipboard + .writeText(text) + .then(function () { + toast(t("invite.copied", "Copied")); + }) + .catch(function () { + fallbackCopy(); + }); + return; + } + fallbackCopy(); + } + + function copyInviteLink() { + copyTextFrom("#inviteLink"); + } + + function copyInviteCode() { + copyTextFrom("#inviteCode"); + } + + function bindEvents() { + document.querySelectorAll(".task-tab").forEach(function (button) { + button.addEventListener("click", function () { + setTab(button.getAttribute("data-tab") || "transport"); + }); + }); + $("#copyLinkButton").addEventListener("click", copyInviteLink); + $("#copyCodeButton").addEventListener("click", copyInviteCode); + document + .querySelectorAll(".copy-task-button") + .forEach(function (button) { + button.addEventListener("click", copyInviteLink); + }); + document.querySelectorAll(".claim-button").forEach(function (button) { + button.addEventListener("click", function () { + if (!button.classList.contains("is-ready")) { + toast(t("invite.notAvailable", "Not available yet")); + return; + } + toast(t("invite.claimed", "Claimed")); + button.classList.remove("is-ready"); + }); + }); + } + + function init() { + renderRank(); + updateCountdown(); + setInterval(updateCountdown, 1000); + bindEvents(); + } + + window.addEventListener("hyapp:i18n-ready", function () { + renderRank(); + }); + + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", init); + } else { + init(); + } +})(); diff --git a/activity/invite/style.css b/activity/invite/style.css new file mode 100644 index 0000000..000b17d --- /dev/null +++ b/activity/invite/style.css @@ -0,0 +1,657 @@ +:root { + --page-width: min(100vw, 430px); + --u: calc(var(--page-width) / 1080); + --blue: #071954; + --gold: #f6e0b2; + --white: #fff; +} + +* { + box-sizing: border-box; +} + +html, +body { + min-height: 100%; + margin: 0; + background: #030b24; + color: var(--white); + font-family: + "Source Han Sans SC", "Noto Sans", "Helvetica Neue", Arial, sans-serif; +} + +button { + border: 0; + padding: 0; + color: inherit; + font: inherit; + background: transparent; + -webkit-tap-highlight-color: transparent; +} + +.invite-page { + position: relative; + width: var(--page-width); + min-height: 100vh; + margin: 0 auto; + overflow: hidden; + background: var(--blue); +} + +.language-switcher { + position: absolute; + z-index: 20; + top: calc(34 * var(--u)); + right: calc(34 * var(--u)); + width: calc(190 * var(--u)); + direction: ltr; +} + +.language-button { + display: flex; + align-items: center; + justify-content: center; + width: calc(156 * var(--u)); + height: calc(82 * var(--u)); + margin-left: auto; + border: calc(2 * var(--u)) solid rgba(255, 232, 184, 0.62); + border-radius: 999px; + color: #ffe8b8; + font-size: calc(34 * var(--u)); + font-weight: 800; + line-height: 1; + letter-spacing: 0; + cursor: pointer; + background: rgba(25, 9, 1, 0.58); + box-shadow: + inset 0 0 calc(18 * var(--u)) rgba(255, 210, 93, 0.18), + 0 calc(8 * var(--u)) calc(18 * var(--u)) rgba(0, 0, 0, 0.28); +} + +.language-menu { + position: absolute; + top: calc(94 * var(--u)); + right: 0; + width: calc(190 * var(--u)); + overflow: hidden; + border: calc(2 * var(--u)) solid rgba(255, 232, 184, 0.56); + border-radius: calc(18 * var(--u)); + background: rgba(25, 9, 1, 0.92); + box-shadow: 0 calc(16 * var(--u)) calc(30 * var(--u)) + rgba(0, 0, 0, 0.34); +} + +.language-menu button { + display: block; + width: 100%; + height: calc(58 * var(--u)); + color: #fff5dc; + font-size: calc(28 * var(--u)); + font-weight: 700; + line-height: 1; + cursor: pointer; +} + +.language-menu button.is-active { + color: #ffd25d; + background: rgba(255, 210, 93, 0.22); +} + +.hero { + position: relative; + height: calc(1110 * var(--u)); + background-image: url("./assets/hero-bg.png"); + background-repeat: no-repeat; + background-position: top center; + background-size: 100% auto; +} + +.countdown-card { + position: absolute; + left: calc(32 * var(--u)); + bottom: calc(0 * var(--u)); + width: calc(1016 * var(--u)); + height: calc(290 * var(--u)); + background: url("./assets/countdown-panel.png") center / 100% 100% + no-repeat; +} + +.time-cell { + position: absolute; + top: 0; + left: calc(var(--countdown-center) * var(--u)); + width: calc(180 * var(--u)); + height: 100%; + transform: translateX(-50%); + color: var(--gold); + text-align: center; +} + +.time-cell:nth-child(1) { + --countdown-center: 172; +} + +.time-cell:nth-child(2) { + --countdown-center: 391; +} + +.time-cell:nth-child(3) { + --countdown-center: 614; +} + +.time-cell:nth-child(4) { + --countdown-center: 841; +} + +.time-cell strong { + position: absolute; + top: calc(107 * var(--u)); + left: 0; + display: flex; + width: 100%; + height: calc(46 * var(--u)); + align-items: center; + justify-content: center; + font-size: calc(56 * var(--u)); + line-height: 1; + font-weight: 700; +} + +.time-cell span { + position: absolute; + top: calc(216 * var(--u)); + left: 50%; + margin: 0; + transform: translateX(-50%); + font-size: calc(32 * var(--u)); + line-height: 1.1; + white-space: nowrap; +} + +.ornate-panel { + position: relative; + width: calc(1016 * var(--u)); + margin: 0 auto; + overflow: hidden; + background-image: + url("./assets/panel-top-a.png"), url("./assets/panel-bottom-a.png"), + url("./assets/panel-middle-a.png"); + background-repeat: no-repeat, no-repeat, no-repeat; + background-position: top center, bottom center, center center; + background-size: 100% auto, 100% auto, 100% 100%; +} + +.ornate-panel > * { + position: relative; + z-index: 1; +} + +h2, +h3, +p { + margin: 0; +} + +.ornate-panel h2, +.invite-copy h2, +.rank-panel h2 { + color: var(--gold); + text-align: center; + font-weight: 800; + text-shadow: 0 calc(2 * var(--u)) calc(4 * var(--u)) rgba(0, 0, 0, 0.35); +} + +.subtle { + color: rgba(255, 255, 255, 0.9); + text-align: center; +} + +.reward-panel { + height: calc(790 * var(--u)); + margin-top: calc(20 * var(--u)); + padding-top: calc(122 * var(--u)); + background-image: url("./assets/reward-panel-bg.png"); + background-position: center; + background-size: 100% 100%; +} + +.reward-panel h2 { + font-size: calc(60 * var(--u)); + line-height: 1; +} + +.reward-panel .subtle { + margin-top: calc(22 * var(--u)); + font-size: calc(30 * var(--u)); +} + +.reward-grid { + position: relative; + width: calc(1016 * var(--u)); + height: calc(486 * var(--u)); + margin: calc(28 * var(--u)) auto 0; +} + +.reward-item { + position: absolute; + top: 0; + width: calc(486 * var(--u)); + height: calc(486 * var(--u)); + color: var(--gold); + text-align: center; +} + +.reward-item:first-child { + left: calc(8 * var(--u)); +} + +.reward-item:last-child { + left: calc(522 * var(--u)); +} + +.reward-orb { + position: absolute; + z-index: 0; + display: block; + inset: 0; + width: calc(486 * var(--u)); + height: calc(486 * var(--u)); +} + +.reward-gold { + position: absolute; + z-index: 1; + top: 50%; + left: 50%; + width: calc(178 * var(--u)); + transform: translate(-50%, -50%); +} + +.reward-item strong { + position: absolute; + top: calc(98 * var(--u)); + left: calc(290 * var(--u)); + font-size: calc(40 * var(--u)); + line-height: 1; + white-space: nowrap; +} + +.reward-item span { + position: absolute; + top: calc(421 * var(--u)); + left: 50%; + display: block; + width: calc(360 * var(--u)); + transform: translateX(-50%); + color: var(--gold); + font-size: calc(30 * var(--u)); + line-height: 1.2; +} + +.plus { + position: absolute; + top: calc(207 * var(--u)); + left: calc(472 * var(--u)); + display: block; + width: calc(71 * var(--u)); + height: calc(71 * var(--u)); +} + +.invite-copy { + width: calc(1016 * var(--u)); + margin: calc(42 * var(--u)) auto 0; + text-align: center; +} + +.invite-copy h2 { + font-size: calc(46 * var(--u)); + line-height: 1; +} + +.invite-copy .subtle { + margin-top: calc(28 * var(--u)); + font-size: calc(30 * var(--u)); +} + +.invite-fields { + display: grid; + grid-template-columns: minmax(0, 1fr) calc(286 * var(--u)); + gap: calc(24 * var(--u)); + width: calc(760 * var(--u)); + margin: calc(58 * var(--u)) auto 0; +} + +.link-box { + display: flex; + align-items: center; + justify-content: center; + min-width: 0; + height: calc(85 * var(--u)); + padding: 0 calc(28 * var(--u)); + overflow: hidden; + color: var(--gold); + font-size: calc(30 * var(--u)); + text-overflow: ellipsis; + white-space: nowrap; + background: url("./assets/link-input.svg") center / 100% 100% no-repeat; +} + +.invite-code { + font-weight: 700; + letter-spacing: calc(1 * var(--u)); +} + +.invite-actions { + display: flex; + width: calc(764 * var(--u)); + align-items: center; + justify-content: center; + gap: calc(24 * var(--u)); + margin: calc(50 * var(--u)) auto 0; +} + +.ornate-button { + display: flex; + align-items: center; + justify-content: center; + width: calc(774 * var(--u)); + height: calc(133 * var(--u)); + margin: 0 auto; + color: var(--gold); + font-size: calc(50 * var(--u)); + font-weight: 800; + line-height: 1; + text-shadow: 0 calc(2 * var(--u)) calc(4 * var(--u)) rgba(0, 0, 0, 0.35); + background: url("./assets/button-active-wide.png") center / 100% 100% + no-repeat; +} + +.ornate-button:active { + transform: translateY(calc(2 * var(--u))); +} + +.invite-actions .ornate-button { + flex: 0 0 calc(520 * var(--u)); + width: calc(520 * var(--u)); + height: calc(100 * var(--u)); + font-size: calc(42 * var(--u)); +} + +.invite-actions .small-copy-button { + flex: 0 0 calc(220 * var(--u)); + width: calc(220 * var(--u)); + height: calc(78 * var(--u)); + font-size: calc(30 * var(--u)); + background-image: url("./assets/claim-active.png"); +} + +.stats-panel { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: calc(16 * var(--u)) calc(30 * var(--u)); + height: calc(440 * var(--u)); + margin-top: calc(62 * var(--u)); + padding: calc(86 * var(--u)) calc(86 * var(--u)) calc(62 * var(--u)); +} + +.stat { + display: flex; + min-width: 0; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; +} + +.stat strong { + color: var(--gold); + font-size: calc(56 * var(--u)); + line-height: 0.95; + font-weight: 700; +} + +.stat span { + width: 100%; + margin-top: calc(16 * var(--u)); + color: var(--gold); + font-size: calc(30 * var(--u)); + line-height: 0.95; +} + +.monthly-panel { + min-height: calc(1530 * var(--u)); + margin-top: calc(34 * var(--u)); + margin-bottom: calc(32 * var(--u)); + padding: calc(126 * var(--u)) calc(78 * var(--u)) calc(70 * var(--u)); +} + +.monthly-panel.is-quota { + min-height: calc(1375 * var(--u)); +} + +.monthly-panel h2, +.rank-panel h2 { + font-size: calc(60 * var(--u)); + line-height: 1; +} + +.task-tabs { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: calc(38 * var(--u)); + margin-top: calc(78 * var(--u)); +} + +.task-tab { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + min-height: calc(120 * var(--u)); + padding: 0 calc(36 * var(--u)); + color: var(--gold); + font-size: calc(30 * var(--u)); + font-weight: 400; + line-height: 1.15; + text-align: center; + text-shadow: 0 calc(2 * var(--u)) calc(2 * var(--u)) rgba(0, 0, 0, 0.25); + background: url("./assets/tab-inactive-a.png") center / 100% 100% + no-repeat; +} + +.task-tab span { + display: block; +} + +.task-tab.is-active { + background-image: url("./assets/tab-active-a.png"); +} + +.monthly-panel.is-quota .task-tab { + background-image: url("./assets/tab-inactive-b.png"); +} + +.monthly-panel.is-quota .task-tab.is-active { + background-image: url("./assets/tab-active-b.png"); +} + +.task-pane { + display: none; +} + +.task-pane.is-active { + display: block; +} + +.timeline { + position: relative; + margin-top: calc(76 * var(--u)); + padding-left: calc(114 * var(--u)); +} + +.timeline::before { + position: absolute; + top: calc(40 * var(--u)); + bottom: calc(92 * var(--u)); + left: calc(38 * var(--u)); + width: calc(4 * var(--u)); + content: ""; + background: var(--gold); +} + +.milestone { + position: relative; + display: flex; + min-height: calc(139 * var(--u)); + flex-direction: column; + justify-content: center; + margin-bottom: calc(30 * var(--u)); + padding: calc(18 * var(--u)) calc(34 * var(--u)); + background: url("./assets/milestone-row.svg") center / 100% 100% + no-repeat; +} + +.milestone::before { + position: absolute; + top: 50%; + left: calc(-92 * var(--u)); + width: calc(41 * var(--u)); + height: calc(41 * var(--u)); + content: ""; + transform: translateY(-50%); + background: url("./assets/timeline-node.png") center / contain no-repeat; +} + +.milestone.is-current::before { + background-image: url("./assets/timeline-node-active.png"); +} + +.milestone h3, +.quota-card h3 { + color: var(--white); + font-size: calc(36 * var(--u)); + font-weight: 700; + line-height: 1.05; +} + +.milestone p, +.quota-card p { + margin-top: calc(14 * var(--u)); + color: var(--gold); + font-size: calc(30 * var(--u)); + line-height: 1.2; +} + +.copy-task-button { + margin-top: calc(54 * var(--u)); +} + +.footnote { + margin-top: calc(34 * var(--u)); + font-size: calc(30 * var(--u)); + line-height: 1.25; +} + +.quota-list { + display: grid; + gap: calc(50 * var(--u)); + margin-top: calc(76 * var(--u)); +} + +.quota-card { + display: grid; + grid-template-columns: minmax(0, 1fr) calc(220 * var(--u)); + align-items: center; + min-height: calc(169 * var(--u)); + padding: calc(24 * var(--u)) calc(30 * var(--u)) calc(22 * var(--u)) + calc(36 * var(--u)); + background: url("./assets/task-row.svg") center / 100% 100% no-repeat; +} + +.claim-button { + display: flex; + align-items: center; + justify-content: center; + width: calc(220 * var(--u)); + height: calc(60 * var(--u)); + color: var(--gold); + font-size: calc(30 * var(--u)); + font-weight: 700; + background: url("./assets/claim-inactive.png") center / 100% 100% no-repeat; +} + +.claim-button.is-ready { + background-image: url("./assets/claim-active.png"); +} + +.rank-panel { + min-height: calc(5124 * var(--u)); + margin-top: calc(42 * var(--u)); + margin-bottom: calc(28 * var(--u)); + padding: calc(126 * var(--u)) calc(68 * var(--u)) calc(72 * var(--u)); + background-image: + url("./assets/panel-top-b.png"), url("./assets/panel-bottom-b.png"), + url("./assets/panel-middle-b.png"); +} + +.rank-list { + display: grid; + gap: calc(10 * var(--u)); + margin-top: calc(72 * var(--u)); +} + +.rank-row { + display: grid; + grid-template-columns: + calc(74 * var(--u)) calc(80 * var(--u)) calc(108 * var(--u)) + minmax(0, 1fr) auto; + align-items: center; + min-height: calc(149 * var(--u)); + padding: 0 calc(42 * var(--u)) 0 calc(28 * var(--u)); + background: url("./assets/rank-row.svg") center / 100% 100% no-repeat; +} + +.rank-no { + color: var(--white); + font-size: calc(36 * var(--u)); + line-height: 1; + text-align: center; +} + +.rank-medal { + width: calc(69 * var(--u)); + max-height: calc(68 * var(--u)); + object-fit: contain; + justify-self: center; +} + +.rank-avatar { + width: calc(108 * var(--u)); + height: calc(108 * var(--u)); + border: calc(2 * var(--u)) solid #ffebbb; + border-radius: 999px; + object-fit: cover; +} + +.rank-name { + padding-left: calc(24 * var(--u)); + overflow: hidden; + color: var(--white); + font-size: calc(36 * var(--u)); + font-weight: 700; + line-height: 1.1; + text-overflow: ellipsis; + white-space: nowrap; +} + +.rank-score { + color: var(--white); + font-size: calc(36 * var(--u)); + font-weight: 700; + line-height: 1; + white-space: nowrap; +} + +[hidden] { + display: none !important; +} diff --git a/activity/recharge-reward/assets/287_2480.png b/activity/recharge-reward/assets/287_2480.png new file mode 100644 index 0000000..d37c1a2 Binary files /dev/null and b/activity/recharge-reward/assets/287_2480.png differ diff --git a/activity/recharge-reward/assets/287_2483.png b/activity/recharge-reward/assets/287_2483.png new file mode 100644 index 0000000..64a18cb Binary files /dev/null and b/activity/recharge-reward/assets/287_2483.png differ diff --git a/activity/recharge-reward/assets/287_2877.png b/activity/recharge-reward/assets/287_2877.png new file mode 100644 index 0000000..015ac55 Binary files /dev/null and b/activity/recharge-reward/assets/287_2877.png differ diff --git a/activity/recharge-reward/assets/287_2887.png b/activity/recharge-reward/assets/287_2887.png new file mode 100644 index 0000000..dcc4e16 Binary files /dev/null and b/activity/recharge-reward/assets/287_2887.png differ diff --git a/activity/recharge-reward/assets/287_2888.png b/activity/recharge-reward/assets/287_2888.png new file mode 100644 index 0000000..6d86504 Binary files /dev/null and b/activity/recharge-reward/assets/287_2888.png differ diff --git a/activity/recharge-reward/assets/287_3031.png b/activity/recharge-reward/assets/287_3031.png new file mode 100644 index 0000000..b5337ac Binary files /dev/null and b/activity/recharge-reward/assets/287_3031.png differ diff --git a/activity/recharge-reward/assets/287_3032.png b/activity/recharge-reward/assets/287_3032.png new file mode 100644 index 0000000..62f8001 Binary files /dev/null and b/activity/recharge-reward/assets/287_3032.png differ diff --git a/activity/recharge-reward/assets/287_3036.png b/activity/recharge-reward/assets/287_3036.png new file mode 100644 index 0000000..db4fd0a Binary files /dev/null and b/activity/recharge-reward/assets/287_3036.png differ diff --git a/activity/recharge-reward/assets/287_3040.png b/activity/recharge-reward/assets/287_3040.png new file mode 100644 index 0000000..db4fd0a Binary files /dev/null and b/activity/recharge-reward/assets/287_3040.png differ diff --git a/activity/recharge-reward/assets/287_3044.png b/activity/recharge-reward/assets/287_3044.png new file mode 100644 index 0000000..db4fd0a Binary files /dev/null and b/activity/recharge-reward/assets/287_3044.png differ diff --git a/activity/recharge-reward/assets/287_3048.png b/activity/recharge-reward/assets/287_3048.png new file mode 100644 index 0000000..62f8001 Binary files /dev/null and b/activity/recharge-reward/assets/287_3048.png differ diff --git a/activity/recharge-reward/assets/287_3051.png b/activity/recharge-reward/assets/287_3051.png new file mode 100644 index 0000000..b2d59bd Binary files /dev/null and b/activity/recharge-reward/assets/287_3051.png differ diff --git a/activity/recharge-reward/assets/287_3054.png b/activity/recharge-reward/assets/287_3054.png new file mode 100644 index 0000000..b6072ef Binary files /dev/null and b/activity/recharge-reward/assets/287_3054.png differ diff --git a/activity/recharge-reward/assets/287_3058.png b/activity/recharge-reward/assets/287_3058.png new file mode 100644 index 0000000..07b6294 Binary files /dev/null and b/activity/recharge-reward/assets/287_3058.png differ diff --git a/activity/recharge-reward/assets/287_3061.png b/activity/recharge-reward/assets/287_3061.png new file mode 100644 index 0000000..d7daa9a Binary files /dev/null and b/activity/recharge-reward/assets/287_3061.png differ diff --git a/activity/recharge-reward/assets/bg-bottom.png b/activity/recharge-reward/assets/bg-bottom.png new file mode 100644 index 0000000..b2d59bd Binary files /dev/null and b/activity/recharge-reward/assets/bg-bottom.png differ diff --git a/activity/recharge-reward/assets/bg-mid.png b/activity/recharge-reward/assets/bg-mid.png new file mode 100644 index 0000000..64a18cb Binary files /dev/null and b/activity/recharge-reward/assets/bg-mid.png differ diff --git a/activity/recharge-reward/assets/bg-top.png b/activity/recharge-reward/assets/bg-top.png new file mode 100644 index 0000000..d37c1a2 Binary files /dev/null and b/activity/recharge-reward/assets/bg-top.png differ diff --git a/activity/recharge-reward/assets/countdown-frame.png b/activity/recharge-reward/assets/countdown-frame.png new file mode 100644 index 0000000..015ac55 Binary files /dev/null and b/activity/recharge-reward/assets/countdown-frame.png differ diff --git a/activity/recharge-reward/assets/profile-avatar.png b/activity/recharge-reward/assets/profile-avatar.png new file mode 100644 index 0000000..6d86504 Binary files /dev/null and b/activity/recharge-reward/assets/profile-avatar.png differ diff --git a/activity/recharge-reward/assets/profile-frame.png b/activity/recharge-reward/assets/profile-frame.png new file mode 100644 index 0000000..dcc4e16 Binary files /dev/null and b/activity/recharge-reward/assets/profile-frame.png differ diff --git a/activity/recharge-reward/assets/reward-card-frame-large.png b/activity/recharge-reward/assets/reward-card-frame-large.png new file mode 100644 index 0000000..b5337ac Binary files /dev/null and b/activity/recharge-reward/assets/reward-card-frame-large.png differ diff --git a/activity/recharge-reward/assets/reward-card-frame.png b/activity/recharge-reward/assets/reward-card-frame.png new file mode 100644 index 0000000..b6072ef Binary files /dev/null and b/activity/recharge-reward/assets/reward-card-frame.png differ diff --git a/activity/recharge-reward/assets/reward-panel-frame.png b/activity/recharge-reward/assets/reward-panel-frame.png new file mode 100644 index 0000000..d7daa9a Binary files /dev/null and b/activity/recharge-reward/assets/reward-panel-frame.png differ diff --git a/activity/recharge-reward/assets/reward-ring-amber.png b/activity/recharge-reward/assets/reward-ring-amber.png new file mode 100644 index 0000000..db4fd0a Binary files /dev/null and b/activity/recharge-reward/assets/reward-ring-amber.png differ diff --git a/activity/recharge-reward/assets/reward-ring-blue.png b/activity/recharge-reward/assets/reward-ring-blue.png new file mode 100644 index 0000000..62f8001 Binary files /dev/null and b/activity/recharge-reward/assets/reward-ring-blue.png differ diff --git a/activity/recharge-reward/assets/reward-ring-gold.png b/activity/recharge-reward/assets/reward-ring-gold.png new file mode 100644 index 0000000..db4fd0a Binary files /dev/null and b/activity/recharge-reward/assets/reward-ring-gold.png differ diff --git a/activity/recharge-reward/assets/reward-ring-purple.png b/activity/recharge-reward/assets/reward-ring-purple.png new file mode 100644 index 0000000..db4fd0a Binary files /dev/null and b/activity/recharge-reward/assets/reward-ring-purple.png differ diff --git a/activity/recharge-reward/assets/reward-ring-white.png b/activity/recharge-reward/assets/reward-ring-white.png new file mode 100644 index 0000000..62f8001 Binary files /dev/null and b/activity/recharge-reward/assets/reward-ring-white.png differ diff --git a/activity/recharge-reward/assets/section-title-frame.png b/activity/recharge-reward/assets/section-title-frame.png new file mode 100644 index 0000000..07b6294 Binary files /dev/null and b/activity/recharge-reward/assets/section-title-frame.png differ diff --git a/activity/recharge-reward/index.html b/activity/recharge-reward/index.html new file mode 100644 index 0000000..d2463a9 --- /dev/null +++ b/activity/recharge-reward/index.html @@ -0,0 +1,93 @@ + + + + + + Recharge Reward + + + +
+
+
+
+
+ + +
+ + + + + + +
+ + 01 + 01 + 01 + 01 + Days + Hours + Minutes + Seconds +
+ +
+ + +

nanfangjian

+

ID: 12345678

+

Accumulated Recharge:$59.98

+
+ +
+
+
+
+
+ + + + + + diff --git a/activity/recharge-reward/script.js b/activity/recharge-reward/script.js new file mode 100644 index 0000000..49c1485 --- /dev/null +++ b/activity/recharge-reward/script.js @@ -0,0 +1,368 @@ +(function () { + var viewport = document.getElementById('appViewport'); + var profileName = document.querySelector('.profile-name'); + var profileID = document.querySelector('.profile-id'); + var profileRecharge = document.querySelector('.profile-recharge'); + var profileAvatar = document.querySelector('.profile-avatar'); + var stage = document.querySelector('.stage'); + var stageWrap = document.getElementById('stageWrap'); + var rewardSectionRoot = document.getElementById('rewardSections'); + var bgBottom = document.querySelector('.bg-bottom'); + var countNodes = { + days: document.querySelector('[data-count="days"]'), + hours: document.querySelector('[data-count="hours"]'), + minutes: document.querySelector('[data-count="minutes"]'), + seconds: document.querySelector('[data-count="seconds"]'), + }; + + var DESIGN_WIDTH = 1080; + var designHeight = 3600; + var VIEWPORT_WIDTH = 375; + var STORAGE_KEY = 'hy_recharge_reward_end_at'; + var timeOffsetMS = 0; + var countdownEndAt = 0; + var countdownTimer = 0; + var fallbackIcons = [ + 'reward-ring-blue.png', + 'reward-ring-white.png', + 'reward-ring-gold.png', + 'reward-ring-purple.png', + 'reward-ring-amber.png', + ]; + var fallbackSections = [ + { + thresholdUsdMinor: 10000, + cards: [ + { label: '$100', icon: 'reward-ring-blue.png', name: 'Frame' }, + { label: '$100', icon: 'reward-ring-white.png', name: 'Avatar frame' }, + ], + }, + { + thresholdUsdMinor: 10000, + cards: [ + { label: '$100', icon: 'reward-ring-gold.png', name: 'Gold frame' }, + { label: '$100', icon: 'reward-ring-purple.png', name: 'Purple frame' }, + { label: '$100', icon: 'reward-ring-amber.png', name: 'Amber frame' }, + ], + }, + { + thresholdUsdMinor: 20000, + cards: [ + { label: '$200', icon: 'reward-ring-blue.png', name: 'Blue frame' }, + { label: '$200', icon: 'reward-ring-white.png', name: 'White frame' }, + { label: '$200', icon: 'reward-ring-purple.png', name: 'Purple frame' }, + { label: '$200', icon: 'reward-ring-amber.png', name: 'Amber frame' }, + ], + }, + ]; + + function getParams() { + return new URLSearchParams(window.location.search || ''); + } + + function t(key, fallback) { + return window.HyAppI18n && window.HyAppI18n.t + ? window.HyAppI18n.t(key, fallback) + : fallback || key; + } + + function isMock(params) { + var value = params.get('mock'); + return value === '1' || value === 'true' || !window.HyAppAPI; + } + + function twoDigits(value) { + return String(Math.max(0, value)).padStart(2, '0'); + } + + function formatUSDMinor(value) { + return ( + '$' + + (Number(value || 0) / 100).toLocaleString('en-US', { + maximumFractionDigits: 2, + minimumFractionDigits: Number(value || 0) % 100 === 0 ? 0 : 2, + }) + ); + } + + function parseAmountToMinor(value, fallbackMinor) { + var amount = Number(String(value || '').replace(/[^\d.]/g, '')); + if (!Number.isFinite(amount)) return fallbackMinor; + return Math.round(amount * 100); + } + + function serverNow() { + return Date.now() - timeOffsetMS; + } + + function resolveFallbackEndAt(params) { + var explicitEnd = Date.parse(params.get('end_at') || params.get('endAt') || ''); + if (Number.isFinite(explicitEnd) && explicitEnd > Date.now()) return explicitEnd; + + var cached = Number(window.localStorage.getItem(STORAGE_KEY)); + if (Number.isFinite(cached) && cached > Date.now()) return cached; + + var fallback = Date.now() + 25 * 60 * 60 * 1000 + 61 * 1000; + window.localStorage.setItem(STORAGE_KEY, String(fallback)); + return fallback; + } + + function updateCountdown() { + var diff = Math.max(0, countdownEndAt - serverNow()); + var totalSeconds = Math.floor(diff / 1000); + var days = Math.floor(totalSeconds / 86400); + var hours = Math.floor((totalSeconds % 86400) / 3600); + var minutes = Math.floor((totalSeconds % 3600) / 60); + var seconds = totalSeconds % 60; + + countNodes.days.textContent = twoDigits(days); + countNodes.hours.textContent = twoDigits(hours); + countNodes.minutes.textContent = twoDigits(minutes); + countNodes.seconds.textContent = twoDigits(seconds); + } + + function applyProfile(data) { + var user = data.user || {}; + var displayUserID = user.display_user_id || user.displayUserId || user.user_id || user.userId || '12345678'; + var name = user.username || user.name || 'nanfangjian'; + var avatar = user.avatar || ''; + var recharge = data.progress ? data.progress.total_usd_minor || data.progress.totalUsdMinor : data.totalUsdMinor; + + profileName.textContent = name; + profileID.textContent = t('rechargeReward.idPrefix', 'ID:') + ' ' + displayUserID; + profileRecharge.textContent = + t('rechargeReward.accumulatedRecharge', 'Accumulated Recharge:') + formatUSDMinor(recharge || 0); + if (avatar) profileAvatar.src = avatar; + } + + function updateBodyHeight() { + var scale = Math.min(window.innerWidth / VIEWPORT_WIDTH, 1); + document.documentElement.style.setProperty('--app-scale', String(scale)); + stageWrap.style.height = Math.ceil(designHeight * (VIEWPORT_WIDTH / DESIGN_WIDTH)) + 'px'; + document.body.style.minHeight = viewport.offsetHeight * scale + 'px'; + } + + function cardLayout(count, index) { + var compact = count >= 4; + var small = count === 3; + var layouts = compact + ? [ + { left: 105, top: 178 }, + { left: 337, top: 178 }, + { left: 569, top: 178 }, + { left: 801, top: 178 }, + ] + : small + ? [ + { left: 142, top: 189 }, + { left: 423, top: 189 }, + { left: 704, top: 189 }, + ] + : [ + { left: 152, top: 189 }, + { left: 601, top: 189 }, + ]; + return layouts[index] || layouts[layouts.length - 1]; + } + + function sectionMetrics(index, count) { + var firstTop = 1693; + if (index === 0) { + return { + top: firstTop, + panelTop: 83, + panelClass: 'reward-panel-large', + cardClass: count >= 4 ? 'reward-card-compact' : 'reward-card-large', + }; + } + return { + top: firstTop + 623 + (index - 1) * 512, + panelTop: 10, + panelClass: 'reward-panel-small', + cardClass: count >= 4 ? 'reward-card-compact' : 'reward-card-small', + }; + } + + function normalizeCard(item, tier, index) { + var resource = item && item.resource ? item.resource : {}; + var icon = resource.preview_url || resource.previewUrl || resource.asset_url || resource.assetUrl || ''; + return { + label: formatUSDMinor(tier.thresholdUsdMinor || tier.threshold_usd_minor || 0), + icon: icon || fallbackIcons[index % fallbackIcons.length], + name: resource.name || item.item_type || item.itemType || tier.tierName || tier.tier_name || 'Reward', + granted: Boolean(tier.grant && tier.grant.status === 'granted'), + remoteIcon: Boolean(icon), + }; + } + + function normalizeTier(tier, index) { + var resourceGroup = tier.resource_group || tier.resourceGroup || {}; + var items = Array.isArray(resourceGroup.items) ? resourceGroup.items : []; + var fallback = fallbackSections[index % fallbackSections.length]; + var normalized = { + thresholdUsdMinor: + Number(tier.threshold_usd_minor || tier.thresholdUsdMinor || fallback.thresholdUsdMinor || 0) || 0, + tierName: tier.tier_name || tier.tierName || '', + grant: tier.grant || null, + cards: [], + }; + normalized.cards = items.length + ? items.slice(0, 4).map(function (item, cardIndex) { + return normalizeCard(item, normalized, cardIndex); + }) + : fallback.cards.map(function (card) { + return { + label: formatUSDMinor(normalized.thresholdUsdMinor || fallback.thresholdUsdMinor), + icon: card.icon, + name: card.name, + granted: Boolean(normalized.grant && normalized.grant.status === 'granted'), + }; + }); + return normalized; + } + + function renderRewardCard(card, cardClass, count, index) { + var frame = cardClass === 'reward-card-large' ? 'reward-card-frame-large.png' : 'reward-card-frame.png'; + var pos = cardLayout(count, index); + var iconSrc = card.remoteIcon ? card.icon : './assets/' + card.icon; + return [ + '
', + '', + '', + '', + escapeHTML(card.label), + '', + '
', + ].join(''); + } + + function renderRewardSections(tiers) { + var sections = (tiers && tiers.length ? tiers : fallbackSections).map(normalizeTier); + rewardSectionRoot.innerHTML = sections + .map(function (section, index) { + var count = Math.max(1, section.cards.length); + var metrics = sectionMetrics(index, count); + return [ + '
', + '
', + '', + '', + escapeHTML( + t('rechargeReward.rechargeTitle', 'Recharge {amount}').replace( + '{amount}', + formatUSDMinor(section.thresholdUsdMinor) + ) + ), + '', + '
', + '
', + '', + '
', + section.cards + .map(function (card, cardIndex) { + return renderRewardCard(card, metrics.cardClass, count, cardIndex); + }) + .join(''), + '
', + ].join(''); + }) + .join(''); + + var lastMetrics = sectionMetrics(sections.length - 1, sections[sections.length - 1].cards.length); + designHeight = Math.max(3600, lastMetrics.top + 660); + stage.style.height = designHeight + 'px'; + if (bgBottom) bgBottom.style.top = Math.max(3022, designHeight - 578) + 'px'; + updateBodyHeight(); + } + + function mockData(params) { + var total = parseAmountToMinor(params.get('recharge'), 599800); + var endAt = resolveFallbackEndAt(params); + return Promise.resolve({ + user: { + username: params.get('name') || 'nanfangjian', + display_user_id: params.get('uid') || params.get('id') || '12345678', + avatar: params.get('avatar') || './assets/profile-avatar.png', + }, + progress: { total_usd_minor: total }, + period: { end_ms: endAt }, + tiers: fallbackSections.map(function (section, index) { + return { + threshold_usd_minor: section.thresholdUsdMinor, + tier_name: 'Tier ' + (index + 1), + grant: total >= section.thresholdUsdMinor ? { status: 'granted' } : null, + resource_group: { items: [] }, + }; + }), + server_time_ms: Date.now(), + }); + } + + function fetchStatus(params) { + if (isMock(params)) return mockData(params); + return window.HyAppAPI.get('/api/v1/activities/cumulative-recharge-reward').catch(function (error) { + console.warn('cumulative recharge reward status failed', error); + return mockData(params); + }); + } + + function applyData(data, params) { + data = data || {}; + timeOffsetMS = Date.now() - Number(data.server_time_ms || data.serverTimeMs || Date.now()); + countdownEndAt = + Number((data.period && (data.period.end_ms || data.period.endMs)) || data.period_end_ms || 0) || + resolveFallbackEndAt(params); + applyProfile(data); + renderRewardSections(data.tiers || []); + updateCountdown(); + if (countdownTimer) window.clearInterval(countdownTimer); + countdownTimer = window.setInterval(updateCountdown, 1000); + } + + function escapeHTML(value) { + return String(value || '') + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + } + + function init() { + var params = getParams(); + document.title = t('rechargeReward.pageTitle', 'Recharge Reward'); + fetchStatus(params).then(function (data) { + applyData(data, params); + }); + window.addEventListener('resize', updateBodyHeight); + window.addEventListener('hyapp:i18n-ready', function () { + document.title = t('rechargeReward.pageTitle', 'Recharge Reward'); + fetchStatus(params).then(function (data) { + applyData(data, params); + }); + }); + } + + init(); +})(); diff --git a/activity/recharge-reward/style.css b/activity/recharge-reward/style.css new file mode 100644 index 0000000..847aa9f --- /dev/null +++ b/activity/recharge-reward/style.css @@ -0,0 +1,484 @@ +* { + box-sizing: border-box; + -webkit-tap-highlight-color: transparent; +} + +:root { + --app-scale: 1; + --design-scale: 0.3472222222; +} + +html, +body { + margin: 0; + width: 100%; + min-height: 100%; + overflow-x: hidden; + background: #1b100d; + color: #f6e0b2; + font-family: + Arial, + "Helvetica Neue", + Helvetica, + sans-serif; +} + +button { + border: 0; + padding: 0; + background: transparent; + color: inherit; + font: inherit; + cursor: pointer; + outline: none; +} + +.app-viewport { + position: relative; + width: 375px; + min-height: 1250px; + margin: 0 auto; + transform: scale(var(--app-scale)); + transform-origin: top center; +} + +.page { + position: relative; + width: 375px; + min-height: 1250px; + overflow: hidden; + background: #1b100d; +} + +.stage-wrap { + position: relative; + width: 375px; + height: 1250px; + overflow: hidden; +} + +.stage { + position: absolute; + left: 0; + top: 0; + width: 1080px; + height: 3600px; + overflow: hidden; + transform: scale(var(--design-scale)); + transform-origin: top left; + background: #1b100d; +} + +.stage > * { + position: absolute; + z-index: 1; +} + +.language-switcher { + position: absolute; + z-index: 10; + top: 44px; + right: 38px; + width: 190px; + direction: ltr; +} + +.language-button { + display: flex; + align-items: center; + justify-content: center; + width: 156px; + height: 82px; + margin-left: auto; + border: 2px solid rgba(255, 232, 184, 0.62); + border-radius: 999px; + background: rgba(25, 9, 1, 0.58); + box-shadow: + inset 0 0 18px rgba(255, 210, 93, 0.18), + 0 8px 18px rgba(0, 0, 0, 0.28); + color: #ffe8b8; + font-size: 34px; + font-weight: 800; + line-height: 34px; + letter-spacing: 0; +} + +.language-menu { + position: absolute; + top: 94px; + right: 0; + width: 190px; + overflow: hidden; + border: 2px solid rgba(255, 232, 184, 0.56); + border-radius: 18px; + background: rgba(25, 9, 1, 0.92); + box-shadow: 0 16px 30px rgba(0, 0, 0, 0.34); +} + +.language-menu button { + display: block; + width: 100%; + height: 58px; + color: #fff5dc; + font-size: 28px; + font-weight: 700; + line-height: 28px; +} + +.language-menu button.is-active { + background: rgba(255, 210, 93, 0.22); + color: #ffd25d; +} + +.bg { + left: 0; + width: 1080px; + object-fit: fill; + pointer-events: none; + z-index: 0; +} + +.bg-top { + top: 0; + height: 1588px; +} + +.bg-mid { + height: 649px; +} + +.bg-mid-a { + top: 1476px; +} + +.bg-mid-b { + top: 2050px; +} + +.bg-mid-c { + top: 2600px; +} + +.bg-bottom { + top: 3022px; + height: 578px; +} + +.countdown { + left: 24px; + top: 696px; + width: 1032px; + height: 344px; +} + +.countdown-frame { + position: absolute; + inset: 0; + width: 1032px; + height: 344px; + object-fit: fill; + pointer-events: none; +} + +.count-number { + position: absolute; + top: 148px; + width: 96px; + height: 74px; + color: #ffce95; + font-size: 60px; + font-weight: 800; + line-height: 74px; + text-align: center; + text-shadow: + 0 2px 0 #47200d, + 0 0 14px rgba(255, 210, 135, 0.58); +} + +.count-number[data-count="days"] { + left: 165px; +} + +.count-number[data-count="hours"] { + left: 365px; +} + +.count-number[data-count="minutes"] { + left: 570px; +} + +.count-number[data-count="seconds"] { + left: 770px; +} + +.count-label { + position: absolute; + top: 239px; + width: 150px; + height: 30px; + color: #100800; + font-size: 22px; + font-weight: 800; + line-height: 30px; + text-align: center; + white-space: nowrap; + transform: translateX(-50%); +} + +.count-label:nth-of-type(1) { + left: 213px; +} + +.count-label:nth-of-type(2) { + left: 413px; +} + +.count-label:nth-of-type(3) { + left: 618px; +} + +.count-label:nth-of-type(4) { + left: 818px; +} + +.profile-card { + left: 43px; + top: 1040px; + width: 996px; + height: 659px; +} + +.profile-frame { + position: absolute; + inset: 0; + width: 996px; + height: 659px; + object-fit: fill; + pointer-events: none; +} + +.profile-avatar { + position: absolute; + left: 381px; + top: 147px; + width: 232px; + height: 232px; + border-radius: 50%; + object-fit: cover; + pointer-events: none; +} + +.profile-name, +.profile-id, +.profile-recharge { + position: absolute; + left: 120px; + width: 756px; + margin: 0; + color: #f6e0b2; + text-align: center; + text-shadow: 0 3px 8px rgba(0, 0, 0, 0.72); +} + +.profile-name { + top: 416px; + font-size: 38px; + font-weight: 800; + line-height: 48px; +} + +.profile-id { + top: 472px; + font-size: 26px; + font-weight: 700; + line-height: 34px; +} + +.profile-recharge { + top: 514px; + font-size: 36px; + font-weight: 800; + line-height: 46px; +} + +.reward-sections { + left: 0; + top: 0; + width: 1080px; + height: 3600px; +} + +.reward-section { + position: absolute; + left: 0; + top: var(--section-top); + width: 1080px; +} + +.title-pill { + position: absolute; + left: 234px; + top: 0; + width: 612px; + height: 204px; + z-index: 4; +} + +.title-pill img { + position: absolute; + inset: 0; + width: 612px; + height: 204px; + object-fit: fill; + pointer-events: none; +} + +.title-pill span { + position: absolute; + left: 0; + top: 78px; + width: 612px; + color: #f6e0b2; + font-size: 40px; + font-weight: 900; + line-height: 48px; + text-align: center; + text-shadow: + 0 2px 0 #4f2306, + 0 0 14px rgba(255, 207, 113, 0.45); +} + +.reward-panel { + position: absolute; + left: 82px; + top: var(--panel-top); + width: 915px; + overflow: hidden; + z-index: 1; +} + +.reward-panel-large { + height: 497px; +} + +.reward-panel-small { + height: 469px; +} + +.reward-panel-frame { + position: absolute; + inset: 0; + width: 915px; + height: 497px; + object-fit: fill; + pointer-events: none; +} + +.reward-panel-small .reward-panel-frame { + height: 497px; +} + +.reward-card { + position: absolute; + color: #f6e0b2; + text-align: center; + z-index: 3; +} + +.reward-card.is-granted .reward-frame { + filter: drop-shadow(0 0 18px rgba(255, 239, 173, 0.72)); +} + +.reward-frame { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + object-fit: fill; + pointer-events: none; +} + +.reward-icon { + position: absolute; + object-fit: contain; + pointer-events: none; +} + +.reward-price { + position: absolute; + left: 0; + width: 100%; + display: flex; + align-items: center; + justify-content: center; + color: #f6e0b2; + font-weight: 900; + text-align: center; + text-shadow: + 0 2px 0 #3a1704, + 0 0 10px rgba(255, 207, 113, 0.44); +} + +.reward-card-large { + width: 327px; + height: 327px; +} + +.reward-card-large .reward-icon { + left: 67px; + top: 53px; + width: 193px; + height: 193px; +} + +.reward-card-large .reward-price { + top: 246px; + height: 52px; + font-size: 30px; + line-height: 36px; +} + +.reward-card-small { + width: 234px; + height: 234px; +} + +.reward-card-small .reward-icon { + left: 48px; + top: 38px; + width: 138px; + height: 138px; +} + +.reward-card-small .reward-price { + top: 175px; + height: 40px; + font-size: 22px; + line-height: 28px; +} + +.reward-card-compact { + width: 210px; + height: 210px; +} + +.reward-card-compact .reward-icon { + left: 43px; + top: 34px; + width: 124px; + height: 124px; +} + +.reward-card-compact .reward-price { + top: 157px; + height: 36px; + font-size: 20px; + line-height: 26px; +} + +@media (min-width: 431px) { + html, + body { + background: #100806; + } +} diff --git a/activity/room-reward/assets/294_8091.png b/activity/room-reward/assets/294_8091.png new file mode 100644 index 0000000..7280c0a Binary files /dev/null and b/activity/room-reward/assets/294_8091.png differ diff --git a/activity/room-reward/assets/296_8264.png b/activity/room-reward/assets/296_8264.png new file mode 100644 index 0000000..ba9bb75 Binary files /dev/null and b/activity/room-reward/assets/296_8264.png differ diff --git a/activity/room-reward/assets/296_8265.png b/activity/room-reward/assets/296_8265.png new file mode 100644 index 0000000..053f197 Binary files /dev/null and b/activity/room-reward/assets/296_8265.png differ diff --git a/activity/room-reward/assets/296_8271.png b/activity/room-reward/assets/296_8271.png new file mode 100644 index 0000000..b3e3bad Binary files /dev/null and b/activity/room-reward/assets/296_8271.png differ diff --git a/activity/room-reward/assets/296_8274.png b/activity/room-reward/assets/296_8274.png new file mode 100644 index 0000000..deac864 Binary files /dev/null and b/activity/room-reward/assets/296_8274.png differ diff --git a/activity/room-reward/assets/296_8275.png b/activity/room-reward/assets/296_8275.png new file mode 100644 index 0000000..938aa9d Binary files /dev/null and b/activity/room-reward/assets/296_8275.png differ diff --git a/activity/room-reward/assets/296_8301.png b/activity/room-reward/assets/296_8301.png new file mode 100644 index 0000000..86ba10a Binary files /dev/null and b/activity/room-reward/assets/296_8301.png differ diff --git a/activity/room-reward/assets/296_8326.png b/activity/room-reward/assets/296_8326.png new file mode 100644 index 0000000..31ca009 Binary files /dev/null and b/activity/room-reward/assets/296_8326.png differ diff --git a/activity/room-reward/assets/296_8350.png b/activity/room-reward/assets/296_8350.png new file mode 100644 index 0000000..78d4056 Binary files /dev/null and b/activity/room-reward/assets/296_8350.png differ diff --git a/activity/room-reward/assets/296_8357.png b/activity/room-reward/assets/296_8357.png new file mode 100644 index 0000000..d27457d Binary files /dev/null and b/activity/room-reward/assets/296_8357.png differ diff --git a/activity/room-reward/assets/296_8362.png b/activity/room-reward/assets/296_8362.png new file mode 100644 index 0000000..5cc48ef Binary files /dev/null and b/activity/room-reward/assets/296_8362.png differ diff --git a/activity/room-reward/assets/296_8368.png b/activity/room-reward/assets/296_8368.png new file mode 100644 index 0000000..d27457d Binary files /dev/null and b/activity/room-reward/assets/296_8368.png differ diff --git a/activity/room-reward/assets/296_8373.png b/activity/room-reward/assets/296_8373.png new file mode 100644 index 0000000..8111a34 Binary files /dev/null and b/activity/room-reward/assets/296_8373.png differ diff --git a/activity/room-reward/assets/296_8380.png b/activity/room-reward/assets/296_8380.png new file mode 100644 index 0000000..8f2ec34 Binary files /dev/null and b/activity/room-reward/assets/296_8380.png differ diff --git a/activity/room-reward/assets/296_8385.png b/activity/room-reward/assets/296_8385.png new file mode 100644 index 0000000..28cd28a Binary files /dev/null and b/activity/room-reward/assets/296_8385.png differ diff --git a/activity/room-reward/assets/296_8391.png b/activity/room-reward/assets/296_8391.png new file mode 100644 index 0000000..ee42666 Binary files /dev/null and b/activity/room-reward/assets/296_8391.png differ diff --git a/activity/room-reward/assets/296_8397.png b/activity/room-reward/assets/296_8397.png new file mode 100644 index 0000000..b5bff90 Binary files /dev/null and b/activity/room-reward/assets/296_8397.png differ diff --git a/activity/room-reward/assets/296_8404.png b/activity/room-reward/assets/296_8404.png new file mode 100644 index 0000000..8f2ec34 Binary files /dev/null and b/activity/room-reward/assets/296_8404.png differ diff --git a/activity/room-reward/assets/296_8409.png b/activity/room-reward/assets/296_8409.png new file mode 100644 index 0000000..28cd28a Binary files /dev/null and b/activity/room-reward/assets/296_8409.png differ diff --git a/activity/room-reward/assets/296_8415.png b/activity/room-reward/assets/296_8415.png new file mode 100644 index 0000000..ee42666 Binary files /dev/null and b/activity/room-reward/assets/296_8415.png differ diff --git a/activity/room-reward/assets/296_8421.png b/activity/room-reward/assets/296_8421.png new file mode 100644 index 0000000..aad1014 Binary files /dev/null and b/activity/room-reward/assets/296_8421.png differ diff --git a/activity/room-reward/assets/296_8422.png b/activity/room-reward/assets/296_8422.png new file mode 100644 index 0000000..deac864 Binary files /dev/null and b/activity/room-reward/assets/296_8422.png differ diff --git a/activity/room-reward/assets/296_8424.png b/activity/room-reward/assets/296_8424.png new file mode 100644 index 0000000..9b4a0b8 Binary files /dev/null and b/activity/room-reward/assets/296_8424.png differ diff --git a/activity/room-reward/assets/296_8429.png b/activity/room-reward/assets/296_8429.png new file mode 100644 index 0000000..913514b Binary files /dev/null and b/activity/room-reward/assets/296_8429.png differ diff --git a/activity/room-reward/assets/296_8434.png b/activity/room-reward/assets/296_8434.png new file mode 100644 index 0000000..9b4a0b8 Binary files /dev/null and b/activity/room-reward/assets/296_8434.png differ diff --git a/activity/room-reward/assets/296_8435.png b/activity/room-reward/assets/296_8435.png new file mode 100644 index 0000000..9b4a0b8 Binary files /dev/null and b/activity/room-reward/assets/296_8435.png differ diff --git a/activity/room-reward/assets/296_8436.png b/activity/room-reward/assets/296_8436.png new file mode 100644 index 0000000..913514b Binary files /dev/null and b/activity/room-reward/assets/296_8436.png differ diff --git a/activity/room-reward/assets/296_8437.png b/activity/room-reward/assets/296_8437.png new file mode 100644 index 0000000..913514b Binary files /dev/null and b/activity/room-reward/assets/296_8437.png differ diff --git a/activity/room-reward/index.html b/activity/room-reward/index.html new file mode 100644 index 0000000..772fcb1 --- /dev/null +++ b/activity/room-reward/index.html @@ -0,0 +1,174 @@ + + + + + + Room Reward Event + + + + +
+
+
+
+
+ + +
+ + +
+ +
+ + 1000 +
+
+ +
+ + + + + +
+
+ +
+ +
Namename...
+
ID: 123456789
+
+ This week's contribution: +
+
+ This week's rewards: +
+ + +
+
+
+
+
+ + + + + + + diff --git a/activity/room-reward/script.js b/activity/room-reward/script.js new file mode 100644 index 0000000..d827d25 --- /dev/null +++ b/activity/room-reward/script.js @@ -0,0 +1,257 @@ +(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, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + } + + 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 = [ + '
', + '
', + t('roomReward.turnover', 'Room turnover'), + '
', + '
', + t('roomReward.receiveReward', 'Receive a reward'), + '
', + '
', + ]; + + (data.tiers || []).forEach(function (item) { + rows.push( + [ + '
', + '
', + escapeHTML(item.turnover), + '
', + '
', + '', + escapeHTML(item.reward), + '', + '', + '
', + '
', + ].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(); + } +})(); diff --git a/activity/room-reward/style.css b/activity/room-reward/style.css new file mode 100644 index 0000000..b2239a7 --- /dev/null +++ b/activity/room-reward/style.css @@ -0,0 +1,422 @@ +* { + box-sizing: border-box; + -webkit-tap-highlight-color: transparent; +} + +:root { + --app-scale: 1; + --design-scale: 0.3472222222; +} + +html, +body { + margin: 0; + width: 100%; + min-height: 100%; + overflow-x: hidden; + background: #291000; + color: #fff; + font-family: + Arial, + "Helvetica Neue", + Helvetica, + sans-serif; +} + +button { + border: 0; + padding: 0; + background: transparent; + color: inherit; + font: inherit; + outline: none; +} + +[hidden] { + display: none !important; +} + +.app-viewport { + position: relative; + width: 375px; + min-height: 772px; + margin: 0 auto; + transform: scale(var(--app-scale)); + transform-origin: top center; +} + +.page { + position: relative; + width: 375px; + min-height: 772px; + overflow: hidden; + background: #291000; +} + +.stage-wrap { + position: relative; + width: 375px; + height: 772px; + overflow: hidden; +} + +.stage { + position: absolute; + left: 0; + top: 0; + width: 1080px; + height: 2221px; + overflow: hidden; + transform: scale(var(--design-scale)); + transform-origin: top left; + background: #291000; +} + +.language-switcher { + position: absolute; + z-index: 10; + top: 44px; + right: 38px; + width: 190px; + direction: ltr; +} + +.language-button { + display: flex; + align-items: center; + justify-content: center; + width: 156px; + height: 82px; + margin-left: auto; + border: 2px solid rgba(255, 232, 184, 0.62); + border-radius: 999px; + background: rgba(25, 9, 1, 0.58); + box-shadow: + inset 0 0 18px rgba(255, 210, 93, 0.18), + 0 8px 18px rgba(0, 0, 0, 0.28); + color: #ffe8b8; + font-size: 34px; + font-weight: 800; + line-height: 34px; + letter-spacing: 0; + cursor: pointer; +} + +.language-menu { + position: absolute; + top: 94px; + right: 0; + width: 190px; + overflow: hidden; + border: 2px solid rgba(255, 232, 184, 0.56); + border-radius: 18px; + background: rgba(25, 9, 1, 0.92); + box-shadow: 0 16px 30px rgba(0, 0, 0, 0.34); +} + +.language-menu button { + display: block; + width: 100%; + height: 58px; + color: #fff5dc; + font-size: 28px; + font-weight: 700; + line-height: 28px; + cursor: pointer; +} + +.language-menu button.is-active { + background: rgba(255, 210, 93, 0.22); + color: #ffd25d; +} + +.hero-bg { + position: absolute; + left: 0; + top: 0; + width: 1080px; + height: 1919px; + object-fit: cover; + pointer-events: none; +} + +.target-card { + position: absolute; + left: 47px; + top: 892px; + width: 985px; + height: 319px; +} + +.target-card-img { + position: absolute; + inset: 0; + width: 985px; + height: 319px; + object-fit: fill; + pointer-events: none; +} + +.target-value { + position: absolute; + left: 395px; + top: 111px; + display: flex; + align-items: center; + justify-content: center; + width: 238px; + height: 96px; + gap: 14px; + color: #fff1d6; +} + +.coin-icon { + width: 44px; + height: 44px; + object-fit: contain; +} + +.target-value strong { + font-size: 80px; + font-weight: 500; + line-height: 80px; + letter-spacing: 0; + color: #ffe6ba; +} + +.reward-table { + position: absolute; + left: 36px; + top: 1241px; + width: 1008px; + height: 811px; +} + +.table-fill { + position: absolute; + left: 20px; + top: 15px; + width: 968px; + height: 824px; + overflow: hidden; +} + +.table-row-bg { + width: 968px; + height: 103px; +} + +.row-dark { + background: #190901; +} + +.row-light { + background: #290e00; +} + +.table-border { + position: absolute; + pointer-events: none; + object-fit: fill; +} + +.table-border-side { + left: 0; + top: 0; + width: 1008px; + height: 811px; +} + +.table-border-top { + left: 0; + top: 0; + width: 1008px; + height: 119px; +} + +.table-border-bottom { + left: 0; + top: 736px; + width: 1008px; + height: 119px; +} + +.table-divider { + position: absolute; + left: 503px; + top: 15px; + width: 2px; + height: 827px; + background: rgba(255, 255, 255, 0.92); + pointer-events: none; +} + +.table-content { + position: absolute; + left: 20px; + top: 15px; + width: 968px; + height: 824px; +} + +.tier-row { + display: grid; + grid-template-columns: 1fr 1fr; + width: 968px; + height: 103px; + color: #fff; + font-size: 30px; + font-weight: 500; + line-height: 30px; + letter-spacing: 0; +} + +.tier-row > div { + display: flex; + align-items: center; + justify-content: center; + min-width: 0; +} + +.tier-row.is-head { + height: 103px; +} + +.tier-row.is-head > div { + padding-top: 4px; +} + +.tier-reward { + gap: 8px; +} + +.tier-reward .mini-coin { + width: 38px; + height: 38px; + object-fit: contain; +} + +.user-panel { + position: absolute; + left: 0; + top: 2052px; + width: 1080px; + height: 169px; + background: #190901; +} + +.user-avatar { + position: absolute; + left: 46px; + top: 25px; + width: 119px; + height: 119px; + object-fit: cover; + border-radius: 50%; +} + +.user-name { + position: absolute; + left: 189px; + top: 36px; + width: 280px; + overflow: hidden; + color: #fff; + font-size: 40px; + font-weight: 500; + line-height: 42px; + letter-spacing: 0; + white-space: nowrap; + text-overflow: ellipsis; +} + +.user-id { + position: absolute; + left: 189px; + top: 102px; + width: 292px; + overflow: hidden; + color: rgba(255, 255, 255, 0.7); + font-size: 30px; + font-weight: 400; + line-height: 36px; + letter-spacing: 0; + white-space: nowrap; + text-overflow: ellipsis; +} + +.metric-label { + position: absolute; + overflow: hidden; + color: #fff; + font-size: 28px; + font-weight: 400; + line-height: 32px; + letter-spacing: 0; + white-space: nowrap; + text-overflow: ellipsis; +} + +.contribution-label { + left: 494px; + top: 43px; + width: 328px; +} + +.rewards-label { + left: 552px; + top: 111px; + width: 270px; +} + +.reward-button { + position: absolute; + width: 213px; + height: 69px; + cursor: pointer; +} + +.reward-button img { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + object-fit: fill; + pointer-events: none; +} + +.reward-button span { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + color: #fff; + font-size: 24px; + font-weight: 500; + line-height: 24px; + letter-spacing: 0; + text-align: center; +} + +#contributionButton { + left: 838px; + top: 19px; +} + +#rewardsButton { + left: 837px; + top: 87px; +} + +.reward-button.is-disabled { + cursor: default; +} + +html[dir="rtl"] .metric-label, +html[dir="rtl"] .user-name, +html[dir="rtl"] .user-id { + direction: rtl; +} diff --git a/activity/weekly-star/assets/avatar-top.png b/activity/weekly-star/assets/avatar-top.png new file mode 100644 index 0000000..a2f0811 Binary files /dev/null and b/activity/weekly-star/assets/avatar-top.png differ diff --git a/activity/weekly-star/assets/avatar-user.png b/activity/weekly-star/assets/avatar-user.png new file mode 100644 index 0000000..6d0410b Binary files /dev/null and b/activity/weekly-star/assets/avatar-user.png differ diff --git a/activity/weekly-star/assets/bg-stars.png b/activity/weekly-star/assets/bg-stars.png new file mode 100644 index 0000000..ef2ea14 Binary files /dev/null and b/activity/weekly-star/assets/bg-stars.png differ diff --git a/activity/weekly-star/assets/gift-ball.png b/activity/weekly-star/assets/gift-ball.png new file mode 100644 index 0000000..4760863 Binary files /dev/null and b/activity/weekly-star/assets/gift-ball.png differ diff --git a/activity/weekly-star/assets/gift-card.png b/activity/weekly-star/assets/gift-card.png new file mode 100644 index 0000000..71a8683 Binary files /dev/null and b/activity/weekly-star/assets/gift-card.png differ diff --git a/activity/weekly-star/assets/gift-glow.png b/activity/weekly-star/assets/gift-glow.png new file mode 100644 index 0000000..68399e8 Binary files /dev/null and b/activity/weekly-star/assets/gift-glow.png differ diff --git a/activity/weekly-star/assets/hero-bg.png b/activity/weekly-star/assets/hero-bg.png new file mode 100644 index 0000000..930f3dd Binary files /dev/null and b/activity/weekly-star/assets/hero-bg.png differ diff --git a/activity/weekly-star/assets/medal-1.png b/activity/weekly-star/assets/medal-1.png new file mode 100644 index 0000000..df7b345 Binary files /dev/null and b/activity/weekly-star/assets/medal-1.png differ diff --git a/activity/weekly-star/assets/medal-2.png b/activity/weekly-star/assets/medal-2.png new file mode 100644 index 0000000..67ad74d Binary files /dev/null and b/activity/weekly-star/assets/medal-2.png differ diff --git a/activity/weekly-star/assets/medal-3.png b/activity/weekly-star/assets/medal-3.png new file mode 100644 index 0000000..5ee50f6 Binary files /dev/null and b/activity/weekly-star/assets/medal-3.png differ diff --git a/activity/weekly-star/assets/reward-bg.png b/activity/weekly-star/assets/reward-bg.png new file mode 100644 index 0000000..1602091 Binary files /dev/null and b/activity/weekly-star/assets/reward-bg.png differ diff --git a/activity/weekly-star/assets/reward-frame-bg.png b/activity/weekly-star/assets/reward-frame-bg.png new file mode 100644 index 0000000..d1ea9c0 Binary files /dev/null and b/activity/weekly-star/assets/reward-frame-bg.png differ diff --git a/activity/weekly-star/assets/reward-tab-active.png b/activity/weekly-star/assets/reward-tab-active.png new file mode 100644 index 0000000..7ec610b Binary files /dev/null and b/activity/weekly-star/assets/reward-tab-active.png differ diff --git a/activity/weekly-star/assets/reward-tab-inactive.png b/activity/weekly-star/assets/reward-tab-inactive.png new file mode 100644 index 0000000..9f66463 Binary files /dev/null and b/activity/weekly-star/assets/reward-tab-inactive.png differ diff --git a/activity/weekly-star/assets/reward-title-bar.png b/activity/weekly-star/assets/reward-title-bar.png new file mode 100644 index 0000000..a2378d0 Binary files /dev/null and b/activity/weekly-star/assets/reward-title-bar.png differ diff --git a/activity/weekly-star/assets/reward-title-fill.png b/activity/weekly-star/assets/reward-title-fill.png new file mode 100644 index 0000000..c41b64d Binary files /dev/null and b/activity/weekly-star/assets/reward-title-fill.png differ diff --git a/activity/weekly-star/assets/tab-active.png b/activity/weekly-star/assets/tab-active.png new file mode 100644 index 0000000..7ec610b Binary files /dev/null and b/activity/weekly-star/assets/tab-active.png differ diff --git a/activity/weekly-star/assets/tab-inactive.png b/activity/weekly-star/assets/tab-inactive.png new file mode 100644 index 0000000..9f66463 Binary files /dev/null and b/activity/weekly-star/assets/tab-inactive.png differ diff --git a/activity/weekly-star/assets/time-text-fill.png b/activity/weekly-star/assets/time-text-fill.png new file mode 100644 index 0000000..fedb3e9 Binary files /dev/null and b/activity/weekly-star/assets/time-text-fill.png differ diff --git a/activity/weekly-star/assets/title-bar.png b/activity/weekly-star/assets/title-bar.png new file mode 100644 index 0000000..0b3345f Binary files /dev/null and b/activity/weekly-star/assets/title-bar.png differ diff --git a/activity/weekly-star/index.html b/activity/weekly-star/index.html new file mode 100644 index 0000000..8ce8cc1 --- /dev/null +++ b/activity/weekly-star/index.html @@ -0,0 +1,116 @@ + + + + + + Weekly Star + + + +
+
+
+
+ + + +
+ +
+ 2025-12-28 00:00-2026-1-3 23:59(utc+3) +
+
+ +

+ Note: Send the following three gifts to participate in the
+ ranking. Users who rank in the top 3 of the leaderboard
+ will receive rewards. +

+ +
+
+ + + Gift +
+
+ + + Gift +
+
+ + + Gift +
+
+ + + +
+

2025/12/07-2025/12/14

+
+
+ + + + +
+
+
+
+ + + + + diff --git a/activity/weekly-star/script.js b/activity/weekly-star/script.js new file mode 100644 index 0000000..344717a --- /dev/null +++ b/activity/weekly-star/script.js @@ -0,0 +1,362 @@ +(function () { + var page = document.getElementById('page'); + var viewport = document.getElementById('appViewport'); + var tabs = Array.prototype.slice.call(document.querySelectorAll('[data-tab-target]')); + var panels = Array.prototype.slice.call(document.querySelectorAll('[data-panel]')); + var stageWrap = document.getElementById('stageWrap'); + var dateText = document.querySelector('.date-text'); + var note = document.querySelector('.note'); + var historyDate = document.querySelector('.history-date'); + + var mockRanks = [ + { rank: 1, name: 'hanneem', score: '337700', avatar: './assets/avatar-top.png' }, + { rank: 2, name: 'hanneem', score: '337700', avatar: './assets/avatar-user.png' }, + { rank: 3, name: 'hanneem', score: '337700', avatar: './assets/avatar-user.png' }, + { rank: 4, name: 'hanneem', score: '337700', avatar: './assets/avatar-user.png' }, + { rank: 5, name: 'hanneem', score: '337700', avatar: './assets/avatar-user.png' }, + ]; + var mockRewards = [ + { rank_no: 1, resource_group_id: 1001, top: 1488 }, + { rank_no: 2, resource_group_id: 1002, top: 1985 }, + { rank_no: 3, resource_group_id: 1003, top: 2482 }, + ]; + var state = { + current: null, + weeklyEntries: [], + historyCycles: [], + error: '', + loading: true, + }; + + function rankMedal(rank) { + if (rank === 1) return './assets/medal-1.png'; + if (rank === 2) return './assets/medal-2.png'; + if (rank === 3) return './assets/medal-3.png'; + return ''; + } + + function renderRankList(targetID, top, items, emptyText) { + var list = document.getElementById(targetID); + var rows = (items || []).slice(0, 8); + if (!rows.length) { + list.innerHTML = + '
' + escapeHTML(emptyText || 'No ranking data yet.') + '
'; + return; + } + list.innerHTML = rows + .map(function (item, index) { + var medal = rankMedal(item.rank); + return [ + '
', + medal + ? 'No. ' + item.rank + '' + : '' + item.rank + '', + '', + '
', + escapeHTML(item.name || '-'), + '
', + '
', + escapeHTML(formatNumber(item.score)), + '
', + '
', + ].join(''); + }) + .join(''); + } + + function rewardItem(item) { + var img = item.image || './assets/gift-ball.png'; + var label = item.label || 'Resource Group #' + (item.resource_group_id || '-'); + return [ + '
', + '
', + '', + '', + 'Reward', + '
', + '
', + escapeHTML(label), + '
', + '
', + ].join(''); + } + + function renderRewards(rewards) { + var root = document.getElementById('rewardGroups'); + var groups = normalizeRewards(rewards); + root.innerHTML = groups + .map(function (group) { + return [ + '
', + '

', + '', + 'TOP', + group.rank_no, + '', + '

', + group.items.map(rewardItem).join(''), + '
', + ].join(''); + }) + .join(''); + } + + function normalizeRewards(rewards) { + var tops = [1488, 1985, 2482]; + var input = rewards && rewards.length ? rewards : []; + return [1, 2, 3].map(function (rankNo, index) { + var reward = + input.find(function (item) { + return Number(item.rank_no || item.rankNo) === rankNo; + }) || {}; + var items = reward.items || reward.resources || []; + if (!items.length) { + items = [ + { + label: reward.name || 'Resource Group #' + (reward.resource_group_id || reward.resourceGroupId || '-'), + resource_group_id: reward.resource_group_id || reward.resourceGroupId, + image: reward.image_url || reward.imageUrl || reward.icon_url || reward.iconUrl, + single: true, + }, + ]; + } + return { rank_no: rankNo, top: tops[index], items: items.slice(0, 3) }; + }); + } + + function renderGiftStrip(gifts) { + var cards = Array.prototype.slice.call(document.querySelectorAll('.gift-strip .gift-card')); + cards.forEach(function (card, index) { + var gift = (gifts || [])[index] || {}; + var img = gift.image_url || gift.imageUrl || gift.icon_url || gift.iconUrl || gift.asset_url || gift.assetUrl; + var label = gift.name || gift.display_name || gift.displayName || gift.gift_id || gift.giftId || ''; + var image = card.querySelector('.gift-img'); + if (image && img) image.src = img; + var labelNode = card.querySelector('.gift-name'); + if (!labelNode) { + labelNode = document.createElement('span'); + labelNode.className = 'gift-name'; + card.appendChild(labelNode); + } + labelNode.textContent = label; + }); + } + + function renderActivity() { + var cycle = state.current && state.current.cycle; + var historyCycle = state.historyCycles[0] || {}; + var historyEntries = normalizeEntries(historyCycle.top_entries || historyCycle.topEntries || []); + var weeklyEntries = normalizeEntries(state.weeklyEntries); + + if (cycle) { + dateText.textContent = formatRangeUTC(cycle.start_ms || cycle.startMs, cycle.end_ms || cycle.endMs); + note.innerHTML = + 'Note: Send the following three gifts to participate in the
ranking. Users who rank in the top 3 of the leaderboard
will receive rewards.'; + renderGiftStrip(cycle.gifts || []); + renderRewards(cycle.rewards || []); + } else { + dateText.textContent = 'No active cycle'; + note.textContent = state.error || 'No Weekly Star activity is configured for your region.'; + renderGiftStrip([]); + renderRewards([]); + } + + if (historyCycle.cycle) { + historyDate.textContent = formatDateRange(historyCycle.cycle.start_ms || historyCycle.cycle.startMs, historyCycle.cycle.end_ms || historyCycle.cycle.endMs); + } else { + historyDate.textContent = 'Previous Top 3 Records'; + } + + renderRankList('historyList', 1607, historyEntries, 'No previous ranking records.'); + renderRankList('weeklyList', 1496, weeklyEntries, state.loading ? 'Loading...' : 'No ranking data yet.'); + } + + function normalizeEntries(entries) { + return (entries || []).map(function (entry, index) { + var user = entry.user || {}; + return { + rank: Number(entry.rank_no || entry.rankNo || index + 1), + name: user.username || user.display_user_id || user.displayUserId || entry.user_id || entry.userId || '-', + score: entry.score || 0, + avatar: user.avatar || (Number(entry.rank_no || entry.rankNo) === 1 ? './assets/avatar-top.png' : './assets/avatar-user.png'), + }; + }); + } + + function setTab(tabName) { + var next = tabName || 'history'; + page.setAttribute('data-tab', next); + tabs.forEach(function (tab) { + var active = tab.getAttribute('data-tab-target') === next; + tab.classList.toggle('is-active', active); + tab.setAttribute('aria-selected', active ? 'true' : 'false'); + }); + panels.forEach(function (panel) { + panel.hidden = panel.getAttribute('data-panel') !== next; + }); + stageWrap.style.height = next === 'rewards' ? '1090px' : '802px'; + updateBodyHeight(); + } + + function normalizeTab(value) { + if (value === 'weekly' || value === 'rewards' || value === 'history') return value; + return 'history'; + } + + 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 loadMock() { + state.loading = false; + state.current = { + cycle: { + start_ms: Date.UTC(2025, 11, 28, 0, 0, 0), + end_ms: Date.UTC(2026, 0, 3, 23, 59, 0), + gifts: [{ gift_id: 'gift_1' }, { gift_id: 'gift_2' }, { gift_id: 'gift_3' }], + rewards: mockRewards, + }, + }; + state.weeklyEntries = mockRanks.map(function (item) { + return { + rank_no: item.rank, + score: item.score, + user: { username: item.name, avatar: item.avatar }, + }; + }); + state.historyCycles = [ + { + cycle: { + start_ms: Date.UTC(2025, 11, 7, 0, 0, 0), + end_ms: Date.UTC(2025, 11, 14, 23, 59, 0), + }, + top_entries: state.weeklyEntries.slice(0, 3), + }, + ]; + renderActivity(); + } + + function loadReal() { + if (!window.HyAppAPI || !window.HyAppAPI.weeklyStar) { + state.loading = false; + state.error = 'API module is not available.'; + renderActivity(); + return; + } + renderRankList('weeklyList', 1496, [], 'Loading...'); + window.HyAppAPI.weeklyStar + .current() + .then(function (current) { + state.current = current || {}; + var cycle = state.current.cycle || {}; + var cycleID = cycle.cycle_id || cycle.cycleId || ''; + return Promise.all([ + cycleID + ? window.HyAppAPI.weeklyStar.leaderboard({ cycle_id: cycleID, page_size: 20 }) + : Promise.resolve({ entries: [] }), + window.HyAppAPI.weeklyStar.history(10), + ]); + }) + .then(function (results) { + state.weeklyEntries = results[0].entries || []; + state.historyCycles = results[1].cycles || []; + state.error = ''; + }) + .catch(function (error) { + state.error = error.message || 'Unable to load Weekly Star.'; + state.weeklyEntries = []; + state.historyCycles = []; + }) + .finally(function () { + state.loading = false; + renderActivity(); + }); + } + + function isMockMode() { + return new URLSearchParams(window.location.search).get('mock') === '1'; + } + + function formatRangeUTC(start, end) { + return formatDateTimeUTC(start) + '-' + formatDateTimeUTC(end) + '(UTC)'; + } + + function formatDateRange(start, end) { + return formatDateUTC(start).replace(/-/g, '/') + '-' + formatDateUTC(end).replace(/-/g, '/'); + } + + function formatDateTimeUTC(value) { + var date = new Date(Number(value || 0)); + if (!Number(value || 0)) return '-'; + return ( + date.getUTCFullYear() + + '-' + + (date.getUTCMonth() + 1) + + '-' + + date.getUTCDate() + + ' ' + + pad(date.getUTCHours()) + + ':' + + pad(date.getUTCMinutes()) + ); + } + + function formatDateUTC(value) { + var date = new Date(Number(value || 0)); + if (!Number(value || 0)) return '-'; + return date.getUTCFullYear() + '-' + pad(date.getUTCMonth() + 1) + '-' + pad(date.getUTCDate()); + } + + function formatNumber(value) { + return new Intl.NumberFormat('en-US').format(Number(value || 0)); + } + + function pad(value) { + return String(value).padStart(2, '0'); + } + + function escapeHTML(value) { + return String(value == null ? '' : value) + .replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + } + + function escapeAttr(value) { + return escapeHTML(value); + } + + function init() { + tabs.forEach(function (tab) { + tab.addEventListener('click', function () { + var next = tab.getAttribute('data-tab-target'); + setTab(next); + if (window.history && window.history.replaceState) { + window.history.replaceState(null, '', '#' + next); + } + }); + }); + + window.addEventListener('resize', updateBodyHeight); + setTab(normalizeTab(window.location.hash.replace('#', ''))); + if (isMockMode()) { + loadMock(); + } else { + loadReal(); + } + } + + init(); +})(); diff --git a/activity/weekly-star/style.css b/activity/weekly-star/style.css new file mode 100644 index 0000000..ee08e7e --- /dev/null +++ b/activity/weekly-star/style.css @@ -0,0 +1,454 @@ +* { + box-sizing: border-box; + -webkit-tap-highlight-color: transparent; +} + +:root { + --app-scale: 1; + --design-scale: 0.3472222222; +} + +html, +body { + margin: 0; + width: 100%; + min-height: 100%; + overflow-x: hidden; + background: #050a36; + color: #f8e8ff; + font-family: + "Source Han Sans SC", + "Noto Sans CJK SC", + Arial, + "Helvetica Neue", + Helvetica, + sans-serif; +} + +button { + border: 0; + padding: 0; + background: transparent; + color: inherit; + font: inherit; + cursor: pointer; + outline: none; +} + +.app-viewport { + position: relative; + width: 375px; + min-height: 800px; + margin: 0 auto; + transform: scale(var(--app-scale)); + transform-origin: top center; +} + +.page { + position: relative; + width: 375px; + min-height: 800px; + overflow: hidden; + background: #050a36; +} + +.stage-wrap { + position: relative; + width: 375px; + height: 802px; + overflow: hidden; +} + +.page[data-tab="rewards"] .stage-wrap { + height: 1090px; +} + +.stage { + position: absolute; + left: 0; + top: 0; + width: 1080px; + height: 3138px; + overflow: hidden; + transform: scale(var(--design-scale)); + transform-origin: top left; + background: #050a36; +} + +.bg-stars, +.hero-bg { + position: absolute; + pointer-events: none; + object-fit: cover; +} + +.bg-stars { + left: -110px; + top: 0; + width: 1300px; + height: 2309px; + opacity: 0.06; +} + +.hero-bg { + left: 0; + top: -24px; + width: 1080px; + height: 1919px; +} + +.date-plate { + position: absolute; + left: 204px; + top: 726px; + width: 672px; + height: 95px; +} + +.date-plate-img { + position: absolute; + inset: 0; + width: 672px; + height: 95px; + object-fit: fill; +} + +.date-text { + position: absolute; + left: -6px; + top: 20px; + width: 684px; + color: #fff; + font-size: 30px; + font-weight: 600; + line-height: 42px; + text-align: center; + text-shadow: + 0 2px 2px rgba(31, 0, 72, 0.8), + 0 0 10px rgba(255, 120, 255, 0.55); + white-space: nowrap; +} + +.note { + position: absolute; + left: 64px; + top: 861px; + width: 1016px; + margin: 0; + color: #f8e8ff; + font-size: 34px; + font-weight: 500; + line-height: 42px; + text-shadow: 0 2px 6px rgba(0, 0, 0, 0.36); +} + +.gift-card { + position: absolute; + left: var(--x); + top: 1027px; + width: 257px; + height: 270px; +} + +.gift-frame { + position: absolute; + inset: 0; + width: 257px; + height: 270px; + object-fit: fill; +} + +.gift-glow { + position: absolute; + left: 19px; + top: 30px; + width: 219px; + height: 219px; + object-fit: contain; + opacity: 0.34; +} + +.gift-img { + position: absolute; + left: 35px; + top: 41px; + width: 188px; + height: 188px; + object-fit: contain; +} + +.gift-name { + position: absolute; + left: 18px; + top: 226px; + width: 221px; + overflow: hidden; + color: #fff; + font-size: 28px; + font-weight: 600; + line-height: 32px; + text-align: center; + white-space: nowrap; + text-overflow: ellipsis; + text-shadow: 0 2px 6px rgba(0, 0, 0, 0.55); +} + +.tabs { + position: absolute; + left: 21px; + top: 1317px; + display: grid; + grid-template-columns: repeat(3, 335px); + column-gap: 18px; + width: 1041px; + height: 155px; +} + +.tab { + position: relative; + width: 335px; + height: 155px; + color: rgba(255, 255, 255, 0.6); + font-size: 32px; + font-weight: 600; + line-height: 34px; + text-align: center; +} + +.tab-img { + position: absolute; + inset: 0; + width: 335px; + height: 155px; + object-fit: fill; + pointer-events: none; +} + +.tab .active-img { + display: none; +} + +.tab.is-active { + color: #f8e8ff; +} + +.tab.is-active .active-img { + display: block; +} + +.tab.is-active .inactive-img { + display: none; +} + +.tab span { + position: absolute; + left: 32px; + top: 56px; + display: flex; + align-items: center; + justify-content: center; + width: 270px; + height: 77px; + text-shadow: 0 2px 5px rgba(0, 0, 0, 0.42); +} + +.tab-panel { + position: absolute; + left: 0; + top: 0; + width: 1080px; +} + +.history-date { + position: absolute; + left: 0; + top: 1514px; + width: 1080px; + margin: 0; + color: #ff77ef; + font-size: 46px; + font-weight: 500; + line-height: 46px; + text-align: center; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.4); +} + +.rank-row { + position: absolute; + left: 0; + width: 1080px; + height: 140px; + color: #fff; +} + +.rank-row.is-odd { + background: rgba(103, 0, 203, 0.2); +} + +.rank-row.is-even { + background: #0a0d41; +} + +.rank-medal { + position: absolute; + left: 45px; + top: 39px; + width: 69px; + height: 61px; + object-fit: contain; +} + +.rank-number { + position: absolute; + left: 69px; + top: 49px; + width: 40px; + color: #fff; + font-size: 36px; + font-weight: 500; + line-height: 42px; + text-align: left; +} + +.rank-avatar { + position: absolute; + left: 160px; + top: 13px; + width: 113px; + height: 113px; + border-radius: 57px; + object-fit: cover; +} + +.rank-name, +.rank-score { + position: absolute; + top: 49px; + overflow: hidden; + color: #fff; + font-size: 36px; + font-weight: 500; + line-height: 42px; + white-space: nowrap; + text-overflow: ellipsis; +} + +.rank-name { + left: 313px; + width: 420px; +} + +.rank-score { + left: 846px; + width: 190px; + text-align: left; +} + +.rank-empty { + position: absolute; + left: 70px; + width: 940px; + color: rgba(255, 255, 255, 0.78); + font-size: 34px; + font-weight: 500; + line-height: 48px; + text-align: center; + text-shadow: 0 2px 6px rgba(0, 0, 0, 0.5); +} + +.reward-frame-bg { + position: absolute; + left: 0; + top: 1489px; + width: 1080px; + height: 1601px; + object-fit: fill; + pointer-events: none; +} + +.reward-group { + position: absolute; + left: 0; + width: 1080px; + height: 470px; +} + +.reward-title { + position: absolute; + left: 189px; + top: 0; + width: 702px; + height: 98px; +} + +.reward-title img { + position: absolute; + inset: 0; + width: 702px; + height: 98px; + object-fit: fill; +} + +.reward-title span { + position: absolute; + left: 0; + top: 40px; + width: 702px; + color: #fff; + font-size: 40px; + font-weight: 500; + line-height: 40px; + text-align: center; + text-shadow: + 0 2px 4px rgba(0, 0, 0, 0.45), + 0 0 9px rgba(255, 93, 255, 0.55); +} + +.reward-item { + position: absolute; + top: 128px; + width: 257px; + height: 316px; +} + +.reward-item:nth-child(2) { + left: 90px; +} + +.reward-item:nth-child(3) { + left: 412px; +} + +.reward-item:nth-child(4) { + left: 733px; +} + +.reward-item.is-single { + left: 412px; +} + +.reward-item .gift-card { + left: 0; + top: 0; +} + +.reward-label { + position: absolute; + left: -18px; + top: 290px; + width: 293px; + color: #fff; + font-size: 28px; + font-weight: 500; + line-height: 36px; + text-align: center; + white-space: nowrap; + text-shadow: 0 2px 6px rgba(0, 0, 0, 0.45); +} + +@media (max-width: 374px) { + .app-viewport { + margin-left: 0; + margin-right: 0; + } +} diff --git a/common/api.js b/common/api.js index 12804f1..3097a1b 100644 --- a/common/api.js +++ b/common/api.js @@ -458,6 +458,26 @@ var default_api = 'https://api.global-interaction.com/'; }, }; + var weeklyStarAPI = { + current: function () { + return request('/api/v1/activities/weekly-star/current', { + method: 'GET', + }); + }, + leaderboard: function (params) { + return request('/api/v1/activities/weekly-star/leaderboard', { + method: 'GET', + query: params || {}, + }); + }, + history: function (limit) { + return request('/api/v1/activities/weekly-star/history', { + method: 'GET', + query: { limit: limit || 10 }, + }); + }, + }; + window.HyAppAPI = { baseURL: resolveBaseURL, buildURL: buildURL, @@ -492,6 +512,7 @@ var default_api = 'https://api.global-interaction.com/'; bdLeaderCenter: bdLeaderCenterAPI, superadminCenter: superadminCenterAPI, level: levelAPI, + weeklyStar: weeklyStarAPI, }; clearLocalDevCache(); })(); diff --git a/common/i18n.js b/common/i18n.js index 0e3f9c8..8387de4 100644 --- a/common/i18n.js +++ b/common/i18n.js @@ -10,6 +10,24 @@ var messages = {}; var currentLang = ''; + function storageGet(key) { + try { + return window.localStorage ? window.localStorage.getItem(key) : ''; + } catch (error) { + return ''; + } + } + + function storageSet(key, value) { + try { + if (window.localStorage) { + window.localStorage.setItem(key, value); + } + } catch (error) { + // Some in-app browser contexts disable localStorage. Language still works for the current page session. + } + } + function queryLang() { return new URLSearchParams(window.location.search).get('lang') || ''; } @@ -31,7 +49,7 @@ function resolveLang() { return ( normalizeLang(queryLang()) || - normalizeLang(window.localStorage.getItem(STORAGE_KEY)) || + normalizeLang(storageGet(STORAGE_KEY)) || normalizeLang(window.navigator.language) || DEFAULT_LANG ); @@ -50,7 +68,7 @@ .then(function (json) { messages = json || {}; currentLang = normalized; - window.localStorage.setItem(STORAGE_KEY, currentLang); + storageSet(STORAGE_KEY, currentLang); apply(); return messages; }) diff --git a/common/locales/ar.json b/common/locales/ar.json index a42600b..cdf894a 100644 --- a/common/locales/ar.json +++ b/common/locales/ar.json @@ -1,4 +1,64 @@ { + "roomReward.pageTitle": "فعالية مكافآت الغرفة", + "roomReward.pageLabel": "فعالية مكافآت الغرفة", + "roomReward.currentTarget": "هدف المكافأة الحالي", + "roomReward.tiersLabel": "مستويات مكافآت الغرفة", + "roomReward.progressLabel": "تقدم مكافآت غرفتي", + "roomReward.turnover": "دوران الغرفة", + "roomReward.receiveReward": "استلام مكافأة", + "roomReward.contribution": "مساهمة هذا الأسبوع:", + "roomReward.rewards": "مكافآت هذا الأسبوع:", + "roomReward.contributionReward": "مكافأة المساهمة", + "roomReward.weeklyRewards": "المكافآت الأسبوعية", + "roomReward.idPrefix": "المعرّف:", + "roomReward.roomOwner": "مالك الغرفة", + "roomReward.changeLanguage": "تغيير اللغة", + "rechargeReward.pageTitle": "مكافأة الشحن التراكمي", + "rechargeReward.pageLabel": "فعالية مكافأة الشحن التراكمي", + "rechargeReward.changeLanguage": "تغيير اللغة", + "rechargeReward.days": "أيام", + "rechargeReward.hours": "ساعات", + "rechargeReward.minutes": "دقائق", + "rechargeReward.seconds": "ثوانٍ", + "rechargeReward.idPrefix": "المعرّف:", + "rechargeReward.accumulatedRecharge": "إجمالي الشحن:", + "rechargeReward.rechargeTitle": "اشحن {amount}", + "invite.pageAria": "دعوة الأصدقاء", + "invite.heroAria": "ادع الأصدقاء واكسب المال", + "invite.countdownAria": "العد التنازلي", + "invite.changeLanguage": "تغيير اللغة", + "invite.days": "أيام", + "invite.hours": "ساعات", + "invite.minutes": "دقائق", + "invite.seconds": "ثوان", + "invite.yourReward": "مكافأتك", + "invite.rewardSubtitle": "(اكسب مقابل كل صديق تدعوه)", + "invite.invitationReceived": "تم استلام الدعوة", + "invite.topUpViaFriends": "الشحن عبر الأصدقاء", + "invite.startInviting": "ابدأ دعوة الأشخاص الآن", + "invite.copyInviteHint": "(انسخ رابط الدعوة وشاركه مع أصدقائك)", + "invite.copy": "نسخ", + "invite.totalInvitees": "إجمالي عدد المدعوين", + "invite.eligibleVoters": "عدد المؤهلين", + "invite.totalRecharged": "إجمالي شحن المدعوين", + "invite.myRewards": "مكافآتي", + "invite.monthlyTasks": "المهام الشهرية", + "invite.totalTransportation": "إجمالي النقل", + "invite.volume": "الحجم", + "invite.invitationQuota": "حصة الدعوة", + "invite.task": "المهمة", + "invite.milestoneTitle": "المرحلة 1: balabalabal", + "invite.totalSupply": "إجمالي المعروض: 49999 عملة", + "invite.invitePaidFriends": "ادع 10 أصدقاء دفعوا بالفعل", + "invite.claim": "استلام", + "invite.transportFootnote": "(تُمنح مكافآت أعلى مستوى فقط)", + "invite.quotaFootnote": "(ستتلقى مكافأة عند الوصول إلى كل مستوى)", + "invite.rank": "الترتيب", + "invite.peopleSuffix": "{value} أشخاص", + "invite.copied": "تم النسخ", + "invite.copyFailed": "فشل النسخ", + "invite.notAvailable": "غير متاح الآن", + "invite.claimed": "تم الاستلام", "host_center.title": "مركز المضيف", "host_center.back": "رجوع", "host_center.change_language": "تغيير اللغة", diff --git a/common/locales/en.json b/common/locales/en.json index 484a856..32c7f5e 100644 --- a/common/locales/en.json +++ b/common/locales/en.json @@ -1,4 +1,64 @@ { + "roomReward.pageTitle": "Room Reward Event", + "roomReward.pageLabel": "Room Reward Event", + "roomReward.currentTarget": "Current reward target", + "roomReward.tiersLabel": "Room reward tiers", + "roomReward.progressLabel": "My room reward progress", + "roomReward.turnover": "Room turnover", + "roomReward.receiveReward": "Receive a reward", + "roomReward.contribution": "This week's contribution:", + "roomReward.rewards": "This week's rewards:", + "roomReward.contributionReward": "Contribution reward", + "roomReward.weeklyRewards": "Weekly rewards", + "roomReward.idPrefix": "ID:", + "roomReward.roomOwner": "Room owner", + "roomReward.changeLanguage": "Change language", + "rechargeReward.pageTitle": "Recharge Reward", + "rechargeReward.pageLabel": "Recharge Reward activity", + "rechargeReward.changeLanguage": "Change language", + "rechargeReward.days": "Days", + "rechargeReward.hours": "Hours", + "rechargeReward.minutes": "Minutes", + "rechargeReward.seconds": "Seconds", + "rechargeReward.idPrefix": "ID:", + "rechargeReward.accumulatedRecharge": "Accumulated Recharge:", + "rechargeReward.rechargeTitle": "Recharge {amount}", + "invite.pageAria": "Invite friends", + "invite.heroAria": "Invite friends make money", + "invite.countdownAria": "Countdown", + "invite.changeLanguage": "Change language", + "invite.days": "Days", + "invite.hours": "Hours", + "invite.minutes": "Minutes", + "invite.seconds": "Seconds", + "invite.yourReward": "Your Reward", + "invite.rewardSubtitle": "(Earn for every friend you invite)", + "invite.invitationReceived": "Invitation received", + "invite.topUpViaFriends": "Top up via friends", + "invite.startInviting": "Start inviting people now", + "invite.copyInviteHint": "(Copy your invitation link and share it with your friends)", + "invite.copy": "Copy", + "invite.totalInvitees": "Total number of invitees", + "invite.eligibleVoters": "Number of eligible voters", + "invite.totalRecharged": "Total amount recharged by invitees", + "invite.myRewards": "My Rewards", + "invite.monthlyTasks": "Monthly Tasks", + "invite.totalTransportation": "Total Transportation", + "invite.volume": "Volume", + "invite.invitationQuota": "Invitation Quota", + "invite.task": "Task", + "invite.milestoneTitle": "Milestone1:balabalabal", + "invite.totalSupply": "Total supply: 49999 coins", + "invite.invitePaidFriends": "Invite 10 friends who have already made a payment", + "invite.claim": "Claim", + "invite.transportFootnote": "(Only the highest-level bonuses may be awarded)", + "invite.quotaFootnote": "(You'll receive a reward upon reaching each level)", + "invite.rank": "Rank", + "invite.peopleSuffix": "{value} people", + "invite.copied": "Copied", + "invite.copyFailed": "Copy failed", + "invite.notAvailable": "Not available yet", + "invite.claimed": "Claimed", "host_center.title": "Host Center", "host_center.back": "Back", "host_center.change_language": "Change language", diff --git a/common/locales/es.json b/common/locales/es.json index cd23bcc..2dc408a 100644 --- a/common/locales/es.json +++ b/common/locales/es.json @@ -1,4 +1,64 @@ { + "roomReward.pageTitle": "Evento de recompensas de sala", + "roomReward.pageLabel": "Evento de recompensas de sala", + "roomReward.currentTarget": "Objetivo de recompensa actual", + "roomReward.tiersLabel": "Niveles de recompensa de sala", + "roomReward.progressLabel": "Progreso de recompensas de mi sala", + "roomReward.turnover": "Facturación de la sala", + "roomReward.receiveReward": "Recibir recompensa", + "roomReward.contribution": "Contribución de esta semana:", + "roomReward.rewards": "Recompensas de esta semana:", + "roomReward.contributionReward": "Recompensa de contribución", + "roomReward.weeklyRewards": "Recompensas semanales", + "roomReward.idPrefix": "ID:", + "roomReward.roomOwner": "Anfitrión de la sala", + "roomReward.changeLanguage": "Cambiar idioma", + "rechargeReward.pageTitle": "Recompensa de recarga acumulada", + "rechargeReward.pageLabel": "Actividad de recompensa de recarga acumulada", + "rechargeReward.changeLanguage": "Cambiar idioma", + "rechargeReward.days": "Días", + "rechargeReward.hours": "Horas", + "rechargeReward.minutes": "Minutos", + "rechargeReward.seconds": "Segundos", + "rechargeReward.idPrefix": "ID:", + "rechargeReward.accumulatedRecharge": "Recarga acumulada:", + "rechargeReward.rechargeTitle": "Recarga {amount}", + "invite.pageAria": "Invitar amigos", + "invite.heroAria": "Invita amigos y gana dinero", + "invite.countdownAria": "Cuenta regresiva", + "invite.changeLanguage": "Cambiar idioma", + "invite.days": "Días", + "invite.hours": "Horas", + "invite.minutes": "Minutos", + "invite.seconds": "Segundos", + "invite.yourReward": "Tu recompensa", + "invite.rewardSubtitle": "(Gana por cada amigo que invites)", + "invite.invitationReceived": "Invitación recibida", + "invite.topUpViaFriends": "Recarga de amigos", + "invite.startInviting": "Empieza a invitar ahora", + "invite.copyInviteHint": "(Copia tu enlace de invitación y compártelo con tus amigos)", + "invite.copy": "Copiar", + "invite.totalInvitees": "Número total de invitados", + "invite.eligibleVoters": "Número de usuarios elegibles", + "invite.totalRecharged": "Total recargado por invitados", + "invite.myRewards": "Mis recompensas", + "invite.monthlyTasks": "Tareas mensuales", + "invite.totalTransportation": "Transporte total", + "invite.volume": "Volumen", + "invite.invitationQuota": "Cuota de invitación", + "invite.task": "Tarea", + "invite.milestoneTitle": "Hito1:balabalabal", + "invite.totalSupply": "Suministro total: 49999 monedas", + "invite.invitePaidFriends": "Invita a 10 amigos que ya hayan pagado", + "invite.claim": "Reclamar", + "invite.transportFootnote": "(Solo se otorgan los bonos del nivel más alto)", + "invite.quotaFootnote": "(Recibirás una recompensa al alcanzar cada nivel)", + "invite.rank": "Ranking", + "invite.peopleSuffix": "{value} personas", + "invite.copied": "Copiado", + "invite.copyFailed": "Error al copiar", + "invite.notAvailable": "Aún no disponible", + "invite.claimed": "Reclamado", "host_center.title": "Centro de anfitrión", "host_center.back": "Volver", "host_center.change_language": "Cambiar idioma", diff --git a/common/locales/id.json b/common/locales/id.json index e81e1b0..e0a51ff 100644 --- a/common/locales/id.json +++ b/common/locales/id.json @@ -1,4 +1,64 @@ { + "roomReward.pageTitle": "Event Hadiah Room", + "roomReward.pageLabel": "Event Hadiah Room", + "roomReward.currentTarget": "Target hadiah saat ini", + "roomReward.tiersLabel": "Level hadiah room", + "roomReward.progressLabel": "Progress hadiah room saya", + "roomReward.turnover": "Omzet room", + "roomReward.receiveReward": "Terima hadiah", + "roomReward.contribution": "Kontribusi minggu ini:", + "roomReward.rewards": "Hadiah minggu ini:", + "roomReward.contributionReward": "Hadiah kontribusi", + "roomReward.weeklyRewards": "Hadiah mingguan", + "roomReward.idPrefix": "ID:", + "roomReward.roomOwner": "Pemilik room", + "roomReward.changeLanguage": "Ganti bahasa", + "rechargeReward.pageTitle": "Hadiah Recharge Akumulatif", + "rechargeReward.pageLabel": "Event Hadiah Recharge Akumulatif", + "rechargeReward.changeLanguage": "Ganti bahasa", + "rechargeReward.days": "Hari", + "rechargeReward.hours": "Jam", + "rechargeReward.minutes": "Menit", + "rechargeReward.seconds": "Detik", + "rechargeReward.idPrefix": "ID:", + "rechargeReward.accumulatedRecharge": "Recharge akumulatif:", + "rechargeReward.rechargeTitle": "Recharge {amount}", + "invite.pageAria": "Undang teman", + "invite.heroAria": "Undang teman dan hasilkan uang", + "invite.countdownAria": "Hitung mundur", + "invite.changeLanguage": "Ganti bahasa", + "invite.days": "Hari", + "invite.hours": "Jam", + "invite.minutes": "Menit", + "invite.seconds": "Detik", + "invite.yourReward": "Hadiahmu", + "invite.rewardSubtitle": "(Dapatkan untuk setiap teman yang kamu undang)", + "invite.invitationReceived": "Undangan diterima", + "invite.topUpViaFriends": "Top up lewat teman", + "invite.startInviting": "Mulai undang orang sekarang", + "invite.copyInviteHint": "(Salin tautan undanganmu dan bagikan ke teman)", + "invite.copy": "Salin", + "invite.totalInvitees": "Jumlah total undangan", + "invite.eligibleVoters": "Jumlah pengguna yang memenuhi syarat", + "invite.totalRecharged": "Total top up oleh undangan", + "invite.myRewards": "Hadiah saya", + "invite.monthlyTasks": "Tugas Bulanan", + "invite.totalTransportation": "Total Transportasi", + "invite.volume": "Volume", + "invite.invitationQuota": "Kuota Undangan", + "invite.task": "Tugas", + "invite.milestoneTitle": "Milestone1:balabalabal", + "invite.totalSupply": "Total suplai: 49999 koin", + "invite.invitePaidFriends": "Undang 10 teman yang sudah melakukan pembayaran", + "invite.claim": "Klaim", + "invite.transportFootnote": "(Hanya bonus level tertinggi yang diberikan)", + "invite.quotaFootnote": "(Kamu akan menerima hadiah saat mencapai setiap level)", + "invite.rank": "Peringkat", + "invite.peopleSuffix": "{value} orang", + "invite.copied": "Disalin", + "invite.copyFailed": "Gagal menyalin", + "invite.notAvailable": "Belum tersedia", + "invite.claimed": "Diklaim", "host_center.title": "Pusat Host", "host_center.back": "Kembali", "host_center.change_language": "Ganti bahasa", diff --git a/common/locales/tr.json b/common/locales/tr.json index 7d25f08..d9afe8e 100644 --- a/common/locales/tr.json +++ b/common/locales/tr.json @@ -1,4 +1,64 @@ { + "roomReward.pageTitle": "Oda Ödül Etkinliği", + "roomReward.pageLabel": "Oda Ödül Etkinliği", + "roomReward.currentTarget": "Mevcut ödül hedefi", + "roomReward.tiersLabel": "Oda ödül kademeleri", + "roomReward.progressLabel": "Oda ödül ilerlemem", + "roomReward.turnover": "Oda cirosu", + "roomReward.receiveReward": "Ödül al", + "roomReward.contribution": "Bu haftaki katkı:", + "roomReward.rewards": "Bu haftaki ödüller:", + "roomReward.contributionReward": "Katkı ödülü", + "roomReward.weeklyRewards": "Haftalık ödüller", + "roomReward.idPrefix": "ID:", + "roomReward.roomOwner": "Oda sahibi", + "roomReward.changeLanguage": "Dili değiştir", + "rechargeReward.pageTitle": "Kümülatif Yükleme Ödülü", + "rechargeReward.pageLabel": "Kümülatif Yükleme Ödülü etkinliği", + "rechargeReward.changeLanguage": "Dili değiştir", + "rechargeReward.days": "Gün", + "rechargeReward.hours": "Saat", + "rechargeReward.minutes": "Dakika", + "rechargeReward.seconds": "Saniye", + "rechargeReward.idPrefix": "ID:", + "rechargeReward.accumulatedRecharge": "Toplam yükleme:", + "rechargeReward.rechargeTitle": "{amount} yükle", + "invite.pageAria": "Arkadaş davet et", + "invite.heroAria": "Arkadaş davet et, para kazan", + "invite.countdownAria": "Geri sayım", + "invite.changeLanguage": "Dili değiştir", + "invite.days": "Gün", + "invite.hours": "Saat", + "invite.minutes": "Dakika", + "invite.seconds": "Saniye", + "invite.yourReward": "Ödülün", + "invite.rewardSubtitle": "(Davet ettiğin her arkadaş için kazan)", + "invite.invitationReceived": "Davet alındı", + "invite.topUpViaFriends": "Arkadaşlarla yükleme", + "invite.startInviting": "Şimdi davet etmeye başla", + "invite.copyInviteHint": "(Davet bağlantını kopyala ve arkadaşlarınla paylaş)", + "invite.copy": "Kopyala", + "invite.totalInvitees": "Toplam davetli sayısı", + "invite.eligibleVoters": "Uygun kullanıcı sayısı", + "invite.totalRecharged": "Davetlilerin toplam yüklemesi", + "invite.myRewards": "Ödüllerim", + "invite.monthlyTasks": "Aylık Görevler", + "invite.totalTransportation": "Toplam Taşıma", + "invite.volume": "Hacim", + "invite.invitationQuota": "Davet Kotası", + "invite.task": "Görev", + "invite.milestoneTitle": "Kilometre taşı1:balabalabal", + "invite.totalSupply": "Toplam arz: 49999 coin", + "invite.invitePaidFriends": "Ödeme yapmış 10 arkadaş davet et", + "invite.claim": "Al", + "invite.transportFootnote": "(Yalnızca en yüksek seviye bonusları verilir)", + "invite.quotaFootnote": "(Her seviyeye ulaştığında ödül alırsın)", + "invite.rank": "Sıralama", + "invite.peopleSuffix": "{value} kişi", + "invite.copied": "Kopyalandı", + "invite.copyFailed": "Kopyalama başarısız", + "invite.notAvailable": "Henüz kullanılamaz", + "invite.claimed": "Alındı", "host_center.title": "Host Merkezi", "host_center.back": "Geri", "host_center.change_language": "Dili değiştir", diff --git a/common/locales/zh.json b/common/locales/zh.json index b3af8ee..c2713b6 100644 --- a/common/locales/zh.json +++ b/common/locales/zh.json @@ -1,4 +1,64 @@ { + "roomReward.pageTitle": "房间奖励活动", + "roomReward.pageLabel": "房间奖励活动", + "roomReward.currentTarget": "当前奖励目标", + "roomReward.tiersLabel": "房间奖励档位", + "roomReward.progressLabel": "我的房间奖励进度", + "roomReward.turnover": "房间流水", + "roomReward.receiveReward": "获得奖励", + "roomReward.contribution": "本周贡献:", + "roomReward.rewards": "本周奖励:", + "roomReward.contributionReward": "贡献奖励", + "roomReward.weeklyRewards": "每周奖励", + "roomReward.idPrefix": "ID:", + "roomReward.roomOwner": "房主", + "roomReward.changeLanguage": "切换语言", + "rechargeReward.pageTitle": "累充奖励", + "rechargeReward.pageLabel": "累充奖励活动", + "rechargeReward.changeLanguage": "切换语言", + "rechargeReward.days": "天", + "rechargeReward.hours": "小时", + "rechargeReward.minutes": "分钟", + "rechargeReward.seconds": "秒", + "rechargeReward.idPrefix": "ID:", + "rechargeReward.accumulatedRecharge": "累计充值:", + "rechargeReward.rechargeTitle": "充值 {amount}", + "invite.pageAria": "邀请好友", + "invite.heroAria": "邀请好友赚钱", + "invite.countdownAria": "倒计时", + "invite.changeLanguage": "切换语言", + "invite.days": "天", + "invite.hours": "小时", + "invite.minutes": "分钟", + "invite.seconds": "秒", + "invite.yourReward": "你的奖励", + "invite.rewardSubtitle": "(每邀请一位好友都可获得奖励)", + "invite.invitationReceived": "收到邀请", + "invite.topUpViaFriends": "好友充值", + "invite.startInviting": "立即开始邀请好友", + "invite.copyInviteHint": "(复制你的邀请链接并分享给好友)", + "invite.copy": "复制", + "invite.totalInvitees": "邀请总人数", + "invite.eligibleVoters": "符合条件人数", + "invite.totalRecharged": "被邀请人充值总额", + "invite.myRewards": "我的奖励", + "invite.monthlyTasks": "月度任务", + "invite.totalTransportation": "总运输", + "invite.volume": "数量", + "invite.invitationQuota": "邀请额度", + "invite.task": "任务", + "invite.milestoneTitle": "里程碑1:balabalabal", + "invite.totalSupply": "总供应:49999 金币", + "invite.invitePaidFriends": "邀请 10 位已完成支付的好友", + "invite.claim": "领取", + "invite.transportFootnote": "(只发放最高档位奖励)", + "invite.quotaFootnote": "(每达到一个等级即可获得奖励)", + "invite.rank": "排行榜", + "invite.peopleSuffix": "{value}人", + "invite.copied": "已复制", + "invite.copyFailed": "复制失败", + "invite.notAvailable": "暂不可领取", + "invite.claimed": "已领取", "host_center.title": "主播中心", "host_center.back": "返回", "host_center.change_language": "切换语言",