import * as MastodonAPI from "./MastodonAPI.js"; import * as BlueskyAPI from "./BlueskyAPI.js"; import * as TumblrAPI from "./TumblrAPI.js"; import * as Variables from "./Variables.js"; // Buttons let Favorite = document.getElementsByClassName("Favorite")[0]; let Boost = document.getElementsByClassName("Boost")[0]; let Reply = document.getElementsByClassName("Reply")[0]; let FavoriteFlipper = false; let BoostFlipper = false; // Variables let website = document.location.href.split("website=")[1]; let post = JSON.parse(localStorage.getItem("post")); let Parentpost; let GrandParentpost; document.getElementsByClassName("Origin Regular")[0].innerHTML = website; GetPost(); // Button stuff Favorite.onclick = (event) => { if (website == "Mastodon") { MastodonAPI.CreateFavorite(post.id, post.favourited); } else if (website == "Bluesky") { BlueskyAPI.CreateLike(localStorage.getItem(Variables.BlueskyDID), post.post.uri, post.post.cid); } SetFavorite(); } Boost.onclick = (event) => { if (website == "Mastodon") { MastodonAPI.CreateReblog(post.id, post.reblogged); } else if (website == "Bluesky") { BlueskyAPI.CreateRepost(localStorage.getItem(Variables.BlueskyDID), post.post.uri, post.post.cid); } SetBoost(); } Reply.onclick = (event) => { window.location.href = "../../HTML/post.html?website=" + website; } // Other post stuff. for (let i of document.getElementsByClassName("Regular")) { i.onclick = (event) => { if (i.classList.contains("Handle")) { window.location.href = "../../HTML/account.html?website=" + website; } } } // Selecting other posts. for (let i of document.getElementsByClassName("Parent")) { i.onclick = (event) => { SetThreadPost(Parentpost, i); } } for (let i of document.getElementsByClassName("GrandParent")) { i.onclick = (event) => { SetThreadPost(GrandParentpost, i); } } async function SetThreadPost(element, i) { if (website == "Mastodon") { localStorage.setItem("post", JSON.stringify(element)); } else if (website == "Bluesky") { let Temp = await BlueskyAPI.GetPosts(element.uri); element.post = Temp.posts[0]; localStorage.setItem("post", JSON.stringify(element)); } if (i.classList.contains("Handle")) { window.location.href = "../../HTML/account.html?website=" + website; } else { window.location.href = "../../HTML/expanded.html?website=" + website; } } // Functions and things. async function GetPost() { if (website == "Mastodon") { // Check for a reblog. if (post.reblog != null) { document.getElementsByClassName("Handle Regular")[0].innerHTML = post.reblog + " ( R: " + post.account.username + " )"; } else { document.getElementsByClassName("Handle Regular")[0].innerHTML = post.account.username; } document.getElementsByClassName("PostText Regular")[0].innerHTML = post.content; // Set the texts. It's opposite because "setting" causes it to switch. post = await MastodonAPI.GetStatus(post.id); FavoriteFlipper = !(post.favourited); BoostFlipper = !(post.reblogged); SetFavorite(); SetBoost(); // Show the image if it exists. if (post.media_attachments.length != 0) { for (let i of post.media_attachments) { ApplyMedia(i, document.getElementsByClassName("Images Regular")[0]); } } // Now time to see if there are any parents if (post.in_reply_to_id != null) { Parentpost = await MastodonReplylFunction("Parent", post.in_reply_to_id); // Now time to see if there are any grandparents if (Parentpost != undefined && Parentpost.in_reply_to_id != null) { GrandParentpost = await MastodonReplylFunction("GrandParent", Parentpost.in_reply_to_id); } } } else if (website == "Bluesky") { // Check for a reblog. if (post.hasOwnProperty("reason") && post.reason.$type == "app.bsky.feed.defs#reasonRepost") { document.getElementsByClassName("Handle Regular")[0].innerHTML = post.post.author.handle + " ( R: " + post.reason.by.handle + " )"; } else { document.getElementsByClassName("Handle Regular")[0].innerHTML = post.post.author.handle; } // Text. This will be modified later. var Text = await BlueskyAPI.ApplyFacets(post.post.record, post.post.record.text); // Place the text. Text = Text.replace(/\r?\n|\r/g, "
"); document.getElementsByClassName("PostText Regular")[0].innerHTML = Text; // Show the image if it exists. if (post.post.record.hasOwnProperty("embed")) { ApplyMedia(post.post.record.embed, document.getElementsByClassName("Images Regular")[0], post.post.author.did); } // We don't need to update the post with new information. The repos are seperate. // Set the texts. It's opposite because "setting" causes it to switch. let GetRepo = await BlueskyAPI.GetRecord(localStorage.getItem(Variables.BlueskyDID), "app.bsky.feed.like", post.post.uri.split("/")[post.post.uri.split("/").length - 1]); if (GetRepo.hasOwnProperty("error") && GetRepo.error == "RecordNotFound") { FavoriteFlipper = true; } GetRepo = await BlueskyAPI.GetRecord(localStorage.getItem(Variables.BlueskyDID), "app.bsky.feed.repost", post.post.uri.split("/")[post.post.uri.split("/").length - 1]); if (GetRepo.hasOwnProperty("error") && GetRepo.error == "RecordNotFound") { BoostFlipper = true; } SetFavorite(); SetBoost(); // Now time to see if there are any parents. if (post.hasOwnProperty("reply")) { Parentpost = await BlueskyReplyFunction("Parent", post.reply.parent, post.reply.parent.author); // Now time to see if there are any grandparents. if (Parentpost.value.hasOwnProperty("reply")) { GrandParentpost = await BlueskyReplyFunction("GrandParent", Parentpost.value.reply.parent, post.reply.grandparentAuthor); } } } else { document.getElementsByClassName("PostText")[0].innerHTML = "Nothing to load."; } } // Because of repeat code, we can put it into it's own function. Hell, more of a thread can be added later. async function MastodonReplylFunction(ClassName, post) { let OtherPost = await MastodonAPI.GetStatus(post); document.getElementsByClassName("Origin " + ClassName)[0].innerHTML = website; document.getElementsByClassName("Handle " + ClassName)[0].innerHTML = OtherPost.account.username; if (OtherPost.spoiler_text != "") { document.getElementsByClassName("PostText " + ClassName)[0].innerHTML = "WARNING: " + OtherPost.spoiler_text; } else { document.getElementsByClassName("PostText " + ClassName)[0].innerHTML = OtherPost.content; } if (OtherPost.media_attachments.length != 0) { for (let i of OtherPost.media_attachments) { ApplyMedia(i, document.getElementsByClassName("Images " + ClassName)[0]); } } return OtherPost; } async function BlueskyReplyFunction(ClassName, post, OtherAuthor) { let OtherPost = await BlueskyAPI.GetRecord(post.uri.split("/")[2], post.uri.split("/")[3], post.uri.split("/")[4]); document.getElementsByClassName("Origin " + ClassName)[0].innerHTML = website; document.getElementsByClassName("Handle " + ClassName)[0].innerHTML = OtherAuthor.handle; Text = BlueskyAPI.ApplyFacets(OtherPost.value, OtherPost.value.text); Text = Text.replace(/\r?\n|\r/g, "
"); // Sensitive topic :3 if (OtherPost.value.hasOwnProperty("labels") && OtherPost.value.labels.length != 0) { document.getElementsByClassName("PostText " + ClassName)[0].innerHTML = "LABELS APPLIED: "; for (let lab of OtherPost.value.labels.values) { document.getElementsByClassName("PostText " + ClassName)[0].innerHTML += lab.val + " "; } } else { document.getElementsByClassName("PostText " + ClassName)[0].innerHTML = Text; if (OtherPost.value.hasOwnProperty("embed")) { ApplyMedia(OtherPost.value.embed, document.getElementsByClassName("Images " + ClassName)[0], OtherAuthor.did); } } return OtherPost; } // Applyers. Essentially applies a thing to an operation. // Finds any associated media and applies it to the post. async function ApplyMedia(Media, Element, Author = undefined) { // Check to see if the image is on the same server. if (website == "Mastodon") { if (Media.type == "image") { if (Media.remote_url == null) { Element.innerHTML += "\"""; } else { Element.innerHTML += "\"""; } } else if (Media.type == "video" || Media.type == "gifv") { if (Media.remote_url == null) { Element.innerHTML += ""; } else { Element.innerHTML += ""; } } } else if (website == "Bluesky") { // Record and media embed; They are from seperate posts. if (Media.$type == "app.bsky.embed.recordWithMedia") { await BlueskyBlobEmbed(Media.media, Element, Author); var Texty = await BlueskyAPI.GetPosts([Media.record.record.uri]); var Text = BlueskyAPI.ApplyFacets(Texty.posts[0].record, Texty.posts[0].record.text); Text = Text.replace(/\r?\n|\r/g, "
"); Element.innerHTML += "

" + Text + "


"; // To stop confusion: this is for the RECORD EMBED! It gets an image from the record embed and puts it there. if (Texty.posts[0].record.embed.$type == "app.bsky.embed.images" || Texty.posts[0].record.embed.$type == "app.bsky.embed.video") { await BlueskyBlobEmbed(Texty.posts[0].record.embed, Element, Texty.posts[0].author.did); } // Just a record on it's own. } else if (Media.$type == "app.bsky.embed.record") { var Texty = await BlueskyAPI.GetPosts([Media.record.uri]); var Text = BlueskyAPI.ApplyFacets(Texty.posts[0].record, Texty.posts[0].record.text); Text = Text.replace(/\r?\n|\r/g, "
"); Element.innerHTML += "

" + Text + "


"; if (Texty.posts[0].record.embed.$type == "app.bsky.embed.images" || Texty.posts[0].record.embed.$type == "app.bsky.embed.video") { await BlueskyBlobEmbed(Texty.posts[0].record.embed, Element, Texty.posts[0].author.did); } // Image on it's own } else if (Media.$type == "app.bsky.embed.images" || Media.$type == "app.bsky.embed.video") { await BlueskyBlobEmbed(Media, Element, Author); } } } // Fucking hell. async function BlueskyBlobEmbed(Blob, Element, Author) { if (Blob.$type == "app.bsky.embed.images") { for (let i of Blob.images) { Element.innerHTML += "\"\"/"; var Blobby = await BlueskyAPI.GetBlob(Author, i.image.ref.$link); var ObjectURL = URL.createObjectURL(Blobby); Element = Element.getElementsByTagName("img")[0]; Element.setAttribute("src", ObjectURL); Element.setAttribute("alt", EscapeRegExp(i.alt)); } // Video embed. } else if (Blob.$type == "app.bsky.embed.video") { Element.innerHTML += ""; Element = Element.getElementsByTagName("video")[0]; var Blobby = await BlueskyAPI.GetBlob(Author, Blob.video.ref.$link); var ObjectURL = URL.createObjectURL(Blobby); Element.setAttribute("src", ObjectURL); Element.innerHTML } } // Setters function SetFavorite() { FavoriteFlipper = !(FavoriteFlipper); if (FavoriteFlipper == false) { Favorite.innerHTML = "Favorite!"; } else { Favorite.innerHTML = "Unfavorite..."; } } function SetBoost() { BoostFlipper = !(BoostFlipper); if (BoostFlipper == false) { Boost.innerHTML = "Boost!"; } else { Boost.innerHTML = "Unboost..."; } } // Functions stolen form elsewhere function EscapeRegExp(text) { if (text == null) { return null; } return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\$&'); }