diff --git a/public/assets/css/modal.css b/public/assets/css/modal.css index 7cd4477..edfdf4c 100644 --- a/public/assets/css/modal.css +++ b/public/assets/css/modal.css @@ -13,6 +13,10 @@ body .modal.active ~ main .screen { pointer-events: none; } +.modal.active + .modal { + z-index: 5; +} + /* -- Boilerplate -- */ .modal { diff --git a/public/assets/css/style.css b/public/assets/css/style.css index f696d52..48e55e6 100644 --- a/public/assets/css/style.css +++ b/public/assets/css/style.css @@ -67,7 +67,9 @@ color: var(--swatch-accent); } +a, picture { + text-decoration: none; display: contents; } diff --git a/public/assets/js/modules/Modals.mjs b/public/assets/js/modules/Modals.mjs index fcae338..819d509 100644 --- a/public/assets/js/modules/Modals.mjs +++ b/public/assets/js/modules/Modals.mjs @@ -67,6 +67,64 @@ class Modal extends Interaction { return element; } + error(message) { + const oops = document.createElement("p"); + const infoButton = document.createElement("p"); + + oops.classList.add("error"); + oops.innerText = "🤯\nSomething went wrong"; + + infoButton.innerText = "more info.."; + infoButton.addEventListener("click",() => { + const details = new Dialog(); + + details.insertHTML(`
${message}`); + details.open(); + + this.close(); + }); + + this.insertElement(infoButton); + this.insertElement(oops); + } + + // Open page from "assets/pages" + openPage(page) { + // Show a spinner while fetching + const spinner = document.createElement("div"); + spinner.classList = "logo spinner"; + this.element.setAttribute("data-page",page); + this.insertElement(spinner); + this.open(); + + // Fetch the requested page + this.getPage(page).then(html => { + this.insertHTML(html); + this.bindAll(this.inner); + }) + .catch(error => { + const tryAgain = new Button({ + text: "try again", + type: "solid" + }); + tryAgain.element.addEventListener("click",() => { + // Clear and recreate modal structure + destroy(this.inner); + this.applyTemplate(this.element); + this.init(); + this.insertElement(spinner); + // Attempt to fetch the requested url again (with soft rate-limiting) + setTimeout(() => { + this.openPage(page); + destroy(spinner); + },500); + }); + this.insertElement(tryAgain.element); + this.error(error); + }) + .finally(() => destroy(spinner)); + } + open() { setTimeout(() => this.element.classList.add("active"),this.transition / 2); } @@ -117,58 +175,4 @@ export class Card extends Modal { this.bind(closeButton.element); this.inner.appendChild(closeButton.element); } - - error(message) { - const oops = document.createElement("p"); - const infoButton = document.createElement("p"); - - oops.classList.add("error"); - oops.innerText = "🤯\nSomething went wrong"; - - infoButton.innerText = "more info.."; - infoButton.addEventListener("click",() => { - const details = new Dialog(); - - details.insertHTML(`
${message}`); - details.open(); - - this.close(); - }); - - this.insertElement(infoButton); - this.insertElement(oops); - } - - // Open page from "assets/pages" - openPage(page) { - // Show a spinner while fetching - const spinner = document.createElement("div"); - spinner.classList = "logo spinner"; - this.element.setAttribute("data-page",page); - this.insertElement(spinner); - this.open(); - - // Fetch the requested page - this.getPage(page).then(html => { - this.insertHTML(html); - this.bindAll(this.inner); - }) - .catch(error => { - const tryAgain = new Button({ - text: "try again", - type: "solid" - }); - tryAgain.element.addEventListener("click",() => { - // Clear and recreate modal structure - destroy(this.inner); - this.applyTemplate(this.element); - this.init(); - // Attempt to fetch the requested url again - this.openPage(page); - }); - this.insertElement(tryAgain.element); - this.error(error); - }) - .finally(() => destroy(spinner)); - } } \ No newline at end of file diff --git a/public/assets/js/script.js b/public/assets/js/script.js index 4b182c6..59bf50f 100644 --- a/public/assets/js/script.js +++ b/public/assets/js/script.js @@ -1,6 +1,6 @@ // Copyright © Victor Westerlund - No libraries! 😲 import { default as Preload } from "./modules/Preload.mjs"; -import { default as Interaction } from "./modules/UI.mjs"; +import { default as Interaction, destroy } from "./modules/UI.mjs"; import "./modules/Debugging.mjs"; // Load these assets when the DOM is ready (not needed right away) @@ -37,7 +37,7 @@ const interactions = { const module = import("./modules/Modals.mjs"); const interactions = { getContact: (event) => { - const service = event.target.getAttribute("data-value"); + const service = event.target.dataset.value; module.then(modals => { event.target.closest(".modal").close(); const card = new modals.Card(interactions); @@ -45,12 +45,21 @@ const interactions = { }); }, copyText: (event) => { - const memory = event.target.innerText; - event.target.classList.add("bounce"); - event.target.innerText = "copied!"; + event.target.classList.add("copied"); + const copied = document.createElement("p"); + copied.innerText = "copied!"; + event.target.appendChild(copied); + setTimeout(() => { - event.target.innerText = memory; + event.target.classList.remove("copied"); + destroy(copied); },1000); + }, + showPgpKey: () => { + module.then(modals => { + const dialog = new modals.Dialog(); + dialog.openPage("contact_email_pgp"); + }); } }; @@ -58,10 +67,6 @@ const interactions = { const card = new modals.Card(interactions); card.openPage("contact"); }); - }, - openSearch: () => { - const module = import("./modules/Search.mjs"); - document.body.classList.add("searchActive"); } } diff --git a/public/assets/pages/contact_email.html b/public/assets/pages/contact_email.html new file mode 100644 index 0000000..04b9dfe --- /dev/null +++ b/public/assets/pages/contact_email.html @@ -0,0 +1,64 @@ + + + +
You can also here to send a mail directly from your mail app
+ + \ No newline at end of file diff --git a/public/assets/pages/contact_email_pgp.html b/public/assets/pages/contact_email_pgp.html new file mode 100644 index 0000000..84202b4 --- /dev/null +++ b/public/assets/pages/contact_email_pgp.html @@ -0,0 +1,39 @@ + ++-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQENBF/K6MkBCACkRMhMfYdeNP+M3XQoZHQVJgippQvYZ4QqH6F6brWD5989Xy5W +kDCvLbmPJ66boqB0dHExswOvMlhfFha65pRmfP6lIoIxZlZKwll1XASP2osS8f6r +63T7hAbL3V2Dkm49tiH1tk578xGomDrxOrd4izpH4mn9AyBIL4M+5j34bKFVZKQ+ +QfMu7tduF/1oQHfDaXJeLXSfn5cNTy8DlLcLJKUSk4cjabf1D88gMVszqAAC5o1a +fI0YxoyZ+Fv+CmyrQm2iIZ3+MyDU9JAvoImtlp1h5aNgbFRDi2vKcSlv158Hq97Z +XlH1ttRZuFZiJzb8iukgUUFi4RORoXWt2rtNABEBAAG0LlZpY3RvciBXZXN0ZXJs +dW5kIDxoZWxsb0B2aWN0b3J3ZXN0ZXJsdW5kLmNvbT6JATUEEAEIACkFAl/K6MkG +CwkIBwMCCRBb4MsL47tp2gQVCAIKAxYCAQIZAQIbAwIeAQAAJ5MIAKDl9yHjwTO7 +20sDrPa6ECsSBU/FwkvkWecuauvY19/OqtacNk8dEeiITLeUeBXkvNzN+P0y8hoF +ABZeir59dsY00iIp8gm03eLalhcblR5jYe3c08HssJH8PksczP3kitRNLvPAf2nU +BYg3zca5Ka21/4BPRLFb9SAQGxfHyZdy3Poug+o+pokbeK2wLqqfSMtH+waBB6Lg +2dRXuEnaZorUpNBpsahxastvNehv31Ke41Brvft15VKpO25GKZDPhm0odXMth1/J +pzWRQtndazY2guB0Ft+5wujv28HFCgVgZn2fKiQVytAetO+/wzPijBkGRvdIE+Zb +VRd3Nc0mHI65AQ0EX8royQEIALcoWEurmyXD2LoGvR+sYW+YPAPM6KG8KF4cWUn8 +8+kZ6F4FH9OW64di2npYe3x+zR7DgQ1yHXcmalAsP0nN4JWTavLwsSO+JAv8NpL5 +bgDs6fGaEQFl+X4fYOpkBkBmb1JrbnBk1a2u3qsEw8t7+wW1LG9z/Si5+G1KQko8 +x/PEaZ2ZVv7L51ZfIQRnMtl4vL5X23BPVsDywotvuFqlTiSjGP4CR0lVa5CRv3DJ +FSmHxAxeI0vMMlwbIIUTrtwJR320sZvh2cRiwAXHQXm6l0ojzRnl46mmXnB3N6q9 +PyWOaUgPrMFjT24wtgopIOwbFAT3xTr1Un0FbdeaG9JhdJ8AEQEAAYkBHwQYAQgA +EwUCX8royQkQW+DLC+O7adoCGwwAAIV/B/9OLYeQOxbXh1/hvW7/oTvN1py8wfFq +buvQSrb/MZKm6lZgG+kQy3DWjGTi/xvNqDHfBiObFSGso8RHSbHFldzEuMgrgoWW +/4JH1GDiKOp+rmBxfG30/DzOoFSfVcUfP5r8xNQby4Bh6zJhKPKVB3sZjO8cHNZD +HcNAqT3Gh5yFzsUna+ZjvPF7iU5RF1YP46dsIdvuo4xFbHpEPoZs7wgZijf+vmKO +lP61UFvKuXzwcLiI6s919EBJ9+7je8ZAxe6BCaazk+AhxXeokVvDgwQ150DNk4up +1ftWZI0LHqEpVGNejQ09uu+TdC/ISy/Ti0XKlJDER1eUL577YRUl876Y +=2qWm +-----END PGP PUBLIC KEY BLOCK-----+
Signal is a free and encrypted message platform with apps for all major platforms.
\ No newline at end of file