diff --git a/.github/workflows/default.yml b/.github/workflows/default.yml index bccc091..275e89d 100644 --- a/.github/workflows/default.yml +++ b/.github/workflows/default.yml @@ -29,12 +29,12 @@ jobs: restore-keys: | ${{ runner.os }}-node- - name: install dependencies - run: npm install + run: npm ci - name: build run: npm run build - name: package run: npm run package - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: truncated-cube-website path: website/truncated-website-build.tar.gz diff --git a/website/.env.online b/website/.env.online new file mode 100644 index 0000000..35c7162 --- /dev/null +++ b/website/.env.online @@ -0,0 +1 @@ +VITE_API_URL=https://lamp.mercotui.com/ diff --git a/website/.gitignore b/website/.gitignore index 11f5d71..f136aea 100644 --- a/website/.gitignore +++ b/website/.gitignore @@ -2,6 +2,8 @@ node_modules /dist +./*.tar.gz + # local env files .env.local .env.*.local diff --git a/website/package-lock.json b/website/package-lock.json index aaf8b6a..acc6074 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -15,6 +15,7 @@ "core-js": "^3.37.1", "lodash": "^4.17.21", "miragejs": "^0.2.0-alpha.3", + "monaco-editor": "^0.52.0", "roboto-fontface": "*", "utf8": "^3.0.0", "vue": "^3.4.31", @@ -3144,6 +3145,11 @@ "pretender": "^3.4.7" } }, + "node_modules/monaco-editor": { + "version": "0.52.0", + "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.52.0.tgz", + "integrity": "sha512-OeWhNpABLCeTqubfqLMXGsqf6OmPU6pHM85kF3dhy6kq5hnhuVS1p3VrEW/XhWHc71P2tHyS5JFySD8mgs1crw==" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", diff --git a/website/package.json b/website/package.json index da393f9..1e642cc 100644 --- a/website/package.json +++ b/website/package.json @@ -3,6 +3,7 @@ "version": "0.0.0", "scripts": { "dev": "vite", + "dev online": "vite -m online", "build": "vite build", "preview": "vite preview", "lint": "eslint . --fix --ignore-path .gitignore", @@ -22,6 +23,7 @@ "core-js": "^3.37.1", "lodash": "^4.17.21", "miragejs": "^0.2.0-alpha.3", + "monaco-editor": "^0.52.0", "roboto-fontface": "*", "utf8": "^3.0.0", "vue": "^3.4.31", diff --git a/website/src/components/CodeEditor.vue b/website/src/components/CodeEditor.vue index a12632f..29610f9 100644 --- a/website/src/components/CodeEditor.vue +++ b/website/src/components/CodeEditor.vue @@ -2,8 +2,8 @@ - - + + Enter Script Name @@ -20,13 +20,15 @@
Save Save As - Delete + Delete + Run in Emulator
- Delete {{script_name}} ? + Delete {{ script_name }} ? Cancel @@ -38,12 +40,8 @@ -
- -
- - - +
+
@@ -54,84 +52,91 @@ import axios from 'axios'; import base64 from 'base-64'; import utf8 from 'utf8'; - export default { - data() { - return { - save_overlay_opened: false, - delete_overlay_opened: false, - type: ["template"], - content: "Loading", - } - }, +import * as monaco from 'monaco-editor' +import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker' +import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker' + +export default { + editor: null, + + data() { + return { + save_overlay_opened: false, + delete_overlay_opened: false, + type: ["template"], + content: "Loading", + } + }, - computed: { - save_enabled: function () { - return !(this.type.includes("default") || this.type.includes("template") || this.script_name === "") - }, - delete_enabled: function () { - return !(this.type.includes("default") || this.type.includes("template")) - }, + computed: { + save_enabled: function () { + return !(this.type.includes("default") || this.type.includes("template") || this.script_name === "") }, + delete_enabled: function () { + return !(this.type.includes("default") || this.type.includes("template")) + }, + }, + + props: { + script_name: String + }, + + mounted() { + self.MonacoEnvironment = { + getWorker(_, label) { + if (label === 'typescript' || label === 'javascript') { + return new tsWorker() + } + return new editorWorker() + } + } + this.editor = monaco.editor.create(document.getElementById('monaco-container'), { + value: "Loading", + language: 'javascript', + theme: "vs-dark", + }); - props: { - script_name: String + if(this.script_name) { + axios.get('/api/scripts/' + this.script_name + '/').then(response => { + const bytes = base64.decode(response.data.script); + const decoded_script = utf8.decode(bytes); + this.editor.setValue(decoded_script); + this.type = response.data.type; + }); + } else { + this.editor.setValue(""); + } + }, + + methods: { + save: function () { + var bytes = utf8.encode(this.editor.getValue()); + var encoded_script = base64.encode(bytes); + + axios.put('/api/scripts/' + this.script_name + '/', { + name: this.script_name, + script: encoded_script, + type: this.type, + }); }, - components: { - editor: require('vue2-ace-editor'), + saveAs: function () { + this.save_overlay_opened = false; + this.type = ["animation"] + this.save(); + this.$router.push('/script/' + this.script_name); }, - mounted() { - axios.get('/api/scripts/' + this.script_name + '/').then(response => { - var bytes = base64.decode(response.data.script); - this.content = utf8.decode(bytes); - this.type = response.data.type - }) + deleteScript: function () { + axios.delete('/api/scripts/' + this.script_name + '/').then(() => { + this.$router.push('/'); + }); }, - methods: { - editorInit: function (editor) { - require('brace/ext/language_tools') //language extension prerequsite... - require('brace/mode/javascript') //language - require('brace/mode/less') - require('brace/theme/monokai') - require('brace/snippets/javascript') //snippet - editor.setOptions({ - maxLines: 30, - wrap: true, - enableBasicAutocompletion: true, - autoScrollEditorIntoView: true - }); - }, - - save: function () { - var bytes = utf8.encode(this.content); - var encoded_script = base64.encode(bytes); - - axios.put('/api/scripts/' + this.script_name + '/', { - name: this.script_name, - script: encoded_script, - type: this.type, - }); - }, - - saveAs: function () { - this.save_overlay_opened = false; - this.type = ["animation"] - this.save(); - this.$router.push('/scriptview/' + this.script_name); - }, - - deleteScript: function () { - axios.delete('/api/scripts/' + this.script_name + '/').then(() => { - this.$router.push('/'); - }); - }, - - runInEmulator: function () { - this.$emit('runInEmulator', this.content) - }, - } + runInEmulator: function () { + this.$emit('runInEmulator', this.editor.getValue()) + }, } +} diff --git a/website/src/main.js b/website/src/main.js index c2a3a0b..249759e 100644 --- a/website/src/main.js +++ b/website/src/main.js @@ -8,7 +8,8 @@ import App from './App.vue' import { createApp } from 'vue' import {makeServer} from "./mock-server" -if (process.env.NODE_ENV === "development") { +if (import.meta.env.DEV && import.meta.env.MODE !== "online") { + // If we are in development mode, and not using a proxy for our API calls, then start a mock API server makeServer() } diff --git a/website/src/plugins/router.js b/website/src/plugins/router.js index d0e0cfe..eab8f6a 100644 --- a/website/src/plugins/router.js +++ b/website/src/plugins/router.js @@ -9,7 +9,7 @@ import {createMemoryHistory, createRouter} from 'vue-router' // Views import IndexView from '../views/IndexView'; -// import ScriptView from '../views/ScriptView'; +import ScriptView from '../views/ScriptView'; import DrawView from '../views/DrawView'; const router = new createRouter({ @@ -18,8 +18,8 @@ const router = new createRouter({ {path: '/', component: IndexView}, {path: '/draw/', component: DrawView, props: true}, {path: '/draw/:name', component: DrawView, props: true}, - // {path: '/script/', component: ScriptView, props: true}, - // {path: '/script/:name', component: ScriptView, props: true}, + {path: '/script/', component: ScriptView, props: true}, + {path: '/script/:name', component: ScriptView, props: true}, ], }) diff --git a/website/src/views/IndexView.vue b/website/src/views/IndexView.vue index 68f6015..5f4eddd 100644 --- a/website/src/views/IndexView.vue +++ b/website/src/views/IndexView.vue @@ -4,7 +4,7 @@ Images - + Draw