Live video on the AT Protocol

Add dynamic favicon, meta description, and use site title in navigation headers.

authored by

Natalie Bridgers and committed by
Natalie B.
ef89f887 850448e2

+44 -7
+3 -1
js/app/hooks/useTitle.tsx
··· 1 1 import { useNavigation } from "@react-navigation/native"; 2 + import { useBrandingAsset } from "@streamplace/components"; 2 3 import { useEffect } from "react"; 3 4 4 5 export default function useTitle(user: string) { 5 6 const navigation = useNavigation(); 7 + const title = useBrandingAsset("siteTitle")?.data || "Streamplace"; 6 8 useEffect(() => { 7 9 navigation.setOptions({ 8 - title: `@${user} on Streamplace`, 10 + title: `@${user} on ${title}`, 9 11 }); 10 12 }, [user, navigation]); 11 13 }
+10 -3
js/app/src/router.tsx
··· 15 15 useRoute, 16 16 } from "@react-navigation/native"; 17 17 import { createNativeStackNavigator } from "@react-navigation/native-stack"; 18 - import { Text, useTheme, useToast } from "@streamplace/components"; 18 + import { 19 + Text, 20 + useSiteTitle, 21 + useTheme, 22 + useToast, 23 + } from "@streamplace/components"; 19 24 import { Provider, Settings } from "components"; 20 25 import AQLink from "components/aqlink"; 21 26 import Login from "components/login/login"; ··· 395 400 const showLoginModal = useStore((state) => state.showLoginModal); 396 401 const closeLoginModal = useStore((state) => state.closeLoginModal); 397 402 const [livePopup, setLivePopup] = useState(false); 403 + const siteTitle = useSiteTitle(); 398 404 399 405 const sidebar = useSidebarControl(); 400 406 ··· 519 525 drawerLabel: () => <Text variant="h5">Home</Text>, 520 526 headerTitle: isWeb ? "Home" : "Streamplace", 521 527 headerShown: isWeb, 522 - title: "Streamplace", 528 + title: siteTitle, 523 529 }} 524 530 listeners={{ 525 531 drawerItemPress: (e) => { ··· 703 709 const MainTab = () => { 704 710 const theme = useTheme(); 705 711 const { isWeb } = usePlatform(); 712 + const siteTitle = useSiteTitle(); 706 713 return ( 707 714 <Stack.Navigator 708 715 initialRouteName="StreamList" ··· 717 724 <Stack.Screen 718 725 name="StreamList" 719 726 component={HomeScreen} 720 - options={{ headerTitle: "Streamplace", title: "Streamplace" }} 727 + options={{ headerTitle: siteTitle, title: siteTitle }} 721 728 /> 722 729 <Stack.Screen 723 730 name="Stream"
+31 -3
js/components/src/hooks/useDocumentTitle.tsx
··· 1 1 import { useEffect } from "react"; 2 2 import { Platform } from "react-native"; 3 - import { useSiteTitle } from "../streamplace-store"; 3 + import { 4 + useFavicon, 5 + useSiteDescription, 6 + useSiteTitle, 7 + } from "../streamplace-store"; 4 8 5 9 /** 6 - * Hook to set the document title on web based on branding. 10 + * Hook to set the document title, description, and favicon on web based on branding. 7 11 * No-op on native platforms. 8 12 */ 9 13 export function useDocumentTitle() { 10 14 const siteTitle = useSiteTitle(); 15 + const siteDescription = useSiteDescription(); 16 + const favicon = useFavicon(); 11 17 12 18 useEffect(() => { 13 19 if (Platform.OS === "web" && typeof document !== "undefined") { 20 + // set title 14 21 document.title = siteTitle; 22 + 23 + // set or update meta description 24 + let metaDescription = document.querySelector('meta[name="description"]'); 25 + if (!metaDescription) { 26 + metaDescription = document.createElement("meta"); 27 + metaDescription.setAttribute("name", "description"); 28 + document.head.appendChild(metaDescription); 29 + } 30 + metaDescription.setAttribute("content", siteDescription); 31 + 32 + // set or update favicon 33 + if (favicon) { 34 + let link: HTMLLinkElement | null = 35 + document.querySelector('link[rel="icon"]'); 36 + if (!link) { 37 + link = document.createElement("link"); 38 + link.rel = "icon"; 39 + document.head.appendChild(link); 40 + } 41 + link.href = favicon; 42 + } 15 43 } 16 - }, [siteTitle]); 44 + }, [siteTitle, siteDescription, favicon]); 17 45 }