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
27
pulls
pipelines
use iframely for urls in embed block editor
awarm.space
3 months ago
cb9348fb
f3e2a86d
+65
-16
1 changed file
expand all
collapse all
unified
split
components
Blocks
EmbedBlock.tsx
+65
-16
components/Blocks/EmbedBlock.tsx
···
10
10
import { Input } from "components/Input";
11
11
import { isUrl } from "src/utils/isURL";
12
12
import { elementId } from "src/utils/elementId";
13
13
-
import { deleteBlock } from "./DeleteBlock";
14
13
import { focusBlock } from "src/utils/focusBlock";
15
14
import { useDrag } from "src/hooks/useDrag";
16
15
import { BlockEmbedSmall } from "components/Icons/BlockEmbedSmall";
17
16
import { CheckTiny } from "components/Icons/CheckTiny";
17
17
+
import { DotLoader } from "components/utils/DotLoader";
18
18
+
import {
19
19
+
LinkPreviewBody,
20
20
+
LinkPreviewMetadataResult,
21
21
+
} from "app/api/link_previews/route";
18
22
19
23
export const EmbedBlock = (props: BlockProps & { preview?: boolean }) => {
20
24
let { permissions } = useEntitySetContext();
···
132
136
133
137
let entity_set = useEntitySetContext();
134
138
let [linkValue, setLinkValue] = useState("");
139
139
+
let [loading, setLoading] = useState(false);
135
140
let { rep } = useReplicache();
136
141
let submit = async () => {
137
142
let entity = props.entityID;
···
149
154
}
150
155
let link = linkValue;
151
156
if (!linkValue.startsWith("http")) link = `https://${linkValue}`;
152
152
-
// these mutations = simpler subset of addLinkBlock
153
157
if (!rep) return;
154
154
-
await rep.mutate.assertFact({
155
155
-
entity: entity,
156
156
-
attribute: "block/type",
157
157
-
data: { type: "block-type-union", value: "embed" },
158
158
-
});
159
159
-
await rep?.mutate.assertFact({
160
160
-
entity: entity,
161
161
-
attribute: "embed/url",
162
162
-
data: {
163
163
-
type: "string",
164
164
-
value: link,
165
165
-
},
166
166
-
});
158
158
+
159
159
+
// Try to get embed URL from iframely, fallback to direct URL
160
160
+
setLoading(true);
161
161
+
try {
162
162
+
let res = await fetch("/api/link_previews", {
163
163
+
headers: { "Content-Type": "application/json" },
164
164
+
method: "POST",
165
165
+
body: JSON.stringify({ url: link, type: "meta" } as LinkPreviewBody),
166
166
+
});
167
167
+
168
168
+
let embedUrl = link;
169
169
+
let embedHeight = 360;
170
170
+
171
171
+
if (res.status === 200) {
172
172
+
let data = await (res.json() as LinkPreviewMetadataResult);
173
173
+
if (data.success && data.data.links?.player?.[0]) {
174
174
+
let embed = data.data.links.player[0];
175
175
+
embedUrl = embed.href;
176
176
+
embedHeight = embed.media?.height || 300;
177
177
+
}
178
178
+
}
179
179
+
180
180
+
await rep.mutate.assertFact([
181
181
+
{
182
182
+
entity: entity,
183
183
+
attribute: "embed/url",
184
184
+
data: {
185
185
+
type: "string",
186
186
+
value: embedUrl,
187
187
+
},
188
188
+
},
189
189
+
{
190
190
+
entity: entity,
191
191
+
attribute: "embed/height",
192
192
+
data: {
193
193
+
type: "number",
194
194
+
value: embedHeight,
195
195
+
},
196
196
+
},
197
197
+
]);
198
198
+
} catch {
199
199
+
// On any error, fallback to using the URL directly
200
200
+
await rep.mutate.assertFact([
201
201
+
{
202
202
+
entity: entity,
203
203
+
attribute: "embed/url",
204
204
+
data: {
205
205
+
type: "string",
206
206
+
value: link,
207
207
+
},
208
208
+
},
209
209
+
]);
210
210
+
} finally {
211
211
+
setLoading(false);
212
212
+
}
167
213
};
168
214
let smoker = useSmoker();
169
215
···
171
217
<form
172
218
onSubmit={(e) => {
173
219
e.preventDefault();
220
220
+
if (loading) return;
174
221
let rect = document
175
222
.getElementById("embed-block-submit")
176
223
?.getBoundingClientRect();
···
212
259
<button
213
260
type="submit"
214
261
id="embed-block-submit"
262
262
+
disabled={loading}
215
263
className={`p-1 ${isSelected && !isLocked ? "text-accent-contrast" : "text-border"}`}
216
264
onMouseDown={(e) => {
217
265
e.preventDefault();
266
266
+
if (loading) return;
218
267
if (!linkValue || linkValue === "") {
219
268
smoker({
220
269
error: true,
···
234
283
submit();
235
284
}}
236
285
>
237
237
-
<CheckTiny />
286
286
+
{loading ? <DotLoader /> : <CheckTiny />}
238
287
</button>
239
288
</div>
240
289
</form>