Feat: クリックイベントを発生させるMFM構文を追加 (#12798)
* Update MkMisskeyFlavoredMarkdown.ts * fix MkMisskeyFlavoredMarkdown.ts * Update MkAsUi.vue * Update ui.ts * Fix MkMisskeyFlavoredMarkdown.ts * Update CHANGELOG.md * fix ui.ts * revert CHANGELOG.md * Update CHANGELOG.md
This commit is contained in:
parent
95547da5a5
commit
4f247a0784
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
### Client
|
### Client
|
||||||
- Fix: 一部のモデログ(logYellowでの表示対象)について、表示の色が変わらない問題を修正
|
- Fix: 一部のモデログ(logYellowでの表示対象)について、表示の色が変わらない問題を修正
|
||||||
|
- Feat: AiScript専用のMFM構文`$[clickable.ev=EVENTNAME ...]`を追加。`Mk:C:mfm`のオプション`onClickEv`に関数を渡すと、クリック時に`EVENTNAME`を引数にして呼び出す
|
||||||
|
|
||||||
### Server
|
### Server
|
||||||
- Enhance: センシティブワードの設定がハッシュタグトレンドにも適用されるようになりました
|
- Enhance: センシティブワードの設定がハッシュタグトレンドにも適用されるようになりました
|
||||||
|
@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<span v-else-if="c.type === 'text'" :class="{ [$style.fontSerif]: c.font === 'serif', [$style.fontMonospace]: c.font === 'monospace' }" :style="{ fontSize: c.size ? `${c.size * 100}%` : null, fontWeight: c.bold ? 'bold' : null, color: c.color ?? null }">{{ c.text }}</span>
|
<span v-else-if="c.type === 'text'" :class="{ [$style.fontSerif]: c.font === 'serif', [$style.fontMonospace]: c.font === 'monospace' }" :style="{ fontSize: c.size ? `${c.size * 100}%` : null, fontWeight: c.bold ? 'bold' : null, color: c.color ?? null }">{{ c.text }}</span>
|
||||||
<Mfm v-else-if="c.type === 'mfm'" :class="{ [$style.fontSerif]: c.font === 'serif', [$style.fontMonospace]: c.font === 'monospace' }" :style="{ fontSize: c.size ? `${c.size * 100}%` : null, fontWeight: c.bold ? 'bold' : null, color: c.color ?? null }" :text="c.text"/>
|
<Mfm v-else-if="c.type === 'mfm'" :class="{ [$style.fontSerif]: c.font === 'serif', [$style.fontMonospace]: c.font === 'monospace' }" :style="{ fontSize: c.size ? `${c.size * 100}%` : null, fontWeight: c.bold ? 'bold' : null, color: c.color ?? null }" :text="c.text" @clickEv="c.onClickEv"/>
|
||||||
<MkButton v-else-if="c.type === 'button'" :primary="c.primary" :rounded="c.rounded" :disabled="c.disabled" :small="size === 'small'" inline @click="c.onClick">{{ c.text }}</MkButton>
|
<MkButton v-else-if="c.type === 'button'" :primary="c.primary" :rounded="c.rounded" :disabled="c.disabled" :small="size === 'small'" inline @click="c.onClick">{{ c.text }}</MkButton>
|
||||||
<div v-else-if="c.type === 'buttons'" class="_buttons" :style="{ justifyContent: align }">
|
<div v-else-if="c.type === 'buttons'" class="_buttons" :style="{ justifyContent: align }">
|
||||||
<MkButton v-for="button in c.buttons" :primary="button.primary" :rounded="button.rounded" :disabled="button.disabled" inline :small="size === 'small'" @click="button.onClick">{{ button.text }}</MkButton>
|
<MkButton v-for="button in c.buttons" :primary="button.primary" :rounded="button.rounded" :disabled="button.disabled" inline :small="size === 'small'" @click="button.onClick">{{ button.text }}</MkButton>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* SPDX-License-Identifier: AGPL-3.0-only
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { VNode, h } from 'vue';
|
import { VNode, h, SetupContext } from 'vue';
|
||||||
import * as mfm from 'mfm-js';
|
import * as mfm from 'mfm-js';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import MkUrl from '@/components/global/MkUrl.vue';
|
import MkUrl from '@/components/global/MkUrl.vue';
|
||||||
@ -43,8 +43,12 @@ type MfmProps = {
|
|||||||
enableEmojiMenuReaction?: boolean;
|
enableEmojiMenuReaction?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type MfmEvents = {
|
||||||
|
clickEv(id: string): void;
|
||||||
|
};
|
||||||
|
|
||||||
// eslint-disable-next-line import/no-default-export
|
// eslint-disable-next-line import/no-default-export
|
||||||
export default function(props: MfmProps) {
|
export default function(props: MfmProps, context: SetupContext<MfmEvents>) {
|
||||||
const isNote = props.isNote ?? true;
|
const isNote = props.isNote ?? true;
|
||||||
const shouldNyaize = props.nyaize ? props.nyaize === 'respect' ? props.author?.isCat : false : false;
|
const shouldNyaize = props.nyaize ? props.nyaize === 'respect' ? props.author?.isCat : false : false;
|
||||||
|
|
||||||
@ -281,6 +285,13 @@ export default function(props: MfmProps) {
|
|||||||
}),
|
}),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
case 'clickable': {
|
||||||
|
return h('span', { onClick(ev: MouseEvent): void {
|
||||||
|
ev.stopPropagation();
|
||||||
|
ev.preventDefault();
|
||||||
|
context.emit('clickEv', token.props.args.ev ?? '');
|
||||||
|
} }, genEl(token.children, scale));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (style === undefined) {
|
if (style === undefined) {
|
||||||
return h('span', {}, ['$[', token.props.name, ' ', ...genEl(token.children, scale), ']']);
|
return h('span', {}, ['$[', token.props.name, ' ', ...genEl(token.children, scale), ']']);
|
||||||
|
@ -47,6 +47,7 @@ export type AsUiMfm = AsUiComponentBase & {
|
|||||||
bold?: boolean;
|
bold?: boolean;
|
||||||
color?: string;
|
color?: string;
|
||||||
font?: 'serif' | 'sans-serif' | 'monospace';
|
font?: 'serif' | 'sans-serif' | 'monospace';
|
||||||
|
onClickEv?: (evId: string) => void
|
||||||
};
|
};
|
||||||
|
|
||||||
export type AsUiButton = AsUiComponentBase & {
|
export type AsUiButton = AsUiComponentBase & {
|
||||||
@ -230,6 +231,8 @@ function getMfmOptions(def: values.Value | undefined): Omit<AsUiMfm, 'id' | 'typ
|
|||||||
if (color) utils.assertString(color);
|
if (color) utils.assertString(color);
|
||||||
const font = def.value.get('font');
|
const font = def.value.get('font');
|
||||||
if (font) utils.assertString(font);
|
if (font) utils.assertString(font);
|
||||||
|
const onClickEv = def.value.get('onClickEv');
|
||||||
|
if (onClickEv) utils.assertFunction(onClickEv);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
text: text?.value,
|
text: text?.value,
|
||||||
@ -237,6 +240,9 @@ function getMfmOptions(def: values.Value | undefined): Omit<AsUiMfm, 'id' | 'typ
|
|||||||
bold: bold?.value,
|
bold: bold?.value,
|
||||||
color: color?.value,
|
color: color?.value,
|
||||||
font: font?.value,
|
font: font?.value,
|
||||||
|
onClickEv: (evId: string) => {
|
||||||
|
if (onClickEv) call(onClickEv, values.STR(evId));
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user