feat: Update refresh logic and footer text for real-time data synchronization

- Changed footer text in multiple components to indicate that data refresh occurs automatically when scrolling to the bottom.
- Removed the 30-second refresh timer and implemented a cooldown mechanism to refresh data only after scrolling ends, enhancing performance and user experience.
- Updated the scrolling logic to trigger data refresh upon reaching the end of the scrollable area in both Ladder and Ranking boards.
This commit is contained in:
Ethanfly 2026-02-10 10:37:36 +08:00
parent 3923217e0e
commit f861f82675
4 changed files with 46 additions and 17 deletions

View File

@ -196,7 +196,7 @@
</div>
<div class="footer">
<span>数据实时同步 · 每30秒刷新</span>
<span>数据实时同步 · 滚动到底部时自动刷新</span>
</div>
</div>
</template>
@ -230,7 +230,6 @@ const loadingBoards = ref(false);
const loadingMatches = ref(false);
let timer = null;
let refreshTimer = null;
let handleWindowClick = null;
let boardsRaf = null;
let matchesRaf = null;
@ -243,6 +242,15 @@ const matchesGroup1 = ref(null);
const boardsScrollY = ref(0);
const matchesScrollY = ref(0);
const REFRESH_COOLDOWN_MS = 3000;
let lastRefreshAt = 0;
const onScrollEndRefresh = () => {
if (Date.now() - lastRefreshAt < REFRESH_COOLDOWN_MS) return;
lastRefreshAt = Date.now();
refreshAll();
};
const updateTime = () => {
currentTime.value = dayjs().format("YYYY-MM-DD HH:mm:ss");
};
@ -373,6 +381,7 @@ const startBoardsScroll = () => {
boardsScrollY.value -= 0.35;
if (Math.abs(boardsScrollY.value) >= h) {
boardsScrollY.value = 0;
onScrollEndRefresh();
}
boardsRaf = requestAnimationFrame(tick);
};
@ -406,6 +415,7 @@ const startMatchesScroll = () => {
matchesScrollY.value -= 0.4;
if (Math.abs(matchesScrollY.value) >= h) {
matchesScrollY.value = 0;
onScrollEndRefresh();
}
matchesRaf = requestAnimationFrame(tick);
};
@ -430,7 +440,6 @@ onMounted(async () => {
await refreshAll();
timer = setInterval(updateTime, 1000);
refreshTimer = setInterval(refreshAll, 30 * 1000);
handleWindowClick = () => {
showStoreMenu.value = false;
@ -445,7 +454,6 @@ onMounted(async () => {
onUnmounted(() => {
if (timer) clearInterval(timer);
if (refreshTimer) clearInterval(refreshTimer);
stopAutoScroll();
if (handleWindowClick) window.removeEventListener("click", handleWindowClick);
});

View File

@ -196,7 +196,7 @@
</div>
<div class="footer">
<span>数据实时同步 · 每30秒刷新</span>
<span>数据实时同步 · 滚动到底部时自动刷新</span>
</div>
</div>
</template>
@ -230,7 +230,6 @@ const loadingBoards = ref(false);
const loadingMatches = ref(false);
let timer = null;
let refreshTimer = null;
let handleWindowClick = null;
let boardsRaf = null;
let matchesRaf = null;
@ -243,6 +242,15 @@ const matchesGroup1 = ref(null);
const boardsScrollY = ref(0);
const matchesScrollY = ref(0);
const REFRESH_COOLDOWN_MS = 3000;
let lastRefreshAt = 0;
const onScrollEndRefresh = () => {
if (Date.now() - lastRefreshAt < REFRESH_COOLDOWN_MS) return;
lastRefreshAt = Date.now();
refreshAll();
};
const updateTime = () => {
currentTime.value = dayjs().format("YYYY-MM-DD HH:mm:ss");
};
@ -373,6 +381,7 @@ const startBoardsScroll = () => {
boardsScrollY.value -= 0.35;
if (Math.abs(boardsScrollY.value) >= h) {
boardsScrollY.value = 0;
onScrollEndRefresh();
}
boardsRaf = requestAnimationFrame(tick);
};
@ -406,6 +415,7 @@ const startMatchesScroll = () => {
matchesScrollY.value -= 0.4;
if (Math.abs(matchesScrollY.value) >= h) {
matchesScrollY.value = 0;
onScrollEndRefresh();
}
matchesRaf = requestAnimationFrame(tick);
};
@ -430,7 +440,6 @@ onMounted(async () => {
await refreshAll();
timer = setInterval(updateTime, 1000);
refreshTimer = setInterval(refreshAll, 30 * 1000);
handleWindowClick = () => {
showStoreMenu.value = false;
@ -445,7 +454,6 @@ onMounted(async () => {
onUnmounted(() => {
if (timer) clearInterval(timer);
if (refreshTimer) clearInterval(refreshTimer);
stopAutoScroll();
if (handleWindowClick) window.removeEventListener("click", handleWindowClick);
});

View File

@ -465,7 +465,7 @@
<!-- 底部装饰 -->
<div class="board-footer">
<div class="footer-hint">数据实时同步 · 每30秒刷新一次</div>
<div class="footer-hint">数据实时同步 · 滚动到底部时自动刷新</div>
</div>
</div>
</template>
@ -492,7 +492,6 @@
const scrollContainer = ref(null);
const isRefreshing = ref(false);
let timer = null;
let refreshTimer = null;
let handleWindowClick = null;
const scrollReqIdAll = ref(null);
const scrollReqIdMale = ref(null);
@ -500,12 +499,21 @@
const scrollYAll = ref(0);
const scrollYMale = ref(0);
const scrollYFemale = ref(0);
const REFRESH_COOLDOWN_MS = 3000;
let lastRefreshAt = 0;
//
const updateTime = () => {
currentTime.value = dayjs().format("YYYY-MM-DD HH:mm:ss");
};
//
const onScrollEndRefresh = () => {
if (Date.now() - lastRefreshAt < REFRESH_COOLDOWN_MS) return;
lastRefreshAt = Date.now();
fetchRanking();
};
// (使 Transform )
const startContinuousScroll = (listRef, scrollYRef, reqIdRef) => {
if (reqIdRef.value) cancelAnimationFrame(reqIdRef.value);
@ -522,9 +530,10 @@
// 100 * (90px + 12px)
const singleSetHeight = listRef.value.length * 102;
// 0
// 0
if (Math.abs(scrollYRef.value) >= singleSetHeight) {
scrollYRef.value = 0;
onScrollEndRefresh();
}
reqIdRef.value = requestAnimationFrame(scroll);
@ -663,7 +672,6 @@
onMounted(() => {
fetchStores();
timer = setInterval(updateTime, 1000);
refreshTimer = setInterval(fetchRanking, 30 * 1000); // 30
//
handleWindowClick = () => {
@ -674,7 +682,6 @@
onUnmounted(() => {
if (timer) clearInterval(timer);
if (refreshTimer) clearInterval(refreshTimer);
if (scrollReqIdAll.value) cancelAnimationFrame(scrollReqIdAll.value);
if (scrollReqIdMale.value) cancelAnimationFrame(scrollReqIdMale.value);
if (scrollReqIdFemale.value) cancelAnimationFrame(scrollReqIdFemale.value);

View File

@ -511,7 +511,7 @@
<div class="footer-bar">
<span>REAL-TIME DATA SYNC ACTIVE</span>
<div class="dot"></div>
<span>REFRESH EVERY 30 SECONDS</span>
<span>滚动到底部时自动刷新</span>
</div>
</div>
</template>
@ -538,7 +538,6 @@
const scrollContainer = ref(null);
const isRefreshing = ref(false);
let timer = null;
let refreshTimer = null;
let handleWindowClick = null;
const group1 = ref(null);
const scrollReqId = ref(null);
@ -549,11 +548,19 @@
const scrollReqIdFemale = ref(null);
const scrollYMale = ref(0);
const scrollYFemale = ref(0);
const REFRESH_COOLDOWN_MS = 3000;
let lastRefreshAt = 0;
const updateTime = () => {
currentTime.value = dayjs().format("HH:mm:ss");
};
const onScrollEndRefresh = () => {
if (Date.now() - lastRefreshAt < REFRESH_COOLDOWN_MS) return;
lastRefreshAt = Date.now();
fetchRanking();
};
const startContinuousScroll = (listRef, scrollYRef, reqIdRef, groupRef) => {
if (reqIdRef.value) cancelAnimationFrame(reqIdRef.value);
@ -569,6 +576,7 @@
if (Math.abs(scrollYRef.value) >= singleSetHeight) {
scrollYRef.value = 0;
onScrollEndRefresh();
}
reqIdRef.value = requestAnimationFrame(scroll);
@ -693,7 +701,6 @@
onMounted(() => {
fetchStores();
timer = setInterval(updateTime, 1000);
refreshTimer = setInterval(fetchRanking, 30 * 1000);
handleWindowClick = () => {
showStoreMenu.value = false;
};
@ -702,7 +709,6 @@
onUnmounted(() => {
if (timer) clearInterval(timer);
if (refreshTimer) clearInterval(refreshTimer);
if (scrollReqId.value) cancelAnimationFrame(scrollReqId.value);
if (scrollReqIdMale.value) cancelAnimationFrame(scrollReqIdMale.value);
if (scrollReqIdFemale.value) cancelAnimationFrame(scrollReqIdFemale.value);