From 7199e6f4e0b3a2c2bc198e689c3e0cd0d0f0354a Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sat, 17 Oct 2020 20:12:00 +0900
Subject: Migrate to Vue3 (#6587)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* Update reaction.vue

* fix  bug

* wip

* wip

* wjio

* wip

* Revert "wip"

This reverts commit e427f2160adf4e8a4147006e25a89854edab0033.

* wip

* wip

* wip

* Update init.ts

* Update drive-window.vue

* wip

* wip

* Use PascalCase for components

* Use PascalCase for components

* update dep

* wip

* wip

* wip

* Update init.ts

* wip

* Update paging.ts

* Update test.vue

* watch deep

* wip

* lint

* wip

* wip

* wip

* wip

* wiop

* wip

* Update webpack.config.ts

* alllow null poll

* wip

* wip

* wip

* wiop

* UI redesign & refactor (#6714)

* wip

* wip

* wip

* wip

* wip

* Update drive.vue

* Update word-mute.vue

* wip

* wip

* wip

* clean up

* wip

* Update default.vue

* wip

* Update notes.vue

* Update mfm.ts

* Update index.home.vue

* Update post-form.vue

* Update post-form-attaches.vue

* wip

* Update post-form.vue

* Update sidebar.vue

* wip

* wip

* Update index.vue

* wip

* Update default.vue

* Update index.vue

* Update index.vue

* wip

* Update post-form-attaches.vue

* Update note.vue

* wip

* clean up

* Update notes.vue

* wip

* wip

* Update ja-JP.yml

* wip

* wip

* Update index.vue

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* Update default.vue

* wip

* Update _dark.json5

* wip

* wip

* wip

* clean up

* wip

* wip

* Update index.vue

* Update test.vue

* wip

* wip

* fix

* wip

* wip

* wip

* wip

* clena yop

* wip

* wip

* Update store.ts

* Update messaging-room.vue

* Update default.widgets.vue

* fix

* wip

* wip

* Update modal.vue

* wip

* Update os.ts

* Update os.ts

* Update deck.vue

* Update init.ts

* wip

* Update ja-JP.yml

* v-sizeは単にwindowのresizeを監視するだけで良いかもしれない

* Update modal.vue

* wip

* Update tooltip.ts

* wip

* wip

* wip

* wip

* wip

* Update image-viewer.vue

* wip

* wip

* Update style.scss

* Update style.scss

* Update visitor.vue

* wip

* Update init.ts

* Update init.ts

* wip

* wip

* Update visitor.vue

* Update visitor.vue

* Update visitor.vue

* Update visitor.vue

* wip

* wip

* Update modal.vue

* Update header.vue

* Update menu.vue

* Update about.vue

* Update about-misskey.vue

* wip

* wip

* Update visitor.vue

* Update tooltip.ts

* wip

* Update drive.vue

* wip

* Update style.scss

* Update header.vue

* wip

* wip

* Update users.user.vue

* Update announcements.vue

* wip

* wip

* wip

* Update emojis.vue

* wip

* Update emojis.vue

* Update style.scss

* Update users.vue

* wip

* Update style.scss

* wip

* Update welcome.entrance.vue

* Update radio.vue

* Update size.ts

* Update emoji-edit-dialog.vue

* wip

* Update emojis.vue

* wip

* Update emojis.vue

* Update emojis.vue

* Update emojis.vue

* wip

* wip

* wip

* wip

* Update file-dialog.vue

* wip

* wip

* Update token-generate-window.vue

* Update notification-setting-window.vue

* wip

* wip

* Update _error_.vue

* Update ja-JP.yml

* wip

* wip

* Update store.ts

* Update emojis.vue

* Update emojis.vue

* Update emojis.vue

* Update announcements.vue

* Update store.ts

* wip

* Update page-editor.vue

* wip

* wip

* Update modal.vue

* wip

* Update select-file.ts

* Update timeline.vue

* Update emojis.vue

* Update os.ts

* wip

* Update user-select.vue

* Update mfm.ts

* Update get-file-info.ts

* Update drive.vue

* Update init.ts

* Update mfm.ts

* wip

* wip

* Update window.vue

* Update note.vue

* wip

* wip

* Update user-info.vue

* wip

* wip

* wip

* wip

* wip

* Update header.vue

* Update header.vue

* wip

* Update explore.vue

* wip

* wip

* wip

* Update webpack.config.ts

* wip

* wip

* wip

* wip

* wip

* wip

* Update autocomplete.ts

* wip

* wip

* wip

* Update toast.vue

* wip

* Update post-form-dialog.vue

* wip

* wip

* wip

* wip

* wip

* Update users.vue

* wip

* Update explore.vue

* wip

* wip

* wip

* Update package.json

* wip

* Update icon-dialog.vue

* wip

* wip

* Update user-preview.ts

* wip

* wip

* wip

* wip

* wip

* Update instance.vue

* Update user-name.vue

* Update federation.vue

* Update instance.vue

* wip

* wip

* Update tag.vue

* wip

* wip

* wip

* wip

* wip

* Update instance.vue

* wip

* Update os.ts

* Update os.ts

* wip

* wip

* wip

* Update router.ts

* wip

* Update init.ts

* Update note.vue

* Update messages.vue

* wip

* wip

* wip

* wip

* wip

* google

* wip

* wip

* wip

* wip

* Update theme-editor.vue

* wip

* wip

* Update room.vue

* Update channel-editor.vue

* wip

* Update window.vue

* Update window.vue

* wip

* Update window.vue

* Update window.vue

* wip

* Update menu.vue

* wip

* wip

* wip

* wip

* Update messaging-room.vue

* wip

* Update post-form.vue

* Update default.widgets.vue

* Update window.vue

* wip
---
 src/client/components/sidebar.vue | 272 +++++++++++++++++---------------------
 1 file changed, 124 insertions(+), 148 deletions(-)

(limited to 'src/client/components/sidebar.vue')

diff --git a/src/client/components/sidebar.vue b/src/client/components/sidebar.vue
index 77e9af27e5..7548b136ea 100644
--- a/src/client/components/sidebar.vue
+++ b/src/client/components/sidebar.vue
@@ -4,7 +4,7 @@
 		<div class="nav-back _modalBg"
 			v-if="showing"
 			@click="showing = false"
-			@touchstart="showing = false"
+			@touchstart.passive="showing = false"
 		></div>
 	</transition>
 
@@ -12,31 +12,31 @@
 		<nav class="nav" :class="{ iconOnly, hidden }" v-show="showing">
 			<div>
 				<button class="item _button account" @click="openAccountMenu" v-if="$store.getters.isSignedIn">
-					<mk-avatar :user="$store.state.i" class="avatar"/><mk-acct class="text" :user="$store.state.i"/>
+					<MkAvatar :user="$store.state.i" class="avatar"/><MkAcct class="text" :user="$store.state.i"/>
 				</button>
 				<button class="item _button index active" @click="top()" v-if="$route.name === 'index'">
-					<fa :icon="faHome" fixed-width/><span class="text">{{ $store.getters.isSignedIn ? $t('timeline') : $t('home') }}</span>
+					<Fa :icon="faHome" fixed-width/><span class="text">{{ $store.getters.isSignedIn ? $t('timeline') : $t('home') }}</span>
 				</button>
 				<router-link class="item index" active-class="active" to="/" exact v-else>
-					<fa :icon="faHome" fixed-width/><span class="text">{{ $store.getters.isSignedIn ? $t('timeline') : $t('home') }}</span>
+					<Fa :icon="faHome" fixed-width/><span class="text">{{ $store.getters.isSignedIn ? $t('timeline') : $t('home') }}</span>
 				</router-link>
 				<template v-for="item in menu">
 					<div v-if="item === '-'" class="divider"></div>
-					<component v-else-if="menuDef[item] && (menuDef[item].show !== false)" :is="menuDef[item].to ? 'router-link' : 'button'" class="item _button" :class="item" active-class="active" @click="() => { if (menuDef[item].action) menuDef[item].action() }" :to="menuDef[item].to">
-						<fa :icon="menuDef[item].icon" fixed-width/><span class="text">{{ $t(menuDef[item].title) }}</span>
-						<i v-if="menuDef[item].indicated"><fa :icon="faCircle"/></i>
+					<component v-else-if="menuDef[item] && (menuDef[item].show !== false)" :is="menuDef[item].to ? 'router-link' : 'button'" class="item _button" :class="item" active-class="active" v-on="menuDef[item].action ? { click: menuDef[item].action } : {}" :to="menuDef[item].to">
+						<Fa :icon="menuDef[item].icon" fixed-width/><span class="text">{{ $t(menuDef[item].title) }}</span>
+						<i v-if="menuDef[item].indicated"><Fa :icon="faCircle"/></i>
 					</component>
 				</template>
 				<div class="divider"></div>
 				<button class="item _button" :class="{ active: $route.path === '/instance' || $route.path.startsWith('/instance/') }" v-if="$store.getters.isSignedIn && ($store.state.i.isAdmin || $store.state.i.isModerator)" @click="oepnInstanceMenu">
-					<fa :icon="faServer" fixed-width/><span class="text">{{ $t('instance') }}</span>
+					<Fa :icon="faServer" fixed-width/><span class="text">{{ $t('instance') }}</span>
 				</button>
 				<button class="item _button" @click="more">
-					<fa :icon="faEllipsisH" fixed-width/><span class="text">{{ $t('more') }}</span>
-					<i v-if="otherNavItemIndicated"><fa :icon="faCircle"/></i>
+					<Fa :icon="faEllipsisH" fixed-width/><span class="text">{{ $t('more') }}</span>
+					<i v-if="otherNavItemIndicated"><Fa :icon="faCircle"/></i>
 				</button>
-				<router-link class="item" active-class="active" to="/preferences">
-					<fa :icon="faCog" fixed-width/><span class="text">{{ $t('settings') }}</span>
+				<router-link class="item" active-class="active" to="/settings">
+					<Fa :icon="faCog" fixed-width/><span class="text">{{ $t('settings') }}</span>
 				</router-link>
 			</div>
 		</nav>
@@ -45,13 +45,15 @@
 </template>
 
 <script lang="ts">
-import Vue from 'vue';
-import { faGripVertical, faChevronLeft, faHashtag, faBroadcastTower, faFireAlt, faEllipsisH, faPencilAlt, faBars, faTimes, faSearch, faUserCog, faCog, faUser, faHome, faStar, faCircle, faAt, faListUl, faPlus, faUserClock, faUsers, faTachometerAlt, faExchangeAlt, faGlobe, faChartBar, faCloud, faServer, faInfoCircle, faQuestionCircle, faProjectDiagram } from '@fortawesome/free-solid-svg-icons';
+import { defineComponent } from 'vue';
+import { faGripVertical, faChevronLeft, faHashtag, faBroadcastTower, faFireAlt, faEllipsisH, faPencilAlt, faBars, faTimes, faSearch, faUserCog, faCog, faUser, faHome, faStar, faCircle, faAt, faListUl, faPlus, faUserClock, faUsers, faTachometerAlt, faExchangeAlt, faGlobe, faChartBar, faCloud, faServer, faInfoCircle, faQuestionCircle, faProjectDiagram, faStream } from '@fortawesome/free-solid-svg-icons';
 import { faBell, faEnvelope, faLaugh, faComments } from '@fortawesome/free-regular-svg-icons';
-import { host, instanceName } from '../config';
-import { search } from '../scripts/search';
+import { host, instanceName } from '@/config';
+import { search } from '@/scripts/search';
+import * as os from '@/os';
+import { sidebarDef } from '@/sidebar';
 
-export default Vue.extend({
+export default defineComponent({
 	data() {
 		return {
 			host: host,
@@ -59,9 +61,7 @@ export default Vue.extend({
 			searching: false,
 			accounts: [],
 			connection: null,
-			menuDef: this.$store.getters.nav({
-				search: this.search
-			}),
+			menuDef: sidebarDef,
 			iconOnly: false,
 			hidden: false,
 			faGripVertical, faChevronLeft, faComments, faHashtag, faBroadcastTower, faFireAlt, faEllipsisH, faPencilAlt, faBars, faTimes, faBell, faSearch, faUserCog, faCog, faUser, faHome, faStar, faCircle, faAt, faEnvelope, faListUl, faPlus, faUserClock, faLaugh, faUsers, faTachometerAlt, faExchangeAlt, faGlobe, faChartBar, faCloud, faServer, faProjectDiagram
@@ -127,7 +127,7 @@ export default Vue.extend({
 		search() {
 			if (this.searching) return;
 
-			this.$root.dialog({
+			os.dialog({
 				title: this.$t('search'),
 				input: true
 			}).then(async ({ canceled, result: query }) => {
@@ -141,7 +141,7 @@ export default Vue.extend({
 		},
 
 		async openAccountMenu(ev) {
-			const accounts = (await this.$root.api('users/show', { userIds: this.$store.state.device.accounts.map(x => x.id) })).filter(x => x.id !== this.$store.state.i.id);
+			const accounts = (await os.api('users/show', { userIds: this.$store.state.device.accounts.map(x => x.id) })).filter(x => x.id !== this.$store.state.i.id);
 
 			const accountItems = accounts.map(account => ({
 				type: 'user',
@@ -149,96 +149,80 @@ export default Vue.extend({
 				action: () => { this.switchAccount(account); }
 			}));
 
-			this.$root.menu({
-				items: [...[{
-					type: 'link',
-					text: this.$t('profile'),
-					to: `/@${ this.$store.state.i.username }`,
-					avatar: this.$store.state.i,
-				}, {
-					type: 'link',
-					text: this.$t('accountSettings'),
-					to: '/my/settings',
-					icon: faCog,
-				}, null, ...accountItems, {
-					icon: faPlus,
-					text: this.$t('addAcount'),
-					action: () => {
-						this.$root.menu({
-							items: [{
-								text: this.$t('existingAcount'),
-								action: () => { this.addAcount(); },
-							}, {
-								text: this.$t('createAccount'),
-								action: () => { this.createAccount(); },
-							}],
-							align: 'left',
-							fixed: true,
-							width: 240,
-							source: ev.currentTarget || ev.target,
-						});
-					},
-				}]],
-				align: 'left',
-				fixed: true,
-				width: 240,
-				source: ev.currentTarget || ev.target,
+			os.modalMenu([...[{
+				type: 'link',
+				text: this.$t('profile'),
+				to: `/@${ this.$store.state.i.username }`,
+				avatar: this.$store.state.i,
+			}, null, ...accountItems, {
+				icon: faPlus,
+				text: this.$t('addAcount'),
+				action: () => {
+					os.modalMenu([{
+						text: this.$t('existingAcount'),
+						action: () => { this.addAcount(); },
+					}, {
+						text: this.$t('createAccount'),
+						action: () => { this.createAccount(); },
+					}], ev.currentTarget || ev.target);
+				},
+			}]], ev.currentTarget || ev.target, {
+				align: 'left'
 			});
 		},
 
 		oepnInstanceMenu(ev) {
-			this.$root.menu({
-				items: [{
-					type: 'link',
-					text: this.$t('dashboard'),
-					to: '/instance',
-					icon: faTachometerAlt,
-				}, null, {
-					type: 'link',
-					text: this.$t('settings'),
-					to: '/instance/settings',
-					icon: faCog,
-				}, {
-					type: 'link',
-					text: this.$t('customEmojis'),
-					to: '/instance/emojis',
-					icon: faLaugh,
-				}, {
-					type: 'link',
-					text: this.$t('users'),
-					to: '/instance/users',
-					icon: faUsers,
-				}, {
-					type: 'link',
-					text: this.$t('files'),
-					to: '/instance/files',
-					icon: faCloud,
-				}, {
-					type: 'link',
-					text: this.$t('jobQueue'),
-					to: '/instance/queue',
-					icon: faExchangeAlt,
-				}, {
-					type: 'link',
-					text: this.$t('federation'),
-					to: '/instance/federation',
-					icon: faGlobe,
-				}, {
-					type: 'link',
-					text: this.$t('relays'),
-					to: '/instance/relays',
-					icon: faProjectDiagram,
-				}, {
-					type: 'link',
-					text: this.$t('announcements'),
-					to: '/instance/announcements',
-					icon: faBroadcastTower,
-				}],
-				align: 'left',
-				fixed: true,
-				width: 200,
-				source: ev.currentTarget || ev.target,
-			});
+			os.modalMenu([{
+				type: 'link',
+				text: this.$t('dashboard'),
+				to: '/instance',
+				icon: faTachometerAlt,
+			}, null, this.$store.state.i.isAdmin ? {
+				type: 'link',
+				text: this.$t('settings'),
+				to: '/instance/settings',
+				icon: faCog,
+			} : undefined, {
+				type: 'link',
+				text: this.$t('customEmojis'),
+				to: '/instance/emojis',
+				icon: faLaugh,
+			}, {
+				type: 'link',
+				text: this.$t('users'),
+				to: '/instance/users',
+				icon: faUsers,
+			}, {
+				type: 'link',
+				text: this.$t('files'),
+				to: '/instance/files',
+				icon: faCloud,
+			}, {
+				type: 'link',
+				text: this.$t('jobQueue'),
+				to: '/instance/queue',
+				icon: faExchangeAlt,
+			}, {
+				type: 'link',
+				text: this.$t('federation'),
+				to: '/instance/federation',
+				icon: faGlobe,
+			}, {
+				type: 'link',
+				text: this.$t('relays'),
+				to: '/instance/relays',
+				icon: faProjectDiagram,
+			}, {
+				type: 'link',
+				text: this.$t('announcements'),
+				to: '/instance/announcements',
+				icon: faBroadcastTower,
+			}, {
+				type: 'link',
+				text: this.$t('logs'),
+				to: '/instance/logs',
+				icon: faStream,
+			}], ev.currentTarget || ev.target);
 		},
 
 		more(ev) {
@@ -250,45 +234,40 @@ export default Vue.extend({
 				action: def.action,
 				indicate: def.indicated,
 			}));
-			this.$root.menu({
-				items: [...items, null, {
-					type: 'link',
-					text: this.$t('help'),
-					to: '/docs',
-					icon: faQuestionCircle,
-				}, {
-					type: 'link',
-					text: this.$t('aboutX', { x: instanceName || host }),
-					to: '/about',
-					icon: faInfoCircle,
-				}, {
-					type: 'link',
-					text: this.$t('aboutMisskey'),
-					to: '/about-misskey',
-					icon: faInfoCircle,
-				}],
-				align: 'left',
-				fixed: true,
-				width: 200,
-				source: ev.currentTarget || ev.target,
-			});
+			os.modalMenu([...items, null, {
+				type: 'link',
+				text: this.$t('help'),
+				to: '/docs',
+				icon: faQuestionCircle,
+			}, {
+				type: 'link',
+				text: this.$t('aboutX', { x: instanceName || host }),
+				to: '/about',
+				icon: faInfoCircle,
+			}, {
+				type: 'link',
+				text: this.$t('aboutMisskey'),
+				to: '/about-misskey',
+				icon: faInfoCircle,
+			}], ev.currentTarget || ev.target);
 		},
 
 		async addAcount() {
-			this.$root.new(await import('./signin-dialog.vue').then(m => m.default)).$once('login', res => {
-				this.$store.dispatch('addAcount', res);
-				this.$root.dialog({
-					type: 'success',
-					iconOnly: true, autoClose: true
-				});
-			});
+			os.popup(await import('./signin-dialog.vue'), {}, {
+				done: res => {
+					this.$store.dispatch('addAcount', res);
+					os.success();
+				},
+			}, 'closed');
 		},
 
 		async createAccount() {
-			this.$root.new(await import('./signup-dialog.vue').then(m => m.default)).$once('signup', res => {
-				this.$store.dispatch('addAcount', res);
-				this.switchAccountWithToken(res.i);
-			});
+			os.popup(await import('./signup-dialog.vue'), {}, {
+				done: res => {
+					this.$store.dispatch('addAcount', res);
+					this.switchAccountWithToken(res.i);
+				},
+			}, 'closed');
 		},
 
 		async switchAccount(account: any) {
@@ -297,12 +276,9 @@ export default Vue.extend({
 		},
 
 		switchAccountWithToken(token: string) {
-			this.$root.dialog({
-				type: 'waiting',
-				iconOnly: true
-			});
+			os.waiting();
 
-			this.$root.api('i', {}, token).then((i: any) => {
+			os.api('i', {}, token).then((i: any) => {
 				this.$store.dispatch('switchAccount', {
 					...i,
 					token: token
@@ -324,7 +300,7 @@ export default Vue.extend({
 	transform: translateX(0);
 	transition: transform 300ms cubic-bezier(0.23, 1, 0.32, 1), opacity 300ms cubic-bezier(0.23, 1, 0.32, 1);
 }
-.nav-enter,
+.nav-enter-from,
 .nav-leave-active {
 	opacity: 0;
 	transform: translateX(-240px);
@@ -335,7 +311,7 @@ export default Vue.extend({
 	opacity: 1;
 	transition: opacity 300ms cubic-bezier(0.23, 1, 0.32, 1);
 }
-.nav-back-enter,
+.nav-back-enter-from,
 .nav-back-leave-active {
 	opacity: 0;
 }
-- 
cgit v1.2.3-freya

