diff options
| author | かっこかり <67428053+kakkokari-gtyih@users.noreply.github.com> | 2025-07-03 18:52:16 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-03 18:52:16 +0900 |
| commit | 179d990c39ed5c7f79e7481ca86b07ec9f70d474 (patch) | |
| tree | 6210475837a0c413eceecf9d6e5a30ee9ac8c6d9 /packages/frontend/src/components/MkStreamingNotificationsTimeline.vue | |
| parent | enhance(backend): avatarUrlの上限文字数の引き上げ (#16235) (diff) | |
| download | misskey-179d990c39ed5c7f79e7481ca86b07ec9f70d474.tar.gz misskey-179d990c39ed5c7f79e7481ca86b07ec9f70d474.tar.bz2 misskey-179d990c39ed5c7f79e7481ca86b07ec9f70d474.zip | |
fix(frontend): タブが不可視なあいだのpaginationのアップデートを停止するように (#16243)
* fix(frontend): タブが不可視なあいだのpaginationのアップデートを停止するように
* fix lint
* 待たない
Diffstat (limited to 'packages/frontend/src/components/MkStreamingNotificationsTimeline.vue')
| -rw-r--r-- | packages/frontend/src/components/MkStreamingNotificationsTimeline.vue | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/packages/frontend/src/components/MkStreamingNotificationsTimeline.vue b/packages/frontend/src/components/MkStreamingNotificationsTimeline.vue index 869d848d90..e21adab36c 100644 --- a/packages/frontend/src/components/MkStreamingNotificationsTimeline.vue +++ b/packages/frontend/src/components/MkStreamingNotificationsTimeline.vue @@ -45,7 +45,9 @@ SPDX-License-Identifier: AGPL-3.0-only import { onUnmounted, onMounted, computed, useTemplateRef, TransitionGroup, markRaw, watch } from 'vue'; import * as Misskey from 'misskey-js'; import { useInterval } from '@@/js/use-interval.js'; +import { useDocumentVisibility } from '@@/js/use-document-visibility.js'; import type { notificationTypes } from '@@/js/const.js'; +import { getScrollContainer, scrollToTop } from '@@/js/scroll.js'; import XNotification from '@/components/MkNotification.vue'; import MkNote from '@/components/MkNote.vue'; import { useStream } from '@/stream.js'; @@ -92,6 +94,49 @@ if (!store.s.realtimeMode) { }); } +function isTop() { + if (scrollContainer == null) return true; + if (rootEl.value == null) return true; + const scrollTop = scrollContainer.scrollTop; + const tlTop = rootEl.value.offsetTop - scrollContainer.offsetTop; + return scrollTop <= tlTop; +} + +function releaseQueue() { + paginator.releaseQueue(); + scrollToTop(rootEl.value!); +} + +let scrollContainer: HTMLElement | null = null; + +function onScrollContainerScroll() { + if (isTop()) { + paginator.releaseQueue(); + } +} + +watch(rootEl, (el) => { + if (el && scrollContainer == null) { + scrollContainer = getScrollContainer(el); + if (scrollContainer == null) return; + scrollContainer.addEventListener('scroll', onScrollContainerScroll, { passive: true }); // ほんとはscrollendにしたいけどiosが非対応 + } +}, { immediate: true }); + +const visibility = useDocumentVisibility(); +let isPausingUpdate = false; + +watch(visibility, () => { + if (visibility.value === 'hidden') { + isPausingUpdate = true; + } else { // 'visible' + isPausingUpdate = false; + if (isTop()) { + releaseQueue(); + } + } +}); + function onNotification(notification) { const isMuted = props.excludeTypes ? props.excludeTypes.includes(notification.type) : false; if (isMuted || window.document.visibilityState === 'visible') { @@ -101,7 +146,11 @@ function onNotification(notification) { } if (!isMuted) { - paginator.prepend(notification); + if (isTop() && !isPausingUpdate) { + paginator.prepend(notification); + } else { + paginator.enqueue(notification); + } } } |