diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index c732f841e0..cd29135bdb 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1867,28 +1867,50 @@ pages: select-type: "種類を選択" enter-variable-name: "変数名を決めてください" the-variable-name-is-already-used: "その変数名は既に使われています" + content-blocks: "コンテンツ" + input-blocks: "入力" + special-blocks: "特殊" + post-from-post-form: "この内容を投稿" + posted-from-post-form: "投稿しました" blocks: text: "テキスト" + textarea: "テキストエリア" section: "セクション" image: "画像" button: "ボタン" + if: "もし" _if: variable: "変数" - input: "ユーザー入力" - _input: + + post: "投稿フォーム" + _post: + text: "内容" + + textInput: "テキスト入力" + _textInput: name: "変数名" text: "タイトル" default: "デフォルト値" - inputType: "入力の種類" - _inputType: - string: "テキスト" - number: "数値" + + textareaInput: "複数行テキスト入力" + _textareaInput: + name: "変数名" + text: "タイトル" + default: "デフォルト値" + + numberInput: "数値入力" + _numberInput: + name: "変数名" + text: "タイトル" + default: "デフォルト値" + switch: "スイッチ" _switch: name: "変数名" text: "タイトル" default: "デフォルト値" + _button: text: "タイトル" action: "ボタンを押したときの動作" @@ -1897,6 +1919,7 @@ pages: _dialog: content: "内容" resetRandom: "乱数をリセット" + script: categories: flow: "制御" diff --git a/src/client/app/common/scripts/aiscript.ts b/src/client/app/common/scripts/aiscript.ts index 50c73421e1..99caec8c15 100644 --- a/src/client/app/common/scripts/aiscript.ts +++ b/src/client/app/common/scripts/aiscript.ts @@ -97,6 +97,7 @@ type PageVar = { name: string; value: any; type: Type; }; const envVarsDef = { AI: 'string', + URL: 'string', VERSION: 'string', LOGIN: 'boolean', NAME: 'string', @@ -120,7 +121,7 @@ export class AiScript { public static blockDefs = blockDefs; public static funcDefs = funcDefs; private opts: { - randomSeed?: string; user?: any; visitor?: any; + randomSeed?: string; user?: any; visitor?: any; page?: any; url?: string; }; constructor(variables: Variable[] = [], pageVars: PageVar[] = [], opts: AiScript['opts'] = {}) { @@ -131,6 +132,7 @@ export class AiScript { this.envVars = { AI: 'kawaii', VERSION: version, + URL: opts.page ? `${opts.url}/@${opts.page.user.username}/pages/${opts.page.name}` : '', LOGIN: opts.visitor != null, NAME: opts.visitor ? opts.visitor.name : '', USERNAME: opts.visitor ? opts.visitor.username : '', diff --git a/src/client/app/common/scripts/collect-page-vars.ts b/src/client/app/common/scripts/collect-page-vars.ts index 86687e21f4..92727ce6db 100644 --- a/src/client/app/common/scripts/collect-page-vars.ts +++ b/src/client/app/common/scripts/collect-page-vars.ts @@ -2,10 +2,22 @@ export function collectPageVars(content) { const pageVars = []; const collect = (xs: any[]) => { for (const x of xs) { - if (x.type === 'input') { + if (x.type === 'textInput') { pageVars.push({ name: x.name, - type: x.inputType, + type: 'string', + value: x.default + }); + } else if (x.type === 'textareaInput') { + pageVars.push({ + name: x.name, + type: 'string', + value: x.default + }); + } else if (x.type === 'numberInput') { + pageVars.push({ + name: x.name, + type: 'number', value: x.default }); } else if (x.type === 'switch') { diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.if.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.if.vue index 46920fafdc..87fc9e6faf 100644 --- a/src/client/app/common/views/components/page-editor/els/page-editor.el.if.vue +++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.if.vue @@ -72,7 +72,7 @@ export default Vue.extend({ type: null, title: this.$t('choose-block'), select: { - items: this.getPageBlockList() + groupedItems: this.getPageBlockList() }, showCancelButton: true }); diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.input.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.input.vue deleted file mode 100644 index b2bcb33c3d..0000000000 --- a/src/client/app/common/views/components/page-editor/els/page-editor.el.input.vue +++ /dev/null @@ -1,61 +0,0 @@ - - - - - diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.number-input.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.number-input.vue new file mode 100644 index 0000000000..aff6cf6b6b --- /dev/null +++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.number-input.vue @@ -0,0 +1,42 @@ + + + diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.post.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.post.vue new file mode 100644 index 0000000000..477d2c8ec5 --- /dev/null +++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.post.vue @@ -0,0 +1,44 @@ + + + diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.section.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.section.vue index 6133faf666..747de481a6 100644 --- a/src/client/app/common/views/components/page-editor/els/page-editor.el.section.vue +++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.section.vue @@ -84,7 +84,7 @@ export default Vue.extend({ type: null, title: this.$t('choose-block'), select: { - items: this.getPageBlockList() + groupedItems: this.getPageBlockList() }, showCancelButton: true }); diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.text-input.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.text-input.vue new file mode 100644 index 0000000000..6c4783fd7e --- /dev/null +++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.text-input.vue @@ -0,0 +1,42 @@ + + + diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.textarea-input.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.textarea-input.vue new file mode 100644 index 0000000000..68edf13824 --- /dev/null +++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.textarea-input.vue @@ -0,0 +1,42 @@ + + + diff --git a/src/client/app/common/views/components/page-editor/els/page-editor.el.textarea.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.textarea.vue new file mode 100644 index 0000000000..4fbe497960 --- /dev/null +++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.textarea.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/src/client/app/common/views/components/page-editor/page-editor.block.vue b/src/client/app/common/views/components/page-editor/page-editor.block.vue index 86ee3f6888..7d4505fca8 100644 --- a/src/client/app/common/views/components/page-editor/page-editor.block.vue +++ b/src/client/app/common/views/components/page-editor/page-editor.block.vue @@ -6,15 +6,19 @@ import Vue from 'vue'; import XSection from './els/page-editor.el.section.vue'; import XText from './els/page-editor.el.text.vue'; +import XTextarea from './els/page-editor.el.textarea.vue'; import XImage from './els/page-editor.el.image.vue'; import XButton from './els/page-editor.el.button.vue'; -import XInput from './els/page-editor.el.input.vue'; +import XTextInput from './els/page-editor.el.text-input.vue'; +import XTextareaInput from './els/page-editor.el.textarea-input.vue'; +import XNumberInput from './els/page-editor.el.text-input.vue'; import XSwitch from './els/page-editor.el.switch.vue'; import XIf from './els/page-editor.el.if.vue'; +import XPost from './els/page-editor.el.post.vue'; export default Vue.extend({ components: { - XSection, XText, XImage, XButton, XInput, XSwitch, XIf + XSection, XText, XImage, XButton, XTextarea, XTextInput, XTextareaInput, XNumberInput, XSwitch, XIf, XPost }, props: { diff --git a/src/client/app/common/views/components/page-editor/page-editor.vue b/src/client/app/common/views/components/page-editor/page-editor.vue index f39985952b..f8959fb0f1 100644 --- a/src/client/app/common/views/components/page-editor/page-editor.vue +++ b/src/client/app/common/views/components/page-editor/page-editor.vue @@ -259,7 +259,7 @@ export default Vue.extend({ type: null, title: this.$t('choose-block'), select: { - items: this.getPageBlockList() + groupedItems: this.getPageBlockList() }, showCancelButton: true }); @@ -323,19 +323,28 @@ export default Vue.extend({ getPageBlockList() { return [{ - value: 'section', text: this.$t('blocks.section') + label: this.$t('content-blocks'), + items: [ + { value: 'section', text: this.$t('blocks.section') }, + { value: 'text', text: this.$t('blocks.text') }, + { value: 'image', text: this.$t('blocks.image') }, + { value: 'textarea', text: this.$t('blocks.textarea') }, + ] }, { - value: 'text', text: this.$t('blocks.text') + label: this.$t('input-blocks'), + items: [ + { value: 'button', text: this.$t('blocks.button') }, + { value: 'textInput', text: this.$t('blocks.textInput') }, + { value: 'textareaInput', text: this.$t('blocks.textareaInput') }, + { value: 'numberInput', text: this.$t('blocks.numberInput') }, + { value: 'switch', text: this.$t('blocks.switch') } + ] }, { - value: 'image', text: this.$t('blocks.image') - }, { - value: 'button', text: this.$t('blocks.button') - }, { - value: 'input', text: this.$t('blocks.input') - }, { - value: 'switch', text: this.$t('blocks.switch') - }, { - value: 'if', text: this.$t('blocks.if') + label: this.$t('special-blocks'), + items: [ + { value: 'if', text: this.$t('blocks.if') }, + { value: 'post', text: this.$t('blocks.post') } + ] }]; }, diff --git a/src/client/app/common/views/pages/page/page.block.vue b/src/client/app/common/views/pages/page/page.block.vue index e3a758ed4e..f348107cc7 100644 --- a/src/client/app/common/views/pages/page/page.block.vue +++ b/src/client/app/common/views/pages/page/page.block.vue @@ -8,13 +8,17 @@ import XText from './page.text.vue'; import XSection from './page.section.vue'; import XImage from './page.image.vue'; import XButton from './page.button.vue'; -import XInput from './page.input.vue'; +import XNumberInput from './page.number-input.vue'; +import XTextInput from './page.text-input.vue'; +import XTextareaInput from './page.textarea-input.vue'; import XSwitch from './page.switch.vue'; import XIf from './page.if.vue'; +import XTextarea from './page.textarea.vue'; +import XPost from './page.post.vue'; export default Vue.extend({ components: { - XText, XSection, XImage, XButton, XInput, XSwitch, XIf + XText, XSection, XImage, XButton, XNumberInput, XTextInput, XTextareaInput, XTextarea, XPost, XSwitch, XIf }, props: { diff --git a/src/client/app/common/views/pages/page/page.input.vue b/src/client/app/common/views/pages/page/page.number-input.vue similarity index 63% rename from src/client/app/common/views/pages/page/page.input.vue rename to src/client/app/common/views/pages/page/page.number-input.vue index 9f4cfd91f3..51d538c369 100644 --- a/src/client/app/common/views/pages/page/page.input.vue +++ b/src/client/app/common/views/pages/page/page.number-input.vue @@ -1,6 +1,6 @@ @@ -25,9 +25,7 @@ export default Vue.extend({ watch: { v() { - let v = this.v; - if (this.value.inputType === 'number') v = parseInt(v, 10); - this.script.aiScript.updatePageVar(this.value.name, v); + this.script.aiScript.updatePageVar(this.value.name, this.v); this.script.reEval(); } } diff --git a/src/client/app/common/views/pages/page/page.post.vue b/src/client/app/common/views/pages/page/page.post.vue new file mode 100644 index 0000000000..cb695e21e9 --- /dev/null +++ b/src/client/app/common/views/pages/page/page.post.vue @@ -0,0 +1,68 @@ + + + + + diff --git a/src/client/app/common/views/pages/page/page.text-input.vue b/src/client/app/common/views/pages/page/page.text-input.vue new file mode 100644 index 0000000000..3d659edd5e --- /dev/null +++ b/src/client/app/common/views/pages/page/page.text-input.vue @@ -0,0 +1,41 @@ + + + + + diff --git a/src/client/app/common/views/pages/page/page.textarea-input.vue b/src/client/app/common/views/pages/page/page.textarea-input.vue new file mode 100644 index 0000000000..fd8174c273 --- /dev/null +++ b/src/client/app/common/views/pages/page/page.textarea-input.vue @@ -0,0 +1,36 @@ + + + + + diff --git a/src/client/app/common/views/pages/page/page.textarea.vue b/src/client/app/common/views/pages/page/page.textarea.vue new file mode 100644 index 0000000000..03c8542cb0 --- /dev/null +++ b/src/client/app/common/views/pages/page/page.textarea.vue @@ -0,0 +1,33 @@ + + + + + diff --git a/src/client/app/common/views/pages/page/page.vue b/src/client/app/common/views/pages/page/page.vue index 7cbd3ed81b..88598d3527 100644 --- a/src/client/app/common/views/pages/page/page.vue +++ b/src/client/app/common/views/pages/page/page.vue @@ -23,6 +23,7 @@ import { faSave, faStickyNote } from '@fortawesome/free-regular-svg-icons'; import XBlock from './page.block.vue'; import { AiScript } from '../../../scripts/aiscript'; import { collectPageVars } from '../../../scripts/collect-page-vars'; +import { url } from '../../../../config'; class Script { public aiScript: AiScript; @@ -82,7 +83,9 @@ export default Vue.extend({ this.script = new Script(new AiScript(this.page.variables, pageVars, { randomSeed: Math.random(), user: page.user, - visitor: this.$store.state.i + visitor: this.$store.state.i, + page: page, + url: url })); }); }, diff --git a/src/models/repositories/page.ts b/src/models/repositories/page.ts index 4c1b4cc793..cbe385568e 100644 --- a/src/models/repositories/page.ts +++ b/src/models/repositories/page.ts @@ -27,6 +27,33 @@ export class PageRepository extends Repository { } }; collectFile(src.content); + + // 後方互換性のため + let migrated = false; + const migrate = (xs: any[]) => { + for (const x of xs) { + if (x.type === 'input') { + if (x.inputType === 'text') { + x.type = 'textInput'; + } + if (x.inputType === 'number') { + x.type = 'numberInput'; + if (x.default) x.default = parseInt(x.default, 10); + } + migrated = true; + } + if (x.children) { + migrate(x.children); + } + } + }; + migrate(src.content); + if (migrated) { + this.update(src.id, { + content: src.content + }); + } + return await awaitAll({ id: src.id, createdAt: src.createdAt.toISOString(),