a tool for shared writing and social publishing
at update/reader 196 lines 6.4 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 /> 70 </div> 71 <AccentPickers 72 entityID={props.entityID} 73 openPicker={openPicker} 74 setOpenPicker={(pickers) => setOpenPicker(pickers)} 75 /> 76 <SamplePage entityID={props.entityID} /> 77 </div> 78 </> 79 ); 80}; 81 82const ResetButton = (props: { entityID: string }) => { 83 let { rep } = useReplicache(); 84 85 return ( 86 <ButtonPrimary 87 compact 88 onClick={() => { 89 if (!rep) return; 90 rep.mutate.retractAttribute({ 91 entity: props.entityID, 92 attribute: [ 93 "theme/primary", 94 "theme/card-background", 95 "theme/accent-background", 96 "theme/accent-text", 97 "theme/card-background-image", 98 "theme/card-background-image-repeat", 99 "theme/card-background-image-opacity", 100 "theme/card-border-hidden", 101 "canvas/background-pattern", 102 ], 103 }); 104 }} 105 > 106 reset 107 </ButtonPrimary> 108 ); 109}; 110 111const SamplePage = (props: { entityID: string }) => { 112 let { rootEntity } = useReplicache(); 113 114 let rootBackgroundImage = useEntity( 115 rootEntity, 116 "theme/card-background-image", 117 ); 118 let rootBackgroundRepeat = useEntity( 119 rootEntity, 120 "theme/card-background-image-repeat", 121 ); 122 let rootBackgroundOpacity = useEntity( 123 rootEntity, 124 "theme/card-background-image-opacity", 125 ); 126 127 let pageBackgroundImage = 128 useEntity(props.entityID, "theme/card-background-image") || 129 rootBackgroundImage; 130 let pageBackgroundImageRepeat = 131 useEntity(props.entityID, "theme/card-background-image-repeat") || 132 rootBackgroundRepeat; 133 let pageBackgroundImageOpacity = 134 useEntity(props.entityID, "theme/card-background-image-opacity") || 135 rootBackgroundOpacity; 136 137 let rootPageBorderHidden = useEntity(rootEntity, "theme/card-border-hidden"); 138 let entityPageBorderHidden = useEntity( 139 props.entityID, 140 "theme/card-border-hidden", 141 ); 142 let pageBorderHidden = (entityPageBorderHidden || rootPageBorderHidden)?.data 143 .value; 144 145 return ( 146 <div 147 className={ 148 pageBorderHidden 149 ? "relative py-2 px-0 border border-transparent" 150 : `relative rounded-t-lg p-2 shadow-md text-primary border border-border border-b-transparent` 151 } 152 style={ 153 pageBorderHidden 154 ? undefined 155 : { 156 backgroundColor: "rgba(var(--bg-page), var(--bg-page-alpha))", 157 } 158 } 159 > 160 <div 161 className="background absolute top-0 right-0 bottom-0 left-0 z-0 rounded-t-lg" 162 style={ 163 pageBorderHidden 164 ? undefined 165 : { 166 backgroundImage: pageBackgroundImage 167 ? `url(${pageBackgroundImage.data.src})` 168 : undefined, 169 170 backgroundRepeat: pageBackgroundImageRepeat 171 ? "repeat" 172 : "no-repeat", 173 opacity: pageBackgroundImageOpacity?.data.value || 1, 174 backgroundSize: !pageBackgroundImageRepeat?.data.value 175 ? "cover" 176 : `calc(${pageBackgroundImageRepeat.data.value}px / 2 )`, 177 } 178 } 179 /> 180 <div className="relative"> 181 <p className="font-bold">Theme Each Page!</p> 182 <small className=""> 183 OMG! You can theme each page individually in{" "} 184 <span className="font-bold text-accent-contrast">Leaflet</span>! 185 <br /> Buttons and sections appear like: 186 </small> 187 <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"> 188 Happy Theming! 189 <div className="bg-accent-1 text-accent-2 py-0.5 px-2 w-fit text-center text-sm font-bold rounded-md"> 190 Button 191 </div> 192 </div> 193 </div> 194 </div> 195 ); 196};