aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/App.js2
-rw-r--r--src/boot/after_store.js41
-rw-r--r--src/components/chat_title/chat_title.js5
-rw-r--r--src/components/emoji_input/emoji_input.js60
-rw-r--r--src/components/emoji_input/emoji_input.vue1
-rw-r--r--src/components/settings_modal/settings_modal.js16
-rw-r--r--src/components/settings_modal/settings_modal.vue32
-rw-r--r--src/components/settings_modal/tabs/version_tab.vue2
-rw-r--r--src/components/user_panel/user_panel.vue2
-rw-r--r--src/hocs/with_load_more/with_load_more.jsx (renamed from src/hocs/with_load_more/with_load_more.js)7
-rw-r--r--src/hocs/with_subscription/with_subscription.jsx (renamed from src/hocs/with_subscription/with_subscription.js)5
-rw-r--r--src/main.js26
12 files changed, 96 insertions, 103 deletions
diff --git a/src/App.js b/src/App.js
index 1ca029b6..f886d7cb 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/boot/after_store.js b/src/boot/after_store.js
index 45090e5d..6f84f686 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 VueClickOutside from 'v-click-outside'
+
+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'
@@ -366,25 +372,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(VueClickOutside)
+ app.use(VBodyScrollLock)
+
+ app.component('FAIcon', FontAwesomeIcon)
+ app.component('FALayers', FontAwesomeLayers)
+
+ app.mount('#app')
+
+ return app
}
export default afterStoreSetup
diff --git a/src/components/chat_title/chat_title.js b/src/components/chat_title/chat_title.js
index edfbe7a4..1da04d4b 100644
--- a/src/components/chat_title/chat_title.js
+++ b/src/components/chat_title/chat_title.js
@@ -1,8 +1,7 @@
-import Vue from 'vue'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
import UserAvatar from '../user_avatar/user_avatar.vue'
-export default Vue.component('chat-title', {
+export default {
name: 'ChatTitle',
components: {
UserAvatar
@@ -23,4 +22,4 @@ export default Vue.component('chat-title', {
return generateProfileLink(user.id, user.screen_name)
}
}
-})
+}
diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js
index dc03bc9f..c4d235c0 100644
--- a/src/components/emoji_input/emoji_input.js
+++ b/src/components/emoji_input/emoji_input.js
@@ -57,6 +57,7 @@ const EmojiInput = {
required: true,
type: Function
},
+ // TODO VUE3: change to modelValue, change 'input' event to 'input'
value: {
/**
* Used for v-model
@@ -143,32 +144,31 @@ const EmojiInput = {
}
},
mounted () {
- const slots = this.$slots.default
- if (!slots || slots.length === 0) return
- const input = slots.find(slot => ['input', 'textarea'].includes(slot.tag))
+ const { root } = this.$refs
+ const input = root.querySelector('.emoji-input > input') || root.querySelector('.emoji-input > textarea')
if (!input) return
this.input = input
this.resize()
- input.elm.addEventListener('blur', this.onBlur)
- input.elm.addEventListener('focus', this.onFocus)
- input.elm.addEventListener('paste', this.onPaste)
- input.elm.addEventListener('keyup', this.onKeyUp)
- input.elm.addEventListener('keydown', this.onKeyDown)
- input.elm.addEventListener('click', this.onClickInput)
- input.elm.addEventListener('transitionend', this.onTransition)
- input.elm.addEventListener('input', this.onInput)
+ input.addEventListener('blur', this.onBlur)
+ input.addEventListener('focus', this.onFocus)
+ input.addEventListener('paste', this.onPaste)
+ input.addEventListener('keyup', this.onKeyUp)
+ input.addEventListener('keydown', this.onKeyDown)
+ input.addEventListener('click', this.onClickInput)
+ input.addEventListener('transitionend', this.onTransition)
+ input.addEventListener('input', this.onInput)
},
unmounted () {
const { input } = this
if (input) {
- input.elm.removeEventListener('blur', this.onBlur)
- input.elm.removeEventListener('focus', this.onFocus)
- input.elm.removeEventListener('paste', this.onPaste)
- input.elm.removeEventListener('keyup', this.onKeyUp)
- input.elm.removeEventListener('keydown', this.onKeyDown)
- input.elm.removeEventListener('click', this.onClickInput)
- input.elm.removeEventListener('transitionend', this.onTransition)
- input.elm.removeEventListener('input', this.onInput)
+ input.removeEventListener('blur', this.onBlur)
+ input.removeEventListener('focus', this.onFocus)
+ input.removeEventListener('paste', this.onPaste)
+ input.removeEventListener('keyup', this.onKeyUp)
+ input.removeEventListener('keydown', this.onKeyDown)
+ input.removeEventListener('click', this.onClickInput)
+ input.removeEventListener('transitionend', this.onTransition)
+ input.removeEventListener('input', this.onInput)
}
},
watch: {
@@ -216,7 +216,7 @@ const EmojiInput = {
}, 0)
},
togglePicker () {
- this.input.elm.focus()
+ this.input.focus()
this.showPicker = !this.showPicker
if (this.showPicker) {
this.scrollIntoView()
@@ -262,13 +262,13 @@ const EmojiInput = {
this.$emit('input', newValue)
const position = this.caret + (insertion + spaceAfter + spaceBefore).length
if (!keepOpen) {
- this.input.elm.focus()
+ this.input.focus()
}
this.$nextTick(function () {
// Re-focus inputbox after clicking suggestion
// Set selection right after the replacement instead of the very end
- this.input.elm.setSelectionRange(position, position)
+ // this.input.setSelectionRange(position, position)
this.caret = position
})
},
@@ -285,9 +285,9 @@ const EmojiInput = {
this.$nextTick(function () {
// Re-focus inputbox after clicking suggestion
- this.input.elm.focus()
+ this.input.focus()
// Set selection right after the replacement instead of the very end
- this.input.elm.setSelectionRange(position, position)
+ this.input.setSelectionRange(position, position)
this.caret = position
})
e.preventDefault()
@@ -349,7 +349,7 @@ const EmojiInput = {
}
this.$nextTick(() => {
- const { offsetHeight } = this.input.elm
+ const { offsetHeight } = this.input
const { picker } = this.$refs
const pickerBottom = picker.$el.getBoundingClientRect().bottom
if (pickerBottom > window.innerHeight) {
@@ -414,8 +414,8 @@ const EmojiInput = {
// Scroll the input element to the position of the cursor
this.$nextTick(() => {
- this.input.elm.blur()
- this.input.elm.focus()
+ this.input.blur()
+ this.input.focus()
})
}
// Disable suggestions hotkeys if suggestions are hidden
@@ -444,7 +444,7 @@ const EmojiInput = {
// de-focuses the element (i.e. default browser behavior)
if (key === 'Escape') {
if (!this.temporarilyHideSuggestions) {
- this.input.elm.focus()
+ this.input.focus()
}
}
@@ -480,7 +480,7 @@ const EmojiInput = {
if (!panel) return
const picker = this.$refs.picker.$el
const panelBody = this.$refs['panel-body']
- const { offsetHeight, offsetTop } = this.input.elm
+ const { offsetHeight, offsetTop } = this.input
const offsetBottom = offsetTop + offsetHeight
this.setPlacement(panelBody, panel, offsetBottom)
@@ -494,7 +494,7 @@ const EmojiInput = {
if (this.placement === 'top' || (this.placement === 'auto' && this.overflowsBottom(container))) {
target.style.top = 'auto'
- target.style.bottom = this.input.elm.offsetHeight + 'px'
+ target.style.bottom = this.input.offsetHeight + 'px'
}
},
overflowsBottom (el) {
diff --git a/src/components/emoji_input/emoji_input.vue b/src/components/emoji_input/emoji_input.vue
index ad62484d..e6f9a9d3 100644
--- a/src/components/emoji_input/emoji_input.vue
+++ b/src/components/emoji_input/emoji_input.vue
@@ -3,6 +3,7 @@
v-click-outside="onClickOutside"
class="emoji-input"
:class="{ 'with-picker': !hideEmojiButton }"
+ ref='root'
>
<slot />
<template v-if="enableEmojiPicker">
diff --git a/src/components/settings_modal/settings_modal.js b/src/components/settings_modal/settings_modal.js
index 04043483..7f97fa08 100644
--- a/src/components/settings_modal/settings_modal.js
+++ b/src/components/settings_modal/settings_modal.js
@@ -1,7 +1,7 @@
+import { defineAsyncComponent } from 'vue'
import Modal from 'src/components/modal/modal.vue'
import PanelLoading from 'src/components/panel_loading/panel_loading.vue'
import AsyncComponentError from 'src/components/async_component_error/async_component_error.vue'
-import getResettableAsyncComponent from 'src/services/resettable_async_component.js'
import Popover from '../popover/popover.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { cloneDeep } from 'lodash'
@@ -51,14 +51,12 @@ const SettingsModal = {
components: {
Modal,
Popover,
- SettingsModalContent: getResettableAsyncComponent(
- () => import('./settings_modal_content.vue'),
- {
- loading: PanelLoading,
- error: AsyncComponentError,
- delay: 0
- }
- )
+ SettingsModalContent: defineAsyncComponent({
+ loader: () => import('./settings_modal_content.vue'),
+ loadingComponent: PanelLoading,
+ errorComponent: AsyncComponentError,
+ delay: 0
+ })
},
methods: {
closeModal () {
diff --git a/src/components/settings_modal/settings_modal.vue b/src/components/settings_modal/settings_modal.vue
index c7da5433..12519925 100644
--- a/src/components/settings_modal/settings_modal.vue
+++ b/src/components/settings_modal/settings_modal.vue
@@ -11,22 +11,24 @@
{{ $t('settings.settings') }}
</span>
<transition name="fade">
- <template v-if="currentSaveStateNotice">
- <div
- v-if="currentSaveStateNotice.error"
- class="alert error"
- @click.prevent
- >
- {{ $t('settings.saving_err') }}
- </div>
+ <template>
+ <template v-if="currentSaveStateNotice">
+ <div
+ v-if="currentSaveStateNotice.error"
+ class="alert error"
+ @click.prevent
+ >
+ {{ $t('settings.saving_err') }}
+ </div>
- <div
- v-if="!currentSaveStateNotice.error"
- class="alert transparent"
- @click.prevent
- >
- {{ $t('settings.saving_ok') }}
- </div>
+ <div
+ v-if="!currentSaveStateNotice.error"
+ class="alert transparent"
+ @click.prevent
+ >
+ {{ $t('settings.saving_ok') }}
+ </div>
+ </template>
</template>
</transition>
<button
diff --git a/src/components/settings_modal/tabs/version_tab.vue b/src/components/settings_modal/tabs/version_tab.vue
index d35ff25e..0330d49f 100644
--- a/src/components/settings_modal/tabs/version_tab.vue
+++ b/src/components/settings_modal/tabs/version_tab.vue
@@ -28,4 +28,4 @@
</div>
</div>
</template>
-<script src="./version_tab.js">
+<script src="./version_tab.js" />
diff --git a/src/components/user_panel/user_panel.vue b/src/components/user_panel/user_panel.vue
index 5685916a..50949b98 100644
--- a/src/components/user_panel/user_panel.vue
+++ b/src/components/user_panel/user_panel.vue
@@ -2,7 +2,7 @@
<div class="user-panel">
<div
v-if="signedIn"
- key="user-panel"
+ key="user-panel-signed"
class="panel panel-default signed-in"
>
<UserCard
diff --git a/src/hocs/with_load_more/with_load_more.js b/src/hocs/with_load_more/with_load_more.jsx
index 671b2b6f..7f491558 100644
--- a/src/hocs/with_load_more/with_load_more.js
+++ b/src/hocs/with_load_more/with_load_more.jsx
@@ -1,4 +1,3 @@
-import Vue from 'vue'
import isEmpty from 'lodash/isEmpty'
import { getComponentProps } from '../../services/component_utils/component_utils'
import './with_load_more.scss'
@@ -23,7 +22,7 @@ const withLoadMore = ({
const originalProps = Object.keys(getComponentProps(WrappedComponent))
const props = originalProps.filter(v => v !== childPropName).concat(additionalPropNames)
- return Vue.component('withLoadMore', {
+ return {
props,
data () {
return {
@@ -39,7 +38,7 @@ const withLoadMore = ({
this.fetchEntries()
}
},
- destroyed () {
+ unmounted () {
window.removeEventListener('scroll', this.scrollLoad)
destroy && destroy(this.$props, this.$store)
},
@@ -106,7 +105,7 @@ const withLoadMore = ({
</div>
)
}
- })
+ }
}
export default withLoadMore
diff --git a/src/hocs/with_subscription/with_subscription.js b/src/hocs/with_subscription/with_subscription.jsx
index b1244276..7e590f73 100644
--- a/src/hocs/with_subscription/with_subscription.js
+++ b/src/hocs/with_subscription/with_subscription.jsx
@@ -1,4 +1,3 @@
-import Vue from 'vue'
import isEmpty from 'lodash/isEmpty'
import { getComponentProps } from '../../services/component_utils/component_utils'
import './with_subscription.scss'
@@ -22,7 +21,7 @@ const withSubscription = ({
const originalProps = Object.keys(getComponentProps(WrappedComponent))
const props = originalProps.filter(v => v !== childPropName).concat(additionalPropNames)
- return Vue.component('withSubscription', {
+ return {
props: [
...props,
'refresh' // boolean saying to force-fetch data whenever created
@@ -88,7 +87,7 @@ const withSubscription = ({
)
}
}
- })
+ }
}
export default withSubscription
diff --git a/src/main.js b/src/main.js
index e1cac748..b7232c2e 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,6 +1,4 @@
-import Vue from 'vue'
-import VueRouter from 'vue-router'
-import Vuex from 'vuex'
+import { createStore } from 'vuex'
import 'custom-event-polyfill'
import './lib/event_target_polyfill.js'
@@ -21,34 +19,18 @@ import pollsModule from './modules/polls.js'
import postStatusModule from './modules/postStatus.js'
import chatsModule from './modules/chats.js'
-import VueI18n from 'vue-i18n'
+import { createI18n } from 'vue-i18n'
import createPersistedState from './lib/persisted_state.js'
import pushNotifications from './lib/push_notifications_plugin.js'
import messages from './i18n/messages.js'
-import VueClickOutside from 'v-click-outside'
-import PortalVue from 'portal-vue'
-import VBodyScrollLock from './directives/body_scroll_lock'
-
-import { FontAwesomeIcon, FontAwesomeLayers } from '@fortawesome/vue-fontawesome'
-
import afterStoreSetup from './boot/after_store.js'
const currentLocale = (window.navigator.language || 'en').split('-')[0]
-Vue.use(Vuex)
-Vue.use(VueRouter)
-Vue.use(VueI18n)
-Vue.use(VueClickOutside)
-Vue.use(PortalVue)
-Vue.use(VBodyScrollLock)
-
-Vue.component('FAIcon', FontAwesomeIcon)
-Vue.component('FALayers', FontAwesomeLayers)
-
-const i18n = new VueI18n({
+const i18n = createI18n({
// By default, use the browser locale, we will update it if neccessary
locale: 'en',
fallbackLocale: 'en',
@@ -75,7 +57,7 @@ const persistedStateOptions = {
console.error(e)
storageError = true
}
- const store = new Vuex.Store({
+ const store = createStore({
modules: {
i18n: {
getters: {