summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2021-02-06 21:36:47 +0900
committersyuilo <syuilotan@yahoo.co.jp>2021-02-06 21:36:47 +0900
commitb2fb92cf0fcf193e46b423b5a0cec8d8c3215c5d (patch)
tree97059e3e660e171edee6828a50c7b05427ae3bb8
parentImprove plugin setting (diff)
downloadsharkey-b2fb92cf0fcf193e46b423b5a0cec8d8c3215c5d.tar.gz
sharkey-b2fb92cf0fcf193e46b423b5a0cec8d8c3215c5d.tar.bz2
sharkey-b2fb92cf0fcf193e46b423b5a0cec8d8c3215c5d.zip
Add AiScript console widget
-rw-r--r--locales/ja-JP.yml1
-rw-r--r--src/client/widgets/aiscript.vue164
-rw-r--r--src/client/widgets/index.ts2
-rw-r--r--src/client/widgets/memo.vue12
4 files changed, 176 insertions, 3 deletions
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 2233fa27f1..3f8542dfd0 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -1067,6 +1067,7 @@ _widgets:
onlineUsers: "オンラインユーザー"
jobQueue: "ジョブキュー"
serverMetric: "サーバーメトリクス"
+ aiscript: "AiScriptコンソール"
_cw:
hide: "隠す"
diff --git a/src/client/widgets/aiscript.vue b/src/client/widgets/aiscript.vue
new file mode 100644
index 0000000000..4e788b4b4a
--- /dev/null
+++ b/src/client/widgets/aiscript.vue
@@ -0,0 +1,164 @@
+<template>
+<MkContainer :show-header="props.showHeader">
+ <template #header><Fa :icon="faTerminal"/>{{ $ts._widgets.aiscript }}</template>
+
+ <div class="uylguesu _monospace">
+ <textarea v-model="props.script" placeholder="(1 + 1)"></textarea>
+ <button @click="run" class="_buttonPrimary">RUN</button>
+ <div class="logs">
+ <div v-for="log in logs" class="log" :key="log.id" :class="{ print: log.print }">{{ log.text }}</div>
+ </div>
+ </div>
+</MkContainer>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue';
+import { faTerminal } from '@fortawesome/free-solid-svg-icons';
+import MkContainer from '@/components/ui/container.vue';
+import define from './define';
+import * as os from '@/os';
+import { AiScript, parse, utils } from '@syuilo/aiscript';
+import { createAiScriptEnv } from '@/scripts/aiscript/api';
+
+const widget = define({
+ name: 'aiscript',
+ props: () => ({
+ showHeader: {
+ type: 'boolean',
+ default: true,
+ },
+ script: {
+ type: 'string',
+ multiline: true,
+ default: '(1 + 1)',
+ hidden: true,
+ },
+ })
+});
+
+export default defineComponent({
+ extends: widget,
+ components: {
+ MkContainer
+ },
+
+ data() {
+ return {
+ logs: [],
+ faTerminal
+ };
+ },
+
+ methods: {
+ async run() {
+ this.logs = [];
+ const aiscript = new AiScript(createAiScriptEnv({
+ storageKey: 'widget'
+ }), {
+ in: (q) => {
+ return new Promise(ok => {
+ os.dialog({
+ title: q,
+ input: {}
+ }).then(({ canceled, result: a }) => {
+ ok(a);
+ });
+ });
+ },
+ out: (value) => {
+ this.logs.push({
+ id: Math.random(),
+ text: value.type === 'str' ? value.value : utils.valToString(value),
+ print: true
+ });
+ },
+ log: (type, params) => {
+ switch (type) {
+ case 'end': this.logs.push({
+ id: Math.random(),
+ text: utils.valToString(params.val, true),
+ print: false
+ }); break;
+ default: break;
+ }
+ }
+ });
+
+ let ast;
+ try {
+ ast = parse(this.props.script);
+ } catch (e) {
+ os.dialog({
+ type: 'error',
+ text: 'Syntax error :('
+ });
+ return;
+ }
+ try {
+ await aiscript.exec(ast);
+ } catch (e) {
+ os.dialog({
+ type: 'error',
+ text: e
+ });
+ }
+ },
+ }
+});
+</script>
+
+<style lang="scss" scoped>
+.uylguesu {
+ text-align: right;
+
+ > textarea {
+ display: block;
+ width: 100%;
+ max-width: 100%;
+ min-width: 100%;
+ padding: 16px;
+ color: var(--fg);
+ background: transparent;
+ border: none;
+ border-bottom: solid 1px var(--divider);
+ border-radius: 0;
+ box-sizing: border-box;
+ font: inherit;
+
+ &:focus {
+ outline: none;
+ }
+ }
+
+ > button {
+ display: inline-block;
+ margin: 8px;
+ padding: 0 10px;
+ height: 28px;
+ outline: none;
+ border-radius: 4px;
+
+ &:disabled {
+ opacity: 0.7;
+ cursor: default;
+ }
+ }
+
+ > .logs {
+ border-top: solid 1px var(--divider);
+ text-align: left;
+ padding: 16px;
+
+ &:empty {
+ display: none;
+ }
+
+ > .log {
+ &:not(.print) {
+ opacity: 0.7;
+ }
+ }
+ }
+}
+</style>
diff --git a/src/client/widgets/index.ts b/src/client/widgets/index.ts
index 0c7e824306..38cb85494a 100644
--- a/src/client/widgets/index.ts
+++ b/src/client/widgets/index.ts
@@ -18,6 +18,7 @@ export default function(app: App) {
app.component('MkwOnlineUsers', defineAsyncComponent(() => import('./online-users.vue')));
app.component('MkwJobQueue', defineAsyncComponent(() => import('./job-queue.vue')));
app.component('MkwButton', defineAsyncComponent(() => import('./button.vue')));
+ app.component('MkwAiscript', defineAsyncComponent(() => import('./aiscript.vue')));
}
export const widgets = [
@@ -38,4 +39,5 @@ export const widgets = [
'onlineUsers',
'jobQueue',
'button',
+ 'aiscript',
];
diff --git a/src/client/widgets/memo.vue b/src/client/widgets/memo.vue
index dab19cd16e..3512429e0d 100644
--- a/src/client/widgets/memo.vue
+++ b/src/client/widgets/memo.vue
@@ -74,12 +74,18 @@ export default defineComponent({
max-width: 100%;
min-width: 100%;
padding: 16px;
- color: var(--inputText);
- background: var(--face);
+ color: var(--fg);
+ background: transparent;
border: none;
- border-bottom: solid var(--lineWidth) var(--faceDivider);
+ border-bottom: solid 1px var(--divider);
border-radius: 0;
box-sizing: border-box;
+ font: inherit;
+ font-size: 0.9em;
+
+ &:focus {
+ outline: none;
+ }
}
> button {