diff --git a/assets/css/style.css b/assets/css/style.css index 5775639..32a818d 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -358,7 +358,7 @@ html { } *, *:before, *:after { - box-sizing: inherit; + box-sizing: border-box; } html, body { @@ -403,9 +403,10 @@ button, color: #fff; border-radius: 5px; border: none; - background-color: #652f8f; + background-color: #64338f; margin: 10px 0 10px 10px; cursor: pointer; + white-space: nowrap; } button i, .purple-button-link i, @@ -417,7 +418,7 @@ button i, .purple-button-link.inverted, .mode-editor #btn-mode-serial, .mode-serial #btn-mode-editor { - color: #652f8f; + color: #64338f; background-color: #c8c8c8; } @@ -429,7 +430,7 @@ button:disabled, } button.purple-button-link { - width: 250px; + min-width: 250px; } fieldset { @@ -442,7 +443,6 @@ fieldset legend { .container { width: 100%; - max-width: 480px; margin: 0 auto; } @@ -464,16 +464,6 @@ fieldset legend { .common-layout { padding: 20px 0 150px 0; background-color: #fff; - /*display: grid; - grid-template-columns: - [full-start] minmax(1em, 1fr) - [main-start] minmax(0, 80em) [main-end] - minmax(1em, 1fr) [full-end]; - grid-row-gap: 1em; - - &> * { - grid-column: main; - }*/ } .common-layout .step { display: flex; @@ -498,6 +488,22 @@ fieldset legend { padding: 40px; } +@media (max-width: 767px) { + .common-layout .step .step-number { + width: 50px; + height: 50px; + color: #333; + font-size: 36px; + font-weight: 600; + line-height: 36px; + margin: 20px 20px 0 0; + border: solid 5px #333; + min-width: 50px; + } + .common-layout.content { + padding: 20px; + } +} #site-header { display: grid; grid-template-rows: 1fr 3px; @@ -608,10 +614,28 @@ fieldset legend { background-color: #e71c8c; } +.file-path { + font-size: 20px; + line-height: 59px; + margin-left: 10px; + display: inline; + flex: auto; + overflow: hidden; + text-overflow: ellipsis; +} + +#editor-bar { + display: flex; +} + @media (max-width: 767px) { #site-header { display: none !important; } + + #editor-bar { + display: none !important; + } } #mobile-header { background-color: #333; @@ -633,39 +657,56 @@ fieldset legend { #mobile-header .site-logo { float: left; } -#mobile-header #mobile-menu { - float: right; +#mobile-header .bottom-bar { + height: 3px; +} + +#mobile-editor-bar #mobile-menu { + float: left; } -#mobile-header #mobile-menu .menu-toggle { +#mobile-editor-bar #mobile-menu .menu-toggle { font-size: 34px; - padding: 10px 20px 10px 0; + padding: 10px 0 10px 10px; } -#mobile-header #mobile-menu .menu-toggle a { - color: #fff; +#mobile-editor-bar #mobile-menu .menu-toggle a { + color: #333333; outline: none; } -#mobile-header #mobile-menu-contents.hidden { +#mobile-editor-bar #mobile-menu-contents.hidden { display: none; } -#mobile-header #mobile-menu-contents ul { +#mobile-editor-bar #mobile-menu-contents ul { list-style: none; - padding-left: 20px; + padding-left: 0; + margin-bottom: 0; font-size: 20px; } -#mobile-header #mobile-menu-contents ul li { - padding: 5px 0 5px 0; +#mobile-editor-bar #mobile-menu-contents ul li { + padding: 20px 0 20px 20px; + border-bottom: 1px solid #dddddd; + background-color: #f0f0f0; } -#mobile-header #mobile-menu-contents ul li a { - color: #fff; +#mobile-editor-bar #mobile-menu-contents ul li a { + color: #64338f; } -#mobile-header .bottom-bar { - height: 3px; +#mobile-editor-bar #mobile-menu-contents ul li a i { + padding-left: 10px; +} +#mobile-editor-bar .btn-save-run { + float: right; +} +#mobile-editor-bar .file-path { + float: left; } -@media (min-width: 767px) { +@media (min-width: 768px) { #mobile-header { display: none !important; } + + #mobile-editor-bar { + display: none !important; + } } #landing-page .content h1 { font-weight: 400; @@ -690,12 +731,15 @@ fieldset legend { text-decoration: underline; } -#editor-page #btn-save-run { - float: right; +#editor-page .btn-save-run { + margin-right: 10px; } #editor-page .editor-container { background: #333; } +#editor-page .editor-container .cm-editor { + height: calc(100vh - 185px); +} #serial-page .terminal-container { background: #333; @@ -703,9 +747,18 @@ fieldset legend { #serial-page #terminal { position: relative; width: 100%; - height: calc(100vh - 215px); + height: calc(100vh - 185px); } +@media (min-width: 768px) { + #serial-page #terminal { + height: calc(100vh - 215px); + } + + #editor-page .editor-container .cm-editor { + height: calc(100vh - 215px); + } +} .mode-landing #editor-page { display: none; } @@ -755,10 +808,10 @@ fieldset legend { } .popup-modal { - height: 365px; - width: 650px; + max-height: 365px; + max-width: 650px; background-color: #fff; - border: 2px solid #652f8f; + border: 2px solid #64338f; border-radius: 5px; position: absolute; left: 50%; @@ -769,10 +822,12 @@ fieldset legend { pointer-events: none; transition: all 300ms ease-in-out; z-index: 1011; + display: none; } .popup-modal.is--visible { opacity: 1; pointer-events: auto; + display: block; } .popup-modal__close { position: absolute; @@ -828,4 +883,50 @@ fieldset legend { padding: 5px; } +.cm-editor { + color: #ddd; + background-color: #333; + line-height: 1.5; + font-family: "Operator Mono", "Source Code Pro", Menlo, Monaco, Consolas, Courier New, monospace; +} +.cm-editor .cm-activeLine { + background-color: #333; +} +.cm-editor .cm-content { + caret-color: orange; +} +.cm-editor .cm-comment { + font-style: italic; + color: #676B79; +} +.cm-editor .cm-operator { + color: #f3f3f3; +} +.cm-editor .cm-string { + color: #19F9D8; +} +.cm-editor .cm-string-2 { + color: #FFB86C; +} +.cm-editor .cm-tag { + color: #ff2c6d; +} +.cm-editor .cm-meta { + color: #b084eb; +} +.cm-editor.cm-focused .cm-cursor { + border-left-color: orange; +} +.cm-editor.cm-focused .cm-selectionBackground, .cm-editor ::selection { + background-color: orange; +} +.cm-editor .cm-gutters { + background-color: #292a2b; + color: #ddd; + border: none; +} +.cm-editor .cm-scroller { + overflow: auto; +} + /*# sourceMappingURL=style.css.map */ diff --git a/assets/css/style.css.map b/assets/css/style.css.map index 2699f70..3c38117 100644 --- a/assets/css/style.css.map +++ b/assets/css/style.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["../sass/vendors/_normalize.scss","../sass/base/_typography.scss","../sass/base/_base.scss","../sass/base/_variables.scss","../sass/layout/_grid.scss","../sass/layout/_header.scss","../sass/base/_mixins.scss","../sass/layout/_header_mobile.scss","../sass/pages/_code.scss"],"names":[],"mappings":"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EACA;EACA;;;AAMF;EACE;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;;AAEA;ECrFA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;ADgFJ;EACE;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;;AAKN;EACE;;;AAGF;EACE;IACE;;;AE3HJ;EACE;AAMA;;AAJA;EACE;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAEA;EACE;EACA;;AAEA;EACE;EACA;;AAMJ;EACE;;AAGF;EACE;EACA;EACA;;AAEA;EACE;;AAEA;EACE;;AAMR;EACE;;;AAIJ;EACE;IACE;;;AC9DA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AACA;EACE;;AAGJ;EACE;EACA;;;AAMF;EACI;;AAGJ;EACI;;;AAKJ;EACI;;AAEJ;EACI;EACA;EACA;;;AAKJ;EACI;;AAEJ;EACI;;AAEJ;EACI;;;AAKJ;EACI;;AAEJ;EACI;;;AAKJ;EACI;;AAEJ;EACI;;;AAIR;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AACA;EACI;EACA;EACA;;AACA;EACI;EACA;;AAEJ;EACI;;AAEJ;EACI,kBLnKD;;AKwKX;EACI;EACA;EACA;;AACA;EACI;;AAEJ;EACI;EACA;EACA;EACA","file":"style.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["../sass/vendors/_normalize.scss","../sass/base/_typography.scss","../sass/base/_base.scss","../sass/base/_variables.scss","../sass/layout/_grid.scss","../sass/layout/_header.scss","../sass/base/_mixins.scss","../sass/layout/_header_mobile.scss","../sass/pages/_code.scss","../sass/pages/_editor.scss"],"names":[],"mappings":"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AAMV;EACE;EACA;EACA;EACA;;;AAGF;EACE;EACA;;AAEA;EACE;;;AAIJ;EACE;EACA;;AAEA;EClFA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;;AD6EJ;EACE;EACA;;AAEA;EACE;EACA;;AAEA;EACE;;;AAKN;EACE;;;AAGF;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACE;IACE;;;EAEF;IACE;;;AEzIJ;EACE;AAMA;;AAJA;EACE;;AAIF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;;AAKA;EACI;;AAEA;EACI;EACA;;AAEA;EACA;EACA;;AAMJ;EACI;;AAGJ;EACI;EACA;EACA;EACA;;AAEA;EACI;EACA;EACA;;AAEA;EACI,OJ5DX;;AI8DW;EACI;;AAOpB;EACI;;AAGJ;EACI;;;AAIR;EACE;IACE;;;EAGF;IACE;;;ACnFA;EACE;;AAGF;EACE;;AAGF;EACE;EACA;EACA;EACA;;AAGF;EACE;;AACA;EACE;;AAGJ;EACE;EACA;;;AAMF;EACI;;AAGJ;EACI;;AAEA;EACI,QLhCa;;;AKsCrB;EACI;;AAEJ;EACI;EACA;EACA,QL5CiB;;;AKgDzB;EAEQ;IACI,QLpDM;;;EK0DN;IACI,QL3DE;;;AKkEd;EACI;;AAEJ;EACI;;AAEJ;EACI;;;AAKJ;EACI;;AAEJ;EACI;;;AAKJ;EACI;;AAEJ;EACI;;;AAIR;EACI;EACA;EACA;;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AAIJ;EACE;;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;AAGF;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;;AACA;EACI;EACA;EACA;;AACA;EACI;EACA;;AAEJ;EACI;;AAEJ;EACI,kBLzLD;;AK8LX;EACI;EACA;EACA;;AACA;EACI;;AAEJ;EACI;EACA;EACA;EACA;;;AC1MZ;EACE;EACA;EACA;EACA;;AAEA;EACI;;AAEJ;EACI;;AAEJ;EACI;EACA;;AAEJ;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAEJ;EACI;;AAEJ;EACI;EACA;EACA;;AAEJ;EACI","file":"style.css"} \ No newline at end of file diff --git a/assets/js/file_dialog.js b/assets/js/file_dialog.js index 2cc734b..86ff513 100644 --- a/assets/js/file_dialog.js +++ b/assets/js/file_dialog.js @@ -142,6 +142,7 @@ class FileDialog { async _openFolder(path) { const fileList = this._currentModal.querySelector("#file-list"); const okButton = this._currentModal.querySelector("button.ok-button"); + const fileName = this._currentModal.querySelector("#filename"); this._removeAllChildNodes(fileList); if (path !== undefined) { this._currentPath = path; @@ -167,6 +168,7 @@ class FileDialog { } catch(e) { console.log(e); } + fileName.value = ""; okButton.disabled = true; } @@ -218,26 +220,31 @@ class FileDialog { async _openItem(item) { const fileNameField = this._currentModal.querySelector("#filename"); + const fileList = this._currentModal.querySelector("#file-list"); let filetype, filename; + let selectedItem = null; + + // Loop through items and see if any have data-selected + for (let listItem of fileList.childNodes) { + if ((/true/i).test(listItem.getAttribute("data-selected"))) { + selectedItem = listItem; + } + } if (item !== undefined) { filetype = item.getAttribute("data-type"); filename = item.querySelector("span").innerHTML; } else if (this._validFilename(fileNameField.value)) { - filename = fileNameField.value; - filetype = "text"; - } else { - // Loop through items and see if any have data-selected - const fileList = this._currentModal.querySelector("#file-list"); - for (let listItem of fileList.childNodes) { - if ((/true/i).test(listItem.getAttribute("data-selected"))) { - item = listItem; - } - } - if (item !== undefined) { - filetype = item.getAttribute("data-type"); - filename = item.querySelector("span").innerHTML; + if (selectedItem !== null && fileNameField.value != selectedItem.querySelector("span").innerHTML) { + filetype = selectedItem.getAttribute("data-type"); + filename = selectedItem.querySelector("span").innerHTML; + } else { + filename = fileNameField.value; + filetype = "text"; } + } else if (selectedItem !== null) { + filetype = selectedItem.getAttribute("data-type"); + filename = selectedItem.querySelector("span").innerHTML; } if (filename !== undefined && filetype !== undefined) { diff --git a/assets/js/header_mobile.js b/assets/js/header_mobile.js new file mode 100644 index 0000000..ae2dd9f --- /dev/null +++ b/assets/js/header_mobile.js @@ -0,0 +1,21 @@ +document.addEventListener('DOMContentLoaded', function() { + document.getElementById('mobile-menu-button').addEventListener('click', handleMobileToggle); + document.querySelectorAll('#mobile-menu-contents li a').forEach((element) => { + element.addEventListener('click', handleMobileToggle); + }); +}); + +function handleMobileToggle(event) { + event.preventDefault(); + + var menuContainer = document.getElementById('mobile-menu-contents'); + + menuContainer.classList.toggle('hidden'); + + var menuIcon = document.querySelector('#mobile-menu-button > i'); + if (menuContainer.classList.contains('hidden')) { + menuIcon.classList.replace('fa-times', 'fa-bars'); + } else { + menuIcon.classList.replace('fa-bars', 'fa-times'); + } +} diff --git a/assets/js/script.js b/assets/js/script.js index fc510c8..e920adf 100644 --- a/assets/js/script.js +++ b/assets/js/script.js @@ -22,65 +22,23 @@ let request_serial = document.querySelector('#requestSerialDevice'); const btnModeEditor = document.getElementById('btn-mode-editor'); const btnModeSerial = document.getElementById('btn-mode-serial'); +const btnRestart = document.getElementById('btn-restart'); const mainContent = document.getElementById('main-content'); -const btnNew = document.getElementById('btn-new'); -const btnOpen = document.getElementById('btn-open'); -const btnSaveAs = document.getElementById('btn-save-as'); -const btnSaveRun = document.getElementById('btn-save-run'); + +const btnNew = document.querySelectorAll('a.btn-new'); +const btnOpen = document.querySelectorAll('a.btn-open'); +const btnSaveAs = document.querySelectorAll('a.btn-save-as'); +const btnSaveRun = document.querySelectorAll('a.btn-save-run'); const MODE_EDITOR = 1; const MODE_SERIAL = 2; const MODE_LANDING = 3; +const CHAR_CTRL_C = '\x03'; +const CHAR_CTRL_D = '\x04'; +const CHAR_ENTER = '\x0a\x0d'; const fileDialog = new FileDialog("files", ".body-blackout"); -const editorTheme = EditorView.theme({ - "&": { - color: "#ddd", - backgroundColor: "#333", - lineHeight: 1.5, - fontFamily: "'Operator Mono', 'Source Code Pro', Menlo, Monaco, Consolas, Courier New, monospace", - height: "calc(100vh - 215px)", - }, - ".cm-activeLine": { - backgroundColor: "#333", - }, - ".cm-content": { - caretColor: "orange" - }, - ".cm-comment": { - fontStyle: "italic", - color: "#676B79" - }, - ".cm-operator": { - color: "#f3f3f3" - }, - ".cm-string": { - color: "#19F9D8" - }, - ".cm-string-2": { - color: "#FFB86C" - }, - ".cm-tag": { - color: "#ff2c6d" - }, - ".cm-meta": { - color: "#b084eb" - }, - "&.cm-focused .cm-cursor": { - borderLeftColor: "orange" - }, - "&.cm-focused .cm-selectionBackground, ::selection": { - backgroundColor: "orange" - }, - ".cm-gutters": { - backgroundColor: "#292a2b", - color: "#ddd", - border: "none" - }, - ".cm-scroller": { - overflow: "auto" - } -}, {dark: true}) +const editorTheme = EditorView.theme({}, {dark: true}) const editorExtensions = [ basicSetup, @@ -88,50 +46,66 @@ const editorExtensions = [ editorTheme, EditorView.updateListener.of(onTextChange) ] -// New Button -btnNew.addEventListener('click', async function(e) { - if (await checkSaved()) { - loadEditorContents(""); - unchanged = editor.state.doc.length; - currentFilename = null; - console.log("Current File Changed to: " + currentFilename); - } - e.preventDefault(); - e.stopPropagation(); +// New Buttons +btnNew.forEach((element) => { + element.addEventListener('click', async function(e) { + if (await checkSaved()) { + loadEditorContents(""); + unchanged = editor.state.doc.length; + setFilename(null); + console.log("Current File Changed to: " + currentFilename); + } + e.preventDefault(); + e.stopPropagation(); + }); +}); + +// Open Buttons +btnOpen.forEach((element) => { + element.addEventListener('click', async function(e) { + if (await checkSaved()) { + let path = await fileDialog.open(client, FILE_DIALOG_OPEN); + if (path !== null) { + let contents = await client.readFile(path); + loadEditorContents(contents); + unchanged = editor.state.doc.length; + setFilename(path); + console.log("Current File Changed to: " + currentFilename); + } + } + e.preventDefault(); + e.stopPropagation(); + }); }); -// Open Button -btnOpen.addEventListener('click', async function(e) { - if (await checkSaved()) { - let path = await fileDialog.open(client, FILE_DIALOG_OPEN); +// Save As Buttons +btnSaveAs.forEach((element) => { + element.addEventListener('click', async function(e) { + let path = await saveAs(); if (path !== null) { - let contents = await client.readFile(path); - loadEditorContents(contents); - unchanged = editor.state.doc.length; - currentFilename = path; console.log("Current File Changed to: " + currentFilename); } - } - e.preventDefault(); - e.stopPropagation(); + e.preventDefault(); + e.stopPropagation(); + }); }); -// Save As Button -btnSaveAs.addEventListener('click', async function(e) { - let path = await saveAs(); - if (path !== null) { - currentFilename = path; - console.log("Current File Changed to: " + currentFilename); - } - e.preventDefault(); - e.stopPropagation(); +// Save + Run Buttons +btnSaveRun.forEach((element) => { + element.addEventListener('click', async function(e) { + await saveFile(); + await runCode(currentFilename); + e.preventDefault(); + e.stopPropagation(); + }); }); -// Save + Run Button -btnSaveRun.addEventListener('click', async function(e) { - await saveFile(); +// Restart Button +btnRestart.addEventListener('click', async function(e) { + // Send the Ctrl+D control character to the board via serial + await serialTransmit(CHAR_CTRL_D); e.preventDefault(); - e.stopPropagation(); + e.stopPropagation(); }); // Mode Buttons @@ -147,6 +121,15 @@ btnModeSerial.addEventListener('click', function(e) { e.stopPropagation(); }); +function setFilename(path) { + currentFilename = path; + if (path === null) { + path = "[New Document]"; + } + document.querySelector('#editor-bar .file-path').innerHTML = path; + document.querySelector('#mobile-editor-bar .file-path').innerHTML = path.split("/")[path.split("/").length - 1]; +} + // Use the editors functions to check if anything has changed function isDirty() { if (unchanged == editor.state.doc.length) return false; @@ -160,6 +143,27 @@ function loadEditorContents(content) { })); } +async function runCode(path) { + if (path == "/code.py") { + await serialTransmit(CHAR_CTRL_D); + } + + let extension = path.split('.').pop(); + if (extension === null) { + console.log("Extension not found"); + return false; + } + if (String(extension).toLowerCase() != "py") { + console.log("Extension not py, twas " + String(extension).toLowerCase()); + return false; + } + path = path.substr(1, path.length - 4); + path = path.replace(/\//g, "."); + + changeMode(MODE_SERIAL); + await serialTransmit(CHAR_CTRL_C + "import " + path + CHAR_ENTER); +} + async function checkSaved() { if (isDirty()) { if (window.confirm("Current changes will be lost. Click OK to continue.")) { @@ -172,21 +176,21 @@ async function checkSaved() { return true; } -async function saveFile(filename) { +async function saveFile(path) { const previousFile = currentFilename; - if (filename !== undefined) { + if (path !== undefined) { // All good, continue } else if (currentFilename !== null) { - filename = currentFilename; + path = currentFilename; } else { - filename = saveAs(); + path = saveAs(); } - if (filename !== null) { - if (filename !== previousFile) { + if (path !== null) { + if (path !== previousFile) { // This is a different file, so we write everything unchanged = 0; } - currentFilename = filename; + setFilename(path); await writeText(); return true; } @@ -286,9 +290,9 @@ async function debugLog(msg) { async function onBLESerialReceive(e) { // console.log("rcv", e.target.value.buffer); terminal.io.print(decoder.decode(e.target.value.buffer, {stream: true})); - } +} - async function serialTransmit(msg) { +async function serialTransmit(msg) { if (serialDevice && serialDevice.writable) { const encoder = new TextEncoder(); const writer = serialDevice.writable.getWriter(); @@ -363,7 +367,7 @@ async function switchToDevice(device) { console.log(services); console.log('Getting Transfer Service...'); - client = new FileTransferClient(bleDevice); + client = new FileTransferClient(bleDevice, 65536); debugLog("connected"); connectToBLESerial(); @@ -445,9 +449,10 @@ async function onBond() { console.log("bond"); await client.bond(); if (await fileExists("/code.py")) { - currentFilename = "/code.py"; + setFilename("/code.py"); var contents = await client.readFile(currentFilename); } else { + setFilename(null); contents = ""; } loadEditorContents(contents); diff --git a/assets/sass/base/_base.scss b/assets/sass/base/_base.scss index 173b497..6560746 100644 --- a/assets/sass/base/_base.scss +++ b/assets/sass/base/_base.scss @@ -3,7 +3,7 @@ html { } *, *:before, *:after { - box-sizing: inherit; + box-sizing: border-box; } html, body { @@ -54,6 +54,7 @@ button, padding-left: 10px; } cursor: pointer; + white-space: nowrap; } .purple-button-link.inverted, @@ -71,7 +72,7 @@ button:disabled, } button.purple-button-link { - width: 250px; + min-width: 250px; } fieldset { diff --git a/assets/sass/base/_variables.scss b/assets/sass/base/_variables.scss index 19e412f..e31900c 100644 --- a/assets/sass/base/_variables.scss +++ b/assets/sass/base/_variables.scss @@ -1,9 +1,12 @@ -$purple: #652f8f; +$purple: #64338f; $light-purple: #652f8f5d; $pink: #e90e8b; $gray: #999999; $gray-border: #cecece; +$terminal-height: calc(100vh - 215px); +$terminal-height-mobile: calc(100vh - 185px); + // derived from bootstrap variables // Extra small screen / phone diff --git a/assets/sass/layout/_grid.scss b/assets/sass/layout/_grid.scss index f75a0a7..c95e64f 100644 --- a/assets/sass/layout/_grid.scss +++ b/assets/sass/layout/_grid.scss @@ -1,13 +1,12 @@ .container { width: 100%; - max-width: $screen-xs; margin: 0 auto; } @media (min-width: 768px) { .container { max-width: $screen-sm; - } + } } @media (min-width: 992px) { @@ -26,17 +25,6 @@ padding: 20px 0 150px 0; background-color: #fff; - /*display: grid; - grid-template-columns: - [full-start] minmax(1em, 1fr) - [main-start] minmax(0, 80em) [main-end] - minmax(1em, 1fr) [full-end]; - grid-row-gap: 1em; - - &> * { - grid-column: main; - }*/ - .step { display: flex; .step-number { @@ -61,3 +49,25 @@ padding: 40px; } } + +@media (max-width: $screen-xs-max) { + .common-layout { + .step { + .step-number { + width: 50px; + height: 50px; + color: #333; + font-size: 36px; + font-weight: 600; + line-height: 36px; + margin: 20px 20px 0 0; + border: solid 5px #333; + min-width: 50px; + } + } + + &.content { + padding: 20px; + } + } +} diff --git a/assets/sass/layout/_header.scss b/assets/sass/layout/_header.scss index e585232..fe6bca3 100644 --- a/assets/sass/layout/_header.scss +++ b/assets/sass/layout/_header.scss @@ -80,9 +80,6 @@ align-items: flex-end; } -.site-logo { -} - .site-banner { font-size: 20px; padding-left: 120px; @@ -119,8 +116,25 @@ background-color: #e71c8c; } +.file-path { + font-size: 20px; + line-height: 59px; + margin-left: 10px; + display: inline; + flex: auto; + overflow: hidden; + text-overflow: ellipsis; +} + +#editor-bar { + display: flex; +} + @media (max-width: $screen-xs-max) { #site-header { display: none !important; } + #editor-bar { + display: none !important; + } } diff --git a/assets/sass/layout/_header_mobile.scss b/assets/sass/layout/_header_mobile.scss index 891a9b0..401ade2 100644 --- a/assets/sass/layout/_header_mobile.scss +++ b/assets/sass/layout/_header_mobile.scss @@ -21,48 +21,69 @@ float: left; } - #mobile-menu { - float: right; + .bottom-bar { + height: 3px; + } +} - .menu-toggle { - font-size: 34px; - padding: 10px 20px 10px 0; +#mobile-editor-bar { + #mobile-menu { + float: left; - a { - color: #fff; - outline: none; - } - } - } + .menu-toggle { + font-size: 34px; + padding: 10px 0 10px 10px; - #mobile-menu-contents { - &.hidden { - display: none; + a { + color: #333333; + outline: none; + } + } } - ul { - list-style: none; - padding-left: 20px; - font-size: 20px; + #mobile-menu-contents { + &.hidden { + display: none; + } + + ul { + list-style: none; + padding-left: 0; + margin-bottom: 0; + font-size: 20px; + + li { + padding: 20px 0 20px 20px; + border-bottom: 1px solid #dddddd; + background-color: #f0f0f0; - li { - padding: 5px 0 5px 0; + a { + color: $purple; - a { - color: #fff; + i { + padding-left: 10px; + } + } + } } - } } - } - .bottom-bar { - height: 3px; - } + .btn-save-run { + float: right; + } + + .file-path { + float: left; + } } -@media (min-width: $screen-xs-max) { +@media (min-width: $screen-sm) { #mobile-header { display: none !important; } + + #mobile-editor-bar { + display: none !important; + } } diff --git a/assets/sass/main.scss b/assets/sass/main.scss index b3bac34..c9a7a0b 100644 --- a/assets/sass/main.scss +++ b/assets/sass/main.scss @@ -12,3 +12,4 @@ @import './layout/header_mobile'; @import './pages/code'; +@import './pages/editor'; diff --git a/assets/sass/pages/_code.scss b/assets/sass/pages/_code.scss index 5ff5172..7cca0c4 100644 --- a/assets/sass/pages/_code.scss +++ b/assets/sass/pages/_code.scss @@ -29,12 +29,16 @@ } #editor-page { - #btn-save-run { - float: right; + .btn-save-run { + margin-right: 10px; } .editor-container { background: #333; + + .cm-editor { + height: $terminal-height-mobile; + } } } @@ -45,7 +49,23 @@ #terminal { position:relative; width:100%; - height: calc(100vh - 215px); + height: $terminal-height-mobile; + } +} + +@media (min-width: $screen-sm) { + #serial-page { + #terminal { + height: $terminal-height; + } + } + + #editor-page { + .editor-container { + .cm-editor { + height: $terminal-height; + } + } } } @@ -105,8 +125,8 @@ } .popup-modal { - height: 365px; - width: 650px; + max-height: 365px; + max-width: 650px; background-color: #fff; border: 2px solid $purple; border-radius: 5px; @@ -119,10 +139,12 @@ pointer-events: none; transition: all 300ms ease-in-out; z-index: 1011; + display: none; &.is--visible { opacity: 1; pointer-events: auto; + display: block; } &__close { diff --git a/assets/sass/pages/_editor.scss b/assets/sass/pages/_editor.scss new file mode 100644 index 0000000..a59879f --- /dev/null +++ b/assets/sass/pages/_editor.scss @@ -0,0 +1,46 @@ +.cm-editor { + color: #ddd; + background-color: #333; + line-height: 1.5; + font-family: 'Operator Mono', 'Source Code Pro', Menlo, Monaco, Consolas, Courier New, monospace; + + .cm-activeLine { + background-color: #333; + } + .cm-content { + caret-color: orange; + } + .cm-comment { + font-style: italic; + color: #676B79; + } + .cm-operator { + color: #f3f3f3; + } + .cm-string { + color: #19F9D8; + } + .cm-string-2 { + color: #FFB86C; + } + .cm-tag { + color: #ff2c6d; + } + .cm-meta { + color: #b084eb; + } + &.cm-focused .cm-cursor { + border-left-color: orange; + } + &.cm-focused .cm-selectionBackground, ::selection { + background-color: orange; + } + .cm-gutters { + background-color: #292a2b; + color: #ddd; + border: none; + } + .cm-scroller { + overflow: auto; + } +} \ No newline at end of file diff --git a/index.html b/index.html index 97bc80a..b239aee 100644 --- a/index.html +++ b/index.html @@ -34,36 +34,17 @@
- -
@@ -89,13 +70,6 @@

Set Up Web Bluetooth

chrome://flags/#enable-web-bluetooth-new-permissions-backend

-
@@ -135,10 +109,34 @@

Bond Device

- New - Open - Save As - Save + Run +
+ +
+ Save + Run +
+ +
+
+ New + Open + Save As +
+ Save + Run +
@@ -150,7 +148,7 @@

Bond Device

@@ -184,6 +182,7 @@

Bond Device

+ \ No newline at end of file diff --git a/package.json b/package.json index 6056b70..48cd36f 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "snowpack": "^3.7.1" }, "dependencies": { - "@adafruit/ble-file-transfer": "^0.9.1", + "@adafruit/ble-file-transfer": "^1.0.0", "@codemirror/basic-setup": "^0.18.2", "@codemirror/lang-python": "^0.18.0", "@snowpack/plugin-run-script": "^2.3.0",