diff options
author | Nikola <nikola.gladovic@nextcloud.com> | 2022-04-06 21:52:40 +0300 |
---|---|---|
committer | Joas Schilling <coding@schilljs.com> | 2022-04-13 11:22:02 +0300 |
commit | c7a7451dcbb4e3739064ac21eb39651308356855 (patch) | |
tree | 82de59f0f73ae2add6a9b0d8ce5d99bb364bf8aa | |
parent | bebdf8bc44c23e4403e758a9e6fd11ff0dcfb716 (diff) |
3299: updated unread mentions viewport of conversation list
Signed-off-by: Nikola <nikola.gladovic@nextcloud.com>
-rw-r--r-- | src/components/LeftSidebar/ConversationsList/Conversation.vue | 1 | ||||
-rw-r--r-- | src/components/LeftSidebar/LeftSidebar.vue | 90 |
2 files changed, 88 insertions, 3 deletions
diff --git a/src/components/LeftSidebar/ConversationsList/Conversation.vue b/src/components/LeftSidebar/ConversationsList/Conversation.vue index 18d10af47..66323d5d6 100644 --- a/src/components/LeftSidebar/ConversationsList/Conversation.vue +++ b/src/components/LeftSidebar/ConversationsList/Conversation.vue @@ -21,6 +21,7 @@ <template> <ListItem :title="item.displayName" + :class="{'unread-mention-conversation': item.unreadMention}" :anchor-id="`conversation_${item.token}`" :active="isActive" :to="to" diff --git a/src/components/LeftSidebar/LeftSidebar.vue b/src/components/LeftSidebar/LeftSidebar.vue index 6ba6ed440..e79e42e88 100644 --- a/src/components/LeftSidebar/LeftSidebar.vue +++ b/src/components/LeftSidebar/LeftSidebar.vue @@ -32,6 +32,12 @@ <NewGroupConversation v-if="canStartConversations" /> </div> <template #list> + <Button v-if="!preventFindingUnread && unreadTop > 0" + class="unread-mention-button unread-mention-button__top" + type="primary" + @click="scrollTopUnread"> + {{ unreadTop }} more mentions + </Button> <div ref="scroller" class="left-sidebar__list" @scroll="debounceHandleScroll"> @@ -91,14 +97,20 @@ <Hint v-else :hint="t('spreed', 'No search results')" /> </template> </div> + <Button v-if="!preventFindingUnread && unreadBottom > 0" + class="unread-mention-button unread-mention-button__bottom" + type="primary" + @click="scrollBottomUnread"> + {{ unreadBottom }} more mentions + </Button> </template> <template #footer> <div id="app-settings"> <div id="app-settings-header"> - <button class="settings-button" @click="showSettings"> + <Button class="settings-button" @click="showSettings"> {{ t('spreed', 'Talk settings') }} - </button> + </Button> </div> </div> </template> @@ -113,6 +125,7 @@ import ConversationsList from './ConversationsList/ConversationsList' import Conversation from './ConversationsList/Conversation' import ConversationsOptionsList from '../ConversationsOptionsList' import Hint from '../Hint' +import Button from '@nextcloud/vue/dist/Components/Button' import SearchBox from './SearchBox/SearchBox' import debounce from 'debounce' import { EventBus } from '../../services/EventBus' @@ -135,6 +148,7 @@ export default { AppNavigation, AppNavigationCaption, ConversationsList, + Button, ConversationsOptionsList, Hint, SearchBox, @@ -164,6 +178,11 @@ export default { // Keeps track of whether the conversation list is scrolled to the top or not isScrolledToTop: true, refreshTimer: null, + unreadTop: 0, + unreadBottom: 0, + firstUnreadPos: 0, + lastUnreadPos: 0, + preventFindingUnread: false, } }, @@ -276,7 +295,28 @@ export default { isFocused() { return this.isSearching }, - + scrollTopUnread() { + this.preventFindingUnread = true + this.$refs.scroller.scrollTo({ + top: this.firstUnreadPos - 100, + behavior: 'smooth', + }) + setTimeout(() => { + this.handleUnreadMention() + this.preventFindingUnread = false + }, 500) + }, + scrollBottomUnread() { + this.preventFindingUnread = true + this.$refs.scroller.scrollTo({ + top: this.lastUnreadPos - this.$refs.scroller.clientHeight + 150, + behavior: 'smooth', + }) + setTimeout(() => { + this.handleUnreadMention() + this.preventFindingUnread = false + }, 500) + }, debounceFetchSearchResults: debounce(function() { if (this.isSearching) { this.fetchSearchResults() @@ -448,8 +488,40 @@ export default { handleScroll() { this.isScrolledToTop = this.$refs.scroller.scrollTop === 0 }, + ensureInView(container, element) { + const cTop = container.scrollTop + const cBottom = cTop + container.clientHeight + + const eTop = element.offsetTop + const eBottom = eTop + element.clientHeight + if (eBottom < cTop) { + return 'outside-top' + } else if (eTop > cBottom) { + return 'outside-bottom' + } else { + return 'inside' + } + }, + handleUnreadMention() { + this.unreadTop = 0 + this.unreadBottom = 0 + const unreadMentions = document.getElementsByClassName('unread-mention-conversation') + unreadMentions.forEach(x => { + const pos = this.ensureInView(this.$refs.scroller, x) + if (pos === 'outside-top') { + if (this.unreadTop === 0) { + this.firstUnreadPos = x.offsetTop + } + this.unreadTop += 1 + } else if (pos === 'outside-bottom') { + this.unreadBottom += 1 + this.lastUnreadPos = x.offsetTop + } + }) + }, debounceHandleScroll: debounce(function() { this.handleScroll() + this.handleUnreadMention() }, 50), }, } @@ -476,4 +548,16 @@ export default { padding: 0 4px; } +.unread-mention-button { + position: absolute; + left: 50%; + transform: translateX(-50%); + z-index: 100; + &__top { + top: 10px; + } + &__bottom { + bottom: 10px; + } +} </style> |