forked from mirrors/misskey
fix(frontend): タブが不可視なあいだのpaginationのアップデートを停止するように (#16243)
* fix(frontend): タブが不可視なあいだのpaginationのアップデートを停止するように * fix lint * 待たない
This commit is contained in:
@@ -59,6 +59,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
import { computed, watch, onUnmounted, provide, useTemplateRef, TransitionGroup, onMounted, shallowRef, ref, markRaw } from 'vue';
|
import { computed, watch, onUnmounted, provide, useTemplateRef, TransitionGroup, onMounted, shallowRef, ref, markRaw } from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import { useInterval } from '@@/js/use-interval.js';
|
import { useInterval } from '@@/js/use-interval.js';
|
||||||
|
import { useDocumentVisibility } from '@@/js/use-document-visibility.js';
|
||||||
import { getScrollContainer, scrollToTop } from '@@/js/scroll.js';
|
import { getScrollContainer, scrollToTop } from '@@/js/scroll.js';
|
||||||
import type { BasicTimelineType } from '@/timelines.js';
|
import type { BasicTimelineType } from '@/timelines.js';
|
||||||
import type { SoundStore } from '@/preferences/def.js';
|
import type { SoundStore } from '@/preferences/def.js';
|
||||||
@@ -224,6 +225,20 @@ onUnmounted(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const visibility = useDocumentVisibility();
|
||||||
|
let isPausingUpdate = false;
|
||||||
|
|
||||||
|
watch(visibility, () => {
|
||||||
|
if (visibility.value === 'hidden') {
|
||||||
|
isPausingUpdate = true;
|
||||||
|
} else { // 'visible'
|
||||||
|
isPausingUpdate = false;
|
||||||
|
if (isTop()) {
|
||||||
|
releaseQueue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
let adInsertionCounter = 0;
|
let adInsertionCounter = 0;
|
||||||
|
|
||||||
const MIN_POLLING_INTERVAL = 1000 * 10;
|
const MIN_POLLING_INTERVAL = 1000 * 10;
|
||||||
@@ -237,7 +252,7 @@ if (!store.s.realtimeMode) {
|
|||||||
// TODO: 先頭のノートの作成日時が1日以上前であれば流速が遅いTLと見做してインターバルを通常より延ばす
|
// TODO: 先頭のノートの作成日時が1日以上前であれば流速が遅いTLと見做してインターバルを通常より延ばす
|
||||||
useInterval(async () => {
|
useInterval(async () => {
|
||||||
paginator.fetchNewer({
|
paginator.fetchNewer({
|
||||||
toQueue: !isTop(),
|
toQueue: !isTop() || isPausingUpdate,
|
||||||
});
|
});
|
||||||
}, POLLING_INTERVAL, {
|
}, POLLING_INTERVAL, {
|
||||||
immediate: false,
|
immediate: false,
|
||||||
@@ -246,7 +261,7 @@ if (!store.s.realtimeMode) {
|
|||||||
|
|
||||||
useGlobalEvent('notePosted', (note) => {
|
useGlobalEvent('notePosted', (note) => {
|
||||||
paginator.fetchNewer({
|
paginator.fetchNewer({
|
||||||
toQueue: !isTop(),
|
toQueue: !isTop() || isPausingUpdate,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -257,7 +272,7 @@ useGlobalEvent('noteDeleted', (noteId) => {
|
|||||||
|
|
||||||
function releaseQueue() {
|
function releaseQueue() {
|
||||||
paginator.releaseQueue();
|
paginator.releaseQueue();
|
||||||
scrollToTop(rootEl.value);
|
scrollToTop(rootEl.value!);
|
||||||
}
|
}
|
||||||
|
|
||||||
function prepend(note: Misskey.entities.Note & MisskeyEntity) {
|
function prepend(note: Misskey.entities.Note & MisskeyEntity) {
|
||||||
@@ -267,7 +282,7 @@ function prepend(note: Misskey.entities.Note & MisskeyEntity) {
|
|||||||
note._shouldInsertAd_ = true;
|
note._shouldInsertAd_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isTop()) {
|
if (isTop() && !isPausingUpdate) {
|
||||||
paginator.prepend(note);
|
paginator.prepend(note);
|
||||||
} else {
|
} else {
|
||||||
paginator.enqueue(note);
|
paginator.enqueue(note);
|
||||||
|
|||||||
@@ -45,7 +45,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
|||||||
import { onUnmounted, onMounted, computed, useTemplateRef, TransitionGroup, markRaw, watch } from 'vue';
|
import { onUnmounted, onMounted, computed, useTemplateRef, TransitionGroup, markRaw, watch } from 'vue';
|
||||||
import * as Misskey from 'misskey-js';
|
import * as Misskey from 'misskey-js';
|
||||||
import { useInterval } from '@@/js/use-interval.js';
|
import { useInterval } from '@@/js/use-interval.js';
|
||||||
|
import { useDocumentVisibility } from '@@/js/use-document-visibility.js';
|
||||||
import type { notificationTypes } from '@@/js/const.js';
|
import type { notificationTypes } from '@@/js/const.js';
|
||||||
|
import { getScrollContainer, scrollToTop } from '@@/js/scroll.js';
|
||||||
import XNotification from '@/components/MkNotification.vue';
|
import XNotification from '@/components/MkNotification.vue';
|
||||||
import MkNote from '@/components/MkNote.vue';
|
import MkNote from '@/components/MkNote.vue';
|
||||||
import { useStream } from '@/stream.js';
|
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) {
|
function onNotification(notification) {
|
||||||
const isMuted = props.excludeTypes ? props.excludeTypes.includes(notification.type) : false;
|
const isMuted = props.excludeTypes ? props.excludeTypes.includes(notification.type) : false;
|
||||||
if (isMuted || window.document.visibilityState === 'visible') {
|
if (isMuted || window.document.visibilityState === 'visible') {
|
||||||
@@ -101,7 +146,11 @@ function onNotification(notification) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!isMuted) {
|
if (!isMuted) {
|
||||||
paginator.prepend(notification);
|
if (isTop() && !isPausingUpdate) {
|
||||||
|
paginator.prepend(notification);
|
||||||
|
} else {
|
||||||
|
paginator.enqueue(notification);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user