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
|
@ -179,6 +179,8 @@ html {
|
||||||
}
|
}
|
||||||
|
|
||||||
.Post {
|
.Post {
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 2px;
|
border-width: 2px;
|
||||||
|
|
||||||
|
@ -186,6 +188,10 @@ html {
|
||||||
height: 25%;
|
height: 25%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.Post:hover {
|
||||||
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
.Username {
|
.Username {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-weight: bold;
|
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";
|
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) {
|
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 PDS = localStorage.getItem(Variables.BlueskyPDS);
|
||||||
let Json = {
|
let Json = {
|
||||||
"$type": "app.bsky.feed.post",
|
"$type": "app.bsky.feed.post",
|
||||||
|
@ -18,18 +49,77 @@ export async function CreatePost(DID, Text) {
|
||||||
let status = await request.then((response) => response.status);
|
let status = await request.then((response) => response.status);
|
||||||
let header = await request.then((response) => response.headers.get("dpop-nonce"));
|
let header = await request.then((response) => response.headers.get("dpop-nonce"));
|
||||||
if (status == 401) {
|
if (status == 401) {
|
||||||
if (body.message.includes("DPoP nonce mismatch")) {
|
await HandleError(body, header);
|
||||||
await localStorage.setItem(Variables.BlueskyNonce, header);
|
|
||||||
}
|
|
||||||
if (body.message.includes("claim timestamp check failed")) {
|
|
||||||
await RefreshTokens();
|
|
||||||
}
|
|
||||||
body = await CreatePost(DID, Text);
|
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;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function SetThreadGate(DID, Post, VisibilitySettings) {
|
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 PDS = localStorage.getItem(Variables.BlueskyPDS);
|
||||||
let Json = {
|
let Json = {
|
||||||
"$type": "app.bsky.feed.threadgate",
|
"$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 status = await request.then((response) => response.status);
|
||||||
let header = await request.then((response) => response.headers.get("dpop-nonce"));
|
let header = await request.then((response) => response.headers.get("dpop-nonce"));
|
||||||
if (status == 401) {
|
if (status == 401) {
|
||||||
if (body.message.includes("DPoP nonce mismatch")) {
|
await HandleError(body, header);
|
||||||
await localStorage.setItem(Variables.BlueskyNonce, header);
|
|
||||||
}
|
|
||||||
if (body.message.includes("claim timestamp check failed")) {
|
|
||||||
await RefreshTokens();
|
|
||||||
}
|
|
||||||
body = await SetThreadGate(DID, Post, VisibilitySettings);
|
body = await SetThreadGate(DID, Post, VisibilitySettings);
|
||||||
}
|
}
|
||||||
return body;
|
return body;
|
||||||
|
@ -251,6 +336,15 @@ export async function RefreshTokens() {
|
||||||
localStorage.setItem(Variables.BlueskyRefreshToken, body.refresh_token);
|
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.
|
// Stolen from elsewhere.
|
||||||
// Firefox snippet; Slightly edited.
|
// Firefox snippet; Slightly edited.
|
||||||
async function sha256(message) {
|
async function sha256(message) {
|
||||||
|
|
|
@ -12,67 +12,115 @@ export async function GetPublicTimeline(Local = false, Remote = false, Website)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Local == true) {
|
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());
|
.then((response) => response.json());
|
||||||
} else if (Remote == true) {
|
} 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());
|
.then((response) => response.json());
|
||||||
} else {
|
} else {
|
||||||
Timeline = await fetch(Website + "/api/v1/timelines/public?limit=12")
|
Timeline = await fetch(Website + "/api/v1/timelines/public")
|
||||||
.then((response) => response.json());
|
.then((response) => response.json());
|
||||||
}
|
}
|
||||||
return Timeline;
|
return Timeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Gets the favorites of a user that you have access to.
|
// Get the personal timeline.
|
||||||
export async function GetFavorites() {
|
export async function GetTimeline(Cursor) {
|
||||||
let Favorites;
|
if (localStorage.getItem(Variables.MastodonAccessToken) == null) {
|
||||||
// Check for a token.
|
console.log("No access token!");
|
||||||
if (localStorage.getItem(Variables.MastodonAccessToken) != null) {
|
return "";
|
||||||
let Website = Variables.MastodonWebsite;
|
}
|
||||||
// Get the varaibles that are stored in localStorage.
|
let Website = localStorage.getItem(Variables.MastodonWebsite);
|
||||||
Favorites = await fetch(Website + "/api/v1/favourites", {method: "GET", headers: {"Authorization": localStorage.getItem(Variables.MastodonTokenType) + " " + localStorage.getItem(Variables.MastodonAccessToken)}})
|
// 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());
|
.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.
|
// Gets the bookmarks of a user that you have access to.
|
||||||
export async function GetBookmarks() {
|
export async function GetBookmarks() {
|
||||||
let Bookmarks;
|
if (localStorage.getItem(Variables.MastodonAccessToken) == null) {
|
||||||
// Check for a token.
|
console.log("No access token!");
|
||||||
if (localStorage.getItem(Variables.MastodonAccessToken) != null) {
|
return "";
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
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.
|
// Gets the notifications of a user that you have access to.
|
||||||
export async function GetNotifications() {
|
export async function GetNotifications() {
|
||||||
let Notifications;
|
if (localStorage.getItem(Variables.MastodonAccessToken) == null) {
|
||||||
// Check for a token.
|
console.log("No access token!");
|
||||||
if (localStorage.getItem(Variables.MastodonAccessToken) != null) {
|
return "";
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
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
|
// Make a status
|
||||||
export async function CreateStatus(Text, Visibility = "public") {
|
export async function CreateStatus(Text, Visibility = "public") {
|
||||||
|
if (localStorage.getItem(Variables.MastodonAccessToken) == null) {
|
||||||
|
console.log("No access token!");
|
||||||
|
return "";
|
||||||
|
}
|
||||||
// Stolen from StackOverflow
|
// Stolen from StackOverflow
|
||||||
Text = Text.replace(/(?:\r|\n|\r\n)/g, '<br>');
|
Text = Text.replace(/(?:\r|\n|\r\n)/g, '<br>');
|
||||||
// Check for a token
|
// Check for a token
|
||||||
if (localStorage.getItem(Variables.MastodonAccessToken) != null) {
|
let Website = localStorage.getItem(Variables.MastodonWebsite);
|
||||||
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)}});
|
||||||
return await 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());
|
||||||
.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.
|
// 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
|
// Mastodon
|
||||||
export const MastodonWebsite = "mastodon_website";
|
export const MastodonWebsite = "mastodon_website";
|
||||||
export const MastodonClientID = "mastodon_client_id";
|
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 Warning = document.getElementsByClassName("WarningMessage")[0];
|
||||||
let Main = document.getElementsByClassName("MainBefore")[0];
|
let Main = document.getElementsByClassName("MainBefore")[0];
|
||||||
let ContainerContainer = document.getElementsByClassName("PostContainerContainer")[0];
|
let ContainerContainer = document.getElementsByClassName("PostContainerContainer")[0];
|
||||||
|
let ClickableContainers = ContainerContainer.getElementsByClassName("PostContainer")[2].children;
|
||||||
|
|
||||||
let BrowserWidth = window.innerWidth;
|
let BrowserWidth = window.innerWidth;
|
||||||
let BrowserHeight = window.innerHeight;
|
let BrowserHeight = window.innerHeight;
|
||||||
|
@ -81,12 +82,11 @@ ArrowsButton[1].onclick = (event) => {
|
||||||
if (!ContainerContainer.classList.contains("NextAnimation")) {
|
if (!ContainerContainer.classList.contains("NextAnimation")) {
|
||||||
ContainerContainer.classList.add("NextAnimation");
|
ContainerContainer.classList.add("NextAnimation");
|
||||||
ButtonSound.play();
|
ButtonSound.play();
|
||||||
console.log("loading next posts...");
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
ContainerContainer.classList.remove("NextAnimation");
|
ContainerContainer.classList.remove("NextAnimation");
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
PosterContainerUpdate("Forward");
|
||||||
}
|
}
|
||||||
PosterContainerUpdate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clicking the back button
|
// Clicking the back button
|
||||||
|
@ -94,39 +94,140 @@ ArrowsButton[0].onclick = (event) => {
|
||||||
if (!ContainerContainer.classList.contains("BackAnimation")) {
|
if (!ContainerContainer.classList.contains("BackAnimation")) {
|
||||||
ContainerContainer.classList.add("BackAnimation");
|
ContainerContainer.classList.add("BackAnimation");
|
||||||
ButtonSound.play();
|
ButtonSound.play();
|
||||||
console.log("getting previous posts...");
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
ContainerContainer.classList.remove("BackAnimation");
|
ContainerContainer.classList.remove("BackAnimation");
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
PosterContainerUpdate("Backward");
|
||||||
}
|
}
|
||||||
PosterContainerUpdate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MastodonAPI integration
|
for (let i of ClickableContainers) {
|
||||||
async function PosterContainerUpdate() {
|
i.onclick = (event) => {
|
||||||
// Variables for the public timelines
|
let content = i.getElementsByClassName("PostContent")[0].innerHTML
|
||||||
let LocalVar = localStorage.getItem("Local");
|
let username = i.getElementsByClassName("Username")[0].innerHTML
|
||||||
var LocalTrue = (LocalVar === "true");
|
// Save some info
|
||||||
let RemoteVar = localStorage.getItem("Remote");
|
window.location.href = "./HTML/expanded.html?username=" + username + "&content=" + content;
|
||||||
var RemoteTrue = (RemoteVar === "true");
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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);
|
let Website = localStorage.getItem(Variables.MastodonWebsite);
|
||||||
|
|
||||||
if (localStorage.getItem(Variables.MastodonWebsite) == null) {
|
let Mastodon = true;
|
||||||
Website = "https://wetdry.world";
|
|
||||||
}
|
|
||||||
|
|
||||||
let Timeline = await MastodonAPI.GetPublicTimeline(LocalTrue, RemoteTrue, Website);
|
// Mastodon gaining of timeline.
|
||||||
let Content = [];
|
if (localStorage.getItem(Variables.MastodonWebsite) == null) {
|
||||||
let Users = [];
|
// The default website is Wetdry :3
|
||||||
for (let i in Timeline) {
|
console.log("No Mastodon instance. multiplying mastodon posts by 2...");
|
||||||
Content[i] = Timeline[i].content;
|
Lim = Lim * 2;
|
||||||
Users[i] = Timeline[i].account.username;
|
Mastodon = false;
|
||||||
|
} else if (MastodonLoadedFeed == 0) {
|
||||||
|
MastodonLoadedFeed = await MastodonAPI.GetTimeline("");
|
||||||
}
|
}
|
||||||
let CenterContainer = document.getElementsByClassName("PostContainer")[2].children;
|
// Bluesky gaining of timeline.
|
||||||
for (let i in CenterContainer) {
|
if (localStorage.getItem(Variables.BlueskyPDS) == null) {
|
||||||
CenterContainer[i].getElementsByClassName("PostContent")[0].innerHTML = Content[i];
|
console.log("No Bluesky instance. multiplying mastodon posts by 2...");
|
||||||
CenterContainer[i].getElementsByClassName("Username")[0].innerHTML = Users[i];
|
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
|
// Open the settings
|
||||||
|
|
|
@ -8,6 +8,9 @@ let PostButton = document.getElementsByClassName("Button")[0];
|
||||||
let VisibilityDropdown = document.getElementsByClassName("PostVisibility")[0];
|
let VisibilityDropdown = document.getElementsByClassName("PostVisibility")[0];
|
||||||
let InputArea = document.getElementsByClassName("Text")[0];
|
let InputArea = document.getElementsByClassName("Text")[0];
|
||||||
|
|
||||||
|
// Extra Variables
|
||||||
|
|
||||||
|
|
||||||
// Clicking the beeg POST button.
|
// Clicking the beeg POST button.
|
||||||
PostButton.onclick = (event) => {
|
PostButton.onclick = (event) => {
|
||||||
Post();
|
Post();
|
||||||
|
@ -57,9 +60,7 @@ async function Post() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let Post = await BlueskyAPI.CreatePost(localStorage.getItem(Variables.BlueskyDID), Text);
|
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);
|
let ThreadGate = await BlueskyAPI.SetThreadGate(localStorage.getItem(Variables.BlueskyDID), Post.uri, TempVisible);
|
||||||
console.log(ThreadGate);
|
|
||||||
}
|
}
|
||||||
InputArea.value = "";
|
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.
|
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. -->
|
I think this is why people use typescript or other frameworks. -->
|
||||||
<script type="module" src="./JS/index.js"></script>
|
<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>
|
</head>
|
||||||
|
|
||||||
<body style="margin: 0px;">
|
<body style="margin: 0px;">
|
||||||
|
@ -31,255 +33,256 @@
|
||||||
<div style="width: 100%" class="PostContainerContainer">
|
<div style="width: 100%" class="PostContainerContainer">
|
||||||
<div style="left: -170vw;" class="PostContainer Back">
|
<div style="left: -170vw;" class="PostContainer Back">
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="left: -85vw;" class="PostContainer Back">
|
<div style="left: -85vw;" class="PostContainer Back">
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- This is the container that houses the current viewing stuff -->
|
||||||
<div class="PostContainer">
|
<div class="PostContainer">
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="left: 85vw;" class="PostContainer Next">
|
<div style="left: 85vw;" class="PostContainer Next">
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">Testing</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent">The things</p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="left: 170vw;" class="PostContainer Next">
|
<div style="left: 170vw;" class="PostContainer Next">
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
<article class="Post">
|
<article class="Post">
|
||||||
<p class="Username">No</p>
|
<p class="Username"></p>
|
||||||
<p class="PostContent"></p>
|
<p class="PostContent"></p>
|
||||||
</article>
|
</article>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Add table
Reference in a new issue