diff options
| author | syuilo <4439005+syuilo@users.noreply.github.com> | 2025-03-25 11:11:24 +0900 |
|---|---|---|
| committer | syuilo <4439005+syuilo@users.noreply.github.com> | 2025-03-25 11:11:24 +0900 |
| commit | 8cbcbd462c1cbfa6256441f5c9b8331660409eb9 (patch) | |
| tree | bd167c9de56df159eff5386ffaf17e635557e56f /packages/frontend/src/pages/chat | |
| parent | enhance(frontend): 設定のインデックス更新 (diff) | |
| download | misskey-8cbcbd462c1cbfa6256441f5c9b8331660409eb9.tar.gz misskey-8cbcbd462c1cbfa6256441f5c9b8331660409eb9.tar.bz2 misskey-8cbcbd462c1cbfa6256441f5c9b8331660409eb9.zip | |
enhance(frontend): チャット画面で確実に最下部へスクロール追従するように
Diffstat (limited to 'packages/frontend/src/pages/chat')
| -rw-r--r-- | packages/frontend/src/pages/chat/room.vue | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/packages/frontend/src/pages/chat/room.vue b/packages/frontend/src/pages/chat/room.vue index 7aeb1f788a..8ffaf233cf 100644 --- a/packages/frontend/src/pages/chat/room.vue +++ b/packages/frontend/src/pages/chat/room.vue @@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only </div> </div> - <div v-else class="_gaps"> + <div v-else ref="timelineEl" class="_gaps"> <div v-if="canFetchMore"> <MkButton :class="$style.more" :wait="moreFetching" primary rounded @click="fetchMore">{{ i18n.ts.loadMore }}</MkButton> </div> @@ -75,7 +75,7 @@ SPDX-License-Identifier: AGPL-3.0-only <script lang="ts" setup> import { ref, useTemplateRef, computed, watch, onMounted, nextTick, onBeforeUnmount, onDeactivated, onActivated } from 'vue'; import * as Misskey from 'misskey-js'; -import { isTailVisible } from '@@/js/scroll.js'; +import { getScrollContainer, isTailVisible } from '@@/js/scroll.js'; import XMessage from './XMessage.vue'; import XForm from './room.form.vue'; import XSearch from './room.search.vue'; @@ -92,6 +92,7 @@ import { definePage } from '@/page.js'; import { prefer } from '@/preferences.js'; import MkButton from '@/components/MkButton.vue'; import { useRouter } from '@/router.js'; +import { useMutationObserver } from '@/use/use-mutation-observer.js'; const $i = ensureSignin(); const router = useRouter(); @@ -109,6 +110,26 @@ const user = ref<Misskey.entities.UserDetailed | null>(null); const room = ref<Misskey.entities.ChatRoom | null>(null); const connection = ref<Misskey.ChannelConnection<Misskey.Channels['chatUser'] | Misskey.Channels['chatRoom']> | null>(null); const showIndicator = ref(false); +const timelineEl = useTemplateRef('timelineEl'); + +const SCROLL_HEAD_THRESHOLD = 200; + +// column-reverseなので本来はスクロール位置の最下部への追従は不要なはずだが、おそらくブラウザのバグにより、最下部にスクロールした状態でも追従されない場合がある(スクロール位置が少数になることがあるのが関わっていそう) +// そのため補助としてMutationObserverを使って追従を行う +useMutationObserver(timelineEl, { + subtree: true, + childList: true, + attributes: false, +}, () => { + const scrollContainer = getScrollContainer(timelineEl.value)!; + // column-reverseなのでscrollTopは負になる + if (-scrollContainer.scrollTop < SCROLL_HEAD_THRESHOLD) { + scrollContainer.scrollTo({ + top: 0, + behavior: 'instant', + }); + } +}); function normalizeMessage(message: Misskey.entities.ChatMessageLite | Misskey.entities.ChatMessage) { const reactions = [...message.reactions]; |