+46
-47
embed_component.js
+46
-47
embed_component.js
···
4
5
class EmbedComponent {
6
7
-
/** @param {Post} post, @param {object} embed */
8
constructor(post, embed) {
9
this.post = post;
10
this.embed = embed;
···
13
/** @returns {AnyElement} */
14
15
buildElement() {
16
-
let wrapper, quoteView, mediaView;
17
-
18
-
switch (this.embed.constructor) {
19
-
case RawRecordEmbed:
20
-
quoteView = this.quotedPostPlaceholder();
21
this.loadQuotedPost(this.embed.record.uri, quoteView);
22
return quoteView;
23
24
-
case RawRecordWithMediaEmbed:
25
-
wrapper = $tag('div');
26
27
-
mediaView = new EmbedComponent(this.post, this.embed.media).buildElement();
28
-
quoteView = this.quotedPostPlaceholder();
29
this.loadQuotedPost(this.embed.record.uri, quoteView);
30
31
wrapper.append(mediaView, quoteView);
32
return wrapper;
33
34
-
case InlineRecordEmbed:
35
-
return this.buildQuotedPostElement();
36
37
-
case InlineRecordWithMediaEmbed:
38
-
wrapper = $tag('div');
39
40
-
mediaView = new EmbedComponent(this.post, this.embed.media).buildElement();
41
-
quoteView = this.buildQuotedPostElement();
42
43
wrapper.append(mediaView, quoteView);
44
return wrapper;
45
46
-
case RawImageEmbed:
47
-
case InlineImageEmbed:
48
-
return this.buildImagesComponent();
49
50
-
case RawLinkEmbed:
51
-
case InlineLinkEmbed:
52
-
return this.buildLinkComponent();
53
54
-
default:
55
return $tag('p', { text: `[${this.embed.type}]` });
56
}
57
}
···
64
});
65
}
66
67
-
/** @returns {AnyElement} */
68
69
-
buildQuotedPostElement() {
70
let div = $tag('div.quote-embed');
71
72
-
if (this.embed.post instanceof Post || this.embed.post instanceof BlockedPost) {
73
-
let postView = new PostComponent(this.embed.post).buildElement('quote');
74
div.appendChild(postView);
75
-
} else if (this.embed.post instanceof MissingPost) {
76
-
let postView = new PostComponent(this.embed.post).buildElement('quote');
77
div.appendChild(postView);
78
-
} else if (this.embed.post instanceof FeedGeneratorRecord) {
79
-
return this.buildFeedGeneratorView(this.embed.post);
80
-
} else if (this.embed.post instanceof UserListRecord) {
81
-
return this.buildUserListView(this.embed.post);
82
} else {
83
-
let p = $tag('p', { text: `[${this.embed.post.type}]` });
84
div.appendChild(p);
85
}
86
87
return div;
88
}
89
90
-
/** @returns {AnyElement} */
91
92
-
buildLinkComponent() {
93
let hostname;
94
95
try {
96
-
hostname = new URL(this.embed.url).hostname;
97
} catch (error) {
98
console.log("Invalid URL:" + error);
99
100
-
let a = $tag('a', { href: this.embed.url, text: this.embed.title || this.embed.url });
101
let p = $tag('p');
102
p.append('[Link: ', a, ']');
103
return p;
104
}
105
106
-
let a = $tag('a.link-card', { href: this.embed.url, target: '_blank' });
107
let box = $tag('div');
108
109
let domain = $tag('p.domain', { text: hostname });
110
-
let title = $tag('h2', { text: this.embed.title });
111
box.append(domain, title);
112
113
-
if (this.embed.description) {
114
let text;
115
116
-
if (this.embed.description.length <= 300) {
117
-
text = this.embed.description;
118
} else {
119
-
text = this.embed.description.slice(0, 300) + '…';
120
}
121
122
box.append($tag('p.description', { text: text }));
···
213
return `https://bsky.app/profile/${repo}/lists/${rkey}`;
214
}
215
216
-
/** @returns {AnyElement} */
217
218
-
buildImagesComponent() {
219
let wrapper = $tag('div');
220
221
-
for (let image of this.embed.images) {
222
let p = $tag('p');
223
p.append('[');
224
···
4
5
class EmbedComponent {
6
7
+
/** @param {Post} post, @param {Embed} embed */
8
constructor(post, embed) {
9
this.post = post;
10
this.embed = embed;
···
13
/** @returns {AnyElement} */
14
15
buildElement() {
16
+
if (this.embed instanceof RawRecordEmbed) {
17
+
let quoteView = this.quotedPostPlaceholder();
18
this.loadQuotedPost(this.embed.record.uri, quoteView);
19
return quoteView;
20
21
+
} else if (this.embed instanceof RawRecordWithMediaEmbed) {
22
+
let wrapper = $tag('div');
23
24
+
let mediaView = new EmbedComponent(this.post, this.embed.media).buildElement();
25
+
let quoteView = this.quotedPostPlaceholder();
26
this.loadQuotedPost(this.embed.record.uri, quoteView);
27
28
wrapper.append(mediaView, quoteView);
29
return wrapper;
30
31
+
} else if (this.embed instanceof InlineRecordEmbed) {
32
+
return this.buildQuotedPostElement(this.embed);
33
34
+
} else if (this.embed instanceof InlineRecordWithMediaEmbed) {
35
+
let wrapper = $tag('div');
36
37
+
let mediaView = new EmbedComponent(this.post, this.embed.media).buildElement();
38
+
let quoteView = this.buildQuotedPostElement(this.embed);
39
40
wrapper.append(mediaView, quoteView);
41
return wrapper;
42
43
+
} else if (this.embed instanceof RawImageEmbed || this.embed instanceof InlineImageEmbed) {
44
+
return this.buildImagesComponent(this.embed);
45
46
+
} else if (this.embed instanceof RawLinkEmbed || this.embed instanceof InlineLinkEmbed) {
47
+
return this.buildLinkComponent(this.embed);
48
49
+
} else {
50
return $tag('p', { text: `[${this.embed.type}]` });
51
}
52
}
···
59
});
60
}
61
62
+
/** @param {InlineRecordEmbed | InlineRecordWithMediaEmbed} embed, @returns {AnyElement} */
63
64
+
buildQuotedPostElement(embed) {
65
let div = $tag('div.quote-embed');
66
67
+
if (embed.post instanceof Post || embed.post instanceof BlockedPost) {
68
+
let postView = new PostComponent(embed.post).buildElement('quote');
69
div.appendChild(postView);
70
+
71
+
} else if (embed.post instanceof MissingPost) {
72
+
let postView = new PostComponent(embed.post).buildElement('quote');
73
div.appendChild(postView);
74
+
75
+
} else if (embed.post instanceof FeedGeneratorRecord) {
76
+
return this.buildFeedGeneratorView(embed.post);
77
+
78
+
} else if (embed.post instanceof UserListRecord) {
79
+
return this.buildUserListView(embed.post);
80
+
81
} else {
82
+
let p = $tag('p', { text: `[${embed.post.type}]` });
83
div.appendChild(p);
84
}
85
86
return div;
87
}
88
89
+
/** @params {RawLinkEmbed | InlineLinkEmbed} embed, @returns {AnyElement} */
90
91
+
buildLinkComponent(embed) {
92
let hostname;
93
94
try {
95
+
hostname = new URL(embed.url).hostname;
96
} catch (error) {
97
console.log("Invalid URL:" + error);
98
99
+
let a = $tag('a', { href: embed.url, text: embed.title || embed.url });
100
let p = $tag('p');
101
p.append('[Link: ', a, ']');
102
return p;
103
}
104
105
+
let a = $tag('a.link-card', { href: embed.url, target: '_blank' });
106
let box = $tag('div');
107
108
let domain = $tag('p.domain', { text: hostname });
109
+
let title = $tag('h2', { text: embed.title });
110
box.append(domain, title);
111
112
+
if (embed.description) {
113
let text;
114
115
+
if (embed.description.length <= 300) {
116
+
text = embed.description;
117
} else {
118
+
text = embed.description.slice(0, 300) + '…';
119
}
120
121
box.append($tag('p.description', { text: text }));
···
212
return `https://bsky.app/profile/${repo}/lists/${rkey}`;
213
}
214
215
+
/** @params {RawImageEmbed | InlineImageEmbed} embed, @returns {AnyElement} */
216
217
+
buildImagesComponent(embed) {
218
let wrapper = $tag('div');
219
220
+
for (let image of embed.images) {
221
let p = $tag('p');
222
p.append('[');
223