feat(client): AiScript: ノート書き換えAPI

This commit is contained in:
syuilo 2020-07-29 01:15:02 +09:00
parent 595ad04ddb
commit 30df8ea121
5 changed files with 30 additions and 8 deletions

View file

@ -47,7 +47,7 @@
"@koa/multer": "3.0.0", "@koa/multer": "3.0.0",
"@koa/router": "9.0.1", "@koa/router": "9.0.1",
"@sinonjs/fake-timers": "6.0.1", "@sinonjs/fake-timers": "6.0.1",
"@syuilo/aiscript": "0.8.0", "@syuilo/aiscript": "0.9.0",
"@types/bcryptjs": "2.4.2", "@types/bcryptjs": "2.4.2",
"@types/bull": "3.14.0", "@types/bull": "3.14.0",
"@types/cbor": "5.0.0", "@types/cbor": "5.0.0",

View file

@ -35,19 +35,19 @@
</div> </div>
</div> </div>
<article class="article"> <article class="article">
<mk-avatar class="avatar" :user="appearNote.user" v-once/> <mk-avatar class="avatar" :user="appearNote.user"/>
<div class="main"> <div class="main">
<x-note-header class="header" :note="appearNote" :mini="true"/> <x-note-header class="header" :note="appearNote" :mini="true"/>
<div class="body" ref="noteBody"> <div class="body" ref="noteBody">
<p v-if="appearNote.cw != null" class="cw"> <p v-if="appearNote.cw != null" class="cw">
<mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis" v-once/> <mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis"/>
<x-cw-button v-model="showContent" :note="appearNote"/> <x-cw-button v-model="showContent" :note="appearNote"/>
</p> </p>
<div class="content" v-show="appearNote.cw == null || showContent"> <div class="content" v-show="appearNote.cw == null || showContent">
<div class="text"> <div class="text">
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ $t('private') }})</span> <span v-if="appearNote.isHidden" style="opacity: 0.5">({{ $t('private') }})</span>
<router-link class="reply" v-if="appearNote.replyId" :to="`/notes/${appearNote.replyId}`"><fa :icon="faReply"/></router-link> <router-link class="reply" v-if="appearNote.replyId" :to="`/notes/${appearNote.replyId}`"><fa :icon="faReply"/></router-link>
<mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis" v-once/> <mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$store.state.i" :custom-emojis="appearNote.emojis"/>
<a class="rp" v-if="appearNote.renote != null">RN:</a> <a class="rp" v-if="appearNote.renote != null">RN:</a>
</div> </div>
<div class="files" v-if="appearNote.files.length > 0"> <div class="files" v-if="appearNote.files.length > 0">
@ -114,6 +114,7 @@ import { focusPrev, focusNext } from '../scripts/focus';
import { url } from '../config'; import { url } from '../config';
import copyToClipboard from '../scripts/copy-to-clipboard'; import copyToClipboard from '../scripts/copy-to-clipboard';
import { checkWordMute } from '../scripts/check-word-mute'; import { checkWordMute } from '../scripts/check-word-mute';
import { utils } from '@syuilo/aiscript';
export default Vue.extend({ export default Vue.extend({
model: { model: {
@ -246,6 +247,15 @@ export default Vue.extend({
this.connection = this.$root.stream; this.connection = this.$root.stream;
} }
// plugin
if (this.$store.state.noteViewInterruptors.length > 0) {
let result = this.note;
for (const interruptor of this.$store.state.noteViewInterruptors) {
result = utils.valToJs(await interruptor.handler(JSON.parse(JSON.stringify(result))));
}
this.$emit('updated', Object.freeze(result));
}
this.muted = await checkWordMute(this.appearNote, this.$store.state.i, this.$store.state.settings.mutedWords); this.muted = await checkWordMute(this.appearNote, this.$store.state.i, this.$store.state.settings.mutedWords);
if (this.detail) { if (this.detail) {

View file

@ -70,6 +70,9 @@ export function createPluginEnv(vm, opts) {
'Plugin:register_note_action': values.FN_NATIVE(([title, handler]) => { 'Plugin:register_note_action': values.FN_NATIVE(([title, handler]) => {
vm.$store.commit('registerNoteAction', { pluginId: opts.plugin.id, title: title.value, handler }); vm.$store.commit('registerNoteAction', { pluginId: opts.plugin.id, title: title.value, handler });
}), }),
'Plugin:register_note_view_interruptor': values.FN_NATIVE(([handler]) => {
vm.$store.commit('registerNoteViewInterruptor', { pluginId: opts.plugin.id, handler });
}),
'Plugin:config': values.OBJ(config), 'Plugin:config': values.OBJ(config),
}; };
} }

View file

@ -111,6 +111,7 @@ export default () => new Vuex.Store({
postFormActions: [], postFormActions: [],
userActions: [], userActions: [],
noteActions: [], noteActions: [],
noteViewInterruptors: [],
}, },
getters: { getters: {
@ -274,6 +275,14 @@ export default () => new Vuex.Store({
} }
}); });
}, },
registerNoteViewInterruptor(state, { pluginId, handler }) {
state.noteViewInterruptors.push({
handler: (note) => {
return state.pluginContexts.get(pluginId).execFn(handler, [utils.jsToVal(note)]);
}
});
},
}, },
actions: { actions: {

View file

@ -192,10 +192,10 @@
dependencies: dependencies:
"@sinonjs/commons" "^1.7.0" "@sinonjs/commons" "^1.7.0"
"@syuilo/aiscript@0.8.0": "@syuilo/aiscript@0.9.0":
version "0.8.0" version "0.9.0"
resolved "https://registry.yarnpkg.com/@syuilo/aiscript/-/aiscript-0.8.0.tgz#3a895ddd9f5bd5afa1648acb5fd3e6f94f434cbb" resolved "https://registry.yarnpkg.com/@syuilo/aiscript/-/aiscript-0.9.0.tgz#95f260989ce1d9d4af49f116a4cc0c30360fcdad"
integrity sha512-mrZ3awYf1R81D+OWZctRFiAWUt6xL3A5ovBn2OD8+1hZyX3T7S+awqrhYVLoQPhd/cijz1RT6PE8AEUtuR1J8Q== integrity sha512-yv/IQgpcAjyKzd8Q87ANAraISOc7X3SHkXUNc3Asv5ABZ4hx8m62+CnPcrNabIuG2PYRnPGef4ImUpavg6C6Ng==
dependencies: dependencies:
autobind-decorator "2.4.0" autobind-decorator "2.4.0"
chalk "4.0.0" chalk "4.0.0"