diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/App.js | 2 | ||||
| -rw-r--r-- | src/boot/after_store.js | 41 | ||||
| -rw-r--r-- | src/components/chat_title/chat_title.js | 5 | ||||
| -rw-r--r-- | src/components/emoji_input/emoji_input.js | 60 | ||||
| -rw-r--r-- | src/components/emoji_input/emoji_input.vue | 1 | ||||
| -rw-r--r-- | src/components/settings_modal/settings_modal.js | 16 | ||||
| -rw-r--r-- | src/components/settings_modal/settings_modal.vue | 32 | ||||
| -rw-r--r-- | src/components/settings_modal/tabs/version_tab.vue | 2 | ||||
| -rw-r--r-- | src/components/user_panel/user_panel.vue | 2 | ||||
| -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.js | 26 |
12 files changed, 96 insertions, 103 deletions
@@ -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: { |
