Merge pull request #43 from ItsVipra/glitch-soc-types

Better fetching for glitch-soc notifications
This commit is contained in:
Vivien 2023-07-14 18:47:44 +02:00 committed by GitHub
commit 36f8f1e4c2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 52 additions and 15 deletions

View file

@ -19,7 +19,12 @@ import {
waitForElement, waitForElement,
waitForElementRemoved, waitForElementRemoved,
} from "../libs/domhelpers"; } from "../libs/domhelpers";
import { addTypeAttribute, normaliseAccountName, sanitizePronouns } from "../libs/protootshelpers"; import {
accountNameFromURL,
addTypeAttribute,
normaliseAccountName,
sanitizePronouns,
} from "../libs/protootshelpers";
//before anything else, check whether we're on a Mastodon page //before anything else, check whether we're on a Mastodon page
checkSite(); checkSite();
@ -81,6 +86,7 @@ function main() {
"conversation", "conversation",
"account-authorize", "account-authorize",
"notification", "notification",
"notification__message",
"account", "account",
)) ))
); );
@ -115,6 +121,11 @@ function onTootIntersection(observerentries) {
waitForElement(ArticleElement, ".conversation__content__names", () => waitForElement(ArticleElement, ".conversation__content__names", () =>
addProplate(ArticleElement), addProplate(ArticleElement),
); );
} else if (ArticleElement.nodeName == "ASIDE") {
//glitch-soc notifications
waitForElement(ArticleElement, ".status__display-name", () => {
addProplate(ArticleElement);
});
} else { } else {
waitForElement(ArticleElement, ".display-name", () => addProplate(ArticleElement)); waitForElement(ArticleElement, ".display-name", () => addProplate(ArticleElement));
} }
@ -215,13 +226,15 @@ async function addProplate(element) {
* @returns {string} * @returns {string}
*/ */
function getID(element) { function getID(element) {
const id = element.dataset.id; let id = element.dataset.id;
if (!id) { if (!id) {
// We don't have a status ID, pronouns might not be in cache // We don't have a status ID, pronouns might not be in cache
warn( warn(
"The element passed to addProplate does not have a data-id attribute, although it should have one.", "The element passed to addProplate does not have a data-id attribute, searching for article.",
element, element,
); );
//if we couldn't get an id from the div try the closest article
id = element.closest("article[data-id]")?.dataset.id;
} }
return id; return id;
} }
@ -236,7 +249,7 @@ async function addProplate(element) {
const accountNameEl = /** @type {HTMLElement|null} */ (element.querySelector(accountNameClass)); const accountNameEl = /** @type {HTMLElement|null} */ (element.querySelector(accountNameClass));
if (!accountNameEl) { if (!accountNameEl) {
warn( warn(
"The element passed to addProplate does not have a .display-name__account, although it should have one.", `The element passed to addProplate does not have a ${accountNameClass}, although it should have one.`,
element, element,
); );
} }
@ -283,11 +296,7 @@ async function addProplate(element) {
async function addToStatus(element) { async function addToStatus(element) {
let statusId = getID(element); let statusId = getID(element);
if (!statusId) { if (!statusId) {
//if we couldn't get an id from the div try the closest article if (type === "detailed-status") {
const ArticleElement = element.closest("article");
if (ArticleElement) {
statusId = getID(ArticleElement);
} else if (type === "detailed-status") {
//if we still don't have an ID try the domain as a last resort //if we still don't have an ID try the domain as a last resort
warn("Attempting to retrieve id from url - this may have unforseen consequences."); warn("Attempting to retrieve id from url - this may have unforseen consequences.");
statusId = location.pathname.split("/").pop(); statusId = location.pathname.split("/").pop();
@ -310,18 +319,23 @@ async function addProplate(element) {
} }
async function addToNotification(element) { async function addToNotification(element) {
//debug("adding to notification");
const statusId = getID(element); const statusId = getID(element);
const accountNameEl = getAccountNameEl(element, ".notification__display-name"); let accountNameEl = getAccountNameEl(element, ".notification__display-name");
const accountName = getAccountName(accountNameEl, "title"); if (!accountNameEl) accountNameEl = getAccountNameEl(element, ".status__display-name");
const nametagEl = getNametagEl(element, ".notification__display-name"); let accountName = getAccountName(accountNameEl, "title");
if (!accountName) accountName = accountNameFromURL(getAccountName(accountNameEl, "href"));
let nametagEl = accountNameEl;
element.setAttribute("protoots-checked", "true"); element.setAttribute("protoots-checked", "true");
generateProPlate(statusId, accountName, nametagEl, "notification"); generateProPlate(statusId, accountName, nametagEl, "notification");
} }
async function addToAccount(element) { async function addToAccount(element) {
//debug("adding to account");
const statusId = getID(element); const statusId = getID(element);
const nametagEl = element.querySelector(".display-name__html"); const nametagEl = element.querySelector(".display-name__html");
const accountName = getAccountName(element.querySelector(".display-name__account")); const accountName = getAccountName(element.querySelector(".display-name__account"));
@ -329,6 +343,7 @@ async function addProplate(element) {
nametagEl.parentElement.style.display = "flex"; nametagEl.parentElement.style.display = "flex";
element.setAttribute("protoots-checked", "true"); element.setAttribute("protoots-checked", "true");
generateProPlate(statusId, accountName, nametagEl, "account"); generateProPlate(statusId, accountName, nametagEl, "account");
} }

View file

@ -1,4 +1,4 @@
import { debug, error, info, warn } from "./logging"; import { debug, error, info, log, warn } from "./logging";
import { cachePronouns, getPronouns } from "./caching"; import { cachePronouns, getPronouns } from "./caching";
import { normaliseAccountName } from "./protootshelpers"; import { normaliseAccountName } from "./protootshelpers";
@ -60,6 +60,9 @@ export async function fetchPronouns(dataID, accountName, type) {
status = await fetchStatus(dataID); status = await fetchStatus(dataID);
} }
log(`Fetching ${type} failed, trying notification instead.`);
if (!status) status = await fetchNotification(dataID); //fallback for glitch-soc notifications
const PronounField = getPronounField(status, accountName); const PronounField = getPronounField(status, accountName);
if (PronounField == "null") { if (PronounField == "null") {
//TODO: if no field check bio //TODO: if no field check bio
@ -84,6 +87,8 @@ async function fetchStatus(statusID) {
}, },
); );
if (!response.ok) return null;
let status = await response.json(); let status = await response.json();
//if status contains a reblog get that for further processing - we want the embedded post's author //if status contains a reblog get that for further processing - we want the embedded post's author
@ -128,6 +133,8 @@ async function fetchAccount(accountID) {
}, },
); );
if (!response.ok) return null;
const account = await response.json(); const account = await response.json();
return { account: account }; return { account: account };

View file

@ -17,6 +17,21 @@ export function normaliseAccountName(name) {
return name; return name;
} }
/**
* Turns a link to an account on a remote instance into a username.
*
* e.g. `https://example.com/@test` -> `@test@example.com`
* @param {string} url URL to an account on their own instance
* @returns {string} username (not normalised)
*/
export function accountNameFromURL(url) {
const splitURL = url.split("/");
const username = [splitURL.pop(), splitURL.pop()].join("@");
return username;
}
/** /**
* Sanitizes the pronoun field by removing various long information parts. * Sanitizes the pronoun field by removing various long information parts.
* As of today, this just removes custom emojis from the field. * As of today, this just removes custom emojis from the field.
@ -40,7 +55,7 @@ export function sanitizePronouns(str) {
* @param {HTMLElement} ActionElement * @param {HTMLElement} ActionElement
*/ */
export function addTypeAttribute(ActionElement) { export function addTypeAttribute(ActionElement) {
if (hasClasses(ActionElement, "status")) { if (hasClasses(ActionElement, "status") && !hasClasses(ActionElement, "notification__message")) {
ActionElement.setAttribute("protoots-type", "status"); ActionElement.setAttribute("protoots-type", "status");
} else if (hasClasses(ActionElement, "detailed-status")) { } else if (hasClasses(ActionElement, "detailed-status")) {
ActionElement.setAttribute("protoots-type", "detailed-status"); ActionElement.setAttribute("protoots-type", "detailed-status");
@ -50,7 +65,7 @@ export function addTypeAttribute(ActionElement) {
} else if (hasClasses(ActionElement, "account-authorize")) { } else if (hasClasses(ActionElement, "account-authorize")) {
ActionElement.setAttribute("protoots-type", "account-authorize"); ActionElement.setAttribute("protoots-type", "account-authorize");
ActionElement.closest("article").setAttribute("protoots-type", "account-authorize"); ActionElement.closest("article").setAttribute("protoots-type", "account-authorize");
} else if (hasClasses(ActionElement, "notification")) { } else if (hasClasses(ActionElement, "notification", "notification__message")) {
ActionElement.setAttribute("protoots-type", "notification"); ActionElement.setAttribute("protoots-type", "notification");
ActionElement.closest("article").setAttribute("protoots-type", "notification"); ActionElement.closest("article").setAttribute("protoots-type", "notification");
} else if (hasClasses(ActionElement, "account")) { } else if (hasClasses(ActionElement, "account")) {