use react-intersection to accurately mark messages as read

pull/1381/head
Audric Ackermann 4 years ago
parent d533a3aca5
commit d0043ca245
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -596,6 +596,7 @@
quote: this.getPropsForQuote(options),
authorAvatarPath,
isExpired: this.hasExpired,
isUnread: this.isUnread(),
expirationLength,
expirationTimestamp,
isPublic: !!this.get('isPublic'),
@ -618,6 +619,7 @@
onRetrySend: () => this.retrySend(),
onShowDetail: () => this.trigger('show-message-detail', this),
onClickLinkPreview: url => this.trigger('navigate-to', url),
markRead: readAt => this.markRead(readAt),
onShowUserDetails: pubkey =>
window.Whisper.events.trigger('onShowUserDetails', {

@ -111,6 +111,7 @@
"react-emoji": "^0.5.0",
"react-emoji-render": "^1.2.4",
"react-h5-audio-player": "^3.2.0",
"react-intersection-observer": "^8.30.3",
"react-mentions": "^4.0.2",
"react-portal": "^4.2.0",
"react-qr-svg": "^2.2.1",

@ -37,6 +37,7 @@ import { SessionIcon, SessionIconSize, SessionIconType } from '../session/icon';
import _ from 'lodash';
import { animation, contextMenu, Item, Menu } from 'react-contexify';
import uuid from 'uuid';
import { InView } from 'react-intersection-observer';
// Same as MIN_WIDTH in ImageGrid.tsx
const MINIMUM_LINK_PREVIEW_IMAGE_WIDTH = 200;
@ -97,6 +98,7 @@ export interface Props {
// whether or not to show check boxes
multiSelectMode: boolean;
firstMessageOfSeries: boolean;
isUnread: boolean;
onClickAttachment?: (attachment: AttachmentType) => void;
onClickLinkPreview?: (url: string) => void;
@ -110,6 +112,7 @@ export interface Props {
onBanUser?: () => void;
onShowDetail: () => void;
onShowUserDetails: (userPubKey: string) => void;
markRead: (readAt: number) => Promise<void>;
}
interface State {
@ -987,7 +990,8 @@ export class Message extends React.PureComponent<Props, State> {
conversationType,
isPublic,
text,
firstMessageOfSeries,
isUnread,
markRead,
} = this.props;
const { expired, expiring } = this.state;
@ -1008,6 +1012,7 @@ export class Message extends React.PureComponent<Props, State> {
const isIncoming = direction === 'incoming';
const shouldHightlight = mentionMe && isIncoming && isPublic;
const shouldMarkReadWhenVisible = isIncoming && isUnread;
const divClasses = ['session-message-wrapper'];
if (shouldHightlight) {
@ -1021,10 +1026,23 @@ export class Message extends React.PureComponent<Props, State> {
divClasses.push('public-chat-message-wrapper');
}
const onVisible = (inView: boolean) => {
if (inView && shouldMarkReadWhenVisible) {
// mark the message as read.
// this will trigger the expire timer.
void markRead(Date.now());
}
};
return (
<div
<InView
id={id}
as="div"
className={classNames(divClasses)}
onChange={onVisible}
threshold={1}
delay={200}
triggerOnce={true}
onContextMenu={this.handleContextMenu}
>
{this.renderAvatar()}
@ -1099,7 +1117,7 @@ export class Message extends React.PureComponent<Props, State> {
{this.renderError(!isIncoming)}
{this.renderContextMenu()}
</div>
</div>
</InView>
);
}

@ -8778,6 +8778,11 @@ react-icons@^2.2.7:
dependencies:
react-icon-base "2.1.0"
react-intersection-observer@^8.30.3:
version "8.30.3"
resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-8.30.3.tgz#99850f0aacc5b474dddb04976e58d7ee9315ba19"
integrity sha512-hKYTJUrU99hAf7h1lNY3pjYXt+09BaPNC6fcLw1B8OLJJUDXTWrwzu4hRuztougeRgPYpxmNaTn1FS4F3EQnhA==
react-is@^16.12.0, react-is@^16.7.0, react-is@^16.8.1:
version "16.13.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.0.tgz#0f37c3613c34fe6b37cd7f763a0d6293ab15c527"

Loading…
Cancel
Save