"use client"; import { useEffect, useMemo, useRef } from "react"; import Image from "next/image"; import { useRouter, useSearchParams } from "next/navigation"; import { CharacterAvatar } from "@/app/_components"; import { AppBottomNav, MobileShell } from "@/app/_components/core"; import { useAppNavigator } from "@/router/use-app-navigator"; import { useActiveCharacter, useActiveCharacterRoutes, } from "@/providers/character-provider"; import { isPrivateAlbumLocked } from "@/lib/private-room/private_album"; import { useAuthDispatch, useAuthState } from "@/stores/auth/auth-context"; import { usePrivateRoomDispatch, usePrivateRoomState, } from "@/stores/private-room"; import { PrivateAlbumCard, PrivateAlbumGallery, StatusCard, UnlockConfirmDialog, } from "./components"; import styles from "./private-room-screen.module.css"; import { isPrivateRoomAuthRequired, usePrivateRoomBootstrapFlow, usePrivateRoomUnlockPaywallNavigation, usePrivateRoomUnlockSuccessRefresh, } from "./use-private-room-flow"; import { buildPrivateAlbumGalleryUrl, buildPrivateRoomWithoutGalleryUrl, getPrivateAlbumGalleryState, } from "./private-album-gallery-url"; export function PrivateRoomScreen() { const router = useRouter(); const searchParams = useSearchParams(); const navigator = useAppNavigator(); const character = useActiveCharacter(); const characterRoutes = useActiveCharacterRoutes(); const authState = useAuthState(); const authDispatch = useAuthDispatch(); const state = usePrivateRoomState(); const dispatch = usePrivateRoomDispatch(); const openedGalleryInPageRef = useRef(false); const galleryState = useMemo( () => getPrivateAlbumGalleryState(searchParams), [searchParams], ); usePrivateRoomBootstrapFlow({ authDispatch, hasInitialized: authState.hasInitialized, isAuthLoading: authState.isLoading, loginStatus: authState.loginStatus, roomDispatch: dispatch, roomStatus: state.status, }); usePrivateRoomUnlockPaywallNavigation({ loginStatus: authState.loginStatus, roomDispatch: dispatch, unlockPaywallRequest: state.unlockPaywallRequest, }); usePrivateRoomUnlockSuccessRefresh(state.unlockSuccessNonce); const displayName = character.displayName; const avatarUrl = character.assets.avatar; const title = character.copy.privateRoomTitle; const subtitle = character.copy.privateRoomSubtitle; const pendingAlbum = useMemo( () => state.items.find( (album) => album.albumId === state.pendingConfirmAlbumId, ) ?? null, [state.items, state.pendingConfirmAlbumId], ); const galleryAlbum = useMemo( () => galleryState ? state.items.find((album) => album.albumId === galleryState.albumId) ?? null : null, [galleryState, state.items], ); useEffect(() => { if (!galleryState || state.isLoading) return; const image = galleryAlbum?.images[galleryState.imageIndex]; if ( !galleryAlbum || isPrivateAlbumLocked(galleryAlbum) || !image?.url ) { router.replace( buildPrivateRoomWithoutGalleryUrl( searchParams, characterRoutes.privateRoom, ), { scroll: false }, ); } }, [ characterRoutes.privateRoom, galleryAlbum, galleryState, router, searchParams, state.isLoading, ]); const handleTopUpClick = () => { if (isPrivateRoomAuthRequired(authState.loginStatus)) { navigator.openAuth(characterRoutes.privateRoom); return; } navigator.openSubscription({ type: "topup", returnTo: "private-room", analytics: { entryPoint: "private_room", triggerReason: "vip_cta", }, }); }; const handleOpenGallery = (albumId: string) => { openedGalleryInPageRef.current = true; router.push( buildPrivateAlbumGalleryUrl(albumId, 0, characterRoutes.privateRoom), { scroll: false }, ); }; const handleCloseGallery = () => { if (openedGalleryInPageRef.current) { openedGalleryInPageRef.current = false; router.back(); return; } router.replace( buildPrivateRoomWithoutGalleryUrl( searchParams, characterRoutes.privateRoom, ), { scroll: false }, ); }; const handleGalleryIndexChange = (imageIndex: number) => { if (!galleryAlbum) return; router.replace( buildPrivateAlbumGalleryUrl( galleryAlbum.albumId, imageIndex, characterRoutes.privateRoom, ), { scroll: false }, ); }; return (

{displayName}

Albums

Private albums

{state.items.length}
{state.errorMessage ? ( dispatch({ type: "PrivateRoomRefresh" })} /> ) : null} {state.isLoading && state.items.length === 0 ? ( ) : null} {!state.isLoading && state.items.length === 0 && !state.errorMessage ? ( dispatch({ type: "PrivateRoomRefresh" })} /> ) : null}
{state.items.map((album, index) => ( handleOpenGallery(album.albumId)} onUnlock={() => dispatch({ type: "PrivateRoomUnlockRequested", albumId: album.albumId, }) } /> ))}
navigator.push(characterRoutes.splash, { scroll: false }) } onPrivateRoomClick={() => undefined} /> {pendingAlbum ? ( dispatch({ type: "PrivateRoomUnlockCancelled" })} onConfirm={() => dispatch({ type: "PrivateRoomUnlockConfirmed" })} /> ) : state.unlockErrorMessage ? (
{state.unlockErrorMessage}
) : null} {galleryAlbum && galleryState && !isPrivateAlbumLocked(galleryAlbum) && galleryAlbum.images[galleryState.imageIndex]?.url ? ( ) : null}
); }