-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Context-menu repositioned #4194
Merged
Merged
Changes from 17 commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
d869215
Context-menu repositioned
parasharrajat fd92bb3
fix: state props
parasharrajat a6e4b74
fix: positioning of menu
parasharrajat f9a0332
fixed ContextMenu actions
parasharrajat 2ef41c7
finalize the menu
parasharrajat 8e8e221
Optimizations for Conextmenu
parasharrajat 7d883ae
cleanup
parasharrajat e0451f6
refactor Context Menu
parasharrajat 70491bf
Pull latest changes
parasharrajat 00478fe
refactor
parasharrajat b1b9877
fix: realtime update issue with menus
parasharrajat 9ea5d71
Pulled changes
parasharrajat df3c6e9
refactor Context Menu
parasharrajat 62b400e
refactor and minor changes
parasharrajat d5ca87e
Rename and fix errors
parasharrajat a964270
fix: Highlight issue when contextMenu toggle between open and close s…
parasharrajat 498b558
clean up
parasharrajat 2bb1e3f
extra code revomed
parasharrajat baf1d29
break fix
parasharrajat bec3d56
refactor code and added comments
parasharrajat File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
src/pages/home/report/ContextMenu/BaseReportActionContextMenu.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import React from 'react'; | ||
import {View} from 'react-native'; | ||
import getReportActionContextMenuStyles from '../../../../styles/getReportActionContextMenuStyles'; | ||
import ContextMenuItem from '../../../../components/ContextMenuItem'; | ||
import { | ||
propTypes as GenericReportActionContextMenuPropTypes, | ||
defaultProps, | ||
} from './GenericReportActionContextMenuPropTypes'; | ||
import withLocalize, {withLocalizePropTypes} from '../../../../components/withLocalize'; | ||
import ContextMenuActions from './ContextMenuActions'; | ||
|
||
const propTypes = { | ||
...GenericReportActionContextMenuPropTypes, | ||
...withLocalizePropTypes, | ||
}; | ||
|
||
class BaseReportActionContextMenu extends React.Component { | ||
constructor(props) { | ||
super(props); | ||
|
||
this.wrapperStyle = getReportActionContextMenuStyles(this.props.isMini); | ||
} | ||
|
||
render() { | ||
return this.props.isVisible && ( | ||
<View style={this.wrapperStyle}> | ||
{ContextMenuActions.map(contextAction => contextAction.shouldShow(this.props.reportAction) && ( | ||
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.
|
||
<ContextMenuItem | ||
icon={contextAction.icon} | ||
text={this.props.translate(contextAction.textTranslateKey)} | ||
successIcon={contextAction.successIcon} | ||
successText={contextAction.successTextTranslateKey | ||
? this.props.translate(contextAction.successTextTranslateKey) | ||
: undefined} | ||
isMini={this.props.isMini} | ||
key={contextAction.textTranslateKey} | ||
onPress={() => contextAction.onPress(!this.props.isMini, { | ||
reportAction: this.props.reportAction, | ||
reportID: this.props.reportID, | ||
draftMessage: this.props.draftMessage, | ||
selection: this.props.selection, | ||
})} | ||
/> | ||
))} | ||
</View> | ||
); | ||
} | ||
} | ||
|
||
BaseReportActionContextMenu.propTypes = propTypes; | ||
BaseReportActionContextMenu.defaultProps = defaultProps; | ||
|
||
export default withLocalize(BaseReportActionContextMenu); |
116 changes: 116 additions & 0 deletions
116
src/pages/home/report/ContextMenu/ContextMenuActions.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,116 @@ | ||||||
import _ from 'underscore'; | ||||||
import lodashGet from 'lodash/get'; | ||||||
import Str from 'expensify-common/lib/str'; | ||||||
import { | ||||||
Clipboard as ClipboardIcon, LinkCopy, Mail, Pencil, Trashcan, Checkmark, | ||||||
} from '../../../../components/Icon/Expensicons'; | ||||||
import { | ||||||
setNewMarkerPosition, updateLastReadActionID, saveReportActionDraft, | ||||||
} from '../../../../libs/actions/Report'; | ||||||
import Clipboard from '../../../../libs/Clipboard'; | ||||||
import {isReportMessageAttachment, canEditReportAction, canDeleteReportAction} from '../../../../libs/reportUtils'; | ||||||
import ReportActionComposeFocusManager from '../../../../libs/ReportActionComposeFocusManager'; | ||||||
import {hideContextMenu, showDeleteModal} from './ReportActionContextMenu'; | ||||||
|
||||||
/** | ||||||
* Gets the markdown version of the message in an action. | ||||||
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. NAB:
Suggested change
|
||||||
* @param {Object} reportAction | ||||||
* @return {String} | ||||||
*/ | ||||||
function getActionText(reportAction) { | ||||||
const message = _.last(lodashGet(reportAction, 'message', null)); | ||||||
return lodashGet(message, 'html', ''); | ||||||
} | ||||||
|
||||||
// A list of all the context actions in this menu. | ||||||
export default [ | ||||||
// Copy to clipboard | ||||||
{ | ||||||
textTranslateKey: 'contextMenuItem.copyToClipboard', | ||||||
icon: ClipboardIcon, | ||||||
successTextTranslateKey: 'contextMenuItem.copied', | ||||||
successIcon: Checkmark, | ||||||
shouldShow: () => true, | ||||||
|
||||||
// If return value is true, we switch the `text` and `icon` on | ||||||
// `ContextMenuItem` with `successText` and `successIcon` which will fallback to | ||||||
// the `text` and `icon` | ||||||
onPress: (closePopover, {reportAction, selection}) => { | ||||||
const message = _.last(lodashGet(reportAction, 'message', null)); | ||||||
const html = lodashGet(message, 'html', ''); | ||||||
const text = Str.htmlDecode(selection || lodashGet(message, 'text', '')); | ||||||
const isAttachment = _.has(reportAction, 'isAttachment') | ||||||
? reportAction.isAttachment | ||||||
: isReportMessageAttachment(text); | ||||||
if (!isAttachment) { | ||||||
Clipboard.setString(text); | ||||||
} else { | ||||||
Clipboard.setString(html); | ||||||
} | ||||||
if (closePopover) { | ||||||
hideContextMenu(true, ReportActionComposeFocusManager.focus); | ||||||
} | ||||||
}, | ||||||
}, | ||||||
|
||||||
{ | ||||||
textTranslateKey: 'reportActionContextMenu.copyLink', | ||||||
icon: LinkCopy, | ||||||
shouldShow: () => false, | ||||||
onPress: () => {}, | ||||||
}, | ||||||
|
||||||
{ | ||||||
textTranslateKey: 'reportActionContextMenu.markAsUnread', | ||||||
icon: Mail, | ||||||
successIcon: Checkmark, | ||||||
shouldShow: () => true, | ||||||
onPress: (closePopover, {reportAction, reportID}) => { | ||||||
updateLastReadActionID(reportID, reportAction.sequenceNumber); | ||||||
setNewMarkerPosition(reportID, reportAction.sequenceNumber); | ||||||
if (closePopover) { | ||||||
hideContextMenu(true, ReportActionComposeFocusManager.focus); | ||||||
} | ||||||
}, | ||||||
}, | ||||||
|
||||||
{ | ||||||
textTranslateKey: 'reportActionContextMenu.editComment', | ||||||
icon: Pencil, | ||||||
shouldShow: reportAction => canEditReportAction(reportAction), | ||||||
onPress: (closePopover, {reportID, reportAction, draftMessage}) => { | ||||||
const editAction = () => saveReportActionDraft( | ||||||
reportID, | ||||||
reportAction.reportActionID, | ||||||
_.isEmpty(draftMessage) ? getActionText(reportAction) : '', | ||||||
); | ||||||
|
||||||
if (closePopover) { | ||||||
// Hide popover, then call editAction | ||||||
hideContextMenu(false, editAction); | ||||||
return; | ||||||
} | ||||||
|
||||||
// No popover to hide, call editAction immediately | ||||||
editAction(); | ||||||
}, | ||||||
}, | ||||||
{ | ||||||
textTranslateKey: 'reportActionContextMenu.deleteComment', | ||||||
icon: Trashcan, | ||||||
shouldShow: reportAction => canDeleteReportAction(reportAction), | ||||||
onPress: (closePopover, {reportID, reportAction}) => { | ||||||
if (closePopover) { | ||||||
// Hide popover, then call showDeleteConfirmModal | ||||||
hideContextMenu( | ||||||
false, | ||||||
() => showDeleteModal(reportID, reportAction), | ||||||
); | ||||||
return; | ||||||
} | ||||||
|
||||||
// No popover to hide, call showDeleteConfirmModal immediately | ||||||
showDeleteModal(reportID, reportAction); | ||||||
}, | ||||||
}, | ||||||
]; |
32 changes: 32 additions & 0 deletions
32
src/pages/home/report/ContextMenu/GenericReportActionContextMenuPropTypes.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import PropTypes from 'prop-types'; | ||
import ReportActionPropTypes from '../ReportActionPropTypes'; | ||
|
||
const propTypes = { | ||
/** The ID of the report this report action is attached to. */ | ||
reportID: PropTypes.number.isRequired, | ||
|
||
/** The report action this context menu is attached to. */ | ||
reportAction: PropTypes.shape(ReportActionPropTypes).isRequired, | ||
|
||
/** If true, this component will be a small, row-oriented menu that displays icons but not text. | ||
If false, this component will be a larger, column-oriented menu that displays icons alongside text in each row. */ | ||
isMini: PropTypes.bool, | ||
|
||
/** Controls the visibility of this component. */ | ||
isVisible: PropTypes.bool, | ||
|
||
/** The copy selection of text. */ | ||
selection: PropTypes.string, | ||
|
||
/** Draft message - if this is set the comment is in 'edit' mode */ | ||
draftMessage: PropTypes.string, | ||
}; | ||
|
||
const defaultProps = { | ||
isMini: false, | ||
isVisible: false, | ||
selection: '', | ||
draftMessage: '', | ||
}; | ||
|
||
export {propTypes, defaultProps}; |
36 changes: 36 additions & 0 deletions
36
src/pages/home/report/ContextMenu/MiniReportActionContextMenu/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import _ from 'underscore'; | ||
import React from 'react'; | ||
import {View} from 'react-native'; | ||
import PropTypes from 'prop-types'; | ||
import { | ||
propTypes as GenericReportActionContextMenuPropTypes, | ||
defaultProps as GenericReportActionContextMenuDefaultProps, | ||
} from '../GenericReportActionContextMenuPropTypes'; | ||
import {getMiniReportActionContextMenuWrapperStyle} from '../../../../../styles/getReportActionItemStyles'; | ||
import BaseReportActionContextMenu from '../BaseReportActionContextMenu'; | ||
|
||
const propTypes = { | ||
..._.omit(GenericReportActionContextMenuPropTypes, ['isMini']), | ||
|
||
/** Should the reportAction this menu is attached to have the appearance of being | ||
* grouped with the previous reportAction? */ | ||
displayAsGroup: PropTypes.bool, | ||
}; | ||
|
||
const defaultProps = { | ||
..._.omit(GenericReportActionContextMenuDefaultProps, ['isMini']), | ||
displayAsGroup: false, | ||
}; | ||
|
||
const MiniReportActionContextMenu = props => ( | ||
<View style={getMiniReportActionContextMenuWrapperStyle(props.displayAsGroup)}> | ||
{/* eslint-disable-next-line react/jsx-props-no-spreading */} | ||
<BaseReportActionContextMenu isMini {...props} /> | ||
</View> | ||
); | ||
|
||
MiniReportActionContextMenu.propTypes = propTypes; | ||
MiniReportActionContextMenu.defaultProps = defaultProps; | ||
MiniReportActionContextMenu.displayName = 'MiniReportActionContextMenu'; | ||
|
||
export default MiniReportActionContextMenu; |
1 change: 1 addition & 0 deletions
1
src/pages/home/report/ContextMenu/MiniReportActionContextMenu/index.native.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export default () => null; |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
derived state is sort of confusing and usually anti-pattern since we don't have a single source of truth for
isVisible
anymore. Maybe just put this back to what it was..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 had to use it to prevent unnecessary render & unmount after isVisible is set on the Popover.
we have a callback onModalHide which fires on the following conditions.
Previously, we are triggering the rerendering of the Modal when
isvisible
is set to true which first unmounts the old Popover and then remounts it with calculated dimensions.Here onModalHide is called due to the reason that isVisible is true and unmounting is happening.
This code does not render the popover until it is measured. we use onModalHide call to reset the reportAction and reportId back to null.
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.
Ok, we can maybe try to improve this in a follow up I don't have a better suggestion at the moment.
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.
Would be good to leave a code comment explaining this.