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:
parent
3923217e0e
commit
f861f82675
@ -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);
|
||||
});
|
||||
|
||||
@ -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);
|
||||
});
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user