enhance(frontend): リアクションの総数を表示するように (#13532)
* enhance(frontend): リアクションの総数を表示するように * Update Changelog * リアクション選択済の色をaccentに
This commit is contained in:
		
							parent
							
								
									62922352b3
								
							
						
					
					
						commit
						7ead98cbe5
					
				
					 14 changed files with 79 additions and 29 deletions
				
			
		| 
						 | 
					@ -5,6 +5,8 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Client
 | 
					### Client
 | 
				
			||||||
- Enhance: 自分のノートの添付ファイルから直接ファイルの詳細ページに飛べるように
 | 
					- Enhance: 自分のノートの添付ファイルから直接ファイルの詳細ページに飛べるように
 | 
				
			||||||
 | 
					- Enhance: リアクション・いいねの総数を表示するように
 | 
				
			||||||
 | 
					- Enhance: リアクション受け入れが「いいねのみ」の場合はリアクション絵文字一覧を表示しないように
 | 
				
			||||||
- Fix: 一部のページ内リンクが正しく動作しない問題を修正
 | 
					- Fix: 一部のページ内リンクが正しく動作しない問題を修正
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Server
 | 
					### Server
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										4
									
								
								locales/index.d.ts
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								locales/index.d.ts
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -8909,6 +8909,10 @@ export interface Locale extends ILocale {
 | 
				
			||||||
         * {n}人がリアクションしました
 | 
					         * {n}人がリアクションしました
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        "reactedBySomeUsers": ParameterizedString<"n">;
 | 
					        "reactedBySomeUsers": ParameterizedString<"n">;
 | 
				
			||||||
 | 
					        /**
 | 
				
			||||||
 | 
					         * {n}人がいいねしました
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        "likedBySomeUsers": ParameterizedString<"n">;
 | 
				
			||||||
        /**
 | 
					        /**
 | 
				
			||||||
         * {n}人がリノートしました
 | 
					         * {n}人がリノートしました
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2355,6 +2355,7 @@ _notification:
 | 
				
			||||||
  sendTestNotification: "テスト通知を送信する"
 | 
					  sendTestNotification: "テスト通知を送信する"
 | 
				
			||||||
  notificationWillBeDisplayedLikeThis: "通知はこのように表示されます"
 | 
					  notificationWillBeDisplayedLikeThis: "通知はこのように表示されます"
 | 
				
			||||||
  reactedBySomeUsers: "{n}人がリアクションしました"
 | 
					  reactedBySomeUsers: "{n}人がリアクションしました"
 | 
				
			||||||
 | 
					  likedBySomeUsers: "{n}人がいいねしました"
 | 
				
			||||||
  renotedBySomeUsers: "{n}人がリノートしました"
 | 
					  renotedBySomeUsers: "{n}人がリノートしました"
 | 
				
			||||||
  followedBySomeUsers: "{n}人にフォローされました"
 | 
					  followedBySomeUsers: "{n}人にフォローされました"
 | 
				
			||||||
  flushNotification: "通知の履歴をリセットする"
 | 
					  flushNotification: "通知の履歴をリセットする"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -333,6 +333,7 @@ export class NoteEntityService implements OnModuleInit {
 | 
				
			||||||
			visibleUserIds: note.visibility === 'specified' ? note.visibleUserIds : undefined,
 | 
								visibleUserIds: note.visibility === 'specified' ? note.visibleUserIds : undefined,
 | 
				
			||||||
			renoteCount: note.renoteCount,
 | 
								renoteCount: note.renoteCount,
 | 
				
			||||||
			repliesCount: note.repliesCount,
 | 
								repliesCount: note.repliesCount,
 | 
				
			||||||
 | 
								reactionCount: Object.values(note.reactions).reduce((a, b) => a + b, 0),
 | 
				
			||||||
			reactions: this.reactionService.convertLegacyReactions(note.reactions),
 | 
								reactions: this.reactionService.convertLegacyReactions(note.reactions),
 | 
				
			||||||
			reactionEmojis: this.customEmojiService.populateEmojis(reactionEmojiNames, host),
 | 
								reactionEmojis: this.customEmojiService.populateEmojis(reactionEmojiNames, host),
 | 
				
			||||||
			reactionAndUserPairCache: opts.withReactionAndUserPairCache ? note.reactionAndUserPairCache : undefined,
 | 
								reactionAndUserPairCache: opts.withReactionAndUserPairCache ? note.reactionAndUserPairCache : undefined,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -223,6 +223,10 @@ export const packedNoteSchema = {
 | 
				
			||||||
				}],
 | 
									}],
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							reactionCount: {
 | 
				
			||||||
 | 
								type: 'number',
 | 
				
			||||||
 | 
								optional: false, nullable: false,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		renoteCount: {
 | 
							renoteCount: {
 | 
				
			||||||
			type: 'number',
 | 
								type: 'number',
 | 
				
			||||||
			optional: false, nullable: false,
 | 
								optional: false, nullable: false,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,7 +93,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
				</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>
 | 
									<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>
 | 
								</div>
 | 
				
			||||||
			<MkReactionsViewer :note="appearNote" :maxNumber="16" @mockUpdateMyReaction="emitUpdReaction">
 | 
								<MkReactionsViewer v-if="appearNote.reactionAcceptance !== 'likeOnly'" :note="appearNote" :maxNumber="16" @mockUpdateMyReaction="emitUpdReaction">
 | 
				
			||||||
				<template #more>
 | 
									<template #more>
 | 
				
			||||||
					<div :class="$style.reactionOmitted">{{ i18n.ts.more }}</div>
 | 
										<div :class="$style.reactionOmitted">{{ i18n.ts.more }}</div>
 | 
				
			||||||
				</template>
 | 
									</template>
 | 
				
			||||||
| 
						 | 
					@ -101,7 +101,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
			<footer :class="$style.footer">
 | 
								<footer :class="$style.footer">
 | 
				
			||||||
				<button :class="$style.footerButton" class="_button" @click="reply()">
 | 
									<button :class="$style.footerButton" class="_button" @click="reply()">
 | 
				
			||||||
					<i class="ti ti-arrow-back-up"></i>
 | 
										<i class="ti ti-arrow-back-up"></i>
 | 
				
			||||||
					<p v-if="appearNote.repliesCount > 0" :class="$style.footerButtonCount">{{ appearNote.repliesCount }}</p>
 | 
										<p v-if="appearNote.repliesCount > 0" :class="$style.footerButtonCount">{{ number(appearNote.repliesCount) }}</p>
 | 
				
			||||||
				</button>
 | 
									</button>
 | 
				
			||||||
				<button
 | 
									<button
 | 
				
			||||||
					v-if="canRenote"
 | 
										v-if="canRenote"
 | 
				
			||||||
| 
						 | 
					@ -111,17 +111,17 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
					@mousedown="renote()"
 | 
										@mousedown="renote()"
 | 
				
			||||||
				>
 | 
									>
 | 
				
			||||||
					<i class="ti ti-repeat"></i>
 | 
										<i class="ti ti-repeat"></i>
 | 
				
			||||||
					<p v-if="appearNote.renoteCount > 0" :class="$style.footerButtonCount">{{ appearNote.renoteCount }}</p>
 | 
										<p v-if="appearNote.renoteCount > 0" :class="$style.footerButtonCount">{{ number(appearNote.renoteCount) }}</p>
 | 
				
			||||||
				</button>
 | 
									</button>
 | 
				
			||||||
				<button v-else :class="$style.footerButton" class="_button" disabled>
 | 
									<button v-else :class="$style.footerButton" class="_button" disabled>
 | 
				
			||||||
					<i class="ti ti-ban"></i>
 | 
										<i class="ti ti-ban"></i>
 | 
				
			||||||
				</button>
 | 
									</button>
 | 
				
			||||||
				<button v-if="appearNote.myReaction == null" ref="reactButton" :class="$style.footerButton" class="_button" @mousedown="react()">
 | 
									<button ref="reactButton" :class="$style.footerButton" class="_button" @click="toggleReact()">
 | 
				
			||||||
					<i v-if="appearNote.reactionAcceptance === 'likeOnly'" class="ti ti-heart"></i>
 | 
										<i v-if="appearNote.reactionAcceptance === 'likeOnly' && appearNote.myReaction != null" class="ti ti-heart-filled" style="color: var(--eventReactionHeart);"></i>
 | 
				
			||||||
 | 
										<i v-else-if="appearNote.myReaction != null" class="ti ti-minus" style="color: var(--accent);"></i>
 | 
				
			||||||
 | 
										<i v-else-if="appearNote.reactionAcceptance === 'likeOnly'" class="ti ti-heart"></i>
 | 
				
			||||||
					<i v-else class="ti ti-plus"></i>
 | 
										<i v-else class="ti ti-plus"></i>
 | 
				
			||||||
				</button>
 | 
										<p v-if="appearNote.reactionCount > 0" :class="$style.footerButtonCount">{{ number(appearNote.reactionCount) }}</p>
 | 
				
			||||||
				<button v-if="appearNote.myReaction != null" ref="reactButton" :class="$style.footerButton" class="_button" @click="undoReact(appearNote)">
 | 
					 | 
				
			||||||
					<i class="ti ti-minus"></i>
 | 
					 | 
				
			||||||
				</button>
 | 
									</button>
 | 
				
			||||||
				<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" :class="$style.footerButton" class="_button" @mousedown="clip()">
 | 
									<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" :class="$style.footerButton" class="_button" @mousedown="clip()">
 | 
				
			||||||
					<i class="ti ti-paperclip"></i>
 | 
										<i class="ti ti-paperclip"></i>
 | 
				
			||||||
| 
						 | 
					@ -175,6 +175,7 @@ import { pleaseLogin } from '@/scripts/please-login.js';
 | 
				
			||||||
import { focusPrev, focusNext } from '@/scripts/focus.js';
 | 
					import { focusPrev, focusNext } from '@/scripts/focus.js';
 | 
				
			||||||
import { checkWordMute } from '@/scripts/check-word-mute.js';
 | 
					import { checkWordMute } from '@/scripts/check-word-mute.js';
 | 
				
			||||||
import { userPage } from '@/filters/user.js';
 | 
					import { userPage } from '@/filters/user.js';
 | 
				
			||||||
 | 
					import number from '@/filters/number.js';
 | 
				
			||||||
import * as os from '@/os.js';
 | 
					import * as os from '@/os.js';
 | 
				
			||||||
import * as sound from '@/scripts/sound.js';
 | 
					import * as sound from '@/scripts/sound.js';
 | 
				
			||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
 | 
					import { misskeyApi } from '@/scripts/misskey-api.js';
 | 
				
			||||||
| 
						 | 
					@ -420,6 +421,14 @@ function undoReact(targetNote: Misskey.entities.Note): void {
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function toggleReact() {
 | 
				
			||||||
 | 
						if (appearNote.value.myReaction == null) {
 | 
				
			||||||
 | 
							react();
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							undoReact(appearNote.value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function onContextmenu(ev: MouseEvent): void {
 | 
					function onContextmenu(ev: MouseEvent): void {
 | 
				
			||||||
	if (props.mock) {
 | 
						if (props.mock) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -106,10 +106,10 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
					<MkTime :time="appearNote.createdAt" mode="detail" colored/>
 | 
										<MkTime :time="appearNote.createdAt" mode="detail" colored/>
 | 
				
			||||||
				</MkA>
 | 
									</MkA>
 | 
				
			||||||
			</div>
 | 
								</div>
 | 
				
			||||||
			<MkReactionsViewer ref="reactionsViewer" :note="appearNote"/>
 | 
								<MkReactionsViewer v-if="appearNote.reactionAcceptance !== 'likeOnly'" ref="reactionsViewer" :note="appearNote"/>
 | 
				
			||||||
			<button class="_button" :class="$style.noteFooterButton" @click="reply()">
 | 
								<button class="_button" :class="$style.noteFooterButton" @click="reply()">
 | 
				
			||||||
				<i class="ti ti-arrow-back-up"></i>
 | 
									<i class="ti ti-arrow-back-up"></i>
 | 
				
			||||||
				<p v-if="appearNote.repliesCount > 0" :class="$style.noteFooterButtonCount">{{ appearNote.repliesCount }}</p>
 | 
									<p v-if="appearNote.repliesCount > 0" :class="$style.noteFooterButtonCount">{{ number(appearNote.repliesCount) }}</p>
 | 
				
			||||||
			</button>
 | 
								</button>
 | 
				
			||||||
			<button
 | 
								<button
 | 
				
			||||||
				v-if="canRenote"
 | 
									v-if="canRenote"
 | 
				
			||||||
| 
						 | 
					@ -119,17 +119,17 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
				@mousedown="renote()"
 | 
									@mousedown="renote()"
 | 
				
			||||||
			>
 | 
								>
 | 
				
			||||||
				<i class="ti ti-repeat"></i>
 | 
									<i class="ti ti-repeat"></i>
 | 
				
			||||||
				<p v-if="appearNote.renoteCount > 0" :class="$style.noteFooterButtonCount">{{ appearNote.renoteCount }}</p>
 | 
									<p v-if="appearNote.renoteCount > 0" :class="$style.noteFooterButtonCount">{{ number(appearNote.renoteCount) }}</p>
 | 
				
			||||||
			</button>
 | 
								</button>
 | 
				
			||||||
			<button v-else class="_button" :class="$style.noteFooterButton" disabled>
 | 
								<button v-else class="_button" :class="$style.noteFooterButton" disabled>
 | 
				
			||||||
				<i class="ti ti-ban"></i>
 | 
									<i class="ti ti-ban"></i>
 | 
				
			||||||
			</button>
 | 
								</button>
 | 
				
			||||||
			<button v-if="appearNote.myReaction == null" ref="reactButton" :class="$style.noteFooterButton" class="_button" @mousedown="react()">
 | 
								<button ref="reactButton" :class="$style.noteFooterButton" class="_button" @click="toggleReact()">
 | 
				
			||||||
				<i v-if="appearNote.reactionAcceptance === 'likeOnly'" class="ti ti-heart"></i>
 | 
									<i v-if="appearNote.reactionAcceptance === 'likeOnly' && appearNote.myReaction != null" class="ti ti-heart-filled" style="color: var(--eventReactionHeart);"></i>
 | 
				
			||||||
 | 
									<i v-else-if="appearNote.myReaction != null" class="ti ti-minus" style="color: var(--accent);"></i>
 | 
				
			||||||
 | 
									<i v-else-if="appearNote.reactionAcceptance === 'likeOnly'" class="ti ti-heart"></i>
 | 
				
			||||||
				<i v-else class="ti ti-plus"></i>
 | 
									<i v-else class="ti ti-plus"></i>
 | 
				
			||||||
			</button>
 | 
									<p v-if="appearNote.reactionCount > 0" :class="$style.noteFooterButtonCount">{{ number(appearNote.reactionCount) }}</p>
 | 
				
			||||||
			<button v-if="appearNote.myReaction != null" ref="reactButton" class="_button" :class="[$style.noteFooterButton, $style.reacted]" @click="undoReact(appearNote)">
 | 
					 | 
				
			||||||
				<i class="ti ti-minus"></i>
 | 
					 | 
				
			||||||
			</button>
 | 
								</button>
 | 
				
			||||||
			<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" class="_button" :class="$style.noteFooterButton" @mousedown="clip()">
 | 
								<button v-if="defaultStore.state.showClipButtonInNoteFooter" ref="clipButton" class="_button" :class="$style.noteFooterButton" @mousedown="clip()">
 | 
				
			||||||
				<i class="ti ti-paperclip"></i>
 | 
									<i class="ti ti-paperclip"></i>
 | 
				
			||||||
| 
						 | 
					@ -209,6 +209,7 @@ import { pleaseLogin } from '@/scripts/please-login.js';
 | 
				
			||||||
import { checkWordMute } from '@/scripts/check-word-mute.js';
 | 
					import { checkWordMute } from '@/scripts/check-word-mute.js';
 | 
				
			||||||
import { userPage } from '@/filters/user.js';
 | 
					import { userPage } from '@/filters/user.js';
 | 
				
			||||||
import { notePage } from '@/filters/note.js';
 | 
					import { notePage } from '@/filters/note.js';
 | 
				
			||||||
 | 
					import number from '@/filters/number.js';
 | 
				
			||||||
import * as os from '@/os.js';
 | 
					import * as os from '@/os.js';
 | 
				
			||||||
import { misskeyApi } from '@/scripts/misskey-api.js';
 | 
					import { misskeyApi } from '@/scripts/misskey-api.js';
 | 
				
			||||||
import * as sound from '@/scripts/sound.js';
 | 
					import * as sound from '@/scripts/sound.js';
 | 
				
			||||||
| 
						 | 
					@ -401,14 +402,22 @@ function react(viaKeyboard = false): void {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function undoReact(note): void {
 | 
					function undoReact(targetNote: Misskey.entities.Note): void {
 | 
				
			||||||
	const oldReaction = note.myReaction;
 | 
						const oldReaction = targetNote.myReaction;
 | 
				
			||||||
	if (!oldReaction) return;
 | 
						if (!oldReaction) return;
 | 
				
			||||||
	misskeyApi('notes/reactions/delete', {
 | 
						misskeyApi('notes/reactions/delete', {
 | 
				
			||||||
		noteId: note.id,
 | 
							noteId: targetNote.id,
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function toggleReact() {
 | 
				
			||||||
 | 
						if (appearNote.value.myReaction == null) {
 | 
				
			||||||
 | 
							react();
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							undoReact(appearNote.value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function onContextmenu(ev: MouseEvent): void {
 | 
					function onContextmenu(ev: MouseEvent): void {
 | 
				
			||||||
	const isLink = (el: HTMLElement): boolean => {
 | 
						const isLink = (el: HTMLElement): boolean => {
 | 
				
			||||||
		if (el.tagName === 'A') return true;
 | 
							if (el.tagName === 'A') return true;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
	<div :class="$style.head">
 | 
						<div :class="$style.head">
 | 
				
			||||||
		<MkAvatar v-if="['pollEnded', 'note'].includes(notification.type) && notification.note" :class="$style.icon" :user="notification.note.user" link preview/>
 | 
							<MkAvatar v-if="['pollEnded', 'note'].includes(notification.type) && notification.note" :class="$style.icon" :user="notification.note.user" link preview/>
 | 
				
			||||||
		<MkAvatar v-else-if="['roleAssigned', 'achievementEarned'].includes(notification.type)" :class="$style.icon" :user="$i" link preview/>
 | 
							<MkAvatar v-else-if="['roleAssigned', 'achievementEarned'].includes(notification.type)" :class="$style.icon" :user="$i" link preview/>
 | 
				
			||||||
 | 
							<div v-else-if="notification.type === 'reaction:grouped' && notification.note.reactionAcceptance === 'likeOnly'" :class="[$style.icon, $style.icon_reactionGroupHeart]"><i class="ti ti-heart" style="line-height: 1;"></i></div>
 | 
				
			||||||
		<div v-else-if="notification.type === 'reaction:grouped'" :class="[$style.icon, $style.icon_reactionGroup]"><i class="ti ti-plus" style="line-height: 1;"></i></div>
 | 
							<div v-else-if="notification.type === 'reaction:grouped'" :class="[$style.icon, $style.icon_reactionGroup]"><i class="ti ti-plus" style="line-height: 1;"></i></div>
 | 
				
			||||||
		<div v-else-if="notification.type === 'renote:grouped'" :class="[$style.icon, $style.icon_renoteGroup]"><i class="ti ti-repeat" style="line-height: 1;"></i></div>
 | 
							<div v-else-if="notification.type === 'renote:grouped'" :class="[$style.icon, $style.icon_renoteGroup]"><i class="ti ti-repeat" style="line-height: 1;"></i></div>
 | 
				
			||||||
		<img v-else-if="notification.type === 'test'" :class="$style.icon" :src="infoImageUrl"/>
 | 
							<img v-else-if="notification.type === 'test'" :class="$style.icon" :src="infoImageUrl"/>
 | 
				
			||||||
| 
						 | 
					@ -57,6 +58,7 @@ SPDX-License-Identifier: AGPL-3.0-only
 | 
				
			||||||
			<span v-else-if="notification.type === 'achievementEarned'">{{ i18n.ts._notification.achievementEarned }}</span>
 | 
								<span v-else-if="notification.type === 'achievementEarned'">{{ i18n.ts._notification.achievementEarned }}</span>
 | 
				
			||||||
			<span v-else-if="notification.type === 'test'">{{ i18n.ts._notification.testNotification }}</span>
 | 
								<span v-else-if="notification.type === 'test'">{{ i18n.ts._notification.testNotification }}</span>
 | 
				
			||||||
			<MkA v-else-if="notification.type === 'follow' || notification.type === 'mention' || notification.type === 'reply' || notification.type === 'renote' || notification.type === 'quote' || notification.type === 'reaction' || notification.type === 'receiveFollowRequest' || notification.type === 'followRequestAccepted'" v-user-preview="notification.user.id" :class="$style.headerName" :to="userPage(notification.user)"><MkUserName :user="notification.user"/></MkA>
 | 
								<MkA v-else-if="notification.type === 'follow' || notification.type === 'mention' || notification.type === 'reply' || notification.type === 'renote' || notification.type === 'quote' || notification.type === 'reaction' || notification.type === 'receiveFollowRequest' || notification.type === 'followRequestAccepted'" v-user-preview="notification.user.id" :class="$style.headerName" :to="userPage(notification.user)"><MkUserName :user="notification.user"/></MkA>
 | 
				
			||||||
 | 
								<span v-else-if="notification.type === 'reaction:grouped' && notification.note.reactionAcceptance === 'likeOnly'">{{ i18n.tsx._notification.likedBySomeUsers({ n: notification.reactions.length }) }}</span>
 | 
				
			||||||
			<span v-else-if="notification.type === 'reaction:grouped'">{{ i18n.tsx._notification.reactedBySomeUsers({ n: notification.reactions.length }) }}</span>
 | 
								<span v-else-if="notification.type === 'reaction:grouped'">{{ i18n.tsx._notification.reactedBySomeUsers({ n: notification.reactions.length }) }}</span>
 | 
				
			||||||
			<span v-else-if="notification.type === 'renote:grouped'">{{ i18n.tsx._notification.renotedBySomeUsers({ n: notification.users.length }) }}</span>
 | 
								<span v-else-if="notification.type === 'renote:grouped'">{{ i18n.tsx._notification.renotedBySomeUsers({ n: notification.users.length }) }}</span>
 | 
				
			||||||
			<span v-else-if="notification.type === 'app'">{{ notification.header }}</span>
 | 
								<span v-else-if="notification.type === 'app'">{{ notification.header }}</span>
 | 
				
			||||||
| 
						 | 
					@ -201,6 +203,7 @@ const rejectFollowRequest = () => {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.icon_reactionGroup,
 | 
					.icon_reactionGroup,
 | 
				
			||||||
 | 
					.icon_reactionGroupHeart,
 | 
				
			||||||
.icon_renoteGroup {
 | 
					.icon_renoteGroup {
 | 
				
			||||||
	display: grid;
 | 
						display: grid;
 | 
				
			||||||
	align-items: center;
 | 
						align-items: center;
 | 
				
			||||||
| 
						 | 
					@ -213,11 +216,15 @@ const rejectFollowRequest = () => {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.icon_reactionGroup {
 | 
					.icon_reactionGroup {
 | 
				
			||||||
	background: #e99a0b;
 | 
						background: var(--eventReaction);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.icon_reactionGroupHeart {
 | 
				
			||||||
 | 
						background: var(--eventReactionHeart);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.icon_renoteGroup {
 | 
					.icon_renoteGroup {
 | 
				
			||||||
	background: #36d298;
 | 
						background: var(--eventRenote);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.icon_app {
 | 
					.icon_app {
 | 
				
			||||||
| 
						 | 
					@ -246,49 +253,49 @@ const rejectFollowRequest = () => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.t_follow, .t_followRequestAccepted, .t_receiveFollowRequest {
 | 
					.t_follow, .t_followRequestAccepted, .t_receiveFollowRequest {
 | 
				
			||||||
	padding: 3px;
 | 
						padding: 3px;
 | 
				
			||||||
	background: #36aed2;
 | 
						background: var(--eventFollow);
 | 
				
			||||||
	pointer-events: none;
 | 
						pointer-events: none;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.t_renote {
 | 
					.t_renote {
 | 
				
			||||||
	padding: 3px;
 | 
						padding: 3px;
 | 
				
			||||||
	background: #36d298;
 | 
						background: var(--eventRenote);
 | 
				
			||||||
	pointer-events: none;
 | 
						pointer-events: none;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.t_quote {
 | 
					.t_quote {
 | 
				
			||||||
	padding: 3px;
 | 
						padding: 3px;
 | 
				
			||||||
	background: #36d298;
 | 
						background: var(--eventRenote);
 | 
				
			||||||
	pointer-events: none;
 | 
						pointer-events: none;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.t_reply {
 | 
					.t_reply {
 | 
				
			||||||
	padding: 3px;
 | 
						padding: 3px;
 | 
				
			||||||
	background: #007aff;
 | 
						background: var(--eventReply);
 | 
				
			||||||
	pointer-events: none;
 | 
						pointer-events: none;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.t_mention {
 | 
					.t_mention {
 | 
				
			||||||
	padding: 3px;
 | 
						padding: 3px;
 | 
				
			||||||
	background: #88a6b7;
 | 
						background: var(--eventOther);
 | 
				
			||||||
	pointer-events: none;
 | 
						pointer-events: none;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.t_pollEnded {
 | 
					.t_pollEnded {
 | 
				
			||||||
	padding: 3px;
 | 
						padding: 3px;
 | 
				
			||||||
	background: #88a6b7;
 | 
						background: var(--eventOther);
 | 
				
			||||||
	pointer-events: none;
 | 
						pointer-events: none;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.t_achievementEarned {
 | 
					.t_achievementEarned {
 | 
				
			||||||
	padding: 3px;
 | 
						padding: 3px;
 | 
				
			||||||
	background: #cb9a11;
 | 
						background: var(--eventAchievement);
 | 
				
			||||||
	pointer-events: none;
 | 
						pointer-events: none;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.t_roleAssigned {
 | 
					.t_roleAssigned {
 | 
				
			||||||
	padding: 3px;
 | 
						padding: 3px;
 | 
				
			||||||
	background: #88a6b7;
 | 
						background: var(--eventOther);
 | 
				
			||||||
	pointer-events: none;
 | 
						pointer-events: none;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,6 +63,7 @@ const exampleNote = reactive<Misskey.entities.Note>({
 | 
				
			||||||
	reactionAcceptance: null,
 | 
						reactionAcceptance: null,
 | 
				
			||||||
	renoteCount: 0,
 | 
						renoteCount: 0,
 | 
				
			||||||
	repliesCount: 1,
 | 
						repliesCount: 1,
 | 
				
			||||||
 | 
						reactionCount: 0,
 | 
				
			||||||
	reactions: {},
 | 
						reactions: {},
 | 
				
			||||||
	reactionEmojis: {},
 | 
						reactionEmojis: {},
 | 
				
			||||||
	fileIds: [],
 | 
						fileIds: [],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -68,6 +68,7 @@ const exampleCWNote = reactive<Misskey.entities.Note>({
 | 
				
			||||||
	reactionAcceptance: null,
 | 
						reactionAcceptance: null,
 | 
				
			||||||
	renoteCount: 0,
 | 
						renoteCount: 0,
 | 
				
			||||||
	repliesCount: 1,
 | 
						repliesCount: 1,
 | 
				
			||||||
 | 
						reactionCount: 0,
 | 
				
			||||||
	reactions: {},
 | 
						reactions: {},
 | 
				
			||||||
	reactionEmojis: {},
 | 
						reactionEmojis: {},
 | 
				
			||||||
	fileIds: [],
 | 
						fileIds: [],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,6 +58,7 @@ const exampleNote = reactive<Misskey.entities.Note>({
 | 
				
			||||||
	reactionAcceptance: null,
 | 
						reactionAcceptance: null,
 | 
				
			||||||
	renoteCount: 0,
 | 
						renoteCount: 0,
 | 
				
			||||||
	repliesCount: 1,
 | 
						repliesCount: 1,
 | 
				
			||||||
 | 
						reactionCount: 0,
 | 
				
			||||||
	reactions: {},
 | 
						reactions: {},
 | 
				
			||||||
	reactionEmojis: {},
 | 
						reactionEmojis: {},
 | 
				
			||||||
	fileIds: ['0000000002'],
 | 
						fileIds: ['0000000002'],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,6 +35,7 @@ export function useNoteCapture(props: {
 | 
				
			||||||
				const currentCount = (note.value.reactions || {})[reaction] || 0;
 | 
									const currentCount = (note.value.reactions || {})[reaction] || 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				note.value.reactions[reaction] = currentCount + 1;
 | 
									note.value.reactions[reaction] = currentCount + 1;
 | 
				
			||||||
 | 
									note.value.reactionCount += 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if ($i && (body.userId === $i.id)) {
 | 
									if ($i && (body.userId === $i.id)) {
 | 
				
			||||||
					note.value.myReaction = reaction;
 | 
										note.value.myReaction = reaction;
 | 
				
			||||||
| 
						 | 
					@ -49,6 +50,7 @@ export function useNoteCapture(props: {
 | 
				
			||||||
				const currentCount = (note.value.reactions || {})[reaction] || 0;
 | 
									const currentCount = (note.value.reactions || {})[reaction] || 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				note.value.reactions[reaction] = Math.max(0, currentCount - 1);
 | 
									note.value.reactions[reaction] = Math.max(0, currentCount - 1);
 | 
				
			||||||
 | 
									note.value.reactionCount = Math.max(0, note.value.reactionCount - 1);
 | 
				
			||||||
				if (note.value.reactions[reaction] === 0) delete note.value.reactions[reaction];
 | 
									if (note.value.reactions[reaction] === 0) delete note.value.reactions[reaction];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if ($i && (body.userId === $i.id)) {
 | 
									if ($i && (body.userId === $i.id)) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,6 +22,13 @@
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//--ad: rgb(255 169 0 / 10%);
 | 
						//--ad: rgb(255 169 0 / 10%);
 | 
				
			||||||
 | 
						--eventFollow: #36aed2;
 | 
				
			||||||
 | 
						--eventRenote: #36d298;
 | 
				
			||||||
 | 
						--eventReply: #007aff;
 | 
				
			||||||
 | 
						--eventReactionHeart: #dd2e44;
 | 
				
			||||||
 | 
						--eventReaction: #e99a0b;
 | 
				
			||||||
 | 
						--eventAchievement: #cb9a11;
 | 
				
			||||||
 | 
						--eventOther: #88a6b7;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
::selection {
 | 
					::selection {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -3987,6 +3987,7 @@ export type components = {
 | 
				
			||||||
      reactions: {
 | 
					      reactions: {
 | 
				
			||||||
        [key: string]: number;
 | 
					        [key: string]: number;
 | 
				
			||||||
      };
 | 
					      };
 | 
				
			||||||
 | 
					      reactionCount: number;
 | 
				
			||||||
      renoteCount: number;
 | 
					      renoteCount: number;
 | 
				
			||||||
      repliesCount: number;
 | 
					      repliesCount: number;
 | 
				
			||||||
      uri?: string;
 | 
					      uri?: string;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue