From 8fbca63cecfbb6e939360c01f07f5907de437a0f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E3=81=8B=E3=81=A3=E3=81=93=E3=81=8B=E3=82=8A?=
 <67428053+kakkokari-gtyih@users.noreply.github.com>
Date: Sat, 29 Apr 2023 15:48:06 +0900
Subject: [PATCH] =?UTF-8?q?feat(client):=20Renote=E3=81=97=E3=81=9F?=
 =?UTF-8?q?=E4=BA=BA=E3=81=AE=E4=B8=80=E8=A6=A7=E3=82=92=E8=A1=A8=E7=A4=BA?=
 =?UTF-8?q?=E3=81=99=E3=82=8B=E3=83=80=E3=82=A4=E3=82=A2=E3=83=AD=E3=82=B0?=
 =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0=20(#10647)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* (add) renote user dialog

* (change) noteMenu order

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>

* (change) menu text

* Update CHANGELOG.md

* (change) dialog title text

* (fix) grammar mistakes in CHANGELOG.md

* (change) i18n keys

---------

Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
---
 CHANGELOG.md                                  |  1 +
 locales/ja-JP.yml                             |  2 +
 .../src/components/MkReactedUsersDialog.vue   |  4 +-
 .../src/components/MkRenotedUsersDialog.vue   | 65 +++++++++++++++++++
 .../frontend/src/scripts/get-note-menu.ts     | 14 +++-
 5 files changed, 82 insertions(+), 4 deletions(-)
 create mode 100644 packages/frontend/src/components/MkRenotedUsersDialog.vue

diff --git a/CHANGELOG.md b/CHANGELOG.md
index ed2c3158f..210b1ed5f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -36,6 +36,7 @@
 - 1枚だけのメディアリストの画像のアスペクト比を画像に応じて縦長にするように
 - Fix: リアクションをホバーした時のユーザーリストで猫耳が切れてしまっていた問題を修正
 - 新しい実績を追加
+- Renoteしたユーザーの一覧を見れるように
 
 ### Server
 - 環境変数MISSKEY_CONFIG_YMLで設定ファイルをdefault.ymlから変更可能に
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 24a4b9fbb..1e2019b8f 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -1007,6 +1007,8 @@ accountMoved: "このユーザーは新しいアカウントに引っ越しま
 forceShowAds: "常に広告を表示する"
 addMemo: "メモを追加"
 editMemo: "メモを編集"
+reactionsList: "リアクション一覧"
+renotesList: "Renote一覧"
 notificationDisplay: "通知の表示"
 leftTop: "左上"
 rightTop: "右上"
diff --git a/packages/frontend/src/components/MkReactedUsersDialog.vue b/packages/frontend/src/components/MkReactedUsersDialog.vue
index 1506e24ce..0c0cc3669 100644
--- a/packages/frontend/src/components/MkReactedUsersDialog.vue
+++ b/packages/frontend/src/components/MkReactedUsersDialog.vue
@@ -6,7 +6,7 @@
 	@close="dialog.close()"
 	@closed="emit('closed')"
 >
-	<template #header>{{ i18n.ts.reactions }}</template>
+	<template #header>{{ i18n.ts.reactionsList }}</template>
 
 	<MkSpacer :margin-min="20" :margin-max="28">
 		<div v-if="note" class="_gaps">
@@ -21,7 +21,7 @@
 						<span style="margin-left: 4px;">{{ note.reactions[reaction] }}</span>
 					</button>
 				</div>
-				<MkA v-for="user in users" :key="user.id" :to="userPage(user)">
+				<MkA v-for="user in users" :key="user.id" :to="userPage(user)" @click="dialog.close()">
 					<MkUserCardMini :user="user" :with-chart="false"/>
 				</MkA>
 			</template>
diff --git a/packages/frontend/src/components/MkRenotedUsersDialog.vue b/packages/frontend/src/components/MkRenotedUsersDialog.vue
new file mode 100644
index 000000000..56025535f
--- /dev/null
+++ b/packages/frontend/src/components/MkRenotedUsersDialog.vue
@@ -0,0 +1,65 @@
+<template>
+<MkModalWindow
+	ref="dialog"
+	:width="400"
+	:height="450"
+	@close="dialog.close()"
+	@closed="emit('closed')"
+>
+	<template #header>{{ i18n.ts.renotesList }}</template>
+
+	<MkSpacer :margin-min="20" :margin-max="28">
+		<div v-if="renotes" class="_gaps">
+			<div v-if="renotes.length === 0" class="_fullinfo">
+				<img src="https://xn--931a.moe/assets/info.jpg" class="_ghost"/>
+				<div>{{ i18n.ts.nothing }}</div>
+			</div>
+			<template v-else>
+				<MkA v-for="user in users" :key="user.id" :to="userPage(user)" @click="dialog.close()">
+					<MkUserCardMini :user="user" :with-chart="false"/>
+				</MkA>
+			</template>
+		</div>
+		<div v-else>
+			<MkLoading/>
+		</div>
+	</MkSpacer>
+</MkModalWindow>
+</template>
+
+<script lang="ts" setup>
+import { onMounted } from 'vue';
+import * as misskey from 'misskey-js';
+import MkModalWindow from '@/components/MkModalWindow.vue';
+import MkUserCardMini from '@/components/MkUserCardMini.vue';
+import { userPage } from '@/filters/user';
+import { i18n } from '@/i18n';
+import * as os from '@/os';
+
+const emit = defineEmits<{
+	(ev: 'closed'): void,
+}>();
+
+const props = defineProps<{
+	noteId: misskey.entities.Note['id'];
+}>();
+
+const dialog = $shallowRef<InstanceType<typeof MkModalWindow>>();
+
+let note = $ref<misskey.entities.Note>();
+let renotes = $ref();
+let users = $ref();
+
+onMounted(async () => {
+	const res = await os.api('notes/renotes', {
+		noteId: props.noteId,
+		limit: 30,
+	});
+
+	renotes = res;
+	users = res.map(x => x.user);
+});
+</script>
+
+<style lang="scss" module>
+</style>
diff --git a/packages/frontend/src/scripts/get-note-menu.ts b/packages/frontend/src/scripts/get-note-menu.ts
index d91f0b0eb..c8a610025 100644
--- a/packages/frontend/src/scripts/get-note-menu.ts
+++ b/packages/frontend/src/scripts/get-note-menu.ts
@@ -211,6 +211,12 @@ export function getNoteMenu(props: {
 		}, {}, 'closed');
 	}
 
+	function showRenotes(): void {
+		os.popup(defineAsyncComponent(() => import('@/components/MkRenotedUsersDialog.vue')), {
+			noteId: appearNote.id,
+		}, {}, 'closed');
+	}
+
 	async function translate(): Promise<void> {
 		if (props.translation.value != null) return;
 		props.translating.value = true;
@@ -241,8 +247,12 @@ export function getNoteMenu(props: {
 				text: i18n.ts.details,
 				action: openDetail,
 			}, {
-				icon: 'ti ti-users',
-				text: i18n.ts.reactions,
+				icon: 'ti ti-repeat',
+				text: i18n.ts.renotesList,
+				action: showRenotes,
+			}, {
+				icon: 'ti ti-icons',
+				text: i18n.ts.reactionsList,
 				action: showReactions,
 			}, {
 				icon: 'ti ti-copy',