-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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 Context menu with Pin option to LHN #16079
Changes from all commits
fc9aec9
5bbf1db
ffaf634
8789f75
d3befa3
28079fe
c3c45ce
a6e1aec
6b26871
cc83d47
6d65fb8
96c8256
eafa87f
310ae83
315fbc6
7ef10b8
5803c47
9f4349d
233ae47
223a550
294ed23
95de7c2
d4c619e
7263848
0c827dc
b554112
fb6c9b4
cc01e7e
8c45c6f
7f61b2a
3775be7
a0b72c6
f3c9046
c1a93de
beaa0e0
698b876
9e7ce9b
9cab709
f125e5d
fddded2
137631e
a433efb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,7 +1,7 @@ | ||||||||||||||
import _ from 'underscore'; | ||||||||||||||
import React from 'react'; | ||||||||||||||
import PropTypes from 'prop-types'; | ||||||||||||||
import {TouchableOpacity, View, StyleSheet} from 'react-native'; | ||||||||||||||
import {View, StyleSheet} from 'react-native'; | ||||||||||||||
import * as optionRowStyles from '../../styles/optionRowStyles'; | ||||||||||||||
import styles from '../../styles/styles'; | ||||||||||||||
import * as StyleUtils from '../../styles/StyleUtils'; | ||||||||||||||
|
@@ -19,6 +19,9 @@ import themeColors from '../../styles/themes/default'; | |||||||||||||
import SidebarUtils from '../../libs/SidebarUtils'; | ||||||||||||||
import TextPill from '../TextPill'; | ||||||||||||||
import OfflineWithFeedback from '../OfflineWithFeedback'; | ||||||||||||||
import PressableWithSecondaryInteraction from '../PressableWithSecondaryInteraction'; | ||||||||||||||
import * as ReportActionContextMenu from '../../pages/home/report/ContextMenu/ReportActionContextMenu'; | ||||||||||||||
import * as ContextMenuActions from '../../pages/home/report/ContextMenu/ContextMenuActions'; | ||||||||||||||
|
||||||||||||||
const propTypes = { | ||||||||||||||
/** Style for hovered state */ | ||||||||||||||
|
@@ -52,11 +55,16 @@ const defaultProps = { | |||||||||||||
|
||||||||||||||
const OptionRowLHN = (props) => { | ||||||||||||||
const optionItem = SidebarUtils.getOptionData(props.reportID); | ||||||||||||||
|
||||||||||||||
React.useEffect(() => { | ||||||||||||||
ReportActionContextMenu.hideContextMenu(false); | ||||||||||||||
}, [optionItem.isPinned]); | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Gonals we should add null safety check on this line. Sometimes app crashes when logout because Lines 197 to 202 in 0813e2c
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||||||||
|
||||||||||||||
if (!optionItem) { | ||||||||||||||
return null; | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
let touchableRef = null; | ||||||||||||||
let popoverAnchor = null; | ||||||||||||||
const textStyle = props.isFocused ? styles.sidebarLinkActiveText : styles.sidebarLinkText; | ||||||||||||||
const textUnreadStyle = optionItem.isUnread ? [textStyle, styles.sidebarLinkTextBold] : [textStyle]; | ||||||||||||||
const displayNameStyle = StyleUtils.combineStyles([styles.optionDisplayName, styles.optionDisplayNameCompact, styles.pre, ...textUnreadStyle], props.style); | ||||||||||||||
|
@@ -83,6 +91,28 @@ const OptionRowLHN = (props) => { | |||||||||||||
// If the item is a thread within a workspace, we will show the subtitle as the second line instead of in a pill | ||||||||||||||
const alternativeText = optionItem.isThread && optionItem.subtitle ? optionItem.subtitle : optionItem.alternateText; | ||||||||||||||
|
||||||||||||||
/** | ||||||||||||||
* Show the ReportActionContextMenu modal popover. | ||||||||||||||
* | ||||||||||||||
* @param {Object} [event] - A press event. | ||||||||||||||
*/ | ||||||||||||||
const showPopover = (event) => { | ||||||||||||||
ReportActionContextMenu.showContextMenu( | ||||||||||||||
ContextMenuActions.CONTEXT_MENU_TYPES.REPORT, | ||||||||||||||
event, | ||||||||||||||
'', | ||||||||||||||
popoverAnchor, | ||||||||||||||
props.reportID, | ||||||||||||||
{}, | ||||||||||||||
'', | ||||||||||||||
() => {}, | ||||||||||||||
() => {}, | ||||||||||||||
false, | ||||||||||||||
false, | ||||||||||||||
optionItem.isPinned, | ||||||||||||||
); | ||||||||||||||
}; | ||||||||||||||
|
||||||||||||||
return ( | ||||||||||||||
<OfflineWithFeedback | ||||||||||||||
pendingAction={optionItem.pendingAction} | ||||||||||||||
|
@@ -91,15 +121,17 @@ const OptionRowLHN = (props) => { | |||||||||||||
> | ||||||||||||||
<Hoverable> | ||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's use same pattern as others. What's the difference (pros/cons) between There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have |
||||||||||||||
{(hovered) => ( | ||||||||||||||
<TouchableOpacity | ||||||||||||||
ref={(el) => (touchableRef = el)} | ||||||||||||||
<PressableWithSecondaryInteraction | ||||||||||||||
ref={(el) => (popoverAnchor = el)} | ||||||||||||||
onPress={(e) => { | ||||||||||||||
if (e) { | ||||||||||||||
e.preventDefault(); | ||||||||||||||
} | ||||||||||||||
|
||||||||||||||
props.onSelectRow(optionItem, touchableRef); | ||||||||||||||
props.onSelectRow(optionItem, popoverAnchor); | ||||||||||||||
}} | ||||||||||||||
onSecondaryInteraction={(e) => showPopover(e)} | ||||||||||||||
withoutFocusOnSecondaryInteraction | ||||||||||||||
activeOpacity={0.8} | ||||||||||||||
style={[ | ||||||||||||||
styles.flexRow, | ||||||||||||||
|
@@ -213,7 +245,7 @@ const OptionRowLHN = (props) => { | |||||||||||||
</View> | ||||||||||||||
)} | ||||||||||||||
</View> | ||||||||||||||
</TouchableOpacity> | ||||||||||||||
</PressableWithSecondaryInteraction> | ||||||||||||||
)} | ||||||||||||||
</Hoverable> | ||||||||||||||
</OfflineWithFeedback> | ||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,6 +36,7 @@ const CONTEXT_MENU_TYPES = { | |
LINK: 'LINK', | ||
REPORT_ACTION: 'REPORT_ACTION', | ||
EMAIL: 'EMAIL', | ||
REPORT: 'REPORT', | ||
}; | ||
|
||
// A list of all the context actions in this menu. | ||
|
@@ -266,6 +267,30 @@ export default [ | |
}, | ||
getDescription: () => {}, | ||
}, | ||
{ | ||
textTranslateKey: 'common.pin', | ||
icon: Expensicons.Pin, | ||
shouldShow: (type, reportAction, isArchivedRoom, betas, anchor, isChronosReport, reportID, isPinnedChat) => type === CONTEXT_MENU_TYPES.REPORT && !isPinnedChat, | ||
onPress: (closePopover, {reportID}) => { | ||
Report.togglePinnedState(reportID, false); | ||
if (closePopover) { | ||
hideContextMenu(false); | ||
} | ||
}, | ||
Comment on lines
+273
to
+279
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it worth it to DRY this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean avoiding having two for pin/unpin? I tried a few options and even asked other engineers during ECX. Apparently, this is the way 🤷 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah I noticed shouldShow is the same for both, and onPress is similar but with the opposite bool values, but I'm good with this as is |
||
getDescription: () => {}, | ||
}, | ||
{ | ||
textTranslateKey: 'common.unPin', | ||
icon: Expensicons.Pin, | ||
shouldShow: (type, reportAction, isArchivedRoom, betas, anchor, isChronosReport, reportID, isPinnedChat) => type === CONTEXT_MENU_TYPES.REPORT && isPinnedChat, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Pin/UnPin options should not be visible on MoneyRequest chats as they are not pinnable. #20255 |
||
onPress: (closePopover, {reportID}) => { | ||
Report.togglePinnedState(reportID, true); | ||
if (closePopover) { | ||
hideContextMenu(false); | ||
} | ||
}, | ||
getDescription: () => {}, | ||
}, | ||
{ | ||
textTranslateKey: 'reportActionContextMenu.flagAsOffensive', | ||
icon: Expensicons.Flag, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm actually not seeing why this is necessary. I removed this and everything seems to work fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That discussion started from here.
Finally landed on #16079 (comment)