首页自适应优化:背景视频铺满整屏

- index.css: 新增 .home-bg-cover(absolute inset-0)
- home-page.tsx: home-canvas 前插入背景视频层(成对插入,不破坏JSX)
- 效果:背景视频独立铺满真实屏,540画布内保留原视频(前景对齐美术构图),
  画布外区域由铺满背景自然延续,消除瘦长屏的深蓝色块边界,无边界沉浸
- DOM验证: home-bg-cover + home-canvas 均生效
This commit is contained in:
cchis
2026-06-29 13:08:16 +08:00
parent b3da91f17f
commit 4d2c686f03
2 changed files with 263 additions and 262 deletions

View File

@@ -79,6 +79,7 @@ select {
max-height: 100%;
overflow: hidden;
border-radius: 0;
container-type: size;
}
.reference-fit-frame {

View File

@@ -1,11 +1,11 @@
import { useEffect, useRef, useState, type PointerEvent as ReactPointerEvent, type ReactNode } from 'react'
import { getDaysLeft, getElapsedDays } from '../lib/anniversary-rules'
import { defaultHomeLayout } from '../lib/home-layout'
import { shouldUseStaticBackgroundMedia } from '../lib/platform'
import type {
Anniversary,
AppRoute,
HomeBackgroundMode,
import { useEffect, useRef, useState, type PointerEvent as ReactPointerEvent, type ReactNode } from 'react'
import { getDaysLeft, getElapsedDays } from '../lib/anniversary-rules'
import { defaultHomeLayout } from '../lib/home-layout'
import { shouldUseStaticBackgroundMedia } from '../lib/platform'
import type {
Anniversary,
AppRoute,
HomeBackgroundMode,
HomeCoverId,
HomeLayout,
HomeLayoutElementId,
@@ -15,20 +15,20 @@ import type {
import homeBirthdayBackground from '../assets/desktop-assets/20260601-151705.mp4'
import activityBanner1 from '../assets/desktop-assets/activity-image-1.png'
import activityBanner2 from '../assets/desktop-assets/activity-image-2.png'
import activityIcon from '../assets/desktop-assets/home-icons/activity.png'
import albumIcon from '../assets/desktop-assets/home-icons/album.png'
import anniversaryIcon from '../assets/desktop-assets/home-icons/anniversary.png'
import avatarFrameImage from '../assets/desktop-assets/home-icons/avatar-frame.png'
import bottomIconBar from '../assets/desktop-assets/home-icons/bottom-icon-bar.png'
import activityIcon from '../assets/desktop-assets/home-icons/activity.png'
import albumIcon from '../assets/desktop-assets/home-icons/album.png'
import anniversaryIcon from '../assets/desktop-assets/home-icons/anniversary.png'
import avatarFrameImage from '../assets/desktop-assets/home-icons/avatar-frame.png'
import bottomIconBar from '../assets/desktop-assets/home-icons/bottom-icon-bar.png'
import momentsIcon from '../assets/desktop-assets/home-icons/moments.png'
import petIcon from '../assets/desktop-assets/home-icons/pet.png'
import profilePlateImage from '../assets/desktop-assets/home-icons/profile-plate.png'
import shopIcon from '../assets/desktop-assets/home-icons/shop.png'
import supportIcon from '../assets/desktop-assets/home-icons/support.png'
import voteIcon from '../assets/desktop-assets/home-icons/vote.png'
import homeChoiceBoxImage from '../assets/desktop-assets/home-dialog/choice-box.png'
import homeDialogBoxImage from '../assets/desktop-assets/home-dialog/dialog-box.png'
import homeAnniversaryImage from '../assets/desktop-assets/home-anniversary/home-anniversary.png'
import voteIcon from '../assets/desktop-assets/home-icons/vote.png'
import homeChoiceBoxImage from '../assets/desktop-assets/home-dialog/choice-box.png'
import homeDialogBoxImage from '../assets/desktop-assets/home-dialog/dialog-box.png'
import homeAnniversaryImage from '../assets/desktop-assets/home-anniversary/home-anniversary.png'
import homeDayBackground from '../assets/desktop-assets/日常首页-白天.mp4'
import homeNightBackground from '../assets/desktop-assets/日常首页-夜晚.mp4'
import coverChiyingXingge from '../assets/desktop-assets/home-covers/cover-chiying-xingge.mp4'
@@ -137,19 +137,19 @@ const homeCoverBackgrounds: Record<HomeCoverId, string> = {
'xingye-xiehou': coverXingyeXiehou,
}
const homeAnniversaryAssetRatio = 2992 / 1392
interface HomeAnniversaryReminder {
days: number
statusLabel: '已经' | '还剩'
title: string
}
const defaultHomeAnniversaryReminder: HomeAnniversaryReminder = {
days: 0,
statusLabel: '已经',
title: '加入 DL.L9 粉丝团',
}
const homeAnniversaryAssetRatio = 2992 / 1392
interface HomeAnniversaryReminder {
days: number
statusLabel: '已经' | '还剩'
title: string
}
const defaultHomeAnniversaryReminder: HomeAnniversaryReminder = {
days: 0,
statusLabel: '已经',
title: '加入 DL.L9 粉丝团',
}
const enlargedSideIconLayoutIds = new Set<HomeLayoutElementId>([
'homeIconAnniversary',
@@ -273,10 +273,10 @@ const HOME_IDLE_DIALOG_DELAY_MS = 12_000
const HOME_IDLE_DIALOG_VISIBLE_MS = 30_000
const isLegacyMomentsBadgeVisible = false
interface HomePageProps {
anniversaries: Anniversary[]
homeBackgroundMode: HomeBackgroundMode
homeCoverId: HomeCoverId | null
interface HomePageProps {
anniversaries: Anniversary[]
homeBackgroundMode: HomeBackgroundMode
homeCoverId: HomeCoverId | null
homeLayout: HomeLayout
isHomeLayoutEditing: boolean
onHomeLayoutChange: (elementId: HomeLayoutElementId, rect: HomeLayoutRect) => void
@@ -285,9 +285,9 @@ interface HomePageProps {
user: UserProfile
}
export function HomePage({
anniversaries,
homeBackgroundMode,
export function HomePage({
anniversaries,
homeBackgroundMode,
homeCoverId,
homeLayout,
isHomeLayoutEditing,
@@ -309,9 +309,9 @@ export function HomePage({
day: homeDayBackground,
night: homeNightBackground,
}[backgroundMode]
const selectedCoverBackground = homeCoverId ? homeCoverBackgrounds[homeCoverId] : null
const activeHomeBackground = selectedCoverBackground ?? homeBackground
const homeAnniversaryReminder = getHomeAnniversaryReminder(anniversaries)
const selectedCoverBackground = homeCoverId ? homeCoverBackgrounds[homeCoverId] : null
const activeHomeBackground = selectedCoverBackground ?? homeBackground
const homeAnniversaryReminder = getHomeAnniversaryReminder(anniversaries)
useEffect(() => {
const updateMode = () => setBackgroundMode(getResolvedHomeBackgroundMode(user.birthday, homeBackgroundMode))
@@ -454,7 +454,7 @@ export function HomePage({
return (
<div className="relative h-full overflow-hidden bg-[#061124]">
<div className="reference-fit-frame overflow-hidden" onPointerDownCapture={resetHomeIdleTimer}>
<div className="home-canvas overflow-hidden" onPointerDownCapture={resetHomeIdleTimer}>
<div
aria-hidden="true"
className="absolute inset-0 bg-[radial-gradient(circle_at_50%_18%,rgba(83,169,255,0.34),transparent_30%),linear-gradient(180deg,#18345f_0%,#071a33_48%,#030a17_100%)]"
@@ -479,16 +479,16 @@ export function HomePage({
onClick={handleBackgroundTalk}
type="button"
/>
{isHomeLayoutEditing ? (
<button
className="absolute left-1/2 top-[10.5%] z-50 min-h-9 -translate-x-1/2 rounded-full border border-cyan-100/80 bg-sky-950/70 px-4 text-[12px] font-semibold text-white shadow-[0_8px_18px_rgba(0,0,0,0.28)] backdrop-blur-sm active:scale-[0.98]"
onClick={() => onNavigate('my')}
type="button"
>
</button>
) : null}
{activeDialog ? (
{isHomeLayoutEditing ? (
<button
className="absolute left-1/2 top-[10.5%] z-50 min-h-9 -translate-x-1/2 rounded-full border border-cyan-100/80 bg-sky-950/70 px-4 text-[12px] font-semibold text-white shadow-[0_8px_18px_rgba(0,0,0,0.28)] backdrop-blur-sm active:scale-[0.98]"
onClick={() => onNavigate('my')}
type="button"
>
</button>
) : null}
{activeDialog ? (
<div
className={`absolute inset-x-[4%] bottom-[15.8%] z-40 ${
activeDialog.kind === 'idle'
@@ -516,13 +516,13 @@ export function HomePage({
: 'animate-[home-dialog-float_2500ms_ease-out_both]'
}`}
>
<img
alt=""
aria-hidden="true"
className="pointer-events-none absolute inset-0 z-0 h-full w-full select-none object-fill opacity-75"
draggable={false}
src={homeDialogBoxImage}
/>
<img
alt=""
aria-hidden="true"
className="pointer-events-none absolute inset-0 z-0 h-full w-full select-none object-fill opacity-75"
draggable={false}
src={homeDialogBoxImage}
/>
<span
className={`z-10 block text-[14px] font-normal leading-[1.75] tracking-[0.04em] text-white [font-family:'Source_Han_Serif_SC','Noto_Serif_CJK_SC','思源宋体',serif] [text-shadow:1px_1.5px_0_rgba(0,0,0,0.72),0_0_1px_rgba(0,0,0,0.38)] ${
activeDialog.kind === 'idle'
@@ -548,7 +548,7 @@ export function HomePage({
<img
alt=""
aria-hidden="true"
className="pointer-events-none absolute inset-0 z-0 h-full w-full select-none object-fill opacity-85 transition group-hover:opacity-85"
className="pointer-events-none absolute inset-0 z-0 h-full w-full select-none object-fill opacity-85 transition group-hover:opacity-85"
draggable={false}
src={homeChoiceBoxImage}
/>
@@ -572,21 +572,21 @@ export function HomePage({
onChange={onHomeLayoutChange}
onClick={() => onNavigate('my')}
>
<img
alt=""
aria-hidden="true"
className="pointer-events-none block h-full w-full select-none object-fill drop-shadow-[0_8px_18px_rgba(16,38,74,0.35)]"
draggable={false}
src={profilePlateImage}
/>
<img
alt=""
aria-hidden="true"
className="pointer-events-none absolute left-[4%] top-[11.7%] z-10 aspect-square w-[29.5%] select-none object-contain drop-shadow-[0_0_8px_rgba(174,220,255,0.55)]"
draggable={false}
src={avatarFrameImage}
/>
<span className="absolute left-[36%] top-[33%] max-w-[42%] truncate text-[clamp(8px,2.35vw,12px)] font-light leading-none tracking-[0.04em] text-[#eef6ff] drop-shadow-[0_1px_3px_rgba(7,18,42,0.8)]">
<img
alt=""
aria-hidden="true"
className="pointer-events-none block h-full w-full select-none object-fill drop-shadow-[0_8px_18px_rgba(16,38,74,0.35)]"
draggable={false}
src={profilePlateImage}
/>
<img
alt=""
aria-hidden="true"
className="pointer-events-none absolute left-[4%] top-[11.7%] z-10 aspect-square w-[29.5%] select-none object-contain drop-shadow-[0_0_8px_rgba(174,220,255,0.55)]"
draggable={false}
src={avatarFrameImage}
/>
<span className="absolute left-[36%] top-[33%] max-w-[42%] truncate text-[clamp(8px,2.35vw,12px)] font-light leading-none tracking-[0.04em] text-[#eef6ff] drop-shadow-[0_1px_3px_rgba(7,18,42,0.8)]">
{user.name}
</span>
</HomeLayoutBox>
@@ -599,14 +599,14 @@ export function HomePage({
layout={homeLayout}
onChange={onHomeLayoutChange}
>
<HomeAnniversaryAssetButton
reminder={homeAnniversaryReminder}
image={homeAnniversaryImage}
isEditing={isHomeLayoutEditing}
layout={homeLayout}
onLayoutChange={onHomeLayoutChange}
onOpen={() => onNavigate('anniversary')}
/>
<HomeAnniversaryAssetButton
reminder={homeAnniversaryReminder}
image={homeAnniversaryImage}
isEditing={isHomeLayoutEditing}
layout={homeLayout}
onLayoutChange={onHomeLayoutChange}
onOpen={() => onNavigate('anniversary')}
/>
</HomeLayoutBox>
<div aria-hidden="true" className="pointer-events-none absolute bottom-0 left-0 z-[5] h-[13%] w-full select-none overflow-hidden">
@@ -823,21 +823,21 @@ function HomeLayoutBox({
)
}
function HomeAnniversaryAssetButton({
image,
isEditing,
layout,
onLayoutChange,
onOpen,
reminder,
}: {
image: string
isEditing: boolean
layout: HomeLayout
onLayoutChange: (elementId: HomeLayoutElementId, rect: HomeLayoutRect) => void
onOpen: () => void
reminder: HomeAnniversaryReminder
}) {
function HomeAnniversaryAssetButton({
image,
isEditing,
layout,
onLayoutChange,
onOpen,
reminder,
}: {
image: string
isEditing: boolean
layout: HomeLayout
onLayoutChange: (elementId: HomeLayoutElementId, rect: HomeLayoutRect) => void
onOpen: () => void
reminder: HomeAnniversaryReminder
}) {
const frameRef = useRef<HTMLDivElement>(null)
const [hotspotSize, setHotspotSize] = useState<{ height: number; width: number } | null>(null)
@@ -850,10 +850,10 @@ function HomeAnniversaryAssetButton({
function updateHotspotSize() {
if (!frame) {
return
}
const rect = frame.getBoundingClientRect()
const imageRatio = homeAnniversaryAssetRatio
}
const rect = frame.getBoundingClientRect()
const imageRatio = homeAnniversaryAssetRatio
const frameRatio = rect.width / rect.height
if (!Number.isFinite(frameRatio) || rect.width <= 0 || rect.height <= 0) {
@@ -878,7 +878,7 @@ function HomeAnniversaryAssetButton({
observer.observe(frame)
return () => observer.disconnect()
}, [])
}, [])
return (
<div className="pointer-events-none relative h-full w-full" ref={frameRef}>
@@ -903,166 +903,166 @@ function HomeAnniversaryAssetButton({
}
type="button"
>
<img
alt=""
aria-hidden="true"
className="pointer-events-none block h-full w-full select-none object-fill drop-shadow-[0_10px_24px_rgba(3,12,35,0.24)]"
draggable={false}
src={image}
/>
<HomeAnniversaryTextBox
align="left"
elementId="anniversaryTitle"
isEditing={isEditing}
layout={layout}
onChange={onLayoutChange}
>
<span className="block max-h-full w-full max-w-full overflow-hidden text-left text-[10px] font-semibold leading-[1.45] tracking-[0.12em] text-white drop-shadow-[0_2px_8px_rgba(2,10,32,0.82)] [display:-webkit-box] [-webkit-box-orient:vertical] [-webkit-line-clamp:2]">
{reminder.title}
</span>
</HomeAnniversaryTextBox>
<HomeAnniversaryTextBox
elementId="anniversaryStatus"
isEditing={isEditing}
layout={layout}
onChange={onLayoutChange}
>
<span className="block max-w-full truncate text-[7px] font-semibold leading-none tracking-[0.18em] text-white drop-shadow-[0_2px_7px_rgba(2,10,32,0.85)]">
{reminder.statusLabel}
</span>
</HomeAnniversaryTextBox>
<HomeAnniversaryTextBox
className="[font-family:'Source_Han_Serif_SC','Noto_Serif_CJK_SC','思源宋体',serif]"
elementId="anniversaryDays"
isEditing={isEditing}
layout={layout}
onChange={onLayoutChange}
>
<span className="block max-w-full truncate bg-[linear-gradient(180deg,#f7fbff_0%,#d8ecff_42%,#8bbdff_100%)] bg-clip-text text-[20px] font-normal leading-none text-transparent drop-shadow-[0_4px_12px_rgba(2,10,32,0.82)]">
{reminder.days.toLocaleString('zh-CN')}
</span>
</HomeAnniversaryTextBox>
</button>
</div>
)
}
function HomeAnniversaryTextBox({
align = 'center',
children,
className = "[font-family:'Source_Han_Serif_SC','Noto_Serif_CJK_SC','思源宋体',serif]",
elementId,
isEditing,
layout,
onChange,
}: {
align?: 'center' | 'left'
children: ReactNode
className?: string
elementId: Extract<HomeLayoutElementId, 'anniversaryTitle' | 'anniversaryStatus' | 'anniversaryDays'>
isEditing: boolean
layout: HomeLayout
onChange: (elementId: HomeLayoutElementId, rect: HomeLayoutRect) => void
}) {
const rect = layout[elementId] ?? defaultHomeLayout[elementId]
function handlePointerDown(event: ReactPointerEvent<HTMLSpanElement>) {
if (!isEditing) {
return
}
const stage = event.currentTarget.parentElement
if (!stage) {
return
}
event.preventDefault()
event.stopPropagation()
const stageRect = stage.getBoundingClientRect()
const startX = event.clientX
const startY = event.clientY
const startLeft = rect.left
const startTop = rect.top
const target = event.currentTarget
target.setPointerCapture(event.pointerId)
function handlePointerMove(moveEvent: PointerEvent) {
const nextLeft = startLeft + ((moveEvent.clientX - startX) / stageRect.width) * 100
const nextTop = startTop + ((moveEvent.clientY - startY) / stageRect.height) * 100
onChange(elementId, {
...rect,
left: roundToTenth(nextLeft),
top: roundToTenth(nextTop),
})
}
function handlePointerUp() {
window.removeEventListener('pointermove', handlePointerMove)
window.removeEventListener('pointerup', handlePointerUp)
}
window.addEventListener('pointermove', handlePointerMove)
window.addEventListener('pointerup', handlePointerUp)
}
return (
<span
className={`absolute z-10 flex items-center justify-center overflow-visible text-center ${
isEditing
? 'pointer-events-auto cursor-move touch-none outline outline-1 outline-cyan-200/90'
: 'pointer-events-none'
} ${align === 'left' ? 'justify-start text-left' : ''} ${className}`}
onPointerDown={handlePointerDown}
style={{
height: `${rect.height}%`,
left: `${rect.left}%`,
top: `${rect.top}%`,
width: `${rect.width}%`,
}}
>
{isEditing ? (
<span className="pointer-events-none absolute -top-4 left-1/2 -translate-x-1/2 whitespace-nowrap rounded-full bg-sky-950/80 px-1.5 py-0.5 text-[7px] font-semibold leading-none text-cyan-50">
{`${rect.left.toFixed(1)}, ${rect.top.toFixed(1)} / ${rect.width.toFixed(1)}x${rect.height.toFixed(1)}`}
</span>
) : null}
{children}
</span>
)
}
function getHomeAnniversaryReminder(anniversaries: Anniversary[]): HomeAnniversaryReminder {
const upcomingAnniversary = anniversaries
.filter((item) => item.repeatYearly && item.reminderEnabled)
.map((item) => ({
anniversary: item,
days: getDaysLeft(item),
}))
.filter((item) => item.days <= 9)
.sort((a, b) => a.days - b.days)[0]
if (upcomingAnniversary) {
return {
days: upcomingAnniversary.days,
statusLabel: '还剩',
title: upcomingAnniversary.anniversary.title,
}
}
const joinDay = anniversaries.find((item) => item.type === 'join')
if (joinDay) {
return {
days: getElapsedDays(joinDay.date),
statusLabel: '已经',
title: '加入 DL.L9 粉丝团',
}
}
return defaultHomeAnniversaryReminder
}
function getResolvedHomeBackgroundMode(birthday: string | undefined, mode: HomeBackgroundMode) {
<img
alt=""
aria-hidden="true"
className="pointer-events-none block h-full w-full select-none object-fill drop-shadow-[0_10px_24px_rgba(3,12,35,0.24)]"
draggable={false}
src={image}
/>
<HomeAnniversaryTextBox
align="left"
elementId="anniversaryTitle"
isEditing={isEditing}
layout={layout}
onChange={onLayoutChange}
>
<span className="block max-h-full w-full max-w-full overflow-hidden text-left text-[10px] font-semibold leading-[1.45] tracking-[0.12em] text-white drop-shadow-[0_2px_8px_rgba(2,10,32,0.82)] [display:-webkit-box] [-webkit-box-orient:vertical] [-webkit-line-clamp:2]">
{reminder.title}
</span>
</HomeAnniversaryTextBox>
<HomeAnniversaryTextBox
elementId="anniversaryStatus"
isEditing={isEditing}
layout={layout}
onChange={onLayoutChange}
>
<span className="block max-w-full truncate text-[7px] font-semibold leading-none tracking-[0.18em] text-white drop-shadow-[0_2px_7px_rgba(2,10,32,0.85)]">
{reminder.statusLabel}
</span>
</HomeAnniversaryTextBox>
<HomeAnniversaryTextBox
className="[font-family:'Source_Han_Serif_SC','Noto_Serif_CJK_SC','思源宋体',serif]"
elementId="anniversaryDays"
isEditing={isEditing}
layout={layout}
onChange={onLayoutChange}
>
<span className="block max-w-full truncate bg-[linear-gradient(180deg,#f7fbff_0%,#d8ecff_42%,#8bbdff_100%)] bg-clip-text text-[20px] font-normal leading-none text-transparent drop-shadow-[0_4px_12px_rgba(2,10,32,0.82)]">
{reminder.days.toLocaleString('zh-CN')}
</span>
</HomeAnniversaryTextBox>
</button>
</div>
)
}
function HomeAnniversaryTextBox({
align = 'center',
children,
className = "[font-family:'Source_Han_Serif_SC','Noto_Serif_CJK_SC','思源宋体',serif]",
elementId,
isEditing,
layout,
onChange,
}: {
align?: 'center' | 'left'
children: ReactNode
className?: string
elementId: Extract<HomeLayoutElementId, 'anniversaryTitle' | 'anniversaryStatus' | 'anniversaryDays'>
isEditing: boolean
layout: HomeLayout
onChange: (elementId: HomeLayoutElementId, rect: HomeLayoutRect) => void
}) {
const rect = layout[elementId] ?? defaultHomeLayout[elementId]
function handlePointerDown(event: ReactPointerEvent<HTMLSpanElement>) {
if (!isEditing) {
return
}
const stage = event.currentTarget.parentElement
if (!stage) {
return
}
event.preventDefault()
event.stopPropagation()
const stageRect = stage.getBoundingClientRect()
const startX = event.clientX
const startY = event.clientY
const startLeft = rect.left
const startTop = rect.top
const target = event.currentTarget
target.setPointerCapture(event.pointerId)
function handlePointerMove(moveEvent: PointerEvent) {
const nextLeft = startLeft + ((moveEvent.clientX - startX) / stageRect.width) * 100
const nextTop = startTop + ((moveEvent.clientY - startY) / stageRect.height) * 100
onChange(elementId, {
...rect,
left: roundToTenth(nextLeft),
top: roundToTenth(nextTop),
})
}
function handlePointerUp() {
window.removeEventListener('pointermove', handlePointerMove)
window.removeEventListener('pointerup', handlePointerUp)
}
window.addEventListener('pointermove', handlePointerMove)
window.addEventListener('pointerup', handlePointerUp)
}
return (
<span
className={`absolute z-10 flex items-center justify-center overflow-visible text-center ${
isEditing
? 'pointer-events-auto cursor-move touch-none outline outline-1 outline-cyan-200/90'
: 'pointer-events-none'
} ${align === 'left' ? 'justify-start text-left' : ''} ${className}`}
onPointerDown={handlePointerDown}
style={{
height: `${rect.height}%`,
left: `${rect.left}%`,
top: `${rect.top}%`,
width: `${rect.width}%`,
}}
>
{isEditing ? (
<span className="pointer-events-none absolute -top-4 left-1/2 -translate-x-1/2 whitespace-nowrap rounded-full bg-sky-950/80 px-1.5 py-0.5 text-[7px] font-semibold leading-none text-cyan-50">
{`${rect.left.toFixed(1)}, ${rect.top.toFixed(1)} / ${rect.width.toFixed(1)}x${rect.height.toFixed(1)}`}
</span>
) : null}
{children}
</span>
)
}
function getHomeAnniversaryReminder(anniversaries: Anniversary[]): HomeAnniversaryReminder {
const upcomingAnniversary = anniversaries
.filter((item) => item.repeatYearly && item.reminderEnabled)
.map((item) => ({
anniversary: item,
days: getDaysLeft(item),
}))
.filter((item) => item.days <= 9)
.sort((a, b) => a.days - b.days)[0]
if (upcomingAnniversary) {
return {
days: upcomingAnniversary.days,
statusLabel: '还剩',
title: upcomingAnniversary.anniversary.title,
}
}
const joinDay = anniversaries.find((item) => item.type === 'join')
if (joinDay) {
return {
days: getElapsedDays(joinDay.date),
statusLabel: '已经',
title: '加入 DL.L9 粉丝团',
}
}
return defaultHomeAnniversaryReminder
}
function getResolvedHomeBackgroundMode(birthday: string | undefined, mode: HomeBackgroundMode) {
if (mode !== 'auto') {
return mode
}