diff --git a/src/components/explore/ExploreLanding.tsx b/src/components/explore/ExploreLanding.tsx index 3dcb92a..d7bff7e 100644 --- a/src/components/explore/ExploreLanding.tsx +++ b/src/components/explore/ExploreLanding.tsx @@ -1,15 +1,46 @@ 'use client'; +import { useEffect, useState } from 'react'; import Link from 'next/link'; -import { Telescope } from 'lucide-react'; +import { Telescope, User } from 'lucide-react'; import AppearIn from './AppearIn'; import SearchBox from './SearchBox'; import JetstreamFeed from './JetstreamFeed'; import CrossLinkCards from '@/components/landing/CrossLinkCards'; +import { useAtprotoSession } from '@/components/AtprotoSessionProvider'; +import { getProfile, type AppViewProfile } from '@/utils/atproto/appview'; +import { encodeRepo } from '@/utils/atproto/urls'; const SUGGESTIONS = ['aturi.to', 'bsky.app', 'dame.is', 'jay.bsky.team']; export default function ExploreLanding() { + const { did } = useAtprotoSession(); + const [profile, setProfile] = useState(null); + + // Lazy-fetch profile so we can show the user's handle rather than the bare + // DID. The explorer route accepts both, so we render the DID immediately + // and upgrade to the prettier handle once it lands. + useEffect(() => { + if (!did) { + setProfile(null); + return undefined; + } + let cancelled = false; + getProfile(did).then((p) => { + if (!cancelled) setProfile(p); + }); + return () => { + cancelled = true; + }; + }, [did]); + + const myRepo = did ? profile?.handle || did : null; + // Avoid showing the user's handle twice when it happens to be one of the + // hard-coded examples. + const otherSuggestions = myRepo + ? SUGGESTIONS.filter((s) => s !== myRepo) + : SUGGESTIONS; + return (
@@ -67,7 +98,27 @@ export default function ExploreLanding() { }} > Try: - {SUGGESTIONS.map((s) => ( + {myRepo && ( + + {myRepo} + + )} + {otherSuggestions.map((s) => (