diff --git a/h5/app-invite/app.js b/h5/app-invite/app.js index 485b15b..bd7f571 100644 --- a/h5/app-invite/app.js +++ b/h5/app-invite/app.js @@ -86,6 +86,7 @@ const els = { navButtons: [...document.querySelectorAll("[data-nav-view]")], copyButtons: [...document.querySelectorAll("[data-copy-target]")], rankList: document.getElementById("rankList"), + rankLists: [...document.querySelectorAll("[data-rank-list]")], giftTitle: document.getElementById("giftTitle"), giftAvatarImage: document.getElementById("giftAvatarImage"), downloadButton: document.getElementById("downloadButton"), @@ -694,10 +695,38 @@ function renderTasks() { els.taskNote.textContent = DEFAULT_TASK_NOTES[state.taskSet] || ""; } -function renderRankList() { +function rankBadgeMarkup(item) { + const badgeMap = { + 1: "./assets/rank-top1.png", + 2: "./assets/rank-top2.png", + 3: "./assets/rank-top3.png", + }; + const badge = badgeMap[item.rank]; + return badge + ? `Rank ${item.rank}` + : escapeHtml(String(item.rank)); +} + +function renderRankRows(container) { const list = state.rankItems; + const inline = container?.dataset?.rankVariant === "inline"; if (!Array.isArray(list) || list.length === 0) { - els.rankList.innerHTML = ` + return inline + ? ` +
+
--
+
+ +
+
No ranking data yet
+
0人
+
0
+
+ ` + : `
0 people
`; - return; } - els.rankList.innerHTML = list.map((item) => { - const badgeMap = { - 1: "./assets/rank-top1.png", - 2: "./assets/rank-top2.png", - 3: "./assets/rank-top3.png", - }; - - const badge = badgeMap[item.rank]; + return list.map((item) => { + if (inline) { + return ` +
+
${rankBadgeMarkup(item)}
+
+ ${escapeHtml(item.name)} +
+
${escapeHtml(item.name)}
+
${escapeHtml(item.inviteCountText)}
+
${escapeHtml(item.rewardText)}
+
+ `; + } return `
-
- ${ - badge - ? `Rank ${item.rank}` - : escapeHtml(String(item.rank)) - } -
+
${rankBadgeMarkup(item)}
${escapeHtml(item.name)}
@@ -743,6 +774,15 @@ function renderRankList() { }).join(""); } +function renderRankList() { + const containers = els.rankLists.length > 0 + ? els.rankLists + : [els.rankList].filter(Boolean); + containers.forEach((container) => { + container.innerHTML = renderRankRows(container); + }); +} + function pad(number) { return String(number).padStart(2, "0"); } @@ -899,6 +939,8 @@ function normalizeRankList(list) { rank, name: userName, avatar: trimValue(item?.avatar) || DEFAULT_AVATAR, + inviteCountText: `${formatMetric(inviteCount)}人`, + rewardText: formatMetric(rewardGoldCoins), score: scoreParts.join(" · "), }; }); @@ -1087,9 +1129,13 @@ async function refreshPageData() { if (state.view === "gift") { await fetchLandingData(); } else { - const hasHome = await fetchHomeData(); - if (hasHome) { - await fetchRankData(); + const results = await Promise.allSettled([ + fetchHomeData(), + fetchRankData(), + ]); + const rejected = results.find((item) => item.status === "rejected"); + if (rejected) { + throw rejected.reason; } } } catch (error) { diff --git a/h5/app-invite/assets/btnselect.png b/h5/app-invite/assets/btnselect.png new file mode 100644 index 0000000..3bcd7c1 Binary files /dev/null and b/h5/app-invite/assets/btnselect.png differ diff --git a/h5/app-invite/assets/btnunselect.png b/h5/app-invite/assets/btnunselect.png new file mode 100644 index 0000000..efde023 Binary files /dev/null and b/h5/app-invite/assets/btnunselect.png differ diff --git a/h5/app-invite/assets/djs.png b/h5/app-invite/assets/djs.png new file mode 100644 index 0000000..b0072d8 Binary files /dev/null and b/h5/app-invite/assets/djs.png differ diff --git a/h5/app-invite/assets/mt1.png b/h5/app-invite/assets/mt1.png new file mode 100644 index 0000000..7ca5fa2 Binary files /dev/null and b/h5/app-invite/assets/mt1.png differ diff --git a/h5/app-invite/assets/panel-bottom.png b/h5/app-invite/assets/panel-bottom.png index 1ed2000..ea2a169 100644 Binary files a/h5/app-invite/assets/panel-bottom.png and b/h5/app-invite/assets/panel-bottom.png differ diff --git a/h5/app-invite/assets/panel-middle.png b/h5/app-invite/assets/panel-middle.png index c3f9e50..520dfbc 100644 Binary files a/h5/app-invite/assets/panel-middle.png and b/h5/app-invite/assets/panel-middle.png differ diff --git a/h5/app-invite/assets/panel-top.png b/h5/app-invite/assets/panel-top.png index 3444635..2ee7db6 100644 Binary files a/h5/app-invite/assets/panel-top.png and b/h5/app-invite/assets/panel-top.png differ diff --git a/h5/app-invite/index.html b/h5/app-invite/index.html index b101ea8..6694a49 100644 --- a/h5/app-invite/index.html +++ b/h5/app-invite/index.html @@ -28,8 +28,12 @@ --ornate-top: url("./assets/panel-top.png"); --ornate-middle: url("./assets/panel-middle.png"); --ornate-bottom: url("./assets/panel-bottom.png"); - --button-active-bg: url("./assets/button-active-bg.png"); - --button-inactive-bg: url("./assets/button-inactive-bg.png"); + --monthly-title-bg: url("./assets/mt1.png"); + --task-tab-active-bg: url("./assets/btnselect.png"); + --task-tab-inactive-bg: url("./assets/btnunselect.png"); + --countdown-card-bg: url("./assets/djs.png"); + --button-active-bg: url("./assets/btnselect.png"); + --button-inactive-bg: url("./assets/btnunselect.png"); } * { @@ -143,12 +147,27 @@ .ornate-panel { position: relative; + z-index: 0; + isolation: isolate; background-color: #0b3a08; + box-shadow: 0 10px 24px rgba(0, 0, 0, 0.22); + } + + .ornate-panel::before { + content: ""; + position: absolute; + inset: 0; + z-index: 0; background-image: var(--ornate-top), var(--ornate-bottom), var(--ornate-middle); background-position: top center, bottom center, top center; background-size: 100% auto, 100% auto, 100% auto; background-repeat: no-repeat, no-repeat, repeat-y; - box-shadow: 0 10px 24px rgba(0, 0, 0, 0.22); + pointer-events: none; + } + + .ornate-panel > * { + position: relative; + z-index: 1; } .timer-panel { @@ -163,22 +182,29 @@ } .timer-box { - border: 1.5px solid rgba(249, 244, 120, 0.55); - border-radius: 10px; - padding: 10px 4px 9px; + display: flex; + flex-direction: column; + align-items: center; + padding: 0; text-align: center; - background: rgba(4, 31, 7, 0.34); } .timer-value { - font-size: 24px; + width: 58px; + aspect-ratio: 113 / 131; + display: flex; + align-items: center; + justify-content: center; + padding-top: 1px; + background: center / 100% 100% no-repeat var(--countdown-card-bg); + font-size: 22px; line-height: 1; font-weight: 700; color: #fff7dd; } .timer-label { - margin-top: 8px; + margin-top: 9px; font-size: 10px; line-height: 1; color: var(--text-muted); @@ -245,10 +271,12 @@ .reward-orb img { position: absolute; - inset: 0; - width: 100%; - height: 100%; + left: 50%; + top: 55%; + width: 66%; + height: 66%; object-fit: contain; + transform: translate(-50%, -50%); } .reward-label { @@ -347,6 +375,16 @@ .copy-action-button { width: 100%; + height: 36px; + display: flex; + align-items: center; + justify-content: center; + background: center / 100% 100% no-repeat var(--button-active-bg); + color: #fff8d5; + font-size: 16px; + font-weight: 800; + line-height: 1; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.45); } .meta-inline { @@ -416,50 +454,70 @@ height: auto; } + .monthly-task-panel { + margin-top: 32px; + padding: 58px 18px 20px; + } + + .inline-rank-panel { + margin-top: 20px; + padding: 44px 16px 18px; + } + + .monthly-title { + position: absolute; + top: -24px; + left: 50%; + z-index: 2; + width: 140px; + aspect-ratio: 419 / 120; + display: flex; + align-items: center; + justify-content: center; + padding: 0 10px; + transform: translateX(-50%); + background: center / 100% 100% no-repeat var(--monthly-title-bg); + color: #fff7d7; + font-size: 16px; + font-weight: 800; + line-height: 1; + text-align: center; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.45); + } + + .inline-rank-title { + top: -16px; + width: 88px; + font-size: 12px; + } + .task-tabs { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 7px; + gap: 10px; } .task-tab { position: relative; min-height: 0; - aspect-ratio: 430 / 130; - padding: 0; + aspect-ratio: 419 / 120; + padding: 0 6px; border: 0; - background: transparent; - color: transparent; - font-size: 0; + background: center / 100% 100% no-repeat var(--task-tab-inactive-bg); + color: #fff4b9; + font-size: 12px; + font-weight: 700; + line-height: 1.05; + text-align: center; display: flex; align-items: center; justify-content: center; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.55); } - .task-tab::after { - content: ""; - position: absolute; - inset: 0; - background-position: center; - background-repeat: no-repeat; - background-size: 100% 100%; - pointer-events: none; - } - - .task-tab[data-task-set="transport"].passive::after { - background-image: url("./assets/tab-transport-inactive.png"); - } - - .task-tab[data-task-set="transport"].active::after { - background-image: url("./assets/tab-transport-active.png"); - } - - .task-tab[data-task-set="quota"].passive::after { - background-image: url("./assets/tab-quota-inactive.png"); - } - - .task-tab[data-task-set="quota"].active::after { - background-image: url("./assets/tab-quota-active.png"); + .task-tab.active { + background-image: var(--task-tab-active-bg); + color: #fff8d5; } .task-list-panel { @@ -470,6 +528,7 @@ .task-list { display: grid; gap: 9px; + margin-top: 14px; } .task-card { @@ -513,9 +572,8 @@ } .claim-button.is-claimable { - padding: 0; background-image: var(--button-active-bg); - color: transparent; + color: #fff8d5; } .claim-button.disabled, @@ -526,14 +584,6 @@ color: rgba(246, 224, 178, 0.75); } - .claim-button.is-claimable::after { - content: ""; - position: absolute; - inset: 0; - background: center / 52px auto no-repeat url("./assets/claim-active.png"); - pointer-events: none; - } - .task-note { margin: 14px 4px 0; font-size: 10px; @@ -542,14 +592,6 @@ color: var(--text-muted); } - .footer-button { - width: min(100%, 269px); - margin: 16px auto 32px; - display: flex; - justify-content: center; - align-items: center; - } - .rank-view { padding: 18px 12px 28px; } @@ -597,6 +639,10 @@ gap: 8px; } + .inline-rank-list { + gap: 4px; + } + .rank-row { display: grid; grid-template-columns: 30px 42px minmax(0, 1fr) auto; @@ -658,6 +704,41 @@ color: #f8ead2; } + .inline-rank-panel .rank-row { + grid-template-columns: 22px 30px minmax(0, 1fr) 48px 48px; + min-height: 37px; + gap: 6px; + padding: 4px 10px; + } + + .inline-rank-panel .rank-badge { + width: 20px; + height: 20px; + font-size: 10px; + } + + .inline-rank-panel .rank-badge img { + width: 20px; + height: 20px; + } + + .inline-rank-panel .avatar { + width: 30px; + height: 30px; + } + + .inline-rank-panel .rank-name, + .inline-rank-panel .rank-score, + .inline-rank-panel .rank-reward { + font-size: 10px; + } + + .inline-rank-panel .rank-score, + .inline-rank-panel .rank-reward { + text-align: right; + white-space: nowrap; + } + .gift-view { position: relative; min-height: 100vh; @@ -875,7 +956,7 @@ data-copy-target="invite-link" aria-label="Copy invitation link" > - + Copy
@@ -889,7 +970,7 @@ data-copy-target="invite-code" aria-label="Copy invitation code" > - + Copy
@@ -916,33 +997,30 @@ -
- Monthly Tasks -
- -
- - -
- -
+
+
Monthly Tasks
+
+ + +

- @@ -957,7 +1035,7 @@ Rank
-
+