Skip to content

Commit

Permalink
Merge pull request #20288 from jayeshmangwani/feat_extract_camera_ico…
Browse files Browse the repository at this point in the history
…n_from_OfflineWithFeedback

Feat: Extract camera icon from offline with feedback
  • Loading branch information
johnmlee101 authored Jun 8, 2023
2 parents 977bdbc + 0b89be3 commit 24161f6
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 59 deletions.
58 changes: 42 additions & 16 deletions src/components/AvatarWithImagePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import themeColors from '../styles/themes/default';
import AttachmentPicker from './AttachmentPicker';
import ConfirmModal from './ConfirmModal';
import AvatarCropModal from './AvatarCropModal/AvatarCropModal';
import OfflineWithFeedback from './OfflineWithFeedback';
import withLocalize, {withLocalizePropTypes} from './withLocalize';
import variables from '../styles/variables';
import CONST from '../CONST';
Expand Down Expand Up @@ -64,6 +65,19 @@ const propTypes = {
/** Image crop vector mask */
editorMaskImage: PropTypes.func,

/** Additional style object for the error row */
errorRowStyles: stylePropTypes,

/** A function to run when the X button next to the error is clicked */
onErrorClose: PropTypes.func,

/** The type of action that's pending */
pendingAction: PropTypes.oneOf(['add', 'update', 'delete']),

/** The errors to display */
// eslint-disable-next-line react/forbid-prop-types
errors: PropTypes.object,

...withLocalizePropTypes,
};

Expand All @@ -79,6 +93,10 @@ const defaultProps = {
fallbackIcon: Expensicons.FallbackAvatar,
type: CONST.ICON_TYPE_AVATAR,
editorMaskImage: undefined,
errorRowStyles: [],
onErrorClose: () => {},
pendingAction: null,
errors: null,
};

