Compare commits

...

2 commits

Author SHA1 Message Date
97a4f32dfc add explanation for meta mfm setting 2025-01-11 19:12:08 +01:00
d3b5ce855b Add meta mfm 2025-01-11 18:41:45 +01:00
9 changed files with 118 additions and 1 deletions

View file

@ -517,6 +517,9 @@ noHistory: "No history available"
signinHistory: "Login history"
enableAdvancedMfm: "Enable advanced MFM"
enableAnimatedMfm: "Enable animated MFM"
enableMetaMfm: "Enable meta MFM"
enableMetaMfmExplanation: "Meta MFM allows posts to dynamically change based on you and your instance. For example with this on A post could say 'Hello [Username]'"
postUsingMetaMfm: "This post is using the meta mfm tag and so its content may change according to your instance, name, and other things"
doing: "Processing..."
category: "Category"
tags: "Aliases"

8
locales/index.d.ts vendored
View file

@ -2096,6 +2096,14 @@ export interface Locale extends ILocale {
* MFMを有効にする
*/
"enableAnimatedMfm": string;
/**
* 稿mfmタグを使用しているため
*/
"postUsingMetaMfm": string;
/**
* Meta MFM 使稿稿Hello []
*/
"enableMetaMfmExplanation": string;
/**
*
*/

View file

@ -520,6 +520,8 @@ noHistory: "履歴はありません"
signinHistory: "ログイン履歴"
enableAdvancedMfm: "高度なMFMを有効にする"
enableAnimatedMfm: "動きのあるMFMを有効にする"
postUsingMetaMfm: "この投稿はメタmfmタグを使用しているため、インスタンス、名前、その他の要素に応じて内容が変わる可能性があります。"
enableMetaMfmExplanation: "Meta MFM を使用すると、ユーザーとインスタンスに基づいて投稿を動的に変更できます。たとえば、これを投稿すると、「Hello [ユーザー名]」と言うことができます。"
doing: "やっています"
category: "カテゴリ"
tags: "タグ"

View file

@ -0,0 +1,70 @@
Components/FkMfmMeta.vue
<template>
<span v-tooltip="i18n.ts.postUsingMetaMfm" :class="$style.special">
<span v-if="props.type==='userName'">
{{metaMfmEnabled ? $i.username : 'you'}}
</span>
<span v-else-if="props.type==='instanceName'">
{{metaMfmEnabled ? loc : 'your instance'}}
</span>
<span v-else-if="props.query">
<span v-if="!metaMfmEnabled">
<slot></slot>
</span>
<span v-else-if="props.hastype==='username' && invertIfHasnt($i.username.includes(props.query))">
<slot></slot>
</span>
<span v-else-if="props.hastype==='desc' && invertIfHasnt($i.description.includes(props.query))">
<slot></slot>
</span>
<span v-else-if="props.hastype==='fields' && invertIfHasnt($i.fields.filter(e => e.value.includes(props.query)).length > 0)">
<slot></slot>
</span>
<span v-else-if="props.hastype==='iscat' && invertIfHasnt(invertIfHasnt($i.isCat))">
<slot></slot>
</span>
</span>
</span>
</template>
<script lang="ts" setup>
import { shallowRef } from 'vue';
import {$i} from "../account.js";
import {i18n} from "@/i18n.js";
import {defaultStore} from "../store.js";
const loc = location.hostname.toString();
const metaMfmEnabled = defaultStore.state.metaMfm;
const el = shallowRef<HTMLElement>();
const container = shallowRef<HTMLElement>();
const props = defineProps({
type: {
type: String,
//Can be 'desc' | 'instanceName' | 'userName' | 'has' | 'hasnt'
default: 'has',
},
query: {
type: String,
default: 'forkey',
},
hastype: {
type: String,
//Can be 'username' | 'instancename' | 'isCat'
default: 'username',
},
userName: {
type: Boolean,
default: true,
},
instanceName: {
type: Boolean,
default: false,
},
});
function invertIfHasnt(condition: boolean) {
return props.type === 'has' ? condition : !condition;
}
</script>

View file

@ -21,6 +21,7 @@ import { host } from '@/config.js';
import { defaultStore } from '@/store.js';
import { nyaize as doNyaize } from '@/scripts/nyaize.js';
import { safeParseFloat } from '@/scripts/safe-parse.js';
import FkMfmMeta from "@/components/FkMfmMeta.vue";
const QUOTE_STYLE = `
display: block;
@ -342,6 +343,29 @@ export default function (props: MfmProps, { emit }: { emit: SetupContext<MfmEven
}),
]);
}
case 'meta': {
let type = 'userName'
if (token.props.args.instance) {
type = 'instanceName';
}
if (token.props.args.has) {
type = 'has';
}
else if (token.props.args.hasnt) {
type = 'hasnt';
}
return h(FkMfmMeta, {
type,
userName: token.props.args.user,
instanceName: token.props.args.instance,
query: token.props.args.has ?? token.props.args.hasnt,
hastype: token.props.args.hastype,
}, genEl(token.children, scale));
}
case 'clickable': {
return h('span', { onClick(ev: MouseEvent): void {
ev.stopPropagation();

View file

@ -122,7 +122,7 @@ export const DEFAULT_SERVER_ERROR_IMAGE_URL = 'https://xn--931a.moe/assets/error
export const DEFAULT_NOT_FOUND_IMAGE_URL = 'https://xn--931a.moe/assets/not-found.jpg';
export const DEFAULT_INFO_IMAGE_URL = 'https://xn--931a.moe/assets/info.jpg';
export const MFM_TAGS = ['tada', 'jelly', 'twitch', 'shake', 'spin', 'jump', 'bounce', 'flip', 'x2', 'x3', 'x4', 'scale', 'position', 'fg', 'bg', 'border', 'font', 'blur', 'rainbow', 'sparkle', 'rotate', 'ruby', 'unixtime', 'crop', 'fade'];
export const MFM_TAGS = ['tada', 'jelly', 'twitch', 'shake', 'spin', 'jump', 'bounce', 'flip', 'x2', 'x3', 'x4', 'scale', 'position', 'fg', 'bg', 'border', 'font', 'blur', 'rainbow', 'sparkle', 'rotate', 'ruby', 'unixtime', 'crop', 'fade', 'meta'];
export const MFM_PARAMS: Record<typeof MFM_TAGS[number], string[]> = {
tada: ['speed=', 'delay='],
jelly: ['speed=', 'delay='],
@ -148,4 +148,5 @@ export const MFM_PARAMS: Record<typeof MFM_TAGS[number], string[]> = {
unixtime: [],
fade: ['speed=', 'delay=', 'loop=', 'out'],
crop: ['top=', 'bottom=', 'left=', 'right='],
meta: ['has=', 'hasnt=', 'hastype=', 'user', 'instance']
};

View file

@ -55,6 +55,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSwitch v-model="collapseRenotes">{{ i18n.ts.collapseRenotes }}</MkSwitch>
<MkSwitch v-model="hideMutedNotes">{{ i18n.ts._wordMute.hideMutedNotes }}</MkSwitch>
<MkSwitch v-model="advancedMfm">{{ i18n.ts.enableAdvancedMfm }}</MkSwitch>
<MkSwitch v-if="advancedMfm" v-model="metaMfm">
<template #label>{{ i18n.ts.enableMetaMfm }} <div v-tooltip:dialog="i18n.ts.enableMetaMfmExplanation" class="_button _help"><i class="ti ti-help-circle"></i></div></template>
</MkSwitch>
<MkSwitch v-if="advancedMfm" v-model="animatedMfm">{{ i18n.ts.enableAnimatedMfm }}</MkSwitch>
<MkSwitch v-if="advancedMfm" v-model="enableQuickAddMfmFunction">{{ i18n.ts.enableQuickAddMfmFunction }}</MkSwitch>
<MkSwitch v-model="showRepliesCount">{{ i18n.ts.showRepliesCount }}</MkSwitch>
@ -288,6 +291,7 @@ const useBlurEffectForModal = computed(defaultStore.makeGetterSetter('useBlurEff
const useBlurEffect = computed(defaultStore.makeGetterSetter('useBlurEffect'));
const showGapBetweenNotesInTimeline = computed(defaultStore.makeGetterSetter('showGapBetweenNotesInTimeline'));
const animatedMfm = computed(defaultStore.makeGetterSetter('animatedMfm'));
const metaMfm = computed(defaultStore.makeGetterSetter('metaMfm'));
const advancedMfm = computed(defaultStore.makeGetterSetter('advancedMfm'));
const showRepliesCount = computed(defaultStore.makeGetterSetter('showRepliesCount'));
const showRenotesCount = computed(defaultStore.makeGetterSetter('showRenotesCount'));

View file

@ -70,6 +70,7 @@ const defaultStoreSaveKeys: (keyof typeof defaultStore['state'])[] = [
'highlightSensitiveMedia',
'animation',
'animatedMfm',
'metaMfm',
'advancedMfm',
'showRepliesCount',
'showRenotesCount',

View file

@ -222,6 +222,10 @@ export const defaultStore = markRaw(new Storage('base', {
animatedMfm: {
where: 'device',
default: false,
},
metaMfm: {
where: 'device',
default: true,
},
advancedMfm: {
where: 'device',