make the last seen indicator work as expected

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

@ -84,7 +84,7 @@ export interface ConversationModel
getNumber: any; getNumber: any;
getProfileName: any; getProfileName: any;
getAvatarPath: any; getAvatarPath: any;
markRead: any; markRead: (timestamp: number) => Promise<void>;
showChannelLightbox: any; showChannelLightbox: any;
deletePublicMessages: any; deletePublicMessages: any;
getMessagesWithTimestamp: any; getMessagesWithTimestamp: any;

@ -1891,7 +1891,7 @@
this.set({ unreadCount: 0 }); this.set({ unreadCount: 0 });
this.commit(); this.commit();
} else { } else {
window.log.info('markRead(): nothing newly read.'); // window.log.info('markRead(): nothing newly read.');
} }
return; return;
} }

@ -162,10 +162,14 @@ export class SessionConversation extends React.Component<Props, State> {
public componentWillUnmount() { public componentWillUnmount() {
const { conversationKey } = this.props; const { conversationKey } = this.props;
const conversationModel = window.ConversationController.getOrThrow( try {
conversationKey const conversationModel = window.ConversationController.getOrThrow(
); conversationKey
conversationModel.off('change', this.refreshMessages); );
conversationModel.off('change', this.refreshMessages);
} catch (e) {
window.log.error(e);
}
const div = this.messageContainerRef.current; const div = this.messageContainerRef.current;
div?.removeEventListener('dragenter', this.handleDragIn); div?.removeEventListener('dragenter', this.handleDragIn);
div?.removeEventListener('dragleave', this.handleDragOut); div?.removeEventListener('dragleave', this.handleDragOut);
@ -213,6 +217,8 @@ export class SessionConversation extends React.Component<Props, State> {
quotedMessageProps, quotedMessageProps,
lightBoxOptions, lightBoxOptions,
selectedMessages, selectedMessages,
isDraggingFile,
stagedAttachments,
} = this.state; } = this.state;
const selectionMode = !!selectedMessages.length; const selectionMode = !!selectedMessages.length;
@ -227,7 +233,6 @@ export class SessionConversation extends React.Component<Props, State> {
const shouldRenderGroupSettings = const shouldRenderGroupSettings =
!conversationModel.isPrivate() && !conversationModel.isRss(); !conversationModel.isPrivate() && !conversationModel.isRss();
const groupSettingsProps = this.getGroupSettingsProps();
const showSafetyNumber = this.state.infoViewState === 'safetyNumber'; const showSafetyNumber = this.state.infoViewState === 'safetyNumber';
const showMessageDetails = this.state.infoViewState === 'messageDetails'; const showMessageDetails = this.state.infoViewState === 'messageDetails';
@ -273,13 +278,13 @@ export class SessionConversation extends React.Component<Props, State> {
{showRecordingView && ( {showRecordingView && (
<div className="conversation-messages__blocking-overlay" /> <div className="conversation-messages__blocking-overlay" />
)} )}
{this.state.isDraggingFile && <SessionFileDropzone />} {isDraggingFile && <SessionFileDropzone />}
</div> </div>
{!isRss && ( {!isRss && (
<SessionCompositionBox <SessionCompositionBox
sendMessage={sendMessageFn} sendMessage={sendMessageFn}
stagedAttachments={this.state.stagedAttachments} stagedAttachments={stagedAttachments}
onMessageSending={this.onMessageSending} onMessageSending={this.onMessageSending}
onMessageSuccess={this.onMessageSuccess} onMessageSuccess={this.onMessageSuccess}
onMessageFailure={this.onMessageFailure} onMessageFailure={this.onMessageFailure}
@ -304,7 +309,7 @@ export class SessionConversation extends React.Component<Props, State> {
showOptionsPane && 'show' showOptionsPane && 'show'
)} )}
> >
<SessionRightPanelWithDetails {...groupSettingsProps} /> <SessionRightPanelWithDetails {...this.getGroupSettingsProps()} />
</div> </div>
)} )}
</SessionTheme> </SessionTheme>

@ -74,7 +74,7 @@ export class SessionConversationMessagesList extends React.Component<
prevProps.conversationKey !== this.props.conversationKey || prevProps.conversationKey !== this.props.conversationKey ||
(prevProps.messages.length === 0 && this.props.messages.length !== 0) (prevProps.messages.length === 0 && this.props.messages.length !== 0)
) { ) {
// we have a bit of cleaning to do here // displayed conversation changed. We have a bit of cleaning to do here
this.setState( this.setState(
{ {
isScrolledToBottom: false, isScrolledToBottom: false,
@ -114,9 +114,11 @@ export class SessionConversationMessagesList extends React.Component<
public renderMessages(messages: Array<MessageModel>) { public renderMessages(messages: Array<MessageModel>) {
const { conversation } = this.props; const { conversation } = this.props;
const { isScrolledToBottom } = this.state;
const { unreadCount } = conversation; const { unreadCount } = conversation;
const multiSelectMode = Boolean(this.props.selectedMessages.length); const multiSelectMode = Boolean(this.props.selectedMessages.length);
let lastMessageIsUnread = true; let currentMessageIndex = 0;
return ( return (
<> <>
{messages.map((message: MessageModel) => { {messages.map((message: MessageModel) => {
@ -129,14 +131,15 @@ export class SessionConversationMessagesList extends React.Component<
const groupNotificationProps = message.propsForGroupNotification; const groupNotificationProps = message.propsForGroupNotification;
let unreadIndicator = null; let unreadIndicator = null;
// FIXME a sending message does not have the isUnread function yet.
const isMessageUnread = message.isUnread && message.isUnread();
// if there is some unread messages // if there is some unread messages
if (lastMessageIsUnread && !isMessageUnread && unreadCount > 0) { if (
unreadCount > 0 &&
currentMessageIndex === unreadCount &&
!isScrolledToBottom
) {
unreadIndicator = <SessionLastSeenIndicator count={unreadCount} />; unreadIndicator = <SessionLastSeenIndicator count={unreadCount} />;
lastMessageIsUnread = false;
} }
currentMessageIndex = currentMessageIndex + 1;
if (groupNotificationProps) { if (groupNotificationProps) {
return ( return (
@ -229,8 +232,6 @@ export class SessionConversationMessagesList extends React.Component<
const { messages, conversationKey } = this.props; const { messages, conversationKey } = this.props;
const { isScrolledToBottom } = this.state; const { isScrolledToBottom } = this.state;
let unread;
if (!messages || messages.length === 0) { if (!messages || messages.length === 0) {
return; return;
} }
@ -244,13 +245,7 @@ export class SessionConversationMessagesList extends React.Component<
} }
if (isScrolledToBottom) { if (isScrolledToBottom) {
unread = messages[0]; void conversation.markRead(messages[0].attributes.received_at);
} else {
unread = null;
}
if (unread) {
conversation.markRead(unread.attributes.received_at);
} }
} }
@ -339,15 +334,39 @@ export class SessionConversationMessagesList extends React.Component<
} }
if (!this.state.doneInitialScroll) { if (!this.state.doneInitialScroll) {
this.setState({ this.setState(
doneInitialScroll: true, {
}); doneInitialScroll: true,
},
() => {
this.updateReadMessages();
}
);
} }
} }
public scrollToMessage(messageId: string) { public scrollToMessage(messageId: string) {
const topUnreadMessage = document.getElementById(messageId); const topUnreadMessage = document.getElementById(messageId);
topUnreadMessage?.scrollIntoView(); topUnreadMessage?.scrollIntoView();
// if the scroll container is not scrollable as it's not tall enough, we have to update
// the isScrollToBottom ourself
const messageContainer = this.messageContainerRef.current;
if (!messageContainer) {
return;
}
const scrollTop = messageContainer.scrollTop;
const scrollHeight = messageContainer.scrollHeight;
const clientHeight = messageContainer.clientHeight;
const scrollOffsetPx = scrollHeight - scrollTop - clientHeight;
const scrollOffsetPc = scrollOffsetPx / clientHeight;
if (scrollOffsetPc === 0 && this.state.doneInitialScroll) {
this.setState({ isScrolledToBottom: true });
}
} }
public scrollToBottom() { public scrollToBottom() {

@ -474,9 +474,13 @@ export function initIncomingMessage(data: MessageCreationData): MessageModel {
const type = 'incoming'; const type = 'incoming';
const messageGroupId = message?.group?.id; const messageGroupId = message?.group?.id;
const groupId = let groupId =
messageGroupId && messageGroupId.length > 0 ? messageGroupId : null; messageGroupId && messageGroupId.length > 0 ? messageGroupId : null;
if (groupId) {
groupId = groupId.replace(PubKey.PREFIX_GROUP_TEXTSECURE, '');
}
const messageData: any = { const messageData: any = {
source, source,
sourceDevice, sourceDevice,

Loading…
Cancel
Save