···77import { OmitKey, Un$Typed } from './util'
88import * as PubLeafletDocument from './types/pub/leaflet/document'
99import * as PubLeafletPublication from './types/pub/leaflet/publication'
1010+import * as PubLeafletBlocksBlockquote from './types/pub/leaflet/blocks/blockquote'
1011import * as PubLeafletBlocksCode from './types/pub/leaflet/blocks/code'
1112import * as PubLeafletBlocksHeader from './types/pub/leaflet/blocks/header'
1213import * as PubLeafletBlocksHorizontalRule from './types/pub/leaflet/blocks/horizontalRule'
···37383839export * as PubLeafletDocument from './types/pub/leaflet/document'
3940export * as PubLeafletPublication from './types/pub/leaflet/publication'
4141+export * as PubLeafletBlocksBlockquote from './types/pub/leaflet/blocks/blockquote'
4042export * as PubLeafletBlocksCode from './types/pub/leaflet/blocks/code'
4143export * as PubLeafletBlocksHeader from './types/pub/leaflet/blocks/header'
4244export * as PubLeafletBlocksHorizontalRule from './types/pub/leaflet/blocks/horizontalRule'
···66import { validate as _validate } from '../../../../lexicons'
77import { $Typed, is$typed as _is$typed, OmitKey } from '../../../../util'
88import type * as PubLeafletBlocksText from '../blocks/text'
99+import type * as PubLeafletBlocksBlockquote from '../blocks/blockquote'
910import type * as PubLeafletBlocksHeader from '../blocks/header'
1011import type * as PubLeafletBlocksImage from '../blocks/image'
1112import type * as PubLeafletBlocksUnorderedList from '../blocks/unorderedList'
···3738 $type?: 'pub.leaflet.pages.linearDocument#block'
3839 block:
3940 | $Typed<PubLeafletBlocksText.Main>
4141+ | $Typed<PubLeafletBlocksBlockquote.Main>
4042 | $Typed<PubLeafletBlocksHeader.Main>
4143 | $Typed<PubLeafletBlocksImage.Main>
4244 | $Typed<PubLeafletBlocksUnorderedList.Main>
···11-import { TextSelection } from "prosemirror-state";
11+import { NodeSelection, TextSelection } from "prosemirror-state";
22import { useUIState } from "src/useUIState";
33import { Block } from "components/Blocks/Block";
44import { elementId } from "src/utils/elementId";
···5656 }
57575858 // if its not a text block, that's all we need to do
5959- if (block.type !== "text" && block.type !== "heading") {
5959+ if (
6060+ block.type !== "text" &&
6161+ block.type !== "heading" &&
6262+ block.type !== "blockquote"
6363+ ) {
6064 return true;
6165 }
6266 // if its a text block, and not an empty block that is last on the page,
···101105 }
102106 }
103107104104- nextBlock.view.dispatch(
105105- tr.setSelection(TextSelection.create(tr.doc, pos?.pos || 1)),
106106- );
108108+ if (block.type === "blockquote") {
109109+ let sel = NodeSelection.create(tr.doc, 0);
110110+ nextBlock.view.dispatch(tr.setSelection(sel));
111111+ } else {
112112+ nextBlock.view.dispatch(
113113+ tr.setSelection(TextSelection.create(tr.doc, pos?.pos || 1)),
114114+ );
115115+ }
107116 nextBlock.view.focus();
108117}
109118
+25
src/utils/getBlocksAsHTML.tsx
···162162 </div>,
163163 );
164164 }
165165+ if (b.type === "blockquote") {
166166+ let value = (await scanIndex(tx).eav(b.value, "block/text"))[0];
167167+ if (!value) return "<blockquote></blockquote>";
168168+ let doc = new Y.Doc();
169169+ const update = base64.toByteArray(value.data.value);
170170+ Y.applyUpdate(doc, update);
171171+ let nodes = doc.getXmlElement("prosemirror").toArray();
172172+ //Have to handle this specially because it's a multi-line block
173173+ return `<blockquote>${nodes
174174+ .map((node) => {
175175+ if (node.constructor === Y.XmlElement) {
176176+ let children = node.toArray();
177177+ if (children.length === 0) return "<p></p>";
178178+ return renderToStaticMarkup(
179179+ <RenderYJSFragment
180180+ attrs={{
181181+ "data-alignment": alignment?.data.value,
182182+ }}
183183+ node={node}
184184+ />,
185185+ );
186186+ }
187187+ })
188188+ .join("\n")}</blockquote>`;
189189+ }
165190 let value = (await scanIndex(tx).eav(b.value, "block/text"))[0];
166191 if (!value)
167192 return ignoreWrapper ? "" : `<${wrapper || "p"}></${wrapper || "p"}>`;
···11+create table "public"."comments_on_documents" (
22+ "uri" text not null,
33+ "record" jsonb not null,
44+ "document" text,
55+ "indexed_at" timestamp with time zone not null default now(),
66+ "profile" text
77+);
88+99+1010+alter table "public"."comments_on_documents" enable row level security;
1111+1212+CREATE UNIQUE INDEX comments_on_documents_pkey ON public.comments_on_documents USING btree (uri);
1313+1414+alter table "public"."comments_on_documents" add constraint "comments_on_documents_pkey" PRIMARY KEY using index "comments_on_documents_pkey";
1515+1616+alter table "public"."comments_on_documents" add constraint "comments_on_documents_document_fkey" FOREIGN KEY (document) REFERENCES documents(uri) ON UPDATE CASCADE ON DELETE CASCADE not valid;
1717+1818+alter table "public"."comments_on_documents" validate constraint "comments_on_documents_document_fkey";
1919+2020+alter table "public"."comments_on_documents" add constraint "comments_on_documents_profile_fkey" FOREIGN KEY (profile) REFERENCES bsky_profiles(did) ON UPDATE CASCADE ON DELETE SET NULL not valid;
2121+2222+alter table "public"."comments_on_documents" validate constraint "comments_on_documents_profile_fkey";
2323+2424+alter table "public"."publications" add constraint "publications_identity_did_fkey" FOREIGN KEY (identity_did) REFERENCES identities(atp_did) ON DELETE CASCADE not valid;
2525+2626+alter table "public"."publications" validate constraint "publications_identity_did_fkey";
2727+2828+grant delete on table "public"."comments_on_documents" to "anon";
2929+3030+grant insert on table "public"."comments_on_documents" to "anon";
3131+3232+grant references on table "public"."comments_on_documents" to "anon";
3333+3434+grant select on table "public"."comments_on_documents" to "anon";
3535+3636+grant trigger on table "public"."comments_on_documents" to "anon";
3737+3838+grant truncate on table "public"."comments_on_documents" to "anon";
3939+4040+grant update on table "public"."comments_on_documents" to "anon";
4141+4242+grant delete on table "public"."comments_on_documents" to "authenticated";
4343+4444+grant insert on table "public"."comments_on_documents" to "authenticated";
4545+4646+grant references on table "public"."comments_on_documents" to "authenticated";
4747+4848+grant select on table "public"."comments_on_documents" to "authenticated";
4949+5050+grant trigger on table "public"."comments_on_documents" to "authenticated";
5151+5252+grant truncate on table "public"."comments_on_documents" to "authenticated";
5353+5454+grant update on table "public"."comments_on_documents" to "authenticated";
5555+5656+grant delete on table "public"."comments_on_documents" to "service_role";
5757+5858+grant insert on table "public"."comments_on_documents" to "service_role";
5959+6060+grant references on table "public"."comments_on_documents" to "service_role";
6161+6262+grant select on table "public"."comments_on_documents" to "service_role";
6363+6464+grant trigger on table "public"."comments_on_documents" to "service_role";
6565+6666+grant truncate on table "public"."comments_on_documents" to "service_role";
6767+6868+grant update on table "public"."comments_on_documents" to "service_role";