mirror of
https://git.joinsharkey.org/Sharkey/Sharkey.git
synced 2024-11-27 03:03:09 +02:00
Improve MisskeyPages
This commit is contained in:
parent
59782973be
commit
759719d124
21 changed files with 520 additions and 93 deletions
|
@ -1867,28 +1867,50 @@ pages:
|
||||||
select-type: "種類を選択"
|
select-type: "種類を選択"
|
||||||
enter-variable-name: "変数名を決めてください"
|
enter-variable-name: "変数名を決めてください"
|
||||||
the-variable-name-is-already-used: "その変数名は既に使われています"
|
the-variable-name-is-already-used: "その変数名は既に使われています"
|
||||||
|
content-blocks: "コンテンツ"
|
||||||
|
input-blocks: "入力"
|
||||||
|
special-blocks: "特殊"
|
||||||
|
post-from-post-form: "この内容を投稿"
|
||||||
|
posted-from-post-form: "投稿しました"
|
||||||
blocks:
|
blocks:
|
||||||
text: "テキスト"
|
text: "テキスト"
|
||||||
|
textarea: "テキストエリア"
|
||||||
section: "セクション"
|
section: "セクション"
|
||||||
image: "画像"
|
image: "画像"
|
||||||
button: "ボタン"
|
button: "ボタン"
|
||||||
|
|
||||||
if: "もし"
|
if: "もし"
|
||||||
_if:
|
_if:
|
||||||
variable: "変数"
|
variable: "変数"
|
||||||
input: "ユーザー入力"
|
|
||||||
_input:
|
post: "投稿フォーム"
|
||||||
|
_post:
|
||||||
|
text: "内容"
|
||||||
|
|
||||||
|
textInput: "テキスト入力"
|
||||||
|
_textInput:
|
||||||
name: "変数名"
|
name: "変数名"
|
||||||
text: "タイトル"
|
text: "タイトル"
|
||||||
default: "デフォルト値"
|
default: "デフォルト値"
|
||||||
inputType: "入力の種類"
|
|
||||||
_inputType:
|
textareaInput: "複数行テキスト入力"
|
||||||
string: "テキスト"
|
_textareaInput:
|
||||||
number: "数値"
|
name: "変数名"
|
||||||
|
text: "タイトル"
|
||||||
|
default: "デフォルト値"
|
||||||
|
|
||||||
|
numberInput: "数値入力"
|
||||||
|
_numberInput:
|
||||||
|
name: "変数名"
|
||||||
|
text: "タイトル"
|
||||||
|
default: "デフォルト値"
|
||||||
|
|
||||||
switch: "スイッチ"
|
switch: "スイッチ"
|
||||||
_switch:
|
_switch:
|
||||||
name: "変数名"
|
name: "変数名"
|
||||||
text: "タイトル"
|
text: "タイトル"
|
||||||
default: "デフォルト値"
|
default: "デフォルト値"
|
||||||
|
|
||||||
_button:
|
_button:
|
||||||
text: "タイトル"
|
text: "タイトル"
|
||||||
action: "ボタンを押したときの動作"
|
action: "ボタンを押したときの動作"
|
||||||
|
@ -1897,6 +1919,7 @@ pages:
|
||||||
_dialog:
|
_dialog:
|
||||||
content: "内容"
|
content: "内容"
|
||||||
resetRandom: "乱数をリセット"
|
resetRandom: "乱数をリセット"
|
||||||
|
|
||||||
script:
|
script:
|
||||||
categories:
|
categories:
|
||||||
flow: "制御"
|
flow: "制御"
|
||||||
|
|
|
@ -97,6 +97,7 @@ type PageVar = { name: string; value: any; type: Type; };
|
||||||
|
|
||||||
const envVarsDef = {
|
const envVarsDef = {
|
||||||
AI: 'string',
|
AI: 'string',
|
||||||
|
URL: 'string',
|
||||||
VERSION: 'string',
|
VERSION: 'string',
|
||||||
LOGIN: 'boolean',
|
LOGIN: 'boolean',
|
||||||
NAME: 'string',
|
NAME: 'string',
|
||||||
|
@ -120,7 +121,7 @@ export class AiScript {
|
||||||
public static blockDefs = blockDefs;
|
public static blockDefs = blockDefs;
|
||||||
public static funcDefs = funcDefs;
|
public static funcDefs = funcDefs;
|
||||||
private opts: {
|
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'] = {}) {
|
constructor(variables: Variable[] = [], pageVars: PageVar[] = [], opts: AiScript['opts'] = {}) {
|
||||||
|
@ -131,6 +132,7 @@ export class AiScript {
|
||||||
this.envVars = {
|
this.envVars = {
|
||||||
AI: 'kawaii',
|
AI: 'kawaii',
|
||||||
VERSION: version,
|
VERSION: version,
|
||||||
|
URL: opts.page ? `${opts.url}/@${opts.page.user.username}/pages/${opts.page.name}` : '',
|
||||||
LOGIN: opts.visitor != null,
|
LOGIN: opts.visitor != null,
|
||||||
NAME: opts.visitor ? opts.visitor.name : '',
|
NAME: opts.visitor ? opts.visitor.name : '',
|
||||||
USERNAME: opts.visitor ? opts.visitor.username : '',
|
USERNAME: opts.visitor ? opts.visitor.username : '',
|
||||||
|
|
|
@ -2,10 +2,22 @@ export function collectPageVars(content) {
|
||||||
const pageVars = [];
|
const pageVars = [];
|
||||||
const collect = (xs: any[]) => {
|
const collect = (xs: any[]) => {
|
||||||
for (const x of xs) {
|
for (const x of xs) {
|
||||||
if (x.type === 'input') {
|
if (x.type === 'textInput') {
|
||||||
pageVars.push({
|
pageVars.push({
|
||||||
name: x.name,
|
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
|
value: x.default
|
||||||
});
|
});
|
||||||
} else if (x.type === 'switch') {
|
} else if (x.type === 'switch') {
|
||||||
|
|
|
@ -72,7 +72,7 @@ export default Vue.extend({
|
||||||
type: null,
|
type: null,
|
||||||
title: this.$t('choose-block'),
|
title: this.$t('choose-block'),
|
||||||
select: {
|
select: {
|
||||||
items: this.getPageBlockList()
|
groupedItems: this.getPageBlockList()
|
||||||
},
|
},
|
||||||
showCancelButton: true
|
showCancelButton: true
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
<template>
|
|
||||||
<x-container @remove="() => $emit('remove')">
|
|
||||||
<template #header><fa :icon="faBolt"/> {{ $t('blocks.input') }}</template>
|
|
||||||
|
|
||||||
<section class="dnvasjon">
|
|
||||||
<ui-input v-model="value.name"><template #prefix><fa :icon="faSquareRootAlt"/></template><span>{{ $t('blocks._input.name') }}</span></ui-input>
|
|
||||||
<ui-input v-model="value.text"><span>{{ $t('blocks._input.text') }}</span></ui-input>
|
|
||||||
<ui-select v-model="value.inputType">
|
|
||||||
<template #label>{{ $t('blocks._input.inputType') }}</template>
|
|
||||||
<option value="string">{{ $t('blocks._input._inputType.string') }}</option>
|
|
||||||
<option value="number">{{ $t('blocks._input._inputType.number') }}</option>
|
|
||||||
</ui-select>
|
|
||||||
<ui-input v-model="value.default" :type="value.inputType"><span>{{ $t('blocks._input.default') }}</span></ui-input>
|
|
||||||
</section>
|
|
||||||
</x-container>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import Vue from 'vue';
|
|
||||||
import { faBolt, faSquareRootAlt } from '@fortawesome/free-solid-svg-icons';
|
|
||||||
import i18n from '../../../../../i18n';
|
|
||||||
import XContainer from '../page-editor.container.vue';
|
|
||||||
|
|
||||||
export default Vue.extend({
|
|
||||||
i18n: i18n('pages'),
|
|
||||||
|
|
||||||
components: {
|
|
||||||
XContainer
|
|
||||||
},
|
|
||||||
|
|
||||||
props: {
|
|
||||||
value: {
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
faBolt, faSquareRootAlt
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
created() {
|
|
||||||
if (this.value.name == null) Vue.set(this.value, 'name', '');
|
|
||||||
if (this.value.inputType == null) Vue.set(this.value, 'inputType', 'string');
|
|
||||||
|
|
||||||
this.$watch('value.inputType', t => {
|
|
||||||
if (this.value.default != null) {
|
|
||||||
if (t === 'number') this.value.default = parseInt(this.value.default, 10);
|
|
||||||
if (t === 'string') this.value.default = this.value.default.toString();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
|
||||||
.dnvasjon
|
|
||||||
padding 0 16px 0 16px
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<template>
|
||||||
|
<x-container @remove="() => $emit('remove')">
|
||||||
|
<template #header><fa :icon="faBolt"/> {{ $t('blocks.numberInput') }}</template>
|
||||||
|
|
||||||
|
<section style="padding: 0 16px 0 16px;">
|
||||||
|
<ui-input v-model="value.name"><template #prefix><fa :icon="faSquareRootAlt"/></template><span>{{ $t('blocks._numberInput.name') }}</span></ui-input>
|
||||||
|
<ui-input v-model="value.text"><span>{{ $t('blocks._numberInput.text') }}</span></ui-input>
|
||||||
|
<ui-input v-model="value.default" type="number"><span>{{ $t('blocks._numberInput.default') }}</span></ui-input>
|
||||||
|
</section>
|
||||||
|
</x-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import { faBolt, faSquareRootAlt } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import i18n from '../../../../../i18n';
|
||||||
|
import XContainer from '../page-editor.container.vue';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
i18n: i18n('pages'),
|
||||||
|
|
||||||
|
components: {
|
||||||
|
XContainer
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
faBolt, faSquareRootAlt
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
if (this.value.name == null) Vue.set(this.value, 'name', '');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,44 @@
|
||||||
|
<template>
|
||||||
|
<x-container @remove="() => $emit('remove')">
|
||||||
|
<template #header><fa :icon="faPaperPlane"/> {{ $t('blocks.post') }}</template>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<textarea v-model="value.text"></textarea>
|
||||||
|
</section>
|
||||||
|
</x-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import { faPaperPlane } from '@fortawesome/free-regular-svg-icons';
|
||||||
|
import i18n from '../../../../../i18n';
|
||||||
|
import XContainer from '../page-editor.container.vue';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
i18n: i18n('pages'),
|
||||||
|
|
||||||
|
components: {
|
||||||
|
XContainer
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
faPaperPlane
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeCreate() {
|
||||||
|
this.$options.components.XBlock = require('../page-editor.block.vue').default
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
if (this.value.text == null) Vue.set(this.value, 'text', '');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -84,7 +84,7 @@ export default Vue.extend({
|
||||||
type: null,
|
type: null,
|
||||||
title: this.$t('choose-block'),
|
title: this.$t('choose-block'),
|
||||||
select: {
|
select: {
|
||||||
items: this.getPageBlockList()
|
groupedItems: this.getPageBlockList()
|
||||||
},
|
},
|
||||||
showCancelButton: true
|
showCancelButton: true
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
<template>
|
||||||
|
<x-container @remove="() => $emit('remove')">
|
||||||
|
<template #header><fa :icon="faBolt"/> {{ $t('blocks.textInput') }}</template>
|
||||||
|
|
||||||
|
<section style="padding: 0 16px 0 16px;">
|
||||||
|
<ui-input v-model="value.name"><template #prefix><fa :icon="faSquareRootAlt"/></template><span>{{ $t('blocks._textInput.name') }}</span></ui-input>
|
||||||
|
<ui-input v-model="value.text"><span>{{ $t('blocks._textInput.text') }}</span></ui-input>
|
||||||
|
<ui-input v-model="value.default" type="text"><span>{{ $t('blocks._textInput.default') }}</span></ui-input>
|
||||||
|
</section>
|
||||||
|
</x-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import { faBolt, faSquareRootAlt } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import i18n from '../../../../../i18n';
|
||||||
|
import XContainer from '../page-editor.container.vue';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
i18n: i18n('pages'),
|
||||||
|
|
||||||
|
components: {
|
||||||
|
XContainer
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
faBolt, faSquareRootAlt
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
if (this.value.name == null) Vue.set(this.value, 'name', '');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,42 @@
|
||||||
|
<template>
|
||||||
|
<x-container @remove="() => $emit('remove')">
|
||||||
|
<template #header><fa :icon="faBolt"/> {{ $t('blocks.textareaInput') }}</template>
|
||||||
|
|
||||||
|
<section style="padding: 0 16px 16px 16px;">
|
||||||
|
<ui-input v-model="value.name"><template #prefix><fa :icon="faSquareRootAlt"/></template><span>{{ $t('blocks._textareaInput.name') }}</span></ui-input>
|
||||||
|
<ui-input v-model="value.text"><span>{{ $t('blocks._textareaInput.text') }}</span></ui-input>
|
||||||
|
<ui-textarea v-model="value.default"><span>{{ $t('blocks._textareaInput.default') }}</span></ui-textarea>
|
||||||
|
</section>
|
||||||
|
</x-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import { faBolt, faSquareRootAlt } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import i18n from '../../../../../i18n';
|
||||||
|
import XContainer from '../page-editor.container.vue';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
i18n: i18n('pages'),
|
||||||
|
|
||||||
|
components: {
|
||||||
|
XContainer
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
faBolt, faSquareRootAlt
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
if (this.value.name == null) Vue.set(this.value, 'name', '');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
|
@ -0,0 +1,58 @@
|
||||||
|
<template>
|
||||||
|
<x-container @remove="() => $emit('remove')">
|
||||||
|
<template #header><fa :icon="faAlignLeft"/> {{ $t('blocks.textarea') }}</template>
|
||||||
|
|
||||||
|
<section class="ihymsbbe">
|
||||||
|
<textarea v-model="value.text"></textarea>
|
||||||
|
</section>
|
||||||
|
</x-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import { faAlignLeft } from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import i18n from '../../../../../i18n';
|
||||||
|
import XContainer from '../page-editor.container.vue';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
i18n: i18n('pages'),
|
||||||
|
|
||||||
|
components: {
|
||||||
|
XContainer
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
faAlignLeft,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
if (this.value.text == null) Vue.set(this.value, 'text', '');
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.ihymsbbe
|
||||||
|
> textarea
|
||||||
|
display block
|
||||||
|
-webkit-appearance none
|
||||||
|
-moz-appearance none
|
||||||
|
appearance none
|
||||||
|
width 100%
|
||||||
|
min-width 100%
|
||||||
|
min-height 150px
|
||||||
|
border none
|
||||||
|
box-shadow none
|
||||||
|
padding 16px
|
||||||
|
background transparent
|
||||||
|
color var(--text)
|
||||||
|
font-size 14px
|
||||||
|
</style>
|
|
@ -6,15 +6,19 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import XSection from './els/page-editor.el.section.vue';
|
import XSection from './els/page-editor.el.section.vue';
|
||||||
import XText from './els/page-editor.el.text.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 XImage from './els/page-editor.el.image.vue';
|
||||||
import XButton from './els/page-editor.el.button.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 XSwitch from './els/page-editor.el.switch.vue';
|
||||||
import XIf from './els/page-editor.el.if.vue';
|
import XIf from './els/page-editor.el.if.vue';
|
||||||
|
import XPost from './els/page-editor.el.post.vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
XSection, XText, XImage, XButton, XInput, XSwitch, XIf
|
XSection, XText, XImage, XButton, XTextarea, XTextInput, XTextareaInput, XNumberInput, XSwitch, XIf, XPost
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
|
|
|
@ -259,7 +259,7 @@ export default Vue.extend({
|
||||||
type: null,
|
type: null,
|
||||||
title: this.$t('choose-block'),
|
title: this.$t('choose-block'),
|
||||||
select: {
|
select: {
|
||||||
items: this.getPageBlockList()
|
groupedItems: this.getPageBlockList()
|
||||||
},
|
},
|
||||||
showCancelButton: true
|
showCancelButton: true
|
||||||
});
|
});
|
||||||
|
@ -323,19 +323,28 @@ export default Vue.extend({
|
||||||
|
|
||||||
getPageBlockList() {
|
getPageBlockList() {
|
||||||
return [{
|
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')
|
label: this.$t('special-blocks'),
|
||||||
}, {
|
items: [
|
||||||
value: 'button', text: this.$t('blocks.button')
|
{ value: 'if', text: this.$t('blocks.if') },
|
||||||
}, {
|
{ value: 'post', text: this.$t('blocks.post') }
|
||||||
value: 'input', text: this.$t('blocks.input')
|
]
|
||||||
}, {
|
|
||||||
value: 'switch', text: this.$t('blocks.switch')
|
|
||||||
}, {
|
|
||||||
value: 'if', text: this.$t('blocks.if')
|
|
||||||
}];
|
}];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -8,13 +8,17 @@ import XText from './page.text.vue';
|
||||||
import XSection from './page.section.vue';
|
import XSection from './page.section.vue';
|
||||||
import XImage from './page.image.vue';
|
import XImage from './page.image.vue';
|
||||||
import XButton from './page.button.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 XSwitch from './page.switch.vue';
|
||||||
import XIf from './page.if.vue';
|
import XIf from './page.if.vue';
|
||||||
|
import XTextarea from './page.textarea.vue';
|
||||||
|
import XPost from './page.post.vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
XText, XSection, XImage, XButton, XInput, XSwitch, XIf
|
XText, XSection, XImage, XButton, XNumberInput, XTextInput, XTextareaInput, XTextarea, XPost, XSwitch, XIf
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<ui-input class="kudkigyw" v-model="v" :type="value.inputType">{{ script.interpolate(value.text) }}</ui-input>
|
<ui-input class="kudkigyw" v-model="v" type="number">{{ script.interpolate(value.text) }}</ui-input>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -25,9 +25,7 @@ export default Vue.extend({
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
v() {
|
v() {
|
||||||
let v = this.v;
|
this.script.aiScript.updatePageVar(this.value.name, this.v);
|
||||||
if (this.value.inputType === 'number') v = parseInt(v, 10);
|
|
||||||
this.script.aiScript.updatePageVar(this.value.name, v);
|
|
||||||
this.script.reEval();
|
this.script.reEval();
|
||||||
}
|
}
|
||||||
}
|
}
|
68
src/client/app/common/views/pages/page/page.post.vue
Normal file
68
src/client/app/common/views/pages/page/page.post.vue
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
<template>
|
||||||
|
<div class="ngbfujlo">
|
||||||
|
<ui-textarea class="textarea" :value="text" readonly></ui-textarea>
|
||||||
|
<ui-button primary @click="post()" :disabled="posting || posted">{{ posted ? $t('posted-from-post-form') : $t('post-from-post-form') }}</ui-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import i18n from '../../../../i18n';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
i18n: i18n('pages'),
|
||||||
|
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
script: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
text: this.script.interpolate(this.value.text),
|
||||||
|
posted: false,
|
||||||
|
posting: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.$watch('script.vars', () => {
|
||||||
|
this.text = this.script.interpolate(this.value.text);
|
||||||
|
}, { deep: true });
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
post() {
|
||||||
|
this.posting = true;
|
||||||
|
this.$root.api('notes/create', {
|
||||||
|
text: this.text,
|
||||||
|
}).then(() => {
|
||||||
|
this.posted = true;
|
||||||
|
this.$root.dialog({
|
||||||
|
type: 'success',
|
||||||
|
splash: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.ngbfujlo
|
||||||
|
padding 0 32px 32px 32px
|
||||||
|
border solid 2px var(--pageBlockBorder)
|
||||||
|
border-radius 6px
|
||||||
|
|
||||||
|
@media (max-width 600px)
|
||||||
|
padding 0 16px 16px 16px
|
||||||
|
|
||||||
|
> .textarea
|
||||||
|
margin-top 16px
|
||||||
|
margin-bottom 16px
|
||||||
|
|
||||||
|
</style>
|
41
src/client/app/common/views/pages/page/page.text-input.vue
Normal file
41
src/client/app/common/views/pages/page/page.text-input.vue
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<ui-input class="kudkigyw" v-model="v" type="text">{{ script.interpolate(value.text) }}</ui-input>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
script: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
v: this.value.default,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
v() {
|
||||||
|
this.script.aiScript.updatePageVar(this.value.name, this.v);
|
||||||
|
this.script.reEval();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.kudkigyw
|
||||||
|
display inline-block
|
||||||
|
min-width 300px
|
||||||
|
max-width 450px
|
||||||
|
margin 8px 0
|
||||||
|
</style>
|
|
@ -0,0 +1,36 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<ui-textarea class="" v-model="v">{{ script.interpolate(value.text) }}</ui-textarea>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
script: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
v: this.value.default,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
v() {
|
||||||
|
this.script.aiScript.updatePageVar(this.value.name, this.v);
|
||||||
|
this.script.reEval();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
</style>
|
33
src/client/app/common/views/pages/page/page.textarea.vue
Normal file
33
src/client/app/common/views/pages/page/page.textarea.vue
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<template>
|
||||||
|
<ui-textarea class="" :value="text" readonly></ui-textarea>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
script: {
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
text: this.script.interpolate(this.value.text),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
this.$watch('script.vars', () => {
|
||||||
|
this.text = this.script.interpolate(this.value.text);
|
||||||
|
}, { deep: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
</style>
|
|
@ -23,6 +23,7 @@ import { faSave, faStickyNote } from '@fortawesome/free-regular-svg-icons';
|
||||||
import XBlock from './page.block.vue';
|
import XBlock from './page.block.vue';
|
||||||
import { AiScript } from '../../../scripts/aiscript';
|
import { AiScript } from '../../../scripts/aiscript';
|
||||||
import { collectPageVars } from '../../../scripts/collect-page-vars';
|
import { collectPageVars } from '../../../scripts/collect-page-vars';
|
||||||
|
import { url } from '../../../../config';
|
||||||
|
|
||||||
class Script {
|
class Script {
|
||||||
public aiScript: AiScript;
|
public aiScript: AiScript;
|
||||||
|
@ -82,7 +83,9 @@ export default Vue.extend({
|
||||||
this.script = new Script(new AiScript(this.page.variables, pageVars, {
|
this.script = new Script(new AiScript(this.page.variables, pageVars, {
|
||||||
randomSeed: Math.random(),
|
randomSeed: Math.random(),
|
||||||
user: page.user,
|
user: page.user,
|
||||||
visitor: this.$store.state.i
|
visitor: this.$store.state.i,
|
||||||
|
page: page,
|
||||||
|
url: url
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
|
@ -27,6 +27,33 @@ export class PageRepository extends Repository<Page> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
collectFile(src.content);
|
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({
|
return await awaitAll({
|
||||||
id: src.id,
|
id: src.id,
|
||||||
createdAt: src.createdAt.toISOString(),
|
createdAt: src.createdAt.toISOString(),
|
||||||
|
|
Loading…
Reference in a new issue