Beautify & Other Things (#26)

:3

Reviewed-on: #26
This commit is contained in:
CatAClock 2025-05-22 23:02:34 +00:00
parent 73472ab227
commit 495c1886f0
19 changed files with 571 additions and 102 deletions

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -12,18 +12,36 @@
</head>
<body style="margin: 0px; text-align: center;">
<!-- Grandparent is a reply post above the reply post above the regular, clicked post. -->
<header>
<h1 class="Handle"></h1>
<h2 class="Origin"></h2>
<h1 class="Handle GrandParent"></h1>
<h2 class="Origin GrandParent"></h2>
</header>
<p class="PostText"></p>
<div class="Images">
</div>
<div>
<p class="PostText GrandParent"></p>
<div class="Images GrandParent"></div>
<hr/>
<!-- Parent is a reply post above the regular, clicked post. -->
<header>
<h1 class="Handle Parent"></h1>
<h2 class="Origin Parent"></h2>
</header>
<p class="PostText Parent"></p>
<div class="Images Parent"></div>
<hr/>
<!-- The regular, clicked post. -->
<header>
<h1 class="Handle Regular"></h1>
<h2 class="Origin Regular"></h2>
</header>
<p class="PostText Regular"></p>
<div class="Images Regular"></div>
<div "display: flex;">
<p class="Favorite">Favorite!</p>
<p class="Boost">Boost!</p>
<p class="Reply">Reply!</p>
</div>
<p onclick="history.back()"><b>Back</b></p>
<footer>
<p class="Button" onclick="history.back()"><b>Back</b></p>
</footer>
</body>
</html>

View file

@ -12,12 +12,16 @@
</head>
<body style="margin: 0px; text-align: center;">
<section style="position: absolute; width: 100%; height: 100%" class="Favorites"></section>
<section style="position: absolute; width: 100%; height: 100%" class="Bookmarks"></section>
<section style="position: absolute; width: 100%; height: 100%" class="Notifications"></section>
<header style="position: relative; z-index: 1;">
<header>
<h1>Mail</h1>
<p onclick="history.back();"><b>Back</b></p>
</header>
<div style="height: 85vh;">
<section class="Favorites"></section>
<section class="Bookmarks"></section>
<section class="Notifications"></section>
</div>
<footer>
<p class="Button" onclick="history.back();"><b>Back</b></p>
</footer>
</body>
</html>

View file

@ -15,16 +15,22 @@
<header>
<h1>Post</h1>
</header>
<textarea cols="50" rows="25" class="Text" placeholder="status here..."></textarea>
<div>
<select class="PostVisibility">
<option value="Public">Public Post</option>
<option value="Quiet">Quiet Public Post</option>
<option value="Friend">Friends Only Post</option>
<option value="Private">Private Post</option>
</select>
</div>
<p class="Button">POST!</p>
<p onclick="history.back();"><b>Back</b></p>
<section>
<textarea cols="50" rows="25" class="Text" placeholder="status here..."></textarea>
<div>
<select class="PostVisibility">
<option value="Public">Public Post</option>
<option value="Quiet">Quiet Public Post</option>
<option value="Friend">Friends Only Post</option>
<option value="Private">Private Post</option>
</select>
<input type="checkbox" class="PostYoutube" />
<label>Post to Youtube</label>
</div>
<p class="Button">POST!</p>
</section>
<footer>
<p class="SmallButton" onclick="history.back();"><b>Back</b></p>
</footer>
</body>
</html>

View file

@ -15,14 +15,37 @@
<header>
<h1>Setting</h1>
</header>
<p class="Local">Toggle Local</p>
<p class="Remote">Toggle Remote</p>
<p class="Login Mastodon"><em>Login to Mastodon</em></p>
<input type="text" class="WebInput Mastodon" placeholder="Website (mastodon.social)"/>
<p class="Logout Mastodon" style="visibility: hidden;"><em>Logout of Mastodon</em></p>
<p class="Login Bluesky"><em>Login to Bluesky</em></p>
<input type="text" class="WebInput Bluesky" placeholder="Website (bsky.social)" />
<p class="Logout Bluesky" style="visibility: hidden;"><em>Logout of Bluesky</em></p>
<p onclick="window.location.href = window.location.origin"><b>Back</b></p>
<div style="display: flex; justify-content: center; height: 75vh;">
<div class="Button" style="margin: auto;">
<p class="Local">Toggle Local</p>
<p class="Remote">Toggle Remote</p>
</div>
<div class="Button" style="display: flex; justify-content: center; margin: auto;">
<!-- Sorry people! -->
<!-- Mastodon things. -->
<div>
<input type="text" class="WebInput Mastodon" placeholder="Website (mastodon.social)"/>
<p class="Login Mastodon"><em>Login to Mastodon</em></p>
<p class="Logout Mastodon Hidden"><em>Logout of Mastodon</em></p>
</div>
<!-- Bluesky things. -->
<div>
<input type="text" class="WebInput Bluesky" placeholder="Website (bsky.social)"/>
<p class="Login Bluesky"><em>Login to Bluesky</em></p>
<p class="Logout Bluesky Hidden"><em>Logout of Bluesky</em></p>
</div>
<!-- Youtube things. -->
<div>
<input type="text" class="WebInput Youtube" placeholder="Youtube API Key"/>
<input type="text" class="WebInput Youtube" placeholder="Youtube Channel Handle"/>
<p class="Login Youtube"><em>Login to Youtube</em></p>
<p class="Logout Youtube Hidden"><em>Logout of Youtube</em></p>
</div>
</div>
</div>
<footer>
<!-- This button has a different script compared to others because of authentication measures. -->
<p class="SmallButton" onclick="window.location.href = window.location.origin"><b>Back</b></p>
</footer>
</body>
</html>

BIN
Icons/IndexBackground.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

View file

@ -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;
}

