diff --git a/CSS/expanded.css b/CSS/expanded.css index 8715043..00ad5c8 100644 --- a/CSS/expanded.css +++ b/CSS/expanded.css @@ -1,27 +1,46 @@ /* HTML items */ -img { +.Embed, img, video { border-style: solid; border-radius: 1%; + background-color: yellow; + width: 45%; } /* Classes */ .Handle { - + background-color: white; } .Origin { - + background-color: grey; } .PostText { - + background-color: #00FFFF; } .Images { display: flex; justify-content: center; flex-wrap: wrap; - + background-color: #050505; +} + +.Button { + margin-top: 30px; + + border-style: solid; + border-width: 1px; + + width: 100px; + height: 100px; +} + +footer { + display: flex; + justify-content: center; + + height: 5vh; } diff --git a/CSS/index.css b/CSS/index.css index 231b039..1207c5b 100644 --- a/CSS/index.css +++ b/CSS/index.css @@ -111,18 +111,17 @@ html { } /* Classes for the main page */ -.MainBefore { +.MainBefore, .MainAfter { position: absolute; top: 0px; left: 0px; - visibility: collapse; + background-image: url("../Icons/IndexBackground.png"); } -.MainAfter { - position: absolute; - top: 0px; - left: 0px; +/* Animation things to get it working smoothly */ +.MainBefore { + visibility: collapse; } .MainFadeInAnimation { @@ -161,6 +160,7 @@ html { height: 5vh; } +/* Stuff that goes into the posts. */ .Arrow { position: absolute; top: 35vh; @@ -182,11 +182,21 @@ html { .Post { overflow: hidden; + margin-top: 1%; + margin-bottom: 1%; + margin-left: 1%; + margin-right: 1%; + border-style: solid; border-width: 2px; + border-top-left-radius: 2% 50%; + border-top-right-radius: 2% 50%; + border-bottom-left-radius: 2% 50%; + border-bottom-right-radius: 2% 50%; - width: 24%; - height: 25%; + background-color: #FFFFFF; + width: 22%; + height: 23%; } .Post:hover { @@ -196,35 +206,46 @@ html { .Username { text-align: center; font-weight: bold; + font-size: 2ch; + + margin-top: -5px; } .PostContent { - font-size: 1ch; + font-size: 0.9ch; } -.Setting { - border-style: solid; - border-width: 1px; -} - -.Mail { - border-style: solid; - border-width: 1px; -} - -.Posting { +/* Footer things */ +.Setting, .Posting, .Mail { + margin-top: 30px; + border-style: solid; border-width: 1px; + width: 100px; + height: 100px; +} + +.Time { + font-size: 4ch; +} + +.Posting { margin-right: 5%; } .MainFooter { display: flex; - margin-top: 75vh; - text-align: center; justify-content: center; - height: 15vh; + background: linear-gradient(#dcdcdc, #b4b4b4); + + margin-top: 75vh; + + border-top-style: solid; + border-width: 2px; + border-color: #00FFFF; + + height: 20vh; } diff --git a/CSS/mail.css b/CSS/mail.css index e18b85f..f1a1769 100644 --- a/CSS/mail.css +++ b/CSS/mail.css @@ -1,3 +1,36 @@ +/* Combination */ +header, footer { + style="position: relative; + z-index: 1; +} + +/* Singletons */ +html { + background: linear-gradient(#b4b4b4, #dcdcdc, #b4b4b4); + overflow-x: hidden; + overflow-y: hidden; +} + +header { + height: 5vh; +} + +section { + position: absolute; + width: 100%; + height: 80vh; +} + +.Button { + margin-top: 30px; + + border-style: solid; + border-width: 1px; + + width: 100px; + height: 100px; +} + .Favorite { border-style: solid; border-width: 2px; @@ -42,3 +75,12 @@ .Notification:hover { overflow: visible; } + +footer { + display: flex; + justify-content: center; + + margin-top: -10vh; + + height: 20vh; +} diff --git a/CSS/post.css b/CSS/post.css index 8b13789..8d19465 100644 --- a/CSS/post.css +++ b/CSS/post.css @@ -1 +1,29 @@ +html { + overflow-x: hidden; + overflow-y: hidden; +} +header { + height: 5vh; +} + +section { + height: 75vh; +} + +.SmallButton { + margin-top: 30px; + + border-style: solid; + border-width: 1px; + + width: 100px; + height: 100px; +} + +footer { + display: flex; + justify-content: center; + + height: 5vh; +} diff --git a/CSS/setting.css b/CSS/setting.css index e69de29..a86bd3d 100644 --- a/CSS/setting.css +++ b/CSS/setting.css @@ -0,0 +1,47 @@ +html { + background-color: black; + color: white; + overflow-x: hidden; + overflow-y: hidden; +} + +header { + border-bottom-style: solid; + + height: 5vh; +} + +.Hidden { + visibility: hidden; + display: none; +} + +.Button { + border-style: solid; + border-width: 6px; + border-color: #00FFFF; + + padding: 25vh 8vw; + + background: linear-gradient(#dcdcdc, #b4b4b4); + color: black; +} + +.SmallButton { + margin-top: 30px; + + border-style: solid; + border-width: 1px; + + width: 100px; + height: 100px; +} + +footer { + display: flex; + justify-content: center; + + border-top-style: solid; + + height: 10vh; +} diff --git a/HTML/expanded.html b/HTML/expanded.html index 76ce64e..1c5dc91 100644 --- a/HTML/expanded.html +++ b/HTML/expanded.html @@ -12,18 +12,36 @@ +
-

-

+

+

-

-
-
-
+

+
+
+ +
+

+

+
+

+
+
+ +
+

+

+
+

+
+

Favorite!

Boost!

Reply!

-

Back

+ diff --git a/HTML/mail.html b/HTML/mail.html index d9417a7..37ce1fe 100644 --- a/HTML/mail.html +++ b/HTML/mail.html @@ -12,12 +12,16 @@ -
-
-
-
+

Mail

-

Back

+
+
+
+
+
+
+

Back

+
diff --git a/HTML/post.html b/HTML/post.html index 612c6e9..15dc869 100644 --- a/HTML/post.html +++ b/HTML/post.html @@ -15,16 +15,22 @@

Post

- -
- -
-

POST!

-

Back

+
+ +
+ + + +
+

POST!

+
+
+

Back

+
diff --git a/HTML/setting.html b/HTML/setting.html index 51f38ed..6a25e31 100644 --- a/HTML/setting.html +++ b/HTML/setting.html @@ -15,14 +15,37 @@

Setting

-

Toggle Local

-

Toggle Remote

- - - - - - -

Back

+
+
+

Toggle Local

+

Toggle Remote

+
+
+ + +
+ + + +
+ +
+ + + +
+ +
+ + + + +
+
+
+
+ +

Back

+
diff --git a/Icons/IndexBackground.png b/Icons/IndexBackground.png new file mode 100644 index 0000000..94981bf Binary files /dev/null and b/Icons/IndexBackground.png differ diff --git a/JS/BlueskyAPI.js b/JS/BlueskyAPI.js index 2d18b84..da94bff 100644 --- a/JS/BlueskyAPI.js +++ b/JS/BlueskyAPI.js @@ -47,9 +47,8 @@ export async function GetPosts(URIs) { // Get a blob (like an image or video). Authentication need not apply. export async function GetBlob(DID, CID) { - let PDS = localStorage.getItem(Variables.BlueskyPDS); let request = fetch("https://bsky.social/xrpc/com.atproto.sync.getBlob?did=" + DID + "&cid=" + CID, {method: "GET"}); - let body = await request.then((response) => response.json()); + let body = await request.then((response) => response.blob()); return body; } diff --git a/JS/Variables.js b/JS/Variables.js index 29d0cf6..3b78a21 100644 --- a/JS/Variables.js +++ b/JS/Variables.js @@ -19,5 +19,8 @@ export const BlueskyRefreshToken = "bluesky_refresh_token"; // Tumblr export const TumblrWebsiteName = "https://www.tumblr.com"; -// WARNING: Research suggests that cookies are very unsecue. +// Youtube +export const YoutubeID = "youtube_id"; + +// WARNING: Research suggests that cookies are very unsecure. // Every Fetch request (http or https) sends these cookies. That's bad! diff --git a/JS/YoutubeAPI.js b/JS/YoutubeAPI.js new file mode 100644 index 0000000..f6aa224 --- /dev/null +++ b/JS/YoutubeAPI.js @@ -0,0 +1,20 @@ +import * as Variables from "./Variables.js"; + +// Uses the API to get the channel ID. +// Interesting problem: You have to use either an API key or a Auth2.0. +// I think only developer asses will be using this, so we'll use API keys. +export async function GetChannelID(APIKey, Channel) { + if (Channel == "" || APIKey == "") { + console.error("Forgot a variable."); + return; + } + if (Channel.slice(0, 1) != "@") { + // Apply the correct Handle + Channel = "@" + Channel; + } + // Get the channel ID + var webbiesite = "https://www.googleapis.com/youtube/v3/channels"; + var response = await fetch(webbiesite + "?part=id&forHandle=" + Channel + "&key=" + APIKey, {method: "GET"}) + .then((response) => response.json()); + localStorage.setItem(Variables.YoutubeID, response.items[0].id); +} diff --git a/JS/expanded.js b/JS/expanded.js index 497f650..931b266 100644 --- a/JS/expanded.js +++ b/JS/expanded.js @@ -15,7 +15,7 @@ let BoostFlipper = false; let website = document.location.href.split("website=")[1]; let post = JSON.parse(localStorage.getItem("post")); -document.getElementsByClassName("Origin")[0].innerHTML = website; +document.getElementsByClassName("Origin Regular")[0].innerHTML = website; GetPost(); // Button stuff @@ -46,48 +46,186 @@ async function GetPost() { if (website == "Mastodon") { // Check for a reblog. if (post.reblog != null) { - document.getElementsByClassName("PostText")[0].innerHTML = post.reblog.content; - document.getElementsByClassName("Handle")[0].innerHTML = post.reblog.account.username + " ( R: " + post.account.username + " )"; + document.getElementsByClassName("PostText Regular")[0].innerHTML = post.reblog.content; + document.getElementsByClassName("Handle Regular")[0].innerHTML = post.reblog.account.username + " ( R: " + post.account.username + " )"; + if (post.reblog.media_attachments.length != 0) { + for (let i of post.reblog.media_attachments) { + await CreateMedia(i, document.getElementsByClassName("Images Regular")[0]); + } + } } else { - document.getElementsByClassName("PostText")[0].innerHTML = post.content; - document.getElementsByClassName("Handle")[0].innerHTML = post.account.username; - } - // Show the image if it exists. - if (post.media_attachments.length != 0) { - for (let i of post.media_attachments) { - document.getElementsByClassName("Images")[0].innerHTML = document.getElementsByClassName("Images")[0].innerHTML + "" + i.description + ""; + document.getElementsByClassName("PostText Regular")[0].innerHTML = post.content; + document.getElementsByClassName("Handle Regular")[0].innerHTML = post.account.username; + // Show the image if it exists. + if (post.media_attachments.length != 0) { + for (let i of post.media_attachments) { + await CreateMedia(i, document.getElementsByClassName("Images Regular")[0]); + } } } - // Update the post to see if there is new information. - post = await MastodonAPI.GetStatus(post.id); - // Set the texts. + // Set the texts. It's opposite because "setting" causes it to switch. FavoriteFlipper = !(post.favourite); BoostFlipper = !(post.reblogged); SetFavorite(); SetBoost(); + // Now time to see if there are any parents + if (post.in_reply_to_id != null) { + var AnotherPost = await MastodonAPI.GetStatus(post.in_reply_to_id); + document.getElementsByClassName("Origin Parent")[0].innerHTML = website; + if (AnotherPost.reblog != null) { + document.getElementsByClassName("PostText Parent")[0].innerHTML = AnotherPost.reblog.content; + if (AnotherPost.reblog.media_attachments.length != 0) { + for (let i of AnotherPost.reblog.media_attachments) { + await CreateMedia(i, document.getElementsByClassName("Images Parent")[0]); + } + } + } else { + document.getElementsByClassName("PostText Parent")[0].innerHTML = AnotherPost.content; + if (AnotherPost.media_attachments.length != 0) { + for (let i of AnotherPost.media_attachments) { + await CreateMedia(i, document.getElementsByClassName("Images Parent")[0]); + } + } + } + // Now time to see if there are any grandparents + if (AnotherPost.in_reply_to_id != null) { + var AnotherAnotherPost = await MastodonAPI.GetStatus(AnotherPost.in_reply_to_id); + document.getElementsByClassName("Origin GrandParent")[0].innerHTML = website; + if (AnotherAnotherPost.reblog != null) { + document.getElementsByClassName("PostText GrandParent")[0].innerHTML = AnotherAnotherPost.reblog.content; + if (AnotherAnotherPost.reblog.media_attachments.length != 0) { + for (let i of AnotherAnotherPost.reblog.media_attachments) { + await CreateMedia(i, document.getElementsByClassName("Images GrandParent")[0]); + } + } + } else { + document.getElementsByClassName("PostText GrandParent")[0].innerHTML = AnotherAnotherPost.content; + if (AnotherAnotherPost.media_attachments.length != 0) { + for (let i of AnotherAnotherPost.media_attachments) { + await CreateMedia(i, document.getElementsByClassName("Images GrandParent")[0]); + } + } + } + } + } } else if (website == "Bluesky") { // Check for a reblog. if (post.hasOwnProperty("reason") && post.reason.$type == "app.bsky.feed.defs#reasonRepost") { - document.getElementsByClassName("PostText")[0].innerHTML = post.post.record.text; - document.getElementsByClassName("Handle")[0].innerHTML = post.post.author.handle + " ( R: " + post.reason.by.handle + " )"; + document.getElementsByClassName("Handle Regular")[0].innerHTML = post.post.author.handle + " ( R: " + post.reason.by.handle + " )"; } else { - document.getElementsByClassName("PostText")[0].innerHTML = post.post.record.text; - document.getElementsByClassName("Handle")[0].innerHTML = post.post.author.handle; + document.getElementsByClassName("Handle Regular")[0].innerHTML = post.post.author.handle; } - // Show the image if it exists. - if (post.post.record.hasOwnProperty("embed") && post.post.record.embed.$type == "app.bsky.embed.images") { - for (let i of post.post.embed.images) { - document.getElementsByClassName("Images")[0].innerHTML = document.getElementsByClassName("Images")[0].innerHTML + "" + i.alt + ""; + // Text. This will be modified later. + var Text = post.post.record.text; + console.log(Text); + var TestText = Text.replace(/\r?\n|\r/g, ""); + console.log(TestText); + // Check for facets. Facets are things that change what the text does or looks like. + if (post.post.record.hasOwnProperty("facets")) { + for (let i of post.post.record.facets) { + if (i.features[0].$type == "app.bsky.richtext.facet#link") { + var EmojiRegex = /\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F/gu; + var EmojiObjects = Text.match(EmojiRegex); + var SubtractNumber = 0; + if (EmojiObjects != null) { + SubtractNumber = EmojiObjects.length * 2; + } + Text = Text.substring(0, i.index.byteStart - SubtractNumber) + "" + Text.substring(i.index.byteStart - SubtractNumber, i.index.byteEnd - SubtractNumber) + "" + Text.substring(i.index.byteEnd - SubtractNumber, Text.length - 1); + } } } + // 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")) { + await CreateMedia(post.post.record, 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. - // TODO! + // 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")) { + var AnotherPost = await BlueskyAPI.GetRecord(post.reply.parent.uri.split("/")[2], post.reply.parent.uri.split("/")[3], post.reply.parent.uri.split("/")[4]); + document.getElementsByClassName("Origin Parent")[0].innerHTML = website; + document.getElementsByClassName("Handle Parent")[0].innerHTML = post.reply.parent.author.handle; + document.getElementsByClassName("PostText Parent")[0].innerHTML = AnotherPost.value.text; + if (AnotherPost.value.hasOwnProperty("embed")) { + await CreateMedia(AnotherPost.value, document.getElementsByClassName("Images Parent")[0], post.reply.parent.author.did); + } + + // Now time to see if there are any grandparents. + if (AnotherPost.value.hasOwnProperty("reply")) { + var AnotherAnotherPost = await BlueskyAPI.GetRecord(AnotherPost.value.reply.parent.uri.split("/")[2], AnotherPost.value.reply.parent.uri.split("/")[3], AnotherPost.value.reply.parent.uri.split("/")[4]); + document.getElementsByClassName("Origin GrandParent")[0].innerHTML = website; + document.getElementsByClassName("Handle Parent")[0].innerHTML = post.reply.grandparentAuthor.handle; + document.getElementsByClassName("PostText GrandParent")[0].innerHTML = AnotherAnotherPost.value.text; + if (AnotherAnotherPost.value.hasOwnProperty("embed")) { + await CreateMedia(AnotherAnotherPost.value, document.getElementsByClassName("Images GrandParent")[0], post.reply.grandparentAuthor.did); + } + } + } } else { document.getElementsByClassName("PostText")[0].innerHTML = "Nothing to load."; } } +async function CreateMedia(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 += "" + Media.description + ""; + } else { + Element.innerHTML += "" + Media.description + ""; + } + } else if (Media.type == "video") { + if (Media.remote_url == null) { + Element.innerHTML += ""; + } else { + Element.innerHTML += ""; + } + } + } else if (website == "Bluesky") { + if (Media.embed.$type == "app.bsky.embed.record") { + var Texty = await BlueskyAPI.GetPosts([Media.embed.record.uri]); + console.log(Texty); + Element.innerHTML += "

" + Texty.posts[0].record.text + "


"; + if (Texty.posts[0].embed.$type == "app.bsky.embed.images") { + for (let i of Texty.posts[0].embed.images) { + var Blobby = await BlueskyAPI.GetBlob(Author, i.image.ref.$link); + var ObjectURL = URL.createObjectURL(Blobby); + Element.innerHTML += "" + i.alt + ""; + } + } else if (Media.embed.$type == "app.bsky.embed.video") { + var Blobby = await BlueskyAPI.GetBlob(Author, Texty.posts[0].embed.video.ref.$link); + var ObjectURL = URL.createObjectURL(Blobby); + Element.innerHTML += ""; + } + // It's not an embed, continue... + } else if (Media.embed.$type == "app.bsky.embed.images") { + for (let i of Media.embed.images) { + var Blobby = await BlueskyAPI.GetBlob(Author, i.image.ref.$link); + var ObjectURL = URL.createObjectURL(Blobby); + Element.innerHTML += "" + i.alt + ""; + } + } else if (Media.embed.$type == "app.bsky.embed.video") { + var Blobby = await BlueskyAPI.GetBlob(Author, Media.embed.video.ref.$link); + var ObjectURL = URL.createObjectURL(Blobby); + Element.innerHTML += ""; + } + } +} + function SetFavorite() { FavoriteFlipper = !(FavoriteFlipper); if (FavoriteFlipper == false) { diff --git a/JS/index.js b/JS/index.js index f8e93f2..9df50e3 100644 --- a/JS/index.js +++ b/JS/index.js @@ -71,12 +71,19 @@ Warning.onclick = (event) => { setTimeout(() => { Main.classList.remove("MainFadeInAnimation"); Main.classList.add("MainAfter"); - BackgroundMusic.play(); + Music(); }, 5000); Main = document.getElementsByClassName("MainFadeInAnimation")[0]; PosterContainerUpdate(); } +function Music() { + BackgroundMusic.play(); + setTimeout(() => { + Music(); + }, 180000); +} + // Clicking the next button ArrowsButton[1].onclick = (event) => { if (!ContainerContainer.classList.contains("NextAnimation")) { @@ -181,14 +188,34 @@ async function PosterContainerUpdate(Direction) { switch(countergroup) { // Mastodon case 0: + // Begin by having the website we are using get pushed to the expanded view array and clean out the HTML. WebsiteAPIType.push("Mastodon"); + i.getElementsByClassName("PostContent")[0].innerHTML = ""; if (MastodonLoadedFeed[CurrentThing + counter] == undefined) { let TempFeed = await MastodonAPI.GetTimeline(MastodonLoadedFeed[CurrentThing + counter - 1].id); MastodonLoadedFeed = MastodonLoadedFeed.concat(TempFeed); } - // Check for images. - if (MastodonLoadedFeed[CurrentThing + counter].media_attachments.length != 0) { - i.getElementsByClassName("PostContent")[0].innerHTML += "This post has an image!
"; + // Check for images. Reblog roundabout fix included. + if (MastodonLoadedFeed[CurrentThing + counter].reblog != null) { + if (MastodonLoadedFeed[CurrentThing + counter].reblog.media_attachments.length != 0) { + if (MastodonLoadedFeed[CurrentThing + counter].reblog.media_attachments[0].type == "image") { + i.getElementsByClassName("PostContent")[0].innerHTML += "This post has an image!
"; + } else if (MastodonLoadedFeed[CurrentThing + counter].reblog.media_attachments[0].type == "video") { + i.getElementsByClassName("PostContent")[0].innerHTML += "This post has a video!
"; + } + } + } else { + if (MastodonLoadedFeed[CurrentThing + counter].media_attachments.length != 0) { + if (MastodonLoadedFeed[CurrentThing + counter].media_attachments[0].type == "image") { + i.getElementsByClassName("PostContent")[0].innerHTML += "This post has an image!
"; + } else if (MastodonLoadedFeed[CurrentThing + counter].media_attachments[0].type == "video") { + i.getElementsByClassName("PostContent")[0].innerHTML += "This post has a video!
"; + } + } + } + // Check for a thread. + if (MastodonLoadedFeed[CurrentThing + counter].in_reply_to_id != null) { + i.getElementsByClassName("PostContent")[0].innerHTML += "This post is a thread!
"; } // Content warning. Don't show the content unless clicked!!! if (MastodonLoadedFeed[CurrentThing + counter].spoiler_text != "") { @@ -207,7 +234,9 @@ async function PosterContainerUpdate(Direction) { break; // Bsky case 1: + // Begin by having the website we are using get pushed to the expanded view array and clean out the HTML. WebsiteAPIType.push("Bluesky"); + i.getElementsByClassName("PostContent")[0].innerHTML = ""; if (BlueskyLoadedFeed[CurrentThing + counter] == undefined) { let TempFeed = await BlueskyAPI.GetTimeline(BlueskyLoadedFeed[CurrentThing + counter - 1].post.indexedAt).then((response) => response.feed) BlueskyLoadedFeed = BlueskyLoadedFeed.concat(TempFeed); @@ -216,8 +245,16 @@ async function PosterContainerUpdate(Direction) { BlueskyLoadedFeed = CheckForDups(BlueskyLoadedFeed, BlueskyPostsDup, counter); BlueskyPostsDup.push(BlueskyLoadedFeed[counter].post.uri); // Check for an image - if (BlueskyLoadedFeed[CurrentThing + counter].post.record.hasOwnProperty("embed") && BlueskyLoadedFeed[CurrentThing + counter].post.record.embed.$type == "app.bsky.embed.images") { - i.getElementsByClassName("PostContent")[0].innerHTML += "This post has an image!
"; + if (BlueskyLoadedFeed[CurrentThing + counter].post.record.hasOwnProperty("embed")) { + if (BlueskyLoadedFeed[CurrentThing + counter].post.record.embed.$type == "app.bsky.embed.images") { + i.getElementsByClassName("PostContent")[0].innerHTML += "This post has an image!
"; + } else if (BlueskyLoadedFeed[CurrentThing + counter].post.record.embed.$type == "app.bsky.embed.video") { + i.getElementsByClassName("PostContent")[0].innerHTML += "This post has a video!
"; + } + } + // Check for a thread. + if (BlueskyLoadedFeed[CurrentThing + counter].hasOwnProperty("reply")) { + i.getElementsByClassName("PostContent")[0].innerHTML += "This post is a thread!
"; } // Labels if (BlueskyLoadedFeed[CurrentThing + counter].post.labels.length != 0) { @@ -231,12 +268,26 @@ async function PosterContainerUpdate(Direction) { } // Check for a reblog if (BlueskyLoadedFeed[CurrentThing + counter].hasOwnProperty("reason") && BlueskyLoadedFeed[CurrentThing + counter].reason.$type == "app.bsky.feed.defs#reasonRepost") { - i.getElementsByClassName("PostContent")[0].innerHTML += BlueskyLoadedFeed[CurrentThing + counter].post.record.text; i.getElementsByClassName("Username")[0].innerHTML = BlueskyLoadedFeed[CurrentThing + counter].post.author.handle + " ( R: " + BlueskyLoadedFeed[CurrentThing + counter].reason.by.handle + " )"; } else { - i.getElementsByClassName("PostContent")[0].innerHTML += BlueskyLoadedFeed[CurrentThing + counter].post.record.text; i.getElementsByClassName("Username")[0].innerHTML = BlueskyLoadedFeed[CurrentThing + counter].post.author.handle; } + var TempText = BlueskyLoadedFeed[CurrentThing + counter].post.record.text; + if (BlueskyLoadedFeed[CurrentThing + counter].post.record.hasOwnProperty("facets")) { + for (let i of BlueskyLoadedFeed[CurrentThing + counter].post.record.facets) { + if (i.features[0].$type == "app.bsky.richtext.facet#link") { + var EmojiRegex = /\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F/gu; + var EmojiObjects = TempText.match(EmojiRegex); + var SubtractNumber = 0; + if (EmojiObjects != null) { + SubtractNumber = EmojiObjects.length * 2; + } + TempText = TempText.substring(0, i.index.byteStart - SubtractNumber) + "" + TempText.substring(i.index.byteStart - SubtractNumber, i.index.byteEnd - SubtractNumber) + "" + TempText.substring(i.index.byteEnd - SubtractNumber, TempText.length - 1); + } + } + } + TempText = TempText.replace(/\r?\n|\r/g, "
"); + i.getElementsByClassName("PostContent")[0].innerHTML += TempText; break; case 2: WebsiteAPIType.push("Nothing"); diff --git a/JS/post.js b/JS/post.js index 0d9771f..6d19e07 100644 --- a/JS/post.js +++ b/JS/post.js @@ -7,6 +7,7 @@ import * as Variables from "./Variables.js"; let PostButton = document.getElementsByClassName("Button")[0]; let VisibilityDropdown = document.getElementsByClassName("PostVisibility")[0]; let InputArea = document.getElementsByClassName("Text")[0]; +let YoutubePoser = document.getElementsByClassName("PostYoutube")[0]; // Clicking the beeg POST button. PostButton.onclick = (event) => { @@ -27,7 +28,6 @@ async function Post() { if (Text == "") { return; } - InputArea.value = ""; // Mastodon posting. if (localStorage.getItem(Variables.MastodonAccessToken) != null) { let TempVisible; @@ -84,9 +84,20 @@ async function Post() { await BlueskyAPI.SetThreadGate(localStorage.getItem(Variables.BlueskyDID), Post.uri, TempVisible); } } + // Youtube posting. + if (YoutubePoser.checked == true) { + navigator.clipboard.writeText(Text); + window.open("https://www.youtube.com/channel/" + localStorage.getItem(Variables.YoutubeID) + "/posts"); + } + // The input being cleared means that the posting happened. + InputArea.value = ""; } // Check if you can interact with the textbox -if (localStorage.getItem(Variables.MastodonAccessToken) == null && localStorage.getItem(Variables.BlueskyAccessToken) == null) { +if (localStorage.getItem(Variables.MastodonAccessToken) == null && localStorage.getItem(Variables.BlueskyAccessToken) == null && localStorage.getItem(Variables.YoutubeID) == null) { InputArea.disabled = true; } +// Check if you can post on Youtube +if (localStorage.getItem(Variables.YoutubeID) == null) { + YoutubePoser.disabled = true; +} diff --git a/JS/setting.js b/JS/setting.js index 779975d..9b98a20 100644 --- a/JS/setting.js +++ b/JS/setting.js @@ -1,19 +1,27 @@ import * as MastodonAPI from "./MastodonAPI.js"; import * as BlueskyAPI from "./BlueskyAPI.js"; import * as TumblrAPI from "./TumblrAPI.js"; +import * as YoutubeAPI from "./YoutubeAPI.js"; import * as Variables from "./Variables.js"; // Settings buttons let LocalButton = document.getElementsByClassName("Local")[0]; let RemoteButton = document.getElementsByClassName("Remote")[0]; +// Website Stuff let MastodonLoginButton = document.getElementsByClassName("Login Mastodon")[0]; let MastodonWebInput = document.getElementsByClassName("WebInput Mastodon")[0]; let MastodonLogoutButton = document.getElementsByClassName("Logout Mastodon")[0]; + let BlueskyLoginButton = document.getElementsByClassName("Login Bluesky")[0]; let BlueskyWebInput = document.getElementsByClassName("WebInput Bluesky")[0]; let BlueskyLogoutButton = document.getElementsByClassName("Logout Bluesky")[0]; +let YoutubeLoginButton = document.getElementsByClassName("Login Youtube")[0]; +let YoutubeAPIInput = document.getElementsByClassName("WebInput Youtube")[0]; +let YoutubeHandleInput = document.getElementsByClassName("WebInput Youtube")[1]; +let YoutubeLogoutButton = document.getElementsByClassName("Logout Youtube")[0]; + // original link let Origin = location.origin + "/HTML/setting.html" @@ -59,7 +67,7 @@ MastodonLogoutButton.onclick = (event) => { // Login BlueskyLoginButton.onclick = (event) => { if (BlueskyWebInput.value != "") { - let text = BlueskyWebInput.value + let text = BlueskyWebInput.value; BlueskyAPI.HandleAuthorization(text); } } @@ -78,6 +86,23 @@ BlueskyLogoutButton.onclick = (event) => { document.location.href = Origin; } +// Youtube Buttons +// Login +YoutubeLoginButton.onclick = (event) => { + if (YoutubeHandleInput.value != "" && YoutubeAPIInput.value != "") { + YoutubeAPI.GetChannelID(YoutubeAPIInput.value, YoutubeHandleInput.value); + // Clear the stuff + YoutubeHandleInput.value = ""; + YoutubeAPIInput.value = ""; + } +} + +// Logout +YoutubeLogoutButton.onclick = (event) => { + localStorage.removeItem(Variables.YoutubeID); + document.location.href = Origin; +} + // if an access token is found, login. async function CheckLogin() { // Check for a mastodon token. @@ -85,7 +110,7 @@ async function CheckLogin() { // Swap the buttons MastodonLoginButton.remove(); MastodonWebInput.remove(); - MastodonLogoutButton.setAttribute("style", ""); + MastodonLogoutButton.classList.remove("Hidden"); } else { // Auto log in await MastodonAPI.GainToken(Variables.MastodonWebsite); @@ -95,11 +120,18 @@ async function CheckLogin() { // Swap the buttons BlueskyLoginButton.remove(); BlueskyWebInput.remove(); - BlueskyLogoutButton.setAttribute("style", ""); + BlueskyLogoutButton.classList.remove("Hidden"); } else { // Auto log in await BlueskyAPI.GainTokens(); } + // Check for a Youtube ID. + if (localStorage.getItem(Variables.YoutubeID) != null) { + YoutubeLoginButton.remove(); + YoutubeAPIInput.remove(); + YoutubeHandleInput.remove(); + YoutubeLogoutButton.classList.remove("Hidden"); + } } // Runs on website start. diff --git a/README.md b/README.md index 73d8218..c736e00 100644 --- a/README.md +++ b/README.md @@ -15,3 +15,4 @@ Quick launch server without docker: `npx http-server /home//Docum |Question|Answer| |--------|-------| |Where can I find my PDS?|Create an access token and then examine the payload's `aud`| +|Where can I get a Youtube Key?|console.cloud.google.com/apis| diff --git a/index.html b/index.html index 8ca936d..fa40d56 100644 --- a/index.html +++ b/index.html @@ -15,12 +15,16 @@ +

Warning! Care for yourself!

- The world might seem like an uncaring place. At a glance, that might seem true. However, that doesn't mean nobody cares. The average person has enough affection to share with you, so please share it back.
- You are also cute :3
- Safety options are available here: https://CrowdedGames.Group + The world might seem like an uncaring place. At a glance, that might seem true looking at social media.

+ However, that doesn't mean nobody cares. The average person has enough affection to share with you. You just need to ask. Trust us.

+ There are mean people on the internet. Pay no attention to them and block them. They don't matter. You do.

+ One more thing... There are people who might also be down. Please spread around the affection. It's for the best.

+ You are also cute :3

+ Safety options are available here: https://CrowdedGames.Group

Click on this webpage to continue

@@ -31,6 +35,7 @@

The World Wide Web

+
@@ -290,6 +295,7 @@
+