feat: implement useMarkAsRead hook for improved unread state management and update notification handling
This commit is contained in:
@@ -29,7 +29,7 @@ import { useRoomUnread } from '../../state/hooks/unread';
|
||||
import { roomToUnreadAtom } from '../../state/room/roomToUnread';
|
||||
import { usePowerLevels } from '../../hooks/usePowerLevels';
|
||||
import { copyToClipboard } from '../../utils/dom';
|
||||
import { markAsRead } from '../../utils/notifications';
|
||||
import { useMarkAsRead } from '../../hooks/useMarkAsRead';
|
||||
import { UseStateProvider } from '../../components/UseStateProvider';
|
||||
import { LeaveRoomPrompt } from '../../components/leave-room-prompt';
|
||||
import { useRoomTypingMember } from '../../hooks/useRoomTypingMembers';
|
||||
@@ -68,6 +68,7 @@ const RoomNavItemMenu = forwardRef<HTMLDivElement, RoomNavItemMenuProps>(
|
||||
const powerLevels = usePowerLevels(room);
|
||||
const creators = useRoomCreators(room);
|
||||
const { startCall, endCall, activeCall, callSupported } = useCall();
|
||||
const markAsRead = useMarkAsRead(mx);
|
||||
|
||||
const permissions = useRoomPermissions(creators, powerLevels);
|
||||
const canInvite = permissions.action('invite', mx.getSafeUserId());
|
||||
@@ -77,7 +78,7 @@ const RoomNavItemMenu = forwardRef<HTMLDivElement, RoomNavItemMenuProps>(
|
||||
const [invitePrompt, setInvitePrompt] = useState(false);
|
||||
|
||||
const handleMarkAsRead = () => {
|
||||
markAsRead(mx, room.roomId, hideActivity);
|
||||
markAsRead(room.roomId, hideActivity);
|
||||
requestClose();
|
||||
};
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ import { settingsAtom } from '../../state/settings';
|
||||
import { PowerLevelsContextProvider, usePowerLevels } from '../../hooks/usePowerLevels';
|
||||
import { useRoom } from '../../hooks/useRoom';
|
||||
import { useKeyDown } from '../../hooks/useKeyDown';
|
||||
import { markAsRead } from '../../utils/notifications';
|
||||
import { useMarkAsRead } from '../../hooks/useMarkAsRead';
|
||||
import { useMatrixClient } from '../../hooks/useMatrixClient';
|
||||
import { useRoomMembers } from '../../hooks/useRoomMembers';
|
||||
import { activeRoomIdAtom } from '../../state/activeRoom';
|
||||
@@ -27,6 +27,7 @@ export function Room() {
|
||||
const screenSize = useScreenSizeContext();
|
||||
const powerLevels = usePowerLevels(room);
|
||||
const members = useRoomMembers(mx, room.roomId);
|
||||
const markAsRead = useMarkAsRead(mx);
|
||||
|
||||
// Update titlebar with current room ID
|
||||
useEffect(() => {
|
||||
@@ -39,10 +40,10 @@ export function Room() {
|
||||
useCallback(
|
||||
(evt) => {
|
||||
if (isKeyHotkey('escape', evt)) {
|
||||
markAsRead(mx, room.roomId, hideActivity);
|
||||
markAsRead(room.roomId, hideActivity);
|
||||
}
|
||||
},
|
||||
[mx, room.roomId, hideActivity]
|
||||
[markAsRead, room.roomId, hideActivity]
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ import {
|
||||
getIntersectionObserverEntry,
|
||||
useIntersectionObserver,
|
||||
} from '../../hooks/useIntersectionObserver';
|
||||
import { markAsRead } from '../../utils/notifications';
|
||||
import { useMarkAsRead } from '../../hooks/useMarkAsRead';
|
||||
import { useDebounce } from '../../hooks/useDebounce';
|
||||
import { getResizeObserverEntry, useResizeObserver } from '../../hooks/useResizeObserver';
|
||||
import * as css from './RoomTimeline.css';
|
||||
@@ -508,6 +508,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
|
||||
const spoilerClickHandler = useSpoilerClickHandler();
|
||||
const openUserRoomProfile = useOpenUserRoomProfile();
|
||||
const space = useSpaceOptionally();
|
||||
const markAsRead = useMarkAsRead(mx);
|
||||
|
||||
const imagePackRooms: Room[] = useImagePackRooms(room.roomId, roomToParents);
|
||||
|
||||
@@ -641,7 +642,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
|
||||
// Check if the document is in focus (user is actively viewing the app),
|
||||
// and either there are no unread messages or the latest message is from the current user.
|
||||
// If either condition is met, trigger the markAsRead function to send a read receipt.
|
||||
requestAnimationFrame(() => markAsRead(mx, mEvt.getRoomId()!, hideActivity));
|
||||
requestAnimationFrame(() => markAsRead(mEvt.getRoomId()!, hideActivity));
|
||||
}
|
||||
|
||||
if (!document.hasFocus() && !unreadInfo) {
|
||||
@@ -665,7 +666,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
|
||||
setUnreadInfo(getRoomUnreadInfo(room));
|
||||
}
|
||||
},
|
||||
[mx, room, unreadInfo, hideActivity]
|
||||
[mx, room, unreadInfo, hideActivity, markAsRead]
|
||||
)
|
||||
);
|
||||
|
||||
@@ -734,15 +735,15 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
|
||||
const tryAutoMarkAsRead = useCallback(() => {
|
||||
const readUptoEventId = readUptoEventIdRef.current;
|
||||
if (!readUptoEventId) {
|
||||
requestAnimationFrame(() => markAsRead(mx, room.roomId, hideActivity));
|
||||
requestAnimationFrame(() => markAsRead(room.roomId, hideActivity));
|
||||
return;
|
||||
}
|
||||
const evtTimeline = getEventTimeline(room, readUptoEventId);
|
||||
const latestTimeline = evtTimeline && getFirstLinkedTimeline(evtTimeline, Direction.Forward);
|
||||
if (latestTimeline === room.getLiveTimeline()) {
|
||||
requestAnimationFrame(() => markAsRead(mx, room.roomId, hideActivity));
|
||||
requestAnimationFrame(() => markAsRead(room.roomId, hideActivity));
|
||||
}
|
||||
}, [mx, room, hideActivity]);
|
||||
}, [room, hideActivity, markAsRead]);
|
||||
|
||||
const debounceSetAtBottom = useDebounce(
|
||||
useCallback((entry: IntersectionObserverEntry) => {
|
||||
@@ -946,7 +947,7 @@ export function RoomTimeline({ room, eventId, roomInputRef, editor }: RoomTimeli
|
||||
};
|
||||
|
||||
const handleMarkAsRead = () => {
|
||||
markAsRead(mx, room.roomId, hideActivity);
|
||||
markAsRead(room.roomId, hideActivity);
|
||||
};
|
||||
|
||||
const handleOpenReply: MouseEventHandler = useCallback(
|
||||
|
||||
@@ -44,8 +44,8 @@ import { _SearchPathSearchParams } from '../../pages/paths';
|
||||
import * as css from './RoomViewHeader.css';
|
||||
import { useRoomUnread } from '../../state/hooks/unread';
|
||||
import { usePowerLevelsContext } from '../../hooks/usePowerLevels';
|
||||
import { markAsRead } from '../../utils/notifications';
|
||||
import { roomToUnreadAtom } from '../../state/room/roomToUnread';
|
||||
import { useMarkAsRead } from '../../hooks/useMarkAsRead';
|
||||
import { copyToClipboard } from '../../utils/dom';
|
||||
import { LeaveRoomPrompt } from '../../components/leave-room-prompt';
|
||||
import { useRoomAvatar, useRoomName, useRoomTopic } from '../../hooks/useRoomMeta';
|
||||
@@ -91,11 +91,12 @@ const RoomMenu = forwardRef<HTMLDivElement, RoomMenuProps>(({ room, requestClose
|
||||
const notificationPreferences = useRoomsNotificationPreferencesContext();
|
||||
const notificationMode = getRoomNotificationMode(notificationPreferences, room.roomId);
|
||||
const { navigateRoom } = useRoomNavigate();
|
||||
const markAsRead = useMarkAsRead(mx);
|
||||
|
||||
const [invitePrompt, setInvitePrompt] = useState(false);
|
||||
|
||||
const handleMarkAsRead = () => {
|
||||
markAsRead(mx, room.roomId, hideActivity);
|
||||
markAsRead(room.roomId, hideActivity);
|
||||
requestClose();
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user