diff --git a/client/src/components/History/HistoryScrollList.vue b/client/src/components/History/HistoryScrollList.vue index 55d3e4f8da59..a2a69921fb09 100644 --- a/client/src/components/History/HistoryScrollList.vue +++ b/client/src/components/History/HistoryScrollList.vue @@ -10,6 +10,8 @@ import { computed, onMounted, onUnmounted, type PropType, type Ref, ref, watch } import { useRouter } from "vue-router/composables"; import type { HistoryDetailed, HistorySummary } from "@/api"; +import { useAnimationFrameResizeObserver } from "@/composables/sensors/animationFrameResizeObserver"; +import { useAnimationFrameScroll } from "@/composables/sensors/animationFrameScroll"; import { useHistoryStore } from "@/stores/historyStore"; import { useUserStore } from "@/stores/userStore"; import localize from "@/utils/localization"; @@ -55,6 +57,15 @@ const hasNoResults = computed(() => props.filter && filtered.value.length == 0); const validFilter = computed(() => props.filter && props.filter.length > 2); const allLoaded = computed(() => totalHistoryCount.value <= filtered.value.length); +// check if we have scrolled to the top or bottom of the scrollable div +const { arrived } = useAnimationFrameScroll(scrollableDiv); +const isScrollable = ref(false); +useAnimationFrameResizeObserver(scrollableDiv, ({ clientSize, scrollSize }) => { + isScrollable.value = scrollSize.height >= clientSize.height + 1; +}); +const scrolledTop = computed(() => !isScrollable.value || arrived.top); +const scrolledBottom = computed(() => !isScrollable.value || arrived.bottom); + onMounted(async () => { useInfiniteScroll(scrollableDiv.value, () => loadMore()); // if mounted with a filter, load histories for filter @@ -190,7 +201,13 @@ async function loadMore(noScroll = false) { No histories found. -
+