a tool for shared writing and social publishing

refactored cardBorderHidden into a context in ThemeProvider and a hook

+159 -148
+1 -3
app/(home-pages)/discover/page.tsx
··· 17 17 return ( 18 18 <DashboardLayout 19 19 id="discover" 20 - cardBorderHidden={false} 21 20 currentPage="discover" 22 21 defaultTab="default" 23 22 actions={null} ··· 32 31 } 33 32 34 33 const DiscoverContent = async (props: { order: string }) => { 35 - const orderValue = 36 - props.order === "popular" ? "popular" : "recentlyUpdated"; 34 + const orderValue = props.order === "popular" ? "popular" : "recentlyUpdated"; 37 35 let { publications, nextCursor } = await getPublications(orderValue); 38 36 39 37 return (
-8
app/(home-pages)/home/HomeLayout.tsx
··· 20 20 useDashboardState, 21 21 } from "components/PageLayouts/DashboardLayout"; 22 22 import { Actions } from "./Actions/Actions"; 23 - import { useCardBorderHidden } from "components/Pages/useCardBorderHidden"; 24 23 import { GetLeafletDataReturnType } from "app/api/rpc/[command]/get_leaflet_data"; 25 24 import { useState } from "react"; 26 25 import { useDebouncedEffect } from "src/hooks/useDebouncedEffect"; ··· 56 55 props.entityID, 57 56 "theme/background-image", 58 57 ); 59 - let cardBorderHidden = !!useCardBorderHidden(props.entityID); 60 58 61 59 let [searchValue, setSearchValue] = useState(""); 62 60 let [debouncedSearchValue, setDebouncedSearchValue] = useState(""); ··· 81 79 return ( 82 80 <DashboardLayout 83 81 id="home" 84 - cardBorderHidden={cardBorderHidden} 85 82 currentPage="home" 86 83 defaultTab="home" 87 84 actions={<Actions />} ··· 101 98 <HomeLeafletList 102 99 titles={props.titles} 103 100 initialFacts={props.initialFacts} 104 - cardBorderHidden={cardBorderHidden} 105 101 searchValue={debouncedSearchValue} 106 102 /> 107 103 ), ··· 117 113 [root_entity: string]: Fact<Attribute>[]; 118 114 }; 119 115 searchValue: string; 120 - cardBorderHidden: boolean; 121 116 }) { 122 117 let { identity } = useIdentityData(); 123 118 let { data: initialFacts } = useSWR( ··· 171 166 searchValue={props.searchValue} 172 167 leaflets={leaflets} 173 168 titles={initialFacts?.titles || {}} 174 - cardBorderHidden={props.cardBorderHidden} 175 169 initialFacts={initialFacts?.facts || {}} 176 170 showPreview 177 171 /> ··· 192 186 [root_entity: string]: Fact<Attribute>[]; 193 187 }; 194 188 searchValue: string; 195 - cardBorderHidden: boolean; 196 189 showPreview?: boolean; 197 190 }) { 198 191 let { identity } = useIdentityData(); ··· 238 231 loggedIn={!!identity} 239 232 display={display} 240 233 added_at={added_at} 241 - cardBorderHidden={props.cardBorderHidden} 242 234 index={index} 243 235 showPreview={props.showPreview} 244 236 isHidden={
+6 -5
app/(home-pages)/home/LeafletList/LeafletListItem.tsx
··· 4 4 import { useState, useRef, useEffect } from "react"; 5 5 import { SpeedyLink } from "components/SpeedyLink"; 6 6 import { useLeafletPublicationStatus } from "components/PageSWRDataProvider"; 7 + import { useCardBorderHidden } from "components/Pages/useCardBorderHidden"; 7 8 8 9 export const LeafletListItem = (props: { 9 10 archived?: boolean | null; 10 11 loggedIn: boolean; 11 12 display: "list" | "grid"; 12 - cardBorderHidden: boolean; 13 13 added_at: string; 14 14 title?: string; 15 15 index: number; 16 16 isHidden: boolean; 17 17 showPreview?: boolean; 18 18 }) => { 19 + const cardBorderHidden = useCardBorderHidden(); 19 20 const pubStatus = useLeafletPublicationStatus(); 20 21 let [isOnScreen, setIsOnScreen] = useState(props.index < 16 ? true : false); 21 22 let previewRef = useRef<HTMLDivElement | null>(null); ··· 47 48 ref={previewRef} 48 49 className={`relative flex gap-3 w-full 49 50 ${props.isHidden ? "hidden" : "flex"} 50 - ${props.cardBorderHidden ? "" : "px-2 py-1 block-border hover:outline-border relative"}`} 51 + ${cardBorderHidden ? "" : "px-2 py-1 block-border hover:outline-border relative"}`} 51 52 style={{ 52 - backgroundColor: props.cardBorderHidden 53 + backgroundColor: cardBorderHidden 53 54 ? "transparent" 54 55 : "rgba(var(--bg-page), var(--bg-page-alpha))", 55 56 }} ··· 67 68 loggedIn={props.loggedIn} 68 69 /> 69 70 </div> 70 - {props.cardBorderHidden && ( 71 + {cardBorderHidden && ( 71 72 <hr 72 73 className="last:hidden border-border-light" 73 74 style={{ ··· 87 88 ${props.isHidden ? "hidden" : "flex"} 88 89 `} 89 90 style={{ 90 - backgroundColor: props.cardBorderHidden 91 + backgroundColor: cardBorderHidden 91 92 ? "transparent" 92 93 : "rgba(var(--bg-page), var(--bg-page-alpha))", 93 94 }}
+16 -4
app/(home-pages)/home/LeafletList/LeafletPreview.tsx
··· 18 18 const firstPage = useEntity(root, "root/page")[0]; 19 19 const page = firstPage?.data.value || root; 20 20 21 - const cardBorderHidden = useCardBorderHidden(root); 21 + const cardBorderHidden = useEntity(root, "theme/card-border-hidden")?.data 22 + .value; 22 23 const rootBackgroundImage = useEntity(root, "theme/card-background-image"); 23 24 const rootBackgroundRepeat = useEntity( 24 25 root, ··· 49 50 50 51 const contentWrapperClass = `leafletContentWrapper h-full sm:w-48 w-40 mx-auto overflow-clip ${!cardBorderHidden && "border border-border-light border-b-0 rounded-t-md"}`; 51 52 52 - return { root, page, cardBorderHidden, contentWrapperStyle, contentWrapperClass }; 53 + return { 54 + root, 55 + page, 56 + cardBorderHidden, 57 + contentWrapperStyle, 58 + contentWrapperClass, 59 + }; 53 60 } 54 61 55 62 export const LeafletListPreview = (props: { isVisible: boolean }) => { 56 - const { root, page, cardBorderHidden, contentWrapperStyle, contentWrapperClass } = 57 - useLeafletPreviewData(); 63 + const { 64 + root, 65 + page, 66 + cardBorderHidden, 67 + contentWrapperStyle, 68 + contentWrapperClass, 69 + } = useLeafletPreviewData(); 58 70 59 71 return ( 60 72 <Tooltip
-6
app/(home-pages)/looseleafs/LooseleafsLayout.tsx
··· 1 1 "use client"; 2 2 import { DashboardLayout } from "components/PageLayouts/DashboardLayout"; 3 - import { useCardBorderHidden } from "components/Pages/useCardBorderHidden"; 4 3 import { useState } from "react"; 5 4 import { useDebouncedEffect } from "src/hooks/useDebouncedEffect"; 6 5 import { Fact, PermissionToken } from "src/replicache"; ··· 30 29 [searchValue], 31 30 ); 32 31 33 - let cardBorderHidden = !!useCardBorderHidden(props.entityID); 34 32 return ( 35 33 <DashboardLayout 36 34 id="looseleafs" 37 - cardBorderHidden={cardBorderHidden} 38 35 currentPage="looseleafs" 39 36 defaultTab="home" 40 37 actions={<Actions />} ··· 45 42 <LooseleafList 46 43 titles={props.titles} 47 44 initialFacts={props.initialFacts} 48 - cardBorderHidden={cardBorderHidden} 49 45 searchValue={debouncedSearchValue} 50 46 /> 51 47 ), ··· 61 57 [root_entity: string]: Fact<Attribute>[]; 62 58 }; 63 59 searchValue: string; 64 - cardBorderHidden: boolean; 65 60 }) => { 66 61 let { identity } = useIdentityData(); 67 62 let { data: initialFacts } = useSWR( ··· 108 103 searchValue={props.searchValue} 109 104 leaflets={leaflets} 110 105 titles={initialFacts?.titles || {}} 111 - cardBorderHidden={props.cardBorderHidden} 112 106 initialFacts={initialFacts?.facts || {}} 113 107 showPreview 114 108 />
-1
app/(home-pages)/notifications/page.tsx
··· 10 10 return ( 11 11 <DashboardLayout 12 12 id="discover" 13 - cardBorderHidden={true} 14 13 currentPage="notifications" 15 14 defaultTab="default" 16 15 actions={null}
-1
app/(home-pages)/reader/page.tsx
··· 12 12 return ( 13 13 <DashboardLayout 14 14 id="reader" 15 - cardBorderHidden={false} 16 15 currentPage="reader" 17 16 defaultTab="Read" 18 17 actions={null}
-1
app/(home-pages)/tag/[tag]/page.tsx
··· 14 14 return ( 15 15 <DashboardLayout 16 16 id="tag" 17 - cardBorderHidden={false} 18 17 currentPage="tag" 19 18 defaultTab="default" 20 19 actions={null}
-1
app/lish/[did]/[publication]/[rkey]/CanvasPage.tsx
··· 57 57 <PageWrapper 58 58 pageType="canvas" 59 59 fullPageScroll={fullPageScroll} 60 - cardBorderHidden={!hasPageBackground} 61 60 id={pageId ? `post-page-${pageId}` : "post-page"} 62 61 drawerOpen={ 63 62 !!drawer && (pageId ? drawer.pageId === pageId : !drawer.pageId)
-1
app/lish/[did]/[publication]/[rkey]/LinearDocumentPage.tsx
··· 61 61 <PageWrapper 62 62 pageType="doc" 63 63 fullPageScroll={fullPageScroll} 64 - cardBorderHidden={!hasPageBackground} 65 64 id={pageId ? `post-page-${pageId}` : "post-page"} 66 65 drawerOpen={ 67 66 !!drawer && (pageId ? drawer.pageId === pageId : !drawer.pageId)
+1 -4
app/lish/[did]/[publication]/[rkey]/PostPages.tsx
··· 290 290 absolute sm:-right-[20px] right-3 sm:top-3 top-0 291 291 flex sm:flex-col flex-row-reverse gap-1 items-start`} 292 292 > 293 - <PageOptionButton 294 - cardBorderHidden={!props.hasPageBackground} 295 - onClick={props.onClick} 296 - > 293 + <PageOptionButton onClick={props.onClick}> 297 294 <CloseTiny /> 298 295 </PageOptionButton> 299 296 </div>
-1
app/lish/[did]/[publication]/dashboard/DraftList.tsx
··· 23 23 searchValue={props.searchValue} 24 24 showPreview={false} 25 25 defaultDisplay="list" 26 - cardBorderHidden={!props.showPageBackground} 27 26 leaflets={leaflets_in_publications 28 27 .filter((l) => !l.documents) 29 28 .filter((l) => !l.archived)
-1
app/lish/[did]/[publication]/dashboard/PublicationDashboard.tsx
··· 39 39 return ( 40 40 <DashboardLayout 41 41 id={publication.uri} 42 - cardBorderHidden={!!record.theme?.showPageBackground} 43 42 defaultTab="Drafts" 44 43 tabs={{ 45 44 Drafts: {
+78 -19
app/p/[didOrHandle]/(profile)/ProfileTabs.tsx
··· 2 2 3 3 import { SpeedyLink } from "components/SpeedyLink"; 4 4 import { useSelectedLayoutSegment } from "next/navigation"; 5 + import { useState, useEffect } from "react"; 6 + import { useCardBorderHidden } from "components/Pages/useCardBorderHidden"; 5 7 6 8 export type ProfileTabType = "posts" | "comments" | "subscriptions"; 7 9 8 10 export const ProfileTabs = (props: { didOrHandle: string }) => { 11 + const cardBorderHidden = useCardBorderHidden(); 9 12 const segment = useSelectedLayoutSegment(); 10 13 const currentTab = (segment || "posts") as ProfileTabType; 14 + const [scrollPos, setScrollPos] = useState(0); 15 + 16 + useEffect(() => { 17 + const profileContent = document.querySelector( 18 + ".overflow-y-scroll", 19 + ) as HTMLElement; 20 + 21 + const handleScroll = () => { 22 + if (profileContent) { 23 + setScrollPos(profileContent.scrollTop); 24 + } 25 + }; 26 + 27 + if (profileContent) { 28 + profileContent.addEventListener("scroll", handleScroll); 29 + return () => profileContent.removeEventListener("scroll", handleScroll); 30 + } 31 + }, []); 11 32 12 33 const baseUrl = `/p/${props.didOrHandle}`; 34 + const bgColor = cardBorderHidden ? "var(--bg-leaflet)" : "var(--bg-page)"; 13 35 14 36 return ( 15 - <div className="flex flex-col w-full px-3 sm:px-4"> 16 - <div className="flex gap-2 justify-between"> 17 - <div className="flex gap-2"> 18 - <TabLink 19 - href={baseUrl} 20 - name="Posts" 21 - selected={currentTab === "posts"} 22 - /> 23 - <TabLink 24 - href={`${baseUrl}/comments`} 25 - name="Comments" 26 - selected={currentTab === "comments"} 27 - /> 37 + <div className="flex flex-col w-full sticky top-3 sm:top-4 z-10"> 38 + <div 39 + style={ 40 + scrollPos < 20 41 + ? { 42 + paddingLeft: `calc(${scrollPos / 20} * 12px + 12px)`, 43 + paddingRight: `calc(${scrollPos / 20} * 12px + 12px)`, 44 + } 45 + : { paddingLeft: "24px", paddingRight: "24px" } 46 + } 47 + > 48 + <div 49 + className={` 50 + border rounded-lg 51 + ${scrollPos > 20 ? "border-border-light" : "border-transparent"} 52 + py-1 53 + w-full `} 54 + style={ 55 + scrollPos < 20 56 + ? { 57 + backgroundColor: cardBorderHidden 58 + ? `rgba(${bgColor}, ${scrollPos / 60 + 0.75})` 59 + : `rgba(${bgColor}, ${scrollPos / 20})`, 60 + paddingLeft: cardBorderHidden 61 + ? "4px" 62 + : `calc(${scrollPos / 20} * 4px)`, 63 + paddingRight: cardBorderHidden 64 + ? "4px" 65 + : `calc(${scrollPos / 20} * 4px)`, 66 + } 67 + : { 68 + backgroundColor: `rgb(${bgColor})`, 69 + paddingLeft: "4px", 70 + paddingRight: "4px", 71 + } 72 + } 73 + > 74 + <div className="flex gap-2 justify-between"> 75 + <div className="flex gap-2"> 76 + <TabLink 77 + href={baseUrl} 78 + name="Posts" 79 + selected={currentTab === "posts"} 80 + /> 81 + <TabLink 82 + href={`${baseUrl}/comments`} 83 + name="Comments" 84 + selected={currentTab === "comments"} 85 + /> 86 + </div> 87 + <TabLink 88 + href={`${baseUrl}/subscriptions`} 89 + name="Subscriptions" 90 + selected={currentTab === "subscriptions"} 91 + /> 92 + </div> 28 93 </div> 29 - <TabLink 30 - href={`${baseUrl}/subscriptions`} 31 - name="Subscriptions" 32 - selected={currentTab === "subscriptions"} 33 - /> 34 94 </div> 35 - <hr className="border-border-light mt-1" /> 36 95 </div> 37 96 ); 38 97 };
+3 -2
app/p/[didOrHandle]/(profile)/layout.tsx
··· 52 52 max-w-prose mx-auto w-full h-full 53 53 flex flex-col 54 54 border border-border-light rounded-lg 55 - text-center mt-8`} 55 + text-center mt-8 56 + overflow-y-scroll`} 56 57 > 57 58 <ProfileHeader profile={profile} publications={publications || []} /> 58 59 <ProfileTabs didOrHandle={params.didOrHandle} /> 59 - <div className="h-full overflow-y-scroll pt-3 pb-4 px-3 sm:px-4 flex flex-col"> 60 + <div className="h-full pt-3 pb-4 px-3 sm:px-4 flex flex-col"> 60 61 {props.children} 61 62 </div> 62 63 </div>
+7 -8
components/PageHeader.tsx
··· 1 1 "use client"; 2 2 import { useState, useEffect } from "react"; 3 + import { useCardBorderHidden } from "./Pages/useCardBorderHidden"; 3 4 4 - export const Header = (props: { 5 - children: React.ReactNode; 6 - cardBorderHidden: boolean; 7 - }) => { 5 + export const Header = (props: { children: React.ReactNode }) => { 6 + let cardBorderHidden = useCardBorderHidden(); 8 7 let [scrollPos, setScrollPos] = useState(0); 9 8 10 9 useEffect(() => { ··· 22 21 } 23 22 }, []); 24 23 25 - let headerBGColor = props.cardBorderHidden 24 + let headerBGColor = !cardBorderHidden 26 25 ? "var(--bg-leaflet)" 27 26 : "var(--bg-page)"; 28 27 ··· 54 53 style={ 55 54 scrollPos < 20 56 55 ? { 57 - backgroundColor: props.cardBorderHidden 56 + backgroundColor: !cardBorderHidden 58 57 ? `rgba(${headerBGColor}, ${scrollPos / 60 + 0.75})` 59 58 : `rgba(${headerBGColor}, ${scrollPos / 20})`, 60 - paddingLeft: props.cardBorderHidden 59 + paddingLeft: !cardBorderHidden 61 60 ? "4px" 62 61 : `calc(${scrollPos / 20}*4px)`, 63 - paddingRight: props.cardBorderHidden 62 + paddingRight: !cardBorderHidden 64 63 ? "8px" 65 64 : `calc(${scrollPos / 20}*8px)`, 66 65 }
+1 -2
components/PageLayouts/DashboardLayout.tsx
··· 134 134 }, 135 135 >(props: { 136 136 id: string; 137 - cardBorderHidden: boolean; 138 137 tabs: T; 139 138 defaultTab: keyof T; 140 139 currentPage: navPages; ··· 187 186 > 188 187 {Object.keys(props.tabs).length <= 1 && !controls ? null : ( 189 188 <> 190 - <Header cardBorderHidden={props.cardBorderHidden}> 189 + <Header> 191 190 {headerState === "default" ? ( 192 191 <> 193 192 {Object.keys(props.tabs).length > 1 && (
+3 -5
components/Pages/Page.tsx
··· 34 34 return focusedPageID === props.entityID; 35 35 }); 36 36 let pageType = useEntity(props.entityID, "page/type")?.data.value || "doc"; 37 - let cardBorderHidden = useCardBorderHidden(props.entityID); 38 37 39 38 let drawerOpen = useDrawerOpen(props.entityID); 40 39 return ( ··· 49 48 }} 50 49 id={elementId.page(props.entityID).container} 51 50 drawerOpen={!!drawerOpen} 52 - cardBorderHidden={!!cardBorderHidden} 53 51 isFocused={isFocused} 54 52 fullPageScroll={props.fullPageScroll} 55 53 pageType={pageType} ··· 77 75 id: string; 78 76 children: React.ReactNode; 79 77 pageOptions?: React.ReactNode; 80 - cardBorderHidden: boolean; 81 78 fullPageScroll: boolean; 82 79 isFocused?: boolean; 83 80 onClickAction?: (e: React.MouseEvent) => void; 84 81 pageType: "canvas" | "doc"; 85 82 drawerOpen: boolean | undefined; 86 83 }) => { 84 + const cardBorderHidden = useCardBorderHidden(); 87 85 let { ref } = usePreserveScroll<HTMLDivElement>(props.id); 88 86 return ( 89 87 // this div wraps the contents AND the page options. ··· 106 104 shrink-0 snap-center 107 105 overflow-y-scroll 108 106 ${ 109 - !props.cardBorderHidden && 107 + !cardBorderHidden && 110 108 `h-full border 111 109 bg-[rgba(var(--bg-page),var(--bg-page-alpha))] 112 110 ${props.drawerOpen ? "rounded-l-lg " : "rounded-lg"} 113 111 ${props.isFocused ? "shadow-md border-border" : "border-border-light"}` 114 112 } 115 - ${props.cardBorderHidden && "sm:h-[calc(100%+48px)] h-[calc(100%+20px)] sm:-my-6 -my-3 sm:pt-6 pt-3"} 113 + ${cardBorderHidden && "sm:h-[calc(100%+48px)] h-[calc(100%+20px)] sm:-my-6 -my-3 sm:pt-6 pt-3"} 116 114 ${props.fullPageScroll && "max-w-full "} 117 115 ${props.pageType === "doc" && !props.fullPageScroll && "w-[10000px] sm:mx-0 max-w-[var(--page-width-units)]"} 118 116 ${
+7 -29
components/Pages/PageOptions.tsx
··· 21 21 export const PageOptionButton = ({ 22 22 children, 23 23 secondary, 24 - cardBorderHidden, 25 24 className, 26 25 disabled, 27 26 ...props 28 27 }: { 29 28 children: React.ReactNode; 30 29 secondary?: boolean; 31 - cardBorderHidden: boolean | undefined; 32 30 className?: string; 33 31 disabled?: boolean; 34 32 } & Omit<JSX.IntrinsicElements["button"], "content">) => { 33 + const cardBorderHidden = useCardBorderHidden(); 35 34 return ( 36 35 <button 37 36 className={` ··· 58 57 first: boolean | undefined; 59 58 isFocused: boolean; 60 59 }) => { 61 - let cardBorderHidden = useCardBorderHidden(props.entityID); 62 - 63 60 return ( 64 61 <div 65 62 className={`pageOptions w-fit z-10 ··· 69 66 > 70 67 {!props.first && ( 71 68 <PageOptionButton 72 - cardBorderHidden={cardBorderHidden} 73 69 secondary 74 70 onClick={() => { 75 71 useUIState.getState().closePage(props.entityID); ··· 78 74 <CloseTiny /> 79 75 </PageOptionButton> 80 76 )} 81 - <OptionsMenu 82 - entityID={props.entityID} 83 - first={!!props.first} 84 - cardBorderHidden={cardBorderHidden} 85 - /> 86 - <UndoButtons cardBorderHidden={cardBorderHidden} /> 77 + <OptionsMenu entityID={props.entityID} first={!!props.first} /> 78 + <UndoButtons /> 87 79 </div> 88 80 ); 89 81 }; 90 82 91 - export const UndoButtons = (props: { 92 - cardBorderHidden: boolean | undefined; 93 - }) => { 83 + export const UndoButtons = () => { 94 84 let undoState = useUndoState(); 95 85 let { undoManager } = useReplicache(); 96 86 return ( 97 87 <Media mobile> 98 88 {undoState.canUndo && ( 99 89 <div className="gap-1 flex sm:flex-col"> 100 - <PageOptionButton 101 - secondary 102 - cardBorderHidden={props.cardBorderHidden} 103 - onClick={() => undoManager.undo()} 104 - > 90 + <PageOptionButton secondary onClick={() => undoManager.undo()}> 105 91 <UndoTiny /> 106 92 </PageOptionButton> 107 93 108 94 <PageOptionButton 109 95 secondary 110 - cardBorderHidden={props.cardBorderHidden} 111 96 onClick={() => undoManager.undo()} 112 97 disabled={!undoState.canRedo} 113 98 > ··· 119 104 ); 120 105 }; 121 106 122 - export const OptionsMenu = (props: { 123 - entityID: string; 124 - first: boolean; 125 - cardBorderHidden: boolean | undefined; 126 - }) => { 107 + export const OptionsMenu = (props: { entityID: string; first: boolean }) => { 127 108 let [state, setState] = useState<"normal" | "theme" | "share">("normal"); 128 109 let { permissions } = useEntitySetContext(); 129 110 if (!permissions.write) return null; ··· 138 119 if (!open) setState("normal"); 139 120 }} 140 121 trigger={ 141 - <PageOptionButton 142 - cardBorderHidden={props.cardBorderHidden} 143 - className="!w-8 !h-5 sm:!w-5 sm:!h-8" 144 - > 122 + <PageOptionButton className="!w-8 !h-5 sm:!w-5 sm:!h-8"> 145 123 <MoreOptionsTiny className="sm:rotate-90" /> 146 124 </PageOptionButton> 147 125 }
+3 -18
components/Pages/useCardBorderHidden.ts
··· 1 - import { useLeafletPublicationData } from "components/PageSWRDataProvider"; 2 - import { PubLeafletPublication } from "lexicons/api"; 3 - import { useEntity, useReplicache } from "src/replicache"; 1 + import { useCardBorderHiddenContext } from "components/ThemeManager/ThemeProvider"; 4 2 5 - export function useCardBorderHidden(entityID: string | null) { 6 - let { rootEntity } = useReplicache(); 7 - let { data: pub } = useLeafletPublicationData(); 8 - let rootCardBorderHidden = useEntity(rootEntity, "theme/card-border-hidden"); 9 - 10 - let cardBorderHidden = 11 - useEntity(entityID, "theme/card-border-hidden") || rootCardBorderHidden; 12 - if (!cardBorderHidden && !rootCardBorderHidden) { 13 - if (pub?.publications?.record) { 14 - let record = pub.publications.record as PubLeafletPublication.Record; 15 - return !record.theme?.showPageBackground; 16 - } 17 - return false; 18 - } 19 - return (cardBorderHidden || rootCardBorderHidden)?.data.value; 3 + export function useCardBorderHidden(entityID?: string | null) { 4 + return useCardBorderHiddenContext(); 20 5 }
+7 -4
components/ThemeManager/PublicationThemeProvider.tsx
··· 4 4 import { useEntity } from "src/replicache"; 5 5 import { getColorContrast } from "./themeUtils"; 6 6 import { useColorAttribute, colorToString } from "./useColorAttribute"; 7 - import { BaseThemeProvider } from "./ThemeProvider"; 7 + import { BaseThemeProvider, CardBorderHiddenContext } from "./ThemeProvider"; 8 8 import { PubLeafletPublication, PubLeafletThemeColor } from "lexicons/api"; 9 9 import { usePublicationData } from "app/lish/[did]/[publication]/dashboard/PublicationSWRProvider"; 10 10 import { blobRefToSrc } from "src/utils/blobRefToSrc"; ··· 103 103 isStandalone?: boolean; 104 104 }) { 105 105 let colors = usePubTheme(props.theme, props.isStandalone); 106 + let cardBorderHidden = !colors.showPageBackground; 106 107 return ( 107 - <BaseThemeProvider local={props.local} {...colors}> 108 - {props.children} 109 - </BaseThemeProvider> 108 + <CardBorderHiddenContext.Provider value={cardBorderHidden}> 109 + <BaseThemeProvider local={props.local} {...colors}> 110 + {props.children} 111 + </BaseThemeProvider> 112 + </CardBorderHiddenContext.Provider> 110 113 ); 111 114 } 112 115
+26 -22
components/ThemeManager/ThemeProvider.tsx
··· 1 1 "use client"; 2 2 3 - import { 4 - createContext, 5 - CSSProperties, 6 - useContext, 7 - useEffect, 8 - } from "react"; 3 + import { createContext, CSSProperties, useContext, useEffect } from "react"; 4 + 5 + // Context for cardBorderHidden 6 + export const CardBorderHiddenContext = createContext<boolean>(false); 7 + 8 + export function useCardBorderHiddenContext() { 9 + return useContext(CardBorderHiddenContext); 10 + } 9 11 import { 10 12 colorToString, 11 13 useColorAttribute, ··· 58 60 }) { 59 61 let bgLeaflet = useColorAttribute(props.entityID, "theme/page-background"); 60 62 let bgPage = useColorAttribute(props.entityID, "theme/card-background"); 61 - let showPageBackground = !useEntity( 63 + let cardBorderHiddenValue = useEntity( 62 64 props.entityID, 63 65 "theme/card-border-hidden", 64 66 )?.data.value; 67 + let showPageBackground = !cardBorderHiddenValue; 65 68 let primary = useColorAttribute(props.entityID, "theme/primary"); 66 69 67 70 let highlight1 = useEntity(props.entityID, "theme/highlight-1"); ··· 72 75 let accent2 = useColorAttribute(props.entityID, "theme/accent-text"); 73 76 74 77 return ( 75 - <BaseThemeProvider 76 - local={props.local} 77 - bgLeaflet={bgLeaflet} 78 - bgPage={bgPage} 79 - primary={primary} 80 - highlight2={highlight2} 81 - highlight3={highlight3} 82 - highlight1={highlight1?.data.value} 83 - accent1={accent1} 84 - accent2={accent2} 85 - showPageBackground={showPageBackground} 86 - > 87 - {props.children} 88 - </BaseThemeProvider> 78 + <CardBorderHiddenContext.Provider value={!!cardBorderHiddenValue}> 79 + <BaseThemeProvider 80 + local={props.local} 81 + bgLeaflet={bgLeaflet} 82 + bgPage={bgPage} 83 + primary={primary} 84 + highlight2={highlight2} 85 + highlight3={highlight3} 86 + highlight1={highlight1?.data.value} 87 + accent1={accent1} 88 + accent2={accent2} 89 + showPageBackground={showPageBackground} 90 + > 91 + {props.children} 92 + </BaseThemeProvider> 93 + </CardBorderHiddenContext.Provider> 89 94 ); 90 95 } 91 96 ··· 337 342 </div> 338 343 ); 339 344 }; 340 -
-2
src/hooks/useLocalizedDate.ts
··· 31 31 ? timezone || "UTC" 32 32 : Intl.DateTimeFormat().resolvedOptions().timeZone; 33 33 34 - console.log("tz", effectiveTimezone); 35 - 36 34 // Apply timezone if available 37 35 if (effectiveTimezone) { 38 36 dateTime = dateTime.setZone(effectiveTimezone);