Public Timelines improvements and fixes (#14)
Here's the rundown: The public timeline no longer exists. However: your private timelines now exist and can be scrolled back and forth. This is an addition to content warnings, boosts, and plenty of bug fixes. A code cleanup has been put into place as well to cut down on some of the crap. Overall it's pretty good. Reviewed-on: #14
This commit is contained in:
parent
9b52f641cb
commit
8b66616c4e
10 changed files with 447 additions and 168 deletions
0
CSS/expanded.css
Normal file
0
CSS/expanded.css
Normal file
|
@ -178,7 +178,9 @@ html {
|
|||
height: 70vh;
|
||||
}
|
||||
|
||||
.Post {
|
||||
.Post {
|
||||
overflow: hidden;
|
||||
|
||||
border-style: solid;
|
||||
border-width: 2px;
|
||||
|
||||
|
@ -186,6 +188,10 @@ html {
|
|||
height: 25%;
|
||||
}
|
||||
|
||||
.Post:hover {
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
.Username {
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
|
|
22
HTML/expanded.html
Normal file
22
HTML/expanded.html
Normal file
|
@ -0,0 +1,22 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>The Fediverse</title>
|
||||
<meta name="description" content="Change the fucking channel already!">
|
||||
<link rel="icon" href="../Icons/favicon.ico" />
|
||||
<link rel="stylesheet" href="../CSS/expanded.css">
|
||||
<script type="module" src="../JS/expanded.js"></script>
|
||||
<!-- Dependenci -->
|
||||
<script language="JavaScript" type="text/javascript" src="https://kjur.github.io/jsrsasign/jsrsasign-latest-all-min.js"></script>
|
||||
</head>
|
||||
|
||||
<body style="margin: 0px; text-align: center;">
|
||||
<header>
|
||||
<h1 class="Handle"></h1>
|
||||
<h2 class="Origin">Bsky/Mastodon (TODO)</h2>
|
||||
<p class="DetailedText"></p>
|
||||
<p>Image here if it is a thing (TODO)</p>
|
||||
<p onclick="history.back()"><b>Back</b></p>
|
||||
</header>
|
||||
</body>
|
||||
</html>
|
118
JS/BlueskyAPI.js
118
JS/BlueskyAPI.js
|
@ -1,6 +1,37 @@
|
|||
import * as Variables from "./Variables.js";
|
||||
|
||||
export async function GetTimeline(Cursor) {
|
||||
if (localStorage.getItem(Variables.BlueskyAccessToken) == null) {
|
||||
console.log("No access token!");
|
||||
return "";
|
||||
}
|
||||
|
||||
let PDS = localStorage.getItem(Variables.BlueskyPDS);
|
||||
let DPoP;
|
||||
let request;
|
||||
if (Cursor == "") {
|
||||
DPoP = await ClientDPoPPDS("GET", PDS + "/xrpc/app.bsky.feed.getTimeline");
|
||||
request = fetch(PDS + "/xrpc/app.bsky.feed.getTimeline", {method: "GET", headers: {"Authorization": "DPoP " + localStorage.getItem(Variables.BlueskyAccessToken), "DPoP": DPoP}});
|
||||
} else {
|
||||
DPoP = await ClientDPoPPDS("GET", PDS + "/xrpc/app.bsky.feed.getTimeline?cursor=" + Cursor);
|
||||
request = fetch(PDS + "/xrpc/app.bsky.feed.getTimeline?cursor=" + Cursor, {method: "GET", headers: {"Authorization": "DPoP " + localStorage.getItem(Variables.BlueskyAccessToken), "DPoP": DPoP}});
|
||||
}
|
||||
let body = await request.then((response) => response.json());
|
||||
let status = await request.then((response) => response.status);
|
||||
let header = await request.then((response) => response.headers.get("dpop-nonce"));
|
||||
if (status == 401) {
|
||||
await HandleError(body, header);
|
||||
body = await GetTimeline(Cursor);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
export async function CreatePost(DID, Text) {
|
||||
if (localStorage.getItem(Variables.BlueskyAccessToken) == null) {
|
||||
console.log("No access token!");
|
||||
return "";
|
||||
}
|
||||
|
||||
let PDS = localStorage.getItem(Variables.BlueskyPDS);
|
||||
let Json = {
|
||||
"$type": "app.bsky.feed.post",
|
||||
|
@ -18,18 +49,77 @@ export async function CreatePost(DID, Text) {
|
|||
let status = await request.then((response) => response.status);
|
||||
let header = await request.then((response) => response.headers.get("dpop-nonce"));
|
||||
if (status == 401) {
|
||||
if (body.message.includes("DPoP nonce mismatch")) {
|
||||
await localStorage.setItem(Variables.BlueskyNonce, header);
|
||||
}
|
||||
if (body.message.includes("claim timestamp check failed")) {
|
||||
await RefreshTokens();
|
||||
}
|
||||
await HandleError(body, header);
|
||||
body = await CreatePost(DID, Text);
|
||||
}
|
||||
if (status == 400) {
|
||||
let matches = body.message.match(/(\d+)/);
|
||||
Json.text = Text.slice(0, matches[0] - 1);
|
||||
RequestBody.record = Json;
|
||||
DPoP = await ClientDPoPPDS("POST", PDS + "/xrpc/com.atproto.repo.createRecord");
|
||||
request = fetch(PDS + "/xrpc/com.atproto.repo.createRecord", { body: JSON.stringify(RequestBody), method: "POST", headers: {"Content-Type": "application/json", "Authorization": "DPoP " + localStorage.getItem(Variables.BlueskyAccessToken), "DPoP": DPoP}});
|
||||
body = await request.then((response) => response.json());
|
||||
status = await request.then((response) => response.status);
|
||||
await CreateReplyPost(DID, Text.slice(matches[0] - 1, Text.length - 1), body, body);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
export async function CreateReplyPost(DID, Text, ReplyID, RootID) {
|
||||
if (localStorage.getItem(Variables.BlueskyAccessToken) == null) {
|
||||
console.log("No access token!");
|
||||
return "";
|
||||
}
|
||||
|
||||
let PDS = localStorage.getItem(Variables.BlueskyPDS);
|
||||
let Json = {
|
||||
"$type": "app.bsky.feed.post",
|
||||
"text": Text,
|
||||
"createdAt": new Date(Date.now()).toISOString(),
|
||||
"reply": {
|
||||
"root": {
|
||||
"uri": ReplyID.uri,
|
||||
"cid": ReplyID.cid
|
||||
},
|
||||
"parent": {
|
||||
"uri": RootID.uri,
|
||||
"cid": RootID.cid
|
||||
}
|
||||
}
|
||||
}
|
||||
let RequestBody = {
|
||||
"repo": DID,
|
||||
"collection": "app.bsky.feed.post",
|
||||
"record": Json
|
||||
}
|
||||
let DPoP = await ClientDPoPPDS("POST", PDS + "/xrpc/com.atproto.repo.createRecord");
|
||||
let request = fetch(PDS + "/xrpc/com.atproto.repo.createRecord", { body: JSON.stringify(RequestBody), method: "POST", headers: {"Content-Type": "application/json", "Authorization": "DPoP " + localStorage.getItem(Variables.BlueskyAccessToken), "DPoP": DPoP}});
|
||||
let body = await request.then((response) => response.json());
|
||||
let status = await request.then((response) => response.status);
|
||||
let header = await request.then((response) => response.headers.get("dpop-nonce"));
|
||||
if (status == 401) {
|
||||
await HandleError(body, header);
|
||||
body = await CreatePost(DID, Text);
|
||||
}
|
||||
if (status == 400) {
|
||||
let matches = body.message.match(/(\d+)/);
|
||||
Json.text = Text.slice(0, matches[0] - 1);
|
||||
RequestBody.record = Json;
|
||||
let DPoP = await ClientDPoPPDS("POST", PDS + "/xrpc/com.atproto.repo.createRecord");
|
||||
let request = fetch(PDS + "/xrpc/com.atproto.repo.createRecord", { body: JSON.stringify(RequestBody), method: "POST", headers: {"Content-Type": "application/json", "Authorization": "DPoP " + localStorage.getItem(Variables.BlueskyAccessToken), "DPoP": DPoP}});
|
||||
let body = await request.then((response) => response.json());
|
||||
let status = await request.then((response) => response.status);
|
||||
await CreateReplyPost(DID, Text.slice(matches[0] - 1, Text.length - 1), body, RootID);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
export async function SetThreadGate(DID, Post, VisibilitySettings) {
|
||||
if (localStorage.getItem(Variables.BlueskyAccessToken) == null) {
|
||||
console.log("No access token!");
|
||||
return "";
|
||||
}
|
||||
|
||||
let PDS = localStorage.getItem(Variables.BlueskyPDS);
|
||||
let Json = {
|
||||
"$type": "app.bsky.feed.threadgate",
|
||||
|
@ -49,12 +139,7 @@ export async function SetThreadGate(DID, Post, VisibilitySettings) {
|
|||
let status = await request.then((response) => response.status);
|
||||
let header = await request.then((response) => response.headers.get("dpop-nonce"));
|
||||
if (status == 401) {
|
||||
if (body.message.includes("DPoP nonce mismatch")) {
|
||||
await localStorage.setItem(Variables.BlueskyNonce, header);
|
||||
}
|
||||
if (body.message.includes("claim timestamp check failed")) {
|
||||
await RefreshTokens();
|
||||
}
|
||||
await HandleError(body, header);
|
||||
body = await SetThreadGate(DID, Post, VisibilitySettings);
|
||||
}
|
||||
return body;
|
||||
|
@ -251,6 +336,15 @@ export async function RefreshTokens() {
|
|||
localStorage.setItem(Variables.BlueskyRefreshToken, body.refresh_token);
|
||||
}
|
||||
|
||||
async function HandleError(body, header) {
|
||||
if (body.message.includes("DPoP nonce mismatch")) {
|
||||
await localStorage.setItem(Variables.BlueskyNonce, header);
|
||||
}
|
||||
if (body.message.includes("claim timestamp check failed")) {
|
||||
await RefreshTokens();
|
||||
}
|
||||
}
|
||||
|
||||
// Stolen from elsewhere.
|
||||
// Firefox snippet; Slightly edited.
|
||||
async function sha256(message) {
|
||||
|
|
|
@ -12,67 +12,115 @@ export async function GetPublicTimeline(Local = false, Remote = false, Website)
|
|||
}
|
||||
|
||||
if (Local == true) {
|
||||
Timeline = await fetch(Website + "/api/v1/timelines/public?limit=12&local=true")
|
||||
Timeline = await fetch(Website + "/api/v1/timelines/public?local=true")
|
||||
.then((response) => response.json());
|
||||
} else if (Remote == true) {
|
||||
Timeline = await fetch(Website + "/api/v1/timelines/public?limit=12&remote=true")
|
||||
Timeline = await fetch(Website + "/api/v1/timelines/public?remote=true")
|
||||
.then((response) => response.json());
|
||||
} else {
|
||||
Timeline = await fetch(Website + "/api/v1/timelines/public?limit=12")
|
||||
Timeline = await fetch(Website + "/api/v1/timelines/public")
|
||||
.then((response) => response.json());
|
||||
}
|
||||
return Timeline;
|
||||
}
|
||||
|
||||
// Gets the favorites of a user that you have access to.
|
||||
export async function GetFavorites() {
|
||||
let Favorites;
|
||||
// Check for a token.
|
||||
if (localStorage.getItem(Variables.MastodonAccessToken) != null) {
|
||||
let Website = Variables.MastodonWebsite;
|
||||
// Get the varaibles that are stored in localStorage.
|
||||
Favorites = await fetch(Website + "/api/v1/favourites", {method: "GET", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}})
|
||||
// Get the personal timeline.
|
||||
export async function GetTimeline(Cursor) {
|
||||
if (localStorage.getItem(Variables.MastodonAccessToken) == null) {
|
||||
console.log("No access token!");
|
||||
return "";
|
||||
}
|
||||
let Website = localStorage.getItem(Variables.MastodonWebsite);
|
||||
// Get the varaibles that are stored in localStorage.
|
||||
if (Cursor == "") {
|
||||
return await fetch(Website + "/api/v1/timelines/home", {method: "GET", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}})
|
||||
.then((response) => response.json());
|
||||
} else {
|
||||
return await fetch(Website + "/api/v1/timelines/home?max_id=" + Cursor, {method: "GET", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}})
|
||||
.then((response) => response.json());
|
||||
}
|
||||
return Favorites;
|
||||
}
|
||||
|
||||
// Gets the favorites of a user that you have access to.
|
||||
export async function GetFavorites() {
|
||||
if (localStorage.getItem(Variables.MastodonAccessToken) == null) {
|
||||
console.log("No access token!");
|
||||
return "";
|
||||
}
|
||||
let Website = localStorage.getItem(Variables.MastodonWebsite);
|
||||
// Get the varaibles that are stored in localStorage.
|
||||
return await fetch(Website + "/api/v1/favourites", {method: "GET", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}})
|
||||
.then((response) => response.json());
|
||||
}
|
||||
|
||||
// Gets the bookmarks of a user that you have access to.
|
||||
export async function GetBookmarks() {
|
||||
let Bookmarks;
|
||||
// Check for a token.
|
||||
if (localStorage.getItem(Variables.MastodonAccessToken) != null) {
|
||||
let Website = localStorage.getItem(Variables.MastodonWebsite);
|
||||
// Get the varaibles that are stored in Variables.
|
||||
Bookmarks = await fetch(Website + "/api/v1/bookmarks", {method: "GET", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}})
|
||||
.then((response) => response.json());
|
||||
if (localStorage.getItem(Variables.MastodonAccessToken) == null) {
|
||||
console.log("No access token!");
|
||||
return "";
|
||||
}
|
||||
return Bookmarks;
|
||||
let Website = localStorage.getItem(Variables.MastodonWebsite);
|
||||
// Get the varaibles that are stored in Variables.
|
||||
return await fetch(Website + "/api/v1/bookmarks", {method: "GET", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}})
|
||||
.then((response) => response.json());
|
||||
}
|
||||
|
||||
// Gets the notifications of a user that you have access to.
|
||||
export async function GetNotifications() {
|
||||
let Notifications;
|
||||
// Check for a token.
|
||||
if (localStorage.getItem(Variables.MastodonAccessToken) != null) {
|
||||
let Website = localStorage.getItem(Variables.MastodonWebsite);
|
||||
// Get the varaibles that are stored in Variables and then input it.
|
||||
Notifications = await fetch(Website + "/api/v1/notifications", {method: "GET", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}})
|
||||
.then((response) => response.json());
|
||||
if (localStorage.getItem(Variables.MastodonAccessToken) == null) {
|
||||
console.log("No access token!");
|
||||
return "";
|
||||
}
|
||||
return Notifications;
|
||||
let Website = localStorage.getItem(Variables.MastodonWebsite);
|
||||
// Get the varaibles that are stored in Variables and then input it.
|
||||
return await fetch(Website + "/api/v1/notifications", {method: "GET", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}})
|
||||
.then((response) => response.json());
|
||||
}
|
||||
|
||||
// Make a status
|
||||
export async function CreateStatus(Text, Visibility = "public") {
|
||||
if (localStorage.getItem(Variables.MastodonAccessToken) == null) {
|
||||
console.log("No access token!");
|
||||
return "";
|
||||
}
|
||||
// Stolen from StackOverflow
|
||||
Text = Text.replace(/(?:\r|\n|\r\n)/g, '<br>');
|
||||
// Check for a token
|
||||
if (localStorage.getItem(Variables.MastodonAccessToken) != null) {
|
||||
let Website = localStorage.getItem(Variables.MastodonWebsite);
|
||||
return await fetch(Website + "/api/v1/statuses?status=" + Text + "&visibility=" + Visibility, {method: "POST", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}})
|
||||
.then((response) => response.json());
|
||||
let Website = localStorage.getItem(Variables.MastodonWebsite);
|
||||
let request = fetch(Website + "/api/v1/statuses?status=" + Text + "&visibility=" + Visibility, {method: "POST", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}});
|
||||
let body = await request.then((response) => response.json());
|
||||
let status = await request.then((response) => response.status);
|
||||
// This is in case you went over the characters.
|
||||
if (status == 422) {
|
||||
let matches = body.error.match(/(\d+)/);
|
||||
console.log(matches);
|
||||
request = fetch(Website + "/api/v1/statuses?status=" + Text.slice(0, matches[0] - 1) + "&visibility=" + Visibility, {method: "POST", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}});
|
||||
body = await request.then((response) => response.json());
|
||||
await CreateReplyStatus(Text.slice(matches[0] - 1, Text.length - 1), Visibility, body.id);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
export async function CreateReplyStatus(Text, Visibility = "public", ReplyID) {
|
||||
if (localStorage.getItem(Variables.MastodonAccessToken) == null) {
|
||||
console.log("No access token!");
|
||||
return "";
|
||||
}
|
||||
// Stolen from StackOverflow
|
||||
Text = Text.replace(/(?:\r|\n|\r\n)/g, '<br>');
|
||||
// Check for a token
|
||||
let Website = localStorage.getItem(Variables.MastodonWebsite);
|
||||
let request = fetch(Website + "/api/v1/statuses?status=" + Text + "&visibility=" + Visibility + "&in_reply_to_id=" + ReplyID, {method: "POST", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}});
|
||||
let body = await request.then((response) => response.json());
|
||||
let status = await request.then((response) => response.status);
|
||||
// This is in case you went over the characters.
|
||||
if (status == 422) {
|
||||
let matches = body.error.match(/(\d+)/);
|
||||
request = fetch(Website + "/api/v1/statuses?status=" + Text.slice(0, matches[0] - 1) + "&visibility=" + Visibility + "&in_reply_to_id=" + ReplyID, {method: "POST", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}});
|
||||
body = await request.then((response) => response.json());
|
||||
await CreateReplyStatus(Text.slice(matches[0] - 1, Text.length - 1), Visibility, body.id);
|
||||
}
|
||||
return body;
|
||||
}
|
||||
|
||||
// The first step to using the app.
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// STRINGS TODO: make sure to seperate stuff that a user will want to input: BlueskyPDSName.
|
||||
// Mastodon
|
||||
export const MastodonWebsite = "mastodon_website";
|
||||
export const MastodonClientID = "mastodon_client_id";
|
||||
|
|
5
JS/expanded.js
Normal file
5
JS/expanded.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
let content = decodeURI(document.location.href.split("content=")[1]);
|
||||
let username = decodeURI(document.location.href.split("username=")[1].split("&content")[0]);
|
||||
|
||||
document.getElementsByClassName("Handle")[0].innerHTML = username;
|
||||
document.getElementsByClassName("DetailedText")[0].innerHTML = content;
|
149
JS/index.js
149
JS/index.js
|
@ -8,6 +8,7 @@ import * as Variables from "./Variables.js";
|
|||
let Warning = document.getElementsByClassName("WarningMessage")[0];
|
||||
let Main = document.getElementsByClassName("MainBefore")[0];
|
||||
let ContainerContainer = document.getElementsByClassName("PostContainerContainer")[0];
|
||||
let ClickableContainers = ContainerContainer.getElementsByClassName("PostContainer")[2].children;
|
||||
|
||||
let BrowserWidth = window.innerWidth;
|
||||
let BrowserHeight = window.innerHeight;
|
||||
|
@ -81,12 +82,11 @@ ArrowsButton[1].onclick = (event) => {
|
|||
if (!ContainerContainer.classList.contains("NextAnimation")) {
|
||||
ContainerContainer.classList.add("NextAnimation");
|
||||
ButtonSound.play();
|
||||
console.log("loading next posts...");
|
||||
setTimeout(() => {
|
||||
ContainerContainer.classList.remove("NextAnimation");
|
||||
}, 1000);
|
||||
PosterContainerUpdate("Forward");
|
||||
}
|
||||
PosterContainerUpdate();
|
||||
}
|
||||
|
||||
// Clicking the back button
|
||||
|
@ -94,39 +94,140 @@ ArrowsButton[0].onclick = (event) => {
|
|||
if (!ContainerContainer.classList.contains("BackAnimation")) {
|
||||
ContainerContainer.classList.add("BackAnimation");
|
||||
ButtonSound.play();
|
||||
console.log("getting previous posts...");
|
||||
setTimeout(() => {
|
||||
ContainerContainer.classList.remove("BackAnimation");
|
||||
}, 1000);
|
||||
PosterContainerUpdate("Backward");
|
||||
}
|
||||
PosterContainerUpdate();
|
||||
}
|
||||
|
||||
// MastodonAPI integration
|
||||
async function PosterContainerUpdate() {
|
||||
// Variables for the public timelines
|
||||
let LocalVar = localStorage.getItem("Local");
|
||||
var LocalTrue = (LocalVar === "true");
|
||||
let RemoteVar = localStorage.getItem("Remote");
|
||||
var RemoteTrue = (RemoteVar === "true");
|
||||
for (let i of ClickableContainers) {
|
||||
i.onclick = (event) => {
|
||||
let content = i.getElementsByClassName("PostContent")[0].innerHTML
|
||||
let username = i.getElementsByClassName("Username")[0].innerHTML
|
||||
// Save some info
|
||||
window.location.href = "./HTML/expanded.html?username=" + username + "&content=" + content;
|
||||
}
|
||||
}
|
||||
|
||||
// These numbers are here so you don't go back.
|
||||
let MastodonLoadedFeed = [];
|
||||
let BlueskyLoadedFeed = [];
|
||||
let CurrentThing = 0;
|
||||
|
||||
// Call this to update the things :)
|
||||
async function PosterContainerUpdate(Direction) {
|
||||
let Lim = 6;
|
||||
let Website = localStorage.getItem(Variables.MastodonWebsite);
|
||||
|
||||
if (localStorage.getItem(Variables.MastodonWebsite) == null) {
|
||||
Website = "https://wetdry.world";
|
||||
}
|
||||
let Mastodon = true;
|
||||
|
||||
let Timeline = await MastodonAPI.GetPublicTimeline(LocalTrue, RemoteTrue, Website);
|
||||
let Content = [];
|
||||
let Users = [];
|
||||
for (let i in Timeline) {
|
||||
Content[i] = Timeline[i].content;
|
||||
Users[i] = Timeline[i].account.username;
|
||||
// Mastodon gaining of timeline.
|
||||
if (localStorage.getItem(Variables.MastodonWebsite) == null) {
|
||||
// The default website is Wetdry :3
|
||||
console.log("No Mastodon instance. multiplying mastodon posts by 2...");
|
||||
Lim = Lim * 2;
|
||||
Mastodon = false;
|
||||
} else if (MastodonLoadedFeed == 0) {
|
||||
MastodonLoadedFeed = await MastodonAPI.GetTimeline("");
|
||||
}
|
||||
let CenterContainer = document.getElementsByClassName("PostContainer")[2].children;
|
||||
for (let i in CenterContainer) {
|
||||
CenterContainer[i].getElementsByClassName("PostContent")[0].innerHTML = Content[i];
|
||||
CenterContainer[i].getElementsByClassName("Username")[0].innerHTML = Users[i];
|
||||
// Bluesky gaining of timeline.
|
||||
if (localStorage.getItem(Variables.BlueskyPDS) == null) {
|
||||
console.log("No Bluesky instance. multiplying mastodon posts by 2...");
|
||||
Lim = Lim * 2;
|
||||
} else if (BlueskyLoadedFeed.length == 0) {
|
||||
BlueskyLoadedFeed = await BlueskyAPI.GetTimeline("").then((response) => response.feed);
|
||||
}
|
||||
if (Direction == "Forward") {
|
||||
CurrentThing = CurrentThing + Lim;
|
||||
} else if (Direction == "Backward") {
|
||||
if (CurrentThing - Lim >= 0) {
|
||||
CurrentThing = CurrentThing - Lim;
|
||||
}
|
||||
}
|
||||
// Debugging
|
||||
console.log(MastodonLoadedFeed);
|
||||
console.log(BlueskyLoadedFeed);
|
||||
// The first one is for counting.
|
||||
// The countergroup increments to another timeline once posts hit the "limit".
|
||||
let counter = 0;
|
||||
let countergroup = 0;
|
||||
if (Mastodon == false) {
|
||||
countergroup = countergroup + 1;
|
||||
}
|
||||
// This var is meant to stop "already seen" posts.
|
||||
let BlueskyPostsDup = [];
|
||||
for (let i of ClickableContainers) {
|
||||
switch(countergroup) {
|
||||
// Mastodon
|
||||
case 0:
|
||||
if (MastodonLoadedFeed[CurrentThing + counter] == undefined) {
|
||||
let TempFeed = await MastodonAPI.GetTimeline(MastodonLoadedFeed[CurrentThing + counter - 1].id);
|
||||
MastodonLoadedFeed = MastodonLoadedFeed.concat(TempFeed);
|
||||
}
|
||||
// Content warning. Don't show the content unless clicked!!!
|
||||
if (MastodonLoadedFeed[CurrentThing + counter].spoiler_text != "") {
|
||||
i.getElementsByClassName("PostContent")[0].innerHTML = "<b>WARNING: " + MastodonLoadedFeed[CurrentThing + counter].spoiler_text + "</b>";
|
||||
i.getElementsByClassName("Username")[0].innerHTML = MastodonLoadedFeed[CurrentThing + counter].account.username;
|
||||
break;
|
||||
}
|
||||
// Check for a reblog.
|
||||
if (MastodonLoadedFeed[CurrentThing + counter].reblog != null) {
|
||||
i.getElementsByClassName("PostContent")[0].innerHTML = MastodonLoadedFeed[CurrentThing + counter].reblog.content;
|
||||
i.getElementsByClassName("Username")[0].innerHTML = MastodonLoadedFeed[CurrentThing + counter].reblog.account.username + " ( R: " + MastodonLoadedFeed[CurrentThing + counter].account.username + " )";
|
||||
} else {
|
||||
i.getElementsByClassName("PostContent")[0].innerHTML = MastodonLoadedFeed[CurrentThing + counter].content;
|
||||
i.getElementsByClassName("Username")[0].innerHTML = MastodonLoadedFeed[CurrentThing + counter].account.username;
|
||||
}
|
||||
break;
|
||||
// Bsky
|
||||
case 1:
|
||||
if (BlueskyLoadedFeed[CurrentThing + counter] == undefined) {
|
||||
let TempFeed = await BlueskyAPI.GetTimeline(BlueskyLoadedFeed[CurrentThing + counter - 1].post.indexedAt).then((response) => response.feed)
|
||||
BlueskyLoadedFeed = BlueskyLoadedFeed.concat(TempFeed);
|
||||
}
|
||||
// check for "already seen" posts, then put it as a seen post.
|
||||
BlueskyLoadedFeed = CheckForDups(BlueskyLoadedFeed, BlueskyPostsDup, counter);
|
||||
BlueskyPostsDup.push(BlueskyLoadedFeed[counter].post.uri);
|
||||
// Labels
|
||||
if (BlueskyLoadedFeed[CurrentThing + counter].post.labels.length != 0) {
|
||||
i.getElementsByClassName("PostContent")[0].innerHTML = "<b>LABELS APPLIED: ";
|
||||
i.getElementsByClassName("Username")[0].innerHTML = BlueskyLoadedFeed[CurrentThing + counter].post.author.handle;
|
||||
for (let lab of BlueskyLoadedFeed[CurrentThing + counter].post.labels) {
|
||||
i.getElementsByClassName("PostContent")[0].innerHTML = i.getElementsByClassName("PostContent")[0].innerHTML + lab.val + " ";
|
||||
}
|
||||
i.getElementsByClassName("PostContent")[0].innerHTML = i.getElementsByClassName("PostContent")[0].innerHTML + "</b>";
|
||||
break;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
// Direction for where you go :3
|
||||
break;
|
||||
}
|
||||
counter = counter + 1;
|
||||
if (counter >= Lim) {
|
||||
counter = 0;
|
||||
countergroup = countergroup + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assistant function to help with checking for duplicates.
|
||||
function CheckForDups(Timeline, DupeArray, counter) {
|
||||
for (let j of DupeArray) {
|
||||
if (j == Timeline[counter].post.uri) {
|
||||
Timeline.splice(counter, 1);
|
||||
console.log("Culled a duplicate post.")
|
||||
Timeline = CheckForDups(Timeline, DupeArray, counter);
|
||||
}
|
||||
}
|
||||
return Timeline;
|
||||
}
|
||||
|
||||
// Open the settings
|
||||
|
|
|
@ -8,6 +8,9 @@ let PostButton = document.getElementsByClassName("Button")[0];
|
|||
let VisibilityDropdown = document.getElementsByClassName("PostVisibility")[0];
|
||||
let InputArea = document.getElementsByClassName("Text")[0];
|
||||
|
||||
// Extra Variables
|
||||
|
||||
|
||||
// Clicking the beeg POST button.
|
||||
PostButton.onclick = (event) => {
|
||||
Post();
|
||||
|
@ -57,9 +60,7 @@ async function Post() {
|
|||
break;
|
||||
}
|
||||
let Post = await BlueskyAPI.CreatePost(localStorage.getItem(Variables.BlueskyDID), Text);
|
||||
console.log(Post);
|
||||
let ThreadGate = await BlueskyAPI.SetThreadGate(localStorage.getItem(Variables.BlueskyDID), Post.uri, TempVisible);
|
||||
console.log(ThreadGate);
|
||||
}
|
||||
InputArea.value = "";
|
||||
}
|
||||
|
|
195
index.html
195
index.html
|
@ -9,6 +9,8 @@
|
|||
This is the only way I knew how to make a "non-module" inherit a module.
|
||||
I think this is why people use typescript or other frameworks. -->
|
||||
<script type="module" src="./JS/index.js"></script>
|
||||
<!-- Dependenci -->
|
||||
<script language="JavaScript" type="text/javascript" src="https://kjur.github.io/jsrsasign/jsrsasign-latest-all-min.js"></script>
|
||||
</head>
|
||||
|
||||
<body style="margin: 0px;">
|
||||
|
@ -31,255 +33,256 @@
|
|||
<div style="width: 100%" class="PostContainerContainer">
|
||||
<div style="left: -170vw;" class="PostContainer Back">
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<div style="left: -85vw;" class="PostContainer Back">
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<!-- This is the container that houses the current viewing stuff -->
|
||||
<div class="PostContainer">
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<div style="left: 85vw;" class="PostContainer Next">
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">Testing</p>
|
||||
<p class="PostContent">The things</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
</div>
|
||||
|
||||
<div style="left: 170vw;" class="PostContainer Next">
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
<article class="Post">
|
||||
<p class="Username">No</p>
|
||||
<p class="Username"></p>
|
||||
<p class="PostContent"></p>
|
||||
</article>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue