This commit is contained in:
syuilo 2025-03-23 08:08:27 +09:00
parent 798a50da0e
commit 53386fb5fc
3 changed files with 42 additions and 72 deletions

View File

@ -63,8 +63,6 @@ export type Paging<E extends keyof Misskey.Endpoints = keyof Misskey.Endpoints>
reversed?: boolean;
offsetMode?: boolean;
pageEl?: HTMLElement;
};
type MisskeyEntity = {
@ -136,8 +134,7 @@ const isBackTop = ref(false);
const empty = computed(() => items.value.size === 0);
const error = ref(false);
const contentEl = computed(() => props.pagination.pageEl ?? rootEl.value);
const scrollableElement = computed(() => contentEl.value ? getScrollContainer(contentEl.value) : document.body);
const scrollableElement = computed(() => rootEl.value ? getScrollContainer(rootEl.value) : document.body);
const visibility = useDocumentVisibility();
@ -168,11 +165,11 @@ watch(rootEl, () => {
});
});
watch([backed, contentEl], () => {
watch([backed, rootEl], () => {
if (!backed.value) {
if (!contentEl.value) return;
if (!rootEl.value) return;
scrollRemove.value = (props.pagination.reversed ? onScrollBottom : onScrollTop)(contentEl.value, executeQueue, TOLERANCE);
scrollRemove.value = (props.pagination.reversed ? onScrollBottom : onScrollTop)(rootEl.value, executeQueue, TOLERANCE);
} else {
if (scrollRemove.value) scrollRemove.value();
scrollRemove.value = null;
@ -345,7 +342,7 @@ const appearFetchMoreAhead = async (): Promise<void> => {
fetchMoreAppearTimeout();
};
const isTop = (): boolean => isBackTop.value || (props.pagination.reversed ? isTailVisible : isHeadVisible)(contentEl.value!, TOLERANCE);
const isTop = (): boolean => isBackTop.value || (props.pagination.reversed ? isTailVisible : isHeadVisible)(rootEl.value!, TOLERANCE);
watch(visibility, () => {
if (visibility.value === 'hidden') {
@ -443,7 +440,7 @@ onDeactivated(() => {
});
function toBottom() {
scrollToBottom(contentEl.value!);
scrollToBottom(rootEl.value!);
}
onBeforeMount(() => {

View File

@ -74,8 +74,6 @@ export type Paging<E extends keyof Misskey.Endpoints = keyof Misskey.Endpoints>
reversed?: boolean;
offsetMode?: boolean;
pageEl?: HTMLElement;
};
type MisskeyEntityMap = Map<string, MisskeyEntity>;
@ -142,8 +140,7 @@ const {
enableInfiniteScroll,
} = prefer.r;
const contentEl = computed(() => props.pagination.pageEl ?? rootEl.value);
const scrollableElement = computed(() => contentEl.value ? getScrollContainer(contentEl.value) : window.document.body);
const scrollableElement = computed(() => rootEl.value ? getScrollContainer(rootEl.value) : window.document.body);
const visibility = useDocumentVisibility();
@ -174,13 +171,13 @@ watch(rootEl, () => {
});
});
watch([backed, contentEl], () => {
watch([backed, rootEl], () => {
if (!backed.value) {
if (!contentEl.value) return;
if (!rootEl.value) return;
scrollRemove.value = props.pagination.reversed
? onScrollBottom(contentEl.value, executeQueue, TOLERANCE)
: onScrollTop(contentEl.value, (topVisible) => { if (topVisible) executeQueue(); }, TOLERANCE);
? onScrollBottom(rootEl.value, executeQueue, TOLERANCE)
: onScrollTop(rootEl.value, (topVisible) => { if (topVisible) executeQueue(); }, TOLERANCE);
} else {
if (scrollRemove.value) scrollRemove.value();
scrollRemove.value = null;
@ -350,7 +347,7 @@ const appearFetchMoreAhead = async (): Promise<void> => {
fetchMoreAppearTimeout();
};
const isHead = (): boolean => isBackTop.value || (props.pagination.reversed && !props.scrollReversed ? isTailVisible : isHeadVisible)(contentEl.value!, TOLERANCE);
const isHead = (): boolean => isBackTop.value || (props.pagination.reversed && !props.scrollReversed ? isTailVisible : isHeadVisible)(rootEl.value!, TOLERANCE);
watch(visibility, () => {
if (visibility.value === 'hidden') {
@ -450,7 +447,7 @@ onDeactivated(() => {
});
function toBottom() {
scrollToBottom(contentEl.value!);
scrollToBottom(rootEl.value!);
}
onBeforeMount(() => {

View File

@ -5,35 +5,33 @@ SPDX-License-Identifier: AGPL-3.0-only
<template>
<PageWithHeader reversed>
<div ref="rootEl" :class="$style.root">
<MkSpacer :contentMax="700">
<MkPagination v-if="pagination" ref="pagingComponent" :key="userId || roomId" :pagination="pagination" :disableAutoLoad="true" :scrollReversed="true">
<template #empty>
<div class="_gaps" style="text-align: center;">
<div>{{ i18n.ts.noMessagesYet }}</div>
<template v-if="user">
<div v-if="user.chatScope === 'followers'">{{ i18n.ts._chat.thisUserAllowsChatOnlyFromFollowers }}</div>
<div v-else-if="user.chatScope === 'following'">{{ i18n.ts._chat.thisUserAllowsChatOnlyFromFollowing }}</div>
<div v-else-if="user.chatScope === 'mutual'">{{ i18n.ts._chat.thisUserAllowsChatOnlyFromMutualFollowing }}</div>
<div v-else>{{ i18n.ts._chat.thisUserNotAllowedChatAnyone }}</div>
</template>
</div>
</template>
<template #default="{ items: messages }">
<TransitionGroup
:enterActiveClass="prefer.s.animation ? $style.transition_x_enterActive : ''"
:leaveActiveClass="prefer.s.animation ? $style.transition_x_leaveActive : ''"
:enterFromClass="prefer.s.animation ? $style.transition_x_enterFrom : ''"
:leaveToClass="prefer.s.animation ? $style.transition_x_leaveTo : ''"
:moveClass="prefer.s.animation ? $style.transition_x_move : ''"
tag="div" class="_gaps"
>
<XMessage v-for="message in messages.toReversed()" :key="message.id" :message="message" :user="message.fromUserId === $i.id ? $i : user" :isRoom="room != null"/>
</TransitionGroup>
</template>
</MkPagination>
</MkSpacer>
</div>
<MkSpacer :contentMax="700">
<MkPagination v-if="pagination" ref="pagingComponent" :key="userId || roomId" :pagination="pagination" :disableAutoLoad="true" :scrollReversed="true">
<template #empty>
<div class="_gaps" style="text-align: center;">
<div>{{ i18n.ts.noMessagesYet }}</div>
<template v-if="user">
<div v-if="user.chatScope === 'followers'">{{ i18n.ts._chat.thisUserAllowsChatOnlyFromFollowers }}</div>
<div v-else-if="user.chatScope === 'following'">{{ i18n.ts._chat.thisUserAllowsChatOnlyFromFollowing }}</div>
<div v-else-if="user.chatScope === 'mutual'">{{ i18n.ts._chat.thisUserAllowsChatOnlyFromMutualFollowing }}</div>
<div v-else>{{ i18n.ts._chat.thisUserNotAllowedChatAnyone }}</div>
</template>
</div>
</template>
<template #default="{ items: messages }">
<TransitionGroup
:enterActiveClass="prefer.s.animation ? $style.transition_x_enterActive : ''"
:leaveActiveClass="prefer.s.animation ? $style.transition_x_leaveActive : ''"
:enterFromClass="prefer.s.animation ? $style.transition_x_enterFrom : ''"
:leaveToClass="prefer.s.animation ? $style.transition_x_leaveTo : ''"
:moveClass="prefer.s.animation ? $style.transition_x_move : ''"
tag="div" class="_gaps"
>
<XMessage v-for="message in messages.toReversed()" :key="message.id" :message="message" :user="message.fromUserId === $i.id ? $i : user" :isRoom="room != null"/>
</TransitionGroup>
</template>
</MkPagination>
</MkSpacer>
<template #footer>
<div :class="$style.footer">
@ -77,7 +75,6 @@ const props = defineProps<{
roomId?: string;
}>();
const rootEl = useTemplateRef('rootEl');
const pagingComponent = useTemplateRef('pagingComponent');
const fetching = ref(true);
@ -107,7 +104,6 @@ async function fetch() {
userId: user.value.id,
},
reversed: true,
pageEl: rootEl.value,
};
connection.value = useStream().useChannel('chat', {
otherId: user.value.id,
@ -123,7 +119,6 @@ async function fetch() {
roomId: room?.id,
},
reversed: true,
pageEl: $$(rootEl).value,
};
connection = useStream().useChannel('chat', {
room: room?.id,
@ -141,8 +136,6 @@ async function fetch() {
function onMessage(message) {
//sound.play('chat');
//const _isBottom = isBottomVisible(rootEl, 64);
pagingComponent.value.prepend(message);
if (message.userId !== $i.id && !window.document.hidden) {
connection.value?.send('read', {
@ -150,16 +143,9 @@ function onMessage(message) {
});
}
/*
if (_isBottom) {
// Scroll to bottom
nextTick(() => {
thisScrollToBottom();
});
} else if (message.userId !== $i.id) {
// Notify
if (message.userId !== $i.id) {
notifyNewMessage();
}*/
}
}
function onDeleted(id) {
@ -169,22 +155,12 @@ function onDeleted(id) {
}
}
function thisScrollToBottom() {
scrollToBottom(rootEl.value, { behavior: 'smooth' });
}
function onIndicatorClick() {
showIndicator.value = false;
thisScrollToBottom();
}
function notifyNewMessage() {
showIndicator.value = true;
scrollRemove.value = onScrollBottom(rootEl, () => {
showIndicator.value = false;
scrollRemove.value = null;
});
}
function onVisibilitychange() {