Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Mark as Read/Unread option to LHN Context menu #20254

Merged
merged 13 commits into from
Jun 16, 2023
1 change: 1 addition & 0 deletions src/components/LHNOptionsList/OptionRowLHN.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ const OptionRowLHN = (props) => {
false,
false,
optionItem.isPinned,
optionItem.isUnread,
);
};

Expand Down
1 change: 1 addition & 0 deletions src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@ export default {
copyURLToClipboard: 'Copy URL to clipboard',
copyEmailToClipboard: 'Copy email to clipboard',
markAsUnread: 'Mark as unread',
markAsRead: 'Mark as Read',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
markAsRead: 'Mark as Read',
markAsRead: 'Mark as read',

Copy link
Contributor

@luacmartins luacmartins Jun 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah nice catch. Yea let's address that @Gonals

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

editComment: 'Edit comment',
deleteAction: ({action}) => `Delete ${ReportActionsUtils.isMoneyRequestAction(action) ? 'request' : 'comment'}`,
deleteConfirmation: ({action}) => `Are you sure you want to delete this ${ReportActionsUtils.isMoneyRequestAction(action) ? 'request' : 'comment'}?`,
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ export default {
copyURLToClipboard: 'Copiar URL al portapapeles',
copyEmailToClipboard: 'Copiar email al portapapeles',
markAsUnread: 'Marcar como no leído',
markAsRead: 'Marcar como leído',
editComment: 'Editar comentario',
deleteAction: ({action}) => `Eliminar ${ReportActionsUtils.isMoneyRequestAction(action) ? 'pedido' : 'comentario'}`,
deleteConfirmation: ({action}) => `¿Estás seguro de que quieres eliminar este ${ReportActionsUtils.isMoneyRequestAction(action) ? 'pedido' : 'comentario'}`,
Expand Down
5 changes: 4 additions & 1 deletion src/libs/actions/Report.js
Original file line number Diff line number Diff line change
Expand Up @@ -663,10 +663,13 @@ function readNewestAction(reportID) {
* @param {String} reportActionCreated
*/
function markCommentAsUnread(reportID, reportActionCreated) {
// If no action created date is provided, use the last action's
const actionCreationTime = reportActionCreated || lodashGet(allReports, [reportID, 'lastVisibleActionCreated'], '0');

// We subtract 1 millisecond so that the lastReadTime is updated to just before a given reportAction's created date
// For example, if we want to mark a report action with ID 100 and created date '2014-04-01 16:07:02.999' unread, we set the lastReadTime to '2014-04-01 16:07:02.998'
// Since the report action with ID 100 will be the first with a timestamp above '2014-04-01 16:07:02.998', it's the first one that will be shown as unread
const lastReadTime = DateUtils.subtractMillisecondsFromDateTime(reportActionCreated, 1);
const lastReadTime = DateUtils.subtractMillisecondsFromDateTime(actionCreationTime, 1);
API.write(
'MarkAsUnread',
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class BaseReportActionContextMenu extends React.Component {
this.props.isChronosReport,
this.props.reportID,
this.props.isPinnedChat,
this.props.isUnreadChat,
);

/**
Expand Down
17 changes: 16 additions & 1 deletion src/pages/home/report/ContextMenu/ContextMenuActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,8 @@ export default [
textTranslateKey: 'reportActionContextMenu.markAsUnread',
icon: Expensicons.Mail,
successIcon: Expensicons.Checkmark,
shouldShow: (type) => type === CONTEXT_MENU_TYPES.REPORT_ACTION,
shouldShow: (type, reportAction, isArchivedRoom, betas, anchor, isChronosReport, reportID, isPinnedChat, isUnreadChat) =>
type === CONTEXT_MENU_TYPES.REPORT_ACTION || (type === CONTEXT_MENU_TYPES.REPORT && !isUnreadChat),
onPress: (closePopover, {reportAction, reportID}) => {
Report.markCommentAsUnread(reportID, reportAction.created);
if (closePopover) {
Expand All @@ -232,6 +233,20 @@ export default [
getDescription: () => {},
},

{
textTranslateKey: 'reportActionContextMenu.markAsRead',
icon: Expensicons.Mail,
successIcon: Expensicons.Checkmark,
shouldShow: (type, reportAction, isArchivedRoom, betas, anchor, isChronosReport, reportID, isPinnedChat, isUnreadChat) => type === CONTEXT_MENU_TYPES.REPORT && isUnreadChat,
onPress: (closePopover, {reportID}) => {
Report.readNewestAction(reportID);
if (closePopover) {
hideContextMenu(true, ReportActionComposeFocusManager.focus);
}
},
getDescription: () => {},
},

{
textTranslateKey: 'reportActionContextMenu.editComment',
icon: Expensicons.Pencil,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class PopoverReportActionContextMenu extends React.Component {
isArchivedRoom: false,
isChronosReport: false,
isPinnedChat: false,
isUnreadChat: false,
};
this.onPopoverShow = () => {};
this.onPopoverHide = () => {};
Expand Down Expand Up @@ -128,6 +129,7 @@ class PopoverReportActionContextMenu extends React.Component {
* @param {Boolean} isArchivedRoom - Whether the provided report is an archived room
* @param {Boolean} isChronosReport - Flag to check if the chat participant is Chronos
* @param {Boolean} isPinnedChat - Flag to check if the chat is pinned in the LHN. Used for the Pin/Unpin action
* @param {Boolean} isUnreadChat - Flag to check if the chat is unread in the LHN. Used for the Mark as Read/Unread action
*/
showContextMenu(
type,
Expand All @@ -142,6 +144,7 @@ class PopoverReportActionContextMenu extends React.Component {
isArchivedRoom = false,
isChronosReport = false,
isPinnedChat = false,
isUnreadChat = false,
) {
const nativeEvent = event.nativeEvent || {};
this.contextMenuAnchor = contextMenuAnchor;
Expand Down Expand Up @@ -173,6 +176,7 @@ class PopoverReportActionContextMenu extends React.Component {
isArchivedRoom,
isChronosReport,
isPinnedChat,
isUnreadChat,
});
});
}
Expand Down Expand Up @@ -261,6 +265,7 @@ class PopoverReportActionContextMenu extends React.Component {
isArchivedRoom: false,
isChronosReport: false,
isPinnedChat: false,
isUnreadChat: false,
});
}

Expand Down Expand Up @@ -308,6 +313,7 @@ class PopoverReportActionContextMenu extends React.Component {
isArchivedRoom={this.state.isArchivedRoom}
isChronosReport={this.state.isChronosReport}
isPinnedChat={this.state.isPinnedChat}
isUnreadChat={this.state.isUnreadChat}
anchor={this.contextMenuTargetNode}
contentRef={this.contentRef}
/>
Expand Down
18 changes: 17 additions & 1 deletion src/pages/home/report/ContextMenu/ReportActionContextMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const contextMenuRef = React.createRef();
* @param {Boolean} isArchivedRoom - Whether the provided report is an archived room
* @param {Boolean} isChronosReport - Flag to check if the chat participant is Chronos
* @param {Boolean} isPinnedChat - Flag to check if the chat is pinned in the LHN. Used for the Pin/Unpin action
* @param {Boolean} isUnreadChat - Flag to check if the chat has unread messages in the LHN. Used for the Mark as Read/Unread action
*/
function showContextMenu(
type,
Expand All @@ -31,11 +32,26 @@ function showContextMenu(
isArchivedRoom = false,
isChronosReport = false,
isPinnedChat = false,
isUnreadChat = false,
) {
if (!contextMenuRef.current) {
return;
}
contextMenuRef.current.showContextMenu(type, event, selection, contextMenuAnchor, reportID, reportAction, draftMessage, onShow, onHide, isArchivedRoom, isChronosReport, isPinnedChat);
contextMenuRef.current.showContextMenu(
type,
event,
selection,
contextMenuAnchor,
reportID,
reportAction,
draftMessage,
onShow,
onHide,
isArchivedRoom,
isChronosReport,
isPinnedChat,
isUnreadChat,
);
}

/**
Expand Down