diff options
Diffstat (limited to 'packages/frontend/src/components/MkNoteDetailed.vue')
| -rw-r--r-- | packages/frontend/src/components/MkNoteDetailed.vue | 80 |
1 files changed, 32 insertions, 48 deletions
diff --git a/packages/frontend/src/components/MkNoteDetailed.vue b/packages/frontend/src/components/MkNoteDetailed.vue index 52cc836926..7f38b9ec02 100644 --- a/packages/frontend/src/components/MkNoteDetailed.vue +++ b/packages/frontend/src/components/MkNoteDetailed.vue @@ -89,21 +89,21 @@ SPDX-License-Identifier: AGPL-3.0-only </p> <div v-show="mergedCW == null || showContent"> <span v-if="appearNote.isHidden" style="opacity: 0.5">({{ i18n.ts.private }})</span> - <MkA v-if="appearNote.replyId" :class="$style.noteReplyTarget" :to="`/notes/${appearNote.replyId}`"><i class="ph-arrow-bend-left-up ph-bold ph-lg"></i></MkA> - <Mfm - v-if="appearNote.text" - :parsedNodes="parsed" - :text="appearNote.text" - :author="appearNote.user" - :nyaize="'respect'" - :emojiUrls="appearNote.emojis" - :enableEmojiMenu="true" - :enableEmojiMenuReaction="true" - :isAnim="allowAnim" - :isBlock="true" - class="_selectable" - /> - <a v-if="appearNote.renote != null" :class="$style.rn">RN:</a> + <div> + <MkA v-if="appearNote.replyId" :class="$style.noteReplyTarget" :to="`/notes/${appearNote.replyId}`"><i class="ph-arrow-bend-left-up ph-bold ph-lg"></i></MkA> + <Mfm + v-if="appearNote.text" + :parsedNodes="parsed" + :text="appearNote.text" + :author="appearNote.user" + :nyaize="'respect'" + :emojiUrls="appearNote.emojis" + :enableEmojiMenu="true" + :enableEmojiMenuReaction="true" + :isAnim="allowAnim" + class="_selectable" + /> + </div> <SkNoteTranslation :note="note" :translation="translation" :translating="translating"></SkNoteTranslation> <MkButton v-if="!allowAnim && animated" :class="$style.playMFMButton" :small="true" @click="animatedMFM()" @click.stop><i class="ph-play ph-bold ph-lg "></i> {{ i18n.ts._animatedMFM.play }}</MkButton> <MkButton v-else-if="!prefer.s.animatedMfm && allowAnim && animated" :class="$style.playMFMButton" :small="true" @click="animatedMFM()" @click.stop><i class="ph-stop ph-bold ph-lg "></i> {{ i18n.ts._animatedMFM.stop }}</MkButton> @@ -112,13 +112,13 @@ SPDX-License-Identifier: AGPL-3.0-only </div> <MkPoll v-if="appearNote.poll" ref="pollViewer" :noteId="appearNote.id" :poll="appearNote.poll" :local="!appearNote.user.host" :class="$style.poll" :author="appearNote.user" :emojiUrls="appearNote.emojis"/> <div v-if="isEnabledUrlPreview"> - <MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="true" :showAsQuote="!appearNote.user.rejectQuotes" :skipNoteIds="selfNoteIds" style="margin-top: 6px;"/> + <SkUrlPreviewGroup :sourceNodes="nodes" :sourceNote="appearNote" :compact="true" :detail="true" :showAsQuote="!appearNote.user.rejectQuotes" :skipNoteIds="selfNoteIds" style="margin-top: 6px;" @click.stop/> </div> <div v-if="appearNote.renote" :class="$style.quote"><MkNoteSimple :note="appearNote.renote" :class="$style.quoteNote" :expandAllCws="props.expandAllCws"/></div> </div> <MkA v-if="appearNote.channel && !inChannel" :class="$style.channel" :to="`/channels/${appearNote.channel.id}`"><i class="ti ti-device-tv"></i> {{ appearNote.channel.name }}</MkA> </div> - <footer :class="$style.footer"> + <footer :class="$style.footer" class="_gaps _h_gaps" tabindex="0" role="group" :aria-label="i18n.ts.noteFooterLabel"> <div :class="$style.noteFooterInfo"> <div v-if="appearNote.updatedAt"> {{ i18n.ts.edited }}: <MkTime :time="appearNote.updatedAt" mode="detail"/> @@ -169,7 +169,7 @@ SPDX-License-Identifier: AGPL-3.0-only <button v-if="prefer.s.showClipButtonInNoteFooter" ref="clipButton" class="_button" :class="$style.noteFooterButton" @click.stop="clip()"> <i class="ti ti-paperclip"></i> </button> - <button v-if="prefer.s.showTranslationButtonInNoteFooter && $i?.policies.canUseTranslator && instance.translatorAvailable" ref="translationButton" class="_button" :class="$style.noteFooterButton" :disabled="translating || !!translation" @click.stop="translate()"> + <button v-if="prefer.s.showTranslationButtonInNoteFooter && policies.canUseTranslator && instance.translatorAvailable" ref="translationButton" class="_button" :class="$style.noteFooterButton" :disabled="translating || !!translation" @click.stop="translate()"> <i class="ti ti-language-hiragana"></i> </button> <button ref="menuButton" class="_button" :class="$style.noteFooterButton" @click.stop="showMenu()"> @@ -233,7 +233,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { computed, inject, onMounted, provide, ref, useTemplateRef, watch } from 'vue'; -import * as mfm from '@transfem-org/sfm-js'; +import * as mfm from 'mfm-js'; import * as Misskey from 'misskey-js'; import { isLink } from '@@/js/is-link.js'; import * as config from '@@/js/config.js'; @@ -278,7 +278,7 @@ import MkPagination from '@/components/MkPagination.vue'; import MkReactionIcon from '@/components/MkReactionIcon.vue'; import MkButton from '@/components/MkButton.vue'; import { boostMenuItems, computeRenoteTooltip } from '@/utility/boost-quote.js'; -import { instance, isEnabledUrlPreview } from '@/instance.js'; +import { instance, isEnabledUrlPreview, policies } from '@/instance.js'; import { getAppearNote } from '@/utility/get-appear-note.js'; import { prefer } from '@/preferences.js'; import { getPluginHandlers } from '@/plugin.js'; @@ -286,7 +286,7 @@ import { DI } from '@/di.js'; import SkMutedNote from '@/components/SkMutedNote.vue'; import SkNoteTranslation from '@/components/SkNoteTranslation.vue'; import { getSelfNoteIds } from '@/utility/get-self-note-ids.js'; -import { extractPreviewUrls } from '@/utility/extract-preview-urls.js'; +import SkUrlPreviewGroup from '@/components/SkUrlPreviewGroup.vue'; const props = withDefaults(defineProps<{ note: Misskey.entities.Note; @@ -339,8 +339,7 @@ const isDeleted = ref(false); const renoted = ref(false); const translation = ref<Misskey.entities.NotesTranslateResponse | false | null>(null); const translating = ref(false); -const parsed = computed(() => appearNote.value.text ? mfm.parse(appearNote.value.text) : null); -const urls = computed(() => parsed.value ? extractPreviewUrls(props.note, parsed.value) : null); +const parsed = computed(() => appearNote.value.text ? mfm.parse(appearNote.value.text) : []); const selfNoteIds = computed(() => getSelfNoteIds(props.note)); const animated = computed(() => parsed.value ? checkAnimationFromMfm(parsed.value) : null); const allowAnim = ref(prefer.s.advancedMfm && prefer.s.animatedMfm); @@ -388,7 +387,7 @@ const keymap = { clip(); }, 't': () => { - if (prefer.s.showTranslationButtonInNoteFooter && $i?.policies.canUseTranslator && instance.translatorAvailable) { + if (prefer.s.showTranslationButtonInNoteFooter && policies.value.canUseTranslator && instance.translatorAvailable) { translate(); } }, @@ -415,6 +414,11 @@ provide(DI.mfmEmojiReactCallback, (reaction) => { const tab = ref(props.initialTab); const reactionTabType = ref<string | null>(null); +// Auto-select the first page of reactions +watch(appearNote, n => { + reactionTabType.value ??= Object.keys(n.reactions)[0] ?? null; +}, { immediate: true }); + const renotesPagination = computed<Paging>(() => ({ endpoint: 'notes/renotes', limit: 10, @@ -886,12 +890,10 @@ function animatedMFM() { } .footer { - position: relative; - z-index: 1; - margin-top: 0.4em; - width: max-content; - min-width: min-content; - max-width: fit-content; + position: relative; + z-index: 1; + margin-top: 0.4em; + overflow-x: auto; } .replyTo { @@ -1083,10 +1085,6 @@ function animatedMFM() { padding: 8px; opacity: 0.7; - &:not(:last-child) { - margin-right: 1.5em; - } - &:hover { color: var(--MI_THEME-fgHighlighted); } @@ -1169,14 +1167,6 @@ function animatedMFM() { } } -@container (max-width: 350px) { - .noteFooterButton { - &:not(:last-child) { - margin-right: 0.1em; - } - } -} - @container (max-width: 300px) { .root { font-size: 0.825em; @@ -1186,12 +1176,6 @@ function animatedMFM() { width: 50px; height: 50px; } - - .noteFooterButton { - &:not(:last-child) { - margin-right: 0.1em; - } - } } .muted { |