feat: add puzzle residence configuration and reflection progress logic
- Introduced `puzzleResidences.ts` to define puzzle residence configurations including properties like display name, position, and puzzle availability. - Added `reflectionProgress.ts` to manage badge unlocking logic based on place completion, including functions to determine unlocked badges and video sources for scenes.
This commit is contained in:
1 parent
e0fa47d21a
commit
f5f36f75b5
153 files changed
+3846
-2352
No files matched your search
@@ -1,6 +1,6 @@
|
||||
import { getStaticImage, getBackgroundImage } from '@/lib/utils'
|
||||
import type { MouseEvent } from 'react'
|
||||
import { useEffect } from 'react'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useAudioManager } from '@/hooks/useAudioManager'
|
||||
|
||||
export interface SuccessAlertProps {
|
||||
@@ -42,6 +42,46 @@ const SuccessAlert = ({
|
||||
const { currentSrc, play, stop } = useAudioManager(
|
||||
audioChannelId ? { mode: 'channel', channelId: audioChannelId } : { mode: 'global' }
|
||||
)
|
||||
const contentRef = useRef<HTMLDivElement>(null)
|
||||
const [shouldIndent, setShouldIndent] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
const element = contentRef.current
|
||||
if (!element || !content) {
|
||||
setShouldIndent(false)
|
||||
return
|
||||
}
|
||||
|
||||
const lineHeight = Number.parseFloat(window.getComputedStyle(element).lineHeight)
|
||||
if (!lineHeight) {
|
||||
setShouldIndent(false)
|
||||
return
|
||||
}
|
||||
|
||||
setShouldIndent(element.scrollHeight - lineHeight > 1)
|
||||
}, [content, visible])
|
||||
|
||||
useEffect(() => {
|
||||
if (!content) return
|
||||
|
||||
const handleResize = () => {
|
||||
const element = contentRef.current
|
||||
if (!element) return
|
||||
|
||||
const lineHeight = Number.parseFloat(window.getComputedStyle(element).lineHeight)
|
||||
if (!lineHeight) {
|
||||
setShouldIndent(false)
|
||||
return
|
||||
}
|
||||
|
||||
setShouldIndent(element.scrollHeight - lineHeight > 1)
|
||||
}
|
||||
|
||||
window.addEventListener('resize', handleResize)
|
||||
return () => window.removeEventListener('resize', handleResize)
|
||||
}, [content])
|
||||
|
||||
const contentStyle = shouldIndent ? { textIndent: '2em' } : undefined
|
||||
|
||||
// 弹窗显示时自动播放音频
|
||||
useEffect(() => {
|
||||
@@ -105,7 +145,11 @@ const SuccessAlert = ({
|
||||
|
||||
{/* 内容文本 */}
|
||||
{content && (
|
||||
<div className="text-white text-4xl font-medium max-w-[1600px] leading-relaxed px-20">
|
||||
<div
|
||||
ref={contentRef}
|
||||
className="text-white text-4xl font-medium max-w-[1600px] leading-relaxed px-20"
|
||||
style={contentStyle}
|
||||
>
|
||||
{content}
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in new issue
Block a user