diff --git a/data/static/style.css b/data/static/style.css index 8a2e5a5..e00bb75 100644 --- a/data/static/style.css +++ b/data/static/style.css @@ -26,7 +26,7 @@ font-weight: bold; font-style: italic; } -.currentpage, .pagebutton, input[type=file]::file-selector-button, button.warn, input[type=submit].warn, .linkbutton.warn, button.critical, input[type=submit].critical, .linkbutton.critical, button, input[type=submit], .linkbutton { +.tab-button, .currentpage, .pagebutton, input[type=file]::file-selector-button, button.warn, input[type=submit].warn, .linkbutton.warn, button.critical, input[type=submit].critical, .linkbutton.critical, button, input[type=submit], .linkbutton { cursor: default; color: black; font-size: 0.9em; @@ -511,6 +511,50 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus, select:focus .babycode-editor { height: 150px; + font-size: 1rem; +} + +.babycode-editor-container { + width: 100%; +} + +.babycode-preview-errors-container { + font-size: 0.8rem; +} + +.tab-button { + background-color: rgb(177, 206, 204.5); + border-bottom: none; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + margin-bottom: 0; +} +.tab-button:hover { + background-color: rgb(192.6, 215.8, 214.6); +} +.tab-button:active { + background-color: rgb(166.6881496063, 178.0118503937, 177.4261417323); +} +.tab-button:disabled { + background-color: rgb(209.535, 211.565, 211.46); +} +.tab-button.active { + background-color: #beb1ce; + padding-top: 8px; +} + +.tab-content { + display: none; +} +.tab-content.active { + min-height: 250px; + display: block; + background-color: rgb(191.3137931034, 189.7, 193.3); + border: 1px solid black; + padding: 10px; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; } ul, ol { diff --git a/js/babycode-editor.js b/js/babycode-editor.js index 075191c..5d1d113 100644 --- a/js/babycode-editor.js +++ b/js/babycode-editor.js @@ -59,4 +59,48 @@ e.preventDefault(); insertTag("code", true) }) + + const previewEndpoint = "/api/babycode-preview"; + let previousMarkup = ""; + const previewTab = document.getElementById("tab-preview"); + previewTab.addEventListener("tab-activated", async () => { + const previewContainer = document.getElementById("babycode-preview-container"); + const previewErrorsContainer = document.getElementById("babycode-preview-errors-container"); + // previewErrorsContainer.textContent = ""; + const markup = ta.value.trim(); + if (markup === "" || markup === previousMarkup) { + return; + } + previousMarkup = markup; + const req = await fetch(previewEndpoint, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({markup: markup}) + }) + if (!req.ok) { + switch (req.status) { + case 429: + previewErrorsContainer.textContent = "(Old preview, try again in a few seconds.)" + previousMarkup = ""; + break; + case 400: + previewErrorsContainer.textContent = "(Request got malformed.)" + break; + case 401: + previewErrorsContainer.textContent = "(You are not logged in.)" + break; + default: + previewErrorsContainer.textContent = "(Error. Check console.)" + console.error(req.error); + break; + } + return; + } + + const json_resp = await req.json(); + previewContainer.innerHTML = json_resp.html; + previewErrorsContainer.textContent = ""; + }); } diff --git a/js/tabs.js b/js/tabs.js new file mode 100644 index 0000000..3066310 --- /dev/null +++ b/js/tabs.js @@ -0,0 +1,30 @@ +function activateSelfDeactivateSibs(button) { + if (button.classList.contains("active")) return; + + Array.from(button.parentNode.children).forEach(s => { + if (s === button){ + button.classList.add('active'); + } else { + s.classList.remove('active'); + } + const targetId = s.dataset.targetId; + const target = document.getElementById(targetId); + + if (!target) return; + + if (s.classList.contains('active')) { + target.classList.add('active'); + target.dispatchEvent(new CustomEvent("tab-activated", {bubbles: false})) + } else { + target.classList.remove('active'); + } + }); +} + +document.addEventListener("DOMContentLoaded", () => { + document.querySelectorAll(".tab-button").forEach(button => { + button.addEventListener("click", () => { + activateSelfDeactivateSibs(button); + }); + }); +}); diff --git a/sass/style.scss b/sass/style.scss index e602371..07b20aa 100644 --- a/sass/style.scss +++ b/sass/style.scss @@ -45,6 +45,7 @@ $lighter: color.scale($accent_color, $lightness: 60%, $saturation: -60%); $main_bg: color.scale($accent_color, $lightness: -10%, $saturation: -40%); $button_color: color.adjust($accent_color, $hue: 90); +$button_color2: color.adjust($accent_color, $hue: 180); %button-base { cursor: default; @@ -524,8 +525,44 @@ input[type="text"], input[type="password"], textarea, select { .babycode-editor { height: 150px; + font-size: 1rem; } +.babycode-editor-container { + width: 100%; +} + +.babycode-preview-errors-container { + font-size: 0.8rem; +} + +.tab-button { + @include button($button_color); + border-bottom: none; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + margin-bottom: 0; + + &.active { + background-color: $button_color2; + padding-top: 8px; + } +} + +.tab-content { + display: none; + + &.active { + min-height: 250px; + display: block; + background-color: color.adjust($button_color2, $saturation: -20%); + border: 1px solid black; + padding: 10px; + border-top-right-radius: 3px; + border-bottom-right-radius: 3px; + border-bottom-left-radius: 3px; + } +} ul, ol { margin: 10px 0 10px 30px; diff --git a/views/base.etlua b/views/base.etlua index 5da0af2..c6fab0f 100644 --- a/views/base.etlua +++ b/views/base.etlua @@ -18,5 +18,6 @@ + diff --git a/views/common/babycode-editor-component.etlua b/views/common/babycode-editor-component.etlua index 1595448..55ac41a 100644 --- a/views/common/babycode-editor-component.etlua +++ b/views/common/babycode-editor-component.etlua @@ -1,8 +1,20 @@ - - - - - - - - +
+
+ + +
+
+ + + + + + + +
+
+
Type something!
+
+
+
+