h5周星优化
This commit is contained in:
parent
bb0a31f601
commit
89534f7bf3
@ -62,8 +62,9 @@
|
||||
}
|
||||
|
||||
.page {
|
||||
width: min(100%, var(--page-width));
|
||||
width: 100%;
|
||||
min-height: 100vh;
|
||||
min-height: 100dvh;
|
||||
margin: 0 auto;
|
||||
background: linear-gradient(180deg, #163a07 0%, #123708 38%, #0d2f08 100%);
|
||||
overflow: hidden;
|
||||
@ -113,7 +114,7 @@
|
||||
width: min(72%, 230px);
|
||||
max-width: calc(100% - 44px);
|
||||
aspect-ratio: 665 / 88;
|
||||
padding: 0 24px 6px;
|
||||
padding: 0 24px 2px;
|
||||
background: center / 100% 100% no-repeat var(--subtitle-frame-image);
|
||||
color: #f8e29b;
|
||||
font-size: 13px;
|
||||
@ -158,6 +159,22 @@
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.gift-card.gift-skeleton .gift-inner {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
.gift-card.gift-skeleton .gift-inner::before {
|
||||
content: "";
|
||||
width: 70%;
|
||||
aspect-ratio: 1;
|
||||
border-radius: 24px;
|
||||
background: linear-gradient(90deg, rgba(255, 255, 255, 0.12) 0%, rgba(255, 248, 198, 0.35) 48%, rgba(255, 255, 255, 0.12) 100%);
|
||||
background-size: 220% 100%;
|
||||
animation: rank-skeleton-loading 1.1s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.gift-empty {
|
||||
opacity: 0.3;
|
||||
}
|
||||
@ -165,14 +182,16 @@
|
||||
.tab-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
gap: 8px;
|
||||
padding: 14px 15px 0;
|
||||
gap: 12px;
|
||||
padding: 12px 17px 14px;
|
||||
}
|
||||
|
||||
.tab-button {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
aspect-ratio: 336 / 126;
|
||||
aspect-ratio: 336 / 108;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
background: none;
|
||||
@ -191,8 +210,8 @@
|
||||
|
||||
.tab-button.active::before {
|
||||
background-image: var(--tab-active-image);
|
||||
width: 103.4%;
|
||||
height: 109%;
|
||||
width: 103.57%;
|
||||
height: 108.73%;
|
||||
}
|
||||
|
||||
.tab-button span {
|
||||
@ -216,15 +235,7 @@
|
||||
|
||||
.tab-button.active span {
|
||||
color: #c15f17;
|
||||
}
|
||||
|
||||
.period-strip {
|
||||
padding: 18px 18px 16px;
|
||||
color: #fff8c6;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
line-height: 1.1;
|
||||
font-weight: 700;
|
||||
transform: translate(-50%, calc(-50% + 1px));
|
||||
}
|
||||
|
||||
.rank-stage {
|
||||
@ -271,6 +282,48 @@
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.rank-row.skeleton {
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.rank-row.skeleton .rank-mark,
|
||||
.rank-row.skeleton .rank-avatar,
|
||||
.rank-row.skeleton .rank-name,
|
||||
.rank-row.skeleton .rank-score {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: linear-gradient(90deg, rgba(255, 255, 255, 0.1) 0%, rgba(255, 248, 198, 0.28) 48%, rgba(255, 255, 255, 0.1) 100%);
|
||||
background-size: 220% 100%;
|
||||
animation: rank-skeleton-loading 1.1s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.rank-row.skeleton .rank-mark {
|
||||
height: 18px;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.rank-row.skeleton .rank-name {
|
||||
height: 16px;
|
||||
max-width: 54%;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.rank-row.skeleton .rank-score {
|
||||
width: 48px;
|
||||
height: 16px;
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
@keyframes rank-skeleton-loading {
|
||||
0% {
|
||||
background-position: 120% 0;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: -120% 0;
|
||||
}
|
||||
}
|
||||
|
||||
.rank-mark {
|
||||
width: 30px;
|
||||
flex: 0 0 30px;
|
||||
@ -485,9 +538,10 @@
|
||||
|
||||
<div class="gift-grid">
|
||||
<template x-for="gift in giftSlots()" :key="gift.key">
|
||||
<div class="gift-card" :class="{ 'gift-empty': gift.placeholder }" :title="giftTitle(gift)">
|
||||
<div class="gift-card" :class="{ 'gift-empty': gift.placeholder, 'gift-skeleton': gift.skeleton }"
|
||||
:title="giftTitle(gift)">
|
||||
<div class="gift-inner">
|
||||
<template x-if="!gift.placeholder">
|
||||
<template x-if="!gift.placeholder && !gift.skeleton">
|
||||
<img :src="giftCover(gift)" :alt="giftTitle(gift)" />
|
||||
</template>
|
||||
</div>
|
||||
@ -497,37 +551,33 @@
|
||||
|
||||
<nav class="tab-row">
|
||||
<button type="button" class="tab-button" :class="{ active: activeTab === 'last' }" @click="activeTab = 'last'">
|
||||
<span>Previous Top 3 Records</span>
|
||||
<span>Previous Top 3</span>
|
||||
</button>
|
||||
<button type="button" class="tab-button" :class="{ active: activeTab === 'current' }"
|
||||
@click="activeTab = 'current'">
|
||||
<span>This Week's rank list</span>
|
||||
<span>This Week</span>
|
||||
</button>
|
||||
<button type="button" class="tab-button" :class="{ active: activeTab === 'reward' }"
|
||||
@click="activeTab = 'reward'">
|
||||
<span>Reward Description</span>
|
||||
<span>Reward</span>
|
||||
</button>
|
||||
</nav>
|
||||
</section>
|
||||
|
||||
<template x-if="activeTab !== 'reward'">
|
||||
<div class="period-strip" x-text="activePeriodText()"></div>
|
||||
</template>
|
||||
|
||||
<section class="rank-stage" x-show="activeTab !== 'reward'">
|
||||
<ul class="rank-list">
|
||||
<template x-for="(item, index) in displayRows()" :key="item.key">
|
||||
<li class="rank-row" :class="rowClass(index, item)">
|
||||
<div class="rank-mark">
|
||||
<template x-if="isTopRank(item.rank)">
|
||||
<template x-if="!item.skeleton && isTopRank(item.rank)">
|
||||
<img class="rank-badge-icon" :src="topRankIcon(item.rank)" :alt="'Top ' + item.rank" />
|
||||
</template>
|
||||
<template x-if="!isTopRank(item.rank)">
|
||||
<template x-if="!item.skeleton && !isTopRank(item.rank)">
|
||||
<span class="plain" x-text="item.rank"></span>
|
||||
</template>
|
||||
</div>
|
||||
<div class="rank-avatar">
|
||||
<template x-if="!item.placeholder">
|
||||
<template x-if="!item.placeholder && !item.skeleton">
|
||||
<img :src="avatarOf(item)" :alt="item.userNickname || 'avatar'" />
|
||||
</template>
|
||||
</div>
|
||||
@ -537,11 +587,11 @@
|
||||
</template>
|
||||
</ul>
|
||||
|
||||
<div class="empty-message" x-show="!hasRealRows() && !error">
|
||||
<div class="empty-message" x-show="!loading && !hasRealRows() && !error">
|
||||
No ranking data yet. Send the selected gifts and the leaderboard will update
|
||||
here.
|
||||
</div>
|
||||
<div class="empty-message" x-show="error" x-text="error"></div>
|
||||
<div class="empty-message" x-show="!loading && error" x-text="error"></div>
|
||||
</section>
|
||||
|
||||
<section class="reward-stage" x-show="activeTab === 'reward'">
|
||||
@ -602,16 +652,10 @@
|
||||
|
||||
function weekStarPage() {
|
||||
return {
|
||||
activeTab: "last",
|
||||
activeTab: "current",
|
||||
data: normalizePageData({}),
|
||||
error: "",
|
||||
|
||||
activePeriodText() {
|
||||
if (this.activeTab === "last") {
|
||||
return this.data.lastPeriodText || this.data.currentPeriodText || "--";
|
||||
}
|
||||
return this.data.currentPeriodText || this.data.lastPeriodText || "--";
|
||||
},
|
||||
loading: true,
|
||||
|
||||
avatarOf(item) {
|
||||
return item && item.userAvatar ? item.userAvatar : DEFAULT_AVATAR;
|
||||
@ -638,6 +682,9 @@
|
||||
},
|
||||
|
||||
displayRows() {
|
||||
if (this.loading) {
|
||||
return this.skeletonRows();
|
||||
}
|
||||
if (this.activeTab === "current") {
|
||||
return this.buildRows(this.data.thisWeekTop10, 5, 10);
|
||||
}
|
||||
@ -646,6 +693,7 @@
|
||||
|
||||
async fetchPage() {
|
||||
this.error = "";
|
||||
this.loading = true;
|
||||
try {
|
||||
const url = new URL("/go/public/h5/week-star/page", resolveWeekStarAPIBase());
|
||||
const sysOrigin = new URLSearchParams(window.location.search).get("sysOrigin");
|
||||
@ -674,6 +722,8 @@
|
||||
? error.message
|
||||
: "Please retry later.";
|
||||
this.data = normalizePageData({});
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
@ -682,6 +732,12 @@
|
||||
},
|
||||
|
||||
giftSlots() {
|
||||
if (this.loading) {
|
||||
return Array.from({ length: 3 }, (_, index) => ({
|
||||
key: "gift-skeleton-" + index,
|
||||
skeleton: true,
|
||||
}));
|
||||
}
|
||||
const slots = (this.data.qualifyingGifts || []).slice(0, 3).map((gift, index) => {
|
||||
return {
|
||||
...gift,
|
||||
@ -699,6 +755,9 @@
|
||||
},
|
||||
|
||||
giftTitle(gift) {
|
||||
if (gift && gift.skeleton) {
|
||||
return "Loading gift";
|
||||
}
|
||||
if (!gift || gift.placeholder) {
|
||||
return "Gift";
|
||||
}
|
||||
@ -706,7 +765,7 @@
|
||||
},
|
||||
|
||||
hasRealRows() {
|
||||
return this.displayRows().some((item) => !item.placeholder);
|
||||
return !this.loading && this.displayRows().some((item) => !item.placeholder && !item.skeleton);
|
||||
},
|
||||
|
||||
heroPeriodText() {
|
||||
@ -761,22 +820,34 @@
|
||||
|
||||
rowClass(index, item) {
|
||||
const stripe = index % 2 === 0 ? "light" : "dark";
|
||||
if (item && item.skeleton) {
|
||||
return stripe + " skeleton";
|
||||
}
|
||||
return item.placeholder ? stripe + " placeholder" : stripe;
|
||||
},
|
||||
|
||||
rowName(item) {
|
||||
if (!item || item.placeholder) {
|
||||
if (!item || item.placeholder || item.skeleton) {
|
||||
return "";
|
||||
}
|
||||
return item.userNickname || ("User " + item.userId);
|
||||
},
|
||||
|
||||
rowScore(item) {
|
||||
if (!item || item.placeholder) {
|
||||
if (!item || item.placeholder || item.skeleton) {
|
||||
return "";
|
||||
}
|
||||
return toScoreText(item.scoreGold);
|
||||
},
|
||||
|
||||
skeletonRows() {
|
||||
const size = this.activeTab === "last" ? 4 : 5;
|
||||
return Array.from({ length: size }, (_, index) => ({
|
||||
key: "skeleton-" + this.activeTab + "-" + index,
|
||||
skeleton: true,
|
||||
rank: 0,
|
||||
}));
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user