diff --git a/main.js b/main.js
index e4a149f..7e4d32d 100644
--- a/main.js
+++ b/main.js
@@ -70,7 +70,9 @@ const defaultSettings = {
cors: true,
dirs: true,
index: true,
+ recent: [],
};
+const maxRecent = 10;
let settings;
try {
@@ -219,6 +221,7 @@ function startServer() {
expressApp.use(serveIndex(root, {
icons: true,
stylesheet: path.join(__dirname, "src", "listing.css"),
+ template: path.join(__dirname, "src", "listing.html"),
}));
}
expressApp.use(nonErrorLocalErrorHandler);
@@ -236,6 +239,7 @@ function startServer() {
saveSettings();
}
sendToWindow('started');
+ sendToWindow('settings', settings);
logToWindow("server started on port:", local ? "127.0.0.1:" : "::", port, "for path:", root);
});
server.on('close', serverClosed);
@@ -258,6 +262,13 @@ function stopServer() {
function saveSettings() {
try {
+ // remove root from recent
+ settings.recent = settings.recent.filter(v => v !== settings.root);
+ // add root to recent
+ settings.recent.unshift(settings.root);
+ // remove excess
+ settings.recent.splice(maxRecent, settings.length - maxRecent);
+
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2));
} catch (e) {
errorToWindow('ERROR: could not save settings:', e);
@@ -265,8 +276,17 @@ function saveSettings() {
}
function updateSettings(event, newSettings) {
- Object.assign(settings, newSettings);
- if (running) {
+ let changed = false;
+ // this is horrible but for now it works
+ for (const key of Object.keys(newSettings)) {
+ const newValue = newSettings[key];
+ const oldValue = settings[key];
+ if (!Array.isArray(oldValue) && oldValue !== newValue) {
+ changed = true;
+ settings[key] = newValue;
+ }
+ }
+ if (changed && running) {
startServer();
}
}
diff --git a/src/index.html b/src/index.html
index 4f21bc7..0330bab 100644
--- a/src/index.html
+++ b/src/index.html
@@ -10,6 +10,10 @@
A simple web server for local web development
diff --git a/src/index.js b/src/index.js
index 3733fd9..bd4dca0 100644
--- a/src/index.js
+++ b/src/index.js
@@ -103,19 +103,56 @@ ipcRenderer.on('stopped', () => {
ipcRenderer.send('getSettings');
function removeClass(elem, className) {
- const classNames = elem.className.split(" ");
- let ndx;
- while ((ndx = classNames.indexOf(className)) >= 0) {
- classNames.splice(ndx, 1);
- }
- elem.className = classNames.join(" ");
+ elem.classList.remove(className);
}
function addClass(elem, className) {
- const classNames = elem.className.split(" ");
- if (classNames.indexOf(className) < 0) {
- classNames.push(className);
- elem.className = classNames.join(" ");
+ elem.classList.add(className);
+}
+
+class Dropdown {
+ constructor(elem, callback) {
+ this.toggle = this.toggle.bind(this);
+ this.hide = this.hide.bind(this);
+ this.callback = callback;
+ this.elem = elem;
+ this.buttonElem = elem.querySelector('button');
+ this.contentElem = elem.querySelector('div');
+ this.buttonElem.addEventListener('click', this.toggle);
+ document.addEventListener('click', (e) => {
+ const isClickInside = this.buttonElem.contains(event.target);
+ if (!isClickInside) {
+ this.hide();
+ }
+ });
+ }
+ toggle() {
+ const style = this.contentElem.style;
+ const show = !!style.display;
+ style.display = show ? '' : 'block';
+ if (show) {
+ this.contentElem.focus();
+ }
+ }
+ hide() {
+ const style = this.contentElem.style;
+ const show = !!style.display;
+ if (show) {
+ this.toggle();
+ }
+ }
+ setOptions(options) {
+ this.contentElem.innerHTML = '';
+ options.forEach((option, ndx) => {
+ const div = document.createElement('div');
+ div.textContent = option;
+ div.addEventListener('click', () => {
+ this.hide();
+ this.callback(option);
+ });
+ this.contentElem.appendChild(div);
+ });
+ this.elem.style.display = options.length ? '' : 'none';
}
}
@@ -161,6 +198,20 @@ async function getFolderToServe() {
}
}
+const recent = new Dropdown($('#recent'), (newPath) => {
+ rootElem.value = newPath;
+ updateSettings();
+});
+
+settingsInfo.recent = {
+ set: settings => {
+ recent.setOptions(settings.recent);
+ },
+ get: settings => {
+ return settings.recent = settingsInfo.recent;
+ },
+};
+
browseRootElem.addEventListener('click', e => {
getFolderToServe();
});
diff --git a/src/listing.html b/src/listing.html
new file mode 100644
index 0000000..05b5d04
--- /dev/null
+++ b/src/listing.html
@@ -0,0 +1,82 @@
+
+
+
+
+
+ listing directory {directory}
+
+
+
+
+
+
+
~{linked-path}
+ {files}
+
+
+
\ No newline at end of file
diff --git a/src/style.css b/src/style.css
index 16fb339..9298a92 100644
--- a/src/style.css
+++ b/src/style.css
@@ -57,8 +57,38 @@ input {
.checkbox label {
order: 2;
}
+
+.icon {
+
+}
+.dropdown {
+ position: relative;
+ display: inline-block;
+}
+
+.dropdown>div {
+ display: none;
+ position: absolute;
+ right: 0;
+ background-color: #DDD;
+ color: black;
+ min-width: 250px;
+ z-index: 1;
+ border: 1px solid #444;
+}
+.dropdown>div>div {
+ padding: .1em;
+ white-space: pre;
+}
+.dropdown>div>div:nth-child(odd) {
+ background-color: #CCC;
+}
+.dropdown>div>div:hover {
+ background-color: #888;
+}
+
.buttons {
- padding-top: 1em;
+ padding-top: s1em;
}
.buttons button {
font-size: large;