From 00114147ff8dc97c646f27ed4ace2e166193f045 Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Sun, 6 Aug 2023 06:32:20 +0500 Subject: [PATCH 1/6] fix: broken attachments and avatar picker --- src/components/AvatarWithImagePicker.js | 151 ++++++------- src/libs/Browser/index.js | 6 +- src/libs/Browser/index.web.js | 6 +- src/pages/home/report/ReportActionCompose.js | 215 +++++++++---------- 4 files changed, 189 insertions(+), 189 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 808d4cb39076..c2c0fb6ecf69 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -22,6 +22,7 @@ import * as FileUtils from '../libs/fileDownload/FileUtils'; import getImageResolution from '../libs/fileDownload/getImageResolution'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; import DotIndicatorMessage from './DotIndicatorMessage'; +import { isSafari } from '../libs/Browser'; const propTypes = { /** Avatar source to display */ @@ -229,42 +230,24 @@ class AvatarWithImagePicker extends React.Component { render() { const DefaultAvatar = this.props.DefaultAvatar; const additionalStyles = _.isArray(this.props.style) ? this.props.style : [this.props.style]; - const menuItems = [ - { - icon: Expensicons.Upload, - text: this.props.translate('avatarWithImagePicker.uploadPhoto'), - onSelected: () => {}, - }, - ]; - - // If current avatar isn't a default avatar, allow Remove Photo option - if (!this.props.isUsingDefaultAvatar) { - menuItems.push({ - icon: Expensicons.Trashcan, - text: this.props.translate('avatarWithImagePicker.removePhoto'), - onSelected: () => { - this.setError(null, {}); - this.props.onImageRemoved(); - }, - }); - } return ( - this.setState((prev) => ({isMenuVisible: !prev.isMenuVisible}))} - accessibilityRole={CONST.ACCESSIBILITY_ROLE.IMAGEBUTTON} - accessibilityLabel={this.props.translate('avatarWithImagePicker.editImage')} - disabled={this.state.isAvatarCropModalOpen} - > - - - + + + + this.setState((prev) => ({isMenuVisible: !prev.isMenuVisible}))} + accessibilityRole={CONST.ACCESSIBILITY_ROLE.IMAGEBUTTON} + accessibilityLabel={this.props.translate('avatarWithImagePicker.editImage')} + disabled={this.state.isAvatarCropModalOpen} + ref={this.anchorRef} + > {this.props.source ? ( )} - - - - - {({openPicker}) => ( - <> - - - - - - this.setState({isMenuVisible: false})} - onItemSelected={(item, index) => { - this.setState({isMenuVisible: false}); - // In order for the file picker to open dynamically, the click - // function must be called from within a event handler that was initiated - // by the user. - if (index === 0) { - openPicker({ - onPicked: this.showAvatarCropModal, - }); - } - }} - menuItems={menuItems} - anchorPosition={this.props.anchorPosition} - withoutOverlay - anchorRef={this.anchorRef} - anchorAlignment={this.props.anchorAlignment} + + - - )} - - - + + + + + + {({openPicker}) => { + const menuItems = [ + { + icon: Expensicons.Upload, + text: this.props.translate('avatarWithImagePicker.uploadPhoto'), + onSelected: () => { + if (!isSafari()) { + openPicker({ + onPicked: this.showAvatarCropModal, + }); + } + }, + }, + ]; + + // If current avatar isn't a default avatar, allow Remove Photo option + if (!this.props.isUsingDefaultAvatar) { + menuItems.push({ + icon: Expensicons.Trashcan, + text: this.props.translate('avatarWithImagePicker.removePhoto'), + onSelected: () => { + this.setError(null, {}); + this.props.onImageRemoved(); + }, + }); + } + return ( + this.setState({isMenuVisible: false})} + onItemSelected={(item, index) => { + this.setState({isMenuVisible: false}); + // In order for the file picker to open dynamically, the click + // function must be called from within a event handler that was initiated + // by the user on Safari. + if (index === 0 && isSafari()) { + openPicker({ + onPicked: this.showAvatarCropModal, + }); + } + }} + menuItems={menuItems} + anchorPosition={this.props.anchorPosition} + withoutOverlay + anchorRef={this.anchorRef} + anchorAlignment={this.props.anchorAlignment} + /> + ); + }} + + {this.state.validationError && ( {}, - }, - ]; - return ( ( <> - {({openPicker}) => ( - <> - - {this.props.isComposerFullSize && ( - - { - e.preventDefault(); - this.setShouldShowSuggestionMenuToFalse(); - Report.setIsComposerFullSize(this.props.reportID, false); - }} - // Keep focus on the composer when Collapse button is clicked. - onMouseDown={(e) => e.preventDefault()} - style={styles.composerSizeButton} - disabled={isBlockedFromConcierge || this.props.disabled} - accessibilityRole={CONST.ACCESSIBILITY_ROLE.BUTTON} - accessibilityLabel={this.props.translate('reportActionCompose.collapse')} - > - - - - )} - {!this.props.isComposerFullSize && isFullComposerAvailable && ( - + {({openPicker}) => { + const triggerAttachmentPicker = () => { + if (this.willBlurTextInputOnTapOutside) { + this.shouldBlockEmojiCalc = true; + this.shouldBlockMentionCalc = true; + } + openPicker({ + onPicked: displayFileInModal, + }); + }; + const menuItems = [ + ...this.getMoneyRequestOptions(reportParticipants), + ...this.getTaskOption(reportParticipants), + { + icon: Expensicons.Paperclip, + text: this.props.translate('reportActionCompose.addAttachment'), + onSelected: () => { + if (!Browser.isSafari()) { + triggerAttachmentPicker(); + } + }, + }, + ]; + return ( + <> + + {this.props.isComposerFullSize && ( + + { + e.preventDefault(); + this.setShouldShowSuggestionMenuToFalse(); + Report.setIsComposerFullSize(this.props.reportID, false); + }} + // Keep focus on the composer when Collapse button is clicked. + onMouseDown={(e) => e.preventDefault()} + style={styles.composerSizeButton} + disabled={isBlockedFromConcierge || this.props.disabled} + accessibilityRole={CONST.ACCESSIBILITY_ROLE.BUTTON} + accessibilityLabel={this.props.translate('reportActionCompose.collapse')} + > + + + + )} + {!this.props.isComposerFullSize && isFullComposerAvailable && ( + + { + e.preventDefault(); + this.setShouldShowSuggestionMenuToFalse(); + Report.setIsComposerFullSize(this.props.reportID, true); + }} + // Keep focus on the composer when Expand button is clicked. + onMouseDown={(e) => e.preventDefault()} + style={styles.composerSizeButton} + disabled={isBlockedFromConcierge || this.props.disabled} + accessibilityRole={CONST.ACCESSIBILITY_ROLE.BUTTON} + accessibilityLabel={this.props.translate('reportActionCompose.expand')} + > + + + + )} + { e.preventDefault(); - this.setShouldShowSuggestionMenuToFalse(); - Report.setIsComposerFullSize(this.props.reportID, true); + + // Drop focus to avoid blue focus ring. + this.actionButtonRef.current.blur(); + this.setMenuVisibility(!this.state.isMenuVisible); }} - // Keep focus on the composer when Expand button is clicked. - onMouseDown={(e) => e.preventDefault()} style={styles.composerSizeButton} disabled={isBlockedFromConcierge || this.props.disabled} accessibilityRole={CONST.ACCESSIBILITY_ROLE.BUTTON} - accessibilityLabel={this.props.translate('reportActionCompose.expand')} + accessibilityLabel={this.props.translate('reportActionCompose.addAction')} > - + - )} - - { - e.preventDefault(); - - // Drop focus to avoid blue focus ring. - this.actionButtonRef.current.blur(); - this.setMenuVisibility(!this.state.isMenuVisible); - }} - style={styles.composerSizeButton} - disabled={isBlockedFromConcierge || this.props.disabled} - accessibilityRole={CONST.ACCESSIBILITY_ROLE.BUTTON} - accessibilityLabel={this.props.translate('reportActionCompose.addAction')} - > - - - - - this.setMenuVisibility(false)} - onItemSelected={(item, index) => { - this.setMenuVisibility(false); - - // In order for the file picker to open dynamically, the click - // function must be called from within a event handler that was initiated - // by the user. - if (index === menuItems.length - 1) { - // Set a flag to block suggestion calculation until we're finished using the file picker, - // which will stop any flickering as the file picker opens on non-native devices. - if (this.willBlurTextInputOnTapOutside) { - this.shouldBlockEmojiCalc = true; - this.shouldBlockMentionCalc = true; + + this.setMenuVisibility(false)} + onItemSelected={(item, index) => { + this.setMenuVisibility(false); + + // In order for the file picker to open dynamically, the click + // function must be called from within a event handler that was initiated + // by the user on Safari. + if (index === menuItems.length - 1 && Browser.isSafari()) { + triggerAttachmentPicker(); } - openPicker({ - onPicked: displayFileInModal, - }); - } - }} - anchorPosition={styles.createMenuPositionReportActionCompose(this.props.windowHeight)} - anchorAlignment={{horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT, vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.BOTTOM}} - menuItems={[ - ...this.getMoneyRequestOptions(reportParticipants), - ...this.getTaskOption(), - { - icon: Expensicons.Paperclip, - text: this.props.translate('reportActionCompose.addAttachment'), - onSelected: () => { - // Set a flag to block suggestion calculation until we're finished using the file picker, - // which will stop any flickering as the file picker opens on non-native devices. - if (this.willBlurTextInputOnTapOutside) { - this.shouldBlockEmojiCalc = true; - this.shouldBlockMentionCalc = true; - } - - openPicker({ - onPicked: displayFileInModal, - }); - }, - }, - ]} - withoutOverlay - anchorRef={this.actionButtonRef} - /> - - )} + }} + anchorPosition={styles.createMenuPositionReportActionCompose(this.props.windowHeight)} + anchorAlignment={{horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.LEFT, vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.BOTTOM}} + menuItems={menuItems} + withoutOverlay + anchorRef={this.actionButtonRef} + /> + + ); + }} Date: Sun, 6 Aug 2023 06:43:50 +0500 Subject: [PATCH 2/6] fix: lint errors --- src/components/AvatarWithImagePicker.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index c2c0fb6ecf69..8db8db2d096f 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -22,7 +22,7 @@ import * as FileUtils from '../libs/fileDownload/FileUtils'; import getImageResolution from '../libs/fileDownload/getImageResolution'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; import DotIndicatorMessage from './DotIndicatorMessage'; -import { isSafari } from '../libs/Browser'; +import {isSafari} from '../libs/Browser'; const propTypes = { /** Avatar source to display */ @@ -274,7 +274,7 @@ class AvatarWithImagePicker extends React.Component { - {({openPicker}) => { + {({openPicker}) => { const menuItems = [ { icon: Expensicons.Upload, @@ -300,7 +300,7 @@ class AvatarWithImagePicker extends React.Component { }, }); } - return ( + return ( this.setState({isMenuVisible: false})} From 134e7ca952b7946f175a53e34fdf11cab19d2a63 Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Sun, 6 Aug 2023 06:49:20 +0500 Subject: [PATCH 3/6] fix: more lint errors fix: more lint errors --- src/components/AvatarWithImagePicker.js | 13 +++++++------ src/pages/home/report/ReportActionCompose.js | 5 +++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 8db8db2d096f..aa50d6db574b 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -22,7 +22,7 @@ import * as FileUtils from '../libs/fileDownload/FileUtils'; import getImageResolution from '../libs/fileDownload/getImageResolution'; import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; import DotIndicatorMessage from './DotIndicatorMessage'; -import {isSafari} from '../libs/Browser'; +import * as Browser from '../libs/Browser'; const propTypes = { /** Avatar source to display */ @@ -280,11 +280,12 @@ class AvatarWithImagePicker extends React.Component { icon: Expensicons.Upload, text: this.props.translate('avatarWithImagePicker.uploadPhoto'), onSelected: () => { - if (!isSafari()) { - openPicker({ - onPicked: this.showAvatarCropModal, - }); + if (Browser.isSafari()) { + return; } + openPicker({ + onPicked: this.showAvatarCropModal, + }); }, }, ]; @@ -309,7 +310,7 @@ class AvatarWithImagePicker extends React.Component { // In order for the file picker to open dynamically, the click // function must be called from within a event handler that was initiated // by the user on Safari. - if (index === 0 && isSafari()) { + if (index === 0 && Browser.isSafari()) { openPicker({ onPicked: this.showAvatarCropModal, }); diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 60953d9792fb..f842b1cb74d0 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -1057,9 +1057,10 @@ class ReportActionCompose extends React.Component { icon: Expensicons.Paperclip, text: this.props.translate('reportActionCompose.addAttachment'), onSelected: () => { - if (!Browser.isSafari()) { - triggerAttachmentPicker(); + if (Browser.isSafari()) { + return; } + triggerAttachmentPicker(); }, }, ]; From a7910437aac7a3ff4b4758ff4e36f7e10317716f Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Mon, 7 Aug 2023 03:51:50 +0500 Subject: [PATCH 4/6] Update src/pages/home/report/ReportActionCompose.js Co-authored-by: Aimane Chnaif <96077027+aimane-chnaif@users.noreply.github.com> --- src/pages/home/report/ReportActionCompose.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index f842b1cb74d0..0412c695d952 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -1052,7 +1052,7 @@ class ReportActionCompose extends React.Component { }; const menuItems = [ ...this.getMoneyRequestOptions(reportParticipants), - ...this.getTaskOption(reportParticipants), + ...this.getTaskOption(), { icon: Expensicons.Paperclip, text: this.props.translate('reportActionCompose.addAttachment'), From 4a38b113546d3e32d029d915e6305d82fc93c5a4 Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Mon, 7 Aug 2023 06:41:26 +0500 Subject: [PATCH 5/6] fix: increase precedence of keyboard listener --- src/components/PopoverProvider/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/PopoverProvider/index.js b/src/components/PopoverProvider/index.js index f8ecf5e6d135..e12e7a96e549 100644 --- a/src/components/PopoverProvider/index.js +++ b/src/components/PopoverProvider/index.js @@ -64,9 +64,9 @@ function PopoverContextProvider(props) { } closePopover(); }; - document.addEventListener('keydown', listener); + document.addEventListener('keydown', listener, true); return () => { - document.removeEventListener('keydown', listener); + document.removeEventListener('keydown', listener, true); }; }, [closePopover]); From 42bf664b9112a1c26dc199a51fb9770cb7db5ef1 Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Mon, 7 Aug 2023 21:10:23 +0500 Subject: [PATCH 6/6] fix: move comment --- src/pages/home/report/ReportActionCompose.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/home/report/ReportActionCompose.js b/src/pages/home/report/ReportActionCompose.js index 0412c695d952..48173754c3be 100644 --- a/src/pages/home/report/ReportActionCompose.js +++ b/src/pages/home/report/ReportActionCompose.js @@ -1042,6 +1042,8 @@ class ReportActionCompose extends React.Component { {({openPicker}) => { const triggerAttachmentPicker = () => { + // Set a flag to block suggestion calculation until we're finished using the file picker, + // which will stop any flickering as the file picker opens on non-native devices. if (this.willBlurTextInputOnTapOutside) { this.shouldBlockEmojiCalc = true; this.shouldBlockMentionCalc = true;