Add loading indicator and improve non-clipboard interactions
This commit is contained in:
parent
66f6f52773
commit
aa5759d6f5
4 changed files with 73 additions and 20 deletions
|
|
@ -1,7 +1,15 @@
|
|||
---
|
||||
import { readFile } from "node:fs/promises";
|
||||
import BaseLayout from "@layouts/BaseLayout.astro";
|
||||
import { IconEnvelope, IconBriefcase, IconKey, IconLink, IconCommentDots, IconSSH } from "@components/icons";
|
||||
import {
|
||||
IconEnvelope,
|
||||
IconBriefcase,
|
||||
IconKey,
|
||||
IconLink,
|
||||
IconCommentDots,
|
||||
IconSSH,
|
||||
IconSquareRSS,
|
||||
} from "@components/icons";
|
||||
import {
|
||||
IconBluesky,
|
||||
IconCodeberg,
|
||||
|
|
@ -104,6 +112,21 @@ const sshKey = await readFile("./public/ssh.pub", { encoding: "utf-8" });
|
|||
<p class="sr-only select-none">Gallery on https://gallery.badmanners.xyz</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
id="gallery-feed"
|
||||
class="u-url contact-link group"
|
||||
type="application/rss+xml"
|
||||
href="https://gallery.badmanners.xyz/feed.xml"
|
||||
rel="alternate"
|
||||
aria-label="Gallery feed"
|
||||
title="Gallery feed"
|
||||
data-tooltip
|
||||
>
|
||||
<IconSquareRSS height="1.75rem" width="1.75rem" class="contact-icon" />
|
||||
<p class="sr-only select-none">Gallery feed</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
id="pronouns"
|
||||
|
|
@ -270,6 +293,7 @@ const sshKey = await readFile("./public/ssh.pub", { encoding: "utf-8" });
|
|||
id="gpg"
|
||||
class="u-key contact-link group"
|
||||
href="/gpg.pub"
|
||||
type="text/plain"
|
||||
aria-label="GPG public key"
|
||||
title="GPG public key"
|
||||
data-tooltip
|
||||
|
|
@ -439,6 +463,7 @@ const sshKey = await readFile("./public/ssh.pub", { encoding: "utf-8" });
|
|||
id="ssh"
|
||||
class="u-key contact-link group"
|
||||
href="/ssh.pub"
|
||||
type="text/plain"
|
||||
aria-label="SSH public key"
|
||||
title="SSH public key"
|
||||
data-tooltip
|
||||
|
|
@ -556,12 +581,6 @@ const sshKey = await readFile("./public/ssh.pub", { encoding: "utf-8" });
|
|||
}
|
||||
|
||||
// Validate links
|
||||
const customClipboardItems = indexLinks.querySelectorAll<HTMLElementTagNameMap["a" | "button"]>(
|
||||
"li > :is(a, button)[data-clipboard]",
|
||||
);
|
||||
if (!customClipboardItems.length) {
|
||||
console.warn("Missing custom clipboard elements in #links list.");
|
||||
}
|
||||
indexLinks.querySelectorAll("li > :not(a, button)").forEach((el) => {
|
||||
console.warn("Element with unknown type found in #links list:", el);
|
||||
});
|
||||
|
|
@ -580,6 +599,12 @@ const sshKey = await readFile("./public/ssh.pub", { encoding: "utf-8" });
|
|||
|
||||
// Add functionality to custom clipboard items
|
||||
if ("clipboard" in navigator) {
|
||||
const customClipboardItems = indexLinks.querySelectorAll<HTMLElementTagNameMap["a" | "button"]>(
|
||||
"li > :is(a, button)[data-clipboard]",
|
||||
);
|
||||
if (!customClipboardItems.length) {
|
||||
console.warn("Missing custom clipboard elements in #links list.");
|
||||
}
|
||||
customClipboardItems.forEach((element) => {
|
||||
const label = element.dataset.noun ?? element.getAttribute("aria-label");
|
||||
const clipboard = element.dataset.clipboard;
|
||||
|
|
@ -587,7 +612,6 @@ const sshKey = await readFile("./public/ssh.pub", { encoding: "utf-8" });
|
|||
console.warn(`Missing "data-clipboard" field for custom clipboard element, ignoring...`, element);
|
||||
return;
|
||||
}
|
||||
// const disabled = element.getAttribute("disabled");
|
||||
element.removeAttribute("disabled");
|
||||
const elementTooltip = tippy(element, {
|
||||
content: label ? `${label} copied to clipboard!` : "Copied to clipboard!",
|
||||
|
|
@ -603,20 +627,35 @@ const sshKey = await readFile("./public/ssh.pub", { encoding: "utf-8" });
|
|||
.then(() => elementTooltip.show())
|
||||
.catch((e) => {
|
||||
console.error("Unable to copy custom content to clipboard.", clipboard, e);
|
||||
// Clean up clipboard logic, and revert element to original state
|
||||
// element.removeEventListener("click", onClickElement);
|
||||
// elementTooltip.destroy();
|
||||
// if (disabled !== null) {
|
||||
// element.setAttribute("disabled", disabled);
|
||||
// } else {
|
||||
// // Invoke default click
|
||||
// element.click();
|
||||
// }
|
||||
});
|
||||
});
|
||||
};
|
||||
element.addEventListener("click", onClickElement);
|
||||
});
|
||||
} else {
|
||||
const customClipboardButtons = indexLinks.querySelectorAll<HTMLElementTagNameMap["button"]>(
|
||||
"li > button[data-clipboard][disabled]",
|
||||
);
|
||||
customClipboardButtons.forEach((element) => {
|
||||
element.removeAttribute("disabled");
|
||||
const clipboard = element.dataset.clipboard;
|
||||
if (!clipboard) {
|
||||
console.warn(`Missing "data-clipboard" field for custom clipboard element, ignoring...`, element);
|
||||
return;
|
||||
}
|
||||
element.removeAttribute("disabled");
|
||||
const elementTooltip = tippy(element, {
|
||||
content: clipboard,
|
||||
trigger: "manual",
|
||||
theme: "bm",
|
||||
});
|
||||
const onClickElement = async (ev: Event) => {
|
||||
ev.preventDefault();
|
||||
hideAll();
|
||||
elementTooltip.show();
|
||||
};
|
||||
element.addEventListener("click", onClickElement);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue