add a react component to display last read message

This commit is contained in:
Audric Ackermann 2020-11-02 10:57:19 +11:00
parent 940ad57f83
commit 35ad4cba24
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4
9 changed files with 115 additions and 70 deletions

View File

@ -55,15 +55,6 @@
</div>
</script>
<script type='text/x-tmpl-mustache' id='last-seen-indicator-view'>
<div class='module-last-seen-indicator__bar'/>
<div class='module-last-seen-indicator__text'>
{{ unreadMessages }}
</div>
</script>
<script type='text/x-tmpl-mustache' id='expired_alert'>
<a target='_blank' href='https://getsession.org/'>
<button class='upgrade'>{{ upgrade }}</button>

View File

@ -55,13 +55,6 @@
</script>
<script type='text/x-tmpl-mustache' id='last-seen-indicator-view'>
<div class='module-last-seen-indicator__bar'/>
<div class='module-last-seen-indicator__text'>
{{ unreadMessages }}
</div>
</script>
<script type='text/x-tmpl-mustache' id='expired_alert'>
<a target='_blank' href='https://getsession.org/'>
<button class='upgrade'>{{ upgrade }}</button>

View File

@ -1888,7 +1888,7 @@
const cachedUnreadCountOnConvo = this.get('unreadCount');
if (cachedUnreadCountOnConvo !== read.length) {
// reset the unreadCount on the convo to the real one coming from markRead messages on the db
this.set({ unreadCount: realUnreadCount });
this.set({ unreadCount: 0 });
this.commit();
} else {
window.log.info('markRead(): nothing newly read.');

View File

@ -53,4 +53,12 @@ export interface MessageModel extends Backbone.Model<MessageAttributes> {
merge: (other: MessageModel) => void;
saveErrors: (error: any) => void;
sendSyncMessageOnly: (message: any) => void;
isUnread: () => boolean;
propsForMessage?: any;
propsForTimerNotification?: any;
propsForResetSessionNotification?: any;
propsForGroupInvitation?: any;
propsForGroupNotification?: any;
firstMessageOfSeries: boolean;
}

View File

@ -311,30 +311,3 @@
color: $color-white;
box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.12), 0 0 0 0.5px rgba(0, 0, 0, 0.08);
}
.module-last-seen-indicator {
padding-top: 25px;
padding-bottom: 35px;
margin-inline-start: 28px;
margin-inline-end: 28px;
&__bar {
@include themify($themes) {
background-color: themed('lastSeenIndicatorColor');
}
width: 100%;
height: 2px;
}
&__text {
margin-top: 3px;
font-size: 11px;
line-height: 16px;
letter-spacing: 0.3px;
text-transform: uppercase;
@include themify($themes) {
color: themed('lastSeenIndicatorTextColor');
}
text-align: center;
}
}

View File

@ -42,15 +42,6 @@
</div>
</script>
<script type="text/x-tmpl-mustache" id="last-seen-indicator-view">
<div class="module-last-seen-indicator__bar"/>
<div class="module-last-seen-indicator__text">
{{ unreadMessages }}
</div>
</script>
<script type="text/x-tmpl-mustache" id="banner">
<div class="body">
<span class="icon warning"></span>

View File

