From d35f90b36dc60fb23704b081bba29ab3c38ebf7d Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Thu, 23 Jul 2020 23:39:15 +0900
Subject: [PATCH] wip

---
 package.json         |  7 +++----
 src/client/init.ts   | 46 +++++++++++++++++++-------------------------
 src/client/root.vue  |  1 +
 src/client/router.ts | 11 ++++-------
 src/client/store.ts  |  4 ++--
 yarn.lock            | 29 ++++++++++++----------------
 6 files changed, 42 insertions(+), 56 deletions(-)

diff --git a/package.json b/package.json
index 111ec8373d..050276ceee 100644
--- a/package.json
+++ b/package.json
@@ -191,7 +191,6 @@
 		"parse5": "6.0.0",
 		"parsimmon": "1.14.0",
 		"pg": "8.3.0",
-		"portal-vue": "2.1.7",
 		"portscanner": "2.2.0",
 		"postcss-loader": "3.0.0",
 		"prismjs": "1.20.0",
@@ -247,19 +246,19 @@
 		"vue-color": "2.7.1",
 		"vue-content-loading": "1.6.0",
 		"vue-cropperjs": "4.1.0",
-		"vue-i18n": "8.18.2",
+		"vue-i18n": "9.0.0-alpha.11",
 		"vue-json-pretty": "1.6.5",
 		"vue-loader": "16.0.0-beta.4",
 		"vue-marquee-text-component": "1.1.1",
 		"vue-meta": "2.4.0",
 		"vue-prism-component": "1.2.0",
 		"vue-prism-editor": "0.6.1",
-		"vue-router": "3.3.4",
+		"vue-router": "4.0.0-beta.3",
 		"vue-style-loader": "4.1.2",
 		"vue-svg-inline-loader-corejs3": "1.5.0",
 		"vue-template-compiler": "2.6.11",
 		"vuedraggable": "2.24.0",
-		"vuex": "3.5.1",
+		"vuex": "4.0.0-beta.4",
 		"vuex-persistedstate": "3.0.1",
 		"web-push": "3.4.4",
 		"webpack": "5.0.0-beta.22",
diff --git a/src/client/init.ts b/src/client/init.ts
index b684f415e3..50f47080bb 100644
--- a/src/client/init.ts
+++ b/src/client/init.ts
@@ -3,11 +3,9 @@
  */
 
 import { createApp } from 'vue';
-import Vuex from 'vuex';
 import VueMeta from 'vue-meta';
-import PortalVue from 'portal-vue';
 import VAnimateCss from 'v-animate-css';
-import VueI18n from 'vue-i18n';
+import { createI18n } from 'vue-i18n';
 import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
 import { AiScript } from '@syuilo/aiscript';
 import { deserialize } from '@syuilo/aiscript/built/serializer';
@@ -15,27 +13,37 @@ import { deserialize } from '@syuilo/aiscript/built/serializer';
 import VueHotkey from './scripts/hotkey';
 import Root from './root.vue';
 import MiOS from './mios';
-import { version, langs, instanceName, getLocale, deckmode } from './config';
-import PostFormDialog from './components/post-form-dialog.vue';
-import Dialog from './components/dialog.vue';
-import Menu from './components/menu.vue';
-import Form from './components/form-window.vue';
+import { version, langs, getLocale } from './config';
+import { store } from './store';
 import { router } from './router';
 import { applyTheme, lightTheme } from './scripts/theme';
 import { isDeviceDarkmode } from './scripts/is-device-darkmode';
-import createStore from './store';
 import { clientDb, get, count } from './db';
 import { setI18nContexts } from './scripts/set-i18n-contexts';
 import { createPluginEnv } from './scripts/aiscript/api';
 
+//#region Fetch locale data
+const i18n = createI18n({
+	legacy: true,
+});
+
+await count(clientDb.i18n).then(async n => {
+	if (n === 0) return setI18nContexts(lang, version, i18n);
+	if ((await get('_version_', clientDb.i18n) !== version)) return setI18nContexts(lang, version, i18n, true);
+
+	i18n.locale = lang;
+	i18n.setLocaleMessage(lang, await getLocale());
+});
+//#endregion
+
 const app = createApp(Root);
 
