share modal behaviur; add route run; codeService
This commit is contained in:
@@ -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
34
package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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',
|
||||
|
||||
35
src/services/codeService.mjs
Normal file
35
src/services/codeService.mjs
Normal 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();
|
||||
@@ -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"/>
|
||||
|
||||
Reference in New Issue
Block a user