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
add interactions preview for subpages
awarm.space
4 months ago
a6e98f01
8eeccb56
+106
-32
2 changed files
expand all
collapse all
unified
split
app
lish
[did]
[publication]
[rkey]
PostPages.tsx
PublishedPageBlock.tsx
+8
-2
app/lish/[did]/[publication]/[rkey]/PostPages.tsx
···
72
72
}, [quote]);
73
73
};
74
74
75
75
-
export const openPage = (parent: string | undefined, page: string) => {
75
75
+
export const openPage = (
76
76
+
parent: string | undefined,
77
77
+
page: string,
78
78
+
options?: { scrollIntoView?: boolean }
79
79
+
) => {
76
80
flushSync(() => {
77
81
usePostPageUIState.setState((state) => {
78
82
let parentPosition = state.pages.findIndex((s) => s == parent);
···
86
90
});
87
91
});
88
92
89
89
-
scrollIntoView(`post-page-${page}`);
93
93
+
if (options?.scrollIntoView !== false) {
94
94
+
scrollIntoView(`post-page-${page}`);
95
95
+
}
90
96
};
91
97
92
98
export const closePage = (page: string) =>
+98
-30
app/lish/[did]/[publication]/[rkey]/PublishedPageBlock.tsx
···
8
8
import {
9
9
PubLeafletBlocksHeader,
10
10
PubLeafletBlocksText,
11
11
+
PubLeafletComment,
11
12
PubLeafletPagesLinearDocument,
12
13
PubLeafletPublication,
13
14
} from "lexicons/api";
···
15
16
import { TextBlock } from "./TextBlock";
16
17
import { PostPageContext } from "./PostPageContext";
17
18
import { openPage, useOpenPages } from "./PostPages";
19
19
+
import {
20
20
+
openInteractionDrawer,
21
21
+
setInteractionState,
22
22
+
useInteractionState,
23
23
+
} from "./Interactions/Interactions";
24
24
+
import { CommentTiny } from "components/Icons/CommentTiny";
25
25
+
import { QuoteTiny } from "components/Icons/QuoteTiny";
18
26
19
27
export function PublishedPageLinkBlock(props: {
20
28
blocks: PubLeafletPagesLinearDocument.Block[];
···
44
52
e.preventDefault();
45
53
e.stopPropagation();
46
54
47
47
-
console.log("yoo@");
48
48
-
49
55
openPage(props.parentPageId, props.pageId);
50
50
-
//open the damn thing somehow
51
56
}}
52
57
>
53
58
<DocLinkBlock {...props} />
···
56
61
}
57
62
export function DocLinkBlock(props: {
58
63
blocks: PubLeafletPagesLinearDocument.Block[];
59
59
-
pageId?: string;
64
64
+
pageId: string;
65
65
+
parentPageId?: string;
60
66
did: string;
61
67
preview?: boolean;
62
68
className?: string;
63
69
prerenderedCodeBlocks?: Map<string, string>;
64
70
bskyPostData: AppBskyFeedDefs.PostView[];
65
71
}) {
66
66
-
let { rep } = useReplicache();
67
72
let [title, description] = props.blocks
68
73
.map((b) => b.block)
69
74
.filter(
···
79
84
>
80
85
<>
81
86
<div className="pageLinkBlockContent w-full flex overflow-clip cursor-pointer h-full">
82
82
-
<div className="my-2 ml-3 grow min-w-0 text-sm bg-transparent overflow-clip ">
83
83
-
{title && (
84
84
-
<div
85
85
-
className={`pageBlockOne outline-none resize-none align-top flex gap-2 ${title.$type === "pub.leaflet.blocks.header" ? "font-bold text-base" : ""}`}
86
86
-
>
87
87
-
<TextBlock
88
88
-
facets={title.facets}
89
89
-
plaintext={title.plaintext}
90
90
-
index={[]}
91
91
-
preview
92
92
-
/>
93
93
-
</div>
94
94
-
)}
95
95
-
{description && (
96
96
-
<div
97
97
-
className={`pageBlockLineTwo outline-none resize-none align-top flex gap-2 ${description.$type === "pub.leaflet.blocks.header" ? "font-bold" : ""}`}
98
98
-
>
99
99
-
<TextBlock
100
100
-
facets={description.facets}
101
101
-
plaintext={description.plaintext}
102
102
-
index={[]}
103
103
-
preview
104
104
-
/>
105
105
-
</div>
106
106
-
)}
87
87
+
<div className="my-2 ml-3 grow min-w-0 text-sm bg-transparent overflow-clip flex flex-col ">
88
88
+
<div className="grow">
89
89
+
{title && (
90
90
+
<div
91
91
+
className={`pageBlockOne outline-none resize-none align-top flex gap-2 ${title.$type === "pub.leaflet.blocks.header" ? "font-bold text-base" : ""}`}
92
92
+
>
93
93
+
<TextBlock
94
94
+
facets={title.facets}
95
95
+
plaintext={title.plaintext}
96
96
+
index={[]}
97
97
+
preview
98
98
+
/>
99
99
+
</div>
100
100
+
)}
101
101
+
{description && (
102
102
+
<div
103
103
+
className={`pageBlockLineTwo outline-none resize-none align-top flex gap-2 ${description.$type === "pub.leaflet.blocks.header" ? "font-bold" : ""}`}
104
104
+
>
105
105
+
<TextBlock
106
106
+
facets={description.facets}
107
107
+
plaintext={description.plaintext}
108
108
+
index={[]}
109
109
+
preview
110
110
+
/>
111
111
+
</div>
112
112
+
)}
113
113
+
</div>
114
114
+
115
115
+
<Interactions
116
116
+
pageId={props.pageId}
117
117
+
parentPageId={props.parentPageId}
118
118
+
/>
107
119
</div>
108
120
{!props.preview && (
109
121
<PagePreview blocks={props.blocks} did={props.did} />
···
158
170
</div>
159
171
);
160
172
}
173
173
+
174
174
+
const Interactions = (props: { pageId: string; parentPageId?: string }) => {
175
175
+
const data = useContext(PostPageContext);
176
176
+
const document_uri = data?.uri;
177
177
+
if (!document_uri)
178
178
+
throw new Error("document_uri not available in PostPageContext");
179
179
+
let comments = data.comments_on_documents.filter(
180
180
+
(c) => (c.record as PubLeafletComment.Record)?.onPage === props.pageId,
181
181
+
).length;
182
182
+
let quotes = data.document_mentions_in_bsky.filter((q) =>
183
183
+
q.link.includes(props.pageId),
184
184
+
).length;
185
185
+
186
186
+
let { drawerOpen, drawer, pageId } = useInteractionState(document_uri);
187
187
+
188
188
+
return (
189
189
+
<div className={`flex gap-2 text-tertiary text-sm`}>
190
190
+
{quotes > 0 && (
191
191
+
<button
192
192
+
className={`flex gap-1 items-center`}
193
193
+
onClick={(e) => {
194
194
+
e.preventDefault();
195
195
+
e.stopPropagation();
196
196
+
openPage(props.parentPageId, props.pageId, {
197
197
+
scrollIntoView: false,
198
198
+
});
199
199
+
if (!drawerOpen || drawer !== "quotes")
200
200
+
openInteractionDrawer("quotes", document_uri, props.pageId);
201
201
+
else setInteractionState(document_uri, { drawerOpen: false });
202
202
+
}}
203
203
+
>
204
204
+
<span className="sr-only">Page quotes</span>
205
205
+
<QuoteTiny aria-hidden /> {quotes}{" "}
206
206
+
</button>
207
207
+
)}
208
208
+
{comments > 0 && (
209
209
+
<button
210
210
+
className={`flex gap-1 items-center`}
211
211
+
onClick={(e) => {
212
212
+
e.preventDefault();
213
213
+
e.stopPropagation();
214
214
+
openPage(props.parentPageId, props.pageId, {
215
215
+
scrollIntoView: false,
216
216
+
});
217
217
+
if (!drawerOpen || drawer !== "comments" || pageId !== props.pageId)
218
218
+
openInteractionDrawer("comments", document_uri, props.pageId);
219
219
+
else setInteractionState(document_uri, { drawerOpen: false });
220
220
+
}}
221
221
+
>
222
222
+
<span className="sr-only">Page comments</span>
223
223
+
<CommentTiny aria-hidden /> {comments}{" "}
224
224
+
</button>
225
225
+
)}
226
226
+
</div>
227
227
+
);
228
228
+
};