feat(know-your-world): enhance hint audio and region name display
Audio hints now include the region name: - Speak "France. Located in Western Europe" instead of just "Located in Western Europe" - Applies to all hint speech triggers (manual, auto-speak, region change) Region name display is now more prominent: - Larger font size (2xl) - Pop-in animation when region changes - Subtle glow pulse animation on the prompt box - Target emoji (🎯) added to "Find" label - Improved styling with rounded corners and thicker border 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
81301ab148
commit
e6f58bfd93
|
|
@ -170,31 +170,48 @@ export function GameInfoPanel({
|
|||
className={css({
|
||||
flex: 1,
|
||||
textAlign: 'center',
|
||||
padding: '2',
|
||||
padding: '3',
|
||||
bg: isDark ? 'blue.900' : 'blue.50',
|
||||
rounded: 'md',
|
||||
border: '2px solid',
|
||||
rounded: 'xl',
|
||||
border: '3px solid',
|
||||
borderColor: 'blue.500',
|
||||
minWidth: 0, // Allow shrinking
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '1',
|
||||
})}
|
||||
style={{
|
||||
animation: 'glowPulse 2s ease-in-out infinite',
|
||||
}}
|
||||
>
|
||||
<style>{`
|
||||
@keyframes glowPulse {
|
||||
0%, 100% { box-shadow: 0 0 10px rgba(59, 130, 246, 0.3); }
|
||||
50% { box-shadow: 0 0 20px rgba(59, 130, 246, 0.6), 0 0 30px rgba(59, 130, 246, 0.3); }
|
||||
}
|
||||
@keyframes popIn {
|
||||
0% { transform: scale(0.8); opacity: 0; }
|
||||
50% { transform: scale(1.1); }
|
||||
100% { transform: scale(1); opacity: 1; }
|
||||
}
|
||||
`}</style>
|
||||
<div
|
||||
className={css({
|
||||
fontSize: '2xs',
|
||||
fontSize: 'xs',
|
||||
color: isDark ? 'blue.300' : 'blue.700',
|
||||
fontWeight: 'semibold',
|
||||
fontWeight: 'bold',
|
||||
textTransform: 'uppercase',
|
||||
letterSpacing: 'wide',
|
||||
})}
|
||||
>
|
||||
Find:
|
||||
🎯 Find
|
||||
</div>
|
||||
<div
|
||||
key={currentRegionId || 'empty'} // Re-trigger animation on change
|
||||
className={css({
|
||||
fontSize: 'lg',
|
||||
fontSize: '2xl',
|
||||
fontWeight: 'bold',
|
||||
color: isDark ? 'blue.100' : 'blue.900',
|
||||
color: isDark ? 'white' : 'blue.900',
|
||||
overflow: 'hidden',
|
||||
textOverflow: 'ellipsis',
|
||||
whiteSpace: 'nowrap',
|
||||
|
|
@ -203,8 +220,12 @@ export function GameInfoPanel({
|
|||
justifyContent: 'center',
|
||||
gap: '2',
|
||||
})}
|
||||
style={{
|
||||
animation: 'popIn 0.4s ease-out',
|
||||
textShadow: isDark ? '0 2px 4px rgba(0,0,0,0.3)' : 'none',
|
||||
}}
|
||||
>
|
||||
{flagEmoji && <span className={css({ fontSize: 'xl' })}>{flagEmoji}</span>}
|
||||
{flagEmoji && <span className={css({ fontSize: '2xl' })}>{flagEmoji}</span>}
|
||||
<span>{currentRegionName || '...'}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -494,6 +494,20 @@ export function MapRenderer({
|
|||
const hintText = useRegionHint(hintMapKey, currentPrompt)
|
||||
const hasHint = useHasRegionHint(hintMapKey, currentPrompt)
|
||||
|
||||
// Get the current region name for audio hints
|
||||
const currentRegionName = useMemo(() => {
|
||||
if (!currentPrompt) return null
|
||||
const region = mapData.regions.find((r) => r.id === currentPrompt)
|
||||
return region?.name ?? null
|
||||
}, [currentPrompt, mapData.regions])
|
||||
|
||||
// Create full hint text with region name prefix for speech
|
||||
const fullHintText = useMemo(() => {
|
||||
if (!hintText) return null
|
||||
if (!currentRegionName) return hintText
|
||||
return `${currentRegionName}. ${hintText}`
|
||||
}, [currentRegionName, hintText])
|
||||
|
||||
// Speech synthesis for reading hints aloud
|
||||
const {
|
||||
speak: speakHint,
|
||||
|
|
@ -585,10 +599,10 @@ export function MapRenderer({
|
|||
const handleSpeakClick = useCallback(() => {
|
||||
if (isSpeaking) {
|
||||
stopSpeaking()
|
||||
} else if (hintText) {
|
||||
speakHint(hintText, withAccent)
|
||||
} else if (fullHintText) {
|
||||
speakHint(fullHintText, withAccent)
|
||||
}
|
||||
}, [isSpeaking, stopSpeaking, hintText, speakHint, withAccent])
|
||||
}, [isSpeaking, stopSpeaking, fullHintText, speakHint, withAccent])
|
||||
|
||||
const speakButton = usePointerLockButton({
|
||||
id: 'speak-hint',
|
||||
|
|
@ -712,10 +726,10 @@ export function MapRenderer({
|
|||
const justOpened = showHintBubble && !prevShowHintBubbleRef.current
|
||||
prevShowHintBubbleRef.current = showHintBubble
|
||||
|
||||
if (justOpened && autoSpeak && hintText && isSpeechSupported) {
|
||||
speakHint(hintText, withAccent)
|
||||
if (justOpened && autoSpeak && fullHintText && isSpeechSupported) {
|
||||
speakHint(fullHintText, withAccent)
|
||||
}
|
||||
}, [showHintBubble, autoSpeak, hintText, isSpeechSupported, speakHint, withAccent])
|
||||
}, [showHintBubble, autoSpeak, fullHintText, isSpeechSupported, speakHint, withAccent])
|
||||
|
||||
// Track previous prompt to detect region changes
|
||||
const prevPromptRef = useRef<string | null>(null)
|
||||
|
|
@ -741,13 +755,13 @@ export function MapRenderer({
|
|||
setShowHintBubble(true)
|
||||
// If region changed and both auto-hint and auto-speak are enabled, speak immediately
|
||||
// This handles the case where the bubble was already open
|
||||
if (isNewRegion && autoSpeakRef.current && hintText && isSpeechSupported) {
|
||||
speakHint(hintText, withAccentRef.current)
|
||||
if (isNewRegion && autoSpeakRef.current && fullHintText && isSpeechSupported) {
|
||||
speakHint(fullHintText, withAccentRef.current)
|
||||
}
|
||||
} else {
|
||||
setShowHintBubble(false)
|
||||
}
|
||||
}, [currentPrompt, hasHint, hintText, isSpeechSupported, speakHint])
|
||||
}, [currentPrompt, hasHint, fullHintText, isSpeechSupported, speakHint])
|
||||
|
||||
// Hot/cold audio feedback hook
|
||||
// Only enabled if: 1) assistance level allows it, 2) user toggle is on, 3) not touch device
|
||||
|
|
|
|||
Loading…
Reference in New Issue