scrolling!

This commit is contained in:
Henry Jameson 2026-07-24 18:24:42 +03:00
commit bc762a9413
6 changed files with 43 additions and 44 deletions

View file

@ -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 },

View file

@ -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)
}
}
},
},
}

View file

@ -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)"
>

View file

@ -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) {

View file

@ -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"

View file

@ -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;
}
}