2020-01-30 04:37:25 +09:00
|
|
|
|
<template>
|
|
|
|
|
<div
|
2021-04-10 12:40:50 +09:00
|
|
|
|
class="tkcbzcuz"
|
2020-07-27 13:34:20 +09:00
|
|
|
|
v-if="!muted"
|
2020-07-27 08:46:21 +09:00
|
|
|
|
v-show="!isDeleted"
|
2020-02-06 09:09:24 +09:00
|
|
|
|
:tabindex="!isDeleted ? '-1' : null"
|
2020-01-30 04:37:25 +09:00
|
|
|
|
:class="{ renote: isRenote }"
|
|
|
|
|
v-hotkey="keymap"
|
2020-08-09 15:51:02 +09:00
|
|
|
|
v-size="{ max: [500, 450, 350, 300] }"
|
2020-01-30 04:37:25 +09:00
|
|
|
|
>
|
2020-10-17 20:12:00 +09:00
|
|
|
|
<XSub :note="appearNote.reply" class="reply-to" v-if="appearNote.reply"/>
|
2021-04-20 23:22:59 +09:00
|
|
|
|
<div class="info" v-if="pinned"><i class="fas fa-thumbtack"></i> {{ $ts.pinnedNote }}</div>
|
|
|
|
|
<div class="info" v-if="appearNote._prId_"><i class="fas fa-bullhorn"></i> {{ $ts.promotion }}<button class="_textButton hide" @click="readPromo()">{{ $ts.hideThisNote }} <i class="fas fa-times"></i></button></div>
|
|
|
|
|
<div class="info" v-if="appearNote._featuredId_"><i class="fas fa-bolt"></i> {{ $ts.featured }}</div>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
<div class="renote" v-if="isRenote">
|
2020-10-17 20:12:00 +09:00
|
|
|
|
<MkAvatar class="avatar" :user="note.user"/>
|
2021-04-20 23:22:59 +09:00
|
|
|
|
<i class="fas fa-retweet"></i>
|
2020-12-26 10:47:36 +09:00
|
|
|
|
<I18n :src="$ts.renotedBy" tag="span">
|
2020-10-17 20:12:00 +09:00
|
|
|
|
<template #user>
|
2020-10-25 01:21:41 +09:00
|
|
|
|
<MkA class="name" :to="userPage(note.user)" v-user-preview="note.userId">
|
2020-10-17 20:12:00 +09:00
|
|
|
|
<MkUserName :user="note.user"/>
|
2020-10-25 01:21:41 +09:00
|
|
|
|
</MkA>
|
2020-10-17 20:12:00 +09:00
|
|
|
|
</template>
|
2020-12-26 10:01:32 +09:00
|
|
|
|
</I18n>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
<div class="info">
|
2020-05-15 20:39:11 +09:00
|
|
|
|
<button class="_button time" @click="showRenoteMenu()" ref="renoteTime">
|
2021-04-20 23:22:59 +09:00
|
|
|
|
<i v-if="isMyRenote" class="fas fa-ellipsis-h dropdownIcon"></i>
|
2020-10-17 20:12:00 +09:00
|
|
|
|
<MkTime :time="note.createdAt"/>
|
2020-05-15 20:39:11 +09:00
|
|
|
|
</button>
|
2020-05-10 15:36:42 +09:00
|
|
|
|
<span class="visibility" v-if="note.visibility !== 'public'">
|
2021-04-20 23:22:59 +09:00
|
|
|
|
<i v-if="note.visibility === 'home'" class="fas fa-home"></i>
|
|
|
|
|
<i v-else-if="note.visibility === 'followers'" class="fas fa-unlock"></i>
|
|
|
|
|
<i v-else-if="note.visibility === 'specified'" class="fas fa-envelope"></i>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
</span>
|
2021-04-20 23:22:59 +09:00
|
|
|
|
<span class="localOnly" v-if="note.localOnly"><i class="fas fa-biohazard"></i></span>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2020-12-29 21:08:08 +09:00
|
|
|
|
<article class="article" @contextmenu.stop="onContextmenu">
|
2020-10-17 20:12:00 +09:00
|
|
|
|
<MkAvatar class="avatar" :user="appearNote.user"/>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
<div class="main">
|
2020-10-17 20:12:00 +09:00
|
|
|
|
<XNoteHeader class="header" :note="appearNote" :mini="true"/>
|
2020-10-27 16:16:59 +09:00
|
|
|
|
<MkInstanceTicker v-if="showTicker" class="ticker" :instance="appearNote.user.instance"/>
|
2020-11-01 15:04:46 +09:00
|
|
|
|
<div class="body">
|
2020-01-30 04:37:25 +09:00
|
|
|
|
<p v-if="appearNote.cw != null" class="cw">
|
2020-12-19 10:55:52 +09:00
|
|
|
|
<Mfm v-if="appearNote.cw != ''" class="text" :text="appearNote.cw" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
|
2020-10-17 20:12:00 +09:00
|
|
|
|
<XCwButton v-model:value="showContent" :note="appearNote"/>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
</p>
|
2020-12-30 09:58:57 +09:00
|
|
|
|
<div class="content" :class="{ collapsed }" v-show="appearNote.cw == null || showContent">
|
2020-01-30 04:37:25 +09:00
|
|
|
|
<div class="text">
|
2020-12-26 10:47:36 +09:00
|
|
|
|
<span v-if="appearNote.isHidden" style="opacity: 0.5">({{ $ts.private }})</span>
|
2021-04-20 23:22:59 +09:00
|
|
|
|
<MkA class="reply" v-if="appearNote.replyId" :to="`/notes/${appearNote.replyId}`"><i class="fas fa-reply"></i></MkA>
|
2020-12-19 10:55:52 +09:00
|
|
|
|
<Mfm v-if="appearNote.text" :text="appearNote.text" :author="appearNote.user" :i="$i" :custom-emojis="appearNote.emojis"/>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
<a class="rp" v-if="appearNote.renote != null">RN:</a>
|
2021-08-15 20:26:44 +09:00
|
|
|
|
<div class="translation" v-if="translating || translation">
|
|
|
|
|
<MkLoading v-if="translating" mini/>
|
|
|
|
|
<div class="translated" v-else>
|
|
|
|
|
<b>{{ $t('translatedFrom', { x: translation.sourceLang }) }}:</b>
|
|
|
|
|
{{ translation.text }}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
</div>
|
|
|
|
|
<div class="files" v-if="appearNote.files.length > 0">
|
2020-11-01 15:04:46 +09:00
|
|
|
|
<XMediaList :media-list="appearNote.files"/>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
</div>
|
2020-10-17 20:12:00 +09:00
|
|
|
|
<XPoll v-if="appearNote.poll" :note="appearNote" ref="pollViewer" class="poll"/>
|
2021-01-01 22:41:20 +09:00
|
|
|
|
<MkUrlPreview v-for="url in urls" :url="url" :key="url" :compact="true" :detail="false" class="url-preview"/>
|
2020-10-17 20:12:00 +09:00
|
|
|
|
<div class="renote" v-if="appearNote.renote"><XNotePreview :note="appearNote.renote"/></div>
|
2020-12-30 09:58:57 +09:00
|
|
|
|
<button v-if="collapsed" class="fade _button" @click="collapsed = false">
|
|
|
|
|
<span>{{ $ts.showMore }}</span>
|
|
|
|
|
</button>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
</div>
|
2021-04-20 23:22:59 +09:00
|
|
|
|
<MkA v-if="appearNote.channel && !inChannel" class="channel" :to="`/channels/${appearNote.channel.id}`"><i class="fas fa-satellite-dish"></i> {{ appearNote.channel.name }}</MkA>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
</div>
|
2020-07-27 08:46:21 +09:00
|
|
|
|
<footer class="footer">
|
2020-10-17 20:12:00 +09:00
|
|
|
|
<XReactionsViewer :note="appearNote" ref="reactionsViewer"/>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
<button @click="reply()" class="button _button">
|
2021-04-20 23:22:59 +09:00
|
|
|
|
<template v-if="appearNote.reply"><i class="fas fa-reply-all"></i></template>
|
|
|
|
|
<template v-else><i class="fas fa-reply"></i></template>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
<p class="count" v-if="appearNote.repliesCount > 0">{{ appearNote.repliesCount }}</p>
|
|
|
|
|
</button>
|
2020-02-16 21:10:52 +09:00
|
|
|
|
<button v-if="canRenote" @click="renote()" class="button _button" ref="renoteButton">
|
2021-04-20 23:22:59 +09:00
|
|
|
|
<i class="fas fa-retweet"></i><p class="count" v-if="appearNote.renoteCount > 0">{{ appearNote.renoteCount }}</p>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
</button>
|
|
|
|
|
<button v-else class="button _button">
|
2021-04-20 23:22:59 +09:00
|
|
|
|
<i class="fas fa-ban"></i>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
</button>
|
2020-07-30 20:28:35 +09:00
|
|
|
|
<button v-if="appearNote.myReaction == null" class="button _button" @click="react()" ref="reactButton">
|
2021-04-20 23:22:59 +09:00
|
|
|
|
<i class="fas fa-plus"></i>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
</button>
|
2020-07-30 20:28:35 +09:00
|
|
|
|
<button v-if="appearNote.myReaction != null" class="button _button reacted" @click="undoReact(appearNote)" ref="reactButton">
|
2021-04-20 23:22:59 +09:00
|
|
|
|
<i class="fas fa-minus"></i>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
</button>
|
|
|
|
|
<button class="button _button" @click="menu()" ref="menuButton">
|
2021-04-20 23:22:59 +09:00
|
|
|
|
<i class="fas fa-ellipsis-h"></i>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
</button>
|
|
|
|
|
</footer>
|
|
|
|
|
</div>
|
|
|
|
|
</article>
|
|
|
|
|
</div>
|
2021-04-10 12:40:50 +09:00
|
|
|
|
<div v-else class="muted" @click="muted = false">
|
2020-12-26 10:47:36 +09:00
|
|
|
|
<I18n :src="$ts.userSaysSomething" tag="small">
|
2020-10-17 20:12:00 +09:00
|
|
|
|
<template #name>
|
2020-10-25 01:21:41 +09:00
|
|
|
|
<MkA class="name" :to="userPage(appearNote.user)" v-user-preview="appearNote.userId">
|
2020-10-17 20:12:00 +09:00
|
|
|
|
<MkUserName :user="appearNote.user"/>
|
2020-10-25 01:21:41 +09:00
|
|
|
|
</MkA>
|
2020-10-17 20:12:00 +09:00
|
|
|
|
</template>
|
2020-12-26 10:01:32 +09:00
|
|
|
|
</I18n>
|
2020-07-27 13:34:20 +09:00
|
|
|
|
</div>
|
2020-01-30 04:37:25 +09:00
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script lang="ts">
|
2021-04-02 10:36:11 +09:00
|
|
|
|
import { defineAsyncComponent, defineComponent, markRaw } from 'vue';
|
|
|
|
|
import * as mfm from 'mfm-js';
|
|
|
|
|
import { sum } from '../../prelude/array';
|
2020-01-30 04:37:25 +09:00
|
|
|
|
import XSub from './note.sub.vue';
|
|
|
|
|
import XNoteHeader from './note-header.vue';
|
|
|
|
|
import XNotePreview from './note-preview.vue';
|
|
|
|
|
import XReactionsViewer from './reactions-viewer.vue';
|
|
|
|
|
import XMediaList from './media-list.vue';
|
|
|
|
|
import XCwButton from './cw-button.vue';
|
|
|
|
|
import XPoll from './poll.vue';
|
2021-03-23 17:30:14 +09:00
|
|
|
|
import { pleaseLogin } from '@client/scripts/please-login';
|
|
|
|
|
import { focusPrev, focusNext } from '@client/scripts/focus';
|
|
|
|
|
import { url } from '@client/config';
|
|
|
|
|
import copyToClipboard from '@client/scripts/copy-to-clipboard';
|
|
|
|
|
import { checkWordMute } from '@client/scripts/check-word-mute';
|
|
|
|
|
import { userPage } from '@client/filters/user';
|
|
|
|
|
import * as os from '@client/os';
|
|
|
|
|
import { noteActions, noteViewInterruptors } from '@client/store';
|
|
|
|
|
import { reactionPicker } from '@client/scripts/reaction-picker';
|
2021-04-02 10:36:11 +09:00
|
|
|
|
import { extractUrlFromMfm } from '@/misc/extract-url-from-mfm';
|
2020-10-17 20:12:00 +09:00
|
|
|
|
|
|
|
|
|
export default defineComponent({
|
2020-01-30 04:37:25 +09:00
|
|
|
|
components: {
|
|
|
|
|
XSub,
|
|
|
|
|
XNoteHeader,
|
|
|
|
|
XNotePreview,
|
|
|
|
|
XReactionsViewer,
|
|
|
|
|
XMediaList,
|
|
|
|
|
XCwButton,
|
|
|
|
|
XPoll,
|
2021-03-23 17:30:14 +09:00
|
|
|
|
MkUrlPreview: defineAsyncComponent(() => import('@client/components/url-preview.vue')),
|
|
|
|
|
MkInstanceTicker: defineAsyncComponent(() => import('@client/components/instance-ticker.vue')),
|
2020-01-30 04:37:25 +09:00
|
|
|
|
},
|
|
|
|
|
|
2020-08-18 22:44:21 +09:00
|
|
|
|
inject: {
|
|
|
|
|
inChannel: {
|
|
|
|
|
default: null
|
2020-10-25 01:21:41 +09:00
|
|
|
|
},
|
2020-08-18 22:44:21 +09:00
|
|
|
|
},
|
|
|
|
|
|
2020-01-30 04:37:25 +09:00
|
|
|
|
props: {
|
|
|
|
|
note: {
|
|
|
|
|
type: Object,
|
|
|
|
|
required: true
|
|
|
|
|
},
|
|
|
|
|
pinned: {
|
|
|
|
|
type: Boolean,
|
|
|
|
|
required: false,
|
|
|
|
|
default: false
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
|
2020-10-17 20:12:00 +09:00
|
|
|
|
emits: ['update:note'],
|
|
|
|
|
|
2020-01-30 04:37:25 +09:00
|
|
|
|
data() {
|
|
|
|
|
return {
|
|
|
|
|
connection: null,
|
|
|
|
|
replies: [],
|
|
|
|
|
showContent: false,
|
2020-12-30 09:58:57 +09:00
|
|
|
|
collapsed: false,
|
2020-07-27 08:46:21 +09:00
|
|
|
|
isDeleted: false,
|
2020-07-27 13:34:20 +09:00
|
|
|
|
muted: false,
|
2021-08-15 20:26:44 +09:00
|
|
|
|
translation: null,
|
|
|
|
|
translating: false,
|
2020-01-30 04:37:25 +09:00
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
computed: {
|
2020-10-17 20:12:00 +09:00
|
|
|
|
rs() {
|
2020-12-19 10:55:52 +09:00
|
|
|
|
return this.$store.state.reactions;
|
2020-10-17 20:12:00 +09:00
|
|
|
|
},
|
2020-01-30 04:37:25 +09:00
|
|
|
|
keymap(): any {
|
|
|
|
|
return {
|
|
|
|
|
'r': () => this.reply(true),
|
|
|
|
|
'e|a|plus': () => this.react(true),
|
|
|
|
|
'q': () => this.renote(true),
|
|
|
|
|
'f|b': this.favorite,
|
|
|
|
|
'delete|ctrl+d': this.del,
|
|
|
|
|
'ctrl+q': this.renoteDirectly,
|
|
|
|
|
'up|k|shift+tab': this.focusBefore,
|
|
|
|
|
'down|j|tab': this.focusAfter,
|
|
|
|
|
'esc': this.blur,
|
|
|
|
|
'm|o': () => this.menu(true),
|
|
|
|
|
's': this.toggleShowContent,
|
2020-10-17 20:12:00 +09:00
|
|
|
|
'1': () => this.reactDirectly(this.rs[0]),
|
|
|
|
|
'2': () => this.reactDirectly(this.rs[1]),
|
|
|
|
|
'3': () => this.reactDirectly(this.rs[2]),
|
|
|
|
|
'4': () => this.reactDirectly(this.rs[3]),
|
|
|
|
|
'5': () => this.reactDirectly(this.rs[4]),
|
|
|
|
|
'6': () => this.reactDirectly(this.rs[5]),
|
|
|
|
|
'7': () => this.reactDirectly(this.rs[6]),
|
|
|
|
|
'8': () => this.reactDirectly(this.rs[7]),
|
|
|
|
|
'9': () => this.reactDirectly(this.rs[8]),
|
|
|
|
|
'0': () => this.reactDirectly(this.rs[9]),
|
2020-01-30 04:37:25 +09:00
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
isRenote(): boolean {
|
|
|
|
|
return (this.note.renote &&
|
|
|
|
|
this.note.text == null &&
|
|
|
|
|
this.note.fileIds.length == 0 &&
|
|
|
|
|
this.note.poll == null);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
appearNote(): any {
|
|
|
|
|
return this.isRenote ? this.note.renote : this.note;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
isMyNote(): boolean {
|
2020-12-19 10:55:52 +09:00
|
|
|
|
return this.$i && (this.$i.id === this.appearNote.userId);
|
2020-01-30 04:37:25 +09:00
|
|
|
|
},
|
|
|
|
|
|
2020-05-16 12:15:59 +09:00
|
|
|
|
isMyRenote(): boolean {
|
2020-12-19 10:55:52 +09:00
|
|
|
|
return this.$i && (this.$i.id === this.note.userId);
|
2020-05-16 12:15:59 +09:00
|
|
|
|
},
|
|
|
|
|
|
2020-02-16 21:10:52 +09:00
|
|
|
|
canRenote(): boolean {
|
|
|
|
|
return ['public', 'home'].includes(this.appearNote.visibility) || this.isMyNote;
|
|
|
|
|
},
|
|
|
|
|
|
2020-01-30 04:37:25 +09:00
|
|
|
|
reactionsCount(): number {
|
2020-07-27 23:25:37 +09:00
|
|
|
|
return this.appearNote.reactions
|
|
|
|
|
? sum(Object.values(this.appearNote.reactions))
|
|
|
|
|
: 0;
|
2020-01-30 04:37:25 +09:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
urls(): string[] {
|
|
|
|
|
if (this.appearNote.text) {
|
2021-04-02 10:36:11 +09:00
|
|
|
|
return extractUrlFromMfm(mfm.parse(this.appearNote.text));
|
2020-01-30 04:37:25 +09:00
|
|
|
|
} else {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2020-10-27 16:16:59 +09:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
showTicker() {
|
2020-12-19 10:55:52 +09:00
|
|
|
|
if (this.$store.state.instanceTicker === 'always') return true;
|
|
|
|
|
if (this.$store.state.instanceTicker === 'remote' && this.appearNote.user.instance) return true;
|
2020-10-27 16:16:59 +09:00
|
|
|
|
return false;
|
2020-01-30 04:37:25 +09:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2020-07-27 13:34:20 +09:00
|
|
|
|
async created() {
|
2020-12-19 10:55:52 +09:00
|
|
|
|
if (this.$i) {
|
2020-10-17 20:12:00 +09:00
|
|
|
|
this.connection = os.stream;
|
2020-01-30 04:37:25 +09:00
|
|
|
|
}
|
|
|
|
|
|
2021-01-01 22:41:20 +09:00
|
|
|
|
this.collapsed = this.appearNote.cw == null && this.appearNote.text && (
|
2020-12-30 10:03:57 +09:00
|
|
|
|
(this.appearNote.text.split('\n').length > 9) ||
|
|
|
|
|
(this.appearNote.text.length > 500)
|
2020-12-30 09:58:57 +09:00
|
|
|
|
);
|
|
|
|
|
this.muted = await checkWordMute(this.appearNote, this.$i, this.$store.state.mutedWords);
|
|
|
|
|
|
2020-07-29 01:15:02 +09:00
|
|
|
|
// plugin
|
2020-10-17 20:12:00 +09:00
|
|
|
|
if (noteViewInterruptors.length > 0) {
|
2020-07-29 01:15:02 +09:00
|
|
|
|
let result = this.note;
|
2020-10-17 20:12:00 +09:00
|
|
|
|
for (const interruptor of noteViewInterruptors) {
|
|
|
|
|
result = await interruptor.handler(JSON.parse(JSON.stringify(result)));
|
2020-07-29 01:15:02 +09:00
|
|
|
|
}
|
2020-10-17 20:12:00 +09:00
|
|
|
|
this.$emit('update:note', Object.freeze(result));
|
2020-07-29 01:15:02 +09:00
|
|
|
|
}
|
2020-01-30 04:37:25 +09:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
mounted() {
|
|
|
|
|
this.capture(true);
|
|
|
|
|
|
2020-12-19 10:55:52 +09:00
|
|
|
|
if (this.$i) {
|
2020-01-30 04:37:25 +09:00
|
|
|
|
this.connection.on('_connected_', this.onStreamConnected);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2020-10-17 20:12:00 +09:00
|
|
|
|
beforeUnmount() {
|
2020-01-30 04:37:25 +09:00
|
|
|
|
this.decapture(true);
|
|
|
|
|
|
2020-12-19 10:55:52 +09:00
|
|
|
|
if (this.$i) {
|
2020-01-30 04:37:25 +09:00
|
|
|
|
this.connection.off('_connected_', this.onStreamConnected);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
methods: {
|
2020-07-27 23:25:37 +09:00
|
|
|
|
updateAppearNote(v) {
|
2020-10-17 20:12:00 +09:00
|
|
|
|
this.$emit('update:note', Object.freeze(this.isRenote ? {
|
2020-07-27 23:25:37 +09:00
|
|
|
|
...this.note,
|
|
|
|
|
renote: {
|
|
|
|
|
...this.note.renote,
|
|
|
|
|
...v
|
|
|
|
|
}
|
|
|
|
|
} : {
|
|
|
|
|
...this.note,
|
|
|
|
|
...v
|
|
|
|
|
}));
|
|
|
|
|
},
|
|
|
|
|
|
2020-02-18 18:14:38 +09:00
|
|
|
|
readPromo() {
|
2020-10-17 20:12:00 +09:00
|
|
|
|
os.api('promo/read', {
|
2020-02-18 18:14:38 +09:00
|
|
|
|
noteId: this.appearNote.id
|
|
|
|
|
});
|
2020-07-27 08:46:21 +09:00
|
|
|
|
this.isDeleted = true;
|
2020-02-18 18:14:38 +09:00
|
|
|
|
},
|
|
|
|
|
|
2020-01-30 04:37:25 +09:00
|
|
|
|
capture(withHandler = false) {
|
2020-12-19 10:55:52 +09:00
|
|
|
|
if (this.$i) {
|
2021-03-21 17:38:09 +09:00
|
|
|
|
// TODO: このノートがストリーミング経由で流れてきた場合のみ sr する
|
|
|
|
|
this.connection.send(document.body.contains(this.$el) ? 'sr' : 's', { id: this.appearNote.id });
|
2020-02-09 03:49:18 +09:00
|
|
|
|
if (withHandler) this.connection.on('noteUpdated', this.onStreamNoteUpdated);
|
2020-01-30 04:37:25 +09:00
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
decapture(withHandler = false) {
|
2020-12-19 10:55:52 +09:00
|
|
|
|
if (this.$i) {
|
2020-01-30 04:37:25 +09:00
|
|
|
|
this.connection.send('un', {
|
|
|
|
|
id: this.appearNote.id
|
|
|
|
|
});
|
|
|
|
|
if (withHandler) this.connection.off('noteUpdated', this.onStreamNoteUpdated);
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
onStreamConnected() {
|
|
|
|
|
this.capture();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
onStreamNoteUpdated(data) {
|
|
|
|
|
const { type, id, body } = data;
|
|
|
|
|
|
|
|
|
|
if (id !== this.appearNote.id) return;
|
|
|
|
|
|
|
|
|
|
switch (type) {
|
|
|
|
|
case 'reacted': {
|
|
|
|
|
const reaction = body.reaction;
|
|
|
|
|
|
2020-07-27 23:25:37 +09:00
|
|
|
|
// DeepではなくShallowコピーであることに注意。n.reactions[reaction] = hogeとかしないように(親からもらったデータをミューテートすることになるので)
|
|
|
|
|
let n = {
|
|
|
|
|
...this.appearNote,
|
|
|
|
|
};
|
|
|
|
|
|
2020-04-14 00:42:59 +09:00
|
|
|
|
if (body.emoji) {
|
2020-07-27 23:25:37 +09:00
|
|
|
|
const emojis = this.appearNote.emojis || [];
|
|
|
|
|
if (!emojis.includes(body.emoji)) {
|
|
|
|
|
n.emojis = [...emojis, body.emoji];
|
2020-04-14 00:42:59 +09:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-27 23:25:37 +09:00
|
|
|
|
// TODO: reactionsプロパティがない場合ってあったっけ? なければ || {} は消せる
|
|
|
|
|
const currentCount = (this.appearNote.reactions || {})[reaction] || 0;
|
2020-01-30 04:37:25 +09:00
|
|
|
|
|
|
|
|
|
// Increment the count
|
2020-07-27 23:25:37 +09:00
|
|
|
|
n.reactions = {
|
|
|
|
|
...this.appearNote.reactions,
|
|
|
|
|
[reaction]: currentCount + 1
|
|
|
|
|
};
|
2020-01-30 04:37:25 +09:00
|
|
|
|
|
2020-12-19 10:55:52 +09:00
|
|
|
|
if (body.userId === this.$i.id) {
|
2020-07-27 23:25:37 +09:00
|
|
|
|
n.myReaction = reaction;
|
2020-01-30 04:37:25 +09:00
|
|
|
|
}
|
2020-07-27 23:25:37 +09:00
|
|
|
|
|
|
|
|
|
this.updateAppearNote(n);
|
2020-01-30 04:37:25 +09:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case 'unreacted': {
|
|
|
|
|
const reaction = body.reaction;
|
|
|
|
|
|
2020-07-27 23:25:37 +09:00
|
|
|
|
// DeepではなくShallowコピーであることに注意。n.reactions[reaction] = hogeとかしないように(親からもらったデータをミューテートすることになるので)
|
|
|
|
|
let n = {
|
|
|
|
|
...this.appearNote,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// TODO: reactionsプロパティがない場合ってあったっけ? なければ || {} は消せる
|
|
|
|
|
const currentCount = (this.appearNote.reactions || {})[reaction] || 0;
|
2020-01-30 04:37:25 +09:00
|
|
|
|
|
|
|
|
|
// Decrement the count
|
2020-07-27 23:25:37 +09:00
|
|
|
|
n.reactions = {
|
|
|
|
|
...this.appearNote.reactions,
|
|
|
|
|
[reaction]: Math.max(0, currentCount - 1)
|
|
|
|
|
};
|
2020-01-30 04:37:25 +09:00
|
|
|
|
|
2020-12-19 10:55:52 +09:00
|
|
|
|
if (body.userId === this.$i.id) {
|
2020-07-27 23:25:37 +09:00
|
|
|
|
n.myReaction = null;
|
2020-01-30 04:37:25 +09:00
|
|
|
|
}
|
2020-07-27 23:25:37 +09:00
|
|
|
|
|
|
|
|
|
this.updateAppearNote(n);
|
2020-01-30 04:37:25 +09:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case 'pollVoted': {
|
|
|
|
|
const choice = body.choice;
|
2020-07-27 23:25:37 +09:00
|
|
|
|
|
|
|
|
|
// DeepではなくShallowコピーであることに注意。n.reactions[reaction] = hogeとかしないように(親からもらったデータをミューテートすることになるので)
|
|
|
|
|
let n = {
|
|
|
|
|
...this.appearNote,
|
|
|
|
|
};
|
|
|
|
|
|
2020-07-31 19:09:38 +09:00
|
|
|
|
const choices = [...this.appearNote.poll.choices];
|
|
|
|
|
choices[choice] = {
|
|
|
|
|
...choices[choice],
|
|
|
|
|
votes: choices[choice].votes + 1,
|
2020-12-19 10:55:52 +09:00
|
|
|
|
...(body.userId === this.$i.id ? {
|
2020-07-31 19:09:38 +09:00
|
|
|
|
isVoted: true
|
|
|
|
|
} : {})
|
|
|
|
|
};
|
|
|
|
|
|
2020-07-27 23:25:37 +09:00
|
|
|
|
n.poll = {
|
|
|
|
|
...this.appearNote.poll,
|
2020-07-31 19:09:38 +09:00
|
|
|
|
choices: choices
|
2020-07-27 23:25:37 +09:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
this.updateAppearNote(n);
|
2020-01-30 04:37:25 +09:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
case 'deleted': {
|
2020-07-27 08:46:21 +09:00
|
|
|
|
this.isDeleted = true;
|
2020-01-30 04:37:25 +09:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
reply(viaKeyboard = false) {
|
2020-10-17 20:12:00 +09:00
|
|
|
|
pleaseLogin();
|
|
|
|
|
os.post({
|
2020-01-30 04:37:25 +09:00
|
|
|
|
reply: this.appearNote,
|
|
|
|
|
animation: !viaKeyboard,
|
|
|
|
|
}, () => {
|
|
|
|
|
this.focus();
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
2020-02-08 23:52:40 +09:00
|
|
|
|
renote(viaKeyboard = false) {
|
2020-10-17 20:12:00 +09:00
|
|
|
|
pleaseLogin();
|
2020-01-30 04:37:25 +09:00
|
|
|
|
this.blur();
|
2021-08-08 12:19:10 +09:00
|
|
|
|
os.popupMenu([{
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.renote,
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-retweet',
|
2020-10-17 20:12:00 +09:00
|
|
|
|
action: () => {
|
|
|
|
|
os.api('notes/create', {
|
|
|
|
|
renoteId: this.appearNote.id
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}, {
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.quote,
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-quote-right',
|
2020-10-17 20:12:00 +09:00
|
|
|
|
action: () => {
|
|
|
|
|
os.post({
|
|
|
|
|
renote: this.appearNote,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}], this.$refs.renoteButton, {
|
2020-02-08 23:52:40 +09:00
|
|
|
|
viaKeyboard
|
2020-02-23 02:34:54 +09:00
|
|
|
|
});
|
2020-01-30 04:37:25 +09:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
renoteDirectly() {
|
2020-12-11 21:22:41 +09:00
|
|
|
|
os.apiWithDialog('notes/create', {
|
2020-01-30 04:37:25 +09:00
|
|
|
|
renoteId: this.appearNote.id
|
2020-12-11 21:22:41 +09:00
|
|
|
|
}, undefined, (res: any) => {
|
|
|
|
|
os.dialog({
|
|
|
|
|
type: 'success',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.renoted,
|
2020-12-11 21:22:41 +09:00
|
|
|
|
});
|
|
|
|
|
}, (e: Error) => {
|
|
|
|
|
if (e.id === 'b5c90186-4ab0-49c8-9bba-a1f76c282ba4') {
|
|
|
|
|
os.dialog({
|
|
|
|
|
type: 'error',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.cantRenote,
|
2020-12-11 21:22:41 +09:00
|
|
|
|
});
|
|
|
|
|
} else if (e.id === 'fd4cc33e-2a37-48dd-99cc-9b806eb2031a') {
|
|
|
|
|
os.dialog({
|
|
|
|
|
type: 'error',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.cantReRenote,
|
2020-12-11 21:22:41 +09:00
|
|
|
|
});
|
|
|
|
|
}
|
2020-01-30 04:37:25 +09:00
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
react(viaKeyboard = false) {
|
2020-10-17 20:12:00 +09:00
|
|
|
|
pleaseLogin();
|
2020-01-30 04:37:25 +09:00
|
|
|
|
this.blur();
|
2021-03-05 13:49:46 +09:00
|
|
|
|
reactionPicker.show(this.$refs.reactButton, reaction => {
|
2021-02-28 01:09:59 +09:00
|
|
|
|
os.api('notes/reactions/create', {
|
|
|
|
|
noteId: this.appearNote.id,
|
|
|
|
|
reaction: reaction
|
|
|
|
|
});
|
|
|
|
|
}, () => {
|
|
|
|
|
this.focus();
|
|
|
|
|
});
|
2020-01-30 04:37:25 +09:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
reactDirectly(reaction) {
|
2020-10-17 20:12:00 +09:00
|
|
|
|
os.api('notes/reactions/create', {
|
2020-01-30 04:37:25 +09:00
|
|
|
|
noteId: this.appearNote.id,
|
|
|
|
|
reaction: reaction
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
2020-07-27 23:25:37 +09:00
|
|
|
|
undoReact(note) {
|
|
|
|
|
const oldReaction = note.myReaction;
|
2020-01-30 04:37:25 +09:00
|
|
|
|
if (!oldReaction) return;
|
2020-10-17 20:12:00 +09:00
|
|
|
|
os.api('notes/reactions/delete', {
|
2020-07-27 23:25:37 +09:00
|
|
|
|
noteId: note.id
|
2020-01-30 04:37:25 +09:00
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
favorite() {
|
2020-10-17 20:12:00 +09:00
|
|
|
|
pleaseLogin();
|
|
|
|
|
os.apiWithDialog('notes/favorites/create', {
|
2020-01-30 04:37:25 +09:00
|
|
|
|
noteId: this.appearNote.id
|
2020-12-11 21:22:41 +09:00
|
|
|
|
}, undefined, (res: any) => {
|
|
|
|
|
os.dialog({
|
|
|
|
|
type: 'success',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.favorited,
|
2020-12-11 21:22:41 +09:00
|
|
|
|
});
|
|
|
|
|
}, (e: Error) => {
|
|
|
|
|
if (e.id === 'a402c12b-34dd-41d2-97d8-4d2ffd96a1a6') {
|
|
|
|
|
os.dialog({
|
|
|
|
|
type: 'error',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.alreadyFavorited,
|
2020-12-11 21:22:41 +09:00
|
|
|
|
});
|
|
|
|
|
} else if (e.id === '6dd26674-e060-4816-909a-45ba3f4da458') {
|
|
|
|
|
os.dialog({
|
|
|
|
|
type: 'error',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.cantFavorite,
|
2020-12-11 21:22:41 +09:00
|
|
|
|
});
|
|
|
|
|
}
|
2020-01-30 04:37:25 +09:00
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
del() {
|
2020-10-17 20:12:00 +09:00
|
|
|
|
os.dialog({
|
2020-01-30 04:37:25 +09:00
|
|
|
|
type: 'warning',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.noteDeleteConfirm,
|
2020-01-30 04:37:25 +09:00
|
|
|
|
showCancelButton: true
|
|
|
|
|
}).then(({ canceled }) => {
|
|
|
|
|
if (canceled) return;
|
|
|
|
|
|
2020-10-17 20:12:00 +09:00
|
|
|
|
os.api('notes/delete', {
|
2020-01-30 04:37:25 +09:00
|
|
|
|
noteId: this.appearNote.id
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
2020-03-21 18:58:05 +09:00
|
|
|
|
delEdit() {
|
2020-10-17 20:12:00 +09:00
|
|
|
|
os.dialog({
|
2020-03-21 18:58:05 +09:00
|
|
|
|
type: 'warning',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.deleteAndEditConfirm,
|
2020-03-21 18:58:05 +09:00
|
|
|
|
showCancelButton: true
|
|
|
|
|
}).then(({ canceled }) => {
|
|
|
|
|
if (canceled) return;
|
|
|
|
|
|
2020-10-17 20:12:00 +09:00
|
|
|
|
os.api('notes/delete', {
|
2020-03-21 18:58:05 +09:00
|
|
|
|
noteId: this.appearNote.id
|
|
|
|
|
});
|
|
|
|
|
|
2020-10-17 20:12:00 +09:00
|
|
|
|
os.post({ initialNote: this.appearNote, renote: this.appearNote.renote, reply: this.appearNote.reply, channel: this.appearNote.channel });
|
2020-03-21 18:58:05 +09:00
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
2020-02-08 23:52:40 +09:00
|
|
|
|
toggleFavorite(favorite: boolean) {
|
2020-10-17 20:12:00 +09:00
|
|
|
|
os.apiWithDialog(favorite ? 'notes/favorites/create' : 'notes/favorites/delete', {
|
2020-02-08 23:52:40 +09:00
|
|
|
|
noteId: this.appearNote.id
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
toggleWatch(watch: boolean) {
|
2020-10-17 20:12:00 +09:00
|
|
|
|
os.apiWithDialog(watch ? 'notes/watching/create' : 'notes/watching/delete', {
|
2020-02-08 23:52:40 +09:00
|
|
|
|
noteId: this.appearNote.id
|
2020-01-30 04:37:25 +09:00
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
2020-10-17 20:12:00 +09:00
|
|
|
|
getMenu() {
|
2020-02-08 23:52:40 +09:00
|
|
|
|
let menu;
|
2020-12-19 10:55:52 +09:00
|
|
|
|
if (this.$i) {
|
2020-10-17 20:12:00 +09:00
|
|
|
|
const statePromise = os.api('notes/state', {
|
2020-02-08 23:52:40 +09:00
|
|
|
|
noteId: this.appearNote.id
|
|
|
|
|
});
|
2020-10-17 20:12:00 +09:00
|
|
|
|
|
2020-02-08 23:52:40 +09:00
|
|
|
|
menu = [{
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-copy',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.copyContent,
|
2020-02-08 23:52:40 +09:00
|
|
|
|
action: this.copyContent
|
|
|
|
|
}, {
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-link',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.copyLink,
|
2020-02-08 23:52:40 +09:00
|
|
|
|
action: this.copyLink
|
2020-04-02 21:59:14 +09:00
|
|
|
|
}, (this.appearNote.url || this.appearNote.uri) ? {
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-external-link-square-alt',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.showOnRemote,
|
2020-02-08 23:52:40 +09:00
|
|
|
|
action: () => {
|
2020-04-02 21:59:14 +09:00
|
|
|
|
window.open(this.appearNote.url || this.appearNote.uri, '_blank');
|
2020-02-08 23:52:40 +09:00
|
|
|
|
}
|
|
|
|
|
} : undefined,
|
2021-04-11 12:42:48 +09:00
|
|
|
|
{
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-share-alt',
|
2021-04-11 12:42:48 +09:00
|
|
|
|
text: this.$ts.share,
|
|
|
|
|
action: this.share
|
|
|
|
|
},
|
2021-08-15 20:26:44 +09:00
|
|
|
|
this.$instance.translatorAvailable ? {
|
|
|
|
|
icon: 'fas fa-language',
|
|
|
|
|
text: this.$ts.translate,
|
|
|
|
|
action: this.translate
|
|
|
|
|
} : undefined,
|
2020-02-08 23:52:40 +09:00
|
|
|
|
null,
|
2020-10-17 20:12:00 +09:00
|
|
|
|
statePromise.then(state => state.isFavorited ? {
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-star',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.unfavorite,
|
2020-02-08 23:52:40 +09:00
|
|
|
|
action: () => this.toggleFavorite(false)
|
|
|
|
|
} : {
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-star',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.favorite,
|
2020-02-08 23:52:40 +09:00
|
|
|
|
action: () => this.toggleFavorite(true)
|
2020-10-17 20:12:00 +09:00
|
|
|
|
}),
|
2020-11-15 12:04:54 +09:00
|
|
|
|
{
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-paperclip',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.clip,
|
2020-11-15 12:04:54 +09:00
|
|
|
|
action: () => this.clip()
|
|
|
|
|
},
|
2020-12-19 10:55:52 +09:00
|
|
|
|
(this.appearNote.userId != this.$i.id) ? statePromise.then(state => state.isWatching ? {
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-eye-slash',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.unwatch,
|
2020-02-08 23:52:40 +09:00
|
|
|
|
action: () => this.toggleWatch(false)
|
|
|
|
|
} : {
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-eye',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.watch,
|
2020-02-08 23:52:40 +09:00
|
|
|
|
action: () => this.toggleWatch(true)
|
2020-10-17 20:12:00 +09:00
|
|
|
|
}) : undefined,
|
2020-12-19 10:55:52 +09:00
|
|
|
|
this.appearNote.userId == this.$i.id ? (this.$i.pinnedNoteIds || []).includes(this.appearNote.id) ? {
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-thumbtack',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.unpin,
|
2020-02-08 23:52:40 +09:00
|
|
|
|
action: () => this.togglePin(false)
|
|
|
|
|
} : {
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-thumbtack',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.pin,
|
2020-02-08 23:52:40 +09:00
|
|
|
|
action: () => this.togglePin(true)
|
|
|
|
|
} : undefined,
|
2020-12-19 10:55:52 +09:00
|
|
|
|
...(this.$i.isModerator || this.$i.isAdmin ? [
|
2020-02-18 08:41:32 +09:00
|
|
|
|
null,
|
|
|
|
|
{
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-bullhorn',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.promote,
|
2020-02-18 08:41:32 +09:00
|
|
|
|
action: this.promote
|
|
|
|
|
}]
|
|
|
|
|
: []
|
|
|
|
|
),
|
2020-12-19 10:55:52 +09:00
|
|
|
|
...(this.appearNote.userId != this.$i.id ? [
|
2020-10-19 19:29:04 +09:00
|
|
|
|
null,
|
|
|
|
|
{
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-exclamation-circle',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.reportAbuse,
|
2020-10-19 19:29:04 +09:00
|
|
|
|
action: () => {
|
|
|
|
|
const u = `${url}/notes/${this.appearNote.id}`;
|
2021-03-23 17:30:14 +09:00
|
|
|
|
os.popup(import('@client/components/abuse-report-window.vue'), {
|
2020-10-19 19:29:04 +09:00
|
|
|
|
user: this.appearNote.user,
|
|
|
|
|
initialComment: `Note: ${u}\n-----\n`
|
|
|
|
|
}, {}, 'closed');
|
|
|
|
|
}
|
|
|
|
|
}]
|
|
|
|
|
: []
|
|
|
|
|
),
|
2020-12-19 10:55:52 +09:00
|
|
|
|
...(this.appearNote.userId == this.$i.id || this.$i.isModerator || this.$i.isAdmin ? [
|
2020-02-08 23:52:40 +09:00
|
|
|
|
null,
|
2020-12-19 10:55:52 +09:00
|
|
|
|
this.appearNote.userId == this.$i.id ? {
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-edit',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.deleteAndEdit,
|
2020-03-21 18:58:05 +09:00
|
|
|
|
action: this.delEdit
|
2020-04-13 23:27:12 +09:00
|
|
|
|
} : undefined,
|
2020-02-08 23:52:40 +09:00
|
|
|
|
{
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-trash-alt',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.delete,
|
2020-10-17 20:12:00 +09:00
|
|
|
|
danger: true,
|
2020-02-08 23:52:40 +09:00
|
|
|
|
action: this.del
|
|
|
|
|
}]
|
|
|
|
|
: []
|
|
|
|
|
)]
|
|
|
|
|
.filter(x => x !== undefined);
|
|
|
|
|
} else {
|
|
|
|
|
menu = [{
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-copy',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.copyContent,
|
2020-02-08 23:52:40 +09:00
|
|
|
|
action: this.copyContent
|
|
|
|
|
}, {
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-link',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.copyLink,
|
2020-02-08 23:52:40 +09:00
|
|
|
|
action: this.copyLink
|
2020-04-02 21:59:14 +09:00
|
|
|
|
}, (this.appearNote.url || this.appearNote.uri) ? {
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-external-link-square-alt',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.showOnRemote,
|
2020-02-08 23:52:40 +09:00
|
|
|
|
action: () => {
|
2020-04-02 21:59:14 +09:00
|
|
|
|
window.open(this.appearNote.url || this.appearNote.uri, '_blank');
|
2020-02-08 23:52:40 +09:00
|
|
|
|
}
|
|
|
|
|
} : undefined]
|
|
|
|
|
.filter(x => x !== undefined);
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-17 20:12:00 +09:00
|
|
|
|
if (noteActions.length > 0) {
|
|
|
|
|
menu = menu.concat([null, ...noteActions.map(action => ({
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-plug',
|
2020-07-12 00:38:55 +09:00
|
|
|
|
text: action.title,
|
|
|
|
|
action: () => {
|
|
|
|
|
action.handler(this.appearNote);
|
|
|
|
|
}
|
|
|
|
|
}))]);
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-17 20:12:00 +09:00
|
|
|
|
return menu;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
onContextmenu(e) {
|
|
|
|
|
const isLink = (el: HTMLElement) => {
|
|
|
|
|
if (el.tagName === 'A') return true;
|
|
|
|
|
if (el.parentElement) {
|
|
|
|
|
return isLink(el.parentElement);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
if (isLink(e.target)) return;
|
|
|
|
|
if (window.getSelection().toString() !== '') return;
|
2021-02-20 16:16:19 +09:00
|
|
|
|
|
|
|
|
|
if (this.$store.state.useReactionPickerForContextMenu) {
|
|
|
|
|
e.preventDefault();
|
|
|
|
|
this.react();
|
|
|
|
|
} else {
|
|
|
|
|
os.contextMenu(this.getMenu(), e).then(this.focus);
|
|
|
|
|
}
|
2020-10-17 20:12:00 +09:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
menu(viaKeyboard = false) {
|
2021-08-08 12:19:10 +09:00
|
|
|
|
os.popupMenu(this.getMenu(), this.$refs.menuButton, {
|
2020-02-08 23:52:40 +09:00
|
|
|
|
viaKeyboard
|
|
|
|
|
}).then(this.focus);
|
|
|
|
|
},
|
|
|
|
|
|
2020-02-09 18:52:53 +09:00
|
|
|
|
showRenoteMenu(viaKeyboard = false) {
|
2020-05-16 12:15:59 +09:00
|
|
|
|
if (!this.isMyRenote) return;
|
2021-08-08 12:19:10 +09:00
|
|
|
|
os.popupMenu([{
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.unrenote,
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-trash-alt',
|
2020-10-18 10:38:35 +09:00
|
|
|
|
danger: true,
|
2020-10-17 20:12:00 +09:00
|
|
|
|
action: () => {
|
|
|
|
|
os.api('notes/delete', {
|
|
|
|
|
noteId: this.note.id
|
|
|
|
|
});
|
|
|
|
|
this.isDeleted = true;
|
|
|
|
|
}
|
|
|
|
|
}], this.$refs.renoteTime, {
|
2020-02-08 23:52:40 +09:00
|
|
|
|
viaKeyboard: viaKeyboard
|
2020-02-06 09:09:24 +09:00
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
2020-01-30 04:37:25 +09:00
|
|
|
|
toggleShowContent() {
|
|
|
|
|
this.showContent = !this.showContent;
|
|
|
|
|
},
|
|
|
|
|
|
2020-02-08 23:52:40 +09:00
|
|
|
|
copyContent() {
|
|
|
|
|
copyToClipboard(this.appearNote.text);
|
2020-10-17 20:12:00 +09:00
|
|
|
|
os.success();
|
2020-02-08 23:52:40 +09:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
copyLink() {
|
|
|
|
|
copyToClipboard(`${url}/notes/${this.appearNote.id}`);
|
2020-10-17 20:12:00 +09:00
|
|
|
|
os.success();
|
2020-02-08 23:52:40 +09:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
togglePin(pin: boolean) {
|
2020-10-17 20:12:00 +09:00
|
|
|
|
os.apiWithDialog(pin ? 'i/pin' : 'i/unpin', {
|
2020-02-08 23:52:40 +09:00
|
|
|
|
noteId: this.appearNote.id
|
2020-10-17 20:12:00 +09:00
|
|
|
|
}, undefined, null, e => {
|
2020-02-08 23:52:40 +09:00
|
|
|
|
if (e.id === '72dab508-c64d-498f-8740-a8eec1ba385a') {
|
2020-10-17 20:12:00 +09:00
|
|
|
|
os.dialog({
|
2020-02-08 23:52:40 +09:00
|
|
|
|
type: 'error',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.pinLimitExceeded
|
2020-02-08 23:52:40 +09:00
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
2020-11-15 12:04:54 +09:00
|
|
|
|
async clip() {
|
|
|
|
|
const clips = await os.api('clips/list');
|
2021-08-08 12:19:10 +09:00
|
|
|
|
os.popupMenu([{
|
2021-04-20 23:22:59 +09:00
|
|
|
|
icon: 'fas fa-plus',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
text: this.$ts.createNew,
|
2020-11-15 12:04:54 +09:00
|
|
|
|
action: async () => {
|
2020-12-26 10:47:36 +09:00
|
|
|
|
const { canceled, result } = await os.form(this.$ts.createNewClip, {
|
2020-11-15 12:04:54 +09:00
|
|
|
|
name: {
|
|
|
|
|
type: 'string',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
label: this.$ts.name
|
2020-11-15 12:04:54 +09:00
|
|
|
|
},
|
|
|
|
|
description: {
|
|
|
|
|
type: 'string',
|
|
|
|
|
required: false,
|
|
|
|
|
multiline: true,
|
2020-12-26 10:47:36 +09:00
|
|
|
|
label: this.$ts.description
|
2020-11-15 12:04:54 +09:00
|
|
|
|
},
|
|
|
|
|
isPublic: {
|
|
|
|
|
type: 'boolean',
|
2020-12-26 10:47:36 +09:00
|
|
|
|
label: this.$ts.public,
|
2020-11-15 14:18:25 +09:00
|
|
|
|
default: false
|
2020-11-15 12:04:54 +09:00
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
if (canceled) return;
|
|
|
|
|
|
|
|
|
|
const clip = await os.apiWithDialog('clips/create', result);
|
|
|
|
|
|
|
|
|
|
os.apiWithDialog('clips/add-note', { clipId: clip.id, noteId: this.appearNote.id });
|
|
|
|
|
}
|
|
|
|
|
}, null, ...clips.map(clip => ({
|
|
|
|
|
text: clip.name,
|
|
|
|
|
action: () => {
|
|
|
|
|
os.apiWithDialog('clips/add-note', { clipId: clip.id, noteId: this.appearNote.id });
|
|
|
|
|
}
|
|
|
|
|
}))], this.$refs.menuButton, {
|
|
|
|
|
}).then(this.focus);
|
|
|
|
|
},
|
|
|
|
|
|
2020-02-18 08:41:32 +09:00
|
|
|
|
async promote() {
|
2020-10-17 20:12:00 +09:00
|
|
|
|
const { canceled, result: days } = await os.dialog({
|
2020-12-26 10:47:36 +09:00
|
|
|
|
title: this.$ts.numberOfDays,
|
2020-02-18 08:41:32 +09:00
|
|
|
|
input: { type: 'number' }
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (canceled) return;
|
|
|
|
|
|
2020-10-17 20:12:00 +09:00
|
|
|
|
os.apiWithDialog('admin/promo/create', {
|
2020-02-18 08:41:32 +09:00
|
|
|
|
noteId: this.appearNote.id,
|
|
|
|
|
expiresAt: Date.now() + (86400000 * days)
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
2021-04-11 12:42:48 +09:00
|
|
|
|
share() {
|
|
|
|
|
navigator.share({
|
|
|
|
|
title: this.$t('noteOf', { user: this.appearNote.user.name }),
|
|
|
|
|
text: this.appearNote.text,
|
|
|
|
|
url: `${url}/notes/${this.appearNote.id}`
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
2021-08-15 20:26:44 +09:00
|
|
|
|
async translate() {
|
|
|
|
|
if (this.translation != null) return;
|
|
|
|
|
this.translating = true;
|
|
|
|
|
const res = await os.api('notes/translate', {
|
|
|
|
|
noteId: this.appearNote.id,
|
|
|
|
|
targetLang: localStorage.getItem('lang') || navigator.language,
|
|
|
|
|
});
|
|
|
|
|
this.translating = false;
|
|
|
|
|
this.translation = res;
|
|
|
|
|
},
|
|
|
|
|
|
2020-01-30 04:37:25 +09:00
|
|
|
|
focus() {
|
|
|
|
|
this.$el.focus();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
blur() {
|
|
|
|
|
this.$el.blur();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
focusBefore() {
|
2020-02-08 23:52:40 +09:00
|
|
|
|
focusPrev(this.$el);
|
2020-01-30 04:37:25 +09:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
focusAfter() {
|
2020-02-08 23:52:40 +09:00
|
|
|
|
focusNext(this.$el);
|
2020-10-17 20:12:00 +09:00
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
userPage
|
2020-01-30 04:37:25 +09:00
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
2021-02-15 17:17:19 +09:00
|
|
|
|
.tkcbzcuz {
|
2020-01-30 04:37:25 +09:00
|
|
|
|
position: relative;
|
|
|
|
|
transition: box-shadow 0.1s ease;
|
2021-04-10 12:40:50 +09:00
|
|
|
|
overflow: clip;
|
2020-10-17 20:12:00 +09:00
|
|
|
|
contain: content;
|
2020-01-30 04:37:25 +09:00
|
|
|
|
|
2020-12-26 22:56:01 +09:00
|
|
|
|
// これらの指定はパフォーマンス向上には有効だが、ノートの高さは一定でないため、
|
|
|
|
|
// 下の方までスクロールすると上のノートの高さがここで決め打ちされたものに変化し、表示しているノートの位置が変わってしまう
|
|
|
|
|
// ノートがマウントされたときに自身の高さを取得し contain-intrinsic-size を設定しなおせばほぼ解決できそうだが、
|
|
|
|
|
// 今度はその処理自体がパフォーマンス低下の原因にならないか懸念される。また、被リアクションでも高さは変化するため、やはり多少のズレは生じる
|
|
|
|
|
// 一度レンダリングされた要素はブラウザがよしなにサイズを覚えておいてくれるような実装になるまで待った方が良さそう(なるのか?)
|
|
|
|
|
//content-visibility: auto;
|
|
|
|
|
//contain-intrinsic-size: 0 128px;
|
|
|
|
|
|
2020-01-30 04:37:25 +09:00
|
|
|
|
&:focus {
|
|
|
|
|
outline: none;
|
2020-10-17 20:12:00 +09:00
|
|
|
|
|
|
|
|
|
&:after {
|
|
|
|
|
content: "";
|
|
|
|
|
pointer-events: none;
|
|
|
|
|
display: block;
|
|
|
|
|
position: absolute;
|
|
|
|
|
z-index: 10;
|
|
|
|
|
top: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
margin: auto;
|
|
|
|
|
width: calc(100% - 8px);
|
|
|
|
|
height: calc(100% - 8px);
|
|
|
|
|
border: dashed 1px var(--focus);
|
|
|
|
|
border-radius: var(--radius);
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
}
|
2020-01-30 04:37:25 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&:hover > .article > .main > .footer > .button {
|
|
|
|
|
opacity: 1;
|
|
|
|
|
}
|
|
|
|
|
|
2020-02-18 18:14:38 +09:00
|
|
|
|
> .info {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
2020-01-30 04:37:25 +09:00
|
|
|
|
padding: 16px 32px 8px 32px;
|
|
|
|
|
line-height: 24px;
|
|
|
|
|
font-size: 90%;
|
|
|
|
|
white-space: pre;
|
|
|
|
|
color: #d28a3f;
|
|
|
|
|
|
2021-04-20 23:22:59 +09:00
|
|
|
|
> i {
|
2020-01-30 04:37:25 +09:00
|
|
|
|
margin-right: 4px;
|
|
|
|
|
}
|
2020-02-18 18:14:38 +09:00
|
|
|
|
|
|
|
|
|
> .hide {
|
|
|
|
|
margin-left: auto;
|
|
|
|
|
color: inherit;
|
|
|
|
|
}
|
2020-01-30 04:37:25 +09:00
|
|
|
|
}
|
|
|
|
|
|
2020-02-18 18:14:38 +09:00
|
|
|
|
> .info + .article {
|
2020-01-30 04:37:25 +09:00
|
|
|
|
padding-top: 8px;
|
|
|
|
|
}
|
|
|
|
|
|
2020-03-20 19:19:28 +09:00
|
|
|
|
> .reply-to {
|
|
|
|
|
opacity: 0.7;
|
|
|
|
|
padding-bottom: 0;
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-30 04:37:25 +09:00
|
|
|
|
> .renote {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center;
|
|
|
|
|
padding: 16px 32px 8px 32px;
|
|
|
|
|
line-height: 28px;
|
|
|
|
|
white-space: pre;
|
|
|
|
|
color: var(--renote);
|
|
|
|
|
|
|
|
|
|
> .avatar {
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
display: inline-block;
|
|
|
|
|
width: 28px;
|
|
|
|
|
height: 28px;
|
|
|
|
|
margin: 0 8px 0 0;
|
|
|
|
|
border-radius: 6px;
|
|
|
|
|
}
|
|
|
|
|
|
2021-04-20 23:22:59 +09:00
|
|
|
|
> i {
|
2020-01-30 04:37:25 +09:00
|
|
|
|
margin-right: 4px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
> span {
|
2021-03-02 22:57:16 +09:00
|
|
|
|
overflow: hidden;
|
2020-01-30 04:37:25 +09:00
|
|
|
|
flex-shrink: 1;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
white-space: nowrap;
|
|
|
|
|
|
|
|
|
|
> .name {
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
> .info {
|
|
|
|
|
margin-left: auto;
|
|
|
|
|
font-size: 0.9em;
|
|
|
|
|
|
2020-02-06 09:09:24 +09:00
|
|
|
|
> .time {
|
2020-01-30 04:37:25 +09:00
|
|
|
|
flex-shrink: 0;
|
2020-02-06 09:09:24 +09:00
|
|
|
|
color: inherit;
|
2020-05-15 20:39:11 +09:00
|
|
|
|
|
|
|
|
|
> .dropdownIcon {
|
|
|
|
|
margin-right: 4px;
|
|
|
|
|
}
|
2020-01-30 04:37:25 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
> .visibility {
|
|
|
|
|
margin-left: 8px;
|
2020-05-16 22:06:39 +09:00
|
|
|
|
}
|
2020-01-30 04:37:25 +09:00
|
|
|
|
|
2020-05-16 22:06:39 +09:00
|
|
|
|
> .localOnly {
|
|
|
|
|
margin-left: 8px;
|
2020-01-30 04:37:25 +09:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
> .renote + .article {
|
|
|
|
|
padding-top: 8px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
> .article {
|
|
|
|
|
display: flex;
|
|
|
|
|
padding: 28px 32px 18px;
|
|
|
|
|
|
|
|
|
|
> .avatar {
|
|
|
|
|
flex-shrink: 0;
|
|
|
|
|
display: block;
|
|
|
|
|
margin: 0 14px 8px 0;
|
|
|
|
|
width: 58px;
|
|
|
|
|
height: 58px;
|
2021-04-10 12:40:50 +09:00
|
|
|
|
position: sticky;
|
|
|
|
|
top: calc(22px + var(--stickyTop, 0px));
|
|
|
|
|
left: 0;
|
2020-01-30 04:37:25 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
> .main {
|
|
|
|
|
flex: 1;
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
|
|
|
|
> .body {
|
|
|
|
|
> .cw {
|
|
|
|
|
cursor: default;
|
|
|
|
|
display: block;
|
|
|
|
|
margin: 0;
|
|
|
|
|
padding: 0;
|
|
|
|
|
overflow-wrap: break-word;
|
|
|
|
|
|
|
|
|
|
> .text {
|
|
|
|
|
margin-right: 8px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
> .content {
|
2020-12-30 09:58:57 +09:00
|
|
|
|
&.collapsed {
|
|
|
|
|
position: relative;
|
|
|
|
|
max-height: 9em;
|
2021-03-02 22:57:16 +09:00
|
|
|
|
overflow: hidden;
|
2020-12-30 09:58:57 +09:00
|
|
|
|
|
|
|
|
|
> .fade {
|
|
|
|
|
display: block;
|
|
|
|
|
position: absolute;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 64px;
|
|
|
|
|
background: linear-gradient(0deg, var(--panel), var(--X15));
|
|
|
|
|
|
|
|
|
|
> span {
|
|
|
|
|
display: inline-block;
|
|
|
|
|
background: var(--panel);
|
|
|
|
|
padding: 6px 10px;
|
|
|
|
|
font-size: 0.8em;
|
|
|
|
|
border-radius: 999px;
|
|
|
|
|
box-shadow: 0 2px 6px rgb(0 0 0 / 20%);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&:hover {
|
|
|
|
|
> span {
|
|
|
|
|
background: var(--panelHighlight);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-30 04:37:25 +09:00
|
|
|
|
> .text {
|
|
|
|
|
overflow-wrap: break-word;
|
|
|
|
|
|
|
|
|
|
> .reply {
|
|
|
|
|
color: var(--accent);
|
|
|
|
|
margin-right: 0.5em;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
> .rp {
|
|
|
|
|
margin-left: 4px;
|
|
|
|
|
font-style: oblique;
|
|
|
|
|
color: var(--renote);
|
|
|
|
|
}
|
2021-08-15 20:26:44 +09:00
|
|
|
|
|
|
|
|
|
> .translation {
|
|
|
|
|
border: solid 0.5px var(--divider);
|
|
|
|
|
border-radius: var(--radius);
|
|
|
|
|
padding: 12px;
|
|
|
|
|
margin-top: 8px;
|
|
|
|
|
}
|
2020-01-30 04:37:25 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
> .url-preview {
|
|
|
|
|
margin-top: 8px;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-10 17:06:20 +09:00
|
|
|
|
> .poll {
|
2020-01-30 04:37:25 +09:00
|
|
|
|
font-size: 80%;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
> .renote {
|
|
|
|
|
padding: 8px 0;
|
|
|
|
|
|
|
|
|
|
> * {
|
|
|
|
|
padding: 16px;
|
|
|
|
|
border: dashed 1px var(--renote);
|
|
|
|
|
border-radius: 8px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-08-18 22:44:21 +09:00
|
|
|
|
|
|
|
|
|
> .channel {
|
|
|
|
|
opacity: 0.7;
|
|
|
|
|
font-size: 80%;
|
|
|
|
|
}
|
2020-01-30 04:37:25 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
> .footer {
|
|
|
|
|
> .button {
|
|
|
|
|
margin: 0;
|
|
|
|
|
padding: 8px;
|
|
|
|
|
opacity: 0.7;
|
|
|
|
|
|
|
|
|
|
&:not(:last-child) {
|
|
|
|
|
margin-right: 28px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&:hover {
|
2020-02-15 01:18:48 +09:00
|
|
|
|
color: var(--fgHighlighted);
|
2020-01-30 04:37:25 +09:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
> .count {
|
|
|
|
|
display: inline;
|
|
|
|
|
margin: 0 0 0 8px;
|
|
|
|
|
opacity: 0.7;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.reacted {
|
|
|
|
|
color: var(--accent);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-03-21 12:32:40 +09:00
|
|
|
|
|
|
|
|
|
> .reply {
|
2021-04-10 12:40:50 +09:00
|
|
|
|
border-top: solid 0.5px var(--divider);
|
2020-03-21 12:32:40 +09:00
|
|
|
|
}
|
2020-07-11 10:13:11 +09:00
|
|
|
|
|
|
|
|
|
&.max-width_500px {
|
|
|
|
|
font-size: 0.9em;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.max-width_450px {
|
|
|
|
|
> .renote {
|
|
|
|
|
padding: 8px 16px 0 16px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
> .info {
|
|
|
|
|
padding: 8px 16px 0 16px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
> .article {
|
|
|
|
|
padding: 14px 16px 9px;
|
|
|
|
|
|
|
|
|
|
> .avatar {
|
|
|
|
|
margin: 0 10px 8px 0;
|
|
|
|
|
width: 50px;
|
|
|
|
|
height: 50px;
|
2021-04-10 12:40:50 +09:00
|
|
|
|
top: calc(14px + var(--stickyTop, 0px));
|
2020-07-11 10:13:11 +09:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.max-width_350px {
|
|
|
|
|
> .article {
|
|
|
|
|
> .main {
|
|
|
|
|
> .footer {
|
|
|
|
|
> .button {
|
|
|
|
|
&:not(:last-child) {
|
|
|
|
|
margin-right: 18px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
&.max-width_300px {
|
|
|
|
|
font-size: 0.825em;
|
|
|
|
|
|
|
|
|
|
> .article {
|
|
|
|
|
> .avatar {
|
|
|
|
|
width: 44px;
|
|
|
|
|
height: 44px;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
> .main {
|
|
|
|
|
> .footer {
|
|
|
|
|
> .button {
|
|
|
|
|
&:not(:last-child) {
|
|
|
|
|
margin-right: 12px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-01-30 04:37:25 +09:00
|
|
|
|
}
|
2020-07-27 13:34:20 +09:00
|
|
|
|
|
|
|
|
|
.muted {
|
|
|
|
|
padding: 8px;
|
|
|
|
|
text-align: center;
|
|
|
|
|
opacity: 0.7;
|
|
|
|
|
}
|
2020-01-30 04:37:25 +09:00
|
|
|
|
</style>
|