From 5dc613cd7957e06f2c29692a3b0d6d7e79311860 Mon Sep 17 00:00:00 2001 From: Ajay Bura <32841439+ajbura@users.noreply.github.com> Date: Sat, 21 Oct 2023 18:14:21 +1100 Subject: [PATCH] Fix auto read (#1466) * add height to bottom anchor * add width to bottom anchor * add make bottom anchor inline-block * try mark as read on focus receive --- src/app/hooks/useDocumentFocusChange.ts | 25 +++++++++++++++++++++ src/app/organisms/room/RoomTimeline.tsx | 30 ++++++++++++++++++------- 2 files changed, 47 insertions(+), 8 deletions(-) create mode 100644 src/app/hooks/useDocumentFocusChange.ts diff --git a/src/app/hooks/useDocumentFocusChange.ts b/src/app/hooks/useDocumentFocusChange.ts new file mode 100644 index 0000000..ae171b6 --- /dev/null +++ b/src/app/hooks/useDocumentFocusChange.ts @@ -0,0 +1,25 @@ +import { useEffect } from 'react'; + +export const useDocumentFocusChange = (onChange: (focus: boolean) => void) => { + useEffect(() => { + let localFocus = document.hasFocus(); + + const handleFocus = () => { + if (document.hasFocus()) { + if (localFocus) return; + localFocus = true; + onChange(localFocus); + } else if (localFocus) { + localFocus = false; + onChange(localFocus); + } + }; + + document.addEventListener('focusin', handleFocus); + document.addEventListener('focusout', handleFocus); + return () => { + document.removeEventListener('focusin', handleFocus); + document.removeEventListener('focusout', handleFocus); + }; + }, [onChange]); +}; diff --git a/src/app/organisms/room/RoomTimeline.tsx b/src/app/organisms/room/RoomTimeline.tsx index bc81081..2a22245 100644 --- a/src/app/organisms/room/RoomTimeline.tsx +++ b/src/app/organisms/room/RoomTimeline.tsx @@ -133,6 +133,7 @@ import { MessageEvent } from '../../../types/matrix/room'; import initMatrix from '../../../client/initMatrix'; import { useKeyDown } from '../../hooks/useKeyDown'; import cons from '../../../client/state/cons'; +import { useDocumentFocusChange } from '../../hooks/useDocumentFocusChange'; const TimelineFloat = as<'div', css.TimelineFloatVariants>( ({ position, className, ...props }, ref) => ( @@ -606,13 +607,15 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli // 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()); + if (atBottomRef.current) { + if (document.hasFocus() && (!unreadInfo || mEvt.getSender() === mx.getUserId())) { + requestAnimationFrame(() => markAsRead(mEvt.getRoomId())); } - scrollToBottomRef.current.count += 1; - scrollToBottomRef.current.smooth = true; + if (document.hasFocus()) { + scrollToBottomRef.current.count += 1; + scrollToBottomRef.current.smooth = true; + } setTimeline((ct) => ({ ...ct, range: { @@ -627,7 +630,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli setUnreadInfo(getRoomUnreadInfo(room)); } }, - [room, unreadInfo] + [mx, room, unreadInfo] ) ); @@ -665,13 +668,13 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli const tryAutoMarkAsRead = useCallback(() => { if (!unreadInfo) { - markAsRead(room.roomId); + requestAnimationFrame(() => markAsRead(room.roomId)); return; } const evtTimeline = getEventTimeline(room, unreadInfo.readUptoEventId); const latestTimeline = evtTimeline && getFirstLinkedTimeline(evtTimeline, Direction.Forward); if (latestTimeline === room.getLiveTimeline()) { - markAsRead(room.roomId); + requestAnimationFrame(() => markAsRead(room.roomId)); } }, [room, unreadInfo]); @@ -705,6 +708,17 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli useCallback(() => atBottomAnchorRef.current, []) ); + useDocumentFocusChange( + useCallback( + (inFocus) => { + if (inFocus && atBottomRef.current) { + tryAutoMarkAsRead(); + } + }, + [tryAutoMarkAsRead] + ) + ); + // Handle up arrow edit useKeyDown( window,