diff --git a/CHANGELOG.md b/CHANGELOG.md index 984061f238..a0c760b47e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ You should also include the user name that made the change. ### Improvements - コンディショナルロールもバッジとして表示可能に - enhance(client): 一度見たノートのRenoteは省略して表示するように +- 一部のMFM構文をopt-inに ### Bugfixes - diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 79b78f3f98..031e90215f 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -467,7 +467,8 @@ youHaveNoGroups: "グループがありません" joinOrCreateGroup: "既存のグループに招待してもらうか、新しくグループを作成してください。" noHistory: "履歴はありません" signinHistory: "ログイン履歴" -disableAnimatedMfm: "動きのあるMFMを無効にする" +enableAdvancedMfm: "高度なMFMを有効にする" +enableAnimatedMfm: "動きのあるMFMを有効にする" doing: "やっています" category: "カテゴリ" tags: "タグ" @@ -1347,73 +1348,6 @@ _nsfw: ignore: "閲覧注意のメディアを隠さない" force: "常にメディアを隠す" -_mfm: - cheatSheet: "MFMチートシート" - intro: "MFMは、Misskey内の様々な場所で使用できる専用のマークアップ言語です。ここでは、MFMで使用可能な構文一覧が確認できます。" - dummy: "MisskeyでFediverseの世界が広がります" - mention: "メンション" - mentionDescription: "アットマーク + ユーザー名で、特定のユーザーを示すことができます。" - hashtag: "ハッシュタグ" - hashtagDescription: "ナンバーサイン + タグで、ハッシュタグを示すことができます。" - url: "URL" - urlDescription: "URLを示すことができます。" - link: "リンク" - linkDescription: "文章の特定の範囲を、URLに紐づけることができます。" - bold: "太字" - boldDescription: "文字を太く表示して強調することができます。" - small: "目立たなく" - smallDescription: "内容を小さく・薄く表示させることができます。" - center: "中央寄せ" - centerDescription: "内容を中央寄せで表示させることができます。" - inlineCode: "コード(インライン)" - inlineCodeDescription: "プログラムなどのコードをインラインでシンタックスハイライトします。" - blockCode: "コード(ブロック)" - blockCodeDescription: "複数行のプログラムなどのコードをブロックでシンタックスハイライトします。" - inlineMath: "数式(インライン)" - inlineMathDescription: "数式(KaTeX)をインラインで表示します。" - blockMath: "数式(ブロック)" - blockMathDescription: "複数行の数式(KaTeX)をブロックで表示します。" - quote: "引用" - quoteDescription: "内容が引用であることを示すことができます。" - emoji: "カスタム絵文字" - emojiDescription: "コロンでカスタム絵文字名を囲むと、カスタム絵文字を表示させることができます。" - search: "検索" - searchDescription: "入力済み検索ボックスを表示させることができます。" - flip: "反転" - flipDescription: "内容を上下または左右に反転させます。" - jelly: "アニメーション(びよんびよん)" - jellyDescription: "びよんびよんするアニメーションを与えます。" - tada: "アニメーション(じゃーん)" - tadaDescription: "ジャーン!という感じのアニメーションを与えます。" - jump: "アニメーション(ジャンプ)" - jumpDescription: "飛び跳ねるようなアニメーションを与えます。" - bounce: "アニメーション(バウンド)" - bounceDescription: "ぽよんぽよん弾むようなアニメーションを与えます。" - shake: "アニメーション(ぶるぶる)" - shakeDescription: "ぶるぶる震えるアニメーションを与えます。" - twitch: "アニメーション(ブレ)" - twitchDescription: "激しくブレるアニメーションを与えます。" - spin: "アニメーション(回転)" - spinDescription: "回転するアニメーションを与えます。" - x2: "大きく" - x2Description: "内容を大きく表示します。" - x3: "とても大きく" - x3Description: "内容をとても大きく表示します。" - x4: "究極に大きく" - x4Description: "内容を究極に大きく表示します。" - blur: "ぼかし" - blurDescription: "内容をぼかすことができます。ポインターを上に乗せるとはっきり見えるようになります。" - font: "フォント" - fontDescription: "内容のフォントを指定することができます。" - rainbow: "レインボー" - rainbowDescription: "内容をレインボーにします。" - sparkle: "キラキラ" - sparkleDescription: "キラキラしたパーティクルのエフェクトを追加します。" - rotate: "回転" - rotateDescription: "指定した角度で回転させます。" - plain: "プレーン" - plainDescription: "内側の構文を全て無効にします。" - _instanceTicker: none: "表示しない" remote: "リモートユーザーに表示" diff --git a/packages/frontend/src/components/mfm.ts b/packages/frontend/src/components/mfm.ts index 8cc35e4781..816a42a5fb 100644 --- a/packages/frontend/src/components/mfm.ts +++ b/packages/frontend/src/components/mfm.ts @@ -65,6 +65,8 @@ export default defineComponent({ return t.match(/^[0-9.]+s$/) ? t : null; }; + const useAnim = defaultStore.state.advancedMfm && defaultStore.state.animatedMfm; + const genEl = (ast: mfm.MfmNode[]) => ast.map((token): VNode | string | (VNode | string)[] => { switch (token.type) { case 'text': { @@ -103,22 +105,22 @@ export default defineComponent({ switch (token.props.name) { case 'tada': { const speed = validTime(token.props.args.speed) ?? '1s'; - style = 'font-size: 150%;' + (defaultStore.state.animatedMfm ? `animation: tada ${speed} linear infinite both;` : ''); + style = 'font-size: 150%;' + (useAnim ? `animation: tada ${speed} linear infinite both;` : ''); break; } case 'jelly': { const speed = validTime(token.props.args.speed) ?? '1s'; - style = (defaultStore.state.animatedMfm ? `animation: mfm-rubberBand ${speed} linear infinite both;` : ''); + style = (useAnim ? `animation: mfm-rubberBand ${speed} linear infinite both;` : ''); break; } case 'twitch': { const speed = validTime(token.props.args.speed) ?? '0.5s'; - style = defaultStore.state.animatedMfm ? `animation: mfm-twitch ${speed} ease infinite;` : ''; + style = useAnim ? `animation: mfm-twitch ${speed} ease infinite;` : ''; break; } case 'shake': { const speed = validTime(token.props.args.speed) ?? '0.5s'; - style = defaultStore.state.animatedMfm ? `animation: mfm-shake ${speed} ease infinite;` : ''; + style = useAnim ? `animation: mfm-shake ${speed} ease infinite;` : ''; break; } case 'spin': { @@ -131,17 +133,17 @@ export default defineComponent({ token.props.args.y ? 'mfm-spinY' : 'mfm-spin'; const speed = validTime(token.props.args.speed) ?? '1.5s'; - style = defaultStore.state.animatedMfm ? `animation: ${anime} ${speed} linear infinite; animation-direction: ${direction};` : ''; + style = useAnim ? `animation: ${anime} ${speed} linear infinite; animation-direction: ${direction};` : ''; break; } case 'jump': { const speed = validTime(token.props.args.speed) ?? '0.75s'; - style = defaultStore.state.animatedMfm ? `animation: mfm-jump ${speed} linear infinite;` : ''; + style = useAnim ? `animation: mfm-jump ${speed} linear infinite;` : ''; break; } case 'bounce': { const speed = validTime(token.props.args.speed) ?? '0.75s'; - style = defaultStore.state.animatedMfm ? `animation: mfm-bounce ${speed} linear infinite; transform-origin: center bottom;` : ''; + style = useAnim ? `animation: mfm-bounce ${speed} linear infinite; transform-origin: center bottom;` : ''; break; } case 'flip': { @@ -154,17 +156,17 @@ export default defineComponent({ } case 'x2': { return h('span', { - class: 'mfm-x2', + class: defaultStore.state.advancedMfm ? 'mfm-x2' : '', }, genEl(token.children)); } case 'x3': { return h('span', { - class: 'mfm-x3', + class: defaultStore.state.advancedMfm ? 'mfm-x3' : '', }, genEl(token.children)); } case 'x4': { return h('span', { - class: 'mfm-x4', + class: defaultStore.state.advancedMfm ? 'mfm-x4' : '', }, genEl(token.children)); } case 'font': { @@ -186,11 +188,11 @@ export default defineComponent({ } case 'rainbow': { const speed = validTime(token.props.args.speed) ?? '1s'; - style = defaultStore.state.animatedMfm ? `animation: mfm-rainbow ${speed} linear infinite;` : ''; + style = useAnim ? `animation: mfm-rainbow ${speed} linear infinite;` : ''; break; } case 'sparkle': { - if (!defaultStore.state.animatedMfm) { + if (!useAnim) { return genEl(token.children); } return h(MkSparkle, {}, genEl(token.children)); @@ -201,12 +203,17 @@ export default defineComponent({ break; } case 'position': { + if (!defaultStore.state.advancedMfm) break; const x = parseFloat(token.props.args.x ?? '0'); const y = parseFloat(token.props.args.y ?? '0'); style = `transform: translateX(${x}em) translateY(${y}em);`; break; } case 'scale': { + if (!defaultStore.state.advancedMfm) { + style = ''; + break; + } const x = Math.min(parseFloat(token.props.args.x ?? '1'), 5); const y = Math.min(parseFloat(token.props.args.y ?? '1'), 5); style = `transform: scale(${x}, ${y});`; diff --git a/packages/frontend/src/pages/mfm-cheat-sheet.vue b/packages/frontend/src/pages/mfm-cheat-sheet.vue deleted file mode 100644 index 73a5716236..0000000000 --- a/packages/frontend/src/pages/mfm-cheat-sheet.vue +++ /dev/null @@ -1,377 +0,0 @@ - - - - - diff --git a/packages/frontend/src/pages/settings/general.vue b/packages/frontend/src/pages/settings/general.vue index 0ce66b065f..b4851df176 100644 --- a/packages/frontend/src/pages/settings/general.vue +++ b/packages/frontend/src/pages/settings/general.vue @@ -45,7 +45,8 @@
- {{ i18n.ts.disableAnimatedMfm }} + {{ i18n.ts.enableAdvancedMfm }} + {{ i18n.ts.enableAnimatedMfm }} {{ i18n.ts.reduceUiAnimation }} {{ i18n.ts.useBlurEffect }} {{ i18n.ts.useBlurEffectForModal }} @@ -142,7 +143,8 @@ const reduceAnimation = computed(defaultStore.makeGetterSetter('animation', v => const useBlurEffectForModal = computed(defaultStore.makeGetterSetter('useBlurEffectForModal')); const useBlurEffect = computed(defaultStore.makeGetterSetter('useBlurEffect')); const showGapBetweenNotesInTimeline = computed(defaultStore.makeGetterSetter('showGapBetweenNotesInTimeline')); -const disableAnimatedMfm = computed(defaultStore.makeGetterSetter('animatedMfm', v => !v, v => !v)); +const animatedMfm = computed(defaultStore.makeGetterSetter('animatedMfm')); +const advancedMfm = computed(defaultStore.makeGetterSetter('advancedMfm')); const emojiStyle = computed(defaultStore.makeGetterSetter('emojiStyle')); const disableDrawer = computed(defaultStore.makeGetterSetter('disableDrawer')); const disableShowingAnimatedImages = computed(defaultStore.makeGetterSetter('disableShowingAnimatedImages')); diff --git a/packages/frontend/src/pages/settings/preferences-backups.vue b/packages/frontend/src/pages/settings/preferences-backups.vue index 87a08612fc..0512a8d0c9 100644 --- a/packages/frontend/src/pages/settings/preferences-backups.vue +++ b/packages/frontend/src/pages/settings/preferences-backups.vue @@ -62,6 +62,7 @@ const defaultStoreSaveKeys: (keyof typeof defaultStore['state'])[] = [ 'nsfw', 'animation', 'animatedMfm', + 'advancedMfm', 'loadRawImages', 'imageNewTab', 'disableShowingAnimatedImages', diff --git a/packages/frontend/src/router.ts b/packages/frontend/src/router.ts index 87d42c5c87..9004262689 100644 --- a/packages/frontend/src/router.ts +++ b/packages/frontend/src/router.ts @@ -224,9 +224,6 @@ export const routes = [{ path: '/api-console', component: page(() => import('./pages/api-console.vue')), loginRequired: true, -}, { - path: '/mfm-cheat-sheet', - component: page(() => import('./pages/mfm-cheat-sheet.vue')), }, { path: '/scratchpad', component: page(() => import('./pages/scratchpad.vue')), diff --git a/packages/frontend/src/store.ts b/packages/frontend/src/store.ts index 94892ff526..9ad931ee80 100644 --- a/packages/frontend/src/store.ts +++ b/packages/frontend/src/store.ts @@ -158,6 +158,10 @@ export const defaultStore = markRaw(new Storage('base', { where: 'device', default: false, }, + advancedMfm: { + where: 'device', + default: false, + }, loadRawImages: { where: 'device', default: false,