-app.use(Vuex);
+app.use(store);
+app.use(router);
 app.use(VueHotkey);
 app.use(VueMeta);
-app.use(PortalVue);
 app.use(VAnimateCss);
-app.use(VueI18n);
+app.use(i18n);
 app.component('fa', FontAwesomeIcon);
 
 require('./directives');
@@ -112,8 +120,6 @@ html.setAttribute('lang', lang);
 // アプリ基底要素マウント
 document.body.innerHTML = '<div id="app"></div>';
 
-const store = createStore();
-
 // 他のタブと永続化されたstateを同期
 window.addEventListener('storage', e => {
 	if (e.key === 'vuex') {
@@ -129,18 +135,6 @@ window.addEventListener('storage', e => {
 const os = new MiOS(store);
 
 os.init(async () => {
-	//#region Fetch locale data
-	const i18n = new VueI18n();
-
-	await count(clientDb.i18n).then(async n => {
-		if (n === 0) return setI18nContexts(lang, version, i18n);
-		if ((await get('_version_', clientDb.i18n) !== version)) return setI18nContexts(lang, version, i18n, true);
-
-		i18n.locale = lang;
-		i18n.setLocaleMessage(lang, await getLocale());
-	});
-	//#endregion
-
 	app.mount('#app');
 
 	store.watch(state => state.device.darkMode, darkMode => {
diff --git a/src/client/root.vue b/src/client/root.vue
index 25a8f7c491..143a523c75 100644
--- a/src/client/root.vue
+++ b/src/client/root.vue
@@ -7,6 +7,7 @@
 import Vue from 'vue';
 import DefaultUI from './default.vue';
 import DeckUI from './deck.vue';
+import { instanceName, deckmode } from './config';
 
 export default Vue.extend({
 	components: {
diff --git a/src/client/router.ts b/src/client/router.ts
index a741aeb955..c8cb3caaef 100644
--- a/src/client/router.ts
+++ b/src/client/router.ts
@@ -1,15 +1,12 @@
-import Vue from 'vue';
-import VueRouter from 'vue-router';
+import { createRouter, createWebHistory } from 'vue-router';
 import MkIndex from './pages/index.vue';
 
-Vue.use(VueRouter);
-
 const page = (path: string) => () => import(`./pages/${path}.vue`).then(m => m.default);
 
 let indexScrollPos = 0;
 
-export const router = new VueRouter({
-	mode: 'history',
+export const router = new createRouter({
+	history: createWebHistory(),
 	routes: [
 		{ path: '/', name: 'index', component: MkIndex },
 		{ path: '/@:user', name: 'user', component: page('user/index'), children: [
@@ -67,7 +64,7 @@ export const router = new VueRouter({
 		{ path: '/miauth/:session', component: page('miauth') },
 		{ path: '/authorize-follow', component: page('follow') },
 		{ path: '/share', component: page('share') },
-		{ path: '*', component: page('not-found') }
+		{ path: '/:catchAll(.*)', component: page('not-found') }
 	],
 	// なんかHacky
 	// 通常の使い方をすると scroll メソッドの behavior を設定できないため、自前で window.scroll するようにする
diff --git a/src/client/store.ts b/src/client/store.ts
index 5cfc1a369e..0e5c9c4e10 100644
--- a/src/client/store.ts
+++ b/src/client/store.ts
@@ -1,4 +1,4 @@
-import Vuex from 'vuex';
+import { createStore } from 'vuex';
 import createPersistedState from 'vuex-persistedstate';
 import * as nestedProperty from 'nested-property';
 import { faTerminal, faHashtag, faBroadcastTower, faFireAlt, faSearch, faStar, faAt, faListUl, faUserClock, faUsers, faCloud, faGamepad, faFileAlt, faSatellite, faDoorClosed, faColumns } from '@fortawesome/free-solid-svg-icons';
@@ -88,7 +88,7 @@ function copy<T>(data: T): T {
 	return JSON.parse(JSON.stringify(data));
 }
 
-export default () => new Vuex.Store({
+export const store = createStore({
 	plugins: [createPersistedState({
 		paths: ['i', 'device', 'deviceUser', 'settings', 'instance']
 	})],
diff --git a/yarn.lock b/yarn.lock
index 3fc6b7cc05..82372f4cc8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7135,11 +7135,6 @@ pngjs@^3.3.0, pngjs@^3.3.1:
   resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f"
   integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w==
 
-portal-vue@2.1.7:
-  version "2.1.7"
-  resolved "https://registry.yarnpkg.com/portal-vue/-/portal-vue-2.1.7.tgz#ea08069b25b640ca08a5b86f67c612f15f4e4ad4"
-  integrity sha512-+yCno2oB3xA7irTt0EU5Ezw22L2J51uKAacE/6hMPMoO/mx3h4rXFkkBkT4GFsMDv/vEe8TNKC3ujJJ0PTwb6g==
-
 portscanner@2.2.0:
   version "2.2.0"
   resolved "https://registry.yarnpkg.com/portscanner/-/portscanner-2.2.0.tgz#6059189b3efa0965c9d96a56b958eb9508411cf1"
@@ -10042,10 +10037,10 @@ vue-eslint-parser@^7.0.0:
     esquery "^1.0.1"
     lodash "^4.17.15"
 
-vue-i18n@8.18.2:
-  version "8.18.2"
-  resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-8.18.2.tgz#cd7c12f2e178e6faa23b0e3cfd2f7bac9305f8fc"
-  integrity sha512-0X5nBTCZAVjlwcrPaYJwNs3iipBBTv0AUHwQUOa8yP3XbQGWKbRHqBb3OhCYtum/IHDD21d/df5Xd2VgyxbxfA==
+vue-i18n@9.0.0-alpha.11:
+  version "9.0.0-alpha.11"
+  resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-9.0.0-alpha.11.tgz#66fc7227022ad40b12b562dace5cb9b739cac3ff"
+  integrity sha512-Ro+85srXAO/eyG/eb1+WOqqxFln7PEP2uv8XSiBfOH1lRGYXu/h5Ixunr1cOHwLJ5cYc1BSkFWW937brYer/tA==
 
 vue-json-pretty@1.6.5:
   version "1.6.5"
@@ -10092,10 +10087,10 @@ vue-prism-editor@0.6.1:
     escape-html "^1.0.3"
     unescape "^1.0.1"
 
-vue-router@3.3.4:
-  version "3.3.4"
-  resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-3.3.4.tgz#4e38abc34a11c41b6c3d8244449a2e363ba6250b"
-  integrity sha512-SdKRBeoXUjaZ9R/8AyxsdTqkOfMcI5tWxPZOUX5Ie1BTL5rPSZ0O++pbiZCeYeythiZIdLEfkDiQPKIaWk5hDg==
+vue-router@4.0.0-beta.3:
+  version "4.0.0-beta.3"
+  resolved "https://registry.yarnpkg.com/vue-router/-/vue-router-4.0.0-beta.3.tgz#e46f45807023a4b8ce73a143a216b4c9ea3eb243"
+  integrity sha512-3/cg3n46D9MO9u2nvtGE38gMyUxg8sjt6jMeZ6zbi9sRGAL0PaDHuKS+xWlOOLit7abP5MepNlh84t41gxtP8Q==
 
 vue-style-loader@4.1.2:
   version "4.1.2"
@@ -10152,10 +10147,10 @@ vuex-persistedstate@3.0.1:
     deepmerge "^4.2.2"
     shvl "^2.0.0"
 
-vuex@3.5.1:
-  version "3.5.1"
-  resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.5.1.tgz#f1b8dcea649bc25254cf4f4358081dbf5da18b3d"
-  integrity sha512-w7oJzmHQs0FM9LXodfskhw9wgKBiaB+totOdb8sNzbTB2KDCEEwEs29NzBZFh/lmEK1t5tDmM1vtsO7ubG1DFw==
+vuex@4.0.0-beta.4:
+  version "4.0.0-beta.4"
+  resolved "https://registry.yarnpkg.com/vuex/-/vuex-4.0.0-beta.4.tgz#7b319ead2ef30432b7eaa4e37258ea3c5e44f698"
+  integrity sha512-/+4E1dokq5cwbl4mohOqOj8h0vOLOWmLSqlqTf++bfmN9/JKWtwYfsBrzlK0sYrNfuYcpQeX0BVxQHoHXDfYZQ==
 
 w3c-hr-time@^1.0.2:
   version "1.0.2"