diff --git a/.gitignore b/.gitignore
index 8e33e27..c680358 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
/*.log
/dist
/dist-zip
+Session.vim
diff --git a/src/common.scss b/src/common.scss
new file mode 100644
index 0000000..388ba73
--- /dev/null
+++ b/src/common.scss
@@ -0,0 +1,52 @@
+html,
+body {
+ font-size: 14px;
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Ubuntu, 'Helvetica Neue', sans-serif;
+}
+
+a,
+a:visited {
+ color: initial;
+ text-decoration: underline dotted #888;
+}
+
+a:hover {
+ opacity: 0.7;
+}
+
+h2 {
+ font-size: 1.2em;
+ margin-bottom: 0.75em;
+ padding-bottom: 0.75em;
+ border-bottom: 1px solid rgba(0, 0, 0, 0.1);
+}
+
+form {
+ input[type='text'] {
+ display: block;
+ margin-bottom: 0.5em;
+ border-radius: 1em;
+ padding: 0.4em;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+
+ &:hover {
+ border: 1px solid rgba(40, 235, 70, 0.3);
+ }
+
+ &:focus {
+ border: 1px solid rgba(40, 235, 70, 0.7);
+ }
+ }
+
+ .buttons {
+ margin-top: 0.5em;
+ padding-top: 0.5em;
+ border-top: 1px solid rgba(0, 0, 0, 0.15);
+
+ button {
+ margin-right: 0.3em;
+ }
+ }
+}
+
+// vim:sw=2:ts=2:et:
diff --git a/src/options/App.vue b/src/options/App.vue
index 846b927..6fdda5c 100644
--- a/src/options/App.vue
+++ b/src/options/App.vue
@@ -11,97 +11,12 @@
/>
-
-
-
-
Procedures stored on browser
-
-
-
-
Procedures stored on server
-
-
-
-
Run a command on {{ hosts[selectedHost].name }}
-
-
-
-
-
-
-
-
Edit device {{ hosts[selectedHost].name }}
-
-
-
-
- Select an option from the menu
-
+
+
+
+
+
+
Select an option from the menu
@@ -109,25 +24,29 @@
+
+
+
+
diff --git a/src/options/LocalCommands.vue b/src/options/LocalCommands.vue
new file mode 100644
index 0000000..5019b20
--- /dev/null
+++ b/src/options/LocalCommands.vue
@@ -0,0 +1,16 @@
+
+
+
Commands stored on the browser
+
+
+
+
+
+
diff --git a/src/options/NewHost.vue b/src/options/NewHost.vue
new file mode 100644
index 0000000..8e44277
--- /dev/null
+++ b/src/options/NewHost.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/options/RemoteCommands.vue b/src/options/RemoteCommands.vue
new file mode 100644
index 0000000..1cedae8
--- /dev/null
+++ b/src/options/RemoteCommands.vue
@@ -0,0 +1,16 @@
+
+
+
Procedures stored on the server
+
+
+
+
+
+
diff --git a/src/options/Run.vue b/src/options/Run.vue
new file mode 100644
index 0000000..3953230
--- /dev/null
+++ b/src/options/Run.vue
@@ -0,0 +1,159 @@
+
+
+
Run a command on {{ host.name }}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/options/options.js b/src/options/options.js
index fa15a1e..0cdd1e0 100644
--- a/src/options/options.js
+++ b/src/options/options.js
@@ -1,6 +1,7 @@
import Vue from 'vue';
import App from './App';
+require('../common.scss');
global.browser = require('webextension-polyfill');
/* eslint-disable no-new */
diff --git a/src/utils.js b/src/utils.js
index e3b078e..03da864 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -1,6 +1,13 @@
import axios from 'axios';
export default {
+ data() {
+ return {
+ loading: false,
+ hosts: [],
+ };
+ },
+
methods: {
notify(message, title) {
browser.notifications.create({
@@ -51,6 +58,55 @@ export default {
throw e;
}
},
+
+ async loadHosts() {
+ this.loading = true;
+
+ try {
+ const response = await browser.storage.local.get('hosts');
+ this.hosts = JSON.parse(response.hosts);
+ } finally {
+ this.loading = false;
+ }
+ },
+
+ async saveHosts() {
+ await browser.storage.local.set({ hosts: JSON.stringify(this.hosts) });
+ },
+
+ formToHost(form) {
+ return {
+ name: form.name.value,
+ address: form.address.value,
+ port: parseInt(form.port.value),
+ websocketPort: parseInt(form.websocketPort.value),
+ ssl: form.ssl.checked,
+ token: form.token.value,
+ };
+ },
+
+ onAddrChange(form) {
+ if (form.name.value.length && !form.address.value.startsWith(form.name.value)) {
+ return;
+ }
+
+ form.name.value = form.address.value;
+ },
+
+ onPortChange(form) {
+ const port = form.port.value;
+ if (!this.isPortValid(port)) return;
+ form.websocketPort.value = '' + (parseInt(port) + 1);
+ },
+
+ isPortValid(port) {
+ port = parseInt(port);
+ return !isNaN(port) && port > 0 && port < 65536;
+ },
+
+ isHostFormValid(form) {
+ return form.name.value.length && form.address.value.length && this.isPortValid(form.port.value) && this.isPortValid(form.websocketPort.value);
+ },
},
};