iceshrimp-161sh/packages/client/src/widgets/aiscript.vue

163 lines
2.9 KiB
Vue
Raw Normal View History

2021-02-06 13:36:47 +01:00
<template>
<MkContainer :show-header="props.showHeader">
<template #header><i class="fas fa-terminal"></i>{{ $ts._widgets.aiscript }}</template>
2021-02-06 13:36:47 +01:00
<div class="uylguesu _monospace">
<textarea v-model="props.script" placeholder="(1 + 1)"></textarea>
2021-11-19 11:36:12 +01:00
<button class="_buttonPrimary" @click="run">RUN</button>
2021-02-06 13:36:47 +01:00
<div class="logs">
2021-11-19 11:36:12 +01:00
<div v-for="log in logs" :key="log.id" class="log" :class="{ print: log.print }">{{ log.text }}</div>
2021-02-06 13:36:47 +01:00
</div>
</div>
</MkContainer>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
2021-11-11 18:02:25 +01:00
import MkContainer from '@/components/ui/container.vue';
2021-02-06 13:36:47 +01:00
import define from './define';
2021-11-11 18:02:25 +01:00
import * as os from '@/os';
2021-02-06 13:36:47 +01:00
import { AiScript, parse, utils } from '@syuilo/aiscript';
2021-11-11 18:02:25 +01:00
import { createAiScriptEnv } from '@/scripts/aiscript/api';
2021-02-06 13:36:47 +01:00
const widget = define({
name: 'aiscript',
props: () => ({
showHeader: {
type: 'boolean',
default: true,
},
script: {
type: 'string',
multiline: true,
default: '(1 + 1)',
hidden: true,
},
})
});
export default defineComponent({
components: {
MkContainer
},
2021-11-19 11:36:12 +01:00
extends: widget,
2021-02-06 13:36:47 +01:00
data() {
return {
logs: [],
};
},
methods: {
async run() {
this.logs = [];
const aiscript = new AiScript(createAiScriptEnv({
storageKey: 'widget',
token: this.$i?.token,
2021-02-06 13:36:47 +01:00
}), {
in: (q) => {
return new Promise(ok => {
os.inputText({
2021-02-06 13:36:47 +01:00
title: q,
}).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.alert({
2021-02-06 13:36:47 +01:00
type: 'error',
text: 'Syntax error :('
});
return;
}
try {
await aiscript.exec(ast);
} catch (e) {
os.alert({
2021-02-06 13:36:47 +01:00
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 0.5px var(--divider);
2021-02-06 13:36:47 +01:00
border-radius: 0;
box-sizing: border-box;
font: inherit;
2021-10-02 19:46:58 +02:00
&:focus-visible {
2021-02-06 13:36:47 +01:00
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 0.5px var(--divider);
2021-02-06 13:36:47 +01:00
text-align: left;
padding: 16px;
&:empty {
display: none;
}
> .log {
&:not(.print) {
opacity: 0.7;
}
}
}
}
</style>