···77import { email_subscriptions_to_entity } from "drizzle/schema";
88import postgres from "postgres";
99import { getBlocksWithTypeLocal } from "src/hooks/queries/useBlocks";
1010-import { Fact, PermissionToken } from "src/replicache";
1111-import { Attributes } from "src/replicache/attributes";
1010+import type { Fact, PermissionToken } from "src/replicache";
1111+import type { Attribute } from "src/replicache/attributes";
1212import { Database } from "supabase/database.types";
1313import * as Y from "yjs";
1414import { YJSFragmentToString } from "components/Blocks/TextBlock/RenderYJSFragment";
···9090 let { data } = await supabase.rpc("get_facts", {
9191 root: root_entity,
9292 });
9393- let initialFacts = (data as unknown as Fact<keyof typeof Attributes>[]) || [];
9393+ let initialFacts = (data as unknown as Fact<Attribute>[]) || [];
9494 let firstPage = initialFacts.find((f) => f.attribute === "root/page") as
9595 | Fact<"root/page">
9696 | undefined;
···11"use client";
22import { Fact, PermissionToken, ReplicacheProvider } from "src/replicache";
33-import { Attributes } from "src/replicache/attributes";
33+import type { Attribute } from "src/replicache/attributes";
44import { SelectionManager } from "components/SelectionManager";
55import { Pages } from "components/Pages";
66import {
···16161717export function Leaflet(props: {
1818 token: PermissionToken;
1919- initialFacts: Fact<keyof typeof Attributes>[];
1919+ initialFacts: Fact<Attribute>[];
2020 leaflet_id: string;
2121}) {
2222 return (
···3434 <UpdateLeafletTitle entityID={props.leaflet_id} />
3535 <AddLeafletToHomepage />
3636 <SelectionManager />
3737- {/* we need the padding bottom here because if we don't have it the mobile footer will cut off
3737+ {/* we need the padding bottom here because if we don't have it the mobile footer will cut off...
3838 the dropshadow on the page... the padding is compensated by a negative top margin in mobile footer */}
3939 <div
4040 className="leafletContentWrapper w-full relative overflow-x-scroll snap-x snap-mandatory no-scrollbar grow items-stretch flex h-full pb-4 pwa-padding"
4141 id="page-carousel"
4242 >
4343+ {/* if you adjust this padding, remember to adjust the negative margins on page in Pages/index when card borders are hidden (also applies for the pb in the parent div)*/}
4344 <div
4445 id="pages"
4545- className="pages flex pt-2 pb-1 sm:pb-8 sm:py-6"
4646+ className="pages flex pt-2 pb-1 sm:pb-8 sm:pt-6"
4647 onClick={(e) => {
4748 e.currentTarget === e.target && blurPage();
4849 }}
···44 PullResponseV1,
55 VersionNotSupportedResponse,
66} from "replicache";
77-import { Fact } from "src/replicache";
77+import type { Fact } from "src/replicache";
88import { FactWithIndexes } from "src/replicache/utils";
99-import { Attributes } from "src/replicache/attributes";
99+import type { Attribute } from "src/replicache/attributes";
1010import { makeRoute } from "../lib";
1111-import { Env } from "./route";
1111+import type { Env } from "./route";
12121313// First define the sub-types for V0 and V1 requests
1414const pullRequestV0 = z.object({
···9595 return {
9696 op: "put",
9797 key: f.id,
9898- value: FactWithIndexes(
9999- f as unknown as Fact<keyof typeof Attributes>,
100100- ),
9898+ value: FactWithIndexes(f as unknown as Fact<Attribute>),
10199 } as const;
102100 }),
103101 ],
+1-1
app/api/rpc/[command]/push.ts
···66import { getClientGroup } from "src/replicache/utils";
77import { makeRoute } from "../lib";
88import { z } from "zod";
99-import { Env } from "./route";
99+import type { Env } from "./route";
1010import postgres from "postgres";
1111import { drizzle } from "drizzle-orm/postgres-js";
1212
+9-2
app/api/rpc/[command]/route.ts
···77import { pull } from "./pull";
88import { getFactsFromHomeLeaflets } from "./getFactsFromHomeLeaflets";
99import { Vercel } from "@vercel/sdk";
1010-import { get_domain_status, get_leaflet_domains } from "./domain_routes";
1010+import {
1111+ get_domain_status,
1212+ get_leaflet_subdomain_status,
1313+} from "./domain_routes";
1414+import { get_leaflet_data } from "./get_leaflet_data";
1515+import { get_publication_data } from "./get_publication_data";
11161217const client = postgres(process.env.DB_URL as string, { idle_timeout: 5 });
1318let supabase = createClient<Database>(
···3136 pull,
3237 getFactsFromHomeLeaflets,
3338 get_domain_status,
3434- get_leaflet_domains,
3939+ get_leaflet_subdomain_status,
4040+ get_leaflet_data,
4141+ get_publication_data,
3542];
3643export async function POST(
3744 req: Request,
···11import { ImageResponse } from "next/og";
22-import { Fact } from "src/replicache";
33-import { Attributes } from "src/replicache/attributes";
22+import type { Fact } from "src/replicache";
33+import type { Attribute } from "src/replicache/attributes";
44import { Database } from "../../supabase/database.types";
55import { createServerClient } from "@supabase/ssr";
66import { parseHSBToRGB } from "src/utils/parseHSB";
···4949 let { data } = await supabase.rpc("get_facts", {
5050 root: rootEntity,
5151 });
5252- let initialFacts =
5353- (data as unknown as Fact<keyof typeof Attributes>[]) || [];
5252+ let initialFacts = (data as unknown as Fact<Attribute>[]) || [];
5453 let themePageBG = initialFacts.find(
5554 (f) => f.attribute === "theme/card-background",
5655 ) as Fact<"theme/card-background"> | undefined;
···6766 return new ImageResponse(
6867 (
6968 // ImageResponse JSX element
7070- (<div style={{ display: "flex" }}>
6969+ <div style={{ display: "flex" }}>
7170 <svg
7271 width="32"
7372 height="32"
···9190 fill={fillColor ? fillColor : "#272727"}
9291 />
9392 </svg>
9494- </div>)
9393+ </div>
9594 ),
9695 // ImageResponse options
9796 {
+13-21
app/home/page.tsx
···11import { cookies } from "next/headers";
22import { Fact, ReplicacheProvider } from "src/replicache";
33-import { createServerClient } from "@supabase/ssr";
44-import { Database } from "supabase/database.types";
55-import { Attributes } from "src/replicache/attributes";
33+import type { Attribute } from "src/replicache/attributes";
64import {
75 ThemeBackgroundProvider,
86 ThemeProvider,
97} from "components/ThemeManager/ThemeProvider";
108import { EntitySetProvider } from "components/EntitySetProvider";
1111-import { ThemePopover } from "components/ThemeManager/ThemeSetter";
129import { createIdentity } from "actions/createIdentity";
1310import postgres from "postgres";
1411import { drizzle } from "drizzle-orm/postgres-js";
1512import { IdentitySetter } from "./IdentitySetter";
1616-import { HomeHelp } from "./HomeHelp";
1713import { LeafletList } from "./LeafletList";
1818-import { CreateNewLeafletButton } from "./CreateNewButton";
1914import { getIdentityData } from "actions/getIdentityData";
2020-import { LoginButton } from "components/LoginButton";
2121-import { HelpPopover } from "components/HelpPopover";
2222-import { AccountSettings } from "./AccountSettings";
2323-import { LoggedOutWarning } from "./LoggedOutWarning";
2415import { getFactsFromHomeLeaflets } from "app/api/rpc/[command]/getFactsFromHomeLeaflets";
2525-import { Media } from "components/Media";
2626-import { Sidebar } from "components/ActionBar/Sidebar";
2716import { HomeSidebar } from "./HomeSidebar";
2817import { HomeFooter } from "./HomeFooter";
1818+import { Media } from "components/Media";
1919+import { MyPublicationList } from "./Publications";
2020+import { supabaseServerClient } from "supabase/serverClient";
29213030-let supabase = createServerClient<Database>(
3131- process.env.NEXT_PUBLIC_SUPABASE_API_URL as string,
3232- process.env.SUPABASE_SERVICE_ROLE_KEY as string,
3333- { cookies: {} },
3434-);
3522export default async function Home() {
3623 let cookieStore = await cookies();
3724···60476148 let permission_token = auth_res?.home_leaflet;
6249 if (!permission_token) {
6363- let res = await supabase
5050+ let res = await supabaseServerClient
6451 .from("identities")
6552 .select(
6653 `*,
···74617562 if (!permission_token) return <div>no home page wierdly</div>;
7663 let [homeLeafletFacts, allLeafletFacts] = await Promise.all([
7777- supabase.rpc("get_facts", {
6464+ supabaseServerClient.rpc("get_facts", {
7865 root: permission_token.root_entity,
7966 }),
8067 auth_res
···8471 (r) => r.permission_tokens.root_entity,
8572 ),
8673 },
8787- { supabase },
7474+ { supabase: supabaseServerClient },
8875 )
8976 : undefined,
9077 ]);
9178 let initialFacts =
9292- (homeLeafletFacts.data as unknown as Fact<keyof typeof Attributes>[]) || [];
7979+ (homeLeafletFacts.data as unknown as Fact<Attribute>[]) || [];
93809481 let root_entity = permission_token.root_entity;
9582 let home_docs_initialFacts = allLeafletFacts?.result || {};
···11097 <div className="home relative max-w-screen-lg w-full h-full mx-auto flex sm:flex-row flex-col sm:items-stretch sm:px-6 ">
11198 <HomeSidebar />
11299 <div className={`h-full overflow-y-scroll`}>
100100+ <Media mobile>
101101+ <div className="pubListWrapper p-2 ">
102102+ <MyPublicationList />
103103+ </div>
104104+ </Media>
113105 <LeafletList initialFacts={home_docs_initialFacts} />
114106 </div>
115107 <HomeFooter />
+1-1
app/home/storage.ts
···11-import { PermissionToken } from "src/replicache";
11+import type { PermissionToken } from "src/replicache";
22import { mutate } from "swr";
3344export type HomeDoc = {
-10
app/lish/AlphaBanner.tsx
···11-import Link from "next/link";
22-33-export const AlphaBanner = () => {
44- return (
55- <div className="w-full h-fit text-center bg-accent-1 text-accent-2">
66- We're still in Early Alpha! <Link href="./lish/">Sign Up</Link> for
77- Updates :)
88- </div>
99- );
1010-};
···11+.grow-wrap {
22+ /* easy way to plop the elements on top of each other and have them both sized based on the tallest one's height */
33+ display: grid;
44+ position: relative;
55+ max-width: 100%;
66+ overflow-wrap: anywhere; /* limit width in chrome */
77+}
88+99+.grow-wrap::after {
1010+ /* Note the weird space! Needed to preventy jumpy behavior */
1111+ content: attr(data-replicated-value) " ";
1212+1313+ /* This is how textarea text behaves */
1414+ white-space: pre-wrap;
1515+1616+ /* Hidden from view, clicks, and screen readers */
1717+ visibility: hidden;
1818+}
1919+.grow-wrap > textarea {
2020+ /* You could leave this, but after a user resizes, then it ruins the auto sizing */
2121+ resize: none;
2222+2323+ /* Firefox shows scrollbar on growth, you can hide like this. */
2424+ overflow: hidden;
2525+}
2626+.grow-wrap > textarea,
2727+.grow-wrap::after {
2828+ padding: 0;
2929+ width: 100%;
3030+ font: inherit;
3131+ border: none;
3232+ /* Place on top of each other */
3333+ grid-area: 1 / 1 / 2 / 2;
3434+}
3535+3636+.grow-wrap > textarea:focus {
3737+ outline: none;
3838+}
···22 * GENERATED CODE - DO NOT MODIFY
33 */
44import { XrpcClient, FetchHandler, FetchHandlerOptions } from '@atproto/xrpc'
55-import { schemas } from './lexicons.js'
55+import { schemas } from './lexicons'
66import { CID } from 'multiformats/cid'
77-import { OmitKey, Un$Typed } from './util.js'
88-import * as PubLeafletDocument from './types/pub/leaflet/document.js'
99-import * as PubLeafletPost from './types/pub/leaflet/post.js'
1010-import * as PubLeafletPublication from './types/pub/leaflet/publication.js'
1111-import * as PubLeafletBlocksHeader from './types/pub/leaflet/blocks/header.js'
1212-import * as PubLeafletBlocksImage from './types/pub/leaflet/blocks/image.js'
1313-import * as PubLeafletBlocksText from './types/pub/leaflet/blocks/text.js'
1414-import * as PubLeafletPagesLinearDocument from './types/pub/leaflet/pages/linearDocument.js'
1515-import * as ComAtprotoLabelDefs from './types/com/atproto/label/defs.js'
1616-import * as ComAtprotoRepoApplyWrites from './types/com/atproto/repo/applyWrites.js'
1717-import * as ComAtprotoRepoCreateRecord from './types/com/atproto/repo/createRecord.js'
1818-import * as ComAtprotoRepoDefs from './types/com/atproto/repo/defs.js'
1919-import * as ComAtprotoRepoDeleteRecord from './types/com/atproto/repo/deleteRecord.js'
2020-import * as ComAtprotoRepoDescribeRepo from './types/com/atproto/repo/describeRepo.js'
2121-import * as ComAtprotoRepoGetRecord from './types/com/atproto/repo/getRecord.js'
2222-import * as ComAtprotoRepoImportRepo from './types/com/atproto/repo/importRepo.js'
2323-import * as ComAtprotoRepoListMissingBlobs from './types/com/atproto/repo/listMissingBlobs.js'
2424-import * as ComAtprotoRepoListRecords from './types/com/atproto/repo/listRecords.js'
2525-import * as ComAtprotoRepoPutRecord from './types/com/atproto/repo/putRecord.js'
2626-import * as ComAtprotoRepoStrongRef from './types/com/atproto/repo/strongRef.js'
2727-import * as ComAtprotoRepoUploadBlob from './types/com/atproto/repo/uploadBlob.js'
77+import { OmitKey, Un$Typed } from './util'
88+import * as PubLeafletDocument from './types/pub/leaflet/document'
99+import * as PubLeafletPublication from './types/pub/leaflet/publication'
1010+import * as PubLeafletBlocksHeader from './types/pub/leaflet/blocks/header'
1111+import * as PubLeafletBlocksImage from './types/pub/leaflet/blocks/image'
1212+import * as PubLeafletBlocksText from './types/pub/leaflet/blocks/text'
1313+import * as PubLeafletBlocksUnorderedList from './types/pub/leaflet/blocks/unorderedList'
1414+import * as PubLeafletPagesLinearDocument from './types/pub/leaflet/pages/linearDocument'
1515+import * as PubLeafletRichtextFacet from './types/pub/leaflet/richtext/facet'
1616+import * as ComAtprotoLabelDefs from './types/com/atproto/label/defs'
1717+import * as ComAtprotoRepoApplyWrites from './types/com/atproto/repo/applyWrites'
1818+import * as ComAtprotoRepoCreateRecord from './types/com/atproto/repo/createRecord'
1919+import * as ComAtprotoRepoDefs from './types/com/atproto/repo/defs'
2020+import * as ComAtprotoRepoDeleteRecord from './types/com/atproto/repo/deleteRecord'
2121+import * as ComAtprotoRepoDescribeRepo from './types/com/atproto/repo/describeRepo'
2222+import * as ComAtprotoRepoGetRecord from './types/com/atproto/repo/getRecord'
2323+import * as ComAtprotoRepoImportRepo from './types/com/atproto/repo/importRepo'
2424+import * as ComAtprotoRepoListMissingBlobs from './types/com/atproto/repo/listMissingBlobs'
2525+import * as ComAtprotoRepoListRecords from './types/com/atproto/repo/listRecords'
2626+import * as ComAtprotoRepoPutRecord from './types/com/atproto/repo/putRecord'
2727+import * as ComAtprotoRepoStrongRef from './types/com/atproto/repo/strongRef'
2828+import * as ComAtprotoRepoUploadBlob from './types/com/atproto/repo/uploadBlob'
28292929-export * as PubLeafletDocument from './types/pub/leaflet/document.js'
3030-export * as PubLeafletPost from './types/pub/leaflet/post.js'
3131-export * as PubLeafletPublication from './types/pub/leaflet/publication.js'
3232-export * as PubLeafletBlocksHeader from './types/pub/leaflet/blocks/header.js'
3333-export * as PubLeafletBlocksImage from './types/pub/leaflet/blocks/image.js'
3434-export * as PubLeafletBlocksText from './types/pub/leaflet/blocks/text.js'
3535-export * as PubLeafletPagesLinearDocument from './types/pub/leaflet/pages/linearDocument.js'
3636-export * as ComAtprotoLabelDefs from './types/com/atproto/label/defs.js'
3737-export * as ComAtprotoRepoApplyWrites from './types/com/atproto/repo/applyWrites.js'
3838-export * as ComAtprotoRepoCreateRecord from './types/com/atproto/repo/createRecord.js'
3939-export * as ComAtprotoRepoDefs from './types/com/atproto/repo/defs.js'
4040-export * as ComAtprotoRepoDeleteRecord from './types/com/atproto/repo/deleteRecord.js'
4141-export * as ComAtprotoRepoDescribeRepo from './types/com/atproto/repo/describeRepo.js'
4242-export * as ComAtprotoRepoGetRecord from './types/com/atproto/repo/getRecord.js'
4343-export * as ComAtprotoRepoImportRepo from './types/com/atproto/repo/importRepo.js'
4444-export * as ComAtprotoRepoListMissingBlobs from './types/com/atproto/repo/listMissingBlobs.js'
4545-export * as ComAtprotoRepoListRecords from './types/com/atproto/repo/listRecords.js'
4646-export * as ComAtprotoRepoPutRecord from './types/com/atproto/repo/putRecord.js'
4747-export * as ComAtprotoRepoStrongRef from './types/com/atproto/repo/strongRef.js'
4848-export * as ComAtprotoRepoUploadBlob from './types/com/atproto/repo/uploadBlob.js'
3030+export * as PubLeafletDocument from './types/pub/leaflet/document'
3131+export * as PubLeafletPublication from './types/pub/leaflet/publication'
3232+export * as PubLeafletBlocksHeader from './types/pub/leaflet/blocks/header'
3333+export * as PubLeafletBlocksImage from './types/pub/leaflet/blocks/image'
3434+export * as PubLeafletBlocksText from './types/pub/leaflet/blocks/text'
3535+export * as PubLeafletBlocksUnorderedList from './types/pub/leaflet/blocks/unorderedList'
3636+export * as PubLeafletPagesLinearDocument from './types/pub/leaflet/pages/linearDocument'
3737+export * as PubLeafletRichtextFacet from './types/pub/leaflet/richtext/facet'
3838+export * as ComAtprotoLabelDefs from './types/com/atproto/label/defs'
3939+export * as ComAtprotoRepoApplyWrites from './types/com/atproto/repo/applyWrites'
4040+export * as ComAtprotoRepoCreateRecord from './types/com/atproto/repo/createRecord'
4141+export * as ComAtprotoRepoDefs from './types/com/atproto/repo/defs'
4242+export * as ComAtprotoRepoDeleteRecord from './types/com/atproto/repo/deleteRecord'
4343+export * as ComAtprotoRepoDescribeRepo from './types/com/atproto/repo/describeRepo'
4444+export * as ComAtprotoRepoGetRecord from './types/com/atproto/repo/getRecord'
4545+export * as ComAtprotoRepoImportRepo from './types/com/atproto/repo/importRepo'
4646+export * as ComAtprotoRepoListMissingBlobs from './types/com/atproto/repo/listMissingBlobs'
4747+export * as ComAtprotoRepoListRecords from './types/com/atproto/repo/listRecords'
4848+export * as ComAtprotoRepoPutRecord from './types/com/atproto/repo/putRecord'
4949+export * as ComAtprotoRepoStrongRef from './types/com/atproto/repo/strongRef'
5050+export * as ComAtprotoRepoUploadBlob from './types/com/atproto/repo/uploadBlob'
49515052export const PUB_LEAFLET_PAGES = {
5153 LinearDocumentTextAlignLeft: 'pub.leaflet.pages.linearDocument#textAlignLeft',
···8486export class PubLeafletNS {
8587 _client: XrpcClient
8688 document: DocumentRecord
8787- post: PostRecord
8889 publication: PublicationRecord
8990 blocks: PubLeafletBlocksNS
9091 pages: PubLeafletPagesNS
9292+ richtext: PubLeafletRichtextNS
91939294 constructor(client: XrpcClient) {
9395 this._client = client
9496 this.blocks = new PubLeafletBlocksNS(client)
9597 this.pages = new PubLeafletPagesNS(client)
9898+ this.richtext = new PubLeafletRichtextNS(client)
9699 this.document = new DocumentRecord(client)
9797- this.post = new PostRecord(client)
98100 this.publication = new PublicationRecord(client)
99101 }
100102}
···115117 }
116118}
117119120120+export class PubLeafletRichtextNS {
121121+ _client: XrpcClient
122122+123123+ constructor(client: XrpcClient) {
124124+ this._client = client
125125+ }
126126+}
127127+118128export class DocumentRecord {
119129 _client: XrpcClient
120130···171181 'com.atproto.repo.deleteRecord',
172182 undefined,
173183 { collection: 'pub.leaflet.document', ...params },
174174- { headers },
175175- )
176176- }
177177-}
178178-179179-export class PostRecord {
180180- _client: XrpcClient
181181-182182- constructor(client: XrpcClient) {
183183- this._client = client
184184- }
185185-186186- async list(
187187- params: OmitKey<ComAtprotoRepoListRecords.QueryParams, 'collection'>,
188188- ): Promise<{
189189- cursor?: string
190190- records: { uri: string; value: PubLeafletPost.Record }[]
191191- }> {
192192- const res = await this._client.call('com.atproto.repo.listRecords', {
193193- collection: 'pub.leaflet.post',
194194- ...params,
195195- })
196196- return res.data
197197- }
198198-199199- async get(
200200- params: OmitKey<ComAtprotoRepoGetRecord.QueryParams, 'collection'>,
201201- ): Promise<{ uri: string; cid: string; value: PubLeafletPost.Record }> {
202202- const res = await this._client.call('com.atproto.repo.getRecord', {
203203- collection: 'pub.leaflet.post',
204204- ...params,
205205- })
206206- return res.data
207207- }
208208-209209- async create(
210210- params: OmitKey<
211211- ComAtprotoRepoCreateRecord.InputSchema,
212212- 'collection' | 'record'
213213- >,
214214- record: Un$Typed<PubLeafletPost.Record>,
215215- headers?: Record<string, string>,
216216- ): Promise<{ uri: string; cid: string }> {
217217- const collection = 'pub.leaflet.post'
218218- const res = await this._client.call(
219219- 'com.atproto.repo.createRecord',
220220- undefined,
221221- { collection, ...params, record: { ...record, $type: collection } },
222222- { encoding: 'application/json', headers },
223223- )
224224- return res.data
225225- }
226226-227227- async delete(
228228- params: OmitKey<ComAtprotoRepoDeleteRecord.InputSchema, 'collection'>,
229229- headers?: Record<string, string>,
230230- ): Promise<void> {
231231- await this._client.call(
232232- 'com.atproto.repo.deleteRecord',
233233- undefined,
234234- { collection: 'pub.leaflet.post', ...params },
235184 { headers },
236185 )
237186 }
···66import { CID } from 'multiformats/cid'
77import { validate as _validate } from '../../../../lexicons'
88import { $Typed, is$typed as _is$typed, OmitKey } from '../../../../util'
99-import type * as ComAtprotoRepoDefs from './defs.js'
99+import type * as ComAtprotoRepoDefs from './defs'
10101111const is$typed = _is$typed,
1212 validate = _validate
···66import { CID } from 'multiformats/cid'
77import { validate as _validate } from '../../../../lexicons'
88import { $Typed, is$typed as _is$typed, OmitKey } from '../../../../util'
99-import type * as ComAtprotoRepoDefs from './defs.js'
99+import type * as ComAtprotoRepoDefs from './defs'
10101111const is$typed = _is$typed,
1212 validate = _validate
···66import { CID } from 'multiformats/cid'
77import { validate as _validate } from '../../../../lexicons'
88import { $Typed, is$typed as _is$typed, OmitKey } from '../../../../util'
99-import type * as ComAtprotoRepoDefs from './defs.js'
99+import type * as ComAtprotoRepoDefs from './defs'
10101111const is$typed = _is$typed,
1212 validate = _validate
+1-1
lexicons/api/types/com/atproto/repo/putRecord.ts
···66import { CID } from 'multiformats/cid'
77import { validate as _validate } from '../../../../lexicons'
88import { $Typed, is$typed as _is$typed, OmitKey } from '../../../../util'
99-import type * as ComAtprotoRepoDefs from './defs.js'
99+import type * as ComAtprotoRepoDefs from './defs'
10101111const is$typed = _is$typed,
1212 validate = _validate
+3-1
lexicons/api/types/pub/leaflet/blocks/header.ts
···55import { CID } from 'multiformats/cid'
66import { validate as _validate } from '../../../../lexicons'
77import { $Typed, is$typed as _is$typed, OmitKey } from '../../../../util'
88+import type * as PubLeafletRichtextFacet from '../richtext/facet'
89910const is$typed = _is$typed,
1011 validate = _validate
···1314export interface Main {
1415 $type?: 'pub.leaflet.blocks.header'
1516 level?: number
1616- plaintext?: string
1717+ plaintext: string
1818+ facets?: PubLeafletRichtextFacet.Main[]
1719}
18201921const hashMain = 'main'
+3-1
lexicons/api/types/pub/leaflet/blocks/text.ts
···55import { CID } from 'multiformats/cid'
66import { validate as _validate } from '../../../../lexicons'
77import { $Typed, is$typed as _is$typed, OmitKey } from '../../../../util'
88+import type * as PubLeafletRichtextFacet from '../richtext/facet'
89910const is$typed = _is$typed,
1011 validate = _validate
···12131314export interface Main {
1415 $type?: 'pub.leaflet.blocks.text'
1515- plaintext?: string
1616+ plaintext: string
1717+ facets?: PubLeafletRichtextFacet.Main[]
1618}
17191820const hashMain = 'main'
···55import { CID } from 'multiformats/cid'
66import { validate as _validate } from '../../../../lexicons'
77import { $Typed, is$typed as _is$typed, OmitKey } from '../../../../util'
88-import type * as PubLeafletBlocksText from '../blocks/text.js'
99-import type * as PubLeafletBlocksHeader from '../blocks/header.js'
1010-import type * as PubLeafletBlocksImage from '../blocks/image.js'
88+import type * as PubLeafletBlocksText from '../blocks/text'
99+import type * as PubLeafletBlocksHeader from '../blocks/header'
1010+import type * as PubLeafletBlocksImage from '../blocks/image'
1111+import type * as PubLeafletBlocksUnorderedList from '../blocks/unorderedList'
11121213const is$typed = _is$typed,
1314 validate = _validate
···3435 | $Typed<PubLeafletBlocksText.Main>
3536 | $Typed<PubLeafletBlocksHeader.Main>
3637 | $Typed<PubLeafletBlocksImage.Main>
3838+ | $Typed<PubLeafletBlocksUnorderedList.Main>
3739 | { $type: string }
3840 alignment?:
3941 | 'lex:pub.leaflet.pages.linearDocument#textAlignLeft'
-30
lexicons/api/types/pub/leaflet/post.ts
···11-/**
22- * GENERATED CODE - DO NOT MODIFY
33- */
44-import { ValidationResult, BlobRef } from '@atproto/lexicon'
55-import { CID } from 'multiformats/cid'
66-import { validate as _validate } from '../../../lexicons'
77-import { $Typed, is$typed as _is$typed, OmitKey } from '../../../util'
88-import type * as ComAtprotoRepoStrongRef from '../../com/atproto/repo/strongRef.js'
99-1010-const is$typed = _is$typed,
1111- validate = _validate
1212-const id = 'pub.leaflet.post'
1313-1414-export interface Record {
1515- $type: 'pub.leaflet.post'
1616- publication?: string
1717- post: ComAtprotoRepoStrongRef.Main
1818- publishedAt: string
1919- [k: string]: unknown
2020-}
2121-2222-const hashRecord = 'main'
2323-2424-export function isRecord<V>(v: V) {
2525- return is$typed(v, id, hashRecord)
2626-}
2727-2828-export function validateRecord<V>(v: V) {
2929- return validate<Record & V>(v, id, hashRecord, true)
3030-}
···44import * as Y from "yjs";
55import { MutationContext } from "./mutations";
66import { entities, facts } from "drizzle/schema";
77-import { Attributes, FilterAttributes } from "./attributes";
77+import { Attribute, Attributes, FilterAttributes } from "./attributes";
88import { Fact, PermissionToken } from ".";
99import { DeepReadonly } from "replicache";
1010import { createClient } from "@supabase/supabase-js";
···7777 },
7878 async assertFact(f) {
7979 if (!f.entity) return;
8080- let attribute = Attributes[f.attribute as keyof typeof Attributes];
8080+ let attribute = Attributes[f.attribute as Attribute];
8181 if (!attribute) return;
8282 let id = f.id || v7();
8383 let data = { ...f.data };
+5-8
src/replicache/utils.ts
···11import { PostgresJsDatabase } from "drizzle-orm/postgres-js";
22import * as driz from "drizzle-orm";
33-import { Fact } from ".";
33+import type { Fact } from ".";
44import { replicache_clients } from "drizzle/schema";
55-import { Attributes, FilterAttributes } from "./attributes";
55+import type { Attribute, FilterAttributes } from "./attributes";
66import { ReadTransaction, WriteTransaction } from "replicache";
7788-export function FactWithIndexes(f: Fact<keyof typeof Attributes>) {
88+export function FactWithIndexes(f: Fact<Attribute>) {
99 let indexes: {
1010 eav: string;
1111 aev: string;
···4242}
43434444export const scanIndex = (tx: ReadTransaction) => ({
4545- async eav<A extends keyof typeof Attributes>(
4646- entity: string,
4747- attribute: A | "",
4848- ) {
4545+ async eav<A extends Attribute>(entity: string, attribute: A | "") {
4946 return (
5047 (
5148 await tx
···6966});
70677168export const scanIndexLocal = (initialFacts: Fact<any>[]) => ({
7272- eav<A extends keyof typeof Attributes>(entity: string, attribute: A) {
6969+ eav<A extends Attribute>(entity: string, attribute: A) {
7370 return initialFacts.filter(
7471 (f) => f.entity === entity && f.attribute === attribute,
7572 ) as Fact<A>[];
+1-1
src/shortcuts.ts
···11-import { isIOS, isMac } from "@react-aria/utils";
21import { useUIState } from "./useUIState";
32import { Replicache } from "replicache";
43import { ReplicacheMutators } from "./replicache";
44+import { isMac } from "./utils/isDevice";
5566type Shortcut = {
77 metaKey?: boolean;
+1-1
src/utils/addImage.ts
···11import { Replicache } from "replicache";
22import { ReplicacheMutators } from "../replicache";
33import { supabaseBrowserClient } from "supabase/browserClient";
44-import { FilterAttributes } from "src/replicache/attributes";
44+import type { FilterAttributes } from "src/replicache/attributes";
55import { rgbaToDataURL, rgbaToThumbHash, thumbHashToDataURL } from "thumbhash";
66import { v7 } from "uuid";
77
+1-1
src/utils/addLinkBlock.ts
···44 LinkPreviewMetadataResult,
55} from "app/api/link_previews/route";
66import { Replicache } from "replicache";
77-import { ReplicacheMutators } from "src/replicache";
77+import type { ReplicacheMutators } from "src/replicache";
88import { AtpAgent } from "@atproto/api";
99import { v7 } from "uuid";
1010
+1-1
src/utils/copySelection.ts
···11import { getBlocksAsHTML } from "src/utils/getBlocksAsHTML";
22import { htmlToMarkdown } from "src/htmlMarkdownParsers";
33import { Replicache } from "replicache";
44-import { ReplicacheMutators } from "src/replicache";
44+import type { ReplicacheMutators } from "src/replicache";
55import { Block } from "components/Blocks/Block";
6677export async function copySelection(
+1
src/utils/focusBlock.ts
···3030 // focus the editor using the mouse position if needed
3131 let nextBlockID = block.value;
3232 let nextBlock = useEditorStates.getState().editorStates[nextBlockID];
3333+ console.log(nextBlock);
3334 if (!nextBlock || !nextBlock.view) return;
3435 let nextBlockViewClientRect = nextBlock.view.dom.getBoundingClientRect();
3536 let tr = nextBlock.editor.tr;
+3-74
src/utils/getBlocksAsHTML.tsx
···11import { ReadTransaction, Replicache } from "replicache";
22-import { Fact, ReplicacheMutators } from "src/replicache";
22+import type { Fact, ReplicacheMutators } from "src/replicache";
33import { scanIndex } from "src/replicache/utils";
44import { renderToStaticMarkup } from "react-dom/server";
55import * as Y from "yjs";
66import * as base64 from "base64-js";
77import { RenderYJSFragment } from "components/Blocks/TextBlock/RenderYJSFragment";
88import { Block } from "components/Blocks/Block";
99-import { getBlocksWithType } from "src/hooks/queries/useBlocks";
99+import { List, parseBlocksToList } from "./parseBlocksToList";
10101111export async function getBlocksAsHTML(
1212 rep: Replicache<ReplicacheMutators>,
···1414) {
1515 let data = await rep?.query(async (tx) => {
1616 let result: string[] = [];
1717- let parsed = parseBlocks(selectedBlocks);
1717+ let parsed = parseBlocksToList(selectedBlocks);
1818 for (let pb of parsed) {
1919 if (pb.type === "block") result.push(await renderBlock(pb.block, tx));
2020 else
···150150 />,
151151 );
152152}
153153-154154-function parseBlocks(blocks: Block[]) {
155155- let parsed: ParsedBlocks = [];
156156- for (let i = 0; i < blocks.length; i++) {
157157- let b = blocks[i];
158158- if (!b.listData) parsed.push({ type: "block", block: b });
159159- else {
160160- let previousBlock = parsed[parsed.length - 1];
161161- if (
162162- !previousBlock ||
163163- previousBlock.type !== "list" ||
164164- previousBlock.depth > b.listData.depth
165165- )
166166- parsed.push({
167167- type: "list",
168168- depth: b.listData.depth,
169169- children: [
170170- {
171171- type: "list",
172172- block: b,
173173- depth: b.listData.depth,
174174- children: [],
175175- },
176176- ],
177177- });
178178- else {
179179- let depth = b.listData.depth;
180180- if (depth === previousBlock.depth)
181181- previousBlock.children.push({
182182- type: "list",
183183- block: b,
184184- depth: b.listData.depth,
185185- children: [],
186186- });
187187- else {
188188- let parent =
189189- previousBlock.children[previousBlock.children.length - 1];
190190- while (depth > 1) {
191191- if (
192192- parent.children[parent.children.length - 1] &&
193193- parent.children[parent.children.length - 1].depth <
194194- b.listData.depth
195195- ) {
196196- parent = parent.children[parent.children.length - 1];
197197- }
198198- depth -= 1;
199199- }
200200- parent.children.push({
201201- type: "list",
202202- block: b,
203203- depth: b.listData.depth,
204204- children: [],
205205- });
206206- }
207207- }
208208- }
209209- }
210210- return parsed;
211211-}
212212-213213-type ParsedBlocks = Array<
214214- | { type: "block"; block: Block }
215215- | { type: "list"; depth: number; children: List[] }
216216->;
217217-218218-type List = {
219219- type: "list";
220220- block: Block;
221221- depth: number;
222222- children: List[];
223223-};
+1-1
src/utils/iosInputMouseDown.ts
···11-import { isIOS } from "@react-aria/utils";
11+import { isIOS } from "./isDevice";
2233export function onMouseDown(e: React.MouseEvent<HTMLInputElement>) {
44 if (!isIOS()) return;
+87
src/utils/isDevice.ts
···11+/*
22+ * Copyright 2020 Adobe. All rights reserved.
33+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
44+ * you may not use this file except in compliance with the License. You may obtain a copy
55+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
66+ *
77+ * Unless required by applicable law or agreed to in writing, software distributed under
88+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
99+ * OF ANY KIND, either express or implied. See the License for the specific language
1010+ * governing permissions and limitations under the License.
1111+ */
1212+1313+function testUserAgent(re: RegExp) {
1414+ if (typeof window === "undefined" || window.navigator == null) {
1515+ return false;
1616+ }
1717+ return (
1818+ //@ts-ignore
1919+ window.navigator["userAgentData"]?.brands.some(
2020+ (brand: { brand: string; version: string }) => re.test(brand.brand),
2121+ ) || re.test(window.navigator.userAgent)
2222+ );
2323+}
2424+2525+function testPlatform(re: RegExp) {
2626+ return typeof window !== "undefined" && window.navigator != null
2727+ ? re.test(
2828+ //@ts-ignore
2929+ window.navigator["userAgentData"]?.platform ||
3030+ window.navigator.platform,
3131+ )
3232+ : false;
3333+}
3434+3535+function cached(fn: () => boolean) {
3636+ if (process.env.NODE_ENV === "test") {
3737+ return fn;
3838+ }
3939+4040+ let res: boolean | null = null;
4141+ return () => {
4242+ if (res == null) {
4343+ res = fn();
4444+ }
4545+ return res;
4646+ };
4747+}
4848+4949+export const isMac = cached(function () {
5050+ return testPlatform(/^Mac/i);
5151+});
5252+5353+export const isIPhone = cached(function () {
5454+ return testPlatform(/^iPhone/i);
5555+});
5656+5757+export const isIPad = cached(function () {
5858+ return (
5959+ testPlatform(/^iPad/i) ||
6060+ // iPadOS 13 lies and says it's a Mac, but we can distinguish by detecting touch support.
6161+ (isMac() && navigator.maxTouchPoints > 1)
6262+ );
6363+});
6464+6565+export const isIOS = cached(function () {
6666+ return isIPhone() || isIPad();
6767+});
6868+6969+export const isAppleDevice = cached(function () {
7070+ return isMac() || isIOS();
7171+});
7272+7373+export const isWebKit = cached(function () {
7474+ return testUserAgent(/AppleWebKit/i) && !isChrome();
7575+});
7676+7777+export const isChrome = cached(function () {
7878+ return testUserAgent(/Chrome/i);
7979+});
8080+8181+export const isAndroid = cached(function () {
8282+ return testUserAgent(/Android/i);
8383+});
8484+8585+export const isFirefox = cached(function () {
8686+ return testUserAgent(/Firefox/i);
8787+});
···11+create table "public"."publication_domains" (
22+ "publication" text not null,
33+ "domain" text not null,
44+ "created_at" timestamp with time zone not null default now()
55+);
66+alter table "public"."publication_domains" enable row level security;
77+CREATE UNIQUE INDEX publication_domains_pkey ON public.publication_domains USING btree (publication, domain);
88+alter table "public"."publication_domains" add constraint "publication_domains_pkey" PRIMARY KEY using index "publication_domains_pkey";
99+alter table "public"."publication_domains" add constraint "publication_domains_domain_fkey" FOREIGN KEY (domain) REFERENCES custom_domains(domain) ON DELETE CASCADE not valid;
1010+alter table "public"."publication_domains" validate constraint "publication_domains_domain_fkey";
1111+alter table "public"."publication_domains" add constraint "publication_domains_publication_fkey" FOREIGN KEY (publication) REFERENCES publications(uri) ON DELETE CASCADE not valid;
1212+alter table "public"."publication_domains" validate constraint "publication_domains_publication_fkey";
1313+grant delete on table "public"."publication_domains" to "anon";
1414+grant insert on table "public"."publication_domains" to "anon";
1515+grant references on table "public"."publication_domains" to "anon";
1616+grant select on table "public"."publication_domains" to "anon";
1717+grant trigger on table "public"."publication_domains" to "anon";
1818+grant truncate on table "public"."publication_domains" to "anon";
1919+grant update on table "public"."publication_domains" to "anon";
2020+grant delete on table "public"."publication_domains" to "authenticated";
2121+grant insert on table "public"."publication_domains" to "authenticated";
2222+grant references on table "public"."publication_domains" to "authenticated";
2323+grant select on table "public"."publication_domains" to "authenticated";
2424+grant trigger on table "public"."publication_domains" to "authenticated";
2525+grant truncate on table "public"."publication_domains" to "authenticated";
2626+grant update on table "public"."publication_domains" to "authenticated";
2727+grant delete on table "public"."publication_domains" to "service_role";
2828+grant insert on table "public"."publication_domains" to "service_role";
2929+grant references on table "public"."publication_domains" to "service_role";
3030+grant select on table "public"."publication_domains" to "service_role";
3131+grant trigger on table "public"."publication_domains" to "service_role";
3232+grant truncate on table "public"."publication_domains" to "service_role";
3333+grant update on table "public"."publication_domains" to "service_role";
+1-1
supabase/serverClient.ts
···11import { createClient } from "@supabase/supabase-js";
22-import { Database } from "supabase/database.types";
22+import type { Database } from "supabase/database.types";
33export const supabaseServerClient = createClient<Database>(
44 process.env.NEXT_PUBLIC_SUPABASE_API_URL as string,
55 process.env.SUPABASE_SERVICE_ROLE_KEY as string,