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 @@
-
- $emit('remove')">
- {{ $t('blocks.input') }}
-
-
- {{ $t('blocks._input.name') }}
- {{ $t('blocks._input.text') }}
-
- {{ $t('blocks._input.inputType') }}
-
-
-
- {{ $t('blocks._input.default') }}
-
-
-
-
-
-
-
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 @@
+
+ $emit('remove')">
+ {{ $t('blocks.numberInput') }}
+
+
+ {{ $t('blocks._numberInput.name') }}
+ {{ $t('blocks._numberInput.text') }}
+ {{ $t('blocks._numberInput.default') }}
+
+
+
+
+
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 @@
+
+ $emit('remove')">
+ {{ $t('blocks.post') }}
+
+
+
+
+
+
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 @@
+
+ $emit('remove')">
+ {{ $t('blocks.textInput') }}
+
+
+ {{ $t('blocks._textInput.name') }}
+ {{ $t('blocks._textInput.text') }}
+ {{ $t('blocks._textInput.default') }}
+
+
+
+
+
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 @@
+
+ $emit('remove')">
+ {{ $t('blocks.textareaInput') }}
+
+
+ {{ $t('blocks._textareaInput.name') }}
+ {{ $t('blocks._textareaInput.text') }}
+ {{ $t('blocks._textareaInput.default') }}
+
+
+
+
+
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 @@
+
+ $emit('remove')">
+ {{ $t('blocks.textarea') }}
+
+
+
+
+
+
+
+
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 @@
- {{ script.interpolate(value.text) }}
+ {{ script.interpolate(value.text) }}
@@ -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 @@
+
+
+
+ {{ posted ? $t('posted-from-post-form') : $t('post-from-post-form') }}
+
+
+
+
+
+
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 @@
+
+
+ {{ script.interpolate(value.text) }}
+
+
+
+
+
+
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 @@
+
+
+ {{ script.interpolate(value.text) }}
+
+
+
+
+
+
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(),