diff --git a/CHANGELOG.md b/CHANGELOG.md index c447084e6..266525277 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,20 @@ mongodb: 8. master ブランチに戻す 9. enjoy +11.7.0 (2019/04/30) +------------------- +### Improvements +* MisskeyPagesに ifブロック を追加 +* MisskeyPagesに テキストエリア を追加 +* MisskeyPagesに 複数行テキスト入力 を追加 +* MisskeyPagesに 投稿フォーム を追加 +* MisskeyPagesに 変換系関数 を追加 +* MisskeyPagesでボタンやスイッチなどのテキストに変数使えるように + +### Fixes +* OGPのサイト名を修正 +* デザインの調整 + 11.6.0 (2019/04/29) ------------------- ### Improvements diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index e2bfb2e89..cd29135bd 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1842,6 +1842,7 @@ dev/views/new-app.vue: pages: new-page: "ページの作成" edit-page: "ページの編集" + read-page: "ソースを表示中" page-created: "ページを作成しました" page-updated: "ページを更新しました" are-you-sure-delete: "このページを削除しますか?" @@ -1866,25 +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: "ボタン" - input: "ユーザー入力" - _input: + + if: "もし" + _if: + variable: "変数" + + 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: "ボタンを押したときの動作" @@ -1893,6 +1919,7 @@ pages: _dialog: content: "内容" resetRandom: "乱数をリセット" + script: categories: flow: "制御" @@ -1903,6 +1930,7 @@ pages: value: "値" fn: "関数" text: "テキスト操作" + convert: "変換" blocks: text: "テキスト" multiLineText: "テキスト(複数行)" @@ -2001,8 +2029,14 @@ pages: _dailyRandomPick: arg1: "リスト" number: "数" + stringToNumber: "テキストを数値に" + _stringToNumber: + arg1: "テキスト" + numberToString: "数値をテキストに" + _numberToString: + arg1: "数値" ref: "変数" - in: "入力" + in: "引数" _in: arg1: "スロット番号" fn: "関数" diff --git a/package.json b/package.json index 4161d89e7..3afb01dc5 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "misskey", "author": "syuilo ", - "version": "11.6.0", + "version": "11.7.0", "codename": "daybreak", "repository": { "type": "git", diff --git a/src/client/app/common/scripts/aiscript.ts b/src/client/app/common/scripts/aiscript.ts index fe9a29500..99caec8c1 100644 --- a/src/client/app/common/scripts/aiscript.ts +++ b/src/client/app/common/scripts/aiscript.ts @@ -26,6 +26,7 @@ import { faNotEqual, faDice, faSortNumericUp, + faExchangeAlt, } from '@fortawesome/free-solid-svg-icons'; import { faFlag } from '@fortawesome/free-regular-svg-icons'; @@ -69,11 +70,13 @@ const funcDefs = { strPick: { in: ['string', 'number'], out: 'string', category: 'text', icon: faQuoteRight, }, strReplace: { in: ['string', 'string', 'string'], out: 'string', category: 'text', icon: faQuoteRight, }, strReverse: { in: ['string'], out: 'string', category: 'text', icon: faQuoteRight, }, + stringToNumber: { in: ['string'], out: 'number', category: 'convert', icon: faExchangeAlt, }, + numberToString: { in: ['number'], out: 'string', category: 'convert', icon: faExchangeAlt, }, rannum: { in: ['number', 'number'], out: 'number', category: 'random', icon: faDice, }, - random: { in: ['number'], out: 'boolean', category: 'random', icon: faDice, }, - randomPick: { in: [0], out: 0, category: 'random', icon: faDice, }, dailyRannum: { in: ['number', 'number'], out: 'number', category: 'random', icon: faDice, }, + random: { in: ['number'], out: 'boolean', category: 'random', icon: faDice, }, dailyRandom: { in: ['number'], out: 'boolean', category: 'random', icon: faDice, }, + randomPick: { in: [0], out: 0, category: 'random', icon: faDice, }, dailyRandomPick: { in: [0], out: 0, category: 'random', icon: faDice, }, }; @@ -94,6 +97,7 @@ type PageVar = { name: string; value: any; type: Type; }; const envVarsDef = { AI: 'string', + URL: 'string', VERSION: 'string', LOGIN: 'boolean', NAME: 'string', @@ -117,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'] = {}) { @@ -128,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 : '', @@ -421,6 +426,8 @@ export class AiScript { strPick: (a, b) => a[b - 1], strReplace: (a, b, c) => a.split(b).join(c), strReverse: (a) => a.split('').reverse().join(''), + stringToNumber: (a) => parseInt(a), + numberToString: (a) => a.toString(), random: (probability) => Math.floor(seedrandom(`${this.opts.randomSeed}:${block.id}`)() * 100) < probability, rannum: (min, max) => min + Math.floor(seedrandom(`${this.opts.randomSeed}:${block.id}`)() * (max - min + 1)), randomPick: (list) => list[Math.floor(seedrandom(`${this.opts.randomSeed}:${block.id}`)() * list.length)], diff --git a/src/client/app/common/scripts/collect-page-vars.ts b/src/client/app/common/scripts/collect-page-vars.ts index 86687e21f..92727ce6d 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/page-editor.button.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.button.vue similarity index 93% rename from src/client/app/common/views/components/page-editor/page-editor.button.vue rename to src/client/app/common/views/components/page-editor/els/page-editor.el.button.vue index d5fc24381..3e2d3fe19 100644 --- a/src/client/app/common/views/components/page-editor/page-editor.button.vue +++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.button.vue @@ -16,9 +16,9 @@ + + diff --git a/src/client/app/common/views/components/page-editor/page-editor.image.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.image.vue similarity index 89% rename from src/client/app/common/views/components/page-editor/page-editor.image.vue rename to src/client/app/common/views/components/page-editor/els/page-editor.el.image.vue index 0bc1816e8..5ada8c77b 100644 --- a/src/client/app/common/views/components/page-editor/page-editor.image.vue +++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.image.vue @@ -15,11 +15,11 @@ 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 000000000..a01fc57f2 --- /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/page-editor.section.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.section.vue similarity index 80% rename from src/client/app/common/views/components/page-editor/page-editor.section.vue rename to src/client/app/common/views/components/page-editor/els/page-editor.el.section.vue index d7a247b0b..747de481a 100644 --- a/src/client/app/common/views/components/page-editor/page-editor.section.vue +++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.section.vue @@ -12,7 +12,7 @@
- +
@@ -20,11 +20,11 @@ diff --git a/src/client/app/common/views/components/page-editor/page-editor.text.vue b/src/client/app/common/views/components/page-editor/els/page-editor.el.text.vue similarity index 89% rename from src/client/app/common/views/components/page-editor/page-editor.text.vue rename to src/client/app/common/views/components/page-editor/els/page-editor.el.text.vue index 7368931b2..1d07c9157 100644 --- a/src/client/app/common/views/components/page-editor/page-editor.text.vue +++ b/src/client/app/common/views/components/page-editor/els/page-editor.el.text.vue @@ -10,9 +10,9 @@ 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 000000000..4fbe49796 --- /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 a3e1488d1..7d4505fca 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 @@ -1,25 +1,33 @@ diff --git a/src/client/app/common/views/components/page-editor/page-editor.input.vue b/src/client/app/common/views/components/page-editor/page-editor.input.vue deleted file mode 100644 index 4e1384043..000000000 --- a/src/client/app/common/views/components/page-editor/page-editor.input.vue +++ /dev/null @@ -1,61 +0,0 @@ - - - - - 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 8b2582851..f8959fb0f 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 @@ -2,16 +2,16 @@
-
{{ pageId ? $t('edit-page') : $t('new-page') }}
+
{{ readonly ? $t('read-page') : pageId ? $t('edit-page') : $t('new-page') }}
- + - +
- {{ $t('view-page') }} + {{ $t('view-page') }} {{ $t('title') }} @@ -23,7 +23,7 @@ - + {{ $t('url') }} @@ -45,10 +45,10 @@
- +
- +
@@ -70,7 +70,7 @@
- + {{ $t('more-details') }} @@ -106,11 +106,17 @@ export default Vue.extend({ page: { type: String, required: false - } + }, + readonly: { + type: Boolean, + required: false, + default: false + }, }, data() { return { + author: this.$store.state.i, pageId: null, currentName: null, title: '', @@ -157,6 +163,7 @@ export default Vue.extend({ this.$root.api('pages/show', { pageId: this.page, }).then(page => { + this.author = page.user; this.pageId = page.id; this.title = page.title; this.name = page.name; @@ -180,7 +187,9 @@ export default Vue.extend({ provide() { return { - getScriptBlockList: this.getScriptBlockList + readonly: this.readonly, + getScriptBlockList: this.getScriptBlockList, + getPageBlockList: this.getPageBlockList } }, @@ -250,19 +259,7 @@ export default Vue.extend({ type: null, title: this.$t('choose-block'), select: { - items: [{ - value: 'section', text: this.$t('blocks.section') - }, { - value: 'text', text: this.$t('blocks.text') - }, { - 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') - }] + groupedItems: this.getPageBlockList() }, showCancelButton: true }); @@ -324,6 +321,33 @@ export default Vue.extend({ this.variables = newValue; }, + getPageBlockList() { + return [{ + 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') }, + ] + }, { + 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') } + ] + }, { + label: this.$t('special-blocks'), + items: [ + { value: 'if', text: this.$t('blocks.if') }, + { value: 'post', text: this.$t('blocks.post') } + ] + }]; + }, + getScriptBlockList(type: string = null) { const list = []; @@ -436,6 +460,7 @@ export default Vue.extend({ > .view display inline-block margin 16px 0 0 0 + font-size 14px > .content margin-bottom 16px 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 48a89f9de..f348107cc 100644 --- a/src/client/app/common/views/pages/page/page.block.vue +++ b/src/client/app/common/views/pages/page/page.block.vue @@ -8,12 +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 + XText, XSection, XImage, XButton, XNumberInput, XTextInput, XTextareaInput, XTextarea, XPost, XSwitch, XIf }, props: { diff --git a/src/client/app/common/views/pages/page/page.button.vue b/src/client/app/common/views/pages/page/page.button.vue index 5063d2712..b77d856d5 100644 --- a/src/client/app/common/views/pages/page/page.button.vue +++ b/src/client/app/common/views/pages/page/page.button.vue @@ -1,6 +1,6 @@ diff --git a/src/client/app/common/views/pages/page/page.if.vue b/src/client/app/common/views/pages/page/page.if.vue new file mode 100644 index 000000000..9dbeaf64f --- /dev/null +++ b/src/client/app/common/views/pages/page/page.if.vue @@ -0,0 +1,30 @@ + + + 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 64% 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 cda555033..51d538c36 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 000000000..cb695e21e --- /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.switch.vue b/src/client/app/common/views/pages/page/page.switch.vue index 962ab84bb..a401e5dfb 100644 --- a/src/client/app/common/views/pages/page/page.switch.vue +++ b/src/client/app/common/views/pages/page/page.switch.vue @@ -1,6 +1,6 @@ @@ -36,4 +36,8 @@ export default Vue.extend({ .hkcxmtwj display inline-block margin 16px auto + + & + .hkcxmtwj + margin-left 16px + 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 000000000..3d659edd5 --- /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 000000000..fd8174c27 --- /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 000000000..03c8542cb --- /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 e7e8f76d5..88598d352 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; @@ -38,6 +39,7 @@ class Script { } public interpolate(str: string) { + if (str == null) return null; return str.replace(/\{(.+?)\}/g, match => { const v = this.vars.find(x => x.name === match.slice(1, -1).trim()).value; return v == null ? 'NULL' : v.toString(); @@ -81,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/client/app/mobile/views/pages/page.vue b/src/client/app/mobile/views/pages/page.vue index 27ade4a39..f494abffd 100644 --- a/src/client/app/mobile/views/pages/page.vue +++ b/src/client/app/mobile/views/pages/page.vue @@ -33,4 +33,7 @@ main padding 16px max-width 1000px + @media (min-width 600px) + padding 32px + diff --git a/src/models/entities/instance.ts b/src/models/entities/instance.ts index 977054263..52c5215f1 100644 --- a/src/models/entities/instance.ts +++ b/src/models/entities/instance.ts @@ -71,7 +71,7 @@ export class Instance { /** * ドライブ使用量 */ - @Column('integer', { + @Column('bigint', { default: 0, }) public driveUsage: number; diff --git a/src/models/repositories/page.ts b/src/models/repositories/page.ts index 4c1b4cc79..cbe385568 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(), diff --git a/src/server/web/views/base.pug b/src/server/web/views/base.pug index e61d29685..733a306d5 100644 --- a/src/server/web/views/base.pug +++ b/src/server/web/views/base.pug @@ -11,7 +11,7 @@ html meta(name='application-name' content='Misskey') meta(name='referrer' content='origin') meta(name='theme-color' content='#105779') - meta(property='og:site_name' content= title || 'Misskey') + meta(property='og:site_name' content= instanceName || 'Misskey') link(rel='icon' href= icon || '/favicon.ico') link(rel='manifest' href='/manifest.json')