a tool for shared writing and social publishing

rename has page loaded and switch logic

+13 -14
+2 -2
app/lish/[did]/[publication]/[rkey]/PublishBskyPostBlock.tsx
··· 7 7 import { focusBlock } from "src/utils/focusBlock"; 8 8 import { AppBskyFeedDefs, AppBskyFeedPost, RichText } from "@atproto/api"; 9 9 import { Separator } from "components/Layout"; 10 - import { useInitialPageLoad } from "components/InitialPageLoadProvider"; 10 + import { useHasPageLoaded } from "components/InitialPageLoadProvider"; 11 11 import { BlueskyTiny } from "components/Icons/BlueskyTiny"; 12 12 import { CommentTiny } from "components/Icons/CommentTiny"; 13 13 import { useLocalizedDate } from "src/hooks/useLocalizedDate"; ··· 123 123 }; 124 124 125 125 const ClientDate = (props: { date?: string }) => { 126 - let pageLoaded = useInitialPageLoad(); 126 + let pageLoaded = useHasPageLoaded(); 127 127 const formattedDate = useLocalizedDate( 128 128 props.date || new Date().toISOString(), 129 129 {
-1
components/Blocks/BlueskyPostBlock/index.tsx
··· 10 10 import { BlueskyPostEmpty } from "./BlueskyEmpty"; 11 11 import { BlueskyRichText } from "./BlueskyRichText"; 12 12 import { Separator } from "components/Layout"; 13 - import { useInitialPageLoad } from "components/InitialPageLoadProvider"; 14 13 import { BlueskyTiny } from "components/Icons/BlueskyTiny"; 15 14 import { CommentTiny } from "components/Icons/CommentTiny"; 16 15 import { useLocalizedDate } from "src/hooks/useLocalizedDate";
+2 -2
components/Blocks/DateTimeBlock.tsx
··· 8 8 import { setHours, setMinutes } from "date-fns"; 9 9 import { Separator } from "react-aria-components"; 10 10 import { Checkbox } from "components/Checkbox"; 11 - import { useInitialPageLoad } from "components/InitialPageLoadProvider"; 11 + import { useHasPageLoaded } from "components/InitialPageLoadProvider"; 12 12 import { useSpring, animated } from "@react-spring/web"; 13 13 import { ArrowRightTiny } from "components/Icons/ArrowRightTiny"; 14 14 import { BlockCalendarSmall } from "components/Icons/BlockCalendarSmall"; 15 15 16 16 export function DateTimeBlock(props: BlockProps) { 17 17 const [isClient, setIsClient] = useState(false); 18 - let initialPageLoad = useInitialPageLoad(); 18 + let initialPageLoad = useHasPageLoaded(); 19 19 20 20 useEffect(() => { 21 21 setIsClient(true);
+2 -2
components/Blocks/TextBlock/index.tsx
··· 4 4 import { isVisible } from "src/utils/isVisible"; 5 5 import { EditorState, TextSelection } from "prosemirror-state"; 6 6 import { RenderYJSFragment } from "./RenderYJSFragment"; 7 - import { useInitialPageLoad } from "components/InitialPageLoadProvider"; 7 + import { useHasPageLoaded } from "components/InitialPageLoadProvider"; 8 8 import { BlockProps } from "../Block"; 9 9 import { focusBlock } from "src/utils/focusBlock"; 10 10 import { useUIState } from "src/useUIState"; ··· 37 37 }, 38 38 ) { 39 39 let isLocked = useEntity(props.entityID, "block/is-locked"); 40 - let initialized = useInitialPageLoad(); 40 + let initialized = useHasPageLoaded(); 41 41 let first = props.previousBlock === null; 42 42 let permission = useEntitySetContext().permissions.write; 43 43
+2 -2
components/InitialPageLoadProvider.tsx
··· 2 2 import { useEffect } from "react"; 3 3 import { create } from "zustand"; 4 4 5 - export const useInitialPageLoad = create(() => false); 5 + export const useHasPageLoaded = create(() => false); 6 6 export function InitialPageLoad(props: { children: React.ReactNode }) { 7 7 useEffect(() => { 8 8 setTimeout(() => { 9 - useInitialPageLoad.setState(() => true); 9 + useHasPageLoaded.setState(() => true); 10 10 }, 80); 11 11 }, []); 12 12 return <>{props.children}</>;
+5 -5
src/hooks/useLocalizedDate.ts
··· 2 2 import { useContext, useMemo } from "react"; 3 3 import { DateTime } from "luxon"; 4 4 import { RequestHeadersContext } from "components/Providers/RequestHeadersProvider"; 5 - import { useInitialPageLoad } from "components/InitialPageLoadProvider"; 5 + import { useHasPageLoaded } from "components/InitialPageLoadProvider"; 6 6 7 7 /** 8 8 * Hook that formats a date string using Luxon with timezone and locale from request headers. ··· 20 20 options?: Intl.DateTimeFormatOptions, 21 21 ): string { 22 22 const { timezone, language } = useContext(RequestHeadersContext); 23 - const isInitialPageLoad = useInitialPageLoad(); 23 + const hasPageLoaded = useHasPageLoaded(); 24 24 25 25 return useMemo(() => { 26 26 // Parse the date string to Luxon DateTime 27 27 let dateTime = DateTime.fromISO(dateString); 28 28 29 29 // On initial page load, use header timezone. After hydration, use system timezone 30 - const effectiveTimezone = isInitialPageLoad 30 + const effectiveTimezone = !hasPageLoaded 31 31 ? timezone 32 32 : Intl.DateTimeFormat().resolvedOptions().timeZone; 33 33 ··· 39 39 // On initial page load, use header locale. After hydration, use system locale 40 40 // Parse locale from accept-language header (take first locale) 41 41 // accept-language format: "en-US,en;q=0.9,es;q=0.8" 42 - const effectiveLocale = isInitialPageLoad 42 + const effectiveLocale = !hasPageLoaded 43 43 ? language?.split(",")[0]?.split(";")[0]?.trim() || "en-US" 44 44 : Intl.DateTimeFormat().resolvedOptions().locale; 45 45 ··· 50 50 // Fallback to en-US if locale is invalid 51 51 return dateTime.toLocaleString(options, { locale: "en-US" }); 52 52 } 53 - }, [dateString, options, timezone, language, isInitialPageLoad]); 53 + }, [dateString, options, timezone, language, hasPageLoaded]); 54 54 }