From 2c068acaf6e1b5f861bff5ffe97ee8ccd4a0f35b Mon Sep 17 00:00:00 2001 From: celine Date: Fri, 16 Jan 2026 12:03:24 -0500 Subject: [PATCH 1/5] oops fix showing quotes on interaction preview --- components/InteractionsPreview.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/InteractionsPreview.tsx b/components/InteractionsPreview.tsx index c2adf6f3..30ddefbb 100644 --- a/components/InteractionsPreview.tsx +++ b/components/InteractionsPreview.tsx @@ -38,7 +38,7 @@ export const InteractionPreview = (props: { )} - {props.showMentions || props.quotesCount === 0 ? null : ( + {!props.showMentions || props.quotesCount === 0 ? null : ( {props.quotesCount} )} - {props.showComments === false || props.commentsCount === 0 ? null : ( + {!props.showComments || props.commentsCount === 0 ? null : ( Date: Fri, 16 Jan 2026 15:55:11 -0500 Subject: [PATCH 2/5] add more resolution to timeAgo, show createdAt on comments --- .../[rkey]/Interactions/Comments/index.tsx | 12 ++++++++++-- src/utils/timeAgo.ts | 6 ++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/app/lish/[did]/[publication]/[rkey]/Interactions/Comments/index.tsx b/app/lish/[did]/[publication]/[rkey]/Interactions/Comments/index.tsx index fea07562..33e771f0 100644 --- a/app/lish/[did]/[publication]/[rkey]/Interactions/Comments/index.tsx +++ b/app/lish/[did]/[publication]/[rkey]/Interactions/Comments/index.tsx @@ -119,10 +119,17 @@ const Comment = (props: { }) => { const did = props.comment.bsky_profiles?.did; + let timeAgoDate = timeAgo(props.record.createdAt); + const formattedDate = useLocalizedDate(props.record.createdAt, { + year: "numeric", + month: "long", + day: "2-digit", + }); + return (
- {did && ( + {did ? ( } /> - )} + ) : null} +
{timeAgoDate}
{props.record.attachment && PubLeafletComment.isLinearDocumentQuote(props.record.attachment) && ( diff --git a/src/utils/timeAgo.ts b/src/utils/timeAgo.ts index bed5d22b..0a59025d 100644 --- a/src/utils/timeAgo.ts +++ b/src/utils/timeAgo.ts @@ -6,10 +6,16 @@ export function timeAgo(timestamp: string): string { const diffMinutes = Math.floor(diffSeconds / 60); const diffHours = Math.floor(diffMinutes / 60); const diffDays = Math.floor(diffHours / 24); + const diffWeeks = Math.floor(diffDays / 7); + const diffMonths = Math.floor(diffDays / 30); const diffYears = Math.floor(diffDays / 365); if (diffYears > 0) { return `${diffYears} year${diffYears === 1 ? "" : "s"} ago`; + } else if (diffMonths > 0) { + return `${diffMonths} month${diffMonths === 1 ? "" : "s"} ago`; + } else if (diffWeeks > 0) { + return `${diffWeeks} week${diffWeeks === 1 ? "" : "s"} ago`; } else if (diffDays > 0) { return `${diffDays} day${diffDays === 1 ? "" : "s"} ago`; } else if (diffHours > 0) { -- 2.51.2 From 18d880dea364ac504591da7e45af6239cbdcc7f7 Mon Sep 17 00:00:00 2001 From: celine Date: Fri, 16 Jan 2026 17:04:04 -0500 Subject: [PATCH 3/5] fixing some color logic stuff --- .../ThemeManager/PublicationThemeProvider.tsx | 36 +------------------ components/ThemeManager/ThemeProvider.tsx | 20 +++++------ 2 files changed, 11 insertions(+), 45 deletions(-) diff --git a/components/ThemeManager/PublicationThemeProvider.tsx b/components/ThemeManager/PublicationThemeProvider.tsx index c21302c1..142520fe 100644 --- a/components/ThemeManager/PublicationThemeProvider.tsx +++ b/components/ThemeManager/PublicationThemeProvider.tsx @@ -171,43 +171,9 @@ export const useLocalPubTheme = ( ...localOverrides, showPageBackground, }; - let newAccentContrast; - let sortedAccents = [newTheme.accent1, newTheme.accent2].sort((a, b) => { - return ( - getColorDifference( - colorToString(b, "rgb"), - colorToString( - showPageBackground ? newTheme.bgPage : newTheme.bgLeaflet, - "rgb", - ), - ) - - getColorDifference( - colorToString(a, "rgb"), - colorToString( - showPageBackground ? newTheme.bgPage : newTheme.bgLeaflet, - "rgb", - ), - ) - ); - }); - if ( - getColorDifference( - colorToString(sortedAccents[0], "rgb"), - colorToString(newTheme.primary, "rgb"), - ) < 0.15 && - getColorDifference( - colorToString(sortedAccents[1], "rgb"), - colorToString( - showPageBackground ? newTheme.bgPage : newTheme.bgLeaflet, - "rgb", - ), - ) > 0.08 - ) { - newAccentContrast = sortedAccents[1]; - } else newAccentContrast = sortedAccents[0]; + return { ...newTheme, - accentContrast: newAccentContrast, }; }, [pubTheme, localOverrides, showPageBackground]); return { diff --git a/components/ThemeManager/ThemeProvider.tsx b/components/ThemeManager/ThemeProvider.tsx index a6211c17..5d00768c 100644 --- a/components/ThemeManager/ThemeProvider.tsx +++ b/components/ThemeManager/ThemeProvider.tsx @@ -134,11 +134,10 @@ export const BaseThemeProvider = ({ // pageBg should inherit from leafletBg const bgPage = !showPageBackground && !hasBackgroundImage ? bgLeaflet : bgPageProp; - // set accent contrast to the accent color that has the highest contrast with the page background - let accentContrast; - //sorting the accents by contrast on background + let accentContrast; let sortedAccents = [accent1, accent2].sort((a, b) => { + // sort accents by contrast against the background return ( getColorDifference( colorToString(b, "rgb"), @@ -150,23 +149,24 @@ export const BaseThemeProvider = ({ ) ); }); - - // if the contrast-y accent is too similar to the primary text color, - // and the not contrast-y option is different from the backgrond, - // then use the not contrasty option - if ( + // if the contrast-y accent is too similar to text color getColorDifference( colorToString(sortedAccents[0], "rgb"), colorToString(primary, "rgb"), ) < 0.15 && + // and if the other accent is different enough from the background getColorDifference( colorToString(sortedAccents[1], "rgb"), colorToString(showPageBackground ? bgPage : bgLeaflet, "rgb"), - ) > 0.08 + ) > 0.31 ) { + //then choose the less contrast-y accent accentContrast = sortedAccents[1]; - } else accentContrast = sortedAccents[0]; + } else { + // otherwise, choose the more contrast-y option + accentContrast = sortedAccents[0]; + } useEffect(() => { if (local) return; -- 2.51.2 From 08302114f7f481f7e2230f35638cac2cb52c6fd8 Mon Sep 17 00:00:00 2001 From: celine Date: Fri, 16 Jan 2026 19:20:33 -0500 Subject: [PATCH 4/5] show mention and comments placeholder in looseleaf draft --- components/Pages/PublicationMetadata.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/Pages/PublicationMetadata.tsx b/components/Pages/PublicationMetadata.tsx index 70f5f121..db1b7a40 100644 --- a/components/Pages/PublicationMetadata.tsx +++ b/components/Pages/PublicationMetadata.tsx @@ -118,18 +118,18 @@ export const PublicationMetadata = () => { {tags && ( <> - {pubRecord?.preferences?.showMentions || - pubRecord?.preferences?.showComments ? ( + {pubRecord?.preferences?.showMentions !== false || + pubRecord?.preferences?.showComments !== false ? ( ) : null} )} - {pubRecord?.preferences?.showMentions && ( + {pubRecord?.preferences?.showMentions !== false && (
—
)} - {pubRecord?.preferences?.showComments && ( + {pubRecord?.preferences?.showComments !== false && (
—
-- 2.51.2 From e13306ec07555547df8e1fbddafda2b29bdd97fc Mon Sep 17 00:00:00 2001 From: celine Date: Mon, 19 Jan 2026 10:47:22 -1000 Subject: [PATCH 5/5] Feature/backdate (#258) * added capability to backdate post on published docs * componentize Date Picker, add Time Picker, mock up date and time pickers in publish show and update flow * wire up backdating posts from the publish flow. still broken from update button * wire up updating pubish date on published post * just bold some stuff * open calendars to corrent months and times by default --- actions/publishToPublication.ts | 11 +- app/[leaflet_id]/actions/PublishButton.tsx | 11 +- app/[leaflet_id]/publish/PublishPost.tsx | 125 +++++++++++++++++++-- components/Blocks/DateTimeBlock.tsx | 34 +----- components/DatePicker.tsx | 71 ++++++++++++ components/Pages/Backdater.tsx | 84 ++++++++++++++ components/Pages/PublicationMetadata.tsx | 7 +- src/replicache/mutations.ts | 6 +- 8 files changed, 297 insertions(+), 52 deletions(-) create mode 100644 components/DatePicker.tsx create mode 100644 components/Pages/Backdater.tsx diff --git a/actions/publishToPublication.ts b/actions/publishToPublication.ts index 4f7e8b38..b5164848 100644 --- a/actions/publishToPublication.ts +++ b/actions/publishToPublication.ts @@ -66,6 +66,7 @@ export async function publishToPublication({ tags, cover_image, entitiesToDelete, + publishedAt, }: { root_entity: string; publication_uri?: string; @@ -75,6 +76,7 @@ export async function publishToPublication({ tags?: string[]; cover_image?: string | null; entitiesToDelete?: string[]; + publishedAt?: string; }): Promise { let identity = await getIdentityData(); if (!identity || !identity.atp_did) { @@ -147,8 +149,9 @@ export async function publishToPublication({ credentialSession.did!, ); - let existingRecord = - (draft?.documents?.data as PubLeafletDocument.Record | undefined) || {}; + let existingRecord = draft?.documents?.data as + | PubLeafletDocument.Record + | undefined; // Extract theme for standalone documents (not for publications) let theme: PubLeafletPublication.Theme | undefined; @@ -174,8 +177,6 @@ export async function publishToPublication({ } let record: PubLeafletDocument.Record = { - publishedAt: new Date().toISOString(), - ...existingRecord, $type: "pub.leaflet.document", author: credentialSession.did!, ...(publication_uri && { publication: publication_uri }), @@ -199,6 +200,8 @@ export async function publishToPublication({ }; } }), + publishedAt: + publishedAt || existingRecord?.publishedAt || new Date().toISOString(), }; // Keep the same rkey if updating an existing document diff --git a/app/[leaflet_id]/actions/PublishButton.tsx b/app/[leaflet_id]/actions/PublishButton.tsx index f0140132..4be7c75b 100644 --- a/app/[leaflet_id]/actions/PublishButton.tsx +++ b/app/[leaflet_id]/actions/PublishButton.tsx @@ -24,7 +24,7 @@ import { useToaster } from "components/Toast"; import { DotLoader } from "components/utils/DotLoader"; import { PubLeafletPublication } from "lexicons/api"; import { useParams, useRouter, useSearchParams } from "next/navigation"; -import { useState, useMemo } from "react"; +import { useState, useMemo, useEffect } from "react"; import { useIsMobile } from "src/hooks/isMobile"; import { useReplicache, useEntity } from "src/replicache"; import { useSubscribe } from "src/replicache/useSubscribe"; @@ -40,6 +40,7 @@ import { BlueskyLogin } from "app/login/LoginForm"; import { moveLeafletToPublication } from "actions/publications/moveLeafletToPublication"; import { AddTiny } from "components/Icons/AddTiny"; import { OAuthErrorMessage, isOAuthSessionError } from "components/OAuthError"; +import { useLocalPublishedAt } from "components/Pages/Backdater"; export const PublishButton = (props: { entityID: string }) => { let { data: pub } = useLeafletPublicationData(); @@ -95,6 +96,11 @@ const UpdateButton = () => { tx.get("publication_cover_image"), ); + // Get local published at from Replicache (session-only state, not persisted to DB) + let publishedAt = useLocalPublishedAt((s) => + pub?.doc ? s[pub?.doc] : undefined, + ); + return ( { description: currentDescription, tags: currentTags, cover_image: coverImage, + publishedAt: publishedAt?.toISOString(), }); setIsLoading(false); mutate(); @@ -134,7 +141,7 @@ const UpdateButton = () => { toaster({ content: ( -
+
{pub.doc ? "Updated! " : "Published! "} See Published Post diff --git a/app/[leaflet_id]/publish/PublishPost.tsx b/app/[leaflet_id]/publish/PublishPost.tsx index 4b890427..8b0aa3cf 100644 --- a/app/[leaflet_id]/publish/PublishPost.tsx +++ b/app/[leaflet_id]/publish/PublishPost.tsx @@ -23,6 +23,11 @@ import { TagSelector } from "../../../components/Tags"; import { LooseLeafSmall } from "components/Icons/LooseleafSmall"; import { PubIcon } from "components/ActionBar/Publications"; import { OAuthErrorMessage, isOAuthSessionError } from "components/OAuthError"; +import { DatePicker, TimePicker } from "components/DatePicker"; +import { Popover } from "components/Popover"; +import { useLocalizedDate } from "src/hooks/useLocalizedDate"; +import { Separator } from "react-aria-components"; +import { setHours, setMinutes } from "date-fns"; type Props = { title: string; @@ -78,14 +83,16 @@ const PublishPostForm = ( ); let [localTags, setLocalTags] = useState([]); + let [localPublishedAt, setLocalPublishedAt] = useState( + undefined, + ); // Get cover image from Replicache let replicacheCoverImage = useSubscribe(rep, (tx) => tx.get("publication_cover_image"), ); // Use Replicache tags only when we have a draft - const hasDraft = props.hasDraft; - const currentTags = hasDraft + const currentTags = props.hasDraft ? Array.isArray(replicacheTags) ? replicacheTags : [] @@ -93,7 +100,7 @@ const PublishPostForm = ( // Update tags via Replicache mutation or local state depending on context const handleTagsChange = async (newTags: string[]) => { - if (hasDraft) { + if (props.hasDraft) { await rep?.mutate.updatePublicationDraft({ tags: newTags, }); @@ -116,6 +123,7 @@ const PublishPostForm = ( tags: currentTags, cover_image: replicacheCoverImage, entitiesToDelete: props.entitiesToDelete, + publishedAt: localPublishedAt?.toISOString() || new Date().toISOString(), }); if (!result.success) { @@ -168,15 +176,13 @@ const PublishPostForm = ( record={props.record} />
-
+

Tags

+
+
@@ -219,6 +234,94 @@ const PublishPostForm = ( ); }; +const BackdateOptions = (props: { + publishedAt: Date | undefined; + setPublishedAt: (date: Date | undefined) => void; +}) => { + const formattedDate = useLocalizedDate( + props.publishedAt?.toISOString() || "", + { + month: "short", + day: "numeric", + year: "numeric", + hour: "numeric", + minute: "numeric", + hour12: true, + }, + ); + + const [timeValue, setTimeValue] = useState(() => { + const date = props.publishedAt || new Date(); + return `${date.getHours().toString().padStart(2, "0")}:${date.getMinutes().toString().padStart(2, "0")}`; + }); + + let currentTime = `${new Date().getHours().toString().padStart(2, "0")}:${new Date().getMinutes().toString().padStart(2, "0")}`; + + const handleTimeChange = (time: string) => { + setTimeValue(time); + if (!props.publishedAt) return; + + const [hours, minutes] = time.split(":").map((str) => parseInt(str, 10)); + const newDate = setHours(setMinutes(props.publishedAt, minutes), hours); + const currentDate = new Date(); + + if (newDate > currentDate) { + props.setPublishedAt(currentDate); + setTimeValue(currentTime); + } else props.setPublishedAt(newDate); + }; + + const handleDateChange = (date: Date | undefined) => { + if (!date) { + props.setPublishedAt(undefined); + return; + } + const [hours, minutes] = timeValue + .split(":") + .map((str) => parseInt(str, 10)); + const newDate = new Date( + date.getFullYear(), + date.getMonth(), + date.getDate(), + hours, + minutes, + ); + const currentDate = new Date(); + if (newDate > currentDate) { + props.setPublishedAt(currentDate); + setTimeValue(currentTime); + } else props.setPublishedAt(newDate); + }; + + return ( +
+

Publish Date

+ {formattedDate}
+ ) : ( +
now
+ ) + } + > +
+ date > new Date()} + /> + +
+ +
+
+ +
+ ); +}; + const ShareOptions = (props: { shareOption: "quiet" | "bluesky"; setShareOption: (option: typeof props.shareOption) => void; @@ -232,7 +335,7 @@ const ShareOptions = (props: { }) => { return (
-

Notifications

+

Share and Notify

{ diff --git a/components/Blocks/DateTimeBlock.tsx b/components/Blocks/DateTimeBlock.tsx index 437b0442..b60d8494 100644 --- a/components/Blocks/DateTimeBlock.tsx +++ b/components/Blocks/DateTimeBlock.tsx @@ -1,6 +1,5 @@ import { useEntity, useReplicache } from "src/replicache"; import { BlockProps, BlockLayout } from "./Block"; -import { ChevronProps, DayPicker } from "react-day-picker"; import { Popover } from "components/Popover"; import { useEffect, useMemo, useState } from "react"; import { useEntitySetContext } from "components/EntitySetProvider"; @@ -10,8 +9,8 @@ import { Separator } from "react-aria-components"; import { Checkbox } from "components/Checkbox"; import { useHasPageLoaded } from "components/InitialPageLoadProvider"; import { useSpring, animated } from "@react-spring/web"; -import { ArrowRightTiny } from "components/Icons/ArrowRightTiny"; import { BlockCalendarSmall } from "components/Icons/BlockCalendarSmall"; +import { DatePicker } from "components/DatePicker"; export function DateTimeBlock(props: BlockProps) { const [isClient, setIsClient] = useState(false); @@ -167,28 +166,7 @@ export function BaseDateTimeBlock( } >
- , - }} - classNames={{ - months: "relative", - month_caption: - "font-bold text-center w-full bg-border-light mb-2 py-1 rounded-md", - button_next: - "absolute right-0 top-1 p-1 text-secondary hover:text-accent-contrast flex align-center", - button_previous: - "absolute left-0 top-1 p-1 text-secondary hover:text-accent-contrast rotate-180 flex align-center ", - chevron: "text-inherit", - month_grid: "w-full table-fixed", - weekdays: "text-secondary text-sm", - selected: "bg-accent-1! text-accent-2 rounded-md font-bold", - - day: "h-[34px] text-center rounded-md sm:hover:bg-border-light", - outside: "text-border", - today: "font-bold", - }} - mode="single" + @@ -230,11 +208,3 @@ let FadeIn = (props: { children: React.ReactNode; active: boolean }) => { let spring = useSpring({ opacity: props.active ? 1 : 0 }); return {props.children}; }; - -const CustomChevron = (props: ChevronProps) => { - return ( -
- -
- ); -}; diff --git a/components/DatePicker.tsx b/components/DatePicker.tsx new file mode 100644 index 00000000..fa401622 --- /dev/null +++ b/components/DatePicker.tsx @@ -0,0 +1,71 @@ +import { ChevronProps, DayPicker as ReactDayPicker } from "react-day-picker"; +import { ArrowRightTiny } from "components/Icons/ArrowRightTiny"; + +const CustomChevron = (props: ChevronProps) => { + return ( +
+ +
+ ); +}; + +interface DayPickerProps { + selected: Date | undefined; + onSelect: (date: Date | undefined) => void; + disabled?: (date: Date) => boolean; +} + +export const DatePicker = ({ + selected, + onSelect, + disabled, +}: DayPickerProps) => { + return ( + , + }} + classNames={{ + months: "relative", + month_caption: + "font-bold text-center w-full bg-border-light mb-2 py-1 rounded-md", + button_next: + "absolute right-0 top-1 p-1 text-secondary hover:text-accent-contrast flex align-center", + button_previous: + "absolute left-0 top-1 p-1 text-secondary hover:text-accent-contrast rotate-180 flex align-center", + chevron: "text-inherit", + month_grid: "w-full table-fixed", + weekdays: "text-secondary text-sm", + selected: "bg-accent-1! text-accent-2 rounded-md font-bold", + day: "h-[34px] text-center rounded-md sm:hover:bg-border-light", + outside: "text-tertiary", + today: "font-bold", + disabled: "text-border cursor-not-allowed hover:bg-transparent!", + }} + mode="single" + selected={selected} + defaultMonth={selected} + onSelect={onSelect} + disabled={disabled} + /> + ); +}; + +export const TimePicker = (props: { + value: string; + onChange: (time: string) => void; + className?: string; +}) => { + let handleTimeChange: React.ChangeEventHandler = (e) => { + props.onChange(e.target.value); + }; + + return ( + + ); +}; diff --git a/components/Pages/Backdater.tsx b/components/Pages/Backdater.tsx new file mode 100644 index 00000000..261f153d --- /dev/null +++ b/components/Pages/Backdater.tsx @@ -0,0 +1,84 @@ +"use client"; +import { DatePicker, TimePicker } from "components/DatePicker"; +import { useMemo, useState } from "react"; +import { timeAgo } from "src/utils/timeAgo"; +import { Popover } from "components/Popover"; +import { Separator } from "react-aria-components"; +import { useReplicache } from "src/replicache"; +import { create } from "zustand"; + +export const useLocalPublishedAt = create<{ [uri: string]: Date }>(() => ({})); +export const Backdater = (props: { publishedAt: string; docURI: string }) => { + let { rep } = useReplicache(); + let localPublishedAtDate = useLocalPublishedAt((s) => + s[props.docURI] ? s[props.docURI] : null, + ); + let localPublishedAt = useMemo( + () => localPublishedAtDate || new Date(props.publishedAt), + [localPublishedAtDate, props.publishedAt], + ); + + let [timeValue, setTimeValue] = useState( + `${localPublishedAt.getHours().toString().padStart(2, "0")}:${localPublishedAt.getMinutes().toString().padStart(2, "0")}`, + ); + + let currentTime = `${new Date().getHours().toString().padStart(2, "0")}:${new Date().getMinutes().toString().padStart(2, "0")}`; + + const handleTimeChange = async (time: string) => { + setTimeValue(time); + const [hours, minutes] = time.split(":").map((str) => parseInt(str, 10)); + const newDate = new Date(localPublishedAt); + newDate.setHours(hours); + newDate.setMinutes(minutes); + + let currentDate = new Date(); + if (newDate > currentDate) { + useLocalPublishedAt.setState({ [props.docURI]: currentDate }); + setTimeValue(currentTime); + } else { + useLocalPublishedAt.setState({ [props.docURI]: newDate }); + } + }; + + const handleDateChange = async (date: Date | undefined) => { + if (!date) return; + const [hours, minutes] = timeValue + .split(":") + .map((str) => parseInt(str, 10)); + const newDate = new Date(date); + newDate.setHours(hours); + newDate.setMinutes(minutes); + + let currentDate = new Date(); + if (newDate > currentDate) { + useLocalPublishedAt.setState({ [props.docURI]: currentDate }); + + setTimeValue(currentTime); + } else { + useLocalPublishedAt.setState({ [props.docURI]: newDate }); + } + }; + + return ( + + {timeAgo(localPublishedAt.toISOString())} +
+ } + > +
+ date > new Date()} + /> + +
+ +
+
+ + ); +}; diff --git a/components/Pages/PublicationMetadata.tsx b/components/Pages/PublicationMetadata.tsx index db1b7a40..32c458ab 100644 --- a/components/Pages/PublicationMetadata.tsx +++ b/components/Pages/PublicationMetadata.tsx @@ -20,6 +20,8 @@ import { Popover } from "components/Popover"; import { TagSelector } from "components/Tags"; import { useIdentityData } from "components/IdentityProvider"; import { PostHeaderLayout } from "app/lish/[did]/[publication]/[rkey]/PostHeader/PostHeader"; +import { Backdater } from "./Backdater"; + export const PublicationMetadata = () => { let { rep } = useReplicache(); let { data: pub } = useLeafletPublicationData(); @@ -96,7 +98,10 @@ export const PublicationMetadata = () => { {pub.doc ? (

- Published {publishedAt && timeAgo(publishedAt)} + Published{" "} + {publishedAt && ( + + )}

= async (args, ctx) => { await ctx.runOnServer(async (serverCtx) => { console.log("updating"); @@ -670,13 +671,14 @@ const updatePublicationDraft: Mutation<{ } }); await ctx.runOnClient(async ({ tx }) => { - if (args.title !== undefined) - await tx.set("publication_title", args.title); + if (args.title !== undefined) await tx.set("publication_title", args.title); if (args.description !== undefined) await tx.set("publication_description", args.description); if (args.tags !== undefined) await tx.set("publication_tags", args.tags); if (args.cover_image !== undefined) await tx.set("publication_cover_image", args.cover_image); + if (args.localPublishedAt !== undefined) + await tx.set("publication_local_published_at", args.localPublishedAt); }); }; -- 2.51.2