import { useNavigation } from "@react-navigation/native"; import { LivestreamProvider, Player, PlayerProvider, Text, Trans, useAvatars, useLivestreamStore, useTranslation, View, zero, } from "@streamplace/components"; import { overflow } from "@streamplace/components/src/lib/theme/atoms"; import { scrims } from "@streamplace/components/src/lib/theme/tokens"; import { Image } from "expo-image"; import { ChevronLeft } from "lucide-react-native"; import { memo, useEffect, useMemo, useState } from "react"; import { Platform, Pressable, useWindowDimensions } from "react-native"; import { useStore } from "../../store"; import FollowButton from "../follow-button"; import { DesktopUi } from "./desktop-ui"; const { bg, borders, flex, gap, h, layout, mt, position, px, py, r, text, w } = zero; interface SourceType { did: string; source: string; } export const UserOffline = memo(() => { console.log("rendering offline"); const { t } = useTranslation("common"); const navigation = useNavigation(); const profile = useLivestreamStore((x) => x.profile); const { width, height } = useWindowDimensions(); const { isSmallScreen, isLandscape, useCompactLayout } = useMemo(() => { const isSmall = width < 1250; const isLand = width > height; return { isSmallScreen: isSmall, isLandscape: isLand, useCompactLayout: isSmall && !isLand, }; }, [width, height]); const [recommendedSource, setRecommendedSource] = useState( null, ); const [isLoadingRecommendation, setIsLoadingRecommendation] = useState(false); const getRecommendations = useStore((state) => state.getRecommendations); const pfp = useAvatars(profile ? [profile?.did] : []); // use the detailed profile from useAvatars const detailedProfile = profile ? pfp[profile?.did] : null; useEffect(() => { if (!profile?.did) return; let mounted = true; const fetchRecommendation = async () => { setIsLoadingRecommendation(true); try { console.log("fetching recommendations for", profile.did); const result = await getRecommendations(profile.did); if (!mounted) return; if (result.recommendations && result.recommendations.length > 0) { // Get the first livestream recommendation const firstLivestream = result.recommendations.find( (rec) => rec.$type === "place.stream.live.getRecommendations#livestreamRecommendation", ); if (firstLivestream?.did) { setRecommendedSource({ did: firstLivestream.did, source: firstLivestream.source || "default", }); } } } catch (err) { console.error("failed to get recommendations", err); } finally { if (mounted) setIsLoadingRecommendation(false); } }; fetchRecommendation(); return () => { mounted = false; }; }, [profile?.did, getRecommendations]); if (!profile) { return ( {t("user-offline")} ); } if (!isLoadingRecommendation && !recommendedSource) { return ( {/* Back Button and Profile */} {Platform.OS !== "web" && ( { if (navigation.canGoBack()) { navigation.goBack(); } else { navigation.reset({ index: 0, routes: [ { name: "MainTabs", params: { screen: "Home" } }, ], }); } }} > {profile?.handle} )} {/* Banner Background */} {detailedProfile?.banner && ( )} ), br: , }} /> ); } return ( {/* Back Button and Profile */} {Platform.OS !== "web" && ( { if (navigation.canGoBack()) { navigation.goBack(); } else { navigation.reset({ index: 0, routes: [{ name: "MainTabs", params: { screen: "Home" } }], }); } }} > {profile?.handle} )} {/* Banner Background */} {detailedProfile?.banner && ( )} {recommendedSource && ( ), }} /> {isLoadingRecommendation ? ( {t("loading")} ) : ( )} {!isLoadingRecommendation && ( )} )} ); }); const RecommendedSourceInfo = memo(() => { const { t } = useTranslation("common"); const profile = useLivestreamStore((x) => x.profile); const viewers = useLivestreamStore((x) => x.viewers); const currentUserDID = useStore((state) => state.oauthSession?.did); const pfp = useAvatars(profile?.did ? [profile.did] : []); const detailedProfile = profile?.did ? pfp[profile.did] : null; return ( @{detailedProfile?.handle || profile?.handle} {t("viewer-count", { count: viewers || 0 })} {profile?.did && ( )} ); });