diff --git a/platypush/backend/http/webapp/src/components/elements/CopyButton.vue b/platypush/backend/http/webapp/src/components/elements/CopyButton.vue index f8f2609241..9878f67964 100644 --- a/platypush/backend/http/webapp/src/components/elements/CopyButton.vue +++ b/platypush/backend/http/webapp/src/components/elements/CopyButton.vue @@ -45,5 +45,6 @@ export default { padding: 0.5em; font-size: 1.5em; cursor: pointer; + z-index: 1; } diff --git a/platypush/backend/http/webapp/src/components/panels/Extensions/Install.vue b/platypush/backend/http/webapp/src/components/panels/Extensions/Install.vue index 3d92de3ccb..63d8415a8f 100644 --- a/platypush/backend/http/webapp/src/components/panels/Extensions/Install.vue +++ b/platypush/backend/http/webapp/src/components/panels/Extensions/Install.vue @@ -1,9 +1,43 @@ @@ -12,14 +46,18 @@ import 'highlight.js/lib/common' import 'highlight.js/styles/stackoverflow-dark.min.css' import hljs from "highlight.js" import CopyButton from "@/components/elements/CopyButton" +import Loading from "@/components/Loading" import Utils from "@/Utils" export default { name: "Install", mixins: [Utils], + emit: ['install-start', 'install-end'], components: { CopyButton, + Loading, }, + props: { extension: { type: Object, @@ -27,6 +65,14 @@ export default { }, }, + data() { + return { + installRunning: false, + installOutput: null, + pendingCommands: 0, + } + }, + computed: { installCmd() { const cmd = this.extension.deps.install_cmd.join('\n').trim() @@ -47,29 +93,142 @@ export default { ) }, }, + + methods: { + wsProcess(path) { + try { + const protocol = window.location.protocol === 'https:' ? 'wss' : 'ws' + const url = `${protocol}://${location.host}${path}` + const ws = new WebSocket(url) + + ws.onmessage = this.onMessage + ws.onerror = this.onError + ws.onclose = this.onClose + } catch (err) { + console.error('Websocket initialization error') // TODO notify + console.error(err) + return + } + }, + + onMessage(msg) { + if (!this.installOutput) + this.installOutput = '' + + this.installOutput += msg.data + }, + + onClose() { + this.installRunning = false + this.$emit('install-end', this.extension) + }, + + onError(error) { + console.error('Websocket error') // TODO notify + console.error(error) + }, + + installExtension() { + this.installRunning = true + this.installOutput = '' + this.$emit('install-start', this.extension) + + const cmd = (this.extension.deps.install_cmd || []).join(';\n') + this.request('shell.exec', { + cmd: cmd, + ws: true, + }).then((output) => { + this.wsProcess(output.ws_path) + }).catch((err) => { + console.error(err) // TODO notify + }) + }, + }, + + mounted() { + this.$watch('installOutput', () => { + this.$nextTick(() => { + this.$refs.installOutput.focus() + this.$refs.installOutput.scrollTop = this.$refs.installOutput.scrollHeight + }) + }) + }, } diff --git a/platypush/backend/http/webapp/src/components/panels/Extensions/common.scss b/platypush/backend/http/webapp/src/components/panels/Extensions/common.scss index 22073c1572..0e19d5934c 100644 --- a/platypush/backend/http/webapp/src/components/panels/Extensions/common.scss +++ b/platypush/backend/http/webapp/src/components/panels/Extensions/common.scss @@ -3,6 +3,7 @@ pre { margin: 0; background: $code-dark-bg; color: $code-dark-fg; + font-size: 0.9em; padding: 0.5em; overflow: auto; } diff --git a/platypush/backend/http/webapp/src/style/themes/light.scss b/platypush/backend/http/webapp/src/style/themes/light.scss index 11ec4f71e8..7e37f6d0f3 100644 --- a/platypush/backend/http/webapp/src/style/themes/light.scss +++ b/platypush/backend/http/webapp/src/style/themes/light.scss @@ -166,7 +166,7 @@ $scrollbar-thumb-bg: #a5a2a2 !default; $row-shadow: 0 0 1px 0.5px #cfcfcf !default; //// Code blocks -$code-dark-bg: #090909 !default; -$code-dark-fg: #f0f0f0 !default; +$code-dark-bg: rgb(11, 11, 13) !default; +$code-dark-fg: rgb(243, 243, 250) !default; $code-light-bg: #f2f0e9 !default; $code-light-fg: #090909 !default; diff --git a/platypush/backend/http/webapp/vue.config.js b/platypush/backend/http/webapp/vue.config.js index cc6aa45cbb..67b0a044a9 100644 --- a/platypush/backend/http/webapp/vue.config.js +++ b/platypush/backend/http/webapp/vue.config.js @@ -36,6 +36,7 @@ module.exports = { proxy: { '^/ws/events': wsProxy, '^/ws/requests': wsProxy, + '^/ws/shell': wsProxy, '^/execute': httpProxy, '^/auth': httpProxy, '^/camera/': httpProxy,