Improve MisskeyPages
This commit is contained in:
parent
d0c8d537f5
commit
10216af48a
3 changed files with 54 additions and 15 deletions
|
@ -2036,12 +2036,18 @@ pages:
|
||||||
_numberToString:
|
_numberToString:
|
||||||
arg1: "数値"
|
arg1: "数値"
|
||||||
ref: "変数"
|
ref: "変数"
|
||||||
in: "引数"
|
in: "スロット入力"
|
||||||
_in:
|
_in:
|
||||||
arg1: "スロット番号"
|
arg1: "スロット番号"
|
||||||
fn: "関数"
|
fn: "関数"
|
||||||
_fn:
|
_fn:
|
||||||
|
slots: "スロット"
|
||||||
|
slots-info: "スロットひとつひとつを改行で区切ってください"
|
||||||
arg1: "出力"
|
arg1: "出力"
|
||||||
|
for: "繰り返し"
|
||||||
|
_for:
|
||||||
|
arg1: "回数"
|
||||||
|
arg2: "処理"
|
||||||
typeError: "スロット{slot}は\"{expect}\"を受け付けますが、\"{actual}\"が入れられています!"
|
typeError: "スロット{slot}は\"{expect}\"を受け付けますが、\"{actual}\"が入れられています!"
|
||||||
thereIsEmptySlot: "スロット{slot}が空です!"
|
thereIsEmptySlot: "スロット{slot}が空です!"
|
||||||
types:
|
types:
|
||||||
|
|
|
@ -27,18 +27,27 @@ import {
|
||||||
faDice,
|
faDice,
|
||||||
faSortNumericUp,
|
faSortNumericUp,
|
||||||
faExchangeAlt,
|
faExchangeAlt,
|
||||||
|
faRecycle,
|
||||||
} from '@fortawesome/free-solid-svg-icons';
|
} from '@fortawesome/free-solid-svg-icons';
|
||||||
import { faFlag } from '@fortawesome/free-regular-svg-icons';
|
import { faFlag } from '@fortawesome/free-regular-svg-icons';
|
||||||
|
|
||||||
import { version } from '../../config';
|
import { version } from '../../config';
|
||||||
|
|
||||||
export type Block = {
|
export type Block<V = any> = {
|
||||||
id: string;
|
id: string;
|
||||||
type: string;
|
type: string;
|
||||||
args: Block[];
|
args: Block[];
|
||||||
value: any;
|
value: V;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type FnBlock = Block<{
|
||||||
|
slots: {
|
||||||
|
name: string;
|
||||||
|
type: Type;
|
||||||
|
}[];
|
||||||
|
expression: Block;
|
||||||
|
}>;
|
||||||
|
|
||||||
export type Variable = Block & {
|
export type Variable = Block & {
|
||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
|
@ -53,6 +62,7 @@ type TypeError = {
|
||||||
|
|
||||||
const funcDefs = {
|
const funcDefs = {
|
||||||
if: { in: ['boolean', 0, 0], out: 0, category: 'flow', icon: faShareAlt, },
|
if: { in: ['boolean', 0, 0], out: 0, category: 'flow', icon: faShareAlt, },
|
||||||
|
for: { in: ['number', 'function'], out: 0, category: 'flow', icon: faRecycle, },
|
||||||
not: { in: ['boolean'], out: 'boolean', category: 'logical', icon: faFlag, },
|
not: { in: ['boolean'], out: 'boolean', category: 'logical', icon: faFlag, },
|
||||||
or: { in: ['boolean', 'boolean'], out: 'boolean', category: 'logical', icon: faFlag, },
|
or: { in: ['boolean', 'boolean'], out: 'boolean', category: 'logical', icon: faFlag, },
|
||||||
and: { in: ['boolean', 'boolean'], out: 'boolean', category: 'logical', icon: faFlag, },
|
and: { in: ['boolean', 'boolean'], out: 'boolean', category: 'logical', icon: faFlag, },
|
||||||
|
@ -99,6 +109,10 @@ const blockDefs = [
|
||||||
}))
|
}))
|
||||||
];
|
];
|
||||||
|
|
||||||
|
function isFnBlock(block: Block): block is FnBlock {
|
||||||
|
return block.type === 'fn';
|
||||||
|
}
|
||||||
|
|
||||||
type PageVar = { name: string; value: any; type: Type; };
|
type PageVar = { name: string; value: any; type: Type; };
|
||||||
|
|
||||||
const envVarsDef = {
|
const envVarsDef = {
|
||||||
|
@ -326,7 +340,7 @@ export class AiScript {
|
||||||
@autobind
|
@autobind
|
||||||
private interpolate(str: string, values: { name: string, value: any }[]) {
|
private interpolate(str: string, values: { name: string, value: any }[]) {
|
||||||
return str.replace(/\{(.+?)\}/g, match => {
|
return str.replace(/\{(.+?)\}/g, match => {
|
||||||
const v = this.getVariableValue(match.slice(1, -1).trim(), values);
|
const v = this.getVarVal(match.slice(1, -1).trim(), values);
|
||||||
return v == null ? 'NULL' : v.toString();
|
return v == null ? 'NULL' : v.toString();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -378,23 +392,23 @@ export class AiScript {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block.type === 'ref') {
|
if (block.type === 'ref') {
|
||||||
return this.getVariableValue(block.value, values);
|
return this.getVarVal(block.value, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block.type === 'in') {
|
if (block.type === 'in') {
|
||||||
return slotArg[block.value];
|
return slotArg[block.value];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block.type === 'fn') { // ユーザー関数定義
|
if (isFnBlock(block)) { // ユーザー関数定義
|
||||||
return {
|
return {
|
||||||
slots: block.value.slots,
|
slots: block.value.slots.map(x => x.name),
|
||||||
exec: slotArg => this.evaluate(block.value.expression, values, slotArg)
|
exec: slotArg => this.evaluate(block.value.expression, values, slotArg)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (block.type.startsWith('fn:')) { // ユーザー関数呼び出し
|
if (block.type.startsWith('fn:')) { // ユーザー関数呼び出し
|
||||||
const fnName = block.type.split(':')[1];
|
const fnName = block.type.split(':')[1];
|
||||||
const fn = this.getVariableValue(fnName, values);
|
const fn = this.getVarVal(fnName, values);
|
||||||
for (let i = 0; i < fn.slots.length; i++) {
|
for (let i = 0; i < fn.slots.length; i++) {
|
||||||
const name = fn.slots[i];
|
const name = fn.slots[i];
|
||||||
slotArg[name] = this.evaluate(block.args[i], values);
|
slotArg[name] = this.evaluate(block.args[i], values);
|
||||||
|
@ -418,6 +432,14 @@ export class AiScript {
|
||||||
or: (a, b) => a || b,
|
or: (a, b) => a || b,
|
||||||
and: (a, b) => a && b,
|
and: (a, b) => a && b,
|
||||||
if: (bool, a, b) => bool ? a : b,
|
if: (bool, a, b) => bool ? a : b,
|
||||||
|
for: (times, fn) => {
|
||||||
|
const result = [];
|
||||||
|
for (let i = 0; i < times; i++) {
|
||||||
|
slotArg[fn.slots[0]] = i + 1;
|
||||||
|
result.push(fn.exec(slotArg));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
},
|
||||||
add: (a, b) => a + b,
|
add: (a, b) => a + b,
|
||||||
subtract: (a, b) => a - b,
|
subtract: (a, b) => a - b,
|
||||||
multiply: (a, b) => a * b,
|
multiply: (a, b) => a * b,
|
||||||
|
@ -449,8 +471,13 @@ export class AiScript {
|
||||||
return fn(...args);
|
return fn(...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定した名前の変数の値を取得します
|
||||||
|
* @param name 変数名
|
||||||
|
* @param values ユーザー定義変数のリスト
|
||||||
|
*/
|
||||||
@autobind
|
@autobind
|
||||||
private getVariableValue(name: string, values: { name: string, value: any }[]): any {
|
private getVarVal(name: string, values: { name: string, value: any }[]): any {
|
||||||
const v = values.find(v => v.name === name);
|
const v = values.find(v => v.name === name);
|
||||||
if (v) {
|
if (v) {
|
||||||
return v.value;
|
return v.value;
|
||||||
|
|
|
@ -35,15 +35,18 @@
|
||||||
</section>
|
</section>
|
||||||
<section v-else-if="value.type === 'in'" class="hpdwcrvs">
|
<section v-else-if="value.type === 'in'" class="hpdwcrvs">
|
||||||
<select v-model="value.value">
|
<select v-model="value.value">
|
||||||
<option v-for="v in fnSlots" :value="v">{{ v }}</option>
|
<option v-for="v in fnSlots" :value="v.name">{{ v.name }}</option>
|
||||||
</select>
|
</select>
|
||||||
</section>
|
</section>
|
||||||
<section v-else-if="value.type === 'fn'" class="" style="padding:16px;">
|
<section v-else-if="value.type === 'fn'" class="" style="padding:0 16px 16px 16px;">
|
||||||
<ui-textarea v-model="slots"></ui-textarea>
|
<ui-textarea v-model="slots">
|
||||||
|
<span>{{ $t('script.blocks._fn.slots') }}</span>
|
||||||
|
<template #desc>{{ $t('script.blocks._fn.slots-info') }}</template>
|
||||||
|
</ui-textarea>
|
||||||
<x-v v-if="value.value.expression" v-model="value.value.expression" :title="$t(`script.blocks._fn.arg1`)" :get-expected-type="() => null" :ai-script="aiScript" :fn-slots="value.value.slots" :name="name"/>
|
<x-v v-if="value.value.expression" v-model="value.value.expression" :title="$t(`script.blocks._fn.arg1`)" :get-expected-type="() => null" :ai-script="aiScript" :fn-slots="value.value.slots" :name="name"/>
|
||||||
</section>
|
</section>
|
||||||
<section v-else-if="value.type.startsWith('fn:')" class="" style="padding:16px;">
|
<section v-else-if="value.type.startsWith('fn:')" class="" style="padding:16px;">
|
||||||
<x-v v-for="(x, i) in value.args" v-model="value.args[i]" :title="aiScript.getVarByName(value.type.split(':')[1]).value.slots[i]" :get-expected-type="() => null" :ai-script="aiScript" :name="name" :key="i"/>
|
<x-v v-for="(x, i) in value.args" v-model="value.args[i]" :title="aiScript.getVarByName(value.type.split(':')[1]).value.slots[i].name" :get-expected-type="() => null" :ai-script="aiScript" :name="name" :key="i"/>
|
||||||
</section>
|
</section>
|
||||||
<section v-else class="" style="padding:16px;">
|
<section v-else class="" style="padding:16px;">
|
||||||
<x-v v-for="(x, i) in value.args" v-model="value.args[i]" :title="$t(`script.blocks._${value.type}.arg${i + 1}`)" :get-expected-type="() => _getExpectedType(i)" :ai-script="aiScript" :name="name" :fn-slots="fnSlots" :key="i"/>
|
<x-v v-for="(x, i) in value.args" v-model="value.args[i]" :title="$t(`script.blocks._${value.type}.arg${i + 1}`)" :get-expected-type="() => _getExpectedType(i)" :ai-script="aiScript" :name="name" :fn-slots="fnSlots" :key="i"/>
|
||||||
|
@ -118,7 +121,10 @@ export default Vue.extend({
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
slots() {
|
slots() {
|
||||||
this.value.value.slots = this.slots.split('\n');
|
this.value.value.slots = this.slots.split('\n').map(x => ({
|
||||||
|
name: x,
|
||||||
|
type: null
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -129,7 +135,7 @@ export default Vue.extend({
|
||||||
created() {
|
created() {
|
||||||
if (this.value.value == null) Vue.set(this.value, 'value', null);
|
if (this.value.value == null) Vue.set(this.value, 'value', null);
|
||||||
|
|
||||||
if (this.value.value && this.value.value.slots) this.slots = this.value.value.slots.join('\n');
|
if (this.value.value && this.value.value.slots) this.slots = this.value.value.slots.map(x => x.name).join('\n');
|
||||||
|
|
||||||
this.$watch('value.type', (t) => {
|
this.$watch('value.type', (t) => {
|
||||||
this.warn = null;
|
this.warn = null;
|
||||||
|
|
Loading…
Reference in a new issue