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: | ||||
|         arg1: "数値" | ||||
|       ref: "変数" | ||||
|       in: "引数" | ||||
|       in: "スロット入力" | ||||
|       _in: | ||||
|         arg1: "スロット番号" | ||||
|       fn: "関数" | ||||
|       _fn: | ||||
|         slots: "スロット" | ||||
|         slots-info: "スロットひとつひとつを改行で区切ってください" | ||||
|         arg1: "出力" | ||||
|       for: "繰り返し" | ||||
|       _for: | ||||
|         arg1: "回数" | ||||
|         arg2: "処理" | ||||
|     typeError: "スロット{slot}は\"{expect}\"を受け付けますが、\"{actual}\"が入れられています!" | ||||
|     thereIsEmptySlot: "スロット{slot}が空です!" | ||||
|     types: | ||||
|  |  | |||
|  | @ -27,18 +27,27 @@ import { | |||
| 	faDice, | ||||
| 	faSortNumericUp, | ||||
| 	faExchangeAlt, | ||||
| 	faRecycle, | ||||
| } from '@fortawesome/free-solid-svg-icons'; | ||||
| import { faFlag } from '@fortawesome/free-regular-svg-icons'; | ||||
| 
 | ||||
| import { version } from '../../config'; | ||||
| 
 | ||||
| export type Block = { | ||||
| export type Block<V = any> = { | ||||
| 	id: string; | ||||
| 	type: string; | ||||
| 	args: Block[]; | ||||
| 	value: any; | ||||
| 	value: V; | ||||
| }; | ||||
| 
 | ||||
| type FnBlock = Block<{ | ||||
| 	slots: { | ||||
| 		name: string; | ||||
| 		type: Type; | ||||
| 	}[]; | ||||
| 	expression: Block; | ||||
| }>; | ||||
| 
 | ||||
| export type Variable = Block & { | ||||
| 	name: string; | ||||
| }; | ||||
|  | @ -53,6 +62,7 @@ type TypeError = { | |||
| 
 | ||||
| const funcDefs = { | ||||
| 	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, }, | ||||
| 	or:              { 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; }; | ||||
| 
 | ||||
| const envVarsDef = { | ||||
|  | @ -326,7 +340,7 @@ export class AiScript { | |||
| 	@autobind | ||||
| 	private interpolate(str: string, values: { name: string, value: any }[]) { | ||||
| 		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(); | ||||
| 		}); | ||||
| 	} | ||||
|  | @ -378,23 +392,23 @@ export class AiScript { | |||
| 		} | ||||
| 
 | ||||
| 		if (block.type === 'ref') { | ||||
| 			return this.getVariableValue(block.value, values); | ||||
| 			return this.getVarVal(block.value, values); | ||||
| 		} | ||||
| 
 | ||||
| 		if (block.type === 'in') { | ||||
| 			return slotArg[block.value]; | ||||
| 		} | ||||
| 
 | ||||
| 		if (block.type === 'fn') { // ユーザー関数定義
 | ||||
| 		if (isFnBlock(block)) { // ユーザー関数定義
 | ||||
| 			return { | ||||
| 				slots: block.value.slots, | ||||
| 				slots: block.value.slots.map(x => x.name), | ||||
| 				exec: slotArg => this.evaluate(block.value.expression, values, slotArg) | ||||
| 			}; | ||||
| 		} | ||||
| 
 | ||||
| 		if (block.type.startsWith('fn:')) { // ユーザー関数呼び出し
 | ||||
| 			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++) { | ||||
| 				const name = fn.slots[i]; | ||||
| 				slotArg[name] = this.evaluate(block.args[i], values); | ||||
|  | @ -418,6 +432,14 @@ export class AiScript { | |||
| 			or: (a, b) => a || b, | ||||
| 			and: (a, b) => 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, | ||||
| 			subtract: (a, b) => a - b, | ||||
| 			multiply: (a, b) => a * b, | ||||
|  | @ -449,8 +471,13 @@ export class AiScript { | |||
| 		return fn(...args); | ||||
| 	} | ||||
| 
 | ||||
| 	/** | ||||
| 	 * 指定した名前の変数の値を取得します | ||||
| 	 * @param name 変数名 | ||||
| 	 * @param values ユーザー定義変数のリスト | ||||
| 	 */ | ||||
| 	@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); | ||||
| 		if (v) { | ||||
| 			return v.value; | ||||
|  |  | |||
|  | @ -35,15 +35,18 @@ | |||
| 	</section> | ||||
| 	<section v-else-if="value.type === 'in'" class="hpdwcrvs"> | ||||
| 		<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> | ||||
| 	</section> | ||||
| 	<section v-else-if="value.type === 'fn'" class="" style="padding:16px;"> | ||||
| 		<ui-textarea v-model="slots"></ui-textarea> | ||||
| 	<section v-else-if="value.type === 'fn'" class="" style="padding:0 16px 16px 16px;"> | ||||
| 		<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"/> | ||||
| 	</section> | ||||
| 	<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 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"/> | ||||
|  | @ -118,7 +121,10 @@ export default Vue.extend({ | |||
| 
 | ||||
| 	watch: { | ||||
| 		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() { | ||||
| 		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.warn = null; | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue