From 3d88a91f618ff8bc27d053fd1292cef617d04c5d Mon Sep 17 00:00:00 2001
From: tamaina <tamaina@hotmail.co.jp>
Date: Sat, 22 Apr 2023 05:16:23 +0000
Subject: [PATCH] =?UTF-8?q?movedTo(Uri),=20alsoKnownAs=E3=81=AF=E3=83=A6?=
 =?UTF-8?q?=E3=83=BC=E3=82=B6=E3=83=BCid=E3=82=92=E8=BF=94=E3=81=99?=
 =?UTF-8?q?=E3=82=88=E3=81=86=E3=81=AB?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../src/core/entities/UserEntityService.ts    |  7 +++--
 .../backend/src/models/json-schema/user.ts    |  5 ++-
 .../src/components/MkAccountMoved.vue         | 14 ++++++---
 .../frontend/src/pages/settings/migration.vue | 31 ++++++++++++++++---
 packages/frontend/src/pages/user/home.vue     |  2 +-
 packages/misskey-js/etc/misskey-js.api.md     |  4 +--
 packages/misskey-js/src/entities.ts           |  4 +--
 7 files changed, 51 insertions(+), 16 deletions(-)

diff --git a/packages/backend/src/core/entities/UserEntityService.ts b/packages/backend/src/core/entities/UserEntityService.ts
index 6678f9a8a9..7c0f607901 100644
--- a/packages/backend/src/core/entities/UserEntityService.ts
+++ b/packages/backend/src/core/entities/UserEntityService.ts
@@ -369,8 +369,11 @@ export class UserEntityService implements OnModuleInit {
 			...(opts.detail ? {
 				url: profile!.url,
 				uri: user.uri,
-				movedToUri: user.movedToUri ? this.apPersonService.resolvePerson(user.movedToUri).then(user => user.uri).catch(() => null) : null,
-				alsoKnownAs: user.alsoKnownAs,
+				movedTo: user.movedToUri ? this.apPersonService.resolvePerson(user.movedToUri).then(user => user.id).catch(() => null) : null,
+				alsoKnownAs: user.alsoKnownAs
+					? Promise.all(user.alsoKnownAs.map(uri => this.apPersonService.fetchPerson(uri).then(user => user?.id).catch(() => null)))
+						.then(xs => xs.length === 0 ? null : xs.filter(x => x != null) as string[])
+					: null,
 				createdAt: user.createdAt.toISOString(),
 				updatedAt: user.updatedAt ? user.updatedAt.toISOString() : null,
 				lastFetchedAt: user.lastFetchedAt ? user.lastFetchedAt.toISOString() : null,
diff --git a/packages/backend/src/models/json-schema/user.ts b/packages/backend/src/models/json-schema/user.ts
index 836368886e..9183f863a5 100644
--- a/packages/backend/src/models/json-schema/user.ts
+++ b/packages/backend/src/models/json-schema/user.ts
@@ -80,9 +80,12 @@ export const packedUserDetailedNotMeOnlySchema = {
 		},
 		alsoKnownAs: {
 			type: 'array',
-			format: 'uri',
 			nullable: true,
 			optional: false,
+			items: {
+				type: 'string',
+				format: 'id',
+			},
 		},
 		createdAt: {
 			type: 'string',
diff --git a/packages/frontend/src/components/MkAccountMoved.vue b/packages/frontend/src/components/MkAccountMoved.vue
index 98979de236..b1dea9176b 100644
--- a/packages/frontend/src/components/MkAccountMoved.vue
+++ b/packages/frontend/src/components/MkAccountMoved.vue
@@ -1,5 +1,5 @@
 <template>
-<div :class="$style.root">
+<div v-show="user" :class="$style.root">
 	<i class="ti ti-plane-departure" style="margin-right: 8px;"></i>
 	{{ i18n.ts.accountMoved }}
 	<MkMention :class="$style.link" :username="username" :host="host ?? localHost"/>
@@ -10,11 +10,17 @@
 import MkMention from './MkMention.vue';
 import { i18n } from '@/i18n';
 import { host as localHost } from '@/config';
+import { ref } from 'vue';
+import { UserLite } from 'misskey-js/built/entities';
+import { api } from '@/os';
 
-defineProps<{
-	username: string;
-	host: string;
+const user = ref<UserLite>();
+
+const props = defineProps<{
+	movedTo: string; // user id
 }>();
+
+api('users/show', { userId: props.movedTo }).then(u => user.value = u);
 </script>
 
 <style lang="scss" module>
diff --git a/packages/frontend/src/pages/settings/migration.vue b/packages/frontend/src/pages/settings/migration.vue
index 78a5f5a95d..598b221822 100644
--- a/packages/frontend/src/pages/settings/migration.vue
+++ b/packages/frontend/src/pages/settings/migration.vue
@@ -51,20 +51,40 @@ import MkFolder from '@/components/MkFolder.vue';
 import * as os from '@/os';
 import { i18n } from '@/i18n';
 import { definePageMetadata } from '@/scripts/page-metadata';
+import { $i } from '@/account';
+import { toString } from 'misskey-js/built/acct';
+import { unisonReload } from '@/scripts/unison-reload';
 
 const moveToAccount = ref('');
 const accountAliases = ref(['']);
 
+async function init() {
+	if ($i?.movedTo) {
+		const movedTo = await os.api('users/show', { userId: $i.movedTo });
+		moveToAccount.value = movedTo ? toString(movedTo) : '';
+	} else {
+		moveToAccount.value = '';
+	}
+
+	if ($i?.alsoKnownAs && $i.alsoKnownAs.length > 0) {
+		const alsoKnownAs = await os.api('users/show', { userIds: $i.alsoKnownAs });
+		accountAliases.value = (alsoKnownAs && alsoKnownAs.length > 0) ? alsoKnownAs.map(user => `@${toString(user)}`) : [''];
+	} else {
+		accountAliases.value = [''];
+	}
+}
+
 async function move(): Promise<void> {
 	const account = moveToAccount.value;
 	const confirm = await os.confirm({
 		type: 'warning',
-		text: i18n.t('_accountMigration.migrationConfirm', { account: account.toString() }),
+		text: i18n.t('_accountMigration.migrationConfirm', { account }),
 	});
 	if (confirm.canceled) return;
-	os.apiWithDialog('i/move', {
+	await os.apiWithDialog('i/move', {
 		moveToAccount: account,
 	});
+	unisonReload();
 }
 
 function add(): void {
@@ -73,12 +93,15 @@ function add(): void {
 
 async function save(): Promise<void> {
 	const alsoKnownAs = accountAliases.value.map(alias => alias.trim()).filter(alias => alias !== '');
-	os.apiWithDialog('i/update', {
+	const i = await os.apiWithDialog('i/update', {
 		alsoKnownAs,
 	});
-	accountAliases.value = alsoKnownAs.length === 0 ? [''] : alsoKnownAs;
+	$i.alsoKnownAs = i.alsoKnownAs;
+	init();
 }
 
+init();
+
 definePageMetadata({
 	title: i18n.ts.accountMigration,
 	icon: 'ti ti-plane',
diff --git a/packages/frontend/src/pages/user/home.vue b/packages/frontend/src/pages/user/home.vue
index 0f9145e974..57063c92de 100644
--- a/packages/frontend/src/pages/user/home.vue
+++ b/packages/frontend/src/pages/user/home.vue
@@ -7,7 +7,7 @@
 			<!-- <div class="punished" v-if="user.isSilenced"><i class="ti ti-alert-triangle" style="margin-right: 8px;"></i> {{ i18n.ts.userSilenced }}</div> -->
 
 			<div class="profile _gaps">
-				<MkAccountMoved v-if="user.movedToUri" :host="user.movedToUri.host" :username="user.movedToUri.username"/>
+				<MkAccountMoved v-if="user.movedTo" :movedTo="user.movedTo" />
 				<MkRemoteCaution v-if="user.host != null" :href="user.url ?? user.uri!" class="warn"/>
 
 				<div :key="user.id" class="main _panel">
diff --git a/packages/misskey-js/etc/misskey-js.api.md b/packages/misskey-js/etc/misskey-js.api.md
index 54424cd6ec..19e5b75443 100644
--- a/packages/misskey-js/etc/misskey-js.api.md
+++ b/packages/misskey-js/etc/misskey-js.api.md
@@ -2631,6 +2631,7 @@ type User = UserLite | UserDetailed;
 
 // @public (undocumented)
 type UserDetailed = UserLite & {
+    alsoKnownAs: string[];
     bannerBlurhash: string | null;
     bannerColor: string | null;
     bannerUrl: string | null;
@@ -2661,7 +2662,7 @@ type UserDetailed = UserLite & {
     lang: string | null;
     lastFetchedAt?: DateString;
     location: string | null;
-    movedToUri: string;
+    movedTo: string;
     notesCount: number;
     pinnedNoteIds: ID[];
     pinnedNotes: Note[];
@@ -2695,7 +2696,6 @@ type UserLite = {
     onlineStatus: 'online' | 'active' | 'offline' | 'unknown';
     avatarUrl: string;
     avatarBlurhash: string;
-    alsoKnownAs: string[];
     emojis: {
         name: string;
         url: string;
diff --git a/packages/misskey-js/src/entities.ts b/packages/misskey-js/src/entities.ts
index 9efc062eac..04065c51c9 100644
--- a/packages/misskey-js/src/entities.ts
+++ b/packages/misskey-js/src/entities.ts
@@ -14,7 +14,6 @@ export type UserLite = {
 	onlineStatus: 'online' | 'active' | 'offline' | 'unknown';
 	avatarUrl: string;
 	avatarBlurhash: string;
-	alsoKnownAs: string[];
 	emojis: {
 		name: string;
 		url: string;
@@ -30,6 +29,7 @@ export type UserLite = {
 };
 
 export type UserDetailed = UserLite & {
+	alsoKnownAs: string[];
 	bannerBlurhash: string | null;
 	bannerColor: string | null;
 	bannerUrl: string | null;
@@ -57,7 +57,7 @@ export type UserDetailed = UserLite & {
 	lang: string | null;
 	lastFetchedAt?: DateString;
 	location: string | null;
-	movedToUri: string;
+	movedTo: string;
 	notesCount: number;
 	pinnedNoteIds: ID[];
 	pinnedNotes: Note[];