Skip to content

Commit

Permalink
Proof of concept (#1)
Browse files Browse the repository at this point in the history
* add url to license

* html first pass

* basic styling

* add header and footer with project info and links

* first pass at script. successfully sends message to specified channel

* demonstrated ability to send json encoded message content

* Create .browserslistrc

* disable submit button while processing

* add rough first pass js to handle dependent fields

* hack: have submit watch new dependency trigger field
  • Loading branch information
thewildmage authored Jan 28, 2022
1 parent cd9fe6e commit 21ac812
Show file tree
Hide file tree
Showing 7 changed files with 254 additions and 1 deletion.
4 changes: 4 additions & 0 deletions .browserslistrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# supported browsers

defaults
not ie > 0
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2022 Magrathea
Copyright (c) 2022 Magrathea (https://github.com/magratheaguide).

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Huningto: Discord Messages via Webhook

> In the _Mass Effect_ series, Huningto is a planet with a magnetic field so strong, it "creates strong radio interference throughout the inner system" (["Huningto," Mass Effect Wiki](https://masseffect.fandom.com/wiki/Huningto)).
81 changes: 81 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />

<title>
Huningto: Discord Messages via Webhook, A Magrathea Project
</title>

<link href="https://cdn.jsdelivr.net/gh/thewildmage/css-reset@1/dist/reset.css" rel="stylesheet" />
<link href="styles.css" rel="stylesheet" />

<script src="js/dependent-fields.js" defer></script>
<script src="js/main.js" defer></script>
</head>
<body class="flow">
<header>
<h1>Huningto</h1>
<p>Discord messages via webhook. A <a href="https://magrathea.guide">Magrathea</a> project.</a></p>
</header>

<main>
<form class="flow" method="post">
<h2>Destination</h2>

<p>
<label for="webhook-url">Webhook URL</label>
<input id="webhook-url" name="action" type="url" required></input>
</p>

<p>
<label for="thread-id">Thread ID</label>
<span id="thread-id-explain">Leave blank for main channel</span>
<input aria-describedby="thread-id-explain" id="thread-id" name="thread_id" type="number"></input>
</p>

<h2>Content</h2>

<fieldset>
<legend>I want to build my message...</legend>

<input class="js-dependency" id="from-scratch" name="buildFrom" type="radio" value="scratch" checked required></input>
<label for="from-scratch">...from scratch.</label>

<input class="js-dependency" id="from-json" name="buildFrom" type="radio" value="json" required></input>
<label for="from-json">...from JSON I already have.</label>
</fieldset>

<p class="js-dependency" data-build-from="scratch">
<label for="message">Message</label>
<textarea id="message" maxlength="2000" name="content" rows="5"></textarea>
</p>

<p class="js-dependency" data-build-from="json">
<label for="payload-json">Message JSON</label>
<textarea id="payload-json" name="payload_json" rows="5"></textarea>
</p>

<h2>Finish</h2>

<p>
<button type="submit">Send</button>
</p>

<p>
<label for="output">Server Response</label>
<output id="output">(None yet)</output>
</p>
</form>
</main>

<footer>
<p>Copyright (c) 2022 <a href="https://magrathea.guide">Magrathea</a>.</p>

<p><a href="https://github.com/magratheaguide/mon-cala/blob/main/LICENSE">Released under the MIT License.</a></p>

<p><a href="https://github.com/magratheaguide/mon-cala">View on GitHub.</a></p>
</footer>
</body>
</html>
30 changes: 30 additions & 0 deletions js/dependent-fields.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"use strict";

(function () {
const form = document.querySelector("form");

const dependencyTriggers = form.querySelectorAll("input.js-dependency");
const dependencyFollowers = form.querySelectorAll(".js-dependency:not(input)");

dependencyTriggers.forEach(trigger => {
// consider initial states
if (trigger.checked) {
updateDependencyFollowers(trigger.name, trigger.value);
}

// update on change
trigger.addEventListener("change", () => {
updateDependencyFollowers(trigger.name, trigger.value, trigger.checked);
});
});

function updateDependencyFollowers(key, value, checked = true) {
dependencyFollowers.forEach(follower => {
if (follower.dataset[key]) {
if (checked && follower.dataset[key] == value) follower.removeAttribute("hidden");
else follower.setAttribute("hidden", "");
}
});
}
})();

73 changes: 73 additions & 0 deletions js/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
"use strict";

(function () {
const form = document.querySelector("form");
const output = document.querySelector("output");

form.addEventListener("submit", event => {
event.preventDefault();

let submitButton = form.querySelector("button[type='submit']");
let url = constructUrl(form.elements);
let body = new FormData();

output.value = "";
submitButton.setAttribute("disabled", "");

// TODO: Need to teach this how to check dependent fields
if (form.elements.buildFrom.value === "json") {
body.append("payload_json", form.elements.payload_json.value);
} else {
body.append("content", form.elements.content.value);
}

fetch(url, {
body: body,
method: "POST"
}).then(response => {
console.log(response);

displayResponse(response);
});

submitButton.removeAttribute("disabled");
});

function constructUrl(elements) {
let baseUrl = elements.action.value;
let threadId = elements.thread_id.value.trim();

if (threadId) {
return `${ baseUrl }?thread_id=${ threadId }`;
}

return baseUrl;
}

function displayResponse(response) {
if (response.ok) {
linebreak(output);
output.value = ("Message sent successfully");
} else {
output.value = (`HTTP Status Code ${ response.status }: ${ response.statusText }`);

response.text().then(text => {
try {
let json = JSON.parse(text);

for (const [key, value] of Object.entries(json)) {
linebreak(output);
output.append(`${ key }: ${ value }`);
}
} catch {
linebreak(output);
output.append(text);
}
});
}
}

function linebreak(element) {
element.append(document.createElement("br"));
}
})();
62 changes: 62 additions & 0 deletions styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
:root {
--border: 2px dotted var(--color-grey);

--color-grey: hsl(0deg 0% 50%);
}

body {
margin-inline: auto;
max-width: 65ch;
min-height: 100%;
padding: 2em;
}

fieldset {
display: grid;
gap: 1em;
grid-template-columns: [input] auto [label] 1fr;
padding-block: 1em;
}

fieldset input {
grid-column: input;
}

fieldset label {
grid-column: label;
}

footer {
border-block-start: var(--border);
padding-block-start: 1em;
text-align: center;
}

form button {
min-inline-size: 15ch;
}

form p {
display: flex;
flex-direction: column;
}

header {
border-block-end: var(--border);
padding-block-end: 1em;
text-align: center;
}

hr {
border: none;
border-block-start: var(--border);
margin-block: 2em;
}

[hidden] {
display: none;
}

.flow > * + * {
margin-block-start: var(--flow-space, 1em);
}

0 comments on commit 21ac812

Please sign in to comment.