Polish museum path puzzle UX for homelab testing.
Add celebration overlay with Ted image, puzzle sounds, larger artifact thumbnails, and fix desktop artifact tray scrolling.
This commit is contained in:
@@ -15,6 +15,7 @@ dist-ssr
|
|||||||
# Local media copies (generated by scripts/setup-dev-media.sh)
|
# Local media copies (generated by scripts/setup-dev-media.sh)
|
||||||
public/media/unlock.mp4
|
public/media/unlock.mp4
|
||||||
public/media/artifact-room-map.jpg
|
public/media/artifact-room-map.jpg
|
||||||
|
public/media/ted-celebrate.png
|
||||||
public/media/artifacts/
|
public/media/artifacts/
|
||||||
public/media/celebration-pop.mp3
|
public/media/celebration-pop.mp3
|
||||||
public/media/celebration-horn.mp3
|
public/media/celebration-horn.mp3
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
"unlockVideoUrl": "/media/unlock.mp4",
|
"unlockVideoUrl": "/media/unlock.mp4",
|
||||||
"mapImageUrl": "/media/artifact-room-map.jpg",
|
"mapImageUrl": "/media/artifact-room-map.jpg",
|
||||||
|
"tedCelebrateImageUrl": "/media/ted-celebrate.png",
|
||||||
"incorrectUrl": "/media/incorrect.mp3",
|
"incorrectUrl": "/media/incorrect.mp3",
|
||||||
"unlockConfirmUrl": "/media/unlock-confirm.mp3",
|
"unlockConfirmUrl": "/media/unlock-confirm.mp3",
|
||||||
"celebrationPopUrl": "/media/celebration-pop.mp3",
|
"celebrationPopUrl": "/media/celebration-pop.mp3",
|
||||||
|
|||||||
@@ -26,6 +26,14 @@ cp "$INCORRECT_SOURCE" "$DEST_DIR/incorrect.mp3"
|
|||||||
cp "$CONFIRM_SOURCE" "$DEST_DIR/unlock-confirm.mp3"
|
cp "$CONFIRM_SOURCE" "$DEST_DIR/unlock-confirm.mp3"
|
||||||
python3 "$ROOT/scripts/extract-artifact-room-map.py" "$PDF_SOURCE" "$DEST_DIR/artifact-room-map.jpg"
|
python3 "$ROOT/scripts/extract-artifact-room-map.py" "$PDF_SOURCE" "$DEST_DIR/artifact-room-map.jpg"
|
||||||
python3 "$ROOT/scripts/extract-artifact-images.py" "$PDF_SOURCE" "$DEST_DIR/artifacts"
|
python3 "$ROOT/scripts/extract-artifact-images.py" "$PDF_SOURCE" "$DEST_DIR/artifacts"
|
||||||
|
TED_CELEBRATE_SOURCE="${TED_CELEBRATE_SOURCE:-$SOURCE_DIR/ted-celebrate.png}"
|
||||||
|
if [[ -f "$TED_CELEBRATE_SOURCE" ]]; then
|
||||||
|
cp "$TED_CELEBRATE_SOURCE" "$DEST_DIR/ted-celebrate.png"
|
||||||
|
elif [[ -f "$ROOT/public/media/ted-celebrate.png" ]]; then
|
||||||
|
cp "$ROOT/public/media/ted-celebrate.png" "$DEST_DIR/ted-celebrate.png"
|
||||||
|
else
|
||||||
|
echo "Warning: ted-celebrate.png not found; puzzle 2 celebration image will be missing" >&2
|
||||||
|
fi
|
||||||
cp "$ROOT/public/media/config.json.example" "$DEST_DIR/config.json"
|
cp "$ROOT/public/media/config.json.example" "$DEST_DIR/config.json"
|
||||||
|
|
||||||
echo "Copied media to $DEST_DIR/"
|
echo "Copied media to $DEST_DIR/"
|
||||||
|
|||||||
@@ -26,10 +26,19 @@ cp "$INCORRECT_SOURCE" "$DEST/incorrect.mp3"
|
|||||||
cp "$CONFIRM_SOURCE" "$DEST/unlock-confirm.mp3"
|
cp "$CONFIRM_SOURCE" "$DEST/unlock-confirm.mp3"
|
||||||
python3 "$ROOT/scripts/extract-artifact-room-map.py" "$PDF_SOURCE" "$DEST/artifact-room-map.jpg"
|
python3 "$ROOT/scripts/extract-artifact-room-map.py" "$PDF_SOURCE" "$DEST/artifact-room-map.jpg"
|
||||||
python3 "$ROOT/scripts/extract-artifact-images.py" "$PDF_SOURCE" "$DEST/artifacts"
|
python3 "$ROOT/scripts/extract-artifact-images.py" "$PDF_SOURCE" "$DEST/artifacts"
|
||||||
|
TED_CELEBRATE_SOURCE="${TED_CELEBRATE_SOURCE:-$SOURCE_DIR/ted-celebrate.png}"
|
||||||
|
if [[ -f "$TED_CELEBRATE_SOURCE" ]]; then
|
||||||
|
cp "$TED_CELEBRATE_SOURCE" "$DEST/ted-celebrate.png"
|
||||||
|
elif [[ -f "$ROOT/public/media/ted-celebrate.png" ]]; then
|
||||||
|
cp "$ROOT/public/media/ted-celebrate.png" "$DEST/ted-celebrate.png"
|
||||||
|
else
|
||||||
|
echo "Warning: ted-celebrate.png not found; puzzle 2 celebration image will be missing" >&2
|
||||||
|
fi
|
||||||
cat >"$DEST/config.json" <<'EOF'
|
cat >"$DEST/config.json" <<'EOF'
|
||||||
{
|
{
|
||||||
"unlockVideoUrl": "/media/unlock.mp4",
|
"unlockVideoUrl": "/media/unlock.mp4",
|
||||||
"mapImageUrl": "/media/artifact-room-map.jpg",
|
"mapImageUrl": "/media/artifact-room-map.jpg",
|
||||||
|
"tedCelebrateImageUrl": "/media/ted-celebrate.png",
|
||||||
"incorrectUrl": "/media/incorrect.mp3",
|
"incorrectUrl": "/media/incorrect.mp3",
|
||||||
"unlockConfirmUrl": "/media/unlock-confirm.mp3",
|
"unlockConfirmUrl": "/media/unlock-confirm.mp3",
|
||||||
"celebrationPopUrl": "/media/celebration-pop.mp3",
|
"celebrationPopUrl": "/media/celebration-pop.mp3",
|
||||||
|
|||||||
+128
-25
@@ -487,10 +487,15 @@
|
|||||||
|
|
||||||
.artifact-bank__grid {
|
.artifact-bank__grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fill, minmax(6.5rem, 1fr));
|
grid-template-columns: repeat(auto-fill, minmax(8.75rem, 1fr));
|
||||||
gap: 0.65rem;
|
gap: 0.75rem;
|
||||||
max-height: 28rem;
|
}
|
||||||
overflow-y: auto;
|
|
||||||
|
@media (max-width: 52rem) {
|
||||||
|
.artifact-bank__grid {
|
||||||
|
max-height: 28rem;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.path-slots {
|
.path-slots {
|
||||||
@@ -503,8 +508,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.65rem;
|
gap: 0.65rem;
|
||||||
min-height: 4.5rem;
|
min-height: 5.5rem;
|
||||||
padding: 0.5rem 0.65rem;
|
padding: 0.55rem 0.75rem;
|
||||||
background: linear-gradient(180deg, #2a2218 0%, #1f1a14 100%);
|
background: linear-gradient(180deg, #2a2218 0%, #1f1a14 100%);
|
||||||
border: 2px solid #4a3f32;
|
border: 2px solid #4a3f32;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
@@ -561,7 +566,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.artifact-card--overlay {
|
.artifact-card--overlay {
|
||||||
width: 6.5rem;
|
width: 8.75rem;
|
||||||
opacity: 0.95;
|
opacity: 0.95;
|
||||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
|
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.5);
|
||||||
cursor: grabbing;
|
cursor: grabbing;
|
||||||
@@ -575,8 +580,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.artifact-card__image {
|
.artifact-card__image {
|
||||||
width: 3.25rem;
|
width: 5rem;
|
||||||
height: 3.25rem;
|
height: 5rem;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
@@ -584,12 +589,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.path-slot .artifact-card__image {
|
.path-slot .artifact-card__image {
|
||||||
width: 2.75rem;
|
width: 4rem;
|
||||||
height: 2.75rem;
|
height: 4rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.artifact-card--overlay .artifact-card__image {
|
||||||
|
width: 5rem;
|
||||||
|
height: 5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.artifact-card__name {
|
.artifact-card__name {
|
||||||
font-size: 0.78rem;
|
font-size: 0.85rem;
|
||||||
line-height: 1.25;
|
line-height: 1.25;
|
||||||
color: #f4e4bc;
|
color: #f4e4bc;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@@ -605,17 +615,110 @@
|
|||||||
margin-top: 0.25rem;
|
margin-top: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.museum-path__success {
|
.museum-path-panel--fade-out {
|
||||||
margin: 0.25rem 0 0;
|
opacity: 0;
|
||||||
padding: 0.85rem 1.25rem;
|
transform: scale(0.98);
|
||||||
font-family: Cinzel, Georgia, serif;
|
pointer-events: none;
|
||||||
font-size: 1.1rem;
|
transition:
|
||||||
font-weight: 600;
|
opacity 0.65s ease-out,
|
||||||
letter-spacing: 0.04em;
|
transform 0.65s ease-out;
|
||||||
color: #e8c547;
|
}
|
||||||
text-align: center;
|
|
||||||
background: rgba(92, 68, 28, 0.5);
|
.museum-path-celebration {
|
||||||
border: 1px solid rgba(201, 162, 39, 0.55);
|
position: fixed;
|
||||||
border-radius: 0.5rem;
|
inset: 0;
|
||||||
animation: error-pop 0.25s ease-out;
|
z-index: 200;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.museum-path-celebration--fade-in {
|
||||||
|
opacity: 0;
|
||||||
|
animation: museum-celebration-in 0.9s ease-out 0.35s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes museum-celebration-in {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.museum-path-celebration__bg {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
object-position: center top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.museum-path-celebration__scrim {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: linear-gradient(
|
||||||
|
180deg,
|
||||||
|
rgba(26, 21, 16, 0.35) 0%,
|
||||||
|
rgba(26, 21, 16, 0.55) 45%,
|
||||||
|
rgba(26, 21, 16, 0.72) 100%
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
.museum-path-celebration__content {
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
max-width: 36rem;
|
||||||
|
margin: 0 1.5rem;
|
||||||
|
padding: 2rem 2.25rem;
|
||||||
|
text-align: center;
|
||||||
|
background: rgba(45, 36, 25, 0.72);
|
||||||
|
border: 3px solid #c9a227;
|
||||||
|
border-radius: 1rem;
|
||||||
|
box-shadow:
|
||||||
|
inset 0 0 0 1px rgba(232, 197, 71, 0.35),
|
||||||
|
0 16px 48px rgba(0, 0, 0, 0.5);
|
||||||
|
animation: museum-celebration-content-in 0.8s ease-out 0.7s both;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes museum-celebration-content-in {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(1.25rem) scale(0.96);
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0) scale(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.museum-path-celebration__eyebrow {
|
||||||
|
margin: 0 0 0.65rem;
|
||||||
|
font-family: Cinzel, Georgia, serif;
|
||||||
|
font-size: clamp(1rem, 2.5vw, 1.2rem);
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.14em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: #e8c547;
|
||||||
|
}
|
||||||
|
|
||||||
|
.museum-path-celebration__title {
|
||||||
|
margin: 0 0 0.85rem;
|
||||||
|
font-family: Cinzel, Georgia, serif;
|
||||||
|
font-size: clamp(2rem, 6vw, 3rem);
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.15;
|
||||||
|
letter-spacing: 0.04em;
|
||||||
|
color: #f4e4bc;
|
||||||
|
text-shadow: 0 2px 12px rgba(0, 0, 0, 0.45);
|
||||||
|
}
|
||||||
|
|
||||||
|
.museum-path-celebration__subtitle {
|
||||||
|
margin: 0;
|
||||||
|
font-size: clamp(1rem, 2.5vw, 1.15rem);
|
||||||
|
line-height: 1.45;
|
||||||
|
color: #c9b896;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
interface MuseumPathCelebrationProps {
|
||||||
|
imageUrl: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function MuseumPathCelebration({ imageUrl }: MuseumPathCelebrationProps) {
|
||||||
|
return (
|
||||||
|
<div className="museum-path-celebration museum-path-celebration--fade-in" role="status">
|
||||||
|
<img
|
||||||
|
className="museum-path-celebration__bg"
|
||||||
|
src={encodeURI(imageUrl)}
|
||||||
|
alt=""
|
||||||
|
aria-hidden="true"
|
||||||
|
/>
|
||||||
|
<div className="museum-path-celebration__scrim" aria-hidden="true" />
|
||||||
|
<div className="museum-path-celebration__content">
|
||||||
|
<p className="museum-path-celebration__eyebrow">You did it!</p>
|
||||||
|
<h1 className="museum-path-celebration__title">Ted escaped the museum!</h1>
|
||||||
|
<p className="museum-path-celebration__subtitle">You found the right path through the displays.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
+23
-15
@@ -13,12 +13,15 @@ import {
|
|||||||
import { CSS } from '@dnd-kit/utilities';
|
import { CSS } from '@dnd-kit/utilities';
|
||||||
import confetti from 'canvas-confetti';
|
import confetti from 'canvas-confetti';
|
||||||
import { useCallback, useMemo, useState } from 'react';
|
import { useCallback, useMemo, useState } from 'react';
|
||||||
|
import { playCelebrationSounds, playIncorrectSound } from './mediaSounds';
|
||||||
import { CORRECT_PATH, SLOT_COUNT } from './puzzle2Config';
|
import { CORRECT_PATH, SLOT_COUNT } from './puzzle2Config';
|
||||||
import {
|
import {
|
||||||
artifactImageUrl,
|
artifactImageUrl,
|
||||||
useArtifactManifest,
|
useArtifactManifest,
|
||||||
type ArtifactEntry,
|
type ArtifactEntry,
|
||||||
} from './useArtifactManifest';
|
} from './useArtifactManifest';
|
||||||
|
import { MuseumPathCelebration } from './MuseumPathCelebration';
|
||||||
|
import { useMediaConfig } from './useMediaConfig';
|
||||||
|
|
||||||
type DropZoneId = 'bank' | `slot-${number}`;
|
type DropZoneId = 'bank' | `slot-${number}`;
|
||||||
|
|
||||||
@@ -153,6 +156,7 @@ function PathSlot({ index, artifact }: { index: number; artifact: ArtifactEntry
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function MuseumPathPuzzle() {
|
export function MuseumPathPuzzle() {
|
||||||
|
const mediaConfig = useMediaConfig();
|
||||||
const manifest = useArtifactManifest();
|
const manifest = useArtifactManifest();
|
||||||
const [slots, setSlots] = useState<(string | null)[]>(() => Array(SLOT_COUNT).fill(null));
|
const [slots, setSlots] = useState<(string | null)[]>(() => Array(SLOT_COUNT).fill(null));
|
||||||
const [activeSlug, setActiveSlug] = useState<string | null>(null);
|
const [activeSlug, setActiveSlug] = useState<string | null>(null);
|
||||||
@@ -214,12 +218,14 @@ export function MuseumPathPuzzle() {
|
|||||||
if (phase !== 'playing') return;
|
if (phase !== 'playing') return;
|
||||||
|
|
||||||
if (!isPathCorrect(slots)) {
|
if (!isPathCorrect(slots)) {
|
||||||
|
playIncorrectSound(mediaConfig.incorrectUrl);
|
||||||
triggerJiggle();
|
triggerJiggle();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setShowError(false);
|
setShowError(false);
|
||||||
setPhase('solved');
|
setPhase('solved');
|
||||||
|
playCelebrationSounds(mediaConfig);
|
||||||
|
|
||||||
const confettiColors = ['#e8c547', '#c9a227', '#f4e4bc', '#d4a84b'];
|
const confettiColors = ['#e8c547', '#c9a227', '#f4e4bc', '#d4a84b'];
|
||||||
const duration = 2000;
|
const duration = 2000;
|
||||||
@@ -245,7 +251,7 @@ export function MuseumPathPuzzle() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
frame();
|
frame();
|
||||||
}, [phase, slots, triggerJiggle]);
|
}, [mediaConfig, phase, slots, triggerJiggle]);
|
||||||
|
|
||||||
if (!manifest) {
|
if (!manifest) {
|
||||||
return (
|
return (
|
||||||
@@ -261,7 +267,14 @@ export function MuseumPathPuzzle() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="museum-path-scene">
|
<div className="museum-path-scene">
|
||||||
<div className="sarcophagus-panel museum-path-panel">
|
{phase === 'solved' && (
|
||||||
|
<MuseumPathCelebration imageUrl={mediaConfig.tedCelebrateImageUrl} />
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={`sarcophagus-panel museum-path-panel ${phase === 'solved' ? 'museum-path-panel--fade-out' : ''}`}
|
||||||
|
aria-hidden={phase === 'solved'}
|
||||||
|
>
|
||||||
<header className="lock-header museum-path__header">
|
<header className="lock-header museum-path__header">
|
||||||
<h1>Museum Path</h1>
|
<h1>Museum Path</h1>
|
||||||
<p className="lock-subtitle">
|
<p className="lock-subtitle">
|
||||||
@@ -296,19 +309,14 @@ export function MuseumPathPuzzle() {
|
|||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{phase === 'solved' ? (
|
<button
|
||||||
<p className="museum-path__success" role="status">
|
type="button"
|
||||||
You found the path! Ted escaped the museum!
|
className={`unlock-btn museum-path__check ${jiggle ? 'unlock-btn--jiggle' : ''}`}
|
||||||
</p>
|
onClick={handleCheckPath}
|
||||||
) : (
|
disabled={phase === 'solved'}
|
||||||
<button
|
>
|
||||||
type="button"
|
CHECK PATH
|
||||||
className={`unlock-btn museum-path__check ${jiggle ? 'unlock-btn--jiggle' : ''}`}
|
</button>
|
||||||
onClick={handleCheckPath}
|
|
||||||
>
|
|
||||||
CHECK PATH
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
export interface MediaConfig {
|
export interface MediaConfig {
|
||||||
unlockVideoUrl: string;
|
unlockVideoUrl: string;
|
||||||
mapImageUrl: string;
|
mapImageUrl: string;
|
||||||
|
tedCelebrateImageUrl: string;
|
||||||
incorrectUrl: string;
|
incorrectUrl: string;
|
||||||
unlockConfirmUrl: string;
|
unlockConfirmUrl: string;
|
||||||
celebrationPopUrl: string;
|
celebrationPopUrl: string;
|
||||||
@@ -11,6 +12,7 @@ export interface MediaConfig {
|
|||||||
export const DEFAULT_MEDIA_CONFIG: MediaConfig = {
|
export const DEFAULT_MEDIA_CONFIG: MediaConfig = {
|
||||||
unlockVideoUrl: '/media/unlock.mp4',
|
unlockVideoUrl: '/media/unlock.mp4',
|
||||||
mapImageUrl: '/media/artifact-room-map.jpg',
|
mapImageUrl: '/media/artifact-room-map.jpg',
|
||||||
|
tedCelebrateImageUrl: '/media/ted-celebrate.png',
|
||||||
incorrectUrl: '/media/incorrect.mp3',
|
incorrectUrl: '/media/incorrect.mp3',
|
||||||
unlockConfirmUrl: '/media/unlock-confirm.mp3',
|
unlockConfirmUrl: '/media/unlock-confirm.mp3',
|
||||||
celebrationPopUrl: '/media/celebration-pop.mp3',
|
celebrationPopUrl: '/media/celebration-pop.mp3',
|
||||||
@@ -23,6 +25,8 @@ export function mergeMediaConfig(partial: Partial<MediaConfig> | null): MediaCon
|
|||||||
return {
|
return {
|
||||||
unlockVideoUrl: partial.unlockVideoUrl ?? DEFAULT_MEDIA_CONFIG.unlockVideoUrl,
|
unlockVideoUrl: partial.unlockVideoUrl ?? DEFAULT_MEDIA_CONFIG.unlockVideoUrl,
|
||||||
mapImageUrl: partial.mapImageUrl ?? DEFAULT_MEDIA_CONFIG.mapImageUrl,
|
mapImageUrl: partial.mapImageUrl ?? DEFAULT_MEDIA_CONFIG.mapImageUrl,
|
||||||
|
tedCelebrateImageUrl:
|
||||||
|
partial.tedCelebrateImageUrl ?? DEFAULT_MEDIA_CONFIG.tedCelebrateImageUrl,
|
||||||
incorrectUrl: partial.incorrectUrl ?? DEFAULT_MEDIA_CONFIG.incorrectUrl,
|
incorrectUrl: partial.incorrectUrl ?? DEFAULT_MEDIA_CONFIG.incorrectUrl,
|
||||||
unlockConfirmUrl: partial.unlockConfirmUrl ?? DEFAULT_MEDIA_CONFIG.unlockConfirmUrl,
|
unlockConfirmUrl: partial.unlockConfirmUrl ?? DEFAULT_MEDIA_CONFIG.unlockConfirmUrl,
|
||||||
celebrationPopUrl: partial.celebrationPopUrl ?? DEFAULT_MEDIA_CONFIG.celebrationPopUrl,
|
celebrationPopUrl: partial.celebrationPopUrl ?? DEFAULT_MEDIA_CONFIG.celebrationPopUrl,
|
||||||
|
|||||||
Reference in New Issue
Block a user