@ -364,7 +364,6 @@ export class SessionConversation extends React.Component<Props, State> {
// Set first member of series here.
const messageModels = messageSet.models;
console.warn('messageSet', messageSet);
const messages = [];
let previousSender;

View File

@ -12,6 +12,8 @@ import { AttachmentType } from '../../../types/Attachment';
import { GroupNotification } from '../../conversation/GroupNotification';
import { GroupInvitation } from '../../conversation/GroupInvitation';
import { ConversationType } from '../../../state/ducks/conversations';
import { MessageModel } from '../../../../js/models/messages';
import { SessionLastSeenIndicator } from './SessionLastSeedIndicator';
interface State {
isScrolledToBottom: boolean;
@ -22,7 +24,7 @@ interface State {
interface Props {
selectedMessages: Array<string>;
conversationKey: string;
messages: Array<any>;
messages: Array<MessageModel>;
initialFetchComplete: boolean;
conversation: ConversationType;
messageContainerRef: React.RefObject<any>;
@ -68,7 +70,10 @@ export class SessionConversationMessagesList extends React.Component<
}
public componentDidUpdate(prevProps: Props, _prevState: State) {
if (prevProps.conversationKey !== this.props.conversationKey) {
if (
prevProps.conversationKey !== this.props.conversationKey ||
(prevProps.messages.length === 0 && this.props.messages.length !== 0)
) {
// we have a bit of cleaning to do here
this.setState(
{
@ -107,12 +112,14 @@ export class SessionConversationMessagesList extends React.Component<
);
}
public renderMessages(messages: any) {
public renderMessages(messages: Array<MessageModel>) {
const { conversation } = this.props;
const { unreadCount } = conversation;
const multiSelectMode = Boolean(this.props.selectedMessages.length);
// FIXME VINCE: IF MESSAGE IS THE TOP OF UNREAD, THEN INSERT AN UNREAD BANNER
let lastMessageIsUnread = true;
return (
<>
{messages.map((message: any) => {
{messages.map((message: MessageModel) => {
const messageProps = message.propsForMessage;
const timerProps = message.propsForTimerNotification;
@ -120,29 +127,64 @@ export class SessionConversationMessagesList extends React.Component<
const propsForGroupInvitation = message.propsForGroupInvitation;
const groupNotificationProps = message.propsForGroupNotification;
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 (lastMessageIsUnread && !isMessageUnread && unreadCount > 0) {
unreadIndicator = <SessionLastSeenIndicator count={unreadCount} />;
lastMessageIsUnread = false;
}
if (groupNotificationProps) {
return <GroupNotification {...groupNotificationProps} />;
return (
<>
{unreadIndicator}
<GroupNotification {...groupNotificationProps} />
</>
);
}
if (propsForGroupInvitation) {
return <GroupInvitation {...propsForGroupInvitation} />;
return (
<>
{unreadIndicator}
<GroupInvitation {...propsForGroupInvitation} />
</>
);
}
if (resetSessionProps) {
return <ResetSessionNotification {...resetSessionProps} />;
return (
<>
{unreadIndicator}
<ResetSessionNotification {...resetSessionProps} />
</>
);
}
if (timerProps) {
return <TimerNotification {...timerProps} />;
return (
<>
{unreadIndicator}
<TimerNotification {...timerProps} />
</>
);
}
// firstMessageOfSeries tells us to render the avatar only for the first message
// in a series of messages from the same user
return this.renderMessage(
messageProps,
message.firstMessageOfSeries,
multiSelectMode
return (
<>
{unreadIndicator}
{this.renderMessage(
messageProps,
message.firstMessageOfSeries,
multiSelectMode
)}{' '}
</>
);
})}
</>
@ -282,11 +324,20 @@ export class SessionConversationMessagesList extends React.Component<
public scrollToUnread() {
const { messages, conversation } = this.props;
const message = messages[conversation.unreadCount];
if (conversation.unreadCount > 0) {
let message;
if (messages.length > conversation.unreadCount) {
// if we have enough message to show one more message, show one more to include the unread banner
message = messages[conversation.unreadCount];
} else {
message = messages[conversation.unreadCount - 1];
}
if (message) {
this.scrollToMessage(message.id);
if (message) {
this.scrollToMessage(message.id);
}
}
if (!this.state.doneInitialScroll) {
this.setState({
doneInitialScroll: true,

View File

@ -0,0 +1,39 @@
import React from 'react';
import styled from 'styled-components';
const LastSeenBarContainer = styled.div`
padding-top: 25px;
padding-bottom: 35px;
margin-inline-start: 28px;
padding-top: 28px;
`;
const LastSeenBar = styled.div`
width: 100%;
height: 2px;
background-color: ${props => props.theme.colors.lastSeenIndicatorColor};
`;
const LastSeenText = styled.div`
margin-top: 3px;
font-size: 11px;
line-height: 16px;
letter-spacing: 0.3px;
text-transform: uppercase;
text-align: center;
color: ${props => props.theme.colors.lastSeenIndicatorTextColor};
`;
export const SessionLastSeenIndicator = ({ count }: { count: number }) => {
const { i18n } = window;
const text =
count > 1 ? i18n('unreadMessages', count) : i18n('unreadMessage', count);
return (
<LastSeenBarContainer>
<LastSeenBar>
<LastSeenText>{text}</LastSeenText>
</LastSeenBar>
</LastSeenBarContainer>
);
};