Skip to content

Commit

Permalink
Merge pull request #7852 from Expensify/marco-avatarsWorkspaceChats
Browse files Browse the repository at this point in the history
  • Loading branch information
roryabraham authored Mar 4, 2022
2 parents c429fe2 + 45b90ae commit 7d6ed27
Show file tree
Hide file tree
Showing 23 changed files with 396 additions and 186 deletions.
8 changes: 7 additions & 1 deletion src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -551,8 +551,14 @@ const CONST = {
AVATAR_SIZE: {
LARGE: 'large',
DEFAULT: 'default',
SMALL: 'small',
SUBSCRIPT: 'subscript',
SMALL_SUBSCRIPT: 'small-subscript',
},
OPTION_MODE: {
COMPACT: 'compact',
DEFAULT: 'default',
},

PHONE_MAX_LENGTH: 15,
PHONE_MIN_LENGTH: 5,
REGEX: {
Expand Down
45 changes: 22 additions & 23 deletions src/components/Avatar.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import React, {PureComponent} from 'react';
import {Image, View} from 'react-native';
import PropTypes from 'prop-types';
import styles from '../styles/styles';
import themeColors from '../styles/themes/default';
import RoomAvatar from './RoomAvatar';
import _ from 'underscore';
import stylePropTypes from '../styles/stylePropTypes';
import Icon from './Icon';
import themeColors from '../styles/themes/default';
import CONST from '../CONST';
import * as StyleUtils from '../styles/StyleUtils';


const propTypes = {
/** Url source for the avatar */
source: PropTypes.string,
/** Source for the avatar. Can be a URL or an icon. */
source: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),

/** Extra styles to pass to Image */
imageStyles: PropTypes.arrayOf(PropTypes.object),
Expand All @@ -17,43 +20,39 @@ const propTypes = {
containerStyles: stylePropTypes,

/** Set the size of Avatar */
size: PropTypes.oneOf(['default', 'small']),
size: PropTypes.oneOf(_.values(CONST.AVATAR_SIZE)),

/** Whether this avatar is for a chat room */
isChatRoom: PropTypes.bool,

/** Whether this avatar is for an archived default room */
isArchivedRoom: PropTypes.bool,
/** The fill color for the icon. Can be hex, rgb, rgba, or valid react-native named color such as 'red' or 'blue' */
fill: PropTypes.string,
};

const defaultProps = {
source: '',
source: null,
imageStyles: [],
containerStyles: [],
size: 'default',
isChatRoom: false,
isArchivedRoom: false,
size: CONST.AVATAR_SIZE.DEFAULT,
fill: themeColors.icon,
};

class Avatar extends PureComponent {
render() {
if (!this.props.source && !this.props.isChatRoom) {
if (!this.props.source) {
return null;
}

const imageStyle = [
this.props.size === 'small' ? styles.avatarSmall : styles.avatarNormal,

// Background color isn't added for room avatar because it changes it's shape to a square
this.props.isChatRoom ? {} : {backgroundColor: themeColors.icon},
StyleUtils.getAvatarStyle(this.props.size),
...this.props.imageStyles,
];

const iconSize = StyleUtils.getAvatarSize(this.props.size);
return (
<View pointerEvents="none" style={this.props.containerStyles}>
{this.props.isChatRoom
? <RoomAvatar avatarStyle={imageStyle} isArchived={this.props.isArchivedRoom} />
: <Image source={{uri: this.props.source}} style={imageStyle} />}
{
_.isFunction(this.props.source)
? <Icon src={this.props.source} fill={this.props.fill} height={iconSize} width={iconSize} />
: <Image source={{uri: this.props.source}} style={imageStyle} />
}
</View>
);
}
Expand Down
4 changes: 4 additions & 0 deletions src/components/Icon/Expensicons.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,11 @@ import Users from '../../../assets/images/users.svg';
import Venmo from '../../../assets/images/venmo.svg';
import Wallet from '../../../assets/images/wallet.svg';
import Workspace from '../../../assets/images/workspace-default-avatar.svg';
import ActiveRoomAvatar from '../../../assets/images/avatars/room.svg';
import DeletedRoomAvatar from '../../../assets/images/avatars/deleted-room.svg';

export {
ActiveRoomAvatar,
Android,
Apple,
ArrowRight,
Expand All @@ -92,6 +95,7 @@ export {
ClosedSign,
Concierge,
CreditCard,
DeletedRoomAvatar,
DownArrow,
Download,
Emoji,
Expand Down
51 changes: 23 additions & 28 deletions src/components/MultipleAvatars.js
Original file line number Diff line number Diff line change
@@ -1,62 +1,57 @@
import React, {memo} from 'react';
import PropTypes from 'prop-types';
import {Image, View} from 'react-native';
import _ from 'underscore';
import styles from '../styles/styles';
import Avatar from './Avatar';
import Tooltip from './Tooltip';
import Text from './Text';
import themeColors from '../styles/themes/default';
import * as StyleUtils from '../styles/StyleUtils';
import CONST from '../CONST';

const propTypes = {
/** Array of avatar URL */
avatarImageURLs: PropTypes.arrayOf(PropTypes.string),
/** Array of avatar URLs or icons */
avatarIcons: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.func])),

/** Set the sie of avatars */
size: PropTypes.oneOf(['default', 'small']),
/** Set the size of avatars */
size: PropTypes.oneOf(_.values(CONST.AVATAR_SIZE)),

/** Style for Second Avatar */
// eslint-disable-next-line react/forbid-prop-types
secondAvatarStyle: PropTypes.arrayOf(PropTypes.object),

/** Whether this avatar is for a chat room */
isChatRoom: PropTypes.bool,

/** Whether this avatar is for an archived room */
isArchivedRoom: PropTypes.bool,

/** Tooltip for the Avatar */
avatarTooltips: PropTypes.arrayOf(PropTypes.string),
};

const defaultProps = {
avatarImageURLs: [],
size: 'default',
secondAvatarStyle: [styles.secondAvatarHovered],
isChatRoom: false,
isArchivedRoom: false,
avatarIcons: [],
size: CONST.AVATAR_SIZE.DEFAULT,
secondAvatarStyle: [StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)],
avatarTooltips: [],
};

const MultipleAvatars = (props) => {
const avatarContainerStyles = props.size === 'small' ? styles.emptyAvatarSmall : styles.emptyAvatar;
const singleAvatarStyles = props.size === 'small' ? styles.singleAvatarSmall : styles.singleAvatar;
const avatarContainerStyles = props.size === CONST.AVATAR_SIZE.SMALL ? styles.emptyAvatarSmall : styles.emptyAvatar;
const singleAvatarStyles = props.size === CONST.AVATAR_SIZE.SMALL ? styles.singleAvatarSmall : styles.singleAvatar;
const secondAvatarStyles = [
props.size === 'small' ? styles.secondAvatarSmall : styles.secondAvatar,
props.size === CONST.AVATAR_SIZE.SMALL ? styles.secondAvatarSmall : styles.secondAvatar,
...props.secondAvatarStyle,
];

if (!props.avatarImageURLs.length) {
if (!props.avatarIcons.length) {
return null;
}

if (props.avatarImageURLs.length === 1) {
if (props.avatarIcons.length === 1) {
return (
<View style={avatarContainerStyles}>
<Tooltip text={props.avatarTooltips[0]}>
<Avatar
source={props.avatarImageURLs[0]}
source={props.avatarIcons[0]}
size={props.size}
isChatRoom={props.isChatRoom}
isArchivedRoom={props.isArchivedRoom}
fill={themeColors.iconSuccessFill}
/>
</Tooltip>
</View>
Expand All @@ -70,17 +65,17 @@ const MultipleAvatars = (props) => {
>
<Tooltip text={props.avatarTooltips[0]} absolute>
<Image
source={{uri: props.avatarImageURLs[0]}}
source={{uri: props.avatarIcons[0]}}
style={singleAvatarStyles}
/>
</Tooltip>
<View
style={secondAvatarStyles}
>
{props.avatarImageURLs.length === 2 ? (
{props.avatarIcons.length === 2 ? (
<Tooltip text={props.avatarTooltips[1]} absolute>
<Image
source={{uri: props.avatarImageURLs[1]}}
source={{uri: props.avatarIcons[1]}}
style={singleAvatarStyles}
/>
</Tooltip>
Expand All @@ -89,11 +84,11 @@ const MultipleAvatars = (props) => {
<View
style={[singleAvatarStyles, styles.alignItemsCenter, styles.justifyContentCenter]}
>
<Text style={props.size === 'small'
<Text style={props.size === CONST.AVATAR_SIZE.SMALL
? styles.avatarInnerTextSmall
: styles.avatarInnerText}
>
{`+${props.avatarImageURLs.length - 1}`}
{`+${props.avatarIcons.length - 1}`}
</Text>
</View>
</Tooltip>
Expand Down
4 changes: 3 additions & 1 deletion src/components/OptionsList/optionsListPropTypes.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import PropTypes from 'prop-types';
import _ from 'underscore';
import SectionList from '../SectionList';
import styles from '../../styles/styles';
import optionPropTypes from '../optionPropTypes';
import CONST from '../../CONST';

const propTypes = {
/** option Background Color */
Expand Down Expand Up @@ -69,7 +71,7 @@ const propTypes = {
showTitleTooltip: PropTypes.bool,

/** Toggle between compact and default view of the option */
optionMode: PropTypes.oneOf(['compact', 'default']),
optionMode: PropTypes.oneOf(_.values(CONST.OPTION_MODE)),

/** Whether to disable the interactivity of the list's option row(s) */
disableRowInteractivity: PropTypes.bool,
Expand Down
2 changes: 1 addition & 1 deletion src/components/ReportActionItem/IOUPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ const IOUPreview = (props) => {
</View>
<View style={styles.iouPreviewBoxAvatar}>
<MultipleAvatars
avatarImageURLs={[managerAvatar, ownerAvatar]}
avatarIcons={[managerAvatar, ownerAvatar]}
secondAvatarStyle={[styles.secondAvatarInline]}
avatarTooltips={avatarTooltip}
/>
Expand Down
31 changes: 0 additions & 31 deletions src/components/RoomAvatar.js

This file was deleted.

53 changes: 38 additions & 15 deletions src/components/RoomHeaderAvatars.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,46 +6,69 @@ import styles from '../styles/styles';
import Text from './Text';
import CONST from '../CONST';
import Avatar from './Avatar';
import themeColors from '../styles/themes/default';
import * as StyleUtils from '../styles/StyleUtils';

const propTypes = {
/** Array of avatar URL */
avatarImageURLs: PropTypes.arrayOf(PropTypes.string),
/** Array of avatar URLs or icons */
avatarIcons: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.func])),

/** Whether this avatar is for a custom/default room */
isChatRoom: PropTypes.bool,
/** Whether show large Avatars */
shouldShowLargeAvatars: PropTypes.bool,
};

const defaultProps = {
avatarImageURLs: [],
isChatRoom: false,
avatarIcons: [],
shouldShowLargeAvatars: false,
};

const RoomHeaderAvatars = (props) => {
if (!props.avatarImageURLs.length) {
if (!props.avatarIcons.length) {
return null;
}

if (props.avatarImageURLs.length === 1 || props.isChatRoom) {
if (props.avatarIcons.length === 1) {
return (
<Avatar
source={props.avatarImageURLs[0]}
source={props.avatarIcons[0]}
imageStyles={[styles.avatarLarge]}
isChatRoom={props.isChatRoom}
fill={themeColors.iconSuccessFill}
size={CONST.AVATAR_SIZE.LARGE}
/>
);
}

// avatarImageURLsToDisplay
const avatarImageURLsToDisplay = props.avatarImageURLs.slice(0, CONST.REPORT.MAX_PREVIEW_AVATARS);
if (props.shouldShowLargeAvatars) {
return (
<View style={[styles.flexRow, styles.wAuto, styles.justifyContentCenter, styles.alignItemsCenter]}>
<View style={styles.leftSideLargeAvatar}>
<Avatar
source={props.avatarIcons[1]}
imageStyles={[styles.avatarLarge]}
size={CONST.AVATAR_SIZE.LARGE}
fill={themeColors.iconSuccessFill}
/>
</View>
<View style={[styles.rightSideLargeAvatar, StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)]}>
<Avatar
source={props.avatarIcons[0]}
imageStyles={[styles.avatarLarge]}
size={CONST.AVATAR_SIZE.LARGE}
/>
</View>
</View>
);
}

const avatarIconsToDisplay = props.avatarIcons.slice(0, CONST.REPORT.MAX_PREVIEW_AVATARS);
return (
<View pointerEvents="none">
<View style={[styles.flexRow, styles.wAuto, styles.ml3]}>
{_.map(avatarImageURLsToDisplay, (val, index) => (
{_.map(avatarIconsToDisplay, (val, index) => (
<View key={val} style={[styles.justifyContentCenter, styles.alignItemsCenter]}>
<Image source={{uri: val}} style={[styles.roomHeaderAvatar]} />

{index === CONST.REPORT.MAX_PREVIEW_AVATARS - 1 && props.avatarImageURLs.length - CONST.REPORT.MAX_PREVIEW_AVATARS !== 0 && (
{index === CONST.REPORT.MAX_PREVIEW_AVATARS - 1 && props.avatarIcons.length - CONST.REPORT.MAX_PREVIEW_AVATARS !== 0 && (
<>
<View
style={[
Expand All @@ -54,7 +77,7 @@ const RoomHeaderAvatars = (props) => {
]}
/>
<Text style={styles.avatarInnerTextChat}>
{`+${props.avatarImageURLs.length - CONST.REPORT.MAX_PREVIEW_AVATARS}`}
{`+${props.avatarIcons.length - CONST.REPORT.MAX_PREVIEW_AVATARS}`}
</Text>
</>
)}
Expand Down
Loading

0 comments on commit 7d6ed27

Please sign in to comment.