Thread viewer for Bluesky
1/**
2 * Manages the page that displays a thread, as a whole.
3 */
4
5class ThreadPage {
6
7 /** @param {AnyPost} post, @returns {HTMLElement} */
8
9 buildParentLink(post) {
10 let p = $tag('p.back');
11
12 if (post instanceof BlockedPost) {
13 let element = new PostComponent(post, 'parent').buildElement();
14 element.className = 'back';
15 let span = $(element.querySelector('p.blocked-header span'));
16 span.innerText = 'Parent post blocked';
17 return element;
18 } else if (post instanceof MissingPost) {
19 p.innerHTML = `<i class="fa-solid fa-ban"></i> parent post has been deleted`;
20 } else {
21 let url = linkToPostThread(post);
22 p.innerHTML = `<i class="fa-solid fa-reply"></i><a href="${url}">See parent post (@${post.author.handle})</a>`;
23 }
24
25 return p;
26 }
27
28 /** @param {string} url, @returns {Promise<void>} */
29
30 async loadThreadByURL(url) {
31 try {
32 let json = url.startsWith('at://') ? await api.loadThreadByAtURI(url) : await api.loadThreadByURL(url);
33 this.displayThread(json);
34 } catch (error) {
35 hideLoader();
36 showError(error);
37 }
38 }
39
40 /** @param {string} author, @param {string} rkey, @returns {Promise<void>} */
41
42 async loadThreadById(author, rkey) {
43 try {
44 let json = await api.loadThreadById(author, rkey);
45 this.displayThread(json);
46 } catch (error) {
47 hideLoader();
48 showError(error);
49 }
50 }
51
52 /** @param {json} json */
53
54 displayThread(json) {
55 let root = Post.parseThreadPost(json.thread);
56 window.root = root;
57 window.subtreeRoot = root;
58
59 let loadQuoteCount;
60
61 if (root instanceof Post) {
62 setPageTitle(root);
63 loadQuoteCount = blueAPI.getQuoteCount(root.uri);
64
65 if (root.parent) {
66 let p = this.buildParentLink(root.parent);
67 $id('thread').appendChild(p);
68 } else if (root.parentReference) {
69 let { repo, rkey } = atURI(root.parentReference.uri);
70 let url = linkToPostById(repo, rkey);
71
72 let handle = api.findHandleByDid(repo);
73 let link = handle ? `See parent post (@${handle})` : "See parent post";
74
75 let p = $tag('p.back', { html: `<i class="fa-solid fa-reply"></i><a href="${url}">${link}</a>` });
76 $id('thread').appendChild(p);
77 }
78 }
79
80 let component = new PostComponent(root, 'thread');
81 let view = component.buildElement();
82 hideLoader();
83 $id('thread').appendChild(view);
84
85 loadQuoteCount?.then(count => {
86 if (count > 0) {
87 component.appendQuotesIconLink(count, true);
88 }
89 }).catch(error => {
90 console.warn("Couldn't load quote count: " + error);
91 });
92 }
93}