diff --git a/HTML/post.html b/HTML/post.html index 3ab1a55..44a3b83 100644 --- a/HTML/post.html +++ b/HTML/post.html @@ -13,9 +13,17 @@

Post

- -

POST!

+ +
+ +
+

POST!

Back

diff --git a/HTML/setting.html b/HTML/setting.html index e3ff4a9..89adb00 100644 --- a/HTML/setting.html +++ b/HTML/setting.html @@ -17,10 +17,10 @@

Toggle Local

Toggle Remote

Login to Mastodon

- +

Login to Bluesky

- +

Back

diff --git a/JS/BlueskyAPI.js b/JS/BlueskyAPI.js index 3e6e367..d47835a 100644 --- a/JS/BlueskyAPI.js +++ b/JS/BlueskyAPI.js @@ -2,7 +2,7 @@ import * as Variables from "./Variables.js"; export async function GetBlueskyDID(PDS, Handle) { let DPoP = await ClientDPoPPDS("GET", PDS + "/xrpc/com.atproto.identity.resolveHandle?handle=" + Handle); - let request = fetch(PDS + "/xrpc/com.atproto.identity.resolveHandle?handle=" + Handle, { method: "GET", headers: {"Authorization": "DPoP " + localStorage.getItem(Veriables.BlueskyAccessToken), "DPoP": DPoP}}); + let request = fetch(PDS + "/xrpc/com.atproto.identity.resolveHandle?handle=" + Handle, { 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")); @@ -46,6 +46,37 @@ export async function CreatePost(PDS, DID, Text) { return body; } +export async function SetThreadGate(PDS, DID, Post, VisibilitySettings) { + + let Json = { + "$type": "app.bsky.feed.threadgate", + "post": Post, + "allow": VisibilitySettings, + "createdAt": new Date(Date.now()).toISOString() + } + let RequestBody = { + "repo": DID, + "collection": "app.bsky.feed.threadgate", + "record": Json, + "rkey": Post.split("/")[Post.split("/").length - 1] + } + 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) { + if (body.message.includes("DPoP nonce mismatch")) { + await localStorage.setItem(Variables.BlueskyNonce, header); + } + if (body.message.includes("claim timestamp check failed")) { + await RefreshTokens(); + } + body = await SetThreadGate(PDS, DID, Post, RKey, VisibilitySettings); + } + return body; +} + // Component 1/4 export async function GetPDSWellKnown() { return await fetch("https://bsky.social/.well-known/oauth-authorization-server", {method: "GET"}) @@ -194,7 +225,7 @@ export async function GainTokens() { let WellKnown = await GetPDSWellKnown(); // Check to see if something's a miss... - if ((document.location.href.split("state=").length > 1 && document.location.href.split("iss=").length > 1 && document.location.href.split("code=").length > 1) && localStorage.getItem(Variables.BlueskyPKCEVerifier) != null && localStorage.getItem(Variables.BlueskyAccessToken == null)) { + if ((document.location.href.split("state=").length > 1 && document.location.href.split("iss=").length > 1 && document.location.href.split("code=").length > 1) && localStorage.getItem(Variables.BlueskyPKCEVerifier) != null && localStorage.getItem(Variables.BlueskyAccessToken) == null) { // Create varaibles, be aware of waits because of internet. let DPoP = await ClientDPoPToken("POST", WellKnown.token_endpoint); let code = document.location.href.split("code=")[1]; diff --git a/JS/MastodonAPI.js b/JS/MastodonAPI.js index 49dcfeb..554ef6c 100644 --- a/JS/MastodonAPI.js +++ b/JS/MastodonAPI.js @@ -64,11 +64,11 @@ export async function GetNotifications() { } // Make a status -export async function CreateStatus(Text) { +export async function CreateStatus(Text, Visibility = "public") { // 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 , {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)}}) .then((response) => response.json()); } } diff --git a/JS/post.js b/JS/post.js index c655e2d..d8e0c8f 100644 --- a/JS/post.js +++ b/JS/post.js @@ -4,8 +4,9 @@ import * as TumblrAPI from "./TumblrAPI.js"; import * as Variables from "./Variables.js"; // Elements. -let PostButton = document.getElementsByClassName("button")[0]; -let InputArea = document.getElementsByClassName("text")[0]; +let PostButton = document.getElementsByClassName("Button")[0]; +let VisibilityDropdown = document.getElementsByClassName("PostVisibility")[0]; +let InputArea = document.getElementsByClassName("Text")[0]; // Clicking the beeg POST button. PostButton.onclick = (event) => { @@ -14,14 +15,48 @@ PostButton.onclick = (event) => { async function Post() { let Text = InputArea.value; + let Visible = VisibilityDropdown.value; // Mastodon posting. if (localStorage.getItem(Variables.MastodonAccessToken) != null) { - MastodonAPI.CreateStatus(Text); + let TempVisible; + switch(Visible) { + case "Public": + TempVisible = "public"; + break; + case "Quiet": + TempVisible = "unlisted"; + break; + case "Friend": + TempVisible = "private"; + break; + case "Private": + TempVisible = "direct"; + break; + } + MastodonAPI.CreateStatus(Text, TempVisible); } // Bluesky posting. if (localStorage.getItem(Variables.BlueskyAccessToken) != null) { + let TempVisible; + switch(Visible) { + case "Public": + TempVisible = undefined; + break; + case "Quiet": + TempVisible = undefined; + break; + case "Friend": + TempVisible = [{"$type": "app.bsky.feed.threadgate#followingRule"}, {"$type": "app.bsky.feed.threadgate#followerRule"}]; + break; + case "Private": + TempVisible = []; + break; + } let DID = await BlueskyAPI.GetBlueskyDID("https://woodear.us-west.host.bsky.network", "crowdedgames.group"); - BlueskyAPI.CreatePost("https://woodear.us-west.host.bsky.network", DID.did, Text); + let Post = await BlueskyAPI.CreatePost("https://woodear.us-west.host.bsky.network", DID.did, Text); + console.log(Post); + let ThreadGate = await BlueskyAPI.SetThreadGate("https://woodear.us-west.host.bsky.network", DID.did, Post.uri, TempVisible); + console.log(ThreadGate); } InputArea.value = ""; } diff --git a/JS/setting.js b/JS/setting.js index cd92676..b24ebde 100644 --- a/JS/setting.js +++ b/JS/setting.js @@ -29,7 +29,7 @@ LocalButton.onclick = (event) => { RemoteButton.onclick = (event) => { // Toggle the Variable - if (localStorage.getItem("Romote") != null) { + if (localStorage.getItem("Remote") != null) { localStorage.removeItem("Remote"); } else { localStorage.setItem("Remote", "true"); @@ -51,6 +51,7 @@ MastodonLogoutButton.onclick = (event) => { localStorage.removeItem(Variables.MastodonClientSecret); localStorage.removeItem(Variables.MastodonAccessToken); localStorage.removeItem(Variables.MastodonTokenType); + localStorage.removeItem(Variables.MastodonWebsite); document.location.href = Origin; }