diff --git a/models.js b/models.js index 11f7ad0..db6b55b 100644 --- a/models.js +++ b/models.js @@ -174,6 +174,55 @@ class Post extends ATProtoRecord { } } + static parseMastodonThread(post, context) { + let idMap = {}; + idMap[post.id] = post; + post.replies = []; + + for (let p of context.descendants) { + p.replies = []; + idMap[p.id] = p; + + if (idMap[p.in_reply_to_id]) { + idMap[p.in_reply_to_id].replies.push(p); + } + } + + let root = Post.parseMastodonPost(post); + + if (context.ancestors && context.ancestors[0]) { + post.parent = Post.parseMastodonPost(context.ancestors[0]); + } + + return root; + } + + static parseMastodonPost(post) { + let model = new Post({ + uri: `at://${post.account.id}/app.bsky.feed.post/${post.id}`, + author: { + handle: post.account.acct, + avatar: post.account.avatar_static, + displayName: post.account.display_name, + did: post.account.id + }, + record: { + mastodonContent: post.content, + createdAt: post.created_at + }, + likeCount: post.favourites_count, + repostCount: post.reblogs_count, + replyCount: post.replies_count + }); + + if (post.replies) { + model.setReplies(post.replies.map(r => Post.parseMastodonPost(r))); + } + + return model; + } + + /** @param {json} data, @param {json} [extra] */ constructor(data, extra) { @@ -249,7 +298,7 @@ class Post extends ATProtoRecord { /** @returns {string | undefined} */ get originalFediContent() { - return this.record.bridgyOriginalText; + return this.record.bridgyOriginalText || this.record.mastodonContent; } /** @returns {string} */ diff --git a/skythread.js b/skythread.js index 3c2a8ab..a2a8f56 100644 --- a/skythread.js +++ b/skythread.js @@ -93,6 +93,7 @@ function parseQueryParams() { let post = params.get('post'); let quotes = params.get('quotes'); let hash = params.get('hash'); + let mastodon = params.get('masto'); if (quotes) { showLoader(); @@ -106,6 +107,9 @@ function parseQueryParams() { } else if (author && post) { showLoader(); loadThread(decodeURIComponent(author), decodeURIComponent(post)); + } else if (mastodon) { + showLoader(); + loadMastodonThread(decodeURIComponent(mastodon)); } else { showSearch(); } @@ -481,3 +485,42 @@ function loadThread(url, postId, nodeToUpdate) { alert(error); }); } + +function loadMastodonThread(url) { + let host = new URL(url).host; + let postId = url.replace(/\/$/, '').split('/').reverse()[0]; + let statusURL = `https://${host}/api/v1/statuses/${postId}`; + let contextURL = `https://${host}/api/v1/statuses/${postId}/context`; + + let load = async function() { + let post = await fetch(statusURL).then(x => x.json()); + let context = await fetch(contextURL).then(x => x.json()); + return [post, context]; + } + + load().then(json => { + console.log(json); + + let root = Post.parseMastodonThread(json[0], json[1]); + window.root = root; + + if (root instanceof Post) { + setPageTitle(root); + + if (root.parent) { + let p = buildParentLink(root.parent); + $id('thread').appendChild(p); + } + } + + let component = new PostComponent(root); + let list = component.buildElement('thread'); + hideLoader(); + + $id('thread').appendChild(list); + }).catch(error => { + hideLoader(); + console.log(error); + alert(error); + }); +}