feat: use login popup announcement on home
Deploy olons-server production / deploy (push) Successful in 4m57s
Deploy olons-server production / deploy (push) Successful in 4m57s
This commit is contained in:
@@ -35,6 +35,7 @@
|
|||||||
title: string;
|
title: string;
|
||||||
content: string;
|
content: string;
|
||||||
body_html?: string;
|
body_html?: string;
|
||||||
|
source_type?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<section class="m-home">
|
<section class="m-home">
|
||||||
<AnnouncementPopup
|
<AnnouncementPopup
|
||||||
:show="Boolean(popupNotice)"
|
:show="popupVisible"
|
||||||
:notice="popupNotice"
|
:notice="loginPopupNotice"
|
||||||
@read="markPopupRead"
|
@read="markPopupRead"
|
||||||
/>
|
/>
|
||||||
<div class="m-home-hero" :style="bannerStyle">
|
<div class="m-home-hero" :style="bannerStyle">
|
||||||
@@ -54,18 +54,18 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
v-if="currentNotice"
|
v-if="displayNotice"
|
||||||
class="m-notice m-card"
|
class="m-notice m-card"
|
||||||
type="button"
|
type="button"
|
||||||
aria-label="查看全部通知"
|
:aria-label="`查看公告:${displayNotice.title || '最新公告'}`"
|
||||||
@click="router.push('/app/content/notices')"
|
@click="openNotice"
|
||||||
>
|
>
|
||||||
<n-icon :component="MegaphoneOutline" />
|
<n-icon :component="MegaphoneOutline" />
|
||||||
<span :class="['m-notice-tag', { 'is-activity': currentNotice.source_type === 'operational_simulation' }]">
|
<span :class="['m-notice-tag', { 'is-activity': displayNotice.source_type === 'operational_simulation' }]">
|
||||||
{{ currentNotice.source_type === 'operational_simulation' ? '活动' : '公告' }}
|
{{ displayNotice.source_type === 'operational_simulation' ? '活动' : '公告' }}
|
||||||
</span>
|
</span>
|
||||||
<p :key="currentNotice.id" class="m-notice-copy">
|
<p :key="displayNotice.id" class="m-notice-copy">
|
||||||
{{ currentNotice.title || currentNotice.content || '查看最新通知' }}
|
{{ displayNotice.title || displayNotice.content || '查看最新通知' }}
|
||||||
</p>
|
</p>
|
||||||
<n-icon class="m-notice-arrow" :component="ChevronForwardOutline" />
|
<n-icon class="m-notice-arrow" :component="ChevronForwardOutline" />
|
||||||
</button>
|
</button>
|
||||||
@@ -165,7 +165,9 @@
|
|||||||
const loading = ref(true);
|
const loading = ref(true);
|
||||||
const error = ref('');
|
const error = ref('');
|
||||||
const leaderboard = ref<LeaderboardEntry[]>([]);
|
const leaderboard = ref<LeaderboardEntry[]>([]);
|
||||||
const popupNotice = ref<AnnouncementNotice | null>(null);
|
const loginPopupNotice = ref<AnnouncementNotice | null>(null);
|
||||||
|
const popupVisible = ref(false);
|
||||||
|
const homeAnnouncement = ref<AnnouncementNotice | null>(null);
|
||||||
const activeBannerIndex = ref(0);
|
const activeBannerIndex = ref(0);
|
||||||
const activeNoticeIndex = ref(0);
|
const activeNoticeIndex = ref(0);
|
||||||
let bannerTimer: number | undefined;
|
let bannerTimer: number | undefined;
|
||||||
@@ -176,6 +178,7 @@
|
|||||||
);
|
);
|
||||||
const currentBanner = computed(() => home.value?.banners?.[activeBannerIndex.value]);
|
const currentBanner = computed(() => home.value?.banners?.[activeBannerIndex.value]);
|
||||||
const currentNotice = computed(() => home.value?.notices?.[activeNoticeIndex.value]);
|
const currentNotice = computed(() => home.value?.notices?.[activeNoticeIndex.value]);
|
||||||
|
const displayNotice = computed(() => homeAnnouncement.value || currentNotice.value);
|
||||||
const bannerStyle = computed(() => {
|
const bannerStyle = computed(() => {
|
||||||
const url = safeImage(currentBanner.value?.image_url);
|
const url = safeImage(currentBanner.value?.image_url);
|
||||||
return {
|
return {
|
||||||
@@ -271,9 +274,7 @@
|
|||||||
loading.value = true;
|
loading.value = true;
|
||||||
error.value = '';
|
error.value = '';
|
||||||
try {
|
try {
|
||||||
const noticeRequest = shouldShowLoginNotice()
|
const noticeRequest = request<AnnouncementNotice | null>({ url: '/v1/notices/popup' }).catch(() => null);
|
||||||
? request<AnnouncementNotice | null>({ url: '/v1/notices/popup' }).catch(() => null)
|
|
||||||
: Promise.resolve(null);
|
|
||||||
const [homeData, rankData, noticeData] = await Promise.all([
|
const [homeData, rankData, noticeData] = await Promise.all([
|
||||||
request<HomeData>({ url: '/v1/home' }),
|
request<HomeData>({ url: '/v1/home' }),
|
||||||
request<LeaderboardEntry[]>({ url: '/v1/leaderboard' }).catch(() => []),
|
request<LeaderboardEntry[]>({ url: '/v1/leaderboard' }).catch(() => []),
|
||||||
@@ -281,7 +282,9 @@
|
|||||||
]);
|
]);
|
||||||
home.value = homeData;
|
home.value = homeData;
|
||||||
leaderboard.value = rankData || [];
|
leaderboard.value = rankData || [];
|
||||||
popupNotice.value = noticeData;
|
homeAnnouncement.value = noticeData;
|
||||||
|
loginPopupNotice.value = shouldShowLoginNotice() ? noticeData : null;
|
||||||
|
popupVisible.value = Boolean(loginPopupNotice.value);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
error.value = errorText(err);
|
error.value = errorText(err);
|
||||||
} finally {
|
} finally {
|
||||||
@@ -290,14 +293,24 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function markPopupRead() {
|
function markPopupRead() {
|
||||||
if (!popupNotice.value) return;
|
if (!loginPopupNotice.value) return;
|
||||||
const noticeId = popupNotice.value.id;
|
const noticeId = loginPopupNotice.value.id;
|
||||||
popupNotice.value = null;
|
popupVisible.value = false;
|
||||||
|
loginPopupNotice.value = null;
|
||||||
completeLoginNotice();
|
completeLoginNotice();
|
||||||
if (noticeId > 0) {
|
if (noticeId > 0) {
|
||||||
request<void>({ url: `/v1/notices/${noticeId}/read`, method: 'POST' }).catch(() => undefined);
|
request<void>({ url: `/v1/notices/${noticeId}/read`, method: 'POST' }).catch(() => undefined);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openNotice() {
|
||||||
|
if (homeAnnouncement.value) {
|
||||||
|
loginPopupNotice.value = homeAnnouncement.value;
|
||||||
|
popupVisible.value = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void router.push('/app/content/notices');
|
||||||
|
}
|
||||||
watch(() => home.value?.banners?.length, () => {
|
watch(() => home.value?.banners?.length, () => {
|
||||||
activeBannerIndex.value = 0;
|
activeBannerIndex.value = 0;
|
||||||
restartBannerTimer();
|
restartBannerTimer();
|
||||||
|
|||||||
Reference in New Issue
Block a user