a tool for shared writing and social publishing
at main 197 lines 6.5 kB view raw
1import { useEntity, useReplicache } from "src/replicache"; 2import { useEntitySetContext } from "components/EntitySetProvider"; 3import { pickers, SectionArrow, setColorAttribute } from "./ThemeSetter"; 4 5import { 6 SubpageBackgroundPicker, 7 PageThemePickers, 8} from "./Pickers/PageThemePickers"; 9import { useMemo, useState } from "react"; 10import { theme } from "tailwind.config"; 11import { ButtonPrimary } from "components/Buttons"; 12import { PaintSmall } from "components/Icons/PaintSmall"; 13import { AccentPickers } from "./Pickers/AccentPickers"; 14import Page from "twilio/lib/base/Page"; 15 16export const PageThemeSetter = (props: { entityID: string }) => { 17 let { rootEntity } = useReplicache(); 18 let permission = useEntitySetContext().permissions.write; 19 let [openPicker, setOpenPicker] = useState<pickers>("null"); 20 21 let leafletBGImage = useEntity(rootEntity, "theme/background-image"); 22 let leafletBGRepeat = useEntity(rootEntity, "theme/background-image-repeat"); 23 24 if (!permission) return null; 25 26 let { rep } = useReplicache(); 27 let set = useMemo(() => { 28 return setColorAttribute(rep, props.entityID); 29 }, [rep, props.entityID]); 30 31 return ( 32 <> 33 <div className="pageThemeSetter flex flex-row gap-2 px-3 py-1 z-10"> 34 <div className="gap-2 flex font-bold "> 35 <PaintSmall /> Theme Page 36 </div> 37 <ResetButton entityID={props.entityID} /> 38 </div> 39 40 <div 41 className="pageThemeSetterContent bg-bg-leaflet w-80 p-3 pb-0 flex flex-col gap-4 rounded-md -mb-1" 42 style={{ 43 backgroundImage: leafletBGImage 44 ? `url(${leafletBGImage.data.src})` 45 : undefined, 46 backgroundPosition: "center", 47 backgroundRepeat: leafletBGRepeat ? "repeat" : "no-repeat", 48 backgroundSize: !leafletBGRepeat 49 ? "cover" 50 : `calc(${leafletBGRepeat.data.value}px / 2 )`, 51 }} 52 > 53 <div 54 className="pageThemeBG flex flex-col gap-2 h-full text-primary bg-bg-leaflet p-2 rounded-md border border-primary shadow-[0_0_0_1px_rgb(var(--bg-page))]" 55 style={{ backgroundColor: "rgba(var(--bg-page), 0.6)" }} 56 > 57 <SubpageBackgroundPicker 58 entityID={props.entityID} 59 openPicker={openPicker} 60 setOpenPicker={setOpenPicker} 61 /> 62 </div> 63 64 <div className="flex flex-col z-10"> 65 <PageThemePickers 66 entityID={props.entityID} 67 openPicker={openPicker} 68 setOpenPicker={(pickers) => setOpenPicker(pickers)} 69 hideFonts 70 /> 71 </div> 72 <AccentPickers 73 entityID={props.entityID} 74 openPicker={openPicker} 75 setOpenPicker={(pickers) => setOpenPicker(pickers)} 76 /> 77 <SamplePage entityID={props.entityID} /> 78 </div> 79 </> 80 ); 81}; 82 83const ResetButton = (props: { entityID: string }) => { 84 let { rep } = useReplicache(); 85 86 return ( 87 <ButtonPrimary 88 compact 89 onClick={() => { 90 if (!rep) return; 91 rep.mutate.retractAttribute({ 92 entity: props.entityID, 93 attribute: [ 94 "theme/primary", 95 "theme/card-background", 96 "theme/accent-background", 97 "theme/accent-text", 98 "theme/card-background-image", 99 "theme/card-background-image-repeat", 100 "theme/card-background-image-opacity", 101 "theme/card-border-hidden", 102 "canvas/background-pattern", 103 ], 104 }); 105 }} 106 > 107 reset 108 </ButtonPrimary> 109 ); 110}; 111 112const SamplePage = (props: { entityID: string }) => { 113 let { rootEntity } = useReplicache(); 114 115 let rootBackgroundImage = useEntity( 116 rootEntity, 117 "theme/card-background-image", 118 ); 119 let rootBackgroundRepeat = useEntity( 120 rootEntity, 121 "theme/card-background-image-repeat", 122 ); 123 let rootBackgroundOpacity = useEntity( 124 rootEntity, 125 "theme/card-background-image-opacity", 126 ); 127 128 let pageBackgroundImage = 129 useEntity(props.entityID, "theme/card-background-image") || 130 rootBackgroundImage; 131 let pageBackgroundImageRepeat = 132 useEntity(props.entityID, "theme/card-background-image-repeat") || 133 rootBackgroundRepeat; 134 let pageBackgroundImageOpacity = 135 useEntity(props.entityID, "theme/card-background-image-opacity") || 136 rootBackgroundOpacity; 137 138 let rootPageBorderHidden = useEntity(rootEntity, "theme/card-border-hidden"); 139 let entityPageBorderHidden = useEntity( 140 props.entityID, 141 "theme/card-border-hidden", 142 ); 143 let pageBorderHidden = (entityPageBorderHidden || rootPageBorderHidden)?.data 144 .value; 145 146 return ( 147 <div 148 className={ 149 pageBorderHidden 150 ? "relative py-2 px-0 border border-transparent" 151 : `relative rounded-t-lg p-2 shadow-md text-primary border border-border border-b-transparent` 152 } 153 style={ 154 pageBorderHidden 155 ? undefined 156 : { 157 backgroundColor: "rgba(var(--bg-page), var(--bg-page-alpha))", 158 } 159 } 160 > 161 <div 162 className="background absolute top-0 right-0 bottom-0 left-0 z-0 rounded-t-lg" 163 style={ 164 pageBorderHidden 165 ? undefined 166 : { 167 backgroundImage: pageBackgroundImage 168 ? `url(${pageBackgroundImage.data.src})` 169 : undefined, 170 171 backgroundRepeat: pageBackgroundImageRepeat 172 ? "repeat" 173 : "no-repeat", 174 opacity: pageBackgroundImageOpacity?.data.value || 1, 175 backgroundSize: !pageBackgroundImageRepeat?.data.value 176 ? "cover" 177 : `calc(${pageBackgroundImageRepeat.data.value}px / 2 )`, 178 } 179 } 180 /> 181 <div className="relative"> 182 <p className="font-bold">Theme Each Page!</p> 183 <small className=""> 184 OMG! You can theme each page individually in{" "} 185 <span className="font-bold text-accent-contrast">Leaflet</span>! 186 <br /> Buttons and sections appear like: 187 </small> 188 <div className="p-2 mt-2 border border-border bg-bg-page rounded-md text-sm flex justify-between items-center font-bold text-secondary"> 189 Happy Theming! 190 <div className="bg-accent-1 text-accent-2 py-0.5 px-2 w-fit text-center text-sm font-bold rounded-md"> 191 Button 192 </div> 193 </div> 194 </div> 195 </div> 196 ); 197};