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

Move all header buttons to overflow menu #27748

Merged
merged 16 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions assets/images/chatbubbles.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 7 additions & 8 deletions assets/images/google-meet.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 7 additions & 1 deletion assets/images/zoom-icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/components/Icon/Expensicons.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import Camera from '../../../assets/images/camera.svg';
import Car from '../../../assets/images/car.svg';
import Cash from '../../../assets/images/cash.svg';
import ChatBubble from '../../../assets/images/chatbubble.svg';
import ChatBubbles from '../../../assets/images/chatbubbles.svg';
import Checkmark from '../../../assets/images/checkmark.svg';
import Chair from '../../../assets/images/chair.svg';
import Close from '../../../assets/images/close.svg';
Expand Down Expand Up @@ -147,6 +148,7 @@ export {
Car,
Cash,
ChatBubble,
ChatBubbles,
Checkmark,
Chair,
Close,
Expand Down
1 change: 1 addition & 0 deletions src/components/PopoverMenu/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ function PopoverMenu(props) {
icon={item.icon}
iconWidth={item.iconWidth}
iconHeight={item.iconHeight}
iconFill={item.iconFill}
title={item.text}
description={item.description}
onPress={() => selectItem(menuIndex)}
Expand Down
1 change: 1 addition & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ export default {
debitCard: 'Debit card',
bankAccount: 'Bank account',
join: 'Join',
joinThread: 'Join thread',
decline: 'Decline',
transferBalance: 'Transfer balance',
cantFindAddress: "Can't find your address? ",
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ export default {
debitCard: 'Tarjeta de débito',
bankAccount: 'Cuenta bancaria',
join: 'Unirse',
joinThread: 'Unirse al hilo',
decline: 'Rechazar',
transferBalance: 'Transferencia de saldo',
cantFindAddress: '¿No encuentras tu dirección? ',
Expand Down
5 changes: 0 additions & 5 deletions src/libs/ReportUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2978,11 +2978,6 @@ function shouldReportBeInOptionList(report, currentReportId, isInGSDMode, betas,
const isEmptyChat = !report.lastMessageText && !report.lastMessageTranslationKey && !lastVisibleMessage.lastMessageText && !lastVisibleMessage.lastMessageTranslationKey;
const canHideReport = shouldHideReport(report, currentReportId);

// Hide only chat threads that haven't been commented on (other threads are actionable)
if (isChatThread(report) && canHideReport && isEmptyChat) {
return false;
}

Comment on lines -2981 to -2985
Copy link
Member

@parasharrajat parasharrajat Oct 27, 2023

Choose a reason for hiding this comment

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

This created an issue #29851

// Include reports if they are pinned
if (report.isPinned) {
return true;
Expand Down
15 changes: 10 additions & 5 deletions src/libs/actions/Report.js
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ function navigateToAndOpenChildReport(childReportID = '0', parentReportAction =
'',
undefined,
undefined,
CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS,
CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN,
parentReportAction.reportActionID,
parentReportID,
);
Expand Down Expand Up @@ -1297,10 +1297,13 @@ function saveReportActionDraftNumberOfLines(reportID, reportActionID, numberOfLi
* @param {String} reportID
* @param {String} previousValue
* @param {String} newValue
* @param {boolean} navigate
*/
function updateNotificationPreferenceAndNavigate(reportID, previousValue, newValue) {
function updateNotificationPreference(reportID, previousValue, newValue, navigate) {
if (previousValue === newValue) {
Navigation.goBack(ROUTES.REPORT_SETTINGS.getRoute(reportID));
if (navigate) {
Navigation.goBack(ROUTES.REPORT_SETTINGS.getRoute(reportID));
}
return;
}
const optimisticData = [
Expand All @@ -1318,7 +1321,9 @@ function updateNotificationPreferenceAndNavigate(reportID, previousValue, newVal
},
];
API.write('UpdateReportNotificationPreference', {reportID, notificationPreference: newValue}, {optimisticData, failureData});
srikarparsi marked this conversation as resolved.
Show resolved Hide resolved
Navigation.goBack(ROUTES.REPORT_SETTINGS.getRoute(reportID));
if (navigate) {
Navigation.goBack(ROUTES.REPORT_SETTINGS.getRoute(reportID));
}
}

/**
Expand Down Expand Up @@ -2168,7 +2173,7 @@ export {
reconnect,
updateWelcomeMessage,
updateWriteCapabilityAndNavigate,
updateNotificationPreferenceAndNavigate,
updateNotificationPreference,
subscribeToReportTypingEvents,
subscribeToReportLeavingEvents,
unsubscribeFromReportChannel,
Expand Down
2 changes: 1 addition & 1 deletion src/pages/ReportDetailsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ function ReportDetailsPage(props) {
});
}

if (isUserCreatedPolicyRoom || canLeaveRoom || isThread) {
if (isUserCreatedPolicyRoom || canLeaveRoom) {
items.push({
key: CONST.REPORT_DETAILS_MENU_ITEM.LEAVE_ROOM,
translationKey: isThread ? 'common.leaveThread' : 'common.leaveRoom',
Expand Down
119 changes: 91 additions & 28 deletions src/pages/home/HeaderView.js
Original file line number Diff line number Diff line change
@@ -1,35 +1,38 @@
import _ from 'underscore';
import lodashGet from 'lodash/get';
import PropTypes from 'prop-types';
import React from 'react';
import {View} from 'react-native';
import PropTypes from 'prop-types';
import lodashGet from 'lodash/get';
import {withOnyx} from 'react-native-onyx';
import styles from '../../styles/styles';
import _ from 'underscore';
import GoogleMeetIcon from '../../../assets/images/google-meet.svg';
import ZoomIcon from '../../../assets/images/zoom-icon.svg';
import CONST from '../../CONST';
import ONYXKEYS from '../../ONYXKEYS';
import DisplayNames from '../../components/DisplayNames';
import Icon from '../../components/Icon';
import * as Expensicons from '../../components/Icon/Expensicons';
import compose from '../../libs/compose';
import withWindowDimensions, {windowDimensionsPropTypes} from '../../components/withWindowDimensions';
import MultipleAvatars from '../../components/MultipleAvatars';
import ParentNavigationSubtitle from '../../components/ParentNavigationSubtitle';
import PressableWithoutFeedback from '../../components/Pressable/PressableWithoutFeedback';
import SubscriptAvatar from '../../components/SubscriptAvatar';
import DisplayNames from '../../components/DisplayNames';
import * as OptionsListUtils from '../../libs/OptionsListUtils';
import TaskHeaderActionButton from '../../components/TaskHeaderActionButton';
import Text from '../../components/Text';
import ThreeDotsMenu from '../../components/ThreeDotsMenu';
import Tooltip from '../../components/Tooltip';
import participantPropTypes from '../../components/participantPropTypes';
import VideoChatButtonAndMenu from '../../components/VideoChatButtonAndMenu';
import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize';
import CONST from '../../CONST';
import withWindowDimensions, {windowDimensionsPropTypes} from '../../components/withWindowDimensions';
import * as OptionsListUtils from '../../libs/OptionsListUtils';
import * as ReportActionsUtils from '../../libs/ReportActionsUtils';
import * as ReportUtils from '../../libs/ReportUtils';
import Text from '../../components/Text';
import Tooltip from '../../components/Tooltip';
import * as Link from '../../libs/actions/Link';
import * as Report from '../../libs/actions/Report';
import * as Session from '../../libs/actions/Session';
import * as Task from '../../libs/actions/Task';
import compose from '../../libs/compose';
import styles from '../../styles/styles';
import themeColors from '../../styles/themes/default';
import reportPropTypes from '../reportPropTypes';
import ONYXKEYS from '../../ONYXKEYS';
import ThreeDotsMenu from '../../components/ThreeDotsMenu';
import * as Task from '../../libs/actions/Task';
import PressableWithoutFeedback from '../../components/Pressable/PressableWithoutFeedback';
import PinButton from '../../components/PinButton';
import TaskHeaderActionButton from '../../components/TaskHeaderActionButton';
import * as ReportActionsUtils from '../../libs/ReportActionsUtils';
import ParentNavigationSubtitle from '../../components/ParentNavigationSubtitle';

const propTypes = {
/** Toggles the navigationMenu open and closed */
Expand Down Expand Up @@ -83,16 +86,18 @@ function HeaderView(props) {
const isAutomatedExpensifyAccount = ReportUtils.hasSingleParticipant(props.report) && ReportUtils.hasAutomatedExpensifyAccountIDs(participants);
const parentReportAction = ReportActionsUtils.getParentReportAction(props.report);
const isCanceledTaskReport = ReportUtils.isCanceledTaskReport(props.report, parentReportAction);
const lastVisibleMessage = ReportActionsUtils.getLastVisibleMessage(props.report.reportID);
const isEmptyChat = !props.report.lastMessageText && !props.report.lastMessageTranslationKey && !lastVisibleMessage.lastMessageText && !lastVisibleMessage.lastMessageTranslationKey;

// We hide the button when we are chatting with an automated Expensify account since it's not possible to contact
// these users via alternative means. It is possible to request a call with Concierge so we leave the option for them.
const shouldShowCallButton = (isConcierge && props.guideCalendarLink) || (!isAutomatedExpensifyAccount && !isTaskReport);
const threeDotMenuItems = [];
if (isTaskReport && !isCanceledTaskReport) {
const canModifyTask = Task.canModifyTask(props.report, props.session.accountID);
if (ReportUtils.isOpenTaskReport(props.report) && canModifyTask) {
threeDotMenuItems.push({
icon: Expensicons.Checkmark,
iconFill: themeColors.icon,
text: props.translate('task.markAsComplete'),
onSelected: () => Task.completeTask(props.report),
});
Expand All @@ -102,6 +107,7 @@ function HeaderView(props) {
if (ReportUtils.isCompletedTaskReport(props.report) && canModifyTask) {
threeDotMenuItems.push({
icon: Expensicons.Checkmark,
iconFill: themeColors.icon,
text: props.translate('task.markAsIncomplete'),
onSelected: () => Task.reopenTask(props.report),
});
Expand All @@ -111,11 +117,75 @@ function HeaderView(props) {
if (props.report.stateNum !== CONST.REPORT.STATE_NUM.SUBMITTED && props.report.statusNum !== CONST.REPORT.STATUS.CLOSED && canModifyTask) {
threeDotMenuItems.push({
icon: Expensicons.Trashcan,
iconFill: themeColors.icon,
text: props.translate('common.cancel'),
onSelected: () => Task.cancelTask(props.report.reportID, props.report.reportName, props.report.stateNum, props.report.statusNum),
});
}
}

if (isChatThread && !isEmptyChat) {
if (props.report.notificationPreference === CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN) {
threeDotMenuItems.push({
icon: Expensicons.ChatBubbles,
iconFill: themeColors.icon,
text: props.translate('common.joinThread'),
onSelected: () => Report.updateNotificationPreference(props.report.reportID, props.report.notificationPreference, CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS, false),
});
} else if (props.report.notificationPreference.length) {
threeDotMenuItems.push({
icon: Expensicons.ChatBubbles,
iconFill: themeColors.icon,
text: props.translate('common.leaveThread'),
onSelected: () => Report.leaveRoom(props.report.reportID),
});
}
}

if (!props.report.isPinned) {
threeDotMenuItems.push({
icon: Expensicons.Pin,
iconFill: themeColors.icon,
Copy link
Contributor

Choose a reason for hiding this comment

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

👋 Coming from #28535
This doesn't need an iconFill, the color is already applied by default, but passing it here was overriding the behavior when the icon changes color when you hover over it

text: props.translate('common.pin'),
onSelected: Session.checkIfActionIsAllowed(() => Report.togglePinnedState(props.report.reportID, props.report.isPinned)),
});
} else {
threeDotMenuItems.push({
icon: Expensicons.Pin,
iconFill: themeColors.icon,
text: props.translate('common.unPin'),
onSelected: Session.checkIfActionIsAllowed(() => Report.togglePinnedState(props.report.reportID, props.report.isPinned)),
});
}

if (isConcierge && props.guideCalendarLink) {
threeDotMenuItems.push({
icon: Expensicons.Phone,
iconFill: themeColors.icon,
text: props.translate('videoChatButtonAndMenu.tooltip'),
onSelected: () => {
Link.openExternalLink(props.guideCalendarLink);
},
});
} else if (!isAutomatedExpensifyAccount && !isTaskReport) {
threeDotMenuItems.push({
icon: ZoomIcon,
iconFill: themeColors.icon,
text: props.translate('videoChatButtonAndMenu.zoom'),
onSelected: () => {
Link.openExternalLink(CONST.NEW_ZOOM_MEETING_URL);
},
});
threeDotMenuItems.push({
icon: GoogleMeetIcon,
iconFill: themeColors.icon,
text: props.translate('videoChatButtonAndMenu.googleMeet'),
onSelected: () => {
Link.openExternalLink(CONST.NEW_GOOGLE_MEET_MEETING_URL);
},
});
}

const shouldShowThreeDotsButton = !!threeDotMenuItems.length;

const shouldShowSubscript = ReportUtils.shouldReportShowSubscript(props.report);
Expand Down Expand Up @@ -206,13 +276,6 @@ function HeaderView(props) {
</PressableWithoutFeedback>
<View style={[styles.reportOptions, styles.flexRow, styles.alignItemsCenter]}>
{isTaskReport && !props.isSmallScreenWidth && ReportUtils.isOpenTaskReport(props.report) && <TaskHeaderActionButton report={props.report} />}
{shouldShowCallButton && (
<VideoChatButtonAndMenu
isConcierge={isConcierge}
guideCalendarLink={props.guideCalendarLink}
/>
)}
<PinButton report={props.report} />
{shouldShowThreeDotsButton && (
<ThreeDotsMenu
anchorPosition={styles.threeDotsPopoverOffset(props.windowWidth)}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/settings/Report/NotificationPreferencePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ function NotificationPreferencePage(props) {
/>
<OptionsList
sections={[{data: notificationPreferenceOptions}]}
onSelectRow={(option) => Report.updateNotificationPreferenceAndNavigate(props.report.reportID, props.report.notificationPreference, option.value)}
onSelectRow={(option) => Report.updateNotificationPreference(props.report.reportID, props.report.notificationPreference, option.value, true)}
hideSectionHeaders
optionHoveredStyle={{
...styles.hoveredComponentBG,
Expand Down