share modal behaviur; add route run; codeService

This commit is contained in:
2022-11-24 10:31:27 +01:00
parent 38be5e93c9
commit 52f49c8a95
10 changed files with 133 additions and 58 deletions

View File

@@ -1,11 +1,11 @@
/* eslint-env node */
module.exports = {
root: true,
'extends': [
extends: [
'plugin:vue/vue3-essential',
'eslint:recommended'
'eslint:recommended',
],
parserOptions: {
ecmaVersion: 'latest'
ecmaVersion: 'latest',
}
}

34
package-lock.json generated
View File

@@ -12,10 +12,12 @@
"@codemirror/theme-one-dark": "^6.1.0",
"@gkucmierz/utils": "^1.12.1",
"codemirror": "^6.0.1",
"copy-to-clipboard": "^3.3.3",
"eventemitter3": "^4.0.7",
"javascript-stringify": "^2.1.0",
"meriyah": "^4.3.3",
"normalize.css": "^8.0.1",
"primeicons": "^6.0.1",
"primevue": "^3.18.0",
"vue": "^3.2.41",
"vue-codemirror": "^6.1.1",
@@ -2892,6 +2894,14 @@
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
"dev": true
},
"node_modules/copy-to-clipboard": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz",
"integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==",
"dependencies": {
"toggle-selection": "^1.0.6"
}
},
"node_modules/core-js-compat": {
"version": "3.26.1",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz",
@@ -4703,8 +4713,7 @@
"node_modules/primeicons": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/primeicons/-/primeicons-6.0.1.tgz",
"integrity": "sha512-KDeO94CbWI4pKsPnYpA1FPjo79EsY9I+M8ywoPBSf9XMXoe/0crjbUK7jcQEDHuc0ZMRIZsxH3TYLv4TUtHmAA==",
"peer": true
"integrity": "sha512-KDeO94CbWI4pKsPnYpA1FPjo79EsY9I+M8ywoPBSf9XMXoe/0crjbUK7jcQEDHuc0ZMRIZsxH3TYLv4TUtHmAA=="
},
"node_modules/primevue": {
"version": "3.18.0",
@@ -5475,6 +5484,11 @@
"node": ">=8.0"
}
},
"node_modules/toggle-selection": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
"integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ=="
},
"node_modules/tr46": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
@@ -8412,6 +8426,14 @@
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
"dev": true
},
"copy-to-clipboard": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz",
"integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==",
"requires": {
"toggle-selection": "^1.0.6"
}
},
"core-js-compat": {
"version": "3.26.1",
"resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.26.1.tgz",
@@ -9738,8 +9760,7 @@
"primeicons": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/primeicons/-/primeicons-6.0.1.tgz",
"integrity": "sha512-KDeO94CbWI4pKsPnYpA1FPjo79EsY9I+M8ywoPBSf9XMXoe/0crjbUK7jcQEDHuc0ZMRIZsxH3TYLv4TUtHmAA==",
"peer": true
"integrity": "sha512-KDeO94CbWI4pKsPnYpA1FPjo79EsY9I+M8ywoPBSf9XMXoe/0crjbUK7jcQEDHuc0ZMRIZsxH3TYLv4TUtHmAA=="
},
"primevue": {
"version": "3.18.0",
@@ -10252,6 +10273,11 @@
"is-number": "^7.0.0"
}
},
"toggle-selection": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz",
"integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ=="
},
"tr46": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",

View File

@@ -13,10 +13,12 @@
"@codemirror/theme-one-dark": "^6.1.0",
"@gkucmierz/utils": "^1.12.1",
"codemirror": "^6.0.1",
"copy-to-clipboard": "^3.3.3",
"eventemitter3": "^4.0.7",
"javascript-stringify": "^2.1.0",
"meriyah": "^4.3.3",
"normalize.css": "^8.0.1",
"primeicons": "^6.0.1",
"primevue": "^3.18.0",
"vue": "^3.2.41",
"vue-codemirror": "^6.1.1",

View File

