|
|
@ -13,6 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
:class="[$style.root, { [$style.showActionsOnlyHover]: defaultStore.state.showNoteActionsOnlyHover, [$style.skipRender]: defaultStore.state.skipNoteRender || defaultStore.state.enableRenderingOptimization }]"
|
|
|
|
:class="[$style.root, { [$style.showActionsOnlyHover]: defaultStore.state.showNoteActionsOnlyHover, [$style.skipRender]: defaultStore.state.skipNoteRender || defaultStore.state.enableRenderingOptimization }]"
|
|
|
|
:tabindex="isDeleted ? '-1' : '0'"
|
|
|
|
:tabindex="isDeleted ? '-1' : '0'"
|
|
|
|
>
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
<div v-if="collapsedUnexpectedLangs && isUnexpectedLanguage && !languageExpanded && !isRenote" :class="$style.collapsedLanguage">
|
|
|
|
<div v-if="collapsedUnexpectedLangs && isUnexpectedLanguage && !languageExpanded && !isRenote" :class="$style.collapsedLanguage">
|
|
|
|
<MkAvatar :class="$style.collapsedLanguageAvatar" :user="appearNote.user" link preview/>
|
|
|
|
<MkAvatar :class="$style.collapsedLanguageAvatar" :user="appearNote.user" link preview/>
|
|
|
|
<Mfm
|
|
|
|
<Mfm
|
|
|
@ -26,151 +27,151 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<template v-else>
|
|
|
|
<template v-else>
|
|
|
|
<div v-if="appearNote.reply && inReplyToCollapsed && !isRenote" :class="$style.collapsedInReplyTo">
|
|
|
|
<div v-if="appearNote.reply && inReplyToCollapsed && !isRenote" :class="$style.collapsedInReplyTo">
|
|
|
|
<MkAvatar :class="$style.collapsedInReplyToAvatar" :user="appearNote.reply.user" link preview/>
|
|
|
|
<MkAvatar :class="$style.collapsedInReplyToAvatar" :user="appearNote.reply.user" link preview/>
|
|
|
|
<Mfm :text="getNoteSummary(appearNote.reply)" :plain="true" :nowrap="true" :author="appearNote.reply.user" :nyaize="'respect'" :class="$style.collapsedInReplyToText" @click.stop="inReplyToCollapsed = false"/>
|
|
|
|
<Mfm :text="getNoteSummary(appearNote.reply)" :plain="true" :nowrap="true" :author="appearNote.reply.user" :nyaize="'respect'" :class="$style.collapsedInReplyToText" @click.stop="inReplyToCollapsed = false"/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<MkNoteSub v-if="appearNote.reply && !renoteCollapsed && !inReplyToCollapsed" :note="appearNote.reply" :class="$style.replyTo"/>
|
|
|
|
|
|
|
|
<div v-if="pinned" :class="$style.tip"><i class="ti ti-pin"></i> {{ i18n.ts.pinnedNote }}</div>
|
|
|
|
|
|
|
|
<!--<div v-if="appearNote._prId_" class="tip"><i class="ti ti-speakerphone"></i> {{ i18n.ts.promotion }}<button class="_textButton hide" @click="readPromo()">{{ i18n.ts.hideThisNote }} <i class="ti ti-x"></i></button></div>-->
|
|
|
|
|
|
|
|
<!--<div v-if="appearNote._featuredId_" class="tip"><i class="ti ti-bolt"></i> {{ i18n.ts.featured }}</div>-->
|
|
|
|
|
|
|
|
<div v-if="isRenote" :class="$style.renote">
|
|
|
|
|
|
|
|
<div v-if="note.channel" :class="$style.colorBar" :style="{ background: note.channel.color }"></div>
|
|
|
|
|
|
|
|
<MkAvatar :class="$style.renoteAvatar" :user="note.user" link preview/>
|
|
|
|
|
|
|
|
<i class="ti ti-repeat" style="margin-right: 4px;"></i>
|
|
|
|
|
|
|
|
<I18n :src="i18n.ts.renotedBy" tag="span" :class="$style.renoteText">
|
|
|
|
|
|
|
|
<template #user>
|
|
|
|
|
|
|
|
<MkA v-user-preview="note.userId" :class="$style.renoteUserName" :to="userPage(note.user)">
|
|
|
|
|
|
|
|
<MkUserName :user="note.user"/>
|
|
|
|
|
|
|
|
</MkA>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
</I18n>
|
|
|
|
|
|
|
|
<div :class="$style.renoteInfo">
|
|
|
|
|
|
|
|
<button ref="renoteTime" :class="$style.renoteTime" class="_button" @mousedown.prevent="showRenoteMenu()">
|
|
|
|
|
|
|
|
<i class="ti ti-dots" :class="$style.renoteMenu"></i>
|
|
|
|
|
|
|
|
<MkTime :time="note.createdAt"/>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<span v-if="note.visibility !== 'public'" style="margin-left: 0.5em;" :title="i18n.ts._visibility[note.visibility]">
|
|
|
|
|
|
|
|
<i v-if="note.visibility === 'home'" class="ti ti-home"></i>
|
|
|
|
|
|
|
|
<i v-else-if="note.visibility === 'followers'" class="ti ti-lock"></i>
|
|
|
|
|
|
|
|
<i v-else-if="note.visibility === 'specified'" ref="specified" class="ti ti-mail"></i>
|
|
|
|
|
|
|
|
</span>
|
|
|
|
|
|
|
|
<span v-if="note.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ti ti-rocket-off"></i></span>
|
|
|
|
|
|
|
|
<span v-if="note.channel" style="margin-left: 0.5em;" :title="note.channel.name"><i class="ti ti-device-tv"></i></span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<MkNoteSub v-if="appearNote.reply && !renoteCollapsed && !inReplyToCollapsed" :note="appearNote.reply" :class="$style.replyTo"/>
|
|
|
|
</div>
|
|
|
|
<div v-if="pinned" :class="$style.tip"><i class="ti ti-pin"></i> {{ i18n.ts.pinnedNote }}</div>
|
|
|
|
<div v-if="renoteCollapsed" :class="$style.collapsedRenoteTarget">
|
|
|
|
<!--<div v-if="appearNote._prId_" class="tip"><i class="ti ti-speakerphone"></i> {{ i18n.ts.promotion }}<button class="_textButton hide" @click="readPromo()">{{ i18n.ts.hideThisNote }} <i class="ti ti-x"></i></button></div>-->
|
|
|
|
<MkAvatar :class="$style.collapsedRenoteTargetAvatar" :user="appearNote.user" link preview/>
|
|
|
|
<!--<div v-if="appearNote._featuredId_" class="tip"><i class="ti ti-bolt"></i> {{ i18n.ts.featured }}</div>-->
|
|
|
|
<Mfm :text="getNoteSummary(appearNote)" :plain="true" :nowrap="true" :author="appearNote.user" :nyaize="'respect'" :class="$style.collapsedRenoteTargetText" @click.stop="renoteCollapsed = false; inReplyToCollapsed = false"/>
|
|
|
|
<div v-if="isRenote" :class="$style.renote">
|
|
|
|
</div>
|
|
|
|
<div v-if="note.channel" :class="$style.colorBar" :style="{ background: note.channel.color }"></div>
|
|
|
|
<article v-else :class="$style.article" @contextmenu.stop="onContextmenu">
|
|
|
|
<MkAvatar :class="$style.renoteAvatar" :user="note.user" link preview/>
|
|
|
|
<div style="display: flex; padding-bottom: 10px;">
|
|
|
|
<i class="ti ti-repeat" style="margin-right: 4px;"></i>
|
|
|
|
<div v-if="appearNote.channel" :class="$style.colorBar" :style="{ background: appearNote.channel.color }"></div>
|
|
|
|
<I18n :src="i18n.ts.renotedBy" tag="span" :class="$style.renoteText">
|
|
|
|
<MkAvatar :class="$style.avatar" :user="appearNote.user" :link="!mock" :preview="!mock"/>
|
|
|
|
<template #user>
|
|
|
|
<div :class="$style.main">
|
|
|
|
<MkA v-user-preview="note.userId" :class="$style.renoteUserName" :to="userPage(note.user)">
|
|
|
|
<MkNoteHeader :note="appearNote" :mini="true" @click.stop/>
|
|
|
|
<MkUserName :user="note.user"/>
|
|
|
|
</div>
|
|
|
|
</MkA>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
<div :class="[{ [$style.noteClickToOpen]: defaultStore.state.noteClickToOpen }]" @click.stop="defaultStore.state.noteClickToOpen ? noteClickToOpen(appearNote.id) : undefined">
|
|
|
|
</I18n>
|
|
|
|
<div style="container-type: inline-size;">
|
|
|
|
<div :class="$style.renoteInfo">
|
|
|
|
<p v-if="appearNote.cw != null" :class="$style.cw">
|
|
|
|
<button ref="renoteTime" :class="$style.renoteTime" class="_button" @mousedown.prevent="showRenoteMenu()">
|
|
|
|
<Mfm
|
|
|
|
<i class="ti ti-dots" :class="$style.renoteMenu"></i>
|
|
|
|
v-if="appearNote.cw != ''"
|
|
|
|
<MkTime :time="note.createdAt"/>
|
|
|
|
:text="appearNote.cw"
|
|
|
|
</button>
|
|
|
|
:author="appearNote.user"
|
|
|
|
<span v-if="note.visibility !== 'public'" style="margin-left: 0.5em;" :title="i18n.ts._visibility[note.visibility]">
|
|
|
|
:nyaize="'respect'"
|
|
|
|
<i v-if="note.visibility === 'home'" class="ti ti-home"></i>
|
|
|
|
:enableEmojiMenu="true"
|
|
|
|
<i v-else-if="note.visibility === 'followers'" class="ti ti-lock"></i>
|
|
|
|
:enableEmojiMenuReaction="true"
|
|
|
|
<i v-else-if="note.visibility === 'specified'" ref="specified" class="ti ti-mail"></i>
|
|
|
|
/>
|
|
|
|
</span>
|
|
|
|
<MkCwButton v-model="showContent" :text="appearNote.text" :renote="appearNote.renote" :files="appearNote.files" :poll="appearNote.poll" style="margin: 4px 0;" @click.stop/>
|
|
|
|
<span v-if="note.localOnly" style="margin-left: 0.5em;" :title="i18n.ts._visibility['disableFederation']"><i class="ti ti-rocket-off"></i></span>
|
|
|
|
</p>
|
|
|
|
<span v-if="note.channel" style="margin-left: 0.5em;" :title="note.channel.name"><i class="ti ti-device-tv"></i></span>
|
|
|
|
<div v-show="appearNote.cw == null || showContent" :class="[{ [$style.contentCollapsed]: collapsed }]">
|
|
|
|
</div>
|
|
|
|
<div :class="$style.text">
|
|
|
|
</div>
|
|
|
|
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ i18n.ts.private }})</span>
|
|
|
|
<div v-if="renoteCollapsed" :class="$style.collapsedRenoteTarget">
|
|
|
|
<MkA v-if="appearNote.replyId" :class="$style.replyIcon" :to="`/notes/${appearNote.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
|
|
|
|
<MkAvatar :class="$style.collapsedRenoteTargetAvatar" :user="appearNote.user" link preview/>
|
|
|
|
|
|
|
|
<Mfm :text="getNoteSummary(appearNote)" :plain="true" :nowrap="true" :author="appearNote.user" :nyaize="'respect'" :class="$style.collapsedRenoteTargetText" @click.stop="renoteCollapsed = false; inReplyToCollapsed = false"/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<article v-else :class="$style.article" @contextmenu.stop="onContextmenu">
|
|
|
|
|
|
|
|
<div style="display: flex; padding-bottom: 10px;">
|
|
|
|
|
|
|
|
<div v-if="appearNote.channel" :class="$style.colorBar" :style="{ background: appearNote.channel.color }"></div>
|
|
|
|
|
|
|
|
<MkAvatar :class="$style.avatar" :user="appearNote.user" :link="!mock" :preview="!mock"/>
|
|
|
|
|
|
|
|
<div :class="$style.main">
|
|
|
|
|
|
|
|
<MkNoteHeader :note="appearNote" :mini="true" @click.stop/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div :class="[{ [$style.noteClickToOpen]: defaultStore.state.noteClickToOpen }]" @click.stop="defaultStore.state.noteClickToOpen ? noteClickToOpen(appearNote.id) : undefined">
|
|
|
|
|
|
|
|
<div style="container-type: inline-size;">
|
|
|
|
|
|
|
|
<p v-if="appearNote.cw != null" :class="$style.cw">
|
|
|
|
|
|
|
|
<Mfm
|
|
|
|
<Mfm
|
|
|
|
v-if="appearNote.cw != ''"
|
|
|
|
v-if="appearNote.text"
|
|
|
|
:text="appearNote.cw"
|
|
|
|
:parsedNodes="parsed"
|
|
|
|
|
|
|
|
:text="appearNote.text"
|
|
|
|
:author="appearNote.user"
|
|
|
|
:author="appearNote.user"
|
|
|
|
:nyaize="'respect'"
|
|
|
|
:nyaize="'respect'"
|
|
|
|
|
|
|
|
:emojiUrls="appearNote.emojis"
|
|
|
|
:enableEmojiMenu="true"
|
|
|
|
:enableEmojiMenu="true"
|
|
|
|
:enableEmojiMenuReaction="true"
|
|
|
|
:enableEmojiMenuReaction="true"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
<MkCwButton v-model="showContent" :text="appearNote.text" :renote="appearNote.renote" :files="appearNote.files" :poll="appearNote.poll" style="margin: 4px 0;" @click.stop/>
|
|
|
|
<div v-if="defaultStore.state.autoTranslateButton && $i.policies.canUseTranslator && appearNote.text && isUnexpectedLanguage" style="padding-top: 5px; color: var(--MI_THEME-accent);">
|
|
|
|
</p>
|
|
|
|
<button v-if="!(translating || translation)" ref="translateButton" class="_button" @click.stop="translate()"><i class="ti ti-language-hiragana"></i>{{ i18n.ts.translate }}</button>
|
|
|
|
<div v-show="appearNote.cw == null || showContent" :class="[{ [$style.contentCollapsed]: collapsed }]">
|
|
|
|
<button v-else class="_button" @click.stop="translation= null">{{ i18n.ts.close }}</button>
|
|
|
|
<div :class="$style.text">
|
|
|
|
</div>
|
|
|
|
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ i18n.ts.private }})</span>
|
|
|
|
<div v-if="translating || translation" :class="$style.translation">
|
|
|
|
<MkA v-if="appearNote.replyId" :class="$style.replyIcon" :to="`/notes/${appearNote.replyId}`"><i class="ti ti-arrow-back-up"></i></MkA>
|
|
|
|
<MkLoading v-if="translating" mini/>
|
|
|
|
<Mfm
|
|
|
|
<div v-else-if="translation">
|
|
|
|
v-if="appearNote.text"
|
|
|
|
<b>{{ i18n.tsx.translatedFrom({ x: translation.sourceLang }) }}: </b>
|
|
|
|
:parsedNodes="parsed"
|
|
|
|
<Mfm :text="translation.text" :author="appearNote.user" :nyaize="'respect'" :emojiUrls="appearNote.emojis"/>
|
|
|
|
:text="appearNote.text"
|
|
|
|
|
|
|
|
:author="appearNote.user"
|
|
|
|
|
|
|
|
:nyaize="'respect'"
|
|
|
|
|
|
|
|
:emojiUrls="appearNote.emojis"
|
|
|
|
|
|
|
|
:enableEmojiMenu="true"
|
|
|
|
|
|
|
|
:enableEmojiMenuReaction="true"
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
<div v-if="defaultStore.state.autoTranslateButton && $i.policies.canUseTranslator && appearNote.text && isUnexpectedLanguage" style="padding-top: 5px; color: var(--MI_THEME-accent);">
|
|
|
|
|
|
|
|
<button v-if="!(translating || translation)" ref="translateButton" class="_button" @click.stop="translate()"><i class="ti ti-language-hiragana"></i>{{ i18n.ts.translate }}</button>
|
|
|
|
|
|
|
|
<button v-else class="_button" @click.stop="translation= null">{{ i18n.ts.close }}</button>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="translating || translation" :class="$style.translation">
|
|
|
|
|
|
|
|
<MkLoading v-if="translating" mini/>
|
|
|
|
|
|
|
|
<div v-else-if="translation">
|
|
|
|
|
|
|
|
<b>{{ i18n.tsx.translatedFrom({ x: translation.sourceLang }) }}: </b>
|
|
|
|
|
|
|
|
<Mfm :text="translation.text" :author="appearNote.user" :nyaize="'respect'" :emojiUrls="appearNote.emojis"/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div v-if="appearNote.files && appearNote.files.length > 0">
|
|
|
|
|
|
|
|
<MkMediaList ref="galleryEl" :mediaList="appearNote.files" @click.stop/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<MkPoll v-if="appearNote.poll" :noteId="appearNote.id" :poll="appearNote.poll" :class="$style.poll" @click.stop/>
|
|
|
|
|
|
|
|
<div v-if="isEnabledUrlPreview">
|
|
|
|
|
|
|
|
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="false" :class="$style.urlPreview" @click.stop/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="appearNote.renote" :class="$style.quote"><MkNoteSimple :note="appearNote.renote" :class="$style.quoteNote" @click.stop/></div>
|
|
|
|
|
|
|
|
<button v-if="isLong && collapsed" :class="$style.collapsed" class="_button" @click.stop="collapsed = false">
|
|
|
|
|
|
|
|
<span :class="$style.collapsedLabel">{{ i18n.ts.showMore }}</span>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<button v-else-if="isLong && !collapsed" :class="$style.showLess" class="_button" @click.stop="collapsed = true">
|
|
|
|
|
|
|
|
<span :class="$style.showLessLabel">{{ i18n.ts.showLess }}</span>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
</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 v-if="appearNote.files && appearNote.files.length > 0">
|
|
|
|
|
|
|
|
<MkMediaList ref="galleryEl" :mediaList="appearNote.files" @click.stop/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<MkPoll v-if="appearNote.poll" :noteId="appearNote.id" :poll="appearNote.poll" :class="$style.poll" @click.stop/>
|
|
|
|
|
|
|
|
<div v-if="isEnabledUrlPreview">
|
|
|
|
|
|
|
|
<MkUrlPreview v-for="url in urls" :key="url" :url="url" :compact="true" :detail="false" :class="$style.urlPreview" @click.stop/>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div v-if="appearNote.renote" :class="$style.quote"><MkNoteSimple :note="appearNote.renote" :class="$style.quoteNote" @click.stop/></div>
|
|
|
|
|
|
|
|
<button v-if="isLong && collapsed" :class="$style.collapsed" class="_button" @click.stop="collapsed = false">
|
|
|
|
|
|
|
|
<span :class="$style.collapsedLabel">{{ i18n.ts.showMore }}</span>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<button v-else-if="isLong && !collapsed" :class="$style.showLess" class="_button" @click.stop="collapsed = true">
|
|
|
|
|
|
|
|
<span :class="$style.showLessLabel">{{ i18n.ts.showLess }}</span>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<MkReactionsViewer v-if="appearNote.reactionAcceptance !== 'likeOnly' && !disableReactionsViewer" :note="appearNote" :maxNumber="16" @mockUpdateMyReaction="emitUpdReaction">
|
|
|
|
<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>
|
|
|
|
<template #more>
|
|
|
|
|
|
|
|
<MkA :to="`/notes/${appearNote.id}/reactions`" :class="[$style.reactionOmitted]">{{ i18n.ts.more }}</MkA>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
</MkReactionsViewer>
|
|
|
|
|
|
|
|
<footer :class="$style.footer">
|
|
|
|
|
|
|
|
<button :class="$style.footerButton" class="_button" @click.stop="reply()">
|
|
|
|
|
|
|
|
<i class="ti ti-arrow-back-up"></i>
|
|
|
|
|
|
|
|
<p v-if="appearNote.repliesCount > 0" :class="$style.footerButtonCount">{{ number(appearNote.repliesCount) }}</p>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
|
|
|
v-if="canRenote"
|
|
|
|
|
|
|
|
ref="renoteButton"
|
|
|
|
|
|
|
|
:class="$style.footerButton"
|
|
|
|
|
|
|
|
class="_button"
|
|
|
|
|
|
|
|
@click.stop
|
|
|
|
|
|
|
|
@mousedown.prevent="renote()"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<i class="ti ti-repeat"></i>
|
|
|
|
|
|
|
|
<p v-if="appearNote.renoteCount > 0" :class="$style.footerButtonCount">{{ number(appearNote.renoteCount) }}</p>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<button v-else :class="$style.footerButton" class="_button" disabled>
|
|
|
|
|
|
|
|
<i class="ti ti-ban"></i>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<button v-if="defaultStore.state.enableFallbackReactButton && appearNote.myReaction == null && appearNote.reactionAcceptance !== 'likeOnly' && !disableReactionsViewer" ref="likeButton" :class="$style.footerButton" class="_button" @click.stop="like()">
|
|
|
|
|
|
|
|
<i class="ti ti-heart"></i>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<button ref="reactButton" :class="$style.footerButton" class="_button" @click.stop="toggleReact()">
|
|
|
|
|
|
|
|
<i v-if="(appearNote.reactionAcceptance === 'likeOnly' || disableReactionsViewer) && appearNote.myReaction != null" class="ti ti-heart-filled" style="color: var(--MI_THEME-love);"></i>
|
|
|
|
|
|
|
|
<i v-else-if="appearNote.myReaction != null" class="ti ti-minus" style="color: var(--MI_THEME-accent);"></i>
|
|
|
|
|
|
|
|
<i v-else-if="appearNote.reactionAcceptance === 'likeOnly' || disableReactionsViewer" class="ti ti-heart"></i>
|
|
|
|
|
|
|
|
<i v-else class="ti ti-mood-plus"></i>
|
|
|
|
|
|
|
|
<p v-if="(appearNote.reactionAcceptance === 'likeOnly' || defaultStore.state.showReactionsCount || disableReactionsViewer) && appearNote.reactionCount > 0" :class="$style.footerButtonCount">{{ number(appearNote.reactionCount) }}</p>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" :class="$style.footerButton" class="_button" @mousedown.prevent="clip()">
|
|
|
|
|
|
|
|
<i class="ti ti-paperclip"></i>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<button ref="menuButton" :class="$style.footerButton" class="_button" @mousedown.prevent="showMenu()">
|
|
|
|
|
|
|
|
<i class="ti ti-dots"></i>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
</footer>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</article>
|
|
|
|
<MkReactionsViewer v-if="appearNote.reactionAcceptance !== 'likeOnly' && !disableReactionsViewer" :note="appearNote" :maxNumber="16" @mockUpdateMyReaction="emitUpdReaction">
|
|
|
|
</template>
|
|
|
|
<template #more>
|
|
|
|
|
|
|
|
<MkA :to="`/notes/${appearNote.id}/reactions`" :class="[$style.reactionOmitted]">{{ i18n.ts.more }}</MkA>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
</MkReactionsViewer>
|
|
|
|
|
|
|
|
<footer :class="$style.footer">
|
|
|
|
|
|
|
|
<button :class="$style.footerButton" class="_button" @click.stop="reply()">
|
|
|
|
|
|
|
|
<i class="ti ti-arrow-back-up"></i>
|
|
|
|
|
|
|
|
<p v-if="appearNote.repliesCount > 0" :class="$style.footerButtonCount">{{ number(appearNote.repliesCount) }}</p>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<button
|
|
|
|
|
|
|
|
v-if="canRenote"
|
|
|
|
|
|
|
|
ref="renoteButton"
|
|
|
|
|
|
|
|
:class="$style.footerButton"
|
|
|
|
|
|
|
|
class="_button"
|
|
|
|
|
|
|
|
@click.stop
|
|
|
|
|
|
|
|
@mousedown.prevent="renote()"
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
<i class="ti ti-repeat"></i>
|
|
|
|
|
|
|
|
<p v-if="appearNote.renoteCount > 0" :class="$style.footerButtonCount">{{ number(appearNote.renoteCount) }}</p>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<button v-else :class="$style.footerButton" class="_button" disabled>
|
|
|
|
|
|
|
|
<i class="ti ti-ban"></i>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<button v-if="defaultStore.state.enableFallbackReactButton && appearNote.myReaction == null && appearNote.reactionAcceptance !== 'likeOnly' && !disableReactionsViewer" ref="likeButton" :class="$style.footerButton" class="_button" @click.stop="like()">
|
|
|
|
|
|
|
|
<i class="ti ti-heart"></i>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<button ref="reactButton" :class="$style.footerButton" class="_button" @click.stop="toggleReact()">
|
|
|
|
|
|
|
|
<i v-if="(appearNote.reactionAcceptance === 'likeOnly' || disableReactionsViewer) && appearNote.myReaction != null" class="ti ti-heart-filled" style="color: var(--MI_THEME-love);"></i>
|
|
|
|
|
|
|
|
<i v-else-if="appearNote.myReaction != null" class="ti ti-minus" style="color: var(--MI_THEME-accent);"></i>
|
|
|
|
|
|
|
|
<i v-else-if="appearNote.reactionAcceptance === 'likeOnly' || disableReactionsViewer" class="ti ti-heart"></i>
|
|
|
|
|
|
|
|
<i v-else class="ti ti-mood-plus"></i>
|
|
|
|
|
|
|
|
<p v-if="(appearNote.reactionAcceptance === 'likeOnly' || defaultStore.state.showReactionsCount || disableReactionsViewer) && appearNote.reactionCount > 0" :class="$style.footerButtonCount">{{ number(appearNote.reactionCount) }}</p>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" :class="$style.footerButton" class="_button" @mousedown.prevent="clip()">
|
|
|
|
|
|
|
|
<i class="ti ti-paperclip"></i>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
<button ref="menuButton" :class="$style.footerButton" class="_button" @mousedown.prevent="showMenu()">
|
|
|
|
|
|
|
|
<i class="ti ti-dots"></i>
|
|
|
|
|
|
|
|
</button>
|
|
|
|
|
|
|
|
</footer>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
</article>
|
|
|
|
|
|
|
|
</template>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div v-else-if="!hardMuted" :class="$style.muted" @click="muted = false">
|
|
|
|
<div v-else-if="!hardMuted" :class="$style.muted" @click="muted = false">
|
|
|
|
<I18n v-if="muted === 'sensitiveMute'" :src="i18n.ts.userSaysSomethingSensitive" tag="small">
|
|
|
|
<I18n v-if="muted === 'sensitiveMute'" :src="i18n.ts.userSaysSomethingSensitive" tag="small">
|
|
|
@ -327,16 +328,16 @@ const disableReactionsViewer = ref(defaultStore.reactiveState.disableReactionsVi
|
|
|
|
|
|
|
|
|
|
|
|
const collapsedUnexpectedLangs = ref(defaultStore.reactiveState.collapsedUnexpectedLangs);
|
|
|
|
const collapsedUnexpectedLangs = ref(defaultStore.reactiveState.collapsedUnexpectedLangs);
|
|
|
|
const expectedLangs = computed(() => new Set([
|
|
|
|
const expectedLangs = computed(() => new Set([
|
|
|
|
(miLocalStorage.getItem('lang') ?? navigator.language).slice(0, 2),
|
|
|
|
(miLocalStorage.getItem('lang') ?? navigator.language).slice(0, 2),
|
|
|
|
navigator.language.slice(0, 2),
|
|
|
|
navigator.language.slice(0, 2)
|
|
|
|
]));
|
|
|
|
]));
|
|
|
|
const noteLanguage = computed(() => {
|
|
|
|
const noteLanguage = computed(() => {
|
|
|
|
if (!appearNote.value.text || appearNote.value.text.length < 10) return '';
|
|
|
|
if (!appearNote.value.text || appearNote.value.text.length < 10) return '';
|
|
|
|
return detectLanguage(appearNote.value.text);
|
|
|
|
return detectLanguage(appearNote.value.text);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
const isUnexpectedLanguage = computed(() => {
|
|
|
|
const isUnexpectedLanguage = computed(() => {
|
|
|
|
const lang = noteLanguage.value;
|
|
|
|
const lang = noteLanguage.value;
|
|
|
|
return lang !== '' && !expectedLangs.value.has(lang);
|
|
|
|
return lang !== '' && !expectedLangs.value.has(lang);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
const pleaseLoginContext = computed<OpenOnRemoteOptions>(() => ({
|
|
|
|
const pleaseLoginContext = computed<OpenOnRemoteOptions>(() => ({
|
|
|
@ -805,7 +806,7 @@ function emitUpdReaction(emoji: string, delta: number) {
|
|
|
|
|
|
|
|
|
|
|
|
.skipRender {
|
|
|
|
.skipRender {
|
|
|
|
content-visibility: auto;
|
|
|
|
content-visibility: auto;
|
|
|
|
contain-intrinsic-size: 0 200px;
|
|
|
|
contain-intrinsic-size: 0 250px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.tip {
|
|
|
|
.tip {
|
|
|
|