Mark conversation as unread
Co-authored-by: Sidney Keese <sidney@carbonfive.com>
This commit is contained in:
parent
184f7e1bf3
commit
c408072576
20 changed files with 169 additions and 62 deletions
|
@ -37,6 +37,7 @@ const createProps = (overrideProps: Partial<Props> = {}): Props => ({
|
|||
name: overrideProps.name || 'Some Person',
|
||||
type: overrideProps.type || 'direct',
|
||||
onClick: action('onClick'),
|
||||
markedUnread: boolean('markedUnread', overrideProps.markedUnread || false),
|
||||
lastMessage: overrideProps.lastMessage || {
|
||||
text: text('lastMessage.text', 'Hi there!'),
|
||||
status: select(
|
||||
|
@ -137,18 +138,32 @@ story.add('Message Request', () => {
|
|||
|
||||
story.add('Unread', () => {
|
||||
const counts = [4, 10, 250];
|
||||
const defaultProps = createProps({
|
||||
lastMessage: {
|
||||
text: 'Hey there!',
|
||||
status: 'delivered',
|
||||
},
|
||||
});
|
||||
|
||||
return counts.map(unreadCount => {
|
||||
const props = createProps({
|
||||
lastMessage: {
|
||||
text: 'Hey there!',
|
||||
status: 'delivered',
|
||||
},
|
||||
const items = counts.map(unreadCount => {
|
||||
const props = {
|
||||
...defaultProps,
|
||||
unreadCount,
|
||||
});
|
||||
};
|
||||
|
||||
return <ConversationListItem key={unreadCount} {...props} />;
|
||||
});
|
||||
|
||||
const markedUnreadProps = {
|
||||
...defaultProps,
|
||||
markedUnread: true,
|
||||
};
|
||||
|
||||
const markedUnreadItem = [
|
||||
<ConversationListItem key={5} {...markedUnreadProps} />,
|
||||
];
|
||||
|
||||
return [...items, ...markedUnreadItem];
|
||||
});
|
||||
|
||||
story.add('Selected', () => {
|
||||
|
|
|
@ -37,6 +37,7 @@ export type PropsData = {
|
|||
|
||||
lastUpdated: number;
|
||||
unreadCount?: number;
|
||||
markedUnread: boolean;
|
||||
isSelected: boolean;
|
||||
|
||||
acceptedMessageRequest?: boolean;
|
||||
|
@ -93,13 +94,19 @@ export class ConversationListItem extends React.PureComponent<Props> {
|
|||
);
|
||||
}
|
||||
|
||||
isUnread(): boolean {
|
||||
const { markedUnread, unreadCount } = this.props;
|
||||
|
||||
return (isNumber(unreadCount) && unreadCount > 0) || markedUnread;
|
||||
}
|
||||
|
||||
public renderUnread(): JSX.Element | null {
|
||||
const { unreadCount } = this.props;
|
||||
|
||||
if (isNumber(unreadCount) && unreadCount > 0) {
|
||||
if (this.isUnread()) {
|
||||
return (
|
||||
<div className="module-conversation-list-item__unread-count">
|
||||
{unreadCount}
|
||||
{unreadCount || ''}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -109,7 +116,6 @@ export class ConversationListItem extends React.PureComponent<Props> {
|
|||
|
||||
public renderHeader(): JSX.Element {
|
||||
const {
|
||||
unreadCount,
|
||||
i18n,
|
||||
isMe,
|
||||
lastUpdated,
|
||||
|
@ -119,14 +125,12 @@ export class ConversationListItem extends React.PureComponent<Props> {
|
|||
title,
|
||||
} = this.props;
|
||||
|
||||
const withUnread = isNumber(unreadCount) && unreadCount > 0;
|
||||
|
||||
return (
|
||||
<div className="module-conversation-list-item__header">
|
||||
<div
|
||||
className={classNames(
|
||||
'module-conversation-list-item__header__name',
|
||||
withUnread
|
||||
this.isUnread()
|
||||
? 'module-conversation-list-item__header__name--with-unread'
|
||||
: null
|
||||
)}
|
||||
|
@ -146,7 +150,7 @@ export class ConversationListItem extends React.PureComponent<Props> {
|
|||
<div
|
||||
className={classNames(
|
||||
'module-conversation-list-item__header__date',
|
||||
withUnread
|
||||
this.isUnread()
|
||||
? 'module-conversation-list-item__header__date--has-unread'
|
||||
: null
|
||||
)}
|
||||
|
@ -155,7 +159,7 @@ export class ConversationListItem extends React.PureComponent<Props> {
|
|||
timestamp={lastUpdated}
|
||||
extended={false}
|
||||
module="module-conversation-list-item__header__timestamp"
|
||||
withUnread={withUnread}
|
||||
withUnread={this.isUnread()}
|
||||
i18n={i18n}
|
||||
/>
|
||||
</div>
|
||||
|
@ -172,14 +176,12 @@ export class ConversationListItem extends React.PureComponent<Props> {
|
|||
muteExpiresAt,
|
||||
shouldShowDraft,
|
||||
typingContact,
|
||||
unreadCount,
|
||||
} = this.props;
|
||||
if (!lastMessage && !typingContact) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const messageBody = lastMessage ? lastMessage.text : '';
|
||||
const withUnread = isNumber(unreadCount) && unreadCount > 0;
|
||||
const showingDraft = shouldShowDraft && draftPreview;
|
||||
const deletedForEveryone = Boolean(
|
||||
lastMessage && lastMessage.deletedForEveryone
|
||||
|
@ -192,7 +194,7 @@ export class ConversationListItem extends React.PureComponent<Props> {
|
|||
dir="auto"
|
||||
className={classNames(
|
||||
'module-conversation-list-item__message__text',
|
||||
withUnread
|
||||
this.isUnread()
|
||||
? 'module-conversation-list-item__message__text--has-unread'
|
||||
: null
|
||||
)}
|
||||
|
@ -249,8 +251,7 @@ export class ConversationListItem extends React.PureComponent<Props> {
|
|||
/* eslint-enable no-nested-ternary */
|
||||
|
||||
public render(): JSX.Element {
|
||||
const { unreadCount, onClick, id, isSelected, style } = this.props;
|
||||
const withUnread = isNumber(unreadCount) && unreadCount > 0;
|
||||
const { id, isSelected, onClick, style } = this.props;
|
||||
|
||||
return (
|
||||
<button
|
||||
|
@ -263,7 +264,7 @@ export class ConversationListItem extends React.PureComponent<Props> {
|
|||
style={style}
|
||||
className={classNames(
|
||||
'module-conversation-list-item',
|
||||
withUnread ? 'module-conversation-list-item--has-unread' : null,
|
||||
this.isUnread() ? 'module-conversation-list-item--has-unread' : null,
|
||||
isSelected ? 'module-conversation-list-item--is-selected' : null
|
||||
)}
|
||||
data-id={cleanId(id)}
|
||||
|
|
|
@ -18,6 +18,7 @@ const defaultConversations: Array<PropsData> = [
|
|||
id: 'fred-convo',
|
||||
isSelected: false,
|
||||
lastUpdated: Date.now(),
|
||||
markedUnread: false,
|
||||
title: 'Fred Willard',
|
||||
type: 'direct',
|
||||
},
|
||||
|
@ -25,6 +26,7 @@ const defaultConversations: Array<PropsData> = [
|
|||
id: 'marc-convo',
|
||||
isSelected: true,
|
||||
lastUpdated: Date.now(),
|
||||
markedUnread: false,
|
||||
title: 'Marc Barraca',
|
||||
type: 'direct',
|
||||
},
|
||||
|
@ -35,6 +37,7 @@ const defaultArchivedConversations: Array<PropsData> = [
|
|||
id: 'michelle-archive-convo',
|
||||
isSelected: false,
|
||||
lastUpdated: Date.now(),
|
||||
markedUnread: false,
|
||||
title: 'Michelle Mercure',
|
||||
type: 'direct',
|
||||
},
|
||||
|
@ -46,6 +49,7 @@ const pinnedConversations: Array<PropsData> = [
|
|||
isPinned: true,
|
||||
isSelected: false,
|
||||
lastUpdated: Date.now(),
|
||||
markedUnread: false,
|
||||
title: 'Philip Glass',
|
||||
type: 'direct',
|
||||
},
|
||||
|
@ -54,6 +58,7 @@ const pinnedConversations: Array<PropsData> = [
|
|||
isPinned: true,
|
||||
isSelected: false,
|
||||
lastUpdated: Date.now(),
|
||||
markedUnread: false,
|
||||
title: 'Robert Moog',
|
||||
type: 'direct',
|
||||
},
|
||||
|
@ -129,6 +134,7 @@ story.add('Search Results', () => {
|
|||
id: 'fred-convo',
|
||||
isSelected: false,
|
||||
lastUpdated: Date.now(),
|
||||
markedUnread: false,
|
||||
title: 'People Named Fred',
|
||||
type: 'group',
|
||||
},
|
||||
|
@ -147,6 +153,7 @@ story.add('Search Results', () => {
|
|||
id: 'fred-contact',
|
||||
isSelected: false,
|
||||
lastUpdated: Date.now(),
|
||||
markedUnread: false,
|
||||
title: 'Fred Willard',
|
||||
type: 'direct',
|
||||
},
|
||||
|
|
|
@ -157,6 +157,7 @@ const conversations = [
|
|||
text: 'The rabbit hopped silently in the night.',
|
||||
status: SENT,
|
||||
},
|
||||
markedUnread: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -177,6 +178,7 @@ const conversations = [
|
|||
text: "What's going on?",
|
||||
status: SENT,
|
||||
},
|
||||
markedUnread: false,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
@ -196,6 +198,7 @@ const contacts = [
|
|||
lastUpdated: Date.now() - 10 * 60 * 1000,
|
||||
unreadCount: 0,
|
||||
isSelected: false,
|
||||
markedUnread: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -211,6 +214,7 @@ const contacts = [
|
|||
lastUpdated: Date.now() - 11 * 60 * 1000,
|
||||
unreadCount: 0,
|
||||
isSelected: false,
|
||||
markedUnread: false,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
|
|
@ -44,6 +44,7 @@ const actionProps: PropsActionsType = {
|
|||
onGoBack: action('onGoBack'),
|
||||
|
||||
onArchive: action('onArchive'),
|
||||
onMarkUnread: action('onMarkUnread'),
|
||||
onMoveToInbox: action('onMoveToInbox'),
|
||||
onSetPin: action('onSetPin'),
|
||||
};
|
||||
|
|
|
@ -36,6 +36,7 @@ export interface PropsDataType {
|
|||
isMe?: boolean;
|
||||
isArchived?: boolean;
|
||||
isPinned?: boolean;
|
||||
markedUnread?: boolean;
|
||||
|
||||
disableTimerChanges?: boolean;
|
||||
expirationSettingName?: string;
|
||||
|
@ -60,6 +61,7 @@ export interface PropsActionsType {
|
|||
onGoBack: () => void;
|
||||
|
||||
onArchive: () => void;
|
||||
onMarkUnread: () => void;
|
||||
onMoveToInbox: () => void;
|
||||
}
|
||||
|
||||
|
@ -310,6 +312,7 @@ export class ConversationHeader extends React.Component<PropsType> {
|
|||
isPinned,
|
||||
type,
|
||||
isArchived,
|
||||
markedUnread,
|
||||
muteExpirationLabel,
|
||||
onDeleteMessages,
|
||||
onResetSession,
|
||||
|
@ -319,6 +322,7 @@ export class ConversationHeader extends React.Component<PropsType> {
|
|||
onShowGroupMembers,
|
||||
onShowSafetyNumber,
|
||||
onArchive,
|
||||
onMarkUnread,
|
||||
onSetPin,
|
||||
onMoveToInbox,
|
||||
timerOptions,
|
||||
|
@ -350,28 +354,6 @@ export class ConversationHeader extends React.Component<PropsType> {
|
|||
|
||||
return (
|
||||
<ContextMenu id={triggerId}>
|
||||
<SubMenu title={muteTitle}>
|
||||
{muteOptions.map(item => (
|
||||
<MenuItem
|
||||
key={item.name}
|
||||
disabled={item.disabled}
|
||||
onClick={() => {
|
||||
onSetMuteNotifications(item.value);
|
||||
}}
|
||||
>
|
||||
{item.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</SubMenu>
|
||||
{isPinned ? (
|
||||
<MenuItem onClick={() => onSetPin(false)}>
|
||||
{i18n('unpinConversation')}
|
||||
</MenuItem>
|
||||
) : (
|
||||
<MenuItem onClick={() => onSetPin(true)}>
|
||||
{i18n('pinConversation')}
|
||||
</MenuItem>
|
||||
)}
|
||||
{disableTimerChanges ? null : (
|
||||
<SubMenu title={disappearingTitle}>
|
||||
{(timerOptions || []).map(item => (
|
||||
|
@ -386,21 +368,37 @@ export class ConversationHeader extends React.Component<PropsType> {
|
|||
))}
|
||||
</SubMenu>
|
||||
)}
|
||||
<MenuItem onClick={onShowAllMedia}>{i18n('viewRecentMedia')}</MenuItem>
|
||||
<SubMenu title={muteTitle}>
|
||||
{muteOptions.map(item => (
|
||||
<MenuItem
|
||||
key={item.name}
|
||||
disabled={item.disabled}
|
||||
onClick={() => {
|
||||
onSetMuteNotifications(item.value);
|
||||
}}
|
||||
>
|
||||
{item.name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</SubMenu>
|
||||
{isGroup ? (
|
||||
<MenuItem onClick={onShowGroupMembers}>
|
||||
{i18n('showMembers')}
|
||||
</MenuItem>
|
||||
) : null}
|
||||
<MenuItem onClick={onShowAllMedia}>{i18n('viewRecentMedia')}</MenuItem>
|
||||
{!isGroup && !isMe ? (
|
||||
<MenuItem onClick={onShowSafetyNumber}>
|
||||
{i18n('showSafetyNumber')}
|
||||
</MenuItem>
|
||||
) : null}
|
||||
<MenuItem divider />
|
||||
{!isGroup && acceptedMessageRequest ? (
|
||||
<MenuItem onClick={onResetSession}>{i18n('resetSession')}</MenuItem>
|
||||
) : null}
|
||||
<MenuItem divider />
|
||||
{!markedUnread ? (
|
||||
<MenuItem onClick={onMarkUnread}>{i18n('markUnread')}</MenuItem>
|
||||
) : null}
|
||||
{isArchived ? (
|
||||
<MenuItem onClick={onMoveToInbox}>
|
||||
{i18n('moveConversationToInbox')}
|
||||
|
@ -409,6 +407,15 @@ export class ConversationHeader extends React.Component<PropsType> {
|
|||
<MenuItem onClick={onArchive}>{i18n('archiveConversation')}</MenuItem>
|
||||
)}
|
||||
<MenuItem onClick={onDeleteMessages}>{i18n('deleteMessages')}</MenuItem>
|
||||
{isPinned ? (
|
||||
<MenuItem onClick={() => onSetPin(false)}>
|
||||
{i18n('unpinConversation')}
|
||||
</MenuItem>
|
||||
) : (
|
||||
<MenuItem onClick={() => onSetPin(true)}>
|
||||
{i18n('pinConversation')}
|
||||
</MenuItem>
|
||||
)}
|
||||
</ContextMenu>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ storiesOf('Components/Conversation/ProfileChangeNotification', module)
|
|||
title: 'Mr. Fire 🔥',
|
||||
name: 'Mr. Fire 🔥',
|
||||
lastUpdated: Date.now(),
|
||||
markedUnread: false,
|
||||
}}
|
||||
change={{
|
||||
type: 'name',
|
||||
|
@ -37,6 +38,7 @@ storiesOf('Components/Conversation/ProfileChangeNotification', module)
|
|||
type: 'direct',
|
||||
title: 'Mr. Fire 🔥',
|
||||
lastUpdated: Date.now(),
|
||||
markedUnread: false,
|
||||
}}
|
||||
change={{
|
||||
type: 'name',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue