Skip to content
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

remove withOnyx from user tooltip #30432

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions src/components/MultipleAvatars.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,19 @@ import * as StyleUtils from '@styles/StyleUtils';
import themeColors from '@styles/themes/default';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import {PersonalDetails} from '@src/types/onyx';
import type {Icon} from '@src/types/onyx/OnyxCommon';
import Avatar from './Avatar';
import Text from './Text';
import Tooltip from './Tooltip';
import UserDetailsTooltip from './UserDetailsTooltip';

// TODO: once `src/components/participantPropTypes.js` is migrated to TS, this type should be moved there
type Participant = Pick<
PersonalDetails,
'accountID' | 'avatar' | 'displayName' | 'firstName' | 'lastName' | 'localCurrencyCode' | 'login' | 'payPalMeAddress' | 'phoneNumber' | 'pronouns' | 'timezone' | 'validated'
>;

type MultipleAvatarsProps = {
/** Array of avatar URLs or icons */
icons: Icon[];
Expand Down Expand Up @@ -52,6 +59,9 @@ type MultipleAvatarsProps = {

/** Prop to limit the amount of avatars displayed horizontally */
maxAvatarsInRow?: number;

/** List of participants */
participants: Participant[];
};

type AvatarStyles = {
Expand Down Expand Up @@ -92,6 +102,7 @@ function MultipleAvatars({
shouldShowTooltip = true,
shouldUseCardBackground = false,
maxAvatarsInRow = CONST.AVATAR_ROW_SIZE.DEFAULT,
participants = [],
}: MultipleAvatarsProps) {
let avatarContainerStyles = StyleUtils.getContainerStyles(size, isInReportAction);
const {singleAvatarStyle, secondAvatarStyles} = useMemo(() => avatarSizeToStylesMap[size as AvatarSizeToStyles] ?? avatarSizeToStylesMap.default, [size]);
Expand All @@ -109,6 +120,17 @@ function MultipleAvatars({
return CONST.AVATAR_SIZE.SMALLER;
}, [isFocusMode, size]);

const participantsList = useMemo(
() =>
participants.reduce<Record<number, Participant>>((all, participant) => {
const items = all;
items[participant.accountID] = participant;

return items;
}, {}),
[participants],
);

const avatarRows = useMemo(() => {
// If we're not displaying avatars in rows or the number of icons is less than or equal to the max avatars in a row, return a single row
if (!shouldDisplayAvatarsInRows || icons.length <= maxAvatarsInRow) {
Expand All @@ -133,7 +155,7 @@ function MultipleAvatars({
if (icons.length === 1 && !shouldStackHorizontally) {
return (
<UserDetailsTooltip
accountID={icons[0].id}
user={participantsList[Number(icons[0].id)]}
icon={icons[0]}
fallbackUserDetails={{
displayName: icons[0].name,
Expand Down Expand Up @@ -175,7 +197,7 @@ function MultipleAvatars({
{[...avatars].splice(0, maxAvatarsInRow).map((icon, index) => (
<UserDetailsTooltip
key={`stackedAvatars-${icon.id}`}
accountID={icon.id}
user={participantsList[Number(icon.id)]}
icon={icon}
fallbackUserDetails={{
displayName: icon.name,
Expand Down Expand Up @@ -246,7 +268,7 @@ function MultipleAvatars({
<View style={avatarContainerStyles}>
<View style={[singleAvatarStyle, icons[0].type === CONST.ICON_TYPE_WORKSPACE ? StyleUtils.getAvatarBorderRadius(size, icons[0].type) : {}]}>
<UserDetailsTooltip
accountID={icons[0].id}
user={participantsList[Number(icons[0].id)]}
icon={icons[0]}
fallbackUserDetails={{
displayName: icons[0].name,
Expand All @@ -268,7 +290,7 @@ function MultipleAvatars({
<View style={[secondAvatarStyles, secondAvatarStyle, icons[1].type === CONST.ICON_TYPE_WORKSPACE ? StyleUtils.getAvatarBorderRadius(size, icons[1].type) : {}]}>
{icons.length === 2 ? (
<UserDetailsTooltip
accountID={icons[1].id}
user={participantsList[Number(icons[1].id)]}
icon={icons[1]}
fallbackUserDetails={{
displayName: icons[1].name,
Expand Down
2 changes: 2 additions & 0 deletions src/components/OptionRow.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,9 +208,11 @@ function OptionRow(props) {
secondaryAvatar={props.option.icons[1]}
backgroundColor={hovered ? hoveredBackgroundColor : subscriptColor}
size={defaultSubscriptSize}
participants={props.option.participantsList}
/>
) : (
<MultipleAvatars
participants={props.option.participantsList}
icons={props.option.icons}
size={CONST.AVATAR_SIZE.DEFAULT}
secondAvatarStyle={[StyleUtils.getBackgroundAndBorderStyle(hovered ? hoveredBackgroundColor : subscriptColor)]}
Expand Down
24 changes: 21 additions & 3 deletions src/components/SubscriptAvatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,16 @@ import * as StyleUtils from '@styles/StyleUtils';
import useTheme from '@styles/themes/useTheme';
import useThemeStyles from '@styles/useThemeStyles';
import CONST from '@src/CONST';
import {PersonalDetails} from '@src/types/onyx';
import Avatar from './Avatar';
import UserDetailsTooltip from './UserDetailsTooltip';

// TODO: once `src/components/participantPropTypes.js` is migrated to TS, this type should be moved there
type Participant = Pick<
PersonalDetails,
'accountID' | 'avatar' | 'displayName' | 'firstName' | 'lastName' | 'localCurrencyCode' | 'login' | 'payPalMeAddress' | 'phoneNumber' | 'pronouns' | 'timezone' | 'validated'
>;

type SubAvatar = {
/** Avatar source to display */
source?: AvatarSource;
Expand Down Expand Up @@ -44,9 +51,20 @@ type SubscriptAvatarProps = {

/** Whether to show the tooltip */
showTooltip?: boolean;

/** List of the participants of the chat */
participants: Participant[];
};

function SubscriptAvatar({mainAvatar = {}, secondaryAvatar = {}, size = CONST.AVATAR_SIZE.DEFAULT, backgroundColor, noMargin = false, showTooltip = true}: SubscriptAvatarProps) {
function SubscriptAvatar({
mainAvatar = {},
secondaryAvatar = {},
size = CONST.AVATAR_SIZE.DEFAULT,
backgroundColor,
noMargin = false,
showTooltip = true,
participants = [],
}: SubscriptAvatarProps) {
const theme = useTheme();
const styles = useThemeStyles();
const isSmall = size === CONST.AVATAR_SIZE.SMALL;
Expand All @@ -57,7 +75,7 @@ function SubscriptAvatar({mainAvatar = {}, secondaryAvatar = {}, size = CONST.AV
<View style={[containerStyle, noMargin ? styles.mr0 : {}]}>
<UserDetailsTooltip
shouldRender={showTooltip}
accountID={mainAvatar.id ?? -1}
user={participants.find((participant) => participant.accountID === mainAvatar.id)}
icon={mainAvatar}
>
<View>
Expand All @@ -73,7 +91,7 @@ function SubscriptAvatar({mainAvatar = {}, secondaryAvatar = {}, size = CONST.AV
</UserDetailsTooltip>
<UserDetailsTooltip
shouldRender={showTooltip}
accountID={secondaryAvatar.id ?? -1}
user={participants.find((participant) => participant.accountID === secondaryAvatar.id)}
icon={secondaryAvatar}
>
<View
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,11 @@ function BaseUserDetailsTooltip(props) {
const styles = useThemeStyles();
const {translate} = useLocalize();
const personalDetails = usePersonalDetails();

const userDetails = lodashGet(personalDetails, props.accountID, props.fallbackUserDetails);
let userDisplayName = ReportUtils.getDisplayNameForParticipant(props.accountID);
const userDetails = props.user || props.fallbackUserDetails;
let userDisplayName = userDetails.displayName ? userDetails.displayName.trim() : '';
let userLogin = (userDetails.login || '').trim() && !_.isEqual(userDetails.login, userDetails.displayName) ? Str.removeSMSDomain(userDetails.login) : '';
let userAvatar = userDetails.avatar;
let userAccountID = props.accountID;
let userAccountID = props.user ? props.user.accountID : props.accountID;

// We replace the actor's email, name, and avatar with the Copilot manually for now. This will be improved upon when
// the Copilot feature is implemented.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import PropTypes from 'prop-types';
import avatarPropTypes from '@components/avatarPropTypes';
import personalDetailsPropType from '@pages/personalDetailsPropType';
import participantPropTypes from '@components/participantPropTypes';

const propTypes = {
/** User's Account ID */
accountID: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
/** Fallback User Details object used if no accountID */
fallbackUserDetails: PropTypes.shape({
/** Avatar URL */
Expand All @@ -20,21 +18,22 @@ const propTypes = {
icon: avatarPropTypes,
/** Component that displays the tooltip */
children: PropTypes.node.isRequired,
/** List of personalDetails (keyed by accountID) */
personalDetailsList: PropTypes.objectOf(personalDetailsPropType),

/** The accountID of the copilot who took this action on behalf of the user */
delegateAccountID: PropTypes.number,

/** Any additional amount to manually adjust the horizontal position of the tooltip.
A positive value shifts the tooltip to the right, and a negative value shifts it to the left. */
shiftHorizontal: PropTypes.oneOfType([PropTypes.number, PropTypes.func]),

/** User object containing the details needed to display in a tooltip */
user: participantPropTypes,
};

const defaultProps = {
accountID: '',
fallbackUserDetails: {displayName: '', login: '', avatar: '', type: ''},
personalDetailsList: {},
user: {},
delegateAccountID: 0,
icon: undefined,
shiftHorizontal: 0,
Expand Down
Loading