@@ -1,4 +1,5 @@
export const APP_URL = 'https://instacode.app';
export const MAX_DATA_SIZE = 1e5;
export const ERROR_MAX_DATA_SIZE = 'Error: Output exceeded maximum size allowed';
export const WELCOME_CODE = `
@@ -17,3 +18,5 @@ for (let i = 0; i < 42; ++i) {
// storage unique keys:
export const STORAGE_KEY_CODE = 'code';
export const STORAGE_KEY_SETTINGS = 'settings';
export const SHARE_CODE_ROUTE_NAME = 'run';

View File

@@ -1,6 +1,7 @@
@import 'normalize.css';
// @import 'primeicons/primeicons.css';
@import 'primevue/resources/primevue.min.css';
@import 'primeicons/primeicons.css';
@import 'primevue/resources/themes/bootstrap4-dark-blue/theme.css';
// @import 'primevue/resources/themes/bootstrap4-light-blue/theme.css';

View File

@@ -5,11 +5,10 @@ import { Codemirror } from 'vue-codemirror'
import { javascript } from '@codemirror/lang-javascript'
import { oneDark } from '@codemirror/theme-one-dark'
import codeService from '../services/codeService';
export default defineComponent({
name: 'CodeEditor',
props: {
code: String,
},
components: {
Codemirror,
},
@@ -37,8 +36,14 @@ export default defineComponent({
return {
extensions,
handleReady,
code: codeService.get(),
}
},
methods: {
change(code) {
codeService.change(code);
},
}
});
</script>
@@ -59,7 +64,7 @@ export default defineComponent({
:tab-size="2"
:extensions="extensions"
@ready="handleReady"
@change="$emit('change', $event)"
@change="change($event)"
/>
</div>
</template>

View File

@@ -1,6 +1,14 @@
<script>
import { defineComponent } from 'vue';
import InputText from 'primevue/inputtext';
import PrimeButton from 'primevue/button';
import copy from 'copy-to-clipboard';
import { APP_URL, SHARE_CODE_ROUTE_NAME } from '../app.config';
import ModalWindow from './ModalWindow.vue';
import codeService from '../services/codeService';
export default defineComponent({
name: 'ShareModal',
@@ -9,39 +17,35 @@ export default defineComponent({
},
components: {
ModalWindow,
InputText,
PrimeButton,
},
data() {
return {
code: '',
};
},
methods: {
encode(code) {
return [APP_URL, SHARE_CODE_ROUTE_NAME, btoa(code)].join('/');
},
copy() {
copy(this.encode(this.code));
this.$emit('close');
},
},
watch: {
visible(visible) {
if (!visible) return;
this.code = codeService.get();
},
},
});
</script>
<style lang="scss" scoped>
ul {
list-style-type: none;
padding: 0;
li {
display: flex;
flex: 1 1 0px;
flex-wrap: nowrap;
* {
width: 50%;
}
b {
padding-right: 4px;
white-space: nowrap;
text-align: right;
}
span {
padding-left: 4px;
white-space: nowrap;
text-align: left;
}
}
}
b {
color: #8f8;
.p-inputgroup {
width: 320px;
}
</style>
@@ -52,7 +56,10 @@ b {
<h3>Share Code</h3>
</template>
<template #body>
<pre>Code goes here...</pre>
<div class="p-inputgroup">
<InputText :modelValue="encode(code)" readonly />
<PrimeButton icon="pi pi-copy" class="p-button-info" @click="copy()" />
</div>
</template>
<!-- <template #footer>
<button @click="showModal = false">close</button>

View File

@@ -2,6 +2,9 @@ import { createRouter, createWebHistory } from 'vue-router';
import HomeView from '../views/HomeView.vue';
import SettingsView from '../views/SettingsView.vue';
import codeService from '../services/codeService';
import { SHARE_CODE_ROUTE_NAME } from '../app.config';
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
@@ -15,6 +18,14 @@ const router = createRouter({
name: 'settings',
component: SettingsView,
},
{
path: `/${SHARE_CODE_ROUTE_NAME}/:encoded`,
name: SHARE_CODE_ROUTE_NAME,
redirect: to => {
codeService.setFromUrl(to.params.encoded);
return { name: 'home' };
},
},
{
path: '/about',
name: 'about',

View File

@@ -0,0 +1,35 @@
import {
WELCOME_CODE,
STORAGE_KEY_CODE,
} from '../app.config';
import EventEmitter from 'eventemitter3';
const ee = new EventEmitter();
let code;
const init = () => {
const lsCode = localStorage.getItem(STORAGE_KEY_CODE);
console.log('code', lsCode);
code = lsCode ? lsCode : WELCOME_CODE;
};
const codeService = {
get() {
return code;
},
change(_code) {
code = _code;
console.log('save', _code)
localStorage.setItem(STORAGE_KEY_CODE, code);
ee.emit('change', code);
},
setFromUrl(_encoded) {
this.change(atob(_encoded));
},
ee,
};
export default codeService;
init();

View File

@@ -1,9 +1,9 @@
<script>
import { WELCOME_CODE, STORAGE_KEY_CODE } from '../app.config';
import ResultCode from '../components/ResultCode.vue';
import CodeEditor from '../components/CodeEditor.vue';
import settingsService from '../services/settingsService';
import codeService from '../services/codeService';
import Worker from '../file.worker.js?worker';
@@ -20,28 +20,13 @@ export default defineComponent({
ResultCode, CodeEditor,
},
data() {
const lsCode = localStorage.getItem(STORAGE_KEY_CODE);
// const code = { value: lsCode ? lsCode : WELCOME_CODE };
const code = lsCode ? lsCode : WELCOME_CODE;
codeService.ee.on('change', code => this.run(code));
return {
code,
worker: null,
result: '',
}
},
mounted() {
// this.run(this.code.value);
this.run(this.code);
},
methods: {
save(code) {
localStorage.setItem(STORAGE_KEY_CODE, code);
},
change(code) {
this.run(code);
setTimeout(() => this.save(code), 1);
},
run(code) {
this.terminate();
this.result = '';
@@ -103,7 +88,7 @@ main {
<main>
<Splitter style="height: 100%" :step="50" :gutterSize="8" layout="horizontal">
<SplitterPanel class="left-pane">
<CodeEditor :code="code" @change="change($event)"/>
<CodeEditor/>
</SplitterPanel>
<SplitterPanel class="right-pane">
<ResultCode :data="result"/>