class AvatarWithImagePicker extends React.Component {
Expand Down Expand Up @@ -263,22 +281,30 @@ class AvatarWithImagePicker extends React.Component {
accessibilityLabel={this.props.translate('avatarWithImagePicker.editImage')}
>
<View style={[styles.pRelative, styles.avatarLarge]}>
<Tooltip text={this.props.translate('avatarWithImagePicker.editImage')}>
<View>
{this.props.source ? (
<Avatar
containerStyles={styles.avatarLarge}
imageStyles={[styles.avatarLarge, styles.alignSelfCenter]}
source={this.props.source}
fallbackIcon={this.props.fallbackIcon}
size={this.props.size}
type={this.props.type}
/>
) : (
<DefaultAvatar />
)}
</View>
</Tooltip>
<OfflineWithFeedback
pendingAction={this.props.pendingAction}
errors={this.props.errors}
errorRowStyles={this.props.errorRowStyles}
onClose={this.props.onErrorClose}
>
<Tooltip text={this.props.translate('avatarWithImagePicker.editImage')}>
<View>
{this.props.source ? (
<Avatar
containerStyles={styles.avatarLarge}
imageStyles={[styles.avatarLarge, styles.alignSelfCenter]}
source={this.props.source}
fallbackIcon={this.props.fallbackIcon}
size={this.props.size}
type={this.props.type}
/>
) : (
<DefaultAvatar />
)}
</View>
</Tooltip>
</OfflineWithFeedback>

<AttachmentPicker type={CONST.ATTACHMENT_PICKER_TYPE.IMAGE}>
{({openPicker}) => (
<>
Expand Down
24 changes: 10 additions & 14 deletions src/pages/settings/Profile/ProfilePage.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import AvatarWithImagePicker from '../../../components/AvatarWithImagePicker';
import HeaderWithBackButton from '../../../components/HeaderWithBackButton';
import MenuItem from '../../../components/MenuItem';
import MenuItemWithTopDescription from '../../../components/MenuItemWithTopDescription';
import OfflineWithFeedback from '../../../components/OfflineWithFeedback';
import ScreenWrapper from '../../../components/ScreenWrapper';
import withCurrentUserPersonalDetails, {withCurrentUserPersonalDetailsDefaultProps, withCurrentUserPersonalDetailsPropTypes} from '../../../components/withCurrentUserPersonalDetails';
import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize';
Expand Down Expand Up @@ -88,22 +87,19 @@ const ProfilePage = (props) => {
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS)}
/>
<ScrollView>
<OfflineWithFeedback
<AvatarWithImagePicker
isUsingDefaultAvatar={UserUtils.isDefaultAvatar(lodashGet(currentUserDetails, 'avatar', ''))}
source={UserUtils.getAvatar(lodashGet(currentUserDetails, 'avatar', ''), lodashGet(currentUserDetails, 'login', ''))}
onImageSelected={PersonalDetails.updateAvatar}
onImageRemoved={PersonalDetails.deleteAvatar}
anchorPosition={styles.createMenuPositionProfile(props.windowWidth)}
anchorAlignment={{horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.CENTER, vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP}}
size={CONST.AVATAR_SIZE.LARGE}
pendingAction={lodashGet(props.currentUserPersonalDetails, 'pendingFields.avatar', null)}
errors={lodashGet(props.currentUserPersonalDetails, 'errorFields.avatar', null)}
errorRowStyles={[styles.mt6]}
onClose={PersonalDetails.clearAvatarErrors}
>
<AvatarWithImagePicker
isUsingDefaultAvatar={UserUtils.isDefaultAvatar(lodashGet(currentUserDetails, 'avatar', ''))}
source={UserUtils.getAvatar(lodashGet(currentUserDetails, 'avatar', ''), lodashGet(currentUserDetails, 'login', ''))}
onImageSelected={PersonalDetails.updateAvatar}
onImageRemoved={PersonalDetails.deleteAvatar}
anchorPosition={styles.createMenuPositionProfile(props.windowWidth)}
anchorAlignment={{horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.CENTER, vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP}}
size={CONST.AVATAR_SIZE.LARGE}
/>
</OfflineWithFeedback>
onErrorClose={PersonalDetails.clearAvatarErrors}
/>
<View style={[styles.mt4]}>
{_.map(profileSettingsOptions, (detail, index) => (
<MenuItemWithTopDescription
Expand Down
55 changes: 26 additions & 29 deletions src/pages/workspace/WorkspaceSettingsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,37 +104,34 @@ function WorkspaceSettingsPage(props) {
onSubmit={submit}
enabledWhenOffline
>
<OfflineWithFeedback
<AvatarWithImagePicker
isUploading={props.policy.isAvatarUploading}
source={lodashGet(props.policy, 'avatar')}
size={CONST.AVATAR_SIZE.LARGE}
DefaultAvatar={() => (
<Avatar
containerStyles={styles.avatarLarge}
imageStyles={[styles.avatarLarge, styles.alignSelfCenter]}
source={props.policy.avatar ? props.policy.avatar : ReportUtils.getDefaultWorkspaceAvatar(policyName)}
fallbackIcon={Expensicons.FallbackWorkspaceAvatar}
size={CONST.AVATAR_SIZE.LARGE}
name={policyName}
type={CONST.ICON_TYPE_WORKSPACE}
/>
)}
type={CONST.ICON_TYPE_WORKSPACE}
fallbackIcon={Expensicons.FallbackWorkspaceAvatar}
style={[styles.mb3]}
anchorPosition={styles.createMenuPositionProfile(props.windowWidth)}
anchorAlignment={{horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.CENTER, vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP}}
isUsingDefaultAvatar={!lodashGet(props.policy, 'avatar', null)}
onImageSelected={(file) => Policy.updateWorkspaceAvatar(lodashGet(props.policy, 'id', ''), file)}
onImageRemoved={() => Policy.deleteWorkspaceAvatar(lodashGet(props.policy, 'id', ''))}
editorMaskImage={Expensicons.ImageCropSquareMask}
pendingAction={lodashGet(props.policy, 'pendingFields.avatar', null)}
errors={lodashGet(props.policy, 'errorFields.avatar', null)}
onClose={() => Policy.clearAvatarErrors(props.policy.id)}
>
<AvatarWithImagePicker
isUploading={props.policy.isAvatarUploading}
source={lodashGet(props.policy, 'avatar')}
size={CONST.AVATAR_SIZE.LARGE}
DefaultAvatar={() => (
<Avatar
containerStyles={styles.avatarLarge}
imageStyles={[styles.avatarLarge, styles.alignSelfCenter]}
source={props.policy.avatar ? props.policy.avatar : ReportUtils.getDefaultWorkspaceAvatar(policyName)}
fallbackIcon={Expensicons.FallbackWorkspaceAvatar}
size={CONST.AVATAR_SIZE.LARGE}
name={policyName}
type={CONST.ICON_TYPE_WORKSPACE}
/>
)}
type={CONST.ICON_TYPE_WORKSPACE}
fallbackIcon={Expensicons.FallbackWorkspaceAvatar}
style={[styles.mb3]}
anchorPosition={styles.createMenuPositionProfile(props.windowWidth)}
anchorAlignment={{horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.CENTER, vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP}}
isUsingDefaultAvatar={!lodashGet(props.policy, 'avatar', null)}
onImageSelected={(file) => Policy.updateWorkspaceAvatar(lodashGet(props.policy, 'id', ''), file)}
onImageRemoved={() => Policy.deleteWorkspaceAvatar(lodashGet(props.policy, 'id', ''))}
editorMaskImage={Expensicons.ImageCropSquareMask}
/>
</OfflineWithFeedback>
onErrorClose={() => Policy.clearAvatarErrors(props.policy.id)}
/>
<OfflineWithFeedback pendingAction={lodashGet(props.policy, 'pendingFields.generalSettings')}>
<TextInput
inputID="name"
Expand Down

0 comments on commit 24161f6

Please sign in to comment.