diff --git a/.stylelintrc.json b/.stylelintrc.json
index d30b4ce0..194688bf 100644
--- a/.stylelintrc.json
+++ b/.stylelintrc.json
@@ -4,6 +4,7 @@
"rules": {
"color-hex-length": "long",
"max-nesting-depth": 6,
+ "no-descending-specificity": null,
"order/order": null,
"order/properties-alphabetical-order": null,
"plugin/no-unsupported-browser-features": [true, { "severity": "warning", "ignore": ["flexbox"] }],
diff --git a/assets/js/src/contact.js b/assets/js/src/contact.js
index a03d40de..728adde0 100644
--- a/assets/js/src/contact.js
+++ b/assets/js/src/contact.js
@@ -2,16 +2,17 @@ import "vanilla-hcaptcha";
import { h, render } from "preact";
import { useState } from "preact/hooks";
import fetch from "unfetch";
+import parseEmoji from "./emoji.js";
const CONTACT_ENDPOINT = "/api/contact/";
const ContactForm = () => {
// status/feedback:
- const [status, setStatus] = useState({ success: false, action: "Submit", message: "" });
+ const [status, setStatus] = useState({ success: false, message: "" });
// keep track of fetch:
const [sending, setSending] = useState(false);
- const onSubmit = async (e) => {
+ const onSubmit = (e) => {
// immediately prevent browser from actually navigating to a new page
e.preventDefault();
@@ -19,19 +20,18 @@ const ContactForm = () => {
setSending(true);
// extract data from form fields
- const { name, email, message } = e.target.elements;
const formData = {
- name: name.value,
- email: email.value,
- message: message.value,
- "h-captcha-response": e.target.elements["h-captcha-response"].value,
+ name: e.target.elements.name?.value,
+ email: e.target.elements.email?.value,
+ message: e.target.elements.message?.value,
+ "h-captcha-response": e.target.elements["h-captcha-response"]?.value,
};
- // some client-side validation. these are all also checked on the server to be safe but we can save some
- // unnecessary requests here.
+ // some client-side validation to save requests (these are also checked on the server to be safe)
+ // TODO: change border color of the specific empty/missing field(s) to red
if (!(formData.name && formData.email && formData.message && formData["h-captcha-response"])) {
setSending(false);
- setStatus({ success: false, action: "Try Again", message: "Please make sure that all fields are filled in." });
+ setStatus({ success: false, message: "❗ Please make sure that all fields are filled in." });
// remove focus from the submit button
document.activeElement.blur();
@@ -55,7 +55,7 @@ const ContactForm = () => {
if (data.success === true) {
// handle successful submission
// disable submissions, hide the send button, and let user know we were successful
- setStatus({ success: true, action: "", message: "Success! You should hear from me soon. :)" });
+ setStatus({ success: true, message: "Thanks! You should hear from me soon. 😊" });
} else {
// pass on any error sent by the server
throw new Error(data.message);
@@ -70,18 +70,16 @@ const ContactForm = () => {
if (message === "USER_INVALID_CAPTCHA") {
setStatus({
success: false,
- action: "Try Again",
- message: "Did you complete the CAPTCHA? (If you're human, that is...)",
+ message: "❗ Did you complete the CAPTCHA? (If you're human, that is...)",
});
} else if (message === "USER_MISSING_DATA") {
setStatus({
success: false,
- action: "Try Again",
- message: "Please make sure that all fields are filled in.",
+ message: "❗ Please make sure that all fields are filled in.",
});
} else {
// something else went wrong, and it's probably my fault...
- setStatus({ success: false, action: "Try Again", message: "Internal server error. Try again later?" });
+ setStatus({ success: false, message: "❗ Internal server error. Try again later?" });
}
// remove focus from the submit button
@@ -95,7 +93,7 @@ const ContactForm = () => {
-
+
-
+
+
+
+ // eslint-disable-next-line react/no-danger
+ dangerouslySetInnerHTML={{ __html: parseEmoji(sending ? "Sending..." : "📤 Send") }}
+ />
- {status.message}
-
+ // eslint-disable-next-line react/no-danger
+ dangerouslySetInnerHTML={{ __html: parseEmoji(status.message) }}
+ />
);
diff --git a/assets/sass/components/_animation.scss b/assets/sass/components/_animation.scss
index 30b97dff..0f864668 100644
--- a/assets/sass/components/_animation.scss
+++ b/assets/sass/components/_animation.scss
@@ -38,12 +38,12 @@
30% {
transform: rotate(0deg);
}
+ // stylelint-enable rule-empty-line-before
// pause for 3.5 out of 5 seconds
100% {
transform: rotate(0deg);
}
- // stylelint-enable rule-empty-line-before
}
@keyframes beat {
@@ -63,12 +63,12 @@
8% {
transform: scale(1);
}
+ // stylelint-enable rule-empty-line-before
// pause for ~9 out of 10 seconds
100% {
transform: scale(1);
}
- // stylelint-enable rule-empty-line-before
}
// modified from https://tobiasahlin.com/spinkit/
diff --git a/assets/sass/components/_content.scss b/assets/sass/components/_content.scss
index 1f6e7506..a9cd220c 100644
--- a/assets/sass/components/_content.scss
+++ b/assets/sass/components/_content.scss
@@ -50,9 +50,7 @@ div#content {
}
// AnchorJS styles
- // stylelint-disable-next-line no-descending-specificity
a.anchorjs-link {
- display: inline-block;
margin-left: 0.25em;
padding: 0 0.5em 0 0.25em;
background: none;
@@ -70,7 +68,6 @@ div#content {
)
);
- // stylelint-disable-next-line no-descending-specificity
&:hover {
@include themes.themed(
(
diff --git a/assets/sass/components/_syntax.scss b/assets/sass/components/_syntax.scss
index a10567a2..66fa59b9 100644
--- a/assets/sass/components/_syntax.scss
+++ b/assets/sass/components/_syntax.scss
@@ -127,7 +127,6 @@ div.highlight-clipboard-enabled {
// Syntax Highlighting (light) - modified from Monokai Light: https://github.com/mlgill/pygments-style-monokailight
body.light {
- // stylelint-disable no-descending-specificity
div.highlight,
button.copy-button,
:not(pre) > code {
@@ -139,7 +138,6 @@ body.light {
button.copy-button {
color: #313131;
}
- // stylelint-enable no-descending-specificity
.chroma {
.k,
@@ -215,7 +213,6 @@ body.light {
// Syntax Highlighting (dark) - modified from Dracula: https://github.com/dracula/pygments
body.dark {
- // stylelint-disable no-descending-specificity
div.highlight,
button.copy-button,
:not(pre) > code {
@@ -227,7 +224,6 @@ body.dark {
button.copy-button {
color: #e4e4e4;
}
- // stylelint-enable no-descending-specificity
.chroma {
.k,
diff --git a/assets/sass/pages/_contact.scss b/assets/sass/pages/_contact.scss
index b2014187..e2e4c1fd 100644
--- a/assets/sass/pages/_contact.scss
+++ b/assets/sass/pages/_contact.scss
@@ -10,11 +10,6 @@ div.layout-contact {
text-align: center;
}
- p {
- font-size: 0.9em;
- margin-bottom: 0.5em;
- }
-
code {
background: none !important;
border: 0;
@@ -30,7 +25,7 @@ div.layout-contact {
width: 100%;
padding: 0.8em;
margin: 0.6em 0;
- border: 1px solid;
+ border: 2px solid;
border-radius: 0.3em;
font-size: 0.9em;
@@ -41,6 +36,16 @@ div.layout-contact {
border-color: "light",
)
);
+
+ &:focus {
+ outline: none; // disable browsers' outer border
+
+ @include themes.themed(
+ (
+ border-color: "links",
+ )
+ );
+ }
}
textarea {
@@ -54,8 +59,10 @@ div.layout-contact {
div#contact-form-action-row {
display: flex;
align-items: center;
+ min-height: 3.75em;
button {
+ flex-shrink: 0;
padding: 0.8em 1.2em;
margin-right: 1.5em;
border: 0;
@@ -71,8 +78,7 @@ div.layout-contact {
)
);
- &:hover,
- &:focus {
+ &:hover {
@include themes.themed(
(
color: "super-duper-light",
@@ -82,13 +88,14 @@ div.layout-contact {
}
img.emoji {
+ margin-left: 0;
margin-right: 0.4em;
cursor: inherit;
}
}
span.contact-form-result {
- font-size: 0.9em;
+ font-size: 0.925em;
font-weight: 600;
contact-form-result-success {
@@ -110,16 +117,14 @@ div.layout-contact {
}
// hcaptcha widget
- #contact-form-captcha {
- display: block;
- margin: 1.2em 0;
+ div#contact-form-captcha {
+ margin: 1em 0;
}
- span#contact-form-md-info {
- display: block;
+ div#contact-form-md-info {
font-size: 0.75em;
- margin-top: 0.25em;
- margin-left: 0.75em;
+ line-height: 1.75;
+ margin: 0.2em 0 0.6em 0;
a {
// disable fancy underline without `.no-underline`
diff --git a/assets/sass/pages/_list.scss b/assets/sass/pages/_list.scss
index 8c033588..7d33b90e 100644
--- a/assets/sass/pages/_list.scss
+++ b/assets/sass/pages/_list.scss
@@ -18,8 +18,7 @@ div.layout-list {
ul {
list-style-type: none;
margin: 0;
- padding-left: 0;
- display: block;
+ padding: 0;
}
li {
diff --git a/content/contact/index.md b/content/contact/index.md
index 43a2f649..afab2b65 100644
--- a/content/contact/index.md
+++ b/content/contact/index.md
@@ -6,3 +6,11 @@ sitemap:
changefreq: never
priority: 0.0
---
+
+
+
+Fill out this quick form and I'll get back to you as soon as I can! You can also email me directly, send me a direct message on Twitter, or text me.
+
+🔐 You can grab my public key here: 6BF3 79D3 6F67 1480 2B0C 9CF2 51E6 9A39
.
+
+
diff --git a/layouts/_default/contact.html b/layouts/_default/contact.html
index 81a73034..3209ab9e 100644
--- a/layouts/_default/contact.html
+++ b/layouts/_default/contact.html
@@ -2,8 +2,9 @@