a tool for shared writing and social publishing
at update/reader 84 lines 2.8 kB view raw
1"use client"; 2import { DatePicker, TimePicker } from "components/DatePicker"; 3import { useMemo, useState } from "react"; 4import { timeAgo } from "src/utils/timeAgo"; 5import { Popover } from "components/Popover"; 6import { Separator } from "react-aria-components"; 7import { useReplicache } from "src/replicache"; 8import { create } from "zustand"; 9 10export const useLocalPublishedAt = create<{ [uri: string]: Date }>(() => ({})); 11export const Backdater = (props: { publishedAt: string; docURI: string }) => { 12 let { rep } = useReplicache(); 13 let localPublishedAtDate = useLocalPublishedAt((s) => 14 s[props.docURI] ? s[props.docURI] : null, 15 ); 16 let localPublishedAt = useMemo( 17 () => localPublishedAtDate || new Date(props.publishedAt), 18 [localPublishedAtDate, props.publishedAt], 19 ); 20 21 let [timeValue, setTimeValue] = useState( 22 `${localPublishedAt.getHours().toString().padStart(2, "0")}:${localPublishedAt.getMinutes().toString().padStart(2, "0")}`, 23 ); 24 25 let currentTime = `${new Date().getHours().toString().padStart(2, "0")}:${new Date().getMinutes().toString().padStart(2, "0")}`; 26 27 const handleTimeChange = async (time: string) => { 28 setTimeValue(time); 29 const [hours, minutes] = time.split(":").map((str) => parseInt(str, 10)); 30 const newDate = new Date(localPublishedAt); 31 newDate.setHours(hours); 32 newDate.setMinutes(minutes); 33 34 let currentDate = new Date(); 35 if (newDate > currentDate) { 36 useLocalPublishedAt.setState({ [props.docURI]: currentDate }); 37 setTimeValue(currentTime); 38 } else { 39 useLocalPublishedAt.setState({ [props.docURI]: newDate }); 40 } 41 }; 42 43 const handleDateChange = async (date: Date | undefined) => { 44 if (!date) return; 45 const [hours, minutes] = timeValue 46 .split(":") 47 .map((str) => parseInt(str, 10)); 48 const newDate = new Date(date); 49 newDate.setHours(hours); 50 newDate.setMinutes(minutes); 51 52 let currentDate = new Date(); 53 if (newDate > currentDate) { 54 useLocalPublishedAt.setState({ [props.docURI]: currentDate }); 55 56 setTimeValue(currentTime); 57 } else { 58 useLocalPublishedAt.setState({ [props.docURI]: newDate }); 59 } 60 }; 61 62 return ( 63 <Popover 64 className="w-64 z-10 px-2!" 65 trigger={ 66 <div className="underline"> 67 {timeAgo(localPublishedAt.toISOString())} 68 </div> 69 } 70 > 71 <div className="flex flex-col gap-3"> 72 <DatePicker 73 selected={localPublishedAt} 74 onSelect={handleDateChange} 75 disabled={(date) => date > new Date()} 76 /> 77 <Separator className="border-border" /> 78 <div className="flex gap-4 pb-1 items-center"> 79 <TimePicker value={timeValue} onChange={handleTimeChange} /> 80 </div> 81 </div> 82 </Popover> 83 ); 84};