diff --git a/src/code.py b/src/code.py
index b7598c0..fe7962b 100644
--- a/src/code.py
+++ b/src/code.py
@@ -9,11 +9,11 @@
import socketpool
import wifi
from adafruit_httpserver import POST, FileResponse, Request, Server
+from ducky import run_boot_script
from api import handle
-
-async def main():
+async def setup_server():
"""
Begin a wifi access point defined by the SSID and PASSWORD environment
variables.
@@ -44,6 +44,17 @@ def api(request: Request):
server.serve_forever(str(wifi.radio.ipv4_address_ap))
+async def main():
+ """
+ Asynchronously run the boot script while setting
+ the server up for the web interface.
+ """
+ await asyncio.gather(
+ run_boot_script(),
+ setup_server()
+ )
+
+
if __name__ == "__main__":
try:
asyncio.run(main())
diff --git a/src/ducky.py b/src/ducky.py
index 9babdac..65c31b2 100644
--- a/src/ducky.py
+++ b/src/ducky.py
@@ -118,3 +118,15 @@ def run_script_file(path: str):
run_script(handle.read())
except OSError as error:
warn(f"unable to open file {path}: {error}")
+
+
+async def run_boot_script():
+ """
+ If a script with the name 'boot.dd' exists,
+ run it without user interaction on boot.
+ """
+ try:
+ with open("payloads/boot.dd", "r", encoding="utf-8") as handle:
+ run_script(handle.read())
+ except OSError:
+ info("boot script does not exist, skipping its execution")
diff --git a/src/static/index.html b/src/static/index.html
index 6d4d00b..9de3f6d 100644
--- a/src/static/index.html
+++ b/src/static/index.html
@@ -11,7 +11,7 @@
-
diff --git a/src/static/main.css b/src/static/main.css
index 40a87bd..7b6e9c5 100644
--- a/src/static/main.css
+++ b/src/static/main.css
@@ -13,8 +13,9 @@ body {
}
.container {
- height: calc(70vh);
+ height: 70vh;
display: flex;
+ overflow: hidden;
flex-direction: row;
}
@@ -44,8 +45,9 @@ body {
background: #111;
display: flex;
flex-direction: column;
- width: 25vw;
+ width: 0;
overflow: scroll;
+ flex-shrink: 0;
}
.entry {
@@ -90,23 +92,36 @@ body {
.editorarea {
display: flex;
flex-direction: column;
- width: 100%;
+ flex: 1;
}
-.editorarea > .title {
- padding: 0.5rem 1rem;
+.editorarea > .title-bar {
color: #888;
background: #222;
outline: none;
- border: none;
border-bottom: #444 solid 0.1rem;
+ display: flex;
+ flex-direction: row;
+}
+
+.editorarea > .title-bar > .title {
+ outline: none;
+ border: none;
+ background: #222;
+ flex-grow: 1;
+ padding: 0.5rem 1rem;
+}
+
+.editorarea > .title-bar > .title-btn {
+ border: none;
+ background: #222;
+ padding: 0 0.4rem 0 0.4rem;
}
.editor {
background: #222;
border: none;
resize: none;
- min-width: max-content;
height: calc(70vh - 3rem);
padding: 0.5rem;
}
@@ -136,3 +151,9 @@ body {
.editor:focus {
outline: none;
}
+
+@media screen and (orientation: portrait) {
+ .show {
+ width: calc(100vw - 3rem);
+ }
+}
\ No newline at end of file
diff --git a/src/static/script.js b/src/static/script.js
index 504b135..b818b35 100644
--- a/src/static/script.js
+++ b/src/static/script.js
@@ -11,7 +11,8 @@ const logs = document.querySelector('.logs')
const documents_icon = document.querySelector('.documents')
const run_icon = document.querySelector('.run')
const add_icon = document.querySelector('.add')
-const title = document.querySelector('.editorarea > .title')
+const title = document.querySelector('.editorarea > .title-bar > .title')
+const title_button = document.querySelector('.editorarea > .title-bar > .title-btn')
let timer
function doApi(message) {
@@ -67,10 +68,15 @@ function reload_listing() {
})
}
+function create_file() {
+ title.readOnly = true
+ doApi({"action": "create", "filename": title.value})
+}
+
+title_button.addEventListener('click', create_file);
title.addEventListener('keypress', (e) => {
if (e.keyCode==13) {
- title.readOnly = true
- doApi({"action": "create", "filename": title.value})
+ create_file()
}
})
@@ -82,14 +88,8 @@ add_icon.addEventListener('click', () => {
})
documents_icon.addEventListener('click', () => {
- const classList = files.classList
- if (classList.contains("show")) {
- files.classList.replace('show', 'hide')
- } else if (classList.contains("hide")) {
- files.classList.replace('hide', 'show')
- } else {
- files.classList.add('hide')
- }
+ files.classList.toggle("show");
+ files.classList.toggle("hide");
});
run_icon.addEventListener('click', () => {