Skip to content

Commit

Permalink
send read-receipt when new message are in view after regaining focus
Browse files Browse the repository at this point in the history
  • Loading branch information
ajbura committed Feb 19, 2025
1 parent eeae519 commit 2b076fe
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 14 deletions.
23 changes: 17 additions & 6 deletions src/app/features/room/RoomTimeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -618,17 +618,22 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
);

const handleOpenEvent = useCallback(
async (evtId: string, highlight = true) => {
async (
evtId: string,
highlight = true,
onScroll: ((scrolled: boolean) => void) | undefined = undefined
) => {
const evtTimeline = getEventTimeline(room, evtId);
const absoluteIndex =
evtTimeline && getEventIdAbsoluteIndex(timeline.linkedTimelines, evtTimeline, evtId);

if (typeof absoluteIndex === 'number') {
scrollToItem(absoluteIndex, {
const scrolled = scrollToItem(absoluteIndex, {
behavior: 'smooth',
align: 'center',
stopInView: true,
});
if (onScroll) onScroll(scrolled);
setFocusItem({
index: absoluteIndex,
scrollTo: false,
Expand Down Expand Up @@ -722,11 +727,17 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
useDocumentFocusChange(
useCallback(
(inFocus) => {
if (inFocus && unreadInfo?.inLiveTimeline) {
handleOpenEvent(unreadInfo.readUptoEventId, false);
return;
}
if (inFocus && atBottomRef.current) {
if (unreadInfo?.inLiveTimeline) {
handleOpenEvent(unreadInfo.readUptoEventId, false, (scrolled) => {
// the unread event is already in view
// so, try mark as read;
if (!scrolled) {
tryAutoMarkAsRead();
}
});
return;
}
tryAutoMarkAsRead();
}
},
Expand Down
32 changes: 24 additions & 8 deletions src/app/hooks/useVirtualPaginator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,23 @@ export type ScrollToOptions = {
stopInView?: boolean;
};

export type ScrollToElement = (element: HTMLElement, opts?: ScrollToOptions) => void;
export type ScrollToItem = (index: number, opts?: ScrollToOptions) => void;
/**
* Scrolls the page to a specified element in the DOM.
*
* @param {HTMLElement} element - The DOM element to scroll to.
* @param {ScrollToOptions} [opts] - Optional configuration for the scroll behavior (e.g., smooth scrolling, alignment).
* @returns {boolean} - Returns `true` if the scroll was successful, otherwise returns `false`.
*/
export type ScrollToElement = (element: HTMLElement, opts?: ScrollToOptions) => boolean;

/**
* Scrolls the page to an item at the specified index within a scrollable container.
*
* @param {number} index - The index of the item to scroll to.
* @param {ScrollToOptions} [opts] - Optional configuration for the scroll behavior (e.g., smooth scrolling, alignment).
* @returns {boolean} - Returns `true` if the scroll was successful, otherwise returns `false`.
*/
export type ScrollToItem = (index: number, opts?: ScrollToOptions) => boolean;

type HandleObserveAnchor = (element: HTMLElement | null) => void;

Expand Down Expand Up @@ -186,10 +201,10 @@ export const useVirtualPaginator = <TScrollElement extends HTMLElement>(
const scrollToElement = useCallback<ScrollToElement>(
(element, opts) => {
const scrollElement = getScrollElement();
if (!scrollElement) return;
if (!scrollElement) return false;

if (opts?.stopInView && isInScrollView(scrollElement, element)) {
return;
return false;
}
let scrollTo = element.offsetTop;
if (opts?.align === 'center' && canFitInScrollView(scrollElement, element)) {
Expand All @@ -207,6 +222,7 @@ export const useVirtualPaginator = <TScrollElement extends HTMLElement>(
top: scrollTo - (opts?.offset ?? 0),
behavior: opts?.behavior,
});
return true;
},
[getScrollElement]
);
Expand All @@ -215,7 +231,7 @@ export const useVirtualPaginator = <TScrollElement extends HTMLElement>(
(index, opts) => {
const { range: currentRange, limit: currentLimit, count: currentCount } = propRef.current;

if (index < 0 || index >= currentCount) return;
if (index < 0 || index >= currentCount) return false;
// index is not in range change range
// and trigger scrollToItem in layoutEffect hook
if (index < currentRange.start || index >= currentRange.end) {
Expand All @@ -227,7 +243,7 @@ export const useVirtualPaginator = <TScrollElement extends HTMLElement>(
index,
opts,
};
return;
return true;
}

// find target or it's previous rendered element to scroll to
Expand All @@ -241,9 +257,9 @@ export const useVirtualPaginator = <TScrollElement extends HTMLElement>(
top: opts?.offset ?? 0,
behavior: opts?.behavior,
});
return;
return true;
}
scrollToElement(itemElement, opts);
return scrollToElement(itemElement, opts);
},
[getScrollElement, scrollToElement, getItemElement, onRangeChange]
);
Expand Down

0 comments on commit 2b076fe

Please # to comment.