feat: finish commands

This commit is contained in:
Stevan Freeborn
2026-01-23 18:22:13 -06:00
parent 68fe011b35
commit 7196cdb3ab
3 changed files with 202 additions and 63 deletions
+2 -2
View File
@@ -16,7 +16,7 @@
<header> <header>
<h1>Stevan's Stream Commands</h1> <h1>Stevan's Stream Commands</h1>
<p> <p>
These are the commands available to use during a stream to interact in These are commands you can use during a stream to interact in
chat. chat.
</p> </p>
</header> </header>
@@ -24,7 +24,7 @@
<ul id="commandsList"></ul> <ul id="commandsList"></ul>
</main> </main>
<footer> <footer>
<p>Hope you enjoy the streams!</p> <p>Hope you enjoy the stream!</p>
</footer> </footer>
<script type="module" src="index.js" /> <script type="module" src="index.js" />
</body> </body>
+156 -43
View File
@@ -1,12 +1,121 @@
const COMMANDS = [ const COMMANDS = [
{
name: "Topic",
description: "Find out what is happening on the stream.",
aliases: ["!whatbrodoing"],
},
{
name: "Lurk",
description:
"Let chat know you are here, but lurking. We support our fellow lurkers.",
aliases: ["!lurk"],
},
{
name: "Schedule",
description: "Get my stream schedule.",
aliases: ["!schedule"],
},
{
name: "Lofi Generator",
description: "Get the link to the website that I use for my stream music.",
aliases: ["!lofi", "!music"],
},
{
name: "ZoomIt",
description: "Get the link to the tool I use to draw on my screen.",
aliases: ["!zoomit"],
},
{
name: "Neovim",
description: "Get the link to my Neovim configs.",
aliases: ["!nvim", "!neovim"],
},
{
name: "My Font",
description: "Get the link to the NerdFont I use.",
aliases: ["!font", "!nerdfont"],
},
{
name: "PowerShell",
description: "Get the link to my PowerShell profile.",
aliases: ["!pwsh", "!powershell"],
},
{
name: "Oh My Posh",
description: "Get the link to my Oh My Posh configs.",
aliases: ["!omp", "!ohmyposh"],
},
{
name: "Member",
description: "Get a link to become a member of the YouTube channel.",
aliases: ["!member"],
},
{
name: "Links",
description: "Get a link to all my links.",
aliases: ["!links"],
},
{
name: "Blog",
description: "Get the link to my blog.",
aliases: ["!blog"],
},
{
name: "Bluesky",
description: "Get the link to my Bluesky profile.",
aliases: ["!bsky", "!bluesky"],
},
{
name: "Bottom",
description: "Get the link to the terminal monitor I use.",
aliases: ["!btm", "!bottom"],
},
{
name: "Discord",
description: "Want to chat off stream? Get the invite link to my discord.",
aliases: ["!discord"],
},
{ {
name: "GitHub", name: "GitHub",
description: "Get the link to my github", description: "Get the link to my GitHub profile.",
aliases: ["!gh"], aliases: ["!gh", "!github"],
},
{
name: "Tangled",
description: "Get the link to my Tangled profile.",
aliases: ["!tangled"],
},
{
name: "LinkedIn",
description: "Get the link to my LinkedIn profile.",
aliases: ["!li", "!linkedin"],
},
{
name: "Telegram",
description: "Get the invite link to my Telegram channel.",
aliases: ["!tg", "!telegram"],
},
{
name: "Twitch",
description: "Get the link to my Twitch channel.",
aliases: ["!ttv", "!twitch"],
},
{
name: "YouTube",
description: "Get the link to my YouTube channel.",
aliases: ["!yt", "!youtube"],
},
{
name: "Commands",
description:
"Get the link to the list of commands available in chat during a stream.",
aliases: ["!help", "!commands"],
}, },
]; ];
document.addEventListener("DOMContentLoaded", () => { document.addEventListener("DOMContentLoaded", handleContentLoaded);
function handleContentLoaded() {
const commandsList = document.getElementById("commandsList"); const commandsList = document.getElementById("commandsList");
if (commandsList === null) { if (commandsList === null) {
@@ -14,17 +123,25 @@ document.addEventListener("DOMContentLoaded", () => {
} }
for (const command of COMMANDS) { for (const command of COMMANDS) {
const listItemElement = document.createElement("li"); commandsList.appendChild(CommandListItem(command));
listItemElement.innerHTML = /*html*/ ` }
commandsList.addEventListener("click", handleCopyButtonClick);
}
function CommandListItem(command) {
const listItemElement = document.createElement("li");
listItemElement.innerHTML = /*html*/ `
<div class="command-card"> <div class="command-card">
<div class="left"> <div class="left">
<div class="name">${command.name}</div> <div class="name">${command.name}</div>
</div>
<div class="right">
<div class="aliases"> <div class="aliases">
${command.aliases ${command.aliases
.map( .map((a) => /*html*/ `
(a) => /*html*/ ` <div class="command-alias">
<div class="command-alias"> <code>${a}
<code>${a}</code>
<button <button
type="button" type="button"
class="copy-button" class="copy-button"
@@ -32,48 +149,44 @@ document.addEventListener("DOMContentLoaded", () => {
data-alias="${a}" data-alias="${a}"
> >
<i class="fa-solid fa-copy"></i> <i class="fa-solid fa-copy"></i>
<i class="fa-solid fa-check hidden"></i> <i class="fa-solid fa-check"></i>
</button> </button>
</div> </code>
`, </div>
) `,
.join("")} )
.join("")}
</div> </div>
</div>
<div class="right">
<p>${command.description}</p> <p>${command.description}</p>
</div> </div>
</div> </div>
`; `;
commandsList.appendChild(listItemElement); return listItemElement;
}
async function handleCopyButtonClick(e) {
const button = e.target.closest(".copy-button");
if (!button || !button.dataset.alias || button.classList.contains("copied")) {
return;
} }
commandsList.addEventListener("click", async (e) => {
const copyButton = e.target.closest(".copy-button");
if (copyButton === null) { try {
return; await navigator.clipboard.writeText(button.dataset.alias);
}
const alias = copyButton.dataset.alias; button.classList.add("copied");
await navigator.clipboard.writeText(alias);
const copyButtonIcons = Array.from(copyButton.children);
for (const icon of copyButtonIcons) {
icon.classList.toggle("hidden");
}
const originalColor = copyButton.style.color;
copyButton.style.color = '#b39cd0';
setTimeout(() => { setTimeout(() => {
for (const icon of copyButtonIcons) { button.classList.remove("copied");
icon.classList.toggle("hidden"); }, 1000);
} } catch (err) {
const permissionStatus = await navigator.permissions.query({
name: "clipboard-write",
});
copyButton.style.color = originalColor; alert(
}, 500); `Failed to copy command to clipboard. This is most often caused my a permission issue. Current clipboard write permission state is ${permissionStatus.state}`,
}); );
}); }
}
+44 -18
View File
@@ -27,7 +27,6 @@
button { button {
background: none; background: none;
border: none; border: none;
outline: none;
cursor: pointer; cursor: pointer;
color: inherit; color: inherit;
font-family: inherit; font-family: inherit;
@@ -52,17 +51,12 @@ table {
border-collapse: collapse; border-collapse: collapse;
} }
/* Utils */
.hidden {
display: none;
}
/* Site Styles */ /* Site Styles */
:root { :root {
--bg-color: #181818; --bg-color: #181818;
--text-color: #E4E4E4; --text-color: #E4E4E4;
--accent-color: #b39cd0;
font-family: 'CaskaydiaCove NFM', monospace; font-family: 'CaskaydiaCove NFM', monospace;
font-size: 16px; font-size: 16px;
@@ -94,26 +88,40 @@ main {
flex: 1; flex: 1;
} }
#commandsList {
display: flex;
flex-direction: column;
gap: 1rem;
margin: auto;
max-width: 50rem;
}
.command-card { .command-card {
display: flex; display: flex;
align-items: center;
gap: 1rem; gap: 1rem;
padding: 1rem; padding: 1rem;
border: 1px solid #b39cd0; border: 1px solid var(--accent-color);
border-radius: 1rem; border-radius: 1rem;
background-color: #353232; background-color: #323232;
} }
.command-card .left { .command-card .left {
display: flex; display: flex;
align-items: center; flex: 1;
gap: 1rem; gap: 1rem;
} }
.command-card .left .aliases {
.command-card .right {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 1rem; gap: 1rem;
flex: 6;
}
.command-card .right .aliases {
display: flex;
gap: 0.5rem;
} }
.command-alias { .command-alias {
@@ -122,25 +130,43 @@ main {
} }
.command-alias code { .command-alias code {
display: flex;
gap: 0.25rem;
color: var(--accent-color);
background-color: var(--bg-color); background-color: var(--bg-color);
padding: 0.25rem; padding: 0.25rem 0.5rem;
border-radius: 0.25rem; border-radius: 0.25rem;
} }
.command-alias button { .copy-button {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.command-card .right { .copy-button .fa-copy {
display: flex; display: block;
justify-content: flex-end; }
flex: 1; .copy-button .fa-check {
display: none;
}
.copy-button.copied {
color: #89D185;
pointer-events: none;
}
.copy-button.copied .fa-copy {
display: none;
}
.copy-button.copied .fa-check {
display: block;
} }
footer { footer {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding-bottom: 1rem;
} }