From 60342ed3fa40e52015a76c597c29fb4146137a03 Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sun, 26 Feb 2023 11:57:37 +0900
Subject: [PATCH] enhance(client): improve user menu ux

---
 .../frontend/src/scripts/get-user-menu.ts     | 74 ++++++++-----------
 1 file changed, 32 insertions(+), 42 deletions(-)

diff --git a/packages/frontend/src/scripts/get-user-menu.ts b/packages/frontend/src/scripts/get-user-menu.ts
index 69d0ed085d..6c6baf8266 100644
--- a/packages/frontend/src/scripts/get-user-menu.ts
+++ b/packages/frontend/src/scripts/get-user-menu.ts
@@ -12,29 +12,6 @@ import { Router } from '@/nirax';
 export function getUserMenu(user: misskey.entities.UserDetailed, router: Router = mainRouter) {
 	const meId = $i ? $i.id : null;
 
-	async function pushList() {
-		const t = i18n.ts.selectList; // なぜか後で参照すると null になるので最初にメモリに確保しておく
-		const lists = await os.api('users/lists/list');
-		if (lists.length === 0) {
-			os.alert({
-				type: 'error',
-				text: i18n.ts.youHaveNoLists,
-			});
-			return;
-		}
-		const { canceled, result: listId } = await os.select({
-			title: t,
-			items: lists.map(list => ({
-				value: list.id, text: list.name,
-			})),
-		});
-		if (canceled) return;
-		os.apiWithDialog('users/lists/push', {
-			listId: listId,
-			userId: user.id,
-		});
-	}
-
 	async function toggleMute() {
 		if (user.isMuted) {
 			os.apiWithDialog('mute/delete', {
@@ -137,12 +114,43 @@ export function getUserMenu(user: misskey.entities.UserDetailed, router: Router
 			os.post({ specified: user });
 		},
 	}, null, {
+		type: 'parent',
 		icon: 'ti ti-list',
 		text: i18n.ts.addToList,
-		action: pushList,
+		children: async () => {
+			const lists = await os.api('users/lists/list');
+
+			return lists.map(list => ({
+				text: list.name,
+				action: () => {
+					os.apiWithDialog('users/lists/push', {
+						listId: list.id,
+						userId: user.id,
+					});
+				},
+			}));
+		},
 	}] as any;
 
 	if ($i && meId !== user.id) {
+		if (iAmModerator) {
+			menu = menu.concat([{
+				type: 'parent',
+				icon: 'ti ti-badges',
+				text: i18n.ts.roles,
+				children: async () => {
+					const roles = await os.api('admin/roles/list');
+
+					return roles.filter(r => r.target === 'manual').map(r => ({
+						text: r.name,
+						action: () => {
+							os.apiWithDialog('admin/roles/assign', { roleId: r.id, userId: user.id });
+						},
+					}));
+				},
+			}]);
+		}
+
 		menu = menu.concat([null, {
 			icon: user.isMuted ? 'ti ti-eye' : 'ti ti-eye-off',
 			text: user.isMuted ? i18n.ts.unmute : i18n.ts.mute,
@@ -166,24 +174,6 @@ export function getUserMenu(user: misskey.entities.UserDetailed, router: Router
 			text: i18n.ts.reportAbuse,
 			action: reportAbuse,
 		}]);
-
-		if (iAmModerator) {
-			menu = menu.concat([null, {
-				icon: 'ti ti-badges',
-				text: i18n.ts.roles,
-				action: async () => {
-					const roles = await os.api('admin/roles/list');
-
-					const { canceled, result: roleId } = await os.select({
-						title: i18n.ts._role.chooseRoleToAssign,
-						items: roles.map(r => ({ text: r.name, value: r.id })),
-					});
-					if (canceled) return;
-
-					await os.apiWithDialog('admin/roles/assign', { roleId, userId: user.id });
-				},
-			}]);
-		}
 	}
 
 	if ($i && meId === user.id) {