diff --git a/.babelrc b/.babelrc
index 94521147..373d2c59 100644
--- a/.babelrc
+++ b/.babelrc
@@ -1,5 +1,5 @@
{
- "presets": ["@babel/preset-env", "@vue/babel-preset-jsx"],
- "plugins": ["@babel/plugin-transform-runtime", "lodash"],
+ "presets": ["@babel/preset-env"],
+ "plugins": ["@babel/plugin-transform-runtime", "lodash", "@vue/babel-plugin-jsx"],
"comments": false
}
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 85d3ee44..ab601173 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,7 +1,7 @@
# This file is a template, and might need editing before it works on your project.
# Official framework image. Look for the different tagged releases at:
# https://hub.docker.com/r/library/node/tags/
-image: node:10
+image: node:12
stages:
- lint
diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js
index 900d824b..f442b2a0 100644
--- a/build/webpack.base.conf.js
+++ b/build/webpack.base.conf.js
@@ -4,6 +4,7 @@ var utils = require('./utils')
var projectRoot = path.resolve(__dirname, '../')
var ServiceWorkerWebpackPlugin = require('serviceworker-webpack-plugin')
var CopyPlugin = require('copy-webpack-plugin');
+var { VueLoaderPlugin } = require('vue-loader')
var env = process.env.NODE_ENV
// check env & config/index.js to decide weither to enable CSS Sourcemaps for the
@@ -29,12 +30,11 @@ module.exports = {
}
},
resolve: {
- extensions: ['.js', '.vue'],
+ extensions: ['.js', '.jsx', '.vue'],
modules: [
path.join(__dirname, '../node_modules')
],
alias: {
- 'vue$': 'vue/dist/vue.runtime.common',
'static': path.resolve(__dirname, '../static'),
'src': path.resolve(__dirname, '../src'),
'assets': path.resolve(__dirname, '../src/assets'),
@@ -60,7 +60,17 @@ module.exports = {
},
{
test: /\.vue$/,
- use: 'vue-loader'
+ loader: 'vue-loader',
+ options: {
+ compilerOptions: {
+ isCustomElement(tag) {
+ if (tag === 'pinch-zoom') {
+ return true
+ }
+ return false
+ }
+ }
+ }
},
{
test: /\.jsx?$/,
@@ -95,6 +105,7 @@ module.exports = {
entry: path.join(__dirname, '..', 'src/sw.js'),
filename: 'sw-pleroma.js'
}),
+ new VueLoaderPlugin(),
// This copies Ruffle's WASM to a directory so that JS side can access it
new CopyPlugin({
patterns: [
diff --git a/build/webpack.dev.conf.js b/build/webpack.dev.conf.js
index 159572ba..4605b93d 100644
--- a/build/webpack.dev.conf.js
+++ b/build/webpack.dev.conf.js
@@ -21,7 +21,9 @@ module.exports = merge(baseWebpackConfig, {
new webpack.DefinePlugin({
'process.env': config.dev.env,
'COMMIT_HASH': JSON.stringify('DEV'),
- 'DEV_OVERRIDES': JSON.stringify(config.dev.settings)
+ 'DEV_OVERRIDES': JSON.stringify(config.dev.settings),
+ '__VUE_OPTIONS_API__': true,
+ '__VUE_PROD_DEVTOOLS__': false
}),
// https://github.com/glenjamin/webpack-hot-middleware#installation--usage
new webpack.HotModuleReplacementPlugin(),
diff --git a/build/webpack.prod.conf.js b/build/webpack.prod.conf.js
index ed11ebad..a67ed2f6 100644
--- a/build/webpack.prod.conf.js
+++ b/build/webpack.prod.conf.js
@@ -36,7 +36,9 @@ var webpackConfig = merge(baseWebpackConfig, {
new webpack.DefinePlugin({
'process.env': env,
'COMMIT_HASH': JSON.stringify(commitHash),
- 'DEV_OVERRIDES': JSON.stringify(undefined)
+ 'DEV_OVERRIDES': JSON.stringify(undefined),
+ '__VUE_OPTIONS_API__': true,
+ '__VUE_PROD_DEVTOOLS__': false
}),
// extract css into its own file
new MiniCssExtractPlugin({
diff --git a/package.json b/package.json
index 7cd94066..0537780e 100644
--- a/package.json
+++ b/package.json
@@ -17,30 +17,31 @@
},
"dependencies": {
"@babel/runtime": "7.17.8",
- "@chenfengyuan/vue-qrcode": "1.0.2",
+ "@chenfengyuan/vue-qrcode": "2.0.0",
"@fortawesome/fontawesome-svg-core": "1.3.0",
"@fortawesome/free-regular-svg-icons": "5.15.4",
"@fortawesome/free-solid-svg-icons": "5.15.4",
- "@fortawesome/vue-fontawesome": "2.0.6",
+ "@fortawesome/vue-fontawesome": "3.0.0-5",
"@kazvmoe-infra/pinch-zoom-element": "1.2.0",
+ "@vuelidate/core": "2.0.0-alpha.35",
+ "@vuelidate/validators": "2.0.0-alpha.27",
"body-scroll-lock": "2.7.1",
"chromatism": "3.0.0",
+ "click-outside-vue3": "4.0.1",
"cropperjs": "1.5.12",
"diff": "3.5.0",
"escape-html": "1.0.3",
"localforage": "1.10.0",
"parse-link-header": "1.0.1",
"phoenix": "1.4.0",
- "portal-vue": "2.1.7",
"punycode.js": "2.1.0",
+ "qrcode": "1",
"ruffle-mirror": "2021.12.31",
- "v-click-outside": "2.1.5",
- "vue": "2.6.11",
- "vue-i18n": "7.8.1",
- "vue-router": "3.0.2",
+ "vue": "^3.2.31",
+ "vue-i18n": "9.1.9",
+ "vue-router": "4.0.14",
"vue-template-compiler": "2.6.11",
- "vuelidate": "0.7.7",
- "vuex": "3.0.1"
+ "vuex": "4.0.2"
},
"devDependencies": {
"@babel/core": "7.17.8",
@@ -49,8 +50,9 @@
"@babel/register": "7.17.7",
"@ungap/event-target": "0.2.3",
"@vue/babel-helper-vue-jsx-merge-props": "1.2.1",
- "@vue/babel-preset-jsx": "1.2.4",
- "@vue/test-utils": "1.0.0-beta.28",
+ "@vue/babel-plugin-jsx": "1.1.1",
+ "@vue/compiler-sfc": "^3.1.0",
+ "@vue/test-utils": "2.0.0-rc.17",
"autoprefixer": "6.7.7",
"babel-eslint": "7.2.3",
"babel-loader": "8.2.4",
@@ -82,10 +84,10 @@
"iso-639-1": "2.1.13",
"isparta-loader": "2.0.0",
"json-loader": "0.5.7",
- "karma": "3.1.4",
+ "karma": "6.3.17",
"karma-coverage": "1.1.2",
"karma-firefox-launcher": "1.3.0",
- "karma-mocha": "1.3.0",
+ "karma-mocha": "2.0.1",
"karma-mocha-reporter": "2.2.5",
"karma-sinon-chai": "2.0.2",
"karma-sourcemap-loader": "0.3.8",
@@ -112,7 +114,7 @@
"stylelint-config-standard": "20.0.0",
"stylelint-rscss": "0.4.0",
"url-loader": "1.1.2",
- "vue-loader": "14.2.4",
+ "vue-loader": "^16.0.0",
"vue-style-loader": "4.1.2",
"webpack": "4.46.0",
"webpack-dev-middleware": "3.7.3",
diff --git a/src/App.js b/src/App.js
index f5e0b9e9..c4360af5 100644
--- a/src/App.js
+++ b/src/App.js
@@ -46,7 +46,7 @@ export default {
this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
window.addEventListener('resize', this.updateMobileState)
},
- destroyed () {
+ unmounted () {
window.removeEventListener('resize', this.updateMobileState)
},
computed: {
diff --git a/src/App.scss b/src/App.scss
index bc027f4f..180c0daf 100644
--- a/src/App.scss
+++ b/src/App.scss
@@ -572,7 +572,7 @@ nav {
.fade-enter-active, .fade-leave-active {
transition: opacity .2s
}
-.fade-enter, .fade-leave-active {
+.fade-enter-from, .fade-leave-active {
opacity: 0
}
diff --git a/src/App.vue b/src/App.vue
index eb65b548..b18b3308 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,6 +1,6 @@
diff --git a/src/boot/after_store.js b/src/boot/after_store.js
index c4a0a800..76832708 100644
--- a/src/boot/after_store.js
+++ b/src/boot/after_store.js
@@ -1,7 +1,13 @@
-import Vue from 'vue'
-import VueRouter from 'vue-router'
-import routes from './routes'
+import { createApp } from 'vue'
+import { createRouter, createWebHistory } from 'vue-router'
+import vClickOutside from 'click-outside-vue3'
+
+import { FontAwesomeIcon, FontAwesomeLayers } from '@fortawesome/vue-fontawesome'
+
import App from '../App.vue'
+import routes from './routes'
+import VBodyScrollLock from 'src/directives/body_scroll_lock'
+
import { windowWidth } from '../services/window_utils/window_utils'
import { getOrCreateApp, getClientToken } from '../services/new_api/oauth.js'
import backendInteractorService from '../services/backend_interactor_service/backend_interactor_service.js'
@@ -367,25 +373,32 @@ const afterStoreSetup = async ({ store, i18n }) => {
getTOS({ store })
getStickers({ store })
- const router = new VueRouter({
- mode: 'history',
+ const router = createRouter({
+ history: createWebHistory(),
routes: routes(store),
scrollBehavior: (to, _from, savedPosition) => {
if (to.matched.some(m => m.meta.dontScroll)) {
return false
}
- return savedPosition || { x: 0, y: 0 }
+ return savedPosition || { left: 0, top: 0 }
}
})
- /* eslint-disable no-new */
- return new Vue({
- router,
- store,
- i18n,
- el: '#app',
- render: h => h(App)
- })
+ const app = createApp(App)
+
+ app.use(router)
+ app.use(store)
+ app.use(i18n)
+
+ app.use(vClickOutside)
+ app.use(VBodyScrollLock)
+
+ app.component('FAIcon', FontAwesomeIcon)
+ app.component('FALayers', FontAwesomeLayers)
+
+ app.mount('#app')
+
+ return app
}
export default afterStoreSetup
diff --git a/src/boot/routes.js b/src/boot/routes.js
index 1bc1f9f7..905ffe41 100644
--- a/src/boot/routes.js
+++ b/src/boot/routes.js
@@ -46,7 +46,7 @@ export default (store) => {
{ name: 'bookmarks', path: '/bookmarks', component: BookmarkTimeline },
{ name: 'conversation', path: '/notice/:id', component: ConversationPage, meta: { dontScroll: true } },
{ name: 'remote-user-profile-acct',
- path: '/remote-users/(@?):username([^/@]+)@:hostname([^/@]+)',
+ path: '/remote-users/:_(@)?:username([^/@]+)@:hostname([^/@]+)',
component: RemoteUserResolver,
beforeEnter: validateAuthenticatedRoute
},
@@ -69,7 +69,7 @@ export default (store) => {
{ name: 'search', path: '/search', component: Search, props: (route) => ({ query: route.query.query }) },
{ name: 'who-to-follow', path: '/who-to-follow', component: WhoToFollow, beforeEnter: validateAuthenticatedRoute },
{ name: 'about', path: '/about', component: About },
- { name: 'user-profile', path: '/(users/)?:name', component: UserProfile }
+ { name: 'user-profile', path: '/:_(users)?/:name', component: UserProfile }
]
if (store.state.instance.pleromaChatMessagesAvailable) {
diff --git a/src/components/async_component_error/async_component_error.vue b/src/components/async_component_error/async_component_error.vue
index b1b59638..26ab5d21 100644
--- a/src/components/async_component_error/async_component_error.vue
+++ b/src/components/async_component_error/async_component_error.vue
@@ -19,6 +19,7 @@
@@ -15,25 +14,27 @@