View file

@ -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!

20
JS/YoutubeAPI.js Normal file
View file

@ -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);
}

View file

@ -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 + "<img src=" + i.remote_url + " alt='" + 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 + "<img src=" + i.fullsize + " alt='" + 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) + "<a href='" + i.features[0].uri + "'>" + Text.substring(i.index.byteStart - SubtractNumber, i.index.byteEnd - SubtractNumber) + "</a>" + Text.substring(i.index.byteEnd - SubtractNumber, Text.length - 1);
}
}
}
// Place the text.
Text = Text.replace(/\r?\n|\r/g, "<br/>");
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 += "<img src=" + Media.url + " alt='" + Media.description + "'/>";
} else {
Element.innerHTML += "<img src=" + Media.remote_url + " alt='" + Media.description + "'/>";
}
} else if (Media.type == "video") {
if (Media.remote_url == null) {
Element.innerHTML += "<video controls src=" + Media.url + " alt='" + Media.description + "'></video>";
} else {
Element.innerHTML += "<video controls src=" + Media.remote_url + " alt='" + Media.description + "'></video>";
}
}
} 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 += "<p class='Embed'>" + Texty.posts[0].record.text + "</p><br/>";
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 += "<img src=" + ObjectURL + " alt='" + 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 += "<video controls src=" + ObjectURL + "></video>";
}
// 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 += "<img src=" + ObjectURL + " alt='" + 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 += "<video controls src=" + ObjectURL + "></video>";
}
}
}
function SetFavorite() {
FavoriteFlipper = !(FavoriteFlipper);
if (FavoriteFlipper == false) {

View file

@ -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!<br/>";
// 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!<br/>";
} else if (MastodonLoadedFeed[CurrentThing + counter].reblog.media_attachments[0].type == "video") {
i.getElementsByClassName("PostContent")[0].innerHTML += "This post has a video!<br/>";
}
}
} 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!<br/>";
} else if (MastodonLoadedFeed[CurrentThing + counter].media_attachments[0].type == "video") {
i.getElementsByClassName("PostContent")[0].innerHTML += "This post has a video!<br/>";
}
}
}
// Check for a thread.
if (MastodonLoadedFeed[CurrentThing + counter].in_reply_to_id != null) {
i.getElementsByClassName("PostContent")[0].innerHTML += "This post is a thread!<br/>";
}
// 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!<br/>";
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!<br/>";
} else if (BlueskyLoadedFeed[CurrentThing + counter].post.record.embed.$type == "app.bsky.embed.video") {
i.getElementsByClassName("PostContent")[0].innerHTML += "This post has a video!<br/>";
}
}
// Check for a thread.
if (BlueskyLoadedFeed[CurrentThing + counter].hasOwnProperty("reply")) {
i.getElementsByClassName("PostContent")[0].innerHTML += "This post is a thread!<br/>";
}
// 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) + "<a href='" + i.features[0].uri + "'>" + TempText.substring(i.index.byteStart - SubtractNumber, i.index.byteEnd - SubtractNumber) + "</a>" + TempText.substring(i.index.byteEnd - SubtractNumber, TempText.length - 1);
}
}
}
TempText = TempText.replace(/\r?\n|\r/g, "<br/>");
i.getElementsByClassName("PostContent")[0].innerHTML += TempText;
break;
case 2:
WebsiteAPIType.push("Nothing");

View file

@ -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;
}

View file

@ -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.

View file

@ -15,3 +15,4 @@ Quick launch server without docker: `npx http-server /home/<HomeDirectory>/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|

View file

@ -15,12 +15,16 @@
</head>
<body style="margin: 0px;">
<!-- This gets the user input to make sounds. Also it (hopefully) makes the user more passive. -->
<section class="WarningMessage">
<h2>Warning! Care for yourself!</h2>
<p>
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. <br>
You are also cute :3 <br>
<em>Safety options are available here: https://CrowdedGames.Group</em>
The world might seem like an uncaring place. At a glance, that might seem true looking at social media.<br><br>
However, that doesn't mean nobody cares. The average person has enough affection to share with you. You just need to ask. Trust us.<br><br>
There are mean people on the internet. Pay no attention to them and block them. They don't matter. You do.<br><br>
One more thing... There are people who might also be down. Please spread around the affection. It's for the best.<br><br>
You are also cute :3<br><br>
<em>Safety options are available here: https://CrowdedGames.Group</em><br><br>
<noscript>Look. Javascript is required to run this. I'm sorry, there isn't anything I can do about it.</noscript>
</p>
<p class="BlinkAnimation"><b>Click on this webpage to continue</b></p>
@ -31,6 +35,7 @@
<h1>The World Wide Web</h1>
</header>
<!-- Container to be inside the container. -->
<div style="width: 100%" class="PostContainerContainer">
<div style="left: -170vw;" class="PostContainer Back">
<article class="Post">
@ -290,6 +295,7 @@
</div>
<!-- Arrows to put the stuff going forward and backward (scrolling posts). -->
<img class="Arrow" src="Icons/ArrowLeft.png" onclick="Back()"/>
<img class="Arrow" src="Icons/ArrowRight.png" onclick="Next()"/>