- Chat messages are now loaded based on scroll position - Read status is now updated and set by last message read - Reworked script importing by using ScriptProvider
77 lines
No EOL
2.3 KiB
TypeScript
77 lines
No EOL
2.3 KiB
TypeScript
import { InfiniteScrollAnchor } from "./InfiniteScrollAnchor";
|
|
|
|
export class InfiniteScroll {
|
|
public scrollHost: Element;
|
|
public sentinel: Element;
|
|
public dotnet: any;
|
|
|
|
public static Create(dotnet: any, scrollHost: Element, sentinel: Element): InfiniteScroll {
|
|
return new InfiniteScroll(dotnet, scrollHost, sentinel);
|
|
}
|
|
|
|
constructor(dotnet: any, scrollHost: Element, sentinel: Element) {
|
|
this.dotnet = dotnet;
|
|
this.scrollHost = scrollHost;
|
|
this.sentinel = sentinel;
|
|
}
|
|
|
|
ObserveSentinel() {
|
|
const observer = new IntersectionObserver((entries) => {
|
|
for (const entry of entries) {
|
|
if (entry.isIntersecting) {
|
|
this.dotnet.invokeMethodAsync("OnSentinelVisible");
|
|
}
|
|
}
|
|
}, {
|
|
root: this.scrollHost,
|
|
threshold: 0.01
|
|
});
|
|
|
|
observer.observe(this.sentinel);
|
|
}
|
|
|
|
CaptureAnchor(): InfiniteScrollAnchor {
|
|
const first = this.scrollHost.querySelector("[data-id]");
|
|
|
|
if (!first)
|
|
return null;
|
|
|
|
const rect = first.getBoundingClientRect();
|
|
const hostRect = this.scrollHost.getBoundingClientRect();
|
|
|
|
const anchor = new InfiniteScrollAnchor();
|
|
|
|
anchor.Id = first.getAttribute("data-id");
|
|
anchor.OffsetTop = rect.top - hostRect.top;
|
|
|
|
return anchor;
|
|
}
|
|
|
|
RestoreAfterPrepend(anchor: InfiniteScrollAnchor) {
|
|
if (!anchor)
|
|
return;
|
|
|
|
const el = this.scrollHost.querySelector(`[data-id="${anchor.Id}"]`);
|
|
|
|
if (!el)
|
|
return;
|
|
|
|
const rect = el.getBoundingClientRect();
|
|
const hostRect = this.scrollHost.getBoundingClientRect();
|
|
const newOffset = rect.top - hostRect.top;
|
|
|
|
this.scrollHost.scrollTop += (newOffset - anchor.OffsetTop);
|
|
}
|
|
|
|
IsSentinelVisible(): boolean {
|
|
const rect = this.sentinel.getBoundingClientRect();
|
|
const hostRect = this.scrollHost.getBoundingClientRect();
|
|
|
|
// Check if sentinel is within the visible area of the scroll host
|
|
return rect.top >= hostRect.top && rect.top <= hostRect.bottom;
|
|
}
|
|
|
|
ScrollToBottom() {
|
|
this.scrollHost.scrollTop = this.scrollHost.scrollHeight;
|
|
}
|
|
} |