aboutsummaryrefslogtreecommitdiff
path: root/src/components/chat
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/chat')
-rw-r--r--src/components/chat/chat.js54
-rw-r--r--src/components/chat/chat.scss69
-rw-r--r--src/components/chat/chat.vue6
3 files changed, 23 insertions, 106 deletions
diff --git a/src/components/chat/chat.js b/src/components/chat/chat.js
index aef11712..5d2c1d09 100644
--- a/src/components/chat/chat.js
+++ b/src/components/chat/chat.js
@@ -6,7 +6,7 @@ import PostStatusForm from '../post_status_form/post_status_form.vue'
import ChatTitle from '../chat_title/chat_title.vue'
import chatService from '../../services/chat_service/chat_service.js'
import { promiseInterval } from '../../services/promise_interval/promise_interval.js'
-import { getScrollPosition, getNewTopPosition, isBottomedOut, scrollableContainerHeight, isScrollable } from './chat_layout_utils.js'
+import { getScrollPosition, getNewTopPosition, isBottomedOut, isScrollable } from './chat_layout_utils.js'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
faChevronDown,
@@ -19,8 +19,10 @@ library.add(
faChevronLeft
)
+const scroller = () => document.getElementById('content')
+
const BOTTOMED_OUT_OFFSET = 10
-const JUMP_TO_BOTTOM_BUTTON_VISIBILITY_OFFSET = 150
+const JUMP_TO_BOTTOM_BUTTON_VISIBILITY_OFFSET = 10
const SAFE_RESIZE_TIME_OFFSET = 100
const MARK_AS_READ_DELAY = 1500
const MAX_RETRIES = 10
@@ -46,19 +48,18 @@ const Chat = {
window.addEventListener('resize', this.handleLayoutChange)
},
mounted () {
- window.addEventListener('scroll', this.handleScroll)
+ scroller().addEventListener('scroll', this.handleScroll)
if (typeof document.hidden !== 'undefined') {
document.addEventListener('visibilitychange', this.handleVisibilityChange, false)
}
this.$nextTick(() => {
- this.updateScrollableContainerHeight()
this.handleResize()
})
this.setChatLayout()
},
unmounted () {
- window.removeEventListener('scroll', this.handleScroll)
+ scroller().removeEventListener('scroll', this.handleScroll)
window.removeEventListener('resize', this.handleLayoutChange)
this.unsetChatLayout()
if (typeof document.hidden !== 'undefined') document.removeEventListener('visibilitychange', this.handleVisibilityChange, false)
@@ -132,7 +133,6 @@ const Chat = {
onFilesDropped () {
this.$nextTick(() => {
this.handleResize()
- this.updateScrollableContainerHeight()
})
},
handleVisibilityChange () {
@@ -154,10 +154,6 @@ const Chat = {
if (html) {
html.classList.add('chat-layout')
}
-
- this.$nextTick(() => {
- this.updateScrollableContainerHeight()
- })
},
unsetChatLayout () {
let html = document.querySelector('html')
@@ -167,17 +163,9 @@ const Chat = {
},
handleLayoutChange () {
this.$nextTick(() => {
- this.updateScrollableContainerHeight()
this.scrollDown()
})
},
- // Ensures the proper position of the posting form in the mobile layout (the mobile browser panel does not overlap or hide it)
- updateScrollableContainerHeight () {
- const header = this.$refs.header
- const footer = this.$refs.footer
- const inner = this.mobileLayout ? window.document.body : this.$refs.inner
- this.scrollableContainerHeight = scrollableContainerHeight(inner, header, footer) + 'px'
- },
// Preserves the scroll position when OSK appears or the posting form changes its height.
handleResize (opts = {}) {
const { expand = false, delayed = false } = opts
@@ -190,17 +178,14 @@ const Chat = {
}
this.$nextTick(() => {
- this.updateScrollableContainerHeight()
-
const { offsetHeight = undefined } = this.lastScrollPosition
- this.lastScrollPosition = getScrollPosition(this.$refs.scrollable)
+ this.lastScrollPosition = getScrollPosition(scroller())
const diff = this.lastScrollPosition.offsetHeight - offsetHeight
if (diff < 0 || (!this.bottomedOut() && expand)) {
this.$nextTick(() => {
- this.updateScrollableContainerHeight()
- this.$refs.scrollable.scrollTo({
- top: this.$refs.scrollable.scrollTop - diff,
+ scroller().scrollTo({
+ top: scroller().scrollTop - diff,
left: 0
})
})
@@ -209,7 +194,7 @@ const Chat = {
},
scrollDown (options = {}) {
const { behavior = 'auto', forceRead = false } = options
- const scrollable = this.$refs.scrollable
+ const scrollable = scroller()
if (!scrollable) { return }
this.$nextTick(() => {
scrollable.scrollTo({ top: scrollable.scrollHeight, left: 0, behavior })
@@ -228,10 +213,10 @@ const Chat = {
})
},
bottomedOut (offset) {
- return isBottomedOut(this.$refs.scrollable, offset)
+ return isBottomedOut(scroller(), offset)
},
reachedTop () {
- const scrollable = this.$refs.scrollable
+ const scrollable = scroller()
return scrollable && scrollable.scrollTop <= 0
},
cullOlderCheck () {
@@ -263,8 +248,8 @@ const Chat = {
}
}, 200),
handleScrollUp (positionBeforeLoading) {
- const positionAfterLoading = getScrollPosition(this.$refs.scrollable)
- this.$refs.scrollable.scrollTo({
+ const positionAfterLoading = getScrollPosition(scroller())
+ scroller().scrollTo({
top: getNewTopPosition(positionBeforeLoading, positionAfterLoading),
left: 0
})
@@ -285,22 +270,18 @@ const Chat = {
chatService.clear(chatMessageService)
}
- const positionBeforeUpdate = getScrollPosition(this.$refs.scrollable)
+ const positionBeforeUpdate = getScrollPosition(scroller())
this.$store.dispatch('addChatMessages', { chatId, messages }).then(() => {
this.$nextTick(() => {
if (fetchOlderMessages) {
this.handleScrollUp(positionBeforeUpdate)
}
- if (isFirstFetch) {
- this.updateScrollableContainerHeight()
- }
-
// In vertical screens, the first batch of fetched messages may not always take the
// full height of the scrollable container.
// If this is the case, we want to fetch the messages until the scrollable container
// is fully populated so that the user has the ability to scroll up and load the history.
- if (!isScrollable(this.$refs.scrollable) && messages.length > 0) {
+ if (!isScrollable(scroller()) && messages.length > 0) {
this.fetchChat({ maxId: this.currentChatMessageService.minId })
}
})
@@ -336,9 +317,6 @@ const Chat = {
this.handleResize()
// When the posting form size changes because of a media attachment, we need an extra resize
// to account for the potential delay in the DOM update.
- setTimeout(() => {
- this.updateScrollableContainerHeight()
- }, SAFE_RESIZE_TIME_OFFSET)
this.scrollDown({ forceRead: true })
})
},
diff --git a/src/components/chat/chat.scss b/src/components/chat/chat.scss
index 3a26686c..34a335fe 100644
--- a/src/components/chat/chat.scss
+++ b/src/components/chat/chat.scss
@@ -1,19 +1,12 @@
.chat-view {
display: flex;
- height: calc(100vh - 60px);
- width: 100%;
-
- .chat-title {
- // prevents chat header jumping on when the user avatar loads
- height: 28px;
- }
+ height: 100%;
.chat-view-inner {
height: auto;
width: 100%;
overflow: visible;
display: flex;
- margin: 0.5em 0.5em 0 0.5em;
}
.chat-view-body {
@@ -32,11 +25,9 @@
}
}
- .scrollable-message-list {
+ .message-list {
padding: 0 0.8em;
height: 100%;
- overflow-y: scroll;
- overflow-x: hidden;
display: flex;
flex-direction: column;
}
@@ -44,12 +35,14 @@
.footer {
position: sticky;
bottom: 0;
+ background-color: $fallback--bg;
+ background-color: var(--bg, $fallback--bg);
+ z-index: 10;
}
.chat-view-heading {
align-items: center;
justify-content: space-between;
- top: 50px;
display: flex;
z-index: 2;
position: sticky;
@@ -115,56 +108,4 @@
}
}
}
-
- @media all and (max-width: 800px) {
- height: 100%;
- overflow: hidden;
-
- .chat-view-inner {
- overflow: hidden;
- height: 100%;
- margin-top: 0;
- margin-left: 0;
- margin-right: 0;
- }
-
- .chat-view-body {
- display: flex;
- min-height: auto;
- overflow: hidden;
- height: 100%;
- margin: 0;
- border-radius: 0;
- }
-
- .chat-view-heading {
- box-sizing: border-box;
- position: static;
- z-index: 9999;
- top: 0;
- margin-top: 0;
- border-radius: 0;
-
- /* This practically overlays the panel heading color over panel background
- * color. This is needed because we allow transparent panel background and
- * it doesn't work well in this "disjointed panel header" case
- */
- background:
- linear-gradient(to top, var(--panel), var(--panel)),
- linear-gradient(to top, var(--bg), var(--bg));
- height: 50px;
- }
-
- .scrollable-message-list {
- display: unset;
- overflow-y: scroll;
- overflow-x: hidden;
- -webkit-overflow-scrolling: touch;
- }
-
- .footer {
- position: sticky;
- bottom: auto;
- }
- }
}
diff --git a/src/components/chat/chat.vue b/src/components/chat/chat.vue
index 493c5d5a..3b0129fa 100644
--- a/src/components/chat/chat.vue
+++ b/src/components/chat/chat.vue
@@ -8,7 +8,7 @@
>
<div
ref="header"
- class="panel-heading chat-view-heading mobile-hidden"
+ class="panel-heading -sticky chat-view-heading mobile-hidden"
>
<a
class="go-back-button"
@@ -27,10 +27,8 @@
</div>
</div>
<div
- ref="scrollable"
- class="scrollable-message-list"
+ class="message-list"
:style="{ height: scrollableContainerHeight }"
- @scroll="handleScroll"
>
<template v-if="!errorLoadingChat">
<ChatMessage