feat: implement scroll position retention
This commit is contained in:
parent
acca8468f0
commit
010472c83d
4 changed files with 59 additions and 1 deletions
|
@ -20,7 +20,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { MessageResponse } from '~/types/interfaces';
|
import type { MessageResponse, ScrollPosition } from '~/types/interfaces';
|
||||||
import scrollToBottom from '~/utils/scrollToBottom';
|
import scrollToBottom from '~/utils/scrollToBottom';
|
||||||
|
|
||||||
const props = defineProps<{ channelUrl: string, amount?: number, offset?: number }>();
|
const props = defineProps<{ channelUrl: string, amount?: number, offset?: number }>();
|
||||||
|
@ -207,6 +207,34 @@ onMounted(async () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
let scrollPosition = ref<Record<string, ScrollPosition>>({});
|
||||||
|
|
||||||
|
onActivated(async () => {
|
||||||
|
await nextTick();
|
||||||
|
console.log("scroll activated");
|
||||||
|
if (messagesElement.value) {
|
||||||
|
if (scrollPosition.value[route.params.channelId as string]) {
|
||||||
|
console.log("saved scroll position:", scrollPosition.value);
|
||||||
|
setScrollPosition(messagesElement.value, scrollPosition.value[route.params.channelId as string]);
|
||||||
|
console.log("scrolled to saved scroll position");
|
||||||
|
} else {
|
||||||
|
scrollToBottom(messagesElement.value);
|
||||||
|
console.log("scrolled to bottom");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
console.log("scroll hi");
|
||||||
|
if (messagesElement.value && from.params.channelId) {
|
||||||
|
scrollPosition.value[from.params.channelId as string] = getScrollPosition(messagesElement.value)
|
||||||
|
console.log("set saved scroll position to:", scrollPosition.value);
|
||||||
|
}
|
||||||
|
next()
|
||||||
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|
|
@ -70,3 +70,14 @@ export interface StatsResponse {
|
||||||
email_verification_required: boolean,
|
email_verification_required: boolean,
|
||||||
build_number: string
|
build_number: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ScrollPosition {
|
||||||
|
scrollHeight: number,
|
||||||
|
scrollWidth: number,
|
||||||
|
scrollTop: number,
|
||||||
|
scrollLeft: number
|
||||||
|
offsetHeight: number,
|
||||||
|
offsetWidth: number,
|
||||||
|
offsetTop: number,
|
||||||
|
offsetLeft: number
|
||||||
|
}
|
||||||
|
|
14
utils/getScrollPosition.ts
Normal file
14
utils/getScrollPosition.ts
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import type { ScrollPosition } from "~/types/interfaces";
|
||||||
|
|
||||||
|
export default (element: HTMLElement): ScrollPosition => {
|
||||||
|
return {
|
||||||
|
scrollHeight: element.scrollHeight,
|
||||||
|
scrollWidth: element.scrollWidth,
|
||||||
|
scrollTop: element.scrollTop,
|
||||||
|
scrollLeft: element.scrollLeft,
|
||||||
|
offsetHeight: element.offsetHeight,
|
||||||
|
offsetWidth: element.offsetWidth,
|
||||||
|
offsetTop: element.offsetTop,
|
||||||
|
offsetLeft: element.offsetLeft
|
||||||
|
};
|
||||||
|
}
|
5
utils/setScrollPosition.ts
Normal file
5
utils/setScrollPosition.ts
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
import type { ScrollPosition } from "~/types/interfaces";
|
||||||
|
|
||||||
|
export default (element: HTMLElement, scrollPosition: ScrollPosition) => {
|
||||||
|
return element.scrollTo({ top: scrollPosition.scrollTop, left: scrollPosition.scrollLeft });
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue