summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGrigorii K. Shartsev <me@shgk.me>2024-05-16 17:59:29 +0200
committerMaksim Sukharev <antreesy.web@gmail.com>2024-06-28 11:03:31 +0200
commitb71a50cf29a27460d6c622a2368be937e972cc0e (patch)
treef080aa1e1376148cb745a00e3d03e96cedcff192
parent39d2d1637a1ebe50fe08cc60473785fd0ef2b3c4 (diff)
fix(RightSidebar): use new open state to fix focus trap on mobile
Signed-off-by: Grigorii K. Shartsev <me@shgk.me>
-rw-r--r--src/components/RightSidebar/RightSidebar.vue119
-rw-r--r--src/components/TopBar/TopBar.vue111
2 files changed, 120 insertions, 110 deletions
diff --git a/src/components/RightSidebar/RightSidebar.vue b/src/components/RightSidebar/RightSidebar.vue
index 435240cd6..8efc1c03a 100644
--- a/src/components/RightSidebar/RightSidebar.vue
+++ b/src/components/RightSidebar/RightSidebar.vue
@@ -4,13 +4,27 @@
-->
<template>
- <NcAppSidebar v-show="opened"
+ <NcAppSidebar v-if="token"
+ :open="opened"
:name="conversation.displayName"
:title="conversation.displayName"
:active.sync="activeTab"
:class="'active-tab-' + activeTab"
+ :toggle-classes="{ 'chat-button-sidebar-toggle': isInCall }"
+ :toggle-attrs="isInCall ? inCallToggleAttrs : undefined"
+ @update:open="handleUpdateOpen"
+ @update:active="handleUpdateActive"
@closed="handleClosed"
@close="handleClose">
+ <!-- Use a custom icon when sidebar is used for chat messages during the call -->
+ <template v-if="isInCall" #toggle-icon>
+ <MessageText :size="20" />
+ <NcCounterBubble v-if="unreadMessagesCounter > 0"
+ class="chat-button__unread-messages-counter"
+ :type="hasUnreadMentions ? 'highlighted' : 'outlined'">
+ {{ unreadMessagesCounter }}
+ </NcCounterBubble>
+ </template>
<template #description>
<LobbyStatus v-if="canFullModerate && hasLobbyEnabled" :token="token" />
</template>
@@ -94,13 +108,16 @@ import DotsCircle from 'vue-material-design-icons/DotsCircle.vue'
import FolderMultipleImage from 'vue-material-design-icons/FolderMultipleImage.vue'
import InformationOutline from 'vue-material-design-icons/InformationOutline.vue'
import Message from 'vue-material-design-icons/Message.vue'
+import MessageText from 'vue-material-design-icons/MessageText.vue'
+import { showMessage } from '@nextcloud/dialogs'
import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus'
import { t } from '@nextcloud/l10n'
import NcAppSidebar from '@nextcloud/vue/dist/Components/NcAppSidebar.js'
import NcAppSidebarTab from '@nextcloud/vue/dist/Components/NcAppSidebarTab.js'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
+import NcCounterBubble from '@nextcloud/vue/dist/Components/NcCounterBubble.js'
import BreakoutRoomsTab from './BreakoutRooms/BreakoutRoomsTab.vue'
import LobbyStatus from './LobbyStatus.vue'
@@ -123,6 +140,7 @@ export default {
NcAppSidebar,
NcAppSidebarTab,
NcButton,
+ NcCounterBubble,
ParticipantsTab,
SetGuestUsername,
SharedItemsTab,
@@ -134,6 +152,7 @@ export default {
FolderMultipleImage,
InformationOutline,
Message,
+ MessageText,
},
props: {
@@ -147,6 +166,7 @@ export default {
return {
activeTab: 'participants',
contactsLoading: false,
+ unreadNotificationHandle: null,
}
},
@@ -155,7 +175,7 @@ export default {
return this.$store.getters.getSidebarStatus
},
opened() {
- return !!this.token && !this.isInLobby && this.show
+ return !this.isInLobby && this.show
},
token() {
return this.$store.getters.getToken()
@@ -257,6 +277,21 @@ export default {
breakoutRoomsText() {
return t('spreed', 'Breakout rooms')
},
+
+ unreadMessagesCounter() {
+ return this.conversation.unreadMessages
+ },
+ hasUnreadMentions() {
+ return this.conversation.unreadMention
+ },
+
+ inCallToggleAttrs() {
+ return {
+ 'data-theme-dark': true,
+ 'aria-label': t('spreed', 'Open chat'),
+ title: t('spreed', 'Open chat')
+ }
+ },
},
watch: {
@@ -287,6 +322,27 @@ export default {
},
},
+ unreadMessagesCounter(newValue, oldValue) {
+ if (!this.isInCall || this.opened) {
+ return
+ }
+
+ // new messages arrived
+ if (newValue > 0 && oldValue === 0 && !this.hasUnreadMentions) {
+ this.notifyUnreadMessages(t('spreed', 'You have new unread messages in the chat.'))
+ }
+ },
+
+ hasUnreadMentions(newValue) {
+ if (!this.isInCall || this.opened) {
+ return
+ }
+
+ if (newValue) {
+ this.notifyUnreadMessages(t('spreed', 'You have been mentioned in the chat.'))
+ }
+ },
+
isInCall(newValue) {
if (newValue) {
// Set 'chat' tab as active, and switch to it if sidebar is open
@@ -294,6 +350,9 @@ export default {
return
}
+ // discard notification if the call ends
+ this.notifyUnreadMessages(null)
+
// If 'chat' tab wasn't active, leave it as is
if (this.activeTab !== 'chat') {
return
@@ -335,11 +394,30 @@ export default {
methods: {
t,
+
+ openSidebar() {
+ // In call by default open on chat
+ if (this.isInCall) {
+ this.activeTab = 'chat'
+ }
+
+ this.$store.dispatch('showSidebar')
+ BrowserStorage.setItem('sidebarOpen', 'true')
+ },
+
handleClose() {
this.$store.dispatch('hideSidebar')
BrowserStorage.setItem('sidebarOpen', 'false')
},
+ handleUpdateOpen(open) {
+ if (open) {
+ this.openSidebar()
+ } else {
+ this.handleClose()
+ }
+ },
+
handleUpdateActive(active) {
this.activeTab = active
},
@@ -351,6 +429,21 @@ export default {
handleClosed() {
emit('files:sidebar:closed', {})
},
+
+ notifyUnreadMessages(message) {
+ if (this.unreadNotificationHandle) {
+ this.unreadNotificationHandle.hideToast()
+ this.unreadNotificationHandle = null
+ }
+ if (message) {
+ this.unreadNotificationHandle = showMessage(message, {
+ onClick: () => {
+ this.activeTab = 'chat'
+ this.openSidebar()
+ },
+ })
+ }
+ },
},
}
</script>
@@ -391,4 +484,26 @@ export default {
height: 100%;
}
+.chat-button__unread-messages-counter {
+ position: absolute;
+ bottom: 2px;
+ right: 2px;
+ pointer-events: none;
+
+ &.counter-bubble__counter--highlighted {
+ color: var(--color-primary-text);
+ }
+}
+</style>
+
+<style lang="scss">
+/*
+ * NcAppSidebar toggle it rendered on the page outside the sidebar element, so we need global styles here.
+ * It is _quite_ safe, as chat-button-sidebar-toggle class is defined here manually, not an internal class.
+ */
+.chat-button-sidebar-toggle {
+ position: relative;
+ // Allow unread counter to overflow rounded button
+ overflow: visible !important;
+}
</style>
diff --git a/src/components/TopBar/TopBar.vue b/src/components/TopBar/TopBar.vue
index fee8bc701..14d25316d 100644
--- a/src/components/TopBar/TopBar.vue
+++ b/src/components/TopBar/TopBar.vue
@@ -80,38 +80,6 @@
<CallButton shrink-on-mobile :is-screensharing="!!localMediaModel.attributes.localScreen" />
- <!-- sidebar toggle -->
- <template v-if="showOpenSidebarButton">
- <!-- in chat: open last tab -->
- <NcButton v-if="!isInCall"
- :aria-label="t('spreed', 'Open sidebar')"
- :title="t('spreed', 'Open sidebar')"
- close-after-click="true"
- type="tertiary"
- @click="openSidebar">
- <template #icon>
- <MenuIcon :size="20" />
- </template>
- </NcButton>
-
- <!-- in call: open chat tab -->
- <NcButton v-else
- :aria-label="t('spreed', 'Open chat')"
- :title="t('spreed', 'Open chat')"
- class="chat-button"
- type="tertiary"
- @click="openSidebar('chat')">
- <template #icon>
- <MessageText :size="20" />
- <NcCounterBubble v-if="unreadMessagesCounter > 0"
- class="chat-button__unread-messages-counter"
- :type="hasUnreadMentions ? 'highlighted' : 'outlined'">
- {{ unreadMessagesCounter }}
- </NcCounterBubble>
- </template>
- </NcButton>
- </template>
-
<!-- Breakout rooms editor -->
<BreakoutRoomsEditor v-if="showBreakoutRoomsEditor"
:token="token"
@@ -121,15 +89,11 @@
<script>
import AccountMultiple from 'vue-material-design-icons/AccountMultiple.vue'
-import MenuIcon from 'vue-material-design-icons/Menu.vue'
-import MessageText from 'vue-material-design-icons/MessageText.vue'
-import { showMessage } from '@nextcloud/dialogs'
import { emit } from '@nextcloud/event-bus'
import { t, n } from '@nextcloud/l10n'
import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
-import NcCounterBubble from '@nextcloud/vue/dist/Components/NcCounterBubble.js'
import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip.js'
import richEditor from '@nextcloud/vue/dist/Mixins/richEditor.js'
@@ -163,13 +127,10 @@ export default {
ConversationIcon,
TopBarMediaControls,
NcButton,
- NcCounterBubble,
TopBarMenu,
ReactionMenu,
// Icons
AccountMultiple,
- MenuIcon,
- MessageText,
},
mixins: [richEditor],
@@ -199,7 +160,6 @@ export default {
data: () => {
return {
- unreadNotificationHandle: null,
showBreakoutRoomsEditor: false,
}
},
@@ -209,10 +169,6 @@ export default {
return this.$store.getters.getMainContainerSelector()
},
- showOpenSidebarButton() {
- return !this.$store.getters.getSidebarStatus
- },
-
isOneToOneConversation() {
return this.conversation.type === CONVERSATION.TYPE.ONE_TO_ONE
|| this.conversation.type === CONVERSATION.TYPE.ONE_TO_ONE_FORMER
@@ -238,13 +194,6 @@ export default {
return getStatusMessage(this.conversation)
},
- unreadMessagesCounter() {
- return this.conversation.unreadMessages
- },
- hasUnreadMentions() {
- return this.conversation.unreadMention
- },
-
renderedDescription() {
return this.renderContent(this.conversation.description)
},
@@ -302,36 +251,6 @@ export default {
},
},
- watch: {
- unreadMessagesCounter(newValue, oldValue) {
- if (!this.isInCall || !this.showOpenSidebarButton) {
- return
- }
-
- // new messages arrived
- if (newValue > 0 && oldValue === 0 && !this.hasUnreadMentions) {
- this.notifyUnreadMessages(t('spreed', 'You have new unread messages in the chat.'))
- }
- },
-
- hasUnreadMentions(newValue) {
- if (!this.isInCall || !this.showOpenSidebarButton) {
- return
- }
-
- if (newValue) {
- this.notifyUnreadMessages(t('spreed', 'You have been mentioned in the chat.'))
- }
- },
-
- isInCall(newValue) {
- if (!newValue) {
- // discard notification if the call ends
- this.notifyUnreadMessages(null)
- }
- },
- },
-
mounted() {
document.body.classList.add('has-topbar')
document.addEventListener('fullscreenchange', this.fullScreenChanged, false)
@@ -352,20 +271,6 @@ export default {
methods: {
t,
n,
- notifyUnreadMessages(message) {
- if (this.unreadNotificationHandle) {
- this.unreadNotificationHandle.hideToast()
- this.unreadNotificationHandle = null
- }
- if (message) {
- this.unreadNotificationHandle = showMessage(message, {
- onClick: () => {
- this.openSidebar('chat')
- },
- })
- }
- },
-
openSidebar(activeTab) {
if (typeof activeTab === 'string') {
emit('spreed:select-active-sidebar-tab', activeTab)
@@ -395,7 +300,9 @@ export default {
z-index: 10;
gap: 3px;
justify-content: flex-end;
- padding: 8px;
+ padding: calc(2 * var(--default-grid-baseline));
+ // Reserve space for the sidebar toggle button
+ padding-right: calc(2 * var(--default-grid-baseline) + var(--app-sidebar-offset));
background-color: var(--color-main-background);
border-bottom: 1px solid var(--color-border);
@@ -411,18 +318,6 @@ export default {
left: 0;
background-color: transparent;
}
-
- .chat-button {
- position: relative;
- overflow: visible;
- &__unread-messages-counter {
- position: absolute;
- top: 24px;
- right: 2px;
- pointer-events: none;
- color: var(--color-primary-element);
- }
- }
}
.conversation-icon {