diff --git a/public/assets/css/modal.css b/public/assets/css/modal.css index 5dfca60..9dd0d83 100644 --- a/public/assets/css/modal.css +++ b/public/assets/css/modal.css @@ -1,9 +1,5 @@ /* -- Transition overrides -- */ -body { - transition: var(--transition) background-color; -} - body main .screen { transition: var(--transition) transform; transition-delay: calc(var(--transition) / 2); @@ -39,13 +35,40 @@ body .modal.active ~ main .screen { } .modal .button { - background-color: rgba(var(--comp-inverted),.05); + align-self: stretch; } -.modal .button p { - color: var(--color-inverted); +.modal .inner { + transition: var(--transition) transform, var(--transition) opacity; + position: relative; + background-color: var(--color-background); + width: calc(100vw - var(--padding)); + max-width: 500px; + max-height: 100%; + overflow-y: auto; + word-break: break-word; + box-sizing: border-box; + padding: var(--padding); + border-radius: var(--border-radius); + opacity: 0; + display: flex; + flex-direction: column; + align-items: center; + gap: var(--padding); } +.modal.active .inner { + opacity: 1; +} + +.modal .inner > h1, +.modal .inner > h2, +.modal .inner > p { + text-align: center; +} + +/* ---- */ + .spinner.logo { --size: 10vw; --anim-speed: 1s; @@ -70,30 +93,42 @@ body .modal.active ~ main .screen { } } +/* ---- */ + +.modal h1 { + font-size: clamp(20px,2vw,20px); +} + +.modal pre { + align-self: stretch; + overflow: scroll; + background-color: black; + color: white; + padding: 10px 15px; + border-radius: 6px; +} + /* -- Cards -- */ .modal.card .inner { - transition: var(--transition) transform, var(--transition) opacity; - position: relative; - background-color: var(--color-background); - width: calc(100vw - var(--padding)); - max-width: 500px; align-self: flex-end; - box-sizing: border-box; - padding: var(--padding); transform: translateY(1vh); - border-radius: var(--border-radius); - opacity: 0; - display: flex; - flex-direction: column; - gap: var(--padding); } .modal.card.active .inner { transform: translateY(0); - opacity: 1; } .modal.card .button[data-action="close"] { margin-top: auto; +} + +/* -- Dialogs -- */ + +.modal.dialog .inner { + transform: scale(.95); +} + +.modal.dialog.active .inner { + transform: scale(1); } \ No newline at end of file diff --git a/public/assets/css/style.css b/public/assets/css/style.css index 543df92..908866d 100644 --- a/public/assets/css/style.css +++ b/public/assets/css/style.css @@ -78,7 +78,15 @@ main { display: flex; } -main.active { +body.menuActive { + background-color: var(--color-contrast); +} + +body.dark.menuActive { + background-color: black; +} + +body.menuActive main { transform: translateX(-100vw); } @@ -95,6 +103,10 @@ body.dark .screen.dark { background-color: black; } +.screen .inner { + display: contents; +} + .screen .content { box-sizing: border-box; padding: calc(var(--padding) * 1.5); @@ -131,7 +143,6 @@ body.dark .screen.dark { /* ---- */ .button { - background-color: var(--color-contrast); text-align: center; padding: 25px; border-radius: var(--border-radius); @@ -141,6 +152,16 @@ body.dark .screen.dark { gap: var(--padding); } +.button.solid { + background-color: var(--color-contrast); + color: var(--color-background); +} + +.button.phantom { + background-color: rgba(var(--comp-inverted),.05); + color: var(--color-contrast); +} + .button svg { pointer-events: none; fill: var(--color-contrast); @@ -150,15 +171,7 @@ body.dark .screen.dark { .button p { pointer-events: none; font-size: clamp(16px,5vw,22px); - color: var(--color-background); -} - -.button.phantom { - background-color: rgba(var(--comp-contrast),.1); -} - -.button.phantom p { - color: var(--color-contrast); + color: inherit; } .button.loading p { diff --git a/public/assets/js/modules/Components.mjs b/public/assets/js/modules/Components.mjs index d026a59..691cfa1 100644 --- a/public/assets/js/modules/Components.mjs +++ b/public/assets/js/modules/Components.mjs @@ -12,19 +12,40 @@ class Component { export class Button extends Component { constructor(properties) { super("div"); + this.properties = properties; this.element.classList.add("button"); - this.setText(properties.text); - this.setAction(properties.action); + this.setText(); + this.setAction(); + this.setType(); } - setText(text) { + setText() { + if(!this.properties.text) { + return false; + } const textElement = document.createElement("p"); - textElement.innerText = text; + textElement.innerText = this.properties.text; this.element.appendChild(textElement); } - setAction(action) { - this.element.setAttribute("data-action",action); + setAction() { + if(!this.properties.action) { + return false; + } + this.element.setAttribute("data-action",this.properties.action); + } + + setType() { + const types = [ + "solid", + "phantom" + ]; + const type = types.includes(this.properties.type) ? this.properties.type : false; + + if(!this.properties.type || !type) { + return false; + } + this.element.classList.add(type); } } \ No newline at end of file diff --git a/public/assets/js/modules/Modals.mjs b/public/assets/js/modules/Modals.mjs index 9a3e03a..d21c12f 100644 --- a/public/assets/js/modules/Modals.mjs +++ b/public/assets/js/modules/Modals.mjs @@ -16,6 +16,8 @@ class Modal extends Interaction { interactions = Object.assign(interactions,extendedInteractions); super(interactions,element); + this.transition = 300; + this.element = this.applyTemplate(element); this.element.close = () => this.close(); // Bind close to element prototype document.body.insertAdjacentElement("afterbegin",this.element); @@ -26,7 +28,15 @@ class Modal extends Interaction { const url = `assets/pages/${page}`; const response = await fetch(url); if(!response.ok) { - throw new Error(`Modal: Failed to fetch page "${page}"`); + const report = { + "self": "Modal.getPage()", + "self_page": page, + "resp_status": response.status, + "resp_statusText": response.statusText, + "resp_url": response.url, + "rqst_ua": navigator.userAgent + }; + throw new Error(JSON.stringify(report,null,2)); } return response.text(); } @@ -68,21 +78,40 @@ class Modal extends Interaction { } } -// Overlay with a slide-in animation from the bottom of the viewport -export class Card extends Modal { - constructor(interactions) { +export class Dialog extends Modal { + constructor(interactions = {}) { super(interactions); - - this.transition = 300; this.init(); } - init(slim) { + init() { + this.element.classList.add("dialog"); + this.element.classList.add("center"); + const closeButton = new Button({ + text: "close", + action: "close", + type: "phantom" + }); + + this.bind(closeButton.element); + this.inner.appendChild(closeButton.element); + } +} + +// Overlay with a slide-in animation from the bottom of the viewport +export class Card extends Modal { + constructor(interactions = {}) { + super(interactions); + this.init(); + } + + init() { this.element.classList.add("card"); this.element.classList.add("center"); const closeButton = new Button({ text: "close", - action: "close" + action: "close", + type: "phantom" }); this.bind(closeButton.element); @@ -91,19 +120,22 @@ export class Card extends Modal { error(message) { const oops = document.createElement("p"); - const infoButton = new Button({ - text: "more info" - }); + const infoButton = document.createElement("p"); oops.classList.add("error"); oops.innerText = "🤯\nSomething went wrong"; + infoButton.innerText = "more info.."; - infoButton.element.addEventListener("click",() => { - oops.innerText = "📋\n" + message; - destroy(infoButton.element); + infoButton.addEventListener("click",() => { + const details = new Dialog(); + + details.insertHTML(`
${message}`); + details.open(); + + this.close(); }); - this.insertElement(infoButton.element); + this.insertElement(infoButton); this.insertElement(oops); } @@ -112,6 +144,7 @@ export class Card extends Modal { // 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(); diff --git a/public/assets/js/modules/UI.mjs b/public/assets/js/modules/UI.mjs index 2464ae0..c59c8ac 100644 --- a/public/assets/js/modules/UI.mjs +++ b/public/assets/js/modules/UI.mjs @@ -42,30 +42,6 @@ export default class Interaction extends Logging { } } - // Set the page theme color (and the theme-color meta tag) - setThemeColor(color) { - const meta = document.head.querySelector("meta[name='theme-color']"); - const style = getComputedStyle(document.body); - - if(!meta || !color) { - return false; - } - - // Dark mode will always use the background color - if(document.body.classList.contains("dark")) { - color = "background"; - } - - if(color[0] !== "#") { - // Get CSS variable if color isn't a HEX code - color = style.getPropertyValue(`--color-${color}`); - color = color.replaceAll(" ",""); - } - - document.body.style.setProperty("background-color",color); - meta.setAttribute("content",color); - } - // Handle click/touch interactions pointerEvent(event) { const target = event.target.closest(`[${this.attribute}]`); @@ -77,10 +53,5 @@ export default class Interaction extends Logging { } // Execute the function from the data-action attribute this.interactions[action](event); - - // The button has requested a theme-color change - if(target.hasAttribute("data-theme-color")) { - this.setThemeColor(target.getAttribute("data-theme-color")); - } } } \ No newline at end of file diff --git a/public/assets/js/script.js b/public/assets/js/script.js index 4a3b001..0ed8ba5 100644 --- a/public/assets/js/script.js +++ b/public/assets/js/script.js @@ -17,7 +17,7 @@ const interactions = { const menu = document.getElementsByTagName("main")[0]; menu.style.setProperty("transition",`${speed}ms`); - menu.classList.toggle("active"); + document.body.classList.toggle("menuActive"); setTimeout(() => menu.style.removeProperty("transition"),speed + 1); }, openContactCard: () => { @@ -30,6 +30,14 @@ const interactions = { const card = new modals.Card(interactions); card.openPage(service); }); + }, + copyText: (event) => { + const memory = event.target.innerText; + event.target.classList.add("bounce"); + event.target.innerText = "Copied!"; + setTimeout(() => { + event.target.innerText = memory; + },this.transition); } }; @@ -52,11 +60,8 @@ function updateTheme() { document.body.classList.add("dark"); return; } - - main.setThemeColor("background"); } // Set the current page theme, and listen for changes theme.addEventListener("change",updateTheme); -updateTheme(); -window._debug.openContactsModal(); \ No newline at end of file +updateTheme(); \ No newline at end of file diff --git a/public/assets/pages/contact.html b/public/assets/pages/contact.html index b32abf4..dd16510 100644 --- a/public/assets/pages/contact.html +++ b/public/assets/pages/contact.html @@ -1,13 +1,15 @@
Signal
-
Signal is a free and encrypted message platform with apps for all major platforms.
+ \ No newline at end of file