diff --git a/src/components/BackToTop.vue b/src/components/BackToTop.vue
index 54403c35..926821d0 100644
--- a/src/components/BackToTop.vue
+++ b/src/components/BackToTop.vue
@@ -5,12 +5,15 @@
import { Button } from '@/components/ui/button';
const props = defineProps({
+ // scroll DOM ref
target: { type: [String, Object], default: null },
+ // @tanstack/virtual instance
+ virtualizer: { type: [Object], default: null },
bottom: { type: Number, default: 20 },
right: { type: Number, default: 20 },
- visibilityHeight: { type: Number, default: 200 },
+ visibilityHeight: { type: Number, default: 400 },
behavior: {
type: String,
@@ -21,28 +24,26 @@
tooltip: { type: Boolean, default: true },
tooltipText: { type: String, default: 'Back to top' },
- teleport: { type: Boolean, default: true }
+ teleport: { type: Boolean, default: true },
+ teleportTo: { type: [Boolean, String, Object], default: null }
});
const visible = ref(false);
let containerEl = null;
- function resolveTarget() {
- if (!props.target) return null;
- if (typeof props.target === 'string') {
- return document.querySelector(props.target);
+ function resolveElement(target) {
+ if (!target) return null;
+ if (typeof target === 'string') return document.querySelector(target);
+ if (typeof target === 'object') {
+ if ('value' in target) return target.value;
+ if ('$el' in target) return target.$el;
}
+ return target;
+ }
- if (typeof props.target === 'object') {
- if ('value' in props.target) {
- return props.target.value;
- }
- if ('$el' in props.target) {
- return props.target.$el;
- }
- }
-
- return props.target;
+ function getVirtualizer() {
+ if (!props.virtualizer) return null;
+ return 'value' in props.virtualizer ? props.virtualizer.value : props.virtualizer;
}
function getScrollTop() {
@@ -58,15 +59,21 @@
function scrollToTop() {
const behavior = props.behavior === 'auto' ? 'auto' : 'smooth';
- if (!containerEl || typeof containerEl.scrollTo !== 'function') {
- window.scrollTo({ top: 0, behavior });
+ const v = getVirtualizer();
+ if (v?.scrollToIndex) {
+ v.scrollToIndex(0, { align: 'start', behavior: 'auto' });
return;
}
- containerEl.scrollTo({ top: 0, behavior });
+ const target = containerEl || resolveElement(props.target);
+ if (target && typeof target.scrollTo === 'function') {
+ target.scrollTo({ top: 0, behavior });
+ return;
+ }
+ window.scrollTo({ top: 0, behavior });
}
function bind() {
- containerEl = resolveTarget();
+ containerEl = resolveElement(props.target);
const target = containerEl && typeof containerEl.addEventListener === 'function' ? containerEl : window;
target.addEventListener('scroll', handleScroll, { passive: true });
@@ -94,13 +101,25 @@
unbind();
});
+ const teleportTarget = computed(() => {
+ if (props.teleportTo !== null && props.teleportTo !== undefined) {
+ if (props.teleportTo === true) return 'body';
+ if (props.teleportTo === false) return null;
+ return resolveElement(props.teleportTo);
+ }
+ return props.teleport ? 'body' : null;
+ });
+
+ const isBodyTeleport = computed(() => teleportTarget.value === 'body' || teleportTarget.value === document.body);
+
const wrapperStyle = computed(
- () => `position:fixed; right:${props.right}px; bottom:${props.bottom}px; z-index:50;`
+ () =>
+ `position:${isBodyTeleport.value ? 'fixed' : 'absolute'}; right:${props.right}px; bottom:${props.bottom}px; z-index:50;`
);
-
+
@@ -115,7 +134,7 @@
-
+
{{ tooltipText }}
@@ -136,7 +155,26 @@
+
+
+
+
+
+
+ {{ tooltipText }}
+
+
+
+
-
+
@@ -107,7 +107,7 @@
import { isRealInstance, userImage, userStatusClass } from '../../../shared/utils';
import { getFriendsLocations } from '../../../shared/utils/location.js';
- import BackToTopVirtual from '../../../components/BackToTopVirtual.vue';
+ import BackToTop from '../../../components/BackToTop.vue';
import FriendItem from './FriendItem.vue';
import Location from '../../../components/Location.vue';
import configRepository from '../../../service/config';
diff --git a/src/views/Sidebar/components/GroupsSidebar.vue b/src/views/Sidebar/components/GroupsSidebar.vue
index cd3818dc..357ffaa9 100644
--- a/src/views/Sidebar/components/GroupsSidebar.vue
+++ b/src/views/Sidebar/components/GroupsSidebar.vue
@@ -52,7 +52,7 @@
-
+
@@ -65,7 +65,7 @@
import { useAppearanceSettingsStore, useGroupStore } from '../../../stores';
import { convertFileUrlToImageUrl } from '../../../shared/utils';
- import BackToTopVirtual from '../../../components/BackToTopVirtual.vue';
+ import BackToTop from '../../../components/BackToTop.vue';
import Location from '../../../components/Location.vue';
const { isAgeGatedInstancesVisible } = storeToRefs(useAppearanceSettingsStore());