feat: 更新 ESLint 和 Prettier 配置,增强代码质量管理

- 在 .gitignore 中添加 public/audio/* 以忽略音频文件。
- 更新 bun.lock,添加 eslint-config-prettier 和 eslint-plugin-prettier 依赖,确保 ESLint 与 Prettier 的兼容性。
- 修改 eslint.config.ts,整合 Prettier 规则,优化代码风格一致性。
- 在 package.json 中添加 lint:fix 和 format 脚本,简化代码格式化和修复流程。
- 更新 tailwind.config.ts 和其他组件文件,统一代码风格,提升可读性。
This commit is contained in:
zhongyidian committed 2026-03-05 13:50:47 +08:00
1 parent 5d00adc1a5
commit 76c67b492e
216 files changed
+12454 -13976

No files matched your search

+49 -58
View File
@@ -1,22 +1,22 @@
import { useEffect, useState } from "react";
import { getStaticImage } from "@/lib/utils";
import { useAudioManager } from "@/hooks/useAudioManager";
import { useEffect, useState } from 'react'
import { getStaticImage } from '@/lib/utils'
import { useAudioManager } from '@/hooks/useAudioManager'
export interface EndingOverlayProps {
/** 是否可见 */
visible: boolean;
visible: boolean
/** 中间显示的文本内容 */
text: string;
text: string
/** 点击继续回调 */
onContinue: () => void;
onContinue: () => void
/** 文字动画速度(毫秒/字),默认 60ms */
animationSpeed?: number;
animationSpeed?: number
/** 结语对应的音频地址(可选) */
audioSrc?: string;
audioSrc?: string
/** 覆盖层出现时是否自动播放音频(默认 true) */
autoPlayAudio?: boolean;
autoPlayAudio?: boolean
/** 音频分组 id,相同 channel 内互斥,不同 channel 可同时播放;不传则全局互斥 */
audioChannelId?: string;
audioChannelId?: string
}
/**
@@ -32,62 +32,62 @@ export const EndingOverlay = ({
autoPlayAudio = true,
audioChannelId,
}: EndingOverlayProps) => {
const [displayedText, setDisplayedText] = useState("");
const [isAnimating, setIsAnimating] = useState(false);
const [displayedText, setDisplayedText] = useState('')
const [isAnimating, setIsAnimating] = useState(false)
// 结语音频:默认自动播放,支持按 channel 分组互斥
const { currentSrc, isPlaying, play, stop } = useAudioManager(
audioChannelId
? {
mode: "channel",
mode: 'channel',
channelId: audioChannelId,
}
: { mode: "global" }
);
: { mode: 'global' }
)
// 文字逐字动画
useEffect(() => {
if (!visible) {
setDisplayedText("");
setIsAnimating(false);
setDisplayedText('')
setIsAnimating(false)
// 结语关闭时,如果当前正在播放该结语音频,则停止
if (audioSrc && currentSrc === audioSrc) {
stop();
stop()
}
return;
return
}
let currentIndex = 0;
setDisplayedText("");
setIsAnimating(true);
let currentIndex = 0
setDisplayedText('')
setIsAnimating(true)
const timer = setInterval(() => {
if (currentIndex < text.length) {
setDisplayedText(text.slice(0, currentIndex + 1));
currentIndex++;
setDisplayedText(text.slice(0, currentIndex + 1))
currentIndex++
} else {
setIsAnimating(false);
clearInterval(timer);
setIsAnimating(false)
clearInterval(timer)
}
}, animationSpeed);
}, animationSpeed)
return () => clearInterval(timer);
}, [visible, text, animationSpeed, audioSrc, currentSrc, stop]);
return () => clearInterval(timer)
}, [visible, text, animationSpeed, audioSrc, currentSrc, stop])
// 覆盖层显示时自动播放音频
useEffect(() => {
if (!visible) return;
if (!autoPlayAudio) return;
if (!audioSrc) return;
if (!visible) return
if (!autoPlayAudio) return
if (!audioSrc) return
play(audioSrc);
}, [visible, autoPlayAudio, audioSrc, play]);
play(audioSrc)
}, [visible, autoPlayAudio, audioSrc, play])
// 全部文字出现后自动关闭(如果有音频,需等待音频播放完成)
useEffect(() => {
if (!visible) return;
if (isAnimating) return;
if (!text || displayedText !== text) return;
if (!visible) return
if (isAnimating) return
if (!text || displayedText !== text) return
// 如果有音频,需要等待音频播放完成
if (audioSrc) {
@@ -95,32 +95,23 @@ export const EndingOverlay = ({
if (currentSrc === audioSrc && !isPlaying) {
// 音频播放完成后,等待 800ms 再关闭
const timer = setTimeout(() => {
onContinue();
}, 800);
return () => clearTimeout(timer);
onContinue()
}, 800)
return () => clearTimeout(timer)
}
// 音频还在播放,等待播放完成
return;
return
}
// 没有音频,文字动画完成后等待 800ms 关闭
const timer = setTimeout(() => {
onContinue();
}, 800);
onContinue()
}, 800)
return () => clearTimeout(timer);
}, [
visible,
isAnimating,
displayedText,
text,
audioSrc,
currentSrc,
isPlaying,
onContinue,
]);
return () => clearTimeout(timer)
}, [visible, isAnimating, displayedText, text, audioSrc, currentSrc, isPlaying, onContinue])
if (!visible) return null;
if (!visible) return null
return (
<div className="fixed inset-0 z-[10000] flex items-center justify-center bg-transparent">
@@ -128,7 +119,7 @@ export const EndingOverlay = ({
<div
className="relative z-10 flex items-center max-w-full transition-all py-50 px-24 h-[825px] bg-cover bg-center bg-no-repeat"
style={{
backgroundImage: `url(${getStaticImage("components/overlay/bg")})`,
backgroundImage: `url(${getStaticImage('components/overlay/bg')})`,
}}
>
<div className="text-4xl leading-relaxed text-[#7b3f00] font-semibold tracking-wide">
@@ -139,5 +130,5 @@ export const EndingOverlay = ({
{/* <div className="mt-16 h-4 w-full bg-gradient-to-r from-transparent via-[rgba(0,0,0,0.35)] to-transparent rounded-full" /> */}
</div>
</div>
);
};
)
}