From e144bcf82d31de0908069ee813b4774a0635e46d Mon Sep 17 00:00:00 2001 From: Jared Pereira Date: Mon, 23 Mar 2026 20:58:06 -0700 Subject: [PATCH 1/9] fix mention service indexing --- appview/index.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/appview/index.ts b/appview/index.ts index 0bdf2d76..e795436f 100644 --- a/appview/index.ts +++ b/appview/index.ts @@ -375,7 +375,6 @@ async function handleEvent(evt: Event) { if (evt.collection === "parts.page.mention.service") { if (evt.event === "create" || evt.event === "update") { let record = evt.record as any; - if (!record?.name || !record?.endpoint) return; let { error } = await supabase.from("mention_services").upsert({ uri: evt.uri.toString(), identity_did: evt.did, -- 2.51.2 From 7cd621e634d4f459e6812c677cc863df8825233d Mon Sep 17 00:00:00 2001 From: Jared Pereira Date: Tue, 24 Mar 2026 18:28:16 -0400 Subject: [PATCH 2/9] Fix Android selection handle drag breaking selection state (#274) * Fix Android selection handle drag breaking selection state The highlightSelectionPlugin creates inline decorations (wrapping text in elements) on every selection change. On Android, these DOM mutations during native selection handle drag cause the browser to lose track of the selection handles. Since these decorations are invisible when the editor is focused (via CSS), skip decoration updates for selection-only changes on Android to prevent the DOM mutations. https://claude.ai/code/session_01Qcv5Xm4QcDnzhWdTbfgQh9 * Skip selection-only decoration updates on all platforms The DOM mutations from updating inline decorations on selection changes are unnecessary since the decorations are invisible when the editor is focused via CSS. Removing the Android-only guard avoids the overhead everywhere. https://claude.ai/code/session_01Qcv5Xm4QcDnzhWdTbfgQh9 * Update decoration on blur so toolbar highlight still works The selection highlight needs to be visible when focus moves from the editor to the toolbar (e.g. for entering a link URL). Dispatch an update on blur via handleDOMEvents so the decoration matches the current selection at that point, while still skipping DOM mutations during active selection drag. https://claude.ai/code/session_01Qcv5Xm4QcDnzhWdTbfgQh9 * Trim verbose comment in highlightSelectionPlugin https://claude.ai/code/session_01Qcv5Xm4QcDnzhWdTbfgQh9 * Fix selection highlight not showing when editor is blurred The `.selected .selection-highlight` CSS rule required a `.selected` ancestor class that only exists during multiselect, so the highlight was never visible for single-block text selection (e.g. when clicking the toolbar). Remove the `.selected` ancestor requirement so the decoration is visible whenever the editor loses focus. https://claude.ai/code/session_01Qcv5Xm4QcDnzhWdTbfgQh9 --------- Co-authored-by: Claude --- app/globals.css | 2 +- components/Blocks/TextBlock/plugins.ts | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/app/globals.css b/app/globals.css index 2145c5b7..24130b0a 100644 --- a/app/globals.css +++ b/app/globals.css @@ -338,7 +338,7 @@ pre.shiki { @apply box-decoration-clone; } -.selected .selection-highlight { +.selection-highlight { background-color: Highlight; @apply py-[1.5px]; } diff --git a/components/Blocks/TextBlock/plugins.ts b/components/Blocks/TextBlock/plugins.ts index c78fb953..256ab470 100644 --- a/components/Blocks/TextBlock/plugins.ts +++ b/components/Blocks/TextBlock/plugins.ts @@ -1,11 +1,19 @@ import { Decoration, DecorationSet } from "prosemirror-view"; import { Plugin } from "prosemirror-state"; + export const highlightSelectionPlugin = new Plugin({ state: { init(_, { doc }) { return DecorationSet.empty; }, apply(tr, oldDecorations, oldState, newState) { + // Skip selection-only changes to avoid DOM mutations that break + // native selection handle dragging. On blur, we force an update + // so the highlight is visible when focus moves to the toolbar. + if (!tr.docChanged && !tr.getMeta("updateSelectionHighlight")) { + return oldDecorations; + } + let decorations = []; // Check if there's a selection @@ -20,6 +28,14 @@ export const highlightSelectionPlugin = new Plugin({ }, }, props: { + handleDOMEvents: { + blur(view) { + view.dispatch( + view.state.tr.setMeta("updateSelectionHighlight", true), + ); + return false; + }, + }, decorations(state) { return this.getState(state); }, -- 2.51.2 From c5602126775a19a2a797506ec4dd0065a7550a00 Mon Sep 17 00:00:00 2001 From: Jared Pereira Date: Tue, 24 Mar 2026 15:44:11 -0700 Subject: [PATCH 3/9] add swipe gestures on list blocks Squashed commit of the following: commit 88e9ea4d1c889a4d304438c872112658f61d2b36 Author: Jared Pereira Date: Tue Mar 24 15:38:47 2026 -0700 tweaks commit 15d34c925489742b00b7bcb4f754b90c35a2fde7 Merge: c10e691e 7cd621e6 Author: Jared Pereira Date: Tue Mar 24 15:29:08 2026 -0700 Merge branch 'main' into feature/list-gestures commit c10e691e797c86f14c25ef1a1799c40819f99d1d Author: Jared Pereira Date: Tue Mar 24 09:47:43 2026 -0700 add swipe gesture on list marker --- components/Blocks/Block.tsx | 43 +++++++++++++++++++++++++++++++++---- package-lock.json | 19 ++++++++++++++++ package.json | 1 + 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/components/Blocks/Block.tsx b/components/Blocks/Block.tsx index 1ba258be..370eafbf 100644 --- a/components/Blocks/Block.tsx +++ b/components/Blocks/Block.tsx @@ -9,7 +9,8 @@ import { useLongPress } from "src/hooks/useLongPress"; import { focusBlock } from "src/utils/focusBlock"; import { useHandleDrop } from "./useHandleDrop"; import { useEntitySetContext } from "components/EntitySetProvider"; - +import { indent, outdent } from "src/utils/list-operations"; +import { useDrag } from "@use-gesture/react"; import { TextBlock } from "./TextBlock/index"; import { ImageBlock } from "./ImageBlock"; import { PageLinkBlock } from "./PageLinkBlock"; @@ -37,6 +38,8 @@ import { Separator } from "components/Layout"; import { moveBlockUp, moveBlockDown } from "src/utils/moveBlock"; import { deleteBlock } from "src/utils/deleteBlock"; +const SWIPE_THRESHOLD = 50; + export type Block = { factID: string; parent: string; @@ -76,6 +79,8 @@ export const Block = memo(function Block( nextPosition: props.nextPosition, }); let entity_set = useEntitySetContext(); + let isMobile = useIsMobile(); + let { rep } = useReplicache(); let { isLongPress, longPressHandlers } = useLongPress(() => { if (isTextBlock[props.type]) return; @@ -115,9 +120,39 @@ export const Block = memo(function Block( // THIS IS WHERE YOU SET WHETHER OR NOT AREYOUSURE IS TRIGGERED ON THE DELETE KEY useBlockKeyboardHandlers(props, areYouSure, setAreYouSure); + const bindSwipe = useDrag( + ({ last, movement: [mx] }) => { + if (!last) return; + if (!rep || !props.listData || !entity_set.permissions.write) return; + if (Math.abs(mx) < SWIPE_THRESHOLD) return; + let { foldedBlocks, toggleFold } = useUIState.getState(); + if (mx > 0) { + if (props.previousBlock) { + indent(props, props.previousBlock, rep, { + foldedBlocks, + toggleFold, + }); + } + } else { + outdent(props, props.previousBlock, rep, { + foldedBlocks, + toggleFold, + }); + } + }, + { + axis: "x", + filterTaps: true, + pointer: { touch: true }, + enabled: isMobile && !!props.listData, + }, + ); + return (
{ - let isMobile = useIsMobile(); let checklist = useEntity(props.value, "block/check-list"); let listStyle = useEntity(props.value, "block/list-style"); let headingLevel = useEntity(props.value, "block/heading-level")?.data.value; @@ -511,7 +546,6 @@ export const ListMarker = ( let [editingNumber, setEditingNumber] = useState(false); let [numberInputValue, setNumberInputValue] = useState(""); - useEffect(() => { if (!editingNumber) { setNumberInputValue(""); @@ -545,6 +579,7 @@ export const ListMarker = ( setEditingNumber(false); }; + return (
= 16.8.0" + } + }, "node_modules/@vercel/analytics": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/@vercel/analytics/-/analytics-1.5.0.tgz", diff --git a/package.json b/package.json index c4c8f256..cccf2886 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "@tinybirdco/sdk": "^0.0.55", "@tiptap/core": "^2.11.5", "@types/mdx": "^2.0.13", + "@use-gesture/react": "^10.3.1", "@vercel/analytics": "^1.5.0", "@vercel/functions": "^2.2.12", "@vercel/sdk": "^1.11.4", -- 2.51.2 From 1561298adfe0da3e6e0d4715dba024a09904e5b6 Mon Sep 17 00:00:00 2001 From: Jared Pereira Date: Tue, 24 Mar 2026 16:17:09 -0700 Subject: [PATCH 4/9] prevent text selection after swipe --- components/Blocks/Block.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/Blocks/Block.tsx b/components/Blocks/Block.tsx index 370eafbf..6a9300f6 100644 --- a/components/Blocks/Block.tsx +++ b/components/Blocks/Block.tsx @@ -121,10 +121,11 @@ export const Block = memo(function Block( useBlockKeyboardHandlers(props, areYouSure, setAreYouSure); const bindSwipe = useDrag( - ({ last, movement: [mx] }) => { + ({ last, movement: [mx], event }) => { if (!last) return; if (!rep || !props.listData || !entity_set.permissions.write) return; if (Math.abs(mx) < SWIPE_THRESHOLD) return; + event?.preventDefault(); let { foldedBlocks, toggleFold } = useUIState.getState(); if (mx > 0) { if (props.previousBlock) { -- 2.51.2 From d1c1952a020e49b03911de3f924e2d952b55cc96 Mon Sep 17 00:00:00 2001 From: Jared Pereira Date: Tue, 24 Mar 2026 18:56:37 -0700 Subject: [PATCH 5/9] fix bsky post ref and tag in update flow --- actions/publishToPublication.ts | 41 ++++++++++++++++------ app/[leaflet_id]/actions/PublishButton.tsx | 7 ++-- 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/actions/publishToPublication.ts b/actions/publishToPublication.ts index d125d0be..288b0d91 100644 --- a/actions/publishToPublication.ts +++ b/actions/publishToPublication.ts @@ -182,7 +182,7 @@ export async function publishToPublication({ credentialSession.did!, ); - let existingRecord: Partial = {}; + let existingRecord: Partial = {}; const normalizedDoc = normalizeDocumentRecord(draft?.documents?.data); if (normalizedDoc) { // When reading existing data, use normalized format to extract fields @@ -194,6 +194,7 @@ export async function publishToPublication({ tags: normalizedDoc.tags, coverImage: normalizedDoc.coverImage, theme: normalizedDoc.theme, + bskyPostRef: normalizedDoc.bskyPostRef, }; } @@ -249,6 +250,14 @@ export async function publishToPublication({ // Determine the rkey early since we need it for the path field const rkey = existingDocUri ? new AtUri(existingDocUri).rkey : TID.nextStr(); + // Resolve fields: use new values if provided, otherwise preserve existing + const resolvedDescription = + description !== undefined ? description : existingRecord.description; + const resolvedTags = tags !== undefined ? tags : existingRecord.tags; + const resolvedCoverImage = coverImageBlob ?? existingRecord.coverImage; + const resolvedPublishedAt = + publishedAt || existingRecord.publishedAt || new Date().toISOString(); + // Create record based on the document type let record: PubLeafletDocument.Record | SiteStandardDocument.Record; @@ -263,11 +272,15 @@ export async function publishToPublication({ title: title || "", site: siteUri, path: "/" + rkey, - publishedAt: - publishedAt || existingRecord.publishedAt || new Date().toISOString(), - ...(description && { description }), - ...(tags !== undefined && { tags }), - ...(coverImageBlob && { coverImage: coverImageBlob }), + publishedAt: resolvedPublishedAt, + ...(resolvedDescription !== undefined && { + description: resolvedDescription, + }), + ...(resolvedTags !== undefined && { tags: resolvedTags }), + ...(resolvedCoverImage && { coverImage: resolvedCoverImage }), + ...(existingRecord.bskyPostRef && { + bskyPostRef: existingRecord.bskyPostRef, + }), // Include theme for standalone documents (not for publication documents) ...(!publication_uri && theme && { theme }), ...(preferences && { @@ -295,12 +308,14 @@ export async function publishToPublication({ }, }), title: title || "", - description: description || "", - ...(tags !== undefined && { tags }), - ...(coverImageBlob && { coverImage: coverImageBlob }), + description: resolvedDescription || "", + ...(resolvedTags !== undefined && { tags: resolvedTags }), + ...(resolvedCoverImage && { coverImage: resolvedCoverImage }), + ...(existingRecord.bskyPostRef && { + postRef: existingRecord.bskyPostRef, + }), pages: pagesArray, - publishedAt: - publishedAt || existingRecord.publishedAt || new Date().toISOString(), + publishedAt: resolvedPublishedAt, } satisfies PubLeafletDocument.Record; } @@ -332,6 +347,8 @@ export async function publishToPublication({ publication: publication_uri, title: title, description: description, + tags: resolvedTags ?? [], + cover_image: cover_image ?? null, }), ]); } else { @@ -341,6 +358,8 @@ export async function publishToPublication({ document: result.uri, title: title || "", description: description || "", + tags: resolvedTags ?? [], + cover_image: cover_image ?? null, }); // Heuristic: Remove title entities if this is the first time publishing standalone diff --git a/app/[leaflet_id]/actions/PublishButton.tsx b/app/[leaflet_id]/actions/PublishButton.tsx index c2497139..5991f28c 100644 --- a/app/[leaflet_id]/actions/PublishButton.tsx +++ b/app/[leaflet_id]/actions/PublishButton.tsx @@ -65,7 +65,7 @@ export const PublishButton = (props: { entityID: string }) => { const UpdateButton = () => { let [isLoading, setIsLoading] = useState(false); - let { data: pub, mutate } = useLeafletPublicationData(); + let { data: pub, mutate, normalizedDocument } = useLeafletPublicationData(); let { permission_token, rootEntity, rep } = useReplicache(); let { identity } = useIdentityData(); let toaster = useToaster(); @@ -88,8 +88,11 @@ const UpdateButton = () => { : pub?.description || ""; // Get tags from Replicache state (same as draft editor) + // Fall back to normalized document tags if Replicache hasn't pulled yet let tags = useSubscribe(rep, (tx) => tx.get("publication_tags")); - const currentTags = Array.isArray(tags) ? tags : []; + const currentTags = Array.isArray(tags) + ? tags + : normalizedDocument?.tags ?? []; // Get cover image from Replicache state let coverImage = useSubscribe(rep, (tx) => -- 2.51.2 From b1d4212d031b64404d68cead0daf93e2a7e7a068 Mon Sep 17 00:00:00 2001 From: Jared Pereira Date: Wed, 25 Mar 2026 12:49:38 -0700 Subject: [PATCH 6/9] remove unsupported rss tags --- app/lish/[did]/[publication]/generateFeed.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/app/lish/[did]/[publication]/generateFeed.ts b/app/lish/[did]/[publication]/generateFeed.ts index 94227ea0..abe30c65 100644 --- a/app/lish/[did]/[publication]/generateFeed.ts +++ b/app/lish/[did]/[publication]/generateFeed.ts @@ -93,6 +93,17 @@ export async function generateFeed( } } + let content = chunks.join(""); + // Strip preload tags injected by React SSR — they trigger + // security warnings in RSS validators and aren't useful in feeds. + content = content.replace(/]*>/gi, ""); + // Convert relative URLs to absolute so RSS readers can resolve them. + const baseUrl = pubRecord.url.replace(/\/$/, ""); + content = content.replace( + /(src|href)="\/(?!\/)/g, + `$1="${baseUrl}/`, + ); + const docUrl = getDocumentURL(record, doc.documents.uri, pubRecord); feed.addItem({ title: record.title, @@ -100,7 +111,7 @@ export async function generateFeed( date: record.publishedAt ? new Date(record.publishedAt) : new Date(), id: docUrl, link: docUrl, - content: chunks.join(""), + content, }); } -- 2.51.2 From 095bf7ceb3d826c2ebbb12039033dd8e6d838d45 Mon Sep 17 00:00:00 2001 From: Jared Pereira Date: Wed, 25 Mar 2026 13:27:12 -0700 Subject: [PATCH 7/9] update middleware route cache --- middleware.ts | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/middleware.ts b/middleware.ts index 5181b052..27b6e977 100644 --- a/middleware.ts +++ b/middleware.ts @@ -1,5 +1,6 @@ import { AtUri } from "@atproto/syntax"; import { createClient } from "@supabase/supabase-js"; +import { getCache } from "@vercel/functions"; import { NextRequest, NextResponse } from "next/server"; import { Database } from "supabase/database.types"; @@ -19,21 +20,22 @@ export const config = { let supabase = createClient( process.env.NEXT_PUBLIC_SUPABASE_API_URL as string, process.env.SUPABASE_SERVICE_ROLE_KEY as string, - { - global: { - fetch: async (...args) => { - const response = await fetch(args[0], { - ...args[1], - next: { - revalidate: 60, - }, - }); - return response; - }, - }, - }, ); +const cache = getCache(); + +async function getDomainRoutes(hostname: string) { + let { data } = await supabase + .from("custom_domains") + .select( + "*, custom_domain_routes(*), publication_domains(*, publications(*))", + ) + .eq("domain", hostname) + .single(); + return data; +} +type DomainRoutes = Awaited>; + const auth_callback_route = "/auth_callback"; const receive_auth_callback_route = "/receive_auth_callback"; export default async function middleware(req: NextRequest) { @@ -44,13 +46,21 @@ export default async function middleware(req: NextRequest) { if (hostname === "leaflet.pub") return; if (req.nextUrl.pathname === "/not-found") return; - let { data: routes } = await supabase - .from("custom_domains") - .select( - "*, custom_domain_routes(*), publication_domains(*, publications(*))", - ) - .eq("domain", hostname) - .single(); + let routes: DomainRoutes = null; + try { + routes = (await cache.get(`domain:${hostname}`)) as DomainRoutes; + } catch {} + if (!routes) { + routes = await getDomainRoutes(hostname); + if (routes) { + try { + await cache.set(`domain:${hostname}`, routes, { + ttl: 60, + tags: [`domain:${hostname}`], + }); + } catch {} + } + } let pub = routes?.publication_domains[0]?.publications; if (pub) { -- 2.51.2 From 0034da769a7fbec490e9281f5a2c90ec5bea3dad Mon Sep 17 00:00:00 2001 From: Jared Pereira Date: Wed, 25 Mar 2026 14:07:15 -0700 Subject: [PATCH 8/9] add unified function for getting leaflet page data --- ...260325000000_add_get_leaflet_page_data.sql | 100 ++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 supabase/migrations/20260325000000_add_get_leaflet_page_data.sql diff --git a/supabase/migrations/20260325000000_add_get_leaflet_page_data.sql b/supabase/migrations/20260325000000_add_get_leaflet_page_data.sql new file mode 100644 index 00000000..dc5c0399 --- /dev/null +++ b/supabase/migrations/20260325000000_add_get_leaflet_page_data.sql @@ -0,0 +1,100 @@ +CREATE OR REPLACE FUNCTION public.get_leaflet_page_data(p_token_id uuid) +RETURNS TABLE ( + permission_token json, + permission_token_rights json, + leaflets_in_publications json, + leaflets_to_documents json, + custom_domain_routes json, + facts json +) +LANGUAGE sql STABLE +AS $$ +WITH token AS ( + SELECT pt.* + FROM permission_tokens pt + WHERE pt.id = p_token_id +), +token_rights AS ( + SELECT json_agg(row_to_json(ptr)) AS rights, array_agg(ptr.entity_set) AS entity_sets + FROM permission_token_rights ptr + WHERE ptr.token = p_token_id +), +related_tokens AS ( + SELECT array_agg(pt2.id) AS ids + FROM permission_token_rights ptr2 + JOIN permission_tokens pt2 ON pt2.id = ptr2.token + WHERE ptr2.entity_set IN (SELECT unnest(entity_sets) FROM token_rights) + AND pt2.id != p_token_id +), +lip_direct AS ( + SELECT json_agg(row_to_json(sub)) AS data + FROM ( + SELECT lip.*, + row_to_json(pub) AS publications, + row_to_json(d) AS documents + FROM leaflets_in_publications lip + LEFT JOIN publications pub ON pub.uri = lip.publication + LEFT JOIN documents d ON d.uri = lip.doc + WHERE lip.leaflet = p_token_id + ) sub +), +lip_fallback AS ( + SELECT json_agg(row_to_json(sub)) AS data + FROM ( + SELECT lip.*, + row_to_json(pub) AS publications, + row_to_json(d) AS documents + FROM leaflets_in_publications lip + LEFT JOIN publications pub ON pub.uri = lip.publication + LEFT JOIN documents d ON d.uri = lip.doc + WHERE lip.leaflet IN (SELECT unnest(ids) FROM related_tokens) + ) sub +), +ltd_direct AS ( + SELECT json_agg(row_to_json(sub)) AS data + FROM ( + SELECT ltd.*, + row_to_json(doc) AS documents + FROM leaflets_to_documents ltd + LEFT JOIN documents doc ON doc.uri = ltd.document + WHERE ltd.leaflet = p_token_id + ) sub +), +ltd_fallback AS ( + SELECT json_agg(row_to_json(sub)) AS data + FROM ( + SELECT ltd.*, + row_to_json(doc) AS documents + FROM leaflets_to_documents ltd + LEFT JOIN documents doc ON doc.uri = ltd.document + WHERE ltd.leaflet IN (SELECT unnest(ids) FROM related_tokens) + ) sub +), +cdr AS ( + SELECT json_agg(row_to_json(c)) AS data + FROM custom_domain_routes c + WHERE c.edit_permission_token = p_token_id +), +facts AS ( + SELECT json_agg(row_to_json(f)) AS data + FROM get_facts((SELECT root_entity FROM token)) f +) +SELECT + row_to_json(token) AS permission_token, + (SELECT rights FROM token_rights) AS permission_token_rights, + COALESCE((SELECT data FROM lip_direct), (SELECT data FROM lip_fallback)) AS leaflets_in_publications, + COALESCE((SELECT data FROM ltd_direct), (SELECT data FROM ltd_fallback)) AS leaflets_to_documents, + (SELECT data FROM cdr) AS custom_domain_routes, + (SELECT data FROM facts) AS facts +FROM token; +$$; + +-- Indexes for get_leaflet_page_data query patterns +CREATE INDEX IF NOT EXISTS leaflets_in_publications_leaflet_idx + ON public.leaflets_in_publications(leaflet); + +CREATE INDEX IF NOT EXISTS permission_token_rights_entity_set_idx + ON public.permission_token_rights(entity_set); + +CREATE INDEX IF NOT EXISTS custom_domain_routes_edit_permission_token_idx + ON public.custom_domain_routes(edit_permission_token); -- 2.51.2 From eed0d15715dfd8d0313c8e97dfd901d1abb3270a Mon Sep 17 00:00:00 2001 From: celine Date: Wed, 25 Mar 2026 17:53:16 -0400 Subject: [PATCH 9/9] set profile description font to inherit body --- app/(home-pages)/p/[didOrHandle]/ProfileHeader.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/(home-pages)/p/[didOrHandle]/ProfileHeader.tsx b/app/(home-pages)/p/[didOrHandle]/ProfileHeader.tsx index 13cdbfba..3589e780 100644 --- a/app/(home-pages)/p/[didOrHandle]/ProfileHeader.tsx +++ b/app/(home-pages)/p/[didOrHandle]/ProfileHeader.tsx @@ -43,7 +43,6 @@ export const ProfileHeader = (props: {
); - return (
-
+          
             {profileRecord.description
               ? parseDescription(profileRecord.description)
               : null}
-- 
2.51.2