Skip to content

Commit

Permalink
fix auto mark as read
Browse files Browse the repository at this point in the history
  • Loading branch information
ajbura committed Oct 18, 2023
1 parent 98c90e1 commit 680a0a9
Showing 1 changed file with 42 additions and 27 deletions.
69 changes: 42 additions & 27 deletions src/app/organisms/room/RoomTimeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
}

const atBottomAnchorRef = useRef<HTMLElement>(null);
const [atBottom, setAtBottom] = useState<boolean>();
const [atBottom, setAtBottom] = useState<boolean>(true);
const atBottomRef = useRef(atBottom);
atBottomRef.current = atBottom;

Expand Down Expand Up @@ -539,6 +539,8 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
typeof timeline.linkedTimelines[0]?.getPaginationToken(Direction.Backward) === 'string';
const rangeAtStart = timeline.range.start === 0;
const rangeAtEnd = timeline.range.end === eventsLength;
const atLiveEndRef = useRef(liveTimelineLinked && rangeAtEnd);
atLiveEndRef.current = liveTimelineLinked && rangeAtEnd;

const handleTimelinePagination = useTimelinePagination(
mx,
Expand Down Expand Up @@ -600,6 +602,10 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
room,
useCallback(
(mEvt: MatrixEvent) => {
// if user is at bottom of timeline
// keep paginating timeline and conditionally mark as read
// otherwise we update timeline without paginating
// so timeline can be updated with evt like: edits, reactions etc
if (atBottomRef.current && document.hasFocus()) {
if (!unreadInfo) {
markAsRead(mEvt.getRoomId());
Expand Down Expand Up @@ -636,8 +642,14 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli

// Stay at bottom when room editor resize
useResizeObserver(
useCallback(
(entries) => {
useMemo(() => {
let mounted = false;
return (entries) => {
if (!mounted) {
// skip initial mounting call
mounted = true;
return;
}
if (!roomInputRef.current) return;
const editorBaseEntry = getResizeObserverEntry(roomInputRef.current, entries);
const scrollElement = getScrollElement();
Expand All @@ -646,12 +658,23 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
if (atBottomRef.current) {
scrollToBottom(scrollElement);
}
},
[getScrollElement, roomInputRef]
),
};
}, [getScrollElement, roomInputRef]),
useCallback(() => roomInputRef.current, [roomInputRef])
);

const tryAutoMarkAsRead = useCallback(() => {
if (!unreadInfo) {
markAsRead(room.roomId);
return;
}
const evtTimeline = getEventTimeline(room, unreadInfo.readUptoEventId);
const latestTimeline = evtTimeline && getFirstLinkedTimeline(evtTimeline, Direction.Forward);
if (latestTimeline === room.getLiveTimeline()) {
markAsRead(room.roomId);
}
}, [room, unreadInfo]);

const debounceSetAtBottom = useDebounce(
useCallback((entry: IntersectionObserverEntry) => {
if (!entry.isIntersecting) setAtBottom(false);
Expand All @@ -665,9 +688,12 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
if (!target) return;
const targetEntry = getIntersectionObserverEntry(target, entries);
if (targetEntry) debounceSetAtBottom(targetEntry);
if (targetEntry?.isIntersecting) setAtBottom(true);
if (targetEntry?.isIntersecting && atLiveEndRef.current) {
setAtBottom(true);
tryAutoMarkAsRead();
}
},
[debounceSetAtBottom]
[debounceSetAtBottom, tryAutoMarkAsRead]
),
useCallback(
() => ({
Expand Down Expand Up @@ -712,23 +738,27 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
// Scroll to bottom on initial timeline load
useLayoutEffect(() => {
const scrollEl = scrollRef.current;
if (scrollEl) scrollToBottom(scrollEl);
if (scrollEl) {
scrollToBottom(scrollEl);
}
}, []);

// Scroll to last read message if it is linked to live timeline
// if live timeline is linked and unreadInfo change
// Scroll to last read message
useLayoutEffect(() => {
const { readUptoEventId, inLiveTimeline, scrollTo } = unreadInfo ?? {};
if (readUptoEventId && inLiveTimeline && scrollTo) {
const linkedTimelines = getLinkedTimelines(getLiveTimeline(room));
const evtTimeline = getEventTimeline(room, readUptoEventId);
const absoluteIndex =
evtTimeline && getEventIdAbsoluteIndex(linkedTimelines, evtTimeline, readUptoEventId);
if (absoluteIndex)
if (absoluteIndex) {
scrollToItem(absoluteIndex, {
behavior: 'instant',
align: 'start',
stopInView: true,
});
}
}
}, [room, unreadInfo, scrollToItem]);

Expand Down Expand Up @@ -756,21 +786,6 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
}
}, [scrollToBottomCount]);

// send readReceipts when reach bottom
useEffect(() => {
if (liveTimelineLinked && rangeAtEnd && atBottom && document.hasFocus()) {
if (!unreadInfo) {
markAsRead(room.roomId);
return;
}
const evtTimeline = getEventTimeline(room, unreadInfo.readUptoEventId);
const latestTimeline = evtTimeline && getFirstLinkedTimeline(evtTimeline, Direction.Forward);
if (latestTimeline === room.getLiveTimeline()) {
markAsRead(room.roomId);
}
}
}, [room, unreadInfo, liveTimelineLinked, rangeAtEnd, atBottom]);

// Remove unreadInfo on mark as read
useEffect(() => {
const handleFullRead = (rId: string) => {
Expand Down Expand Up @@ -1733,7 +1748,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
<span ref={atBottomAnchorRef} />
</Box>
</Scroll>
{(atBottom === false || !liveTimelineLinked || !rangeAtEnd) && (
{!atBottom && (
<TimelineFloat position="Bottom">
<Chip
variant="SurfaceVariant"
Expand Down

0 comments on commit 680a0a9

Please sign in to comment.