Skip to content

Commit

Permalink
fix: jump to message sometimes not working
Browse files Browse the repository at this point in the history
  • Loading branch information
szuperaz committed Nov 14, 2024
1 parent c512116 commit 4b7b9f2
Showing 1 changed file with 80 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ export class MessageListComponent
private checkIfUnreadNotificationIsVisibleTimeout?: ReturnType<
typeof setTimeout
>;
private jumpToMessageTimeouts: ReturnType<typeof setTimeout>[] = [];
private jumpToLatestButtonVisibilityTimeout?: ReturnType<typeof setTimeout>;
private forceRepaintSubject = new Subject<void>();
private messageIdToAnchorTo?: string;
Expand Down Expand Up @@ -202,6 +203,11 @@ export class MessageListComponent
if (this.checkIfUnreadNotificationIsVisibleTimeout) {
clearTimeout(this.checkIfUnreadNotificationIsVisibleTimeout);
}
this.jumpToMessageTimeouts.forEach((timeout) =>
clearTimeout(timeout)
);
this.jumpToMessageTimeouts = [];
this.highlightedMessageId = undefined;
this.isUnreadNotificationVisible = false;
this.parsedDates = new Map();
this.resetScrollState();
Expand Down Expand Up @@ -445,6 +451,7 @@ export class MessageListComponent
if (this.jumpToLatestButtonVisibilityTimeout) {
clearTimeout(this.jumpToLatestButtonVisibilityTimeout);
}
this.jumpToMessageTimeouts.forEach((timeout) => clearTimeout(timeout));
this.disposeVirtualizedList();
}

Expand Down Expand Up @@ -501,22 +508,10 @@ export class MessageListComponent
this.isJumpToLatestButtonVisible = true;
}
}

this.scroll$.next();
let scrollPosition = this.getScrollPosition();

const isUserScrolled =
(this.direction === 'bottom-to-top'
? scrollPosition !== 'bottom'
: scrollPosition !== 'top') || !this.isLatestMessageInList;
if (this.isUserScrolled !== isUserScrolled) {
this.ngZone.run(() => {
this.isUserScrolled = isUserScrolled;
if (!this.isUserScrolled) {
this.newMessageCountWhileBeingScrolled = 0;
}
this.cdRef.detectChanges();
});
}
this.checkIfUserScrolled();

if (this.hideJumpToLatestButtonDuringScroll) {
if (this.isJumpToLatestButtonVisible) {
Expand All @@ -534,35 +529,6 @@ export class MessageListComponent
}
}, 100);
}

const prevScrollPosition = this.scrollPosition$.getValue();

if (this.direction === 'top-to-bottom') {
if (scrollPosition === 'top') {
scrollPosition = 'bottom';
} else if (scrollPosition === 'bottom') {
scrollPosition = 'top';
}
}

if (prevScrollPosition !== scrollPosition && !this.isJumpingToMessage) {
if (scrollPosition === 'top' || scrollPosition === 'bottom') {
this.virtualizedList?.virtualizedItems$
.pipe(take(1))
.subscribe((items) => {
this.messageIdToAnchorTo =
scrollPosition === 'top'
? items[0]?.id
: items[items.length - 1]?.id;
this.anchorMessageTopOffset = document
.getElementById(this.messageIdToAnchorTo)
?.getBoundingClientRect()?.top;
});
}
this.ngZone.run(() => {
this.scrollPosition$.next(scrollPosition);
});
}
}

jumpToFirstUnreadMessage() {
Expand Down Expand Up @@ -611,6 +577,53 @@ export class MessageListComponent
: this.emptyThreadMessageListTemplate;
}

private checkIfUserScrolled() {
let scrollPosition = this.getScrollPosition();

const isUserScrolled =
(this.direction === 'bottom-to-top'
? scrollPosition !== 'bottom'
: scrollPosition !== 'top') || !this.isLatestMessageInList;
if (this.isUserScrolled !== isUserScrolled) {
this.ngZone.run(() => {
this.isUserScrolled = isUserScrolled;
if (!this.isUserScrolled) {
this.newMessageCountWhileBeingScrolled = 0;
}
this.cdRef.detectChanges();
});
}

const prevScrollPosition = this.scrollPosition$.getValue();

if (this.direction === 'top-to-bottom') {
if (scrollPosition === 'top') {
scrollPosition = 'bottom';
} else if (scrollPosition === 'bottom') {
scrollPosition = 'top';
}
}

if (prevScrollPosition !== scrollPosition && !this.isJumpingToMessage) {
if (scrollPosition === 'top' || scrollPosition === 'bottom') {
this.virtualizedList?.virtualizedItems$
.pipe(take(1))
.subscribe((items) => {
this.messageIdToAnchorTo =
scrollPosition === 'top'
? items[0]?.id
: items[items.length - 1]?.id;
this.anchorMessageTopOffset = document
.getElementById(this.messageIdToAnchorTo)
?.getBoundingClientRect()?.top;
});
}
this.ngZone.run(() => {
this.scrollPosition$.next(scrollPosition);
});
}
}

private preserveScrollbarPosition() {
if (!this.messageIdToAnchorTo) {
return;
Expand Down Expand Up @@ -792,32 +805,46 @@ export class MessageListComponent
withRetry: boolean = true
) {
const element = document.getElementById(options.messageId);
this.jumpToMessageTimeouts.forEach((t) => clearTimeout(t));
this.jumpToMessageTimeouts = [];
if (!element && withRetry) {
// If the message was newly inserted into activeChannelMessages$, the message will be rendered after the current change detection cycle -> wait for this cycle to complete
setTimeout(() => this.scrollMessageIntoView(options, false));
this.jumpToMessageTimeouts.push(
setTimeout(() => this.scrollMessageIntoView(options, false))
);
} else if (element) {
const blockMapping: { [key: string]: ScrollLogicalPosition } = {
top: 'start',
bottom: 'end',
middle: 'center',
};
// We can't know when smooth scrolling ends, so we set the behavior to instant https://github.com/w3c/csswg-drafts/issues/3744
element.scrollIntoView({
behavior: 'instant' as ScrollBehavior,
block: blockMapping[options.position],
});
if (options.position !== 'middle') {
options.position === 'bottom'
? this.scrollToBottom()
: this.scrollToTop();
}
setTimeout(() => {
this.isJumpingToMessage = false;
}, 0);
setTimeout(() => {
this.highlightedMessageId = undefined;
this.firstUnreadMessageId = undefined;
this.isJumpingToLatestUnreadMessage = false;
this.cdRef.detectChanges();
}, 1000);
this.jumpToMessageTimeouts.push(
setTimeout(() => {
this.isJumpingToMessage = false;
if (!this.isUserScrolled) {
this.checkIfUserScrolled();
}
}, 200)
);
this.jumpToMessageTimeouts.push(
setTimeout(() => {
this.highlightedMessageId = undefined;
this.firstUnreadMessageId = undefined;
this.isJumpingToLatestUnreadMessage = false;
this.jumpToMessageTimeouts = [];
this.cdRef.detectChanges();
}, 1000)
);
}
}

Expand Down

0 comments on commit 4b7b9f2

Please sign in to comment.