Thread viewer for Bluesky

type safety refactors in EmbedComponent

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