From 2e4ccd8d133a5b18256e4c612123e4c3192426a9 Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Mon, 21 Sep 2020 10:31:00 +0900
Subject: [PATCH] wip

---
 src/client/components/autocomplete.vue        |  3 +-
 src/client/components/page/page.vue           |  2 +-
 src/client/components/poll-editor.vue         |  2 +-
 src/client/components/post-form.vue           |  5 ++-
 src/client/components/sidebar.vue             |  6 ++--
 src/client/components/signin.vue              |  2 +-
 src/client/components/signup.vue              |  6 ++--
 src/client/components/user-select.vue         | 15 ++++----
 src/client/os.ts                              | 36 ++++++++++++-------
 src/client/pages/instance/settings.vue        |  7 ++--
 src/client/pages/instance/users.vue           |  7 ++--
 src/client/pages/messaging/index.vue          |  3 +-
 .../pages/my-antennas/index.antenna.vue       |  3 +-
 src/client/pages/my-groups/group.vue          |  5 ++-
 src/client/pages/my-lists/list.vue            |  3 +-
 .../pages/page-editor/page-editor.blocks.vue  |  2 +-
 src/client/pages/page-editor/page-editor.vue  |  2 +-
 src/client/pages/room/room.vue                |  2 +-
 src/client/pages/test.vue                     | 32 ++++++++++++++++-
 src/client/pages/theme-editor.vue             |  2 +-
 src/client/pages/user/index.vue               |  7 ++--
 21 files changed, 92 insertions(+), 60 deletions(-)

diff --git a/src/client/components/autocomplete.vue b/src/client/components/autocomplete.vue
index fce6500d29..e8915a9b41 100644
--- a/src/client/components/autocomplete.vue
+++ b/src/client/components/autocomplete.vue
@@ -33,7 +33,6 @@ import { emojilist } from '../../misc/emojilist';
 import contains from '@/scripts/contains';
 import { twemojiSvgBase } from '../../misc/twemoji-base';
 import { getStaticImageUrl } from '@/scripts/get-static-image-url';
-import MkUserSelect from '@/components/user-select.vue';
 import { acct } from '@/filters/user';
 import * as os from '@/os';
 
