scrolling!
This commit is contained in:
parent
147f34c1fd
commit
bc762a9413
6 changed files with 43 additions and 44 deletions
|
|
@ -72,6 +72,7 @@ export default (store) => {
|
|||
() => import('src/components/chat_view/chat_view.vue'),
|
||||
),
|
||||
props: true,
|
||||
meta: { dontScroll: true },
|
||||
beforeEnter: validateAuthenticatedRoute,
|
||||
},
|
||||
{ name: 'quotes', path: '/notice/:id/quotes', component: QuotesTimeline },
|
||||
|
|
|
|||
|
|
@ -184,11 +184,6 @@ const ChatMessage = {
|
|||
menuOpened: false,
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
focused: function (value) {
|
||||
this.scrollIfFocused(value)
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onHover(bool) {
|
||||
this.$emit('hover', {
|
||||
|
|
@ -224,22 +219,6 @@ const ChatMessage = {
|
|||
this.hovered = false
|
||||
this.menuOpened = false
|
||||
},
|
||||
scrollIfFocused(focused) {
|
||||
if (this.$el.getBoundingClientRect == null) return
|
||||
if (focused) {
|
||||
const rect = this.$el.getBoundingClientRect()
|
||||
if (rect.top < 100) {
|
||||
// Post is above screen, match its top to screen top
|
||||
window.scrollBy(0, rect.top - 100)
|
||||
} else if (rect.height >= window.innerHeight - 50) {
|
||||
// Post we want to see is taller than screen so match its top to screen top
|
||||
window.scrollBy(0, rect.top - 100)
|
||||
} else if (rect.bottom > window.innerHeight - 50) {
|
||||
// Post is below screen, match its bottom to screen bottom
|
||||
window.scrollBy(0, rect.bottom - window.innerHeight + 50)
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
v-if="isMessage"
|
||||
class="chat-message-wrapper"
|
||||
:class="[classnames, { 'hovered-message-chain': hoveredMessageChain }]"
|
||||
:id="`chatmessage-${message.id}`"
|
||||
@mouseover="onHover(true)"
|
||||
@mouseleave="onHover(false)"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -86,9 +86,9 @@ const Chat = {
|
|||
created() {
|
||||
if (this.testMode) return
|
||||
this.startFetching()
|
||||
window.addEventListener('resize', this.handleResize)
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener('resize', this.handleResize)
|
||||
window.addEventListener('scroll', this.handleScroll)
|
||||
if (typeof document.hidden !== 'undefined') {
|
||||
document.addEventListener(
|
||||
|
|
@ -122,14 +122,11 @@ const Chat = {
|
|||
)
|
||||
},
|
||||
isConversation() {
|
||||
return this.conversationId !== null
|
||||
return this.statusId !== null
|
||||
},
|
||||
recipient() {
|
||||
return this.chat?.account
|
||||
},
|
||||
recipientId() {
|
||||
return this.$route.params.recipient_id
|
||||
},
|
||||
formPlaceholder() {
|
||||
if (this.recipient) {
|
||||
return this.$t('chats.message_user', {
|
||||
|
|
@ -166,7 +163,8 @@ const Chat = {
|
|||
}),
|
||||
},
|
||||
watch: {
|
||||
messages() {
|
||||
messages(old, neu) {
|
||||
if (old.length === neu.length) return
|
||||
// We don't want to scroll to the bottom on a new message when the user is viewing older messages.
|
||||
// Therefore we need to know whether the scroll position was at the bottom before the DOM update.
|
||||
const bottomedOutBeforeUpdate = isBottomedOut(BOTTOMED_OUT_OFFSET)
|
||||
|
|
@ -180,7 +178,38 @@ const Chat = {
|
|||
await nextTick() // wait for changes to propagate to postStatusForm
|
||||
this.$refs.postStatusForm.update()
|
||||
},
|
||||
$route: function () {
|
||||
$route: async function (newVal) {
|
||||
if (this.messagesIndex[newVal.params.statusId]) {
|
||||
const focused = document.getElementById(`chatmessage-${this.$route.params.statusId}`)
|
||||
if (focused?.getBoundingClientRect == null) return
|
||||
const bottomBoundary = window.innerHeight - this.$refs.footer.clientHeight
|
||||
const topBoundary = this.$refs.header.clientHeight + document.getElementById('nav').clientHeight
|
||||
const margin = Number(window.getComputedStyle(this.$refs.messageList.$el).gap.replace('px',''))
|
||||
|
||||
const rect = focused.getBoundingClientRect()
|
||||
const scrollAmount = (() => {
|
||||
if (rect.top < topBoundary) {
|
||||
// Post is above screen, match its top to screen top
|
||||
return rect.top - topBoundary - margin
|
||||
} else if (rect.height >= bottomBoundary) {
|
||||
// Post we want to see is taller than screen so match its top to screen top
|
||||
return rect.top - topBoundary - margin
|
||||
} else if (rect.bottom > bottomBoundary) {
|
||||
// Post is below screen, match its bottom to screen bottom
|
||||
return rect.bottom - bottomBoundary + margin
|
||||
} else {
|
||||
return 0
|
||||
}
|
||||
})()
|
||||
|
||||
if (scrollAmount !== 0) {
|
||||
window.scrollBy(0, scrollAmount)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
this.clear()
|
||||
this.startFetching()
|
||||
},
|
||||
mastoUserSocketStatus(newValue) {
|
||||
|
|
@ -295,6 +324,9 @@ const Chat = {
|
|||
this.addMessages({ messages })
|
||||
|
||||
await nextTick()
|
||||
if (isFirstFetch) {
|
||||
this.scrollDown()
|
||||
}
|
||||
|
||||
const fetchOlderMessages = !!maxId
|
||||
if (fetchOlderMessages) {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
icon="chevron-left"
|
||||
/>
|
||||
</button>
|
||||
<div class="title text-center">
|
||||
<div class="title">
|
||||
<template v-if="isConversation">
|
||||
<RichContent
|
||||
v-if="messages[0]?.summary"
|
||||
|
|
@ -38,6 +38,7 @@
|
|||
<div class="chat-list-wrapper panel-body">
|
||||
<div class="top-spacer" />
|
||||
<ChatMessageList
|
||||
ref="messageList"
|
||||
header-date
|
||||
:messages="messages"
|
||||
:pending-messages="pendingMessages"
|
||||
|
|
|
|||
|
|
@ -92,19 +92,4 @@
|
|||
backdrop-filter: var(--__panel-backdrop-filter);
|
||||
}
|
||||
}
|
||||
|
||||
.chat-view-reply-form {
|
||||
position: sticky;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
bottom: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.reply-to-text {
|
||||
line-height: 1.2;
|
||||
padding-top: 0.5em;
|
||||
margin-bottom: -0.5em;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue