269 lines
8.6 KiB
JavaScript
269 lines
8.6 KiB
JavaScript
import { throttle } from 'lodash'
|
|
import { defineAsyncComponent } from 'vue'
|
|
import { mapGetters } from 'vuex'
|
|
|
|
import DesktopNav from './components/desktop_nav/desktop_nav.vue'
|
|
import EditStatusModal from './components/edit_status_modal/edit_status_modal.vue'
|
|
import FeaturesPanel from './components/features_panel/features_panel.vue'
|
|
import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue'
|
|
import InstanceSpecificPanel from './components/instance_specific_panel/instance_specific_panel.vue'
|
|
import MediaModal from './components/media_modal/media_modal.vue'
|
|
import MobileNav from './components/mobile_nav/mobile_nav.vue'
|
|
import MobilePostStatusButton from './components/mobile_post_status_button/mobile_post_status_button.vue'
|
|
import NavPanel from './components/nav_panel/nav_panel.vue'
|
|
import PostStatusModal from './components/post_status_modal/post_status_modal.vue'
|
|
import ShoutPanel from './components/shout_panel/shout_panel.vue'
|
|
import SideDrawer from './components/side_drawer/side_drawer.vue'
|
|
import StatusHistoryModal from './components/status_history_modal/status_history_modal.vue'
|
|
import UserPanel from './components/user_panel/user_panel.vue'
|
|
import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue'
|
|
import WhoToFollowPanel from './components/who_to_follow_panel/who_to_follow_panel.vue'
|
|
import { getOrCreateServiceWorker } from './services/sw/sw'
|
|
import { windowHeight, windowWidth } from './services/window_utils/window_utils'
|
|
import { useInterfaceStore } from './stores/interface'
|
|
import { useShoutStore } from './stores/shout'
|
|
|
|
export default {
|
|
name: 'app',
|
|
components: {
|
|
UserPanel,
|
|
NavPanel,
|
|
Notifications: defineAsyncComponent(
|
|
() => import('./components/notifications/notifications.vue'),
|
|
),
|
|
InstanceSpecificPanel,
|
|
FeaturesPanel,
|
|
WhoToFollowPanel,
|
|
ShoutPanel,
|
|
MediaModal,
|
|
SideDrawer,
|
|
MobilePostStatusButton,
|
|
MobileNav,
|
|
DesktopNav,
|
|
SettingsModal: defineAsyncComponent(
|
|
() => import('./components/settings_modal/settings_modal.vue'),
|
|
),
|
|
UpdateNotification: defineAsyncComponent(
|
|
() => import('./components/update_notification/update_notification.vue'),
|
|
),
|
|
UserReportingModal,
|
|
PostStatusModal,
|
|
EditStatusModal,
|
|
StatusHistoryModal,
|
|
GlobalNoticeList,
|
|
},
|
|
data: () => ({
|
|
mobileActivePanel: 'timeline',
|
|
}),
|
|
watch: {
|
|
themeApplied() {
|
|
this.removeSplash()
|
|
},
|
|
currentTheme() {
|
|
this.setThemeBodyClass()
|
|
},
|
|
layoutType() {
|
|
document.getElementById('modal').classList = ['-' + this.layoutType]
|
|
},
|
|
},
|
|
created() {
|
|
// Load the locale from the storage
|
|
const val = this.$store.getters.mergedConfig.interfaceLanguage
|
|
this.$store.dispatch('setOption', { name: 'interfaceLanguage', value: val })
|
|
document.getElementById('modal').classList = ['-' + this.layoutType]
|
|
|
|
// Create bound handlers
|
|
this.updateScrollState = throttle(this.scrollHandler, 200)
|
|
this.updateMobileState = throttle(this.resizeHandler, 200)
|
|
},
|
|
mounted() {
|
|
window.addEventListener('resize', this.updateMobileState)
|
|
this.scrollParent.addEventListener('scroll', this.updateScrollState)
|
|
|
|
if (useInterfaceStore().themeApplied) {
|
|
this.setThemeBodyClass()
|
|
this.removeSplash()
|
|
}
|
|
getOrCreateServiceWorker()
|
|
},
|
|
unmounted() {
|
|
window.removeEventListener('resize', this.updateMobileState)
|
|
this.scrollParent.removeEventListener('scroll', this.updateScrollState)
|
|
},
|
|
computed: {
|
|
themeApplied() {
|
|
return useInterfaceStore().themeApplied
|
|
},
|
|
currentTheme() {
|
|
if (useInterfaceStore().styleDataUsed) {
|
|
const styleMeta = useInterfaceStore().styleDataUsed.find(
|
|
(x) => x.component === '@meta',
|
|
)
|
|
|
|
if (styleMeta !== undefined) {
|
|
return styleMeta.directives.name.replaceAll(' ', '-').toLowerCase()
|
|
}
|
|
}
|
|
|
|
return 'stock'
|
|
},
|
|
layoutModalClass() {
|
|
return '-' + this.layoutType
|
|
},
|
|
classes() {
|
|
return [
|
|
{
|
|
'-reverse': this.reverseLayout,
|
|
'-no-sticky-headers': this.noSticky,
|
|
'-has-new-post-button': this.newPostButtonShown,
|
|
},
|
|
'-' + this.layoutType,
|
|
]
|
|
},
|
|
navClasses() {
|
|
const { navbarColumnStretch } = this.$store.getters.mergedConfig
|
|
return [
|
|
'-' + this.layoutType,
|
|
...(navbarColumnStretch ? ['-column-stretch'] : []),
|
|
]
|
|
},
|
|
currentUser() {
|
|
return this.$store.state.users.currentUser
|
|
},
|
|
userBackground() {
|
|
return this.currentUser.background_image
|
|
},
|
|
instanceBackground() {
|
|
return this.mergedConfig.hideInstanceWallpaper
|
|
? null
|
|
: this.$store.state.instance.background
|
|
},
|
|
background() {
|
|
return this.userBackground || this.instanceBackground
|
|
},
|
|
bgStyle() {
|
|
if (this.background) {
|
|
return {
|
|
'--body-background-image': `url(${this.background})`,
|
|
}
|
|
}
|
|
},
|
|
shout() {
|
|
return useShoutStore().joined
|
|
},
|
|
suggestionsEnabled() {
|
|
return this.$store.state.instance.suggestionsEnabled
|
|
},
|
|
showInstanceSpecificPanel() {
|
|
return (
|
|
this.$store.state.instance.showInstanceSpecificPanel &&
|
|
!this.$store.getters.mergedConfig.hideISP &&
|
|
this.$store.state.instance.instanceSpecificPanelContent
|
|
)
|
|
},
|
|
isChats() {
|
|
return this.$route.name === 'chat' || this.$route.name === 'chats'
|
|
},
|
|
isListEdit() {
|
|
return this.$route.name === 'lists-edit'
|
|
},
|
|
newPostButtonShown() {
|
|
if (this.isChats) return false
|
|
if (this.isListEdit) return false
|
|
return (
|
|
this.$store.getters.mergedConfig.alwaysShowNewPostButton ||
|
|
this.layoutType === 'mobile'
|
|
)
|
|
},
|
|
showFeaturesPanel() {
|
|
return this.$store.state.instance.showFeaturesPanel
|
|
},
|
|
editingAvailable() {
|
|
return this.$store.state.instance.editingAvailable
|
|
},
|
|
shoutboxPosition() {
|
|
return this.$store.getters.mergedConfig.alwaysShowNewPostButton || false
|
|
},
|
|
hideShoutbox() {
|
|
return this.$store.getters.mergedConfig.hideShoutbox
|
|
},
|
|
layoutType() {
|
|
return useInterfaceStore().layoutType
|
|
},
|
|
privateMode() {
|
|
return this.$store.state.instance.private
|
|
},
|
|
reverseLayout() {
|
|
const { thirdColumnMode, sidebarRight: reverseSetting } =
|
|
this.$store.getters.mergedConfig
|
|
if (this.layoutType !== 'wide') {
|
|
return reverseSetting
|
|
} else {
|
|
return thirdColumnMode === 'notifications'
|
|
? reverseSetting
|
|
: !reverseSetting
|
|
}
|
|
},
|
|
noSticky() {
|
|
return this.$store.getters.mergedConfig.disableStickyHeaders
|
|
},
|
|
showScrollbars() {
|
|
return this.$store.getters.mergedConfig.showScrollbars
|
|
},
|
|
scrollParent() {
|
|
return window /* this.$refs.appContentRef */
|
|
},
|
|
...mapGetters(['mergedConfig']),
|
|
},
|
|
methods: {
|
|
resizeHandler() {
|
|
useInterfaceStore().setLayoutWidth(windowWidth())
|
|
useInterfaceStore().setLayoutHeight(windowHeight())
|
|
},
|
|
scrollHandler() {
|
|
const scrollPosition =
|
|
this.scrollParent === window
|
|
? window.scrollY
|
|
: this.scrollParent.scrollTop
|
|
|
|
if (scrollPosition != 0) {
|
|
this.$refs.appContentRef.classList.add(['-scrolled'])
|
|
} else {
|
|
this.$refs.appContentRef.classList.remove(['-scrolled'])
|
|
}
|
|
},
|
|
setThemeBodyClass() {
|
|
const themeName = this.currentTheme
|
|
const classList = Array.from(document.body.classList)
|
|
const oldTheme = classList.filter((c) => c.startsWith('theme-'))
|
|
|
|
if (themeName !== null && themeName !== '') {
|
|
const newTheme = `theme-${themeName.toLowerCase()}`
|
|
|
|
// remove old theme reference if there are any
|
|
if (oldTheme.length) {
|
|
document.body.classList.replace(oldTheme[0], newTheme)
|
|
} else {
|
|
document.body.classList.add(newTheme)
|
|
}
|
|
} else {
|
|
// remove theme reference if non-V3 theme is used
|
|
document.body.classList.remove(...oldTheme)
|
|
}
|
|
},
|
|
removeSplash() {
|
|
document.querySelector('#status').textContent = this.$t(
|
|
'splash.fun_' + Math.ceil(Math.random() * 4),
|
|
)
|
|
const splashscreenRoot = document.querySelector('#splash')
|
|
splashscreenRoot.addEventListener('transitionend', () => {
|
|
splashscreenRoot.remove()
|
|
})
|
|
setTimeout(() => {
|
|
splashscreenRoot.remove() // forcibly remove it, should fix my plasma browser widget t. HJ
|
|
}, 600)
|
|
splashscreenRoot.classList.add('hidden')
|
|
document.querySelector('#app').classList.remove('hidden')
|
|
},
|
|
},
|
|
}
|