Skip to content

Commit

Permalink
fix: move page visibility check to composable
Browse files Browse the repository at this point in the history
Signed-off-by: Maksim Sukharev <[email protected]>
  • Loading branch information
Antreesy committed Sep 14, 2024
1 parent dd61c8e commit 60cb14e
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 59 deletions.
44 changes: 20 additions & 24 deletions src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { useActiveSession } from './composables/useActiveSession.js'
import { useHashCheck } from './composables/useHashCheck.js'
import { useIsInCall } from './composables/useIsInCall.js'
import { useSessionIssueHandler } from './composables/useSessionIssueHandler.js'
import { useWindowVisibility } from './composables/useWindowVisibility.ts'
import { CONVERSATION, PARTICIPANT } from './constants.js'
import Router from './router/router.js'
import BrowserStorage from './services/BrowserStorage.js'
Expand Down Expand Up @@ -71,6 +72,7 @@ export default {
isLeavingAfterSessionIssue: useSessionIssueHandler(),
isMobile: useIsMobile(),
isNextcloudTalkHashDirty: useHashCheck(),
isWindowVisible: useWindowVisibility(),
supportSessionState: useActiveSession(),
federationStore: useFederationStore(),
}
Expand All @@ -88,9 +90,6 @@ export default {
},
computed: {
windowIsVisible() {
return this.$store.getters.windowIsVisible()
},
isFullscreen() {
return this.$store.getters.isFullscreen()
},
Expand Down Expand Up @@ -189,7 +188,7 @@ export default {
watch: {
atLeastOneLastMessageIdChanged() {
if (this.windowIsVisible) {
if (this.isWindowVisible) {
return
}
Expand Down Expand Up @@ -220,7 +219,23 @@ export default {
toggle?.removeAttribute('data-theme-dark')
}
}
}
},
isWindowVisible(value) {
if (value) {
// Remove the potential "*" marker for unread chat messages
let title = this.getConversationName(this.token)
if (window.document.title.indexOf(t('spreed', 'Duplicate session')) === 0) {
title = t('spreed', 'Duplicate session')
}
this.setPageTitle(title, false)
} else {
// Copy the last message map to the saved version,
// this will be our reference to check if any chat got a new
// message since the last visit
this.savedLastMessageMap = this.lastMessageMap
}
},
},
beforeCreate() {
Expand Down Expand Up @@ -249,7 +264,6 @@ export default {
if (!getCurrentUser()) {
EventBus.off('should-refresh-conversations', this.debounceRefreshCurrentConversation)
}
document.removeEventListener('visibilitychange', this.changeWindowVisibility)
unsubscribe('notifications:action:execute', this.interceptNotificationActions)
Expand All @@ -272,7 +286,6 @@ export default {
}
window.addEventListener('resize', this.onResize)
document.addEventListener('visibilitychange', this.changeWindowVisibility)
this.onResize()
Expand Down Expand Up @@ -625,23 +638,6 @@ export default {
this.fetchSingleConversation(this.token)
},
changeWindowVisibility() {
this.$store.dispatch('setWindowVisibility', !document.hidden)
if (this.windowIsVisible) {
// Remove the potential "*" marker for unread chat messages
let title = this.getConversationName(this.token)
if (window.document.title.indexOf(t('spreed', 'Duplicate session')) === 0) {
title = t('spreed', 'Duplicate session')
}
this.setPageTitle(title, false)
} else {
// Copy the last message map to the saved version,
// this will be our reference to check if any chat got a new
// message since the last visit
this.savedLastMessageMap = this.lastMessageMap
}
},
/**
* Set the page title to the conversation name
*
Expand Down
15 changes: 8 additions & 7 deletions src/components/MessagesList/MessagesList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
<script>
import debounce from 'debounce'
import uniqueId from 'lodash/uniqueId.js'
import { computed } from 'vue'
import Message from 'vue-material-design-icons/Message.vue'
Expand All @@ -76,6 +77,7 @@ import LoadingPlaceholder from '../UIShared/LoadingPlaceholder.vue'
import TransitionWrapper from '../UIShared/TransitionWrapper.vue'
import { useIsInCall } from '../../composables/useIsInCall.js'
import { useWindowVisibility } from '../../composables/useWindowVisibility.ts'
import { ATTENDEE, CHAT, CONVERSATION } from '../../constants.js'
import { EventBus } from '../../services/EventBus.js'
import { useChatExtrasStore } from '../../stores/chatExtras.js'
Expand Down Expand Up @@ -121,10 +123,13 @@ export default {
emits: ['update:is-chat-scrolled-to-bottom'],
setup() {
setup(props) {
const isWindowVisible = useWindowVisibility()
const isChatVisible = computed(() => isWindowVisible.value && props.isVisible)
return {
isInCall: useIsInCall(),
chatExtrasStore: useChatExtrasStore(),
isChatVisible,
}
},
Expand Down Expand Up @@ -177,10 +182,6 @@ export default {
},
computed: {
isWindowVisible() {
return this.$store.getters.windowIsVisible() && this.isVisible
},
visualLastReadMessageId() {
return this.$store.getters.getVisualLastReadMessageId(this.token)
},
Expand Down Expand Up @@ -262,7 +263,7 @@ export default {
},
watch: {
isWindowVisible(visible) {
isChatVisible(visible) {
if (visible) {
this.onWindowFocus()
}
Expand Down Expand Up @@ -1107,7 +1108,7 @@ export default {
} else if (!this.isSticky) {
// Reading old messages
return
} else if (!this.isWindowVisible) {
} else if (!this.isChatVisible) {
const firstUnreadMessageHeight = this.$refs.scroller.scrollHeight - this.$refs.scroller.scrollTop - this.$refs.scroller.offsetHeight
const scrollBy = firstUnreadMessageHeight < 40 ? 10 : 40
// We jump half a message and stop autoscrolling, so the user can read up
Expand Down
9 changes: 8 additions & 1 deletion src/components/TopBar/CallTime.vue
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'
import NcPopover from '@nextcloud/vue/dist/Components/NcPopover.js'
import { useWindowVisibility } from '../../composables/useWindowVisibility.ts'
import { CALL } from '../../constants.js'
import { formattedTime } from '../../utils/formattedTime.ts'
Expand All @@ -93,6 +94,12 @@ export default {
},
},
setup() {
return {
isWindowVisible: useWindowVisibility(),
}
},
data() {
return {
callTime: undefined,
Expand Down Expand Up @@ -198,7 +205,7 @@ export default {
this.isCallDurationHintShown = true
// close the popover after 10 seconds
if (this.$store.getters.windowIsVisible()) {
if (this.isWindowVisible) {
setTimeout(() => {
this.showPopover = false
}, 10000)
Expand Down
5 changes: 3 additions & 2 deletions src/composables/useActiveSession.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { computed, onBeforeMount, onBeforeUnmount, ref, watch } from 'vue'

import { useIsInCall } from './useIsInCall.js'
import { useStore } from './useStore.js'
import { useWindowVisibility } from './useWindowVisibility.ts'
import { SESSION } from '../constants.js'
import { hasTalkFeature } from '../services/CapabilitiesManager.ts'
import { setSessionState } from '../services/participantsService.js'
Expand All @@ -31,7 +32,7 @@ export function useActiveSession() {
}

const isInCall = useIsInCall()
const windowIsVisible = computed(() => store.getters.windowIsVisible())
const isWindowVisible = useWindowVisibility()

const inactiveTimer = ref(null)
const currentState = ref(SESSION.STATE.ACTIVE)
Expand All @@ -41,7 +42,7 @@ export function useActiveSession() {
currentState.value = SESSION.STATE.ACTIVE
})

watch(windowIsVisible, (value) => {
watch(isWindowVisible, (value) => {
// Change state if tab is hidden or minimized
if (value) {
setSessionAsActive()
Expand Down
4 changes: 3 additions & 1 deletion src/composables/useGetParticipants.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { subscribe, unsubscribe } from '@nextcloud/event-bus'

import { useIsInCall } from './useIsInCall.js'
import { useStore } from './useStore.js'
import { useWindowVisibility } from './useWindowVisibility.ts'
import { CONVERSATION } from '../constants.js'
import { EventBus } from '../services/EventBus.js'

Expand All @@ -23,6 +24,7 @@ export function useGetParticipants(isActive = ref(true), isTopBar = true) {
const token = computed(() => store.getters.getToken())
const conversation = computed(() => store.getters.conversation(token.value))
const isInCall = useIsInCall()
const isWindowVisible = useWindowVisibility()
const isOneToOneConversation = computed(() => conversation.value?.type === CONVERSATION.TYPE.ONE_TO_ONE
|| conversation.value?.type === CONVERSATION.TYPE.ONE_TO_ONE_FORMER)
let fetchingParticipants = false
Expand Down Expand Up @@ -67,7 +69,7 @@ export function useGetParticipants(isActive = ref(true), isTopBar = true) {
return
}

if (store.getters.windowIsVisible() && (isInCall.value || !conversation.value?.hasCall)) {
if (isWindowVisible.value && (isInCall.value || !conversation.value?.hasCall)) {
debounceFastUpdateParticipants()
} else {
debounceSlowUpdateParticipants()
Expand Down
36 changes: 36 additions & 0 deletions src/composables/useWindowVisibility.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { createSharedComposable } from '@vueuse/core'
import { readonly, ref, onBeforeMount, onBeforeUnmount } from 'vue'
import type { Ref, DeepReadonly } from 'vue'

/**
* Composable to check whether the page is visible.
* @return {DeepReadonly<Ref<boolean>>} - computed boolean whether the page is visible
*/
function useWindowVisibilityComposable() {
const isWindowVisible = ref<boolean>(!document.hidden)

const changeWindowVisibility = () => {
isWindowVisible.value = !document.hidden
}

onBeforeMount(() => {
document.addEventListener('visibilitychange', changeWindowVisibility)
})

onBeforeUnmount(() => {
document.removeEventListener('visibilitychange', changeWindowVisibility)
})

return readonly(isWindowVisible)
}

/**
* Shared composable to check whether the page is visible.
* @return {DeepReadonly<Ref<boolean>>} - computed boolean whether the page is visible
*/
export const useWindowVisibility = createSharedComposable(useWindowVisibilityComposable)
24 changes: 0 additions & 24 deletions src/store/windowVisibilityStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,16 @@
*/

const state = {
visible: true,
fullscreen: false,
}

const getters = {
windowIsVisible: (state) => () => {
return state.visible
},
isFullscreen: (state) => () => {
return state.fullscreen
},
}

const mutations = {
/**
* Sets the current visibility state
*
* @param {object} state current store state;
* @param {boolean} value the value;
*/
setVisibility(state, value) {
state.visible = value
},

/**
* Sets the fullscreen state
*
Expand All @@ -40,16 +26,6 @@ const mutations = {
}

const actions = {
/**
* Sets the current visibility state
*
* @param {object} context the context object;
* @param {boolean} value the value;
*/
setWindowVisibility(context, value) {
context.commit('setVisibility', value)
},

/**
* Sets the fullscreen state
*
Expand Down

0 comments on commit 60cb14e

Please sign in to comment.