@@ -378,7 +377,7 @@ export default defineComponent({
 
 		chooseUser() {
 			this.close();
-			os.modal(MkUserSelect, {}).then(user => {
+			os.selectUser().then(user => {
 				this.complete('user', user);
 				this.textarea.focus();
 			});
diff --git a/src/client/components/page/page.vue b/src/client/components/page/page.vue
index 5cc9bd5a78..3fde9d4ba6 100644
--- a/src/client/components/page/page.vue
+++ b/src/client/components/page/page.vue
@@ -1,6 +1,6 @@
 <template>
 <div class="iroscrza" :class="{ center: page.alignCenter, serif: page.font === 'serif' }" v-if="hpml">
-	<x-block v-for="child in page.content" :value="child" @onUpdate:value="v => updateBlock(v)" :page="page" :hpml="hpml" :key="child.id" :h="2"/>
+	<x-block v-for="child in page.content" :value="child" @update:value="v => updateBlock(v)" :page="page" :hpml="hpml" :key="child.id" :h="2"/>
 </div>
 </template>
 
diff --git a/src/client/components/poll-editor.vue b/src/client/components/poll-editor.vue
index 99449da0ac..d79465d5c8 100644
--- a/src/client/components/poll-editor.vue
+++ b/src/client/components/poll-editor.vue
@@ -5,7 +5,7 @@
 	</p>
 	<ul ref="choices">
 		<li v-for="(choice, i) in choices" :key="i">
-			<mk-input class="input" :value="choice" @onUpdate:value="onInput(i, $event)">
+			<mk-input class="input" :value="choice" @update:value="onInput(i, $event)">
 				<span>{{ $t('_poll.choiceN', { n: i + 1 }) }}</span>
 			</mk-input>
 			<button @click="remove(i)" class="_button">
diff --git a/src/client/components/post-form.vue b/src/client/components/post-form.vue
index 88bf552612..ccb33d41f5 100644
--- a/src/client/components/post-form.vue
+++ b/src/client/components/post-form.vue
@@ -58,7 +58,6 @@ import { faEyeSlash, faLaughSquint } from '@fortawesome/free-regular-svg-icons';
 import insertTextAtCursor from 'insert-text-at-cursor';
 import { length } from 'stringz';
 import { toASCII } from 'punycode';
-import MkUserSelect from './user-select.vue';
 import XNotePreview from './note-preview.vue';
 import { parse } from '../../mfm/parse';
 import { host, url } from '@/config';
@@ -442,7 +441,7 @@ export default defineComponent({
 		},
 
 		addVisibleUser() {
-			os.modal(MkUserSelect, {}).then(user => {
+			os.selectUser().then(user => {
 				this.visibleUsers.push(user);
 			});
 		},
@@ -605,7 +604,7 @@ export default defineComponent({
 		},
 
 		insertMention() {
-			os.modal(MkUserSelect, {}).then(user => {
+			os.selectUser().then(user => {
 				insertTextAtCursor(this.$refs.text, getAcct(user) + ' ');
 			});
 		},
diff --git a/src/client/components/sidebar.vue b/src/client/components/sidebar.vue
index 2d4ec2a58e..f26eefd2ca 100644
--- a/src/client/components/sidebar.vue
+++ b/src/client/components/sidebar.vue
@@ -280,7 +280,8 @@ export default defineComponent({
 		},
 
 		async addAcount() {
-			os.modal(await import('./signin-dialog.vue')).$once('login', res => {
+			os.modal(await import('./signin-dialog.vue')).then(res => {
+				if (res == null) return;
 				this.$store.dispatch('addAcount', res);
 				os.dialog({
 					type: 'success',
@@ -290,7 +291,8 @@ export default defineComponent({
 		},
 
 		async createAccount() {
-			os.modal(await import('./signup-dialog.vue')).$once('signup', res => {
+			os.modal(await import('./signup-dialog.vue')).then(res => {
+				if (res == null) return;
 				this.$store.dispatch('addAcount', res);
 				this.switchAccountWithToken(res.i);
 			});
diff --git a/src/client/components/signin.vue b/src/client/components/signin.vue
index 7b92c1e56e..e556abf68d 100755
--- a/src/client/components/signin.vue
+++ b/src/client/components/signin.vue
@@ -2,7 +2,7 @@
 <form class="eppvobhk" :class="{ signing, totpLogin }" @submit.prevent="onSubmit">
 	<div class="avatar" :style="{ backgroundImage: user ? `url('${ user.avatarUrl }')` : null }" v-show="withAvatar"></div>
 	<div class="normal-signin" v-if="!totpLogin">
-		<mk-input v-model:value="username" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required @onUpdate:value="onUsernameChange">
+		<mk-input v-model:value="username" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required @update:value="onUsernameChange">
 			<span>{{ $t('username') }}</span>
 			<template #prefix>@</template>
 			<template #suffix>@{{ host }}</template>
diff --git a/src/client/components/signup.vue b/src/client/components/signup.vue
index 892312a13e..587c1263d0 100644
--- a/src/client/components/signup.vue
+++ b/src/client/components/signup.vue
@@ -5,7 +5,7 @@
 			<span>{{ $t('invitationCode') }}</span>
 			<template #prefix><fa :icon="faKey"/></template>
 		</mk-input>
-		<mk-input v-model:value="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :autocomplete="Math.random()" spellcheck="false" required @onUpdate:value="onChangeUsername">
+		<mk-input v-model:value="username" type="text" pattern="^[a-zA-Z0-9_]{1,20}$" :autocomplete="Math.random()" spellcheck="false" required @update:value="onChangeUsername">
 			<span>{{ $t('username') }}</span>
 			<template #prefix>@</template>
 			<template #suffix>@{{ host }}</template>
@@ -19,7 +19,7 @@
 				<span v-if="usernameState == 'max-range'" style="color:#FF1161"><fa :icon="faExclamationTriangle" fixed-width/> {{ $t('tooLong') }}</span>
 			</template>
 		</mk-input>
-		<mk-input v-model:value="password" type="password" :autocomplete="Math.random()" required @onUpdate:value="onChangePassword">
+		<mk-input v-model:value="password" type="password" :autocomplete="Math.random()" required @update:value="onChangePassword">
 			<span>{{ $t('password') }}</span>
 			<template #prefix><fa :icon="faLock"/></template>
 			<template #desc>
@@ -28,7 +28,7 @@
 				<p v-if="passwordStrength == 'high'" style="color:#3CB7B5"><fa :icon="faCheck" fixed-width/> {{ $t('strongPassword') }}</p>
 			</template>
 		</mk-input>
-		<mk-input v-model:value="retypedPassword" type="password" :autocomplete="Math.random()" required @onUpdate:value="onChangePasswordRetype">
+		<mk-input v-model:value="retypedPassword" type="password" :autocomplete="Math.random()" required @update:value="onChangePasswordRetype">
 			<span>{{ $t('password') }} ({{ $t('retype') }})</span>
 			<template #prefix><fa :icon="faLock"/></template>
 			<template #desc>
diff --git a/src/client/components/user-select.vue b/src/client/components/user-select.vue
index f6efe82fa1..3cbb58f44a 100644
--- a/src/client/components/user-select.vue
+++ b/src/client/components/user-select.vue
@@ -1,10 +1,10 @@
 <template>
-<x-window ref="window" @closed="() => { $emit('closed'); destroyDom(); }" :with-ok-button="true" :ok-button-disabled="selected == null" @ok="ok()">
+<x-window @close="$emit('done')" :with-ok-button="true" :ok-button-disabled="selected == null" @ok="ok()">
 	<template #header>{{ $t('selectUser') }}</template>
 	<div class="tbhwbxda">
 		<div class="inputs">
-			<mk-input v-model:value="username" class="input" @onUpdate:value="search" ref="username"><span>{{ $t('username') }}</span><template #prefix>@</template></mk-input>
-			<mk-input v-model:value="host" class="input" @onUpdate:value="search"><span>{{ $t('host') }}</span><template #prefix>@</template></mk-input>
+			<mk-input v-model:value="username" class="input" @update:value="search" ref="username"><span>{{ $t('username') }}</span><template #prefix>@</template></mk-input>
+			<mk-input v-model:value="host" class="input" @update:value="search"><span>{{ $t('host') }}</span><template #prefix>@</template></mk-input>
 		</div>
 		<div class="users">
 			<div class="user" v-for="user in users" :key="user.id" :class="{ selected: selected && selected.id === user.id }" @click="selected = user" @dblclick="ok()">
@@ -35,6 +35,8 @@ export default defineComponent({
 	props: {
 	},
 
+	emits: ['done'],
+
 	data() {
 		return {
 			username: '',
@@ -73,13 +75,8 @@ export default defineComponent({
 			this.$refs.username.focus();
 		},
 
-		close() {
-			this.$refs.window.close();
-		},
-
 		ok() {
-			this.$emit('selected', this.selected);
-			this.close();
+			this.$emit('done', this.selected);
 		},
 	}
 });
diff --git a/src/client/os.ts b/src/client/os.ts
index 69094169a1..bc4d09b74a 100644
--- a/src/client/os.ts
+++ b/src/client/os.ts
@@ -143,9 +143,21 @@ export function dialog(props: Record<string, any>, opts?: { cancelableByBgClick:
 	});
 }
 
-export function selectDriveFile(multiple) {
-	return new Promise(async (res, rej) => {
-		modal(await import('@/components/drive-window.vue'), {
+export async function selectUser() {
+	const component = await import('@/components/user-select.vue');
+	return new Promise((res, rej) => {
+		modal(component, {}).then(user => {
+			if (user) {
+				res(user);
+			}
+		});
+	});
+}
+
+export async function selectDriveFile(multiple: boolean) {
+	const component = await import('@/components/drive-window.vue');
+	return new Promise((res, rej) => {
+		modal(component, {
 			type: 'file',
 			multiple
 		}).then(files => {
@@ -156,16 +168,16 @@ export function selectDriveFile(multiple) {
 	});
 }
 
-export function selectDriveFolder(multiple) {
+export async function selectDriveFolder(multiple: boolean) {
+	const component = await import('@/components/drive-window.vue');
 	return new Promise((res, rej) => {
-		import('@/components/drive-window.vue').then(dialog => {
-			const w = $root.new(dialog, {
-				type: 'folder',
-				multiple
-			});
-			w.$once('selected', folders => {
-				res(multiple ? folders : (folders.length === 0 ? null : folders[0]));
-			});
+		modal(component, {
+			type: 'folder',
+			multiple
+		}).then(folders => {
+			if (folders) {
+				res(folders[0]);
+			}
 		});
 	});
 }
diff --git a/src/client/pages/instance/settings.vue b/src/client/pages/instance/settings.vue
index fd9ce3e790..30fc8b7ca1 100644
--- a/src/client/pages/instance/settings.vue
+++ b/src/client/pages/instance/settings.vue
@@ -242,7 +242,6 @@ import MkInput from '@/components/ui/input.vue';
 import MkTextarea from '@/components/ui/textarea.vue';
 import MkSwitch from '@/components/ui/switch.vue';
 import MkInfo from '@/components/ui/info.vue';
-import MkUserSelect from '@/components/user-select.vue';
 import { url } from '@/config';
 import getAcct from '../../../misc/acct/render';
 import * as os from '@/os';
@@ -452,8 +451,7 @@ export default defineComponent({
 		},
 
 		addPinUser() {
-			os.modal(MkUserSelect, {}).then(user => {
-				if (user == null) return;
+			os.selectUser().then(user => {
 				this.pinnedUsers = this.pinnedUsers.trim();
 				this.pinnedUsers += '\n@' + getAcct(user);
 				this.pinnedUsers = this.pinnedUsers.trim();
@@ -461,8 +459,7 @@ export default defineComponent({
 		},
 
 		chooseProxyAccount() {
-			os.modal(MkUserSelect, {}).then(user => {
-				if (user == null) return;
+			os.selectUser().then(user => {
 				this.proxyAccount = user;
 				this.proxyAccountId = user.id;
 				this.save(true);
diff --git a/src/client/pages/instance/users.vue b/src/client/pages/instance/users.vue
index 919627c0a3..e044b0d95f 100644
--- a/src/client/pages/instance/users.vue
+++ b/src/client/pages/instance/users.vue
@@ -43,10 +43,10 @@
 				</mk-select>
 			</div>
 			<div class="inputs" style="display: flex; padding-top: 1.2em;">
-				<mk-input v-model:value="searchUsername" style="margin: 0; flex: 1;" type="text" spellcheck="false" @onUpdate:value="$refs.users.reload()">
+				<mk-input v-model:value="searchUsername" style="margin: 0; flex: 1;" type="text" spellcheck="false" @update:value="$refs.users.reload()">
 					<span>{{ $t('username') }}</span>
 				</mk-input>
-				<mk-input v-model:value="searchHost" style="margin: 0; flex: 1;" type="text" spellcheck="false" @onUpdate:value="$refs.users.reload()" :disabled="pagination.params().origin === 'local'">
+				<mk-input v-model:value="searchHost" style="margin: 0; flex: 1;" type="text" spellcheck="false" @update:value="$refs.users.reload()" :disabled="pagination.params().origin === 'local'">
 					<span>{{ $t('host') }}</span>
 				</mk-input>
 			</div>
@@ -90,7 +90,6 @@ import MkButton from '@/components/ui/button.vue';
 import MkInput from '@/components/ui/input.vue';
 import MkSelect from '@/components/ui/select.vue';
 import MkPagination from '@/components/ui/pagination.vue';
-import MkUserSelect from '@/components/user-select.vue';
 import { acct } from '../../filters/user';
 import * as os from '@/os';
 
@@ -180,7 +179,7 @@ export default defineComponent({
 		},
 
 		searchUser() {
-			os.modal(MkUserSelect, {}).$once('selected', user => {
+			os.selectUser().then(user => {
 				this.show(user);
 			});
 		},
diff --git a/src/client/pages/messaging/index.vue b/src/client/pages/messaging/index.vue
index a2cc0e36f7..7f23837fe6 100644
--- a/src/client/pages/messaging/index.vue
+++ b/src/client/pages/messaging/index.vue
@@ -42,7 +42,6 @@ import { defineComponent } from 'vue';
 import { faUser, faUsers, faComments, faPlus } from '@fortawesome/free-solid-svg-icons';
 import getAcct from '../../../misc/acct/render';
 import MkButton from '@/components/ui/button.vue';
-import MkUserSelect from '@/components/user-select.vue';
 import { acct } from '../../filters/user';
 import * as os from '@/os';
 
@@ -132,7 +131,7 @@ export default defineComponent({
 		},
 
 		async startUser() {
-			os.modal(MkUserSelect, {}).$once('selected', user => {
+			os.selectUser().then(user => {
 				this.$router.push(`/my/messaging/${getAcct(user)}`);
 			});
 		},
diff --git a/src/client/pages/my-antennas/index.antenna.vue b/src/client/pages/my-antennas/index.antenna.vue
index 52af31606d..13c709bf1c 100644
--- a/src/client/pages/my-antennas/index.antenna.vue
+++ b/src/client/pages/my-antennas/index.antenna.vue
@@ -53,7 +53,6 @@ import MkInput from '@/components/ui/input.vue';
 import MkTextarea from '@/components/ui/textarea.vue';
 import MkSelect from '@/components/ui/select.vue';
 import MkSwitch from '@/components/ui/switch.vue';
-import MkUserSelect from '@/components/user-select.vue';
 import getAcct from '../../../misc/acct/render';
 import * as os from '@/os';
 
@@ -177,7 +176,7 @@ export default defineComponent({
 		},
 
 		addUser() {
-			os.modal(MkUserSelect, {}).$once('selected', user => {
+			os.selectUser().then(user => {
 				this.users = this.users.trim();
 				this.users += '\n@' + getAcct(user);
 				this.users = this.users.trim();
diff --git a/src/client/pages/my-groups/group.vue b/src/client/pages/my-groups/group.vue
index e0edffa80d..01a30030dc 100644
--- a/src/client/pages/my-groups/group.vue
+++ b/src/client/pages/my-groups/group.vue
@@ -42,7 +42,6 @@ import { defineComponent } from 'vue';
 import { faTimes, faUsers } from '@fortawesome/free-solid-svg-icons';
 import Progress from '@/scripts/loading';
 import MkButton from '@/components/ui/button.vue';
-import MkUserSelect from '@/components/user-select.vue';
 import * as os from '@/os';
 
 export default defineComponent({
@@ -89,7 +88,7 @@ export default defineComponent({
 		},
 
 		invite() {
-			os.modal(MkUserSelect, {}).$once('selected', user => {
+			os.selectUser().then(user => {
 				os.api('users/groups/invite', {
 					groupId: this.group.id,
 					userId: user.id
@@ -134,7 +133,7 @@ export default defineComponent({
 		},
 
 		transfer() {
-			os.modal(MkUserSelect, {}).$once('selected', user => {
+			os.selectUser().then(user => {
 				os.api('users/groups/transfer', {
 					groupId: this.group.id,
 					userId: user.id
diff --git a/src/client/pages/my-lists/list.vue b/src/client/pages/my-lists/list.vue
index 9185323c98..e9e93efa8b 100644
--- a/src/client/pages/my-lists/list.vue
+++ b/src/client/pages/my-lists/list.vue
@@ -41,7 +41,6 @@ import { defineComponent } from 'vue';
 import { faTimes, faListUl } from '@fortawesome/free-solid-svg-icons';
 import Progress from '@/scripts/loading';
 import MkButton from '@/components/ui/button.vue';
-import MkUserSelect from '@/components/user-select.vue';
 import * as os from '@/os';
 
 export default defineComponent({
@@ -88,7 +87,7 @@ export default defineComponent({
 		},
 
 		addUser() {
-			os.modal(MkUserSelect, {}).$once('selected', user => {
+			os.selectUser().then(user => {
 				os.api('users/lists/push', {
 					listId: this.list.id,
 					userId: user.id
diff --git a/src/client/pages/page-editor/page-editor.blocks.vue b/src/client/pages/page-editor/page-editor.blocks.vue
index 6b78f0846a..d99a82052d 100644
--- a/src/client/pages/page-editor/page-editor.blocks.vue
+++ b/src/client/pages/page-editor/page-editor.blocks.vue
@@ -1,6 +1,6 @@
 <template>
 <x-draggable tag="div" :list="blocks" handle=".drag-handle" :group="{ name: 'blocks' }" animation="150" swap-threshold="0.5">
-	<component v-for="block in blocks" :is="'x-' + block.type" :value="block" @onUpdate:value="updateItem" @remove="() => removeItem(block)" :key="block.id" :hpml="hpml"/>
+	<component v-for="block in blocks" :is="'x-' + block.type" :value="block" @update:value="updateItem" @remove="() => removeItem(block)" :key="block.id" :hpml="hpml"/>
 </x-draggable>
 </template>
 
diff --git a/src/client/pages/page-editor/page-editor.vue b/src/client/pages/page-editor/page-editor.vue
index e60cfe3b2a..ec9d75ace3 100644
--- a/src/client/pages/page-editor/page-editor.vue
+++ b/src/client/pages/page-editor/page-editor.vue
@@ -59,7 +59,7 @@
 				<x-variable v-for="variable in variables"
 					:value="variable"
 					:removable="true"
-					@onUpdate:value="v => updateVariable(v)"
+					@update:value="v => updateVariable(v)"
 					@remove="() => removeVariable(variable)"
 					:key="variable.name"
 					:hpml="hpml"
diff --git a/src/client/pages/room/room.vue b/src/client/pages/room/room.vue
index 433d8c1276..4b42f29f0e 100644
--- a/src/client/pages/room/room.vue
+++ b/src/client/pages/room/room.vue
@@ -39,7 +39,7 @@
 			<mk-button @click="add()"><fa :icon="faBoxOpen"/> {{ $t('_rooms.addFurniture') }}</mk-button>
 		</div>
 		<div class="_content">
-			<mk-select :value="roomType" @onUpdate:value="updateRoomType($event)">
+			<mk-select :value="roomType" @update:value="updateRoomType($event)">
 				<template #label>{{ $t('_rooms.roomType') }}</template>
 				<option value="default">{{ $t('_rooms._roomType.default') }}</option>
 				<option value="washitsu">{{ $t('_rooms._roomType.washitsu') }}</option>
diff --git a/src/client/pages/test.vue b/src/client/pages/test.vue
index 9f3674771b..71bd9a3f3d 100644
--- a/src/client/pages/test.vue
+++ b/src/client/pages/test.vue
@@ -48,6 +48,27 @@
 
 		</div>
 	</div>
+
+	<div class="_card _vMargin">
+		<div class="_title">selectDriveFolder</div>
+		<div class="_content">
+			<mk-button @click="selectDriveFolder()">selectDriveFolder</mk-button>
+		</div>
+		<div class="_content">
+
+		</div>
+	</div>
+
+
+	<div class="_card _vMargin">
+		<div class="_title">selectUser</div>
+		<div class="_content">
+			<mk-button @click="selectUser()">selectUser</mk-button>
+		</div>
+		<div class="_content">
+			<span>Result: {{ user }}</span>
+		</div>
+	</div>
 </div>
 </template>
 
@@ -83,6 +104,7 @@ export default defineComponent({
 			dialogInput: false,
 			dialogResult: null,
 			mfm: '',
+			user: null,
 			faExclamationTriangle
 		}
 	},
@@ -101,7 +123,15 @@ export default defineComponent({
 
 		async selectDriveFile() {
 			const files = await os.selectDriveFile();
-		}
+		},
+
+		async selectDriveFolder() {
+			const folder = await os.selectDriveFolder();
+		},
+
+		async selectUser() {
+			this.user = await os.selectUser();
+		},
 	}
 });
 </script>
diff --git a/src/client/pages/theme-editor.vue b/src/client/pages/theme-editor.vue
index 7c5569cfa9..c106c64c8e 100644
--- a/src/client/pages/theme-editor.vue
+++ b/src/client/pages/theme-editor.vue
@@ -30,7 +30,7 @@
 							<!-- color -->
 							<div v-else-if="typeof v === 'string'" class="color">
 								<input type="color" :value="v" @input="colorChanged($event.target.value, i)"/>
-								<mk-input class="select" :value="v" @onUpdate:value="colorChanged($event, i)"/>
+								<mk-input class="select" :value="v" @update:value="colorChanged($event, i)"/>
 							</div>
 							<!-- ref const -->
 							<mk-input v-else-if="v.type === 'refConst'" v-model:value="v.key">
diff --git a/src/client/pages/user/index.vue b/src/client/pages/user/index.vue
index 6c8d817367..072821eb07 100644
--- a/src/client/pages/user/index.vue
+++ b/src/client/pages/user/index.vue
@@ -171,9 +171,10 @@ export default defineComponent({
 
 	mounted() {
 		window.requestAnimationFrame(this.parallaxLoop);
-		this.$once('hook:beforeUnmount', () => {
-			window.cancelAnimationFrame(this.parallaxAnimationId);
-		});
+	},
+
+	beforeUnmount() {
+		window.cancelAnimationFrame(this.parallaxAnimationId);
 	},
 
 	methods: {