tangled
alpha
login
or
join now
leaflet.pub
/
leaflet
289
fork
atom
a tool for shared writing and social publishing
289
fork
atom
overview
issues
28
pulls
pipelines
Merge branch 'main' into feature/atp-canvas-blocks
awarm.space
4 months ago
25bd9f64
055e5cab
+53
-37
14 changed files
expand all
collapse all
unified
split
actions
publishToPublication.ts
app
lish
Subscribe.tsx
[did]
[publication]
[rkey]
Interactions
Interactions.tsx
PostContent.tsx
PostPages.tsx
PubCodeBlock.tsx
PublishedPageBlock.tsx
StaticPostContent.tsx
extractCodeBlocks.ts
l-quote
[quote]
opengraph-image.ts
dashboard
page.tsx
reader
ReaderContent.tsx
components
ThemeManager
PubThemeSetter.tsx
PublicationThemeProvider.tsx
+5
-3
actions/publishToPublication.ts
···
152
152
let scan = scanIndexLocal(facts);
153
153
let pages: {
154
154
id: string;
155
155
-
blocks: PubLeafletPagesLinearDocument.Block[] | PubLeafletPagesCanvas.Block[];
155
155
+
blocks:
156
156
+
| PubLeafletPagesLinearDocument.Block[]
157
157
+
| PubLeafletPagesCanvas.Block[];
156
158
type: "doc" | "canvas";
157
159
}[] = [];
158
160
···
415
417
// Get canvas-specific properties
416
418
let width =
417
419
scan.eav(blockEntity, "canvas/block/width")?.[0]?.data.value || 360;
418
418
-
let rotation =
419
419
-
scan.eav(blockEntity, "canvas/block/rotation")?.[0]?.data.value;
420
420
+
let rotation = scan.eav(blockEntity, "canvas/block/rotation")?.[0]
421
421
+
?.data.value;
420
422
421
423
let canvasBlockRecord: PubLeafletPagesCanvas.Block = {
422
424
$type: "pub.leaflet.pages.canvas#block",
+2
-4
app/lish/Subscribe.tsx
···
217
217
pub_uri={props.pub_uri}
218
218
setSuccessModalOpen={setSuccessModalOpen}
219
219
/>
220
220
-
<a href={`${props.base_url}/rss`} className="flex" target="_blank">
221
221
-
<span className="sr-only">Subscribe to RSS</span>
220
220
+
<a href={`${props.base_url}/rss`} className="flex" target="_blank" aria-label="Subscribe to RSS">
222
221
<RSSSmall className="self-center" aria-hidden />
223
222
</a>
224
223
</div>
···
267
266
</a>
268
267
)}
269
268
270
270
-
<a href={`${props.base_url}/rss`} className="flex" target="_blank">
271
271
-
<span className="sr-only">Subscribe to RSS</span>
269
269
+
<a href={`${props.base_url}/rss`} className="flex" target="_blank" aria-label="Subscribe to RSS">
272
270
<ButtonPrimary fullWidth compact>
273
271
Get RSS
274
272
</ButtonPrimary>
+2
-2
app/lish/[did]/[publication]/[rkey]/Interactions/Interactions.tsx
···
119
119
openInteractionDrawer("quotes", document_uri, props.pageId);
120
120
else setInteractionState(document_uri, { drawerOpen: false });
121
121
}}
122
122
+
aria-label="Post quotes"
122
123
>
123
123
-
<span className="sr-only">Post quotes</span>
124
124
<QuoteTiny aria-hidden /> {props.quotesCount}{" "}
125
125
{!props.compact && (
126
126
<span
···
136
136
openInteractionDrawer("comments", document_uri, props.pageId);
137
137
else setInteractionState(document_uri, { drawerOpen: false });
138
138
}}
139
139
+
aria-label="Post comments"
139
140
>
140
140
-
<span className="sr-only">Post comments</span>
141
141
<CommentTiny aria-hidden /> {props.commentsCount}{" "}
142
142
{!props.compact && (
143
143
<span
+1
-1
app/lish/[did]/[publication]/[rkey]/PostContent.tsx
···
52
52
return (
53
53
<div
54
54
//The postContent class is important for QuoteHandler
55
55
-
className={`postContent flex flex-col sm:px-4 px-3 sm:pt-3 pt-2 pb-1 sm:pb-2 ${className}`}
55
55
+
className={`postContent flex flex-col sm:px-4 px-3 sm:pt-3 pt-2 pb-1 sm:pb-6 ${className}`}
56
56
>
57
57
{blocks.map((b, index) => {
58
58
return (
+9
-2
app/lish/[did]/[publication]/[rkey]/PostPages.tsx
···
160
160
{pages.map((p) => {
161
161
let page = record.pages.find(
162
162
(page) =>
163
163
-
(page as PubLeafletPagesLinearDocument.Main | PubLeafletPagesCanvas.Main).id === p,
164
164
-
) as PubLeafletPagesLinearDocument.Main | PubLeafletPagesCanvas.Main | undefined;
163
163
+
(
164
164
+
page as
165
165
+
| PubLeafletPagesLinearDocument.Main
166
166
+
| PubLeafletPagesCanvas.Main
167
167
+
).id === p,
168
168
+
) as
169
169
+
| PubLeafletPagesLinearDocument.Main
170
170
+
| PubLeafletPagesCanvas.Main
171
171
+
| undefined;
165
172
if (!page) return null;
166
173
167
174
const isCanvas = PubLeafletPagesCanvas.isMain(page);
+5
-5
app/lish/[did]/[publication]/[rkey]/PubCodeBlock.tsx
···
2
2
3
3
import { PubLeafletBlocksCode } from "lexicons/api";
4
4
import { useLayoutEffect, useState } from "react";
5
5
-
import { codeToHtml } from "shiki";
5
5
+
import { codeToHtml, bundledLanguagesInfo, bundledThemesInfo } from "shiki";
6
6
7
7
export function PubCodeBlock({
8
8
block,
···
14
14
const [html, setHTML] = useState<string | null>(prerenderedCode || null);
15
15
16
16
useLayoutEffect(() => {
17
17
-
codeToHtml(block.plaintext, {
18
18
-
lang: block.language || "plaintext",
19
19
-
theme: block.syntaxHighlightingTheme || "github-light",
20
20
-
}).then(setHTML);
17
17
+
const lang = bundledLanguagesInfo.find((l) => l.id === block.language)?.id || "plaintext";
18
18
+
const theme = bundledThemesInfo.find((t) => t.id === block.syntaxHighlightingTheme)?.id || "github-light";
19
19
+
20
20
+
codeToHtml(block.plaintext, { lang, theme }).then(setHTML);
21
21
}, [block]);
22
22
return (
23
23
<div
+2
-1
app/lish/[did]/[publication]/[rkey]/PublishedPageBlock.tsx
···
254
254
pages: (PubLeafletPagesLinearDocument.Main | PubLeafletPagesCanvas.Main)[];
255
255
}) => {
256
256
let pageWidth = `var(--page-width-unitless)`;
257
257
-
let height = props.blocks.length > 0 ? Math.max(...props.blocks.map((b) => b.y), 0) : 0;
257
257
+
let height =
258
258
+
props.blocks.length > 0 ? Math.max(...props.blocks.map((b) => b.y), 0) : 0;
258
259
259
260
return (
260
261
<div
+9
-5
app/lish/[did]/[publication]/[rkey]/StaticPostContent.tsx
···
14
14
import { blobRefToSrc } from "src/utils/blobRefToSrc";
15
15
import { BaseTextBlock } from "./BaseTextBlock";
16
16
import { StaticMathBlock } from "./StaticMathBlock";
17
17
-
import { codeToHtml } from "shiki";
17
17
+
import { codeToHtml, bundledLanguagesInfo, bundledThemesInfo } from "shiki";
18
18
19
19
export function StaticPostContent({
20
20
blocks,
···
62
62
return <StaticMathBlock block={b.block} />;
63
63
}
64
64
case PubLeafletBlocksCode.isMain(b.block): {
65
65
-
let html = await codeToHtml(b.block.plaintext, {
66
66
-
lang: b.block.language || "plaintext",
67
67
-
theme: b.block.syntaxHighlightingTheme || "github-light",
68
68
-
});
65
65
+
let { language, syntaxHighlightingTheme } = b.block;
66
66
+
const lang =
67
67
+
bundledLanguagesInfo.find((l) => l.id === language)?.id || "plaintext";
68
68
+
const theme =
69
69
+
bundledThemesInfo.find((t) => t.id === syntaxHighlightingTheme)?.id ||
70
70
+
"github-light";
71
71
+
72
72
+
let html = await codeToHtml(b.block.plaintext, { lang, theme });
69
73
return (
70
74
<div
71
75
className="w-full min-h-[42px] rounded-md border-border-light outline-border-light selected-outline"
+9
-5
app/lish/[did]/[publication]/[rkey]/extractCodeBlocks.ts
···
3
3
PubLeafletPagesLinearDocument,
4
4
PubLeafletBlocksCode,
5
5
} from "lexicons/api";
6
6
-
import { codeToHtml } from "shiki";
6
6
+
import { codeToHtml, bundledLanguagesInfo, bundledThemesInfo } from "shiki";
7
7
8
8
export async function extractCodeBlocks(
9
9
blocks: PubLeafletPagesLinearDocument.Block[],
···
17
17
const indexKey = currentIndex.join(".");
18
18
19
19
if (PubLeafletBlocksCode.isMain(block.block)) {
20
20
-
const html = await codeToHtml(block.block.plaintext, {
21
21
-
lang: block.block.language || "plaintext",
22
22
-
theme: block.block.syntaxHighlightingTheme || "github-light",
23
23
-
});
20
20
+
let { language, syntaxHighlightingTheme } = block.block;
21
21
+
const lang =
22
22
+
bundledLanguagesInfo.find((l) => l.id === language)?.id || "plaintext";
23
23
+
let theme =
24
24
+
bundledThemesInfo.find((t) => t.id === syntaxHighlightingTheme)?.id ||
25
25
+
"github-light";
26
26
+
27
27
+
const html = await codeToHtml(block.block.plaintext, { lang, theme });
24
28
codeBlocks.set(indexKey, html);
25
29
}
26
30
}
+1
-1
app/lish/[did]/[publication]/[rkey]/l-quote/[quote]/opengraph-image.ts
···
9
9
}) {
10
10
let quotePosition = decodeQuotePosition(props.params.quote);
11
11
return getMicroLinkOgImage(
12
12
-
`/lish/${decodeURIComponent(props.params.did)}/${decodeURIComponent(props.params.publication)}/${props.params.rkey}/l-quote/${props.params.quote}#${quotePosition?.start.block.join(".")}_${quotePosition?.start.offset}`,
12
12
+
`/lish/${decodeURIComponent(props.params.did)}/${decodeURIComponent(props.params.publication)}/${props.params.rkey}/l-quote/${props.params.quote}#${quotePosition?.pageId ? `${quotePosition.pageId}~` : ""}${quotePosition?.start.block.join(".")}_${quotePosition?.start.offset}`,
13
13
{
14
14
width: 620,
15
15
height: 324,
+1
-1
app/lish/[did]/[publication]/dashboard/page.tsx
···
69
69
publication_rkey={uri.rkey}
70
70
publication_data={publication_data}
71
71
>
72
72
-
<PublicationThemeProviderDashboard record={record}>
72
72
+
<PublicationThemeProviderDashboard>
73
73
<PublicationDashboard publication={publication} record={record} />
74
74
</PublicationThemeProviderDashboard>
75
75
</PublicationSWRDataProvider>
+2
-4
app/reader/ReaderContent.tsx
···
229
229
return (
230
230
<div className={`flex gap-2 text-tertiary text-sm items-center`}>
231
231
{props.quotesCount === 0 ? null : (
232
232
-
<div className={`flex gap-1 items-center `}>
233
233
-
<span className="sr-only">Post quotes</span>
232
232
+
<div className={`flex gap-1 items-center `} aria-label="Post quotes">
234
233
<QuoteTiny aria-hidden /> {props.quotesCount}
235
234
</div>
236
235
)}
237
236
{props.showComments === false || props.commentsCount === 0 ? null : (
238
238
-
<div className={`flex gap-1 items-center`}>
239
239
-
<span className="sr-only">Post comments</span>
237
237
+
<div className={`flex gap-1 items-center`} aria-label="Post comments">
240
238
<CommentTiny aria-hidden /> {props.commentsCount}
241
239
</div>
242
240
)}
+5
-2
components/ThemeManager/PubThemeSetter.tsx
···
79
79
},
80
80
});
81
81
mutate((pub) => {
82
82
-
if (result?.publication && pub)
83
83
-
return { ...pub, record: result.publication.record };
82
82
+
if (result?.publication && pub?.publication)
83
83
+
return {
84
84
+
...pub,
85
85
+
publication: { ...pub.publication, ...result.publication },
86
86
+
};
84
87
return pub;
85
88
}, false);
86
89
setLoading(false);
-1
components/ThemeManager/PublicationThemeProvider.tsx
···
47
47
48
48
export function PublicationThemeProviderDashboard(props: {
49
49
children: React.ReactNode;
50
50
-
record?: PubLeafletPublication.Record | null;
51
50
}) {
52
51
let { data } = usePublicationData();
53
52
let { publication: pub } = data || {};