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

[Group Chats] Add remaining features #39757

Merged
merged 98 commits into from
Apr 12, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
9dba74f
members, avatar, rename report, settings, default view for other reports
waterim Apr 4, 2024
b35fccb
Merge pull request #39639 from waterim/feat-34927-group-chat-2
marcaaron Apr 5, 2024
bf96f01
Use draft for Group Chat name instead of passing it via route param. …
marcaaron Apr 5, 2024
c14f10b
Hook up editing the Group Chat name via Report settings
marcaaron Apr 5, 2024
66a220a
Call OpenReport with a file
marcaaron Apr 5, 2024
2e3e6bb
Get avatars to load everywhere we need them
marcaaron Apr 5, 2024
b041c73
Use getVisibleParticipantAccountIDs to populate the report details name
marcaaron Apr 5, 2024
9ed73cd
Allow updating avatars
marcaaron Apr 5, 2024
35bbf1b
Add ChatActionsBar component
marcaaron Apr 5, 2024
9aa8f74
Refactor navigate to most recent chat logic so we can reuse it in the…
marcaaron Apr 5, 2024
b7caed0
Fix header on Members page
marcaaron Apr 5, 2024
d8c6956
Use InviteToGroupChat instead of InviteMembersToGroupChat
marcaaron Apr 5, 2024
459bef4
Use correct variable name
marcaaron Apr 6, 2024
5a0e7eb
Use RadioListItem
marcaaron Apr 6, 2024
e6a047d
Use the UserListItem styles to correctly style the invite members page
marcaaron Apr 6, 2024
699cfc7
Fix up badge styles
marcaaron Apr 6, 2024
8791b81
Override checklist behavior for UserListItem
marcaaron Apr 6, 2024
fc84939
Remove duplicate methods. Use new ones for now.
marcaaron Apr 6, 2024
639693b
Add optimstic updated participants when removing members
marcaaron Apr 6, 2024
790d3ca
Add ability to update member roles
marcaaron Apr 6, 2024
b734506
Hook up final API
marcaaron Apr 6, 2024
8118ed1
style
marcaaron Apr 6, 2024
7ac3859
Remove unneeded props in RoomHeaderAvatars
marcaaron Apr 8, 2024
61afba6
Update comment & fix import
marcaaron Apr 8, 2024
cd7ccc0
Use badgeText prop instead of isAdmin to make more generic
marcaaron Apr 8, 2024
c7d89f2
Revert shouldSHowLeftCheckbox logic.
marcaaron Apr 8, 2024
98058a5
Move badge logic to InviteMemberListItem
marcaaron Apr 8, 2024
08fedfc
Rename ReportParticipantDetailsRoleSelectionPage
marcaaron Apr 8, 2024
46c75fd
Prettier
marcaaron Apr 8, 2024
d37e029
Add types for UpdateGroupChatName params
marcaaron Apr 8, 2024
259355f
Update API command types and constants
marcaaron Apr 8, 2024
0b56abe
Remove unused translations and add missing ones
marcaaron Apr 8, 2024
a6d8ca4
Fix inviteToGroupChat participants logic
marcaaron Apr 8, 2024
09c2fd9
Use spread for report.participants
marcaaron Apr 8, 2024
896f0c7
More requested changes
marcaaron Apr 8, 2024
38c5934
Fix some inline styles
marcaaron Apr 8, 2024
640f90b
Fix inline styles and types
marcaaron Apr 8, 2024
6c59b94
Fix styles for non-admin Group Chat member
marcaaron Apr 8, 2024
0289227
Fix conflicts;
marcaaron Apr 8, 2024
d7837d8
Fix remove avatar
marcaaron Apr 8, 2024
14aaaf1
Use correct camera icon. Make sure we are defaulting to the correct n…
marcaaron Apr 9, 2024
dea4cbf
Fix some Group Chat name logic to support newly created Group Chats a…
marcaaron Apr 9, 2024
46ea41a
Fix options not populating correctly when inviting members
marcaaron Apr 9, 2024
5dae3d1
Make sure recent reports are also available to invite
marcaaron Apr 9, 2024
2bdf2c8
Clear selected options when inviting users
marcaaron Apr 9, 2024
17ad9c5
Navigate before leaving chat to prevent crash
marcaaron Apr 9, 2024
99cfe87
Show Members row even when members are hidden for Group Chat
marcaaron Apr 9, 2024
aae648b
Ensure that participants are shown on Members page (even when hidden)
marcaaron Apr 9, 2024
fab964f
Add length validation for Group Chat name
marcaaron Apr 9, 2024
6664cfb
Remove unnecessary text style
marcaaron Apr 9, 2024
51ab0c2
Fixing Ts errors
marcaaron Apr 9, 2024
e2663cb
Fix ts
marcaaron Apr 9, 2024
c7d2d36
Calculate participants in useMemo()
marcaaron Apr 9, 2024
e202c7b
Add Log back in for Hidden member case
marcaaron Apr 9, 2024
67f2986
Fix avatarUrl
marcaaron Apr 9, 2024
bd0f05e
Fix conflicts
marcaaron Apr 9, 2024
2dda3f1
Fix isValidReportName condition
marcaaron Apr 9, 2024
9488c3b
Fix isValidReportName()
marcaaron Apr 9, 2024
0dd6b90
Fixing typescript
marcaaron Apr 9, 2024
3241bbd
Fix more typescript errors
marcaaron Apr 9, 2024
21fd1d6
Fix API params
marcaaron Apr 9, 2024
ef4286d
Fix types
marcaaron Apr 9, 2024
51052e0
Prettier
marcaaron Apr 9, 2024
9b10486
Fix style and ts
marcaaron Apr 9, 2024
f049283
Remove validation stuff
marcaaron Apr 9, 2024
dec226e
Clean up ReportParticipantsPage.tsx
marcaaron Apr 9, 2024
1dfdc64
Return NotFoundPage when member does not exist
marcaaron Apr 9, 2024
6a74c9d
If we cant add participants for some reason when inviting remove them…
marcaaron Apr 10, 2024
faed7df
Add reportID to params
marcaaron Apr 10, 2024
72b4884
Remove duplication in inviteToGroup()
marcaaron Apr 10, 2024
9568bc3
Lint
marcaaron Apr 10, 2024
9c2ab05
Fix pendingChatMebers
marcaaron Apr 10, 2024
def5c54
Add pending delete for RemoveFromRoom
marcaaron Apr 10, 2024
feaf901
Fix typescript
marcaaron Apr 10, 2024
d27b691
Fix padding. Fix avatar bugs.
marcaaron Apr 10, 2024
ba3e768
Fixing table styles
marcaaron Apr 10, 2024
1efda68
Fix badge
marcaaron Apr 10, 2024
4ee60b5
Add dependency
marcaaron Apr 10, 2024
76e0d92
Fix conflicts
marcaaron Apr 10, 2024
bc0c380
Ensure we are passing the success and failure data for the Group Chat…
marcaaron Apr 11, 2024
b4248e4
Make some requested changes
marcaaron Apr 11, 2024
2acb986
Fix leave chat bug
marcaaron Apr 11, 2024
69e0de5
Use new function name to make it clear that we should use this only w…
marcaaron Apr 11, 2024
e57ad31
Revert wrong method name
marcaaron Apr 11, 2024
01b032a
Fix Leave/Pin padding
marcaaron Apr 11, 2024
6f3c030
add explicit API param types
marcaaron Apr 11, 2024
84e631c
Merge branch 'main' into feature-groupChats2
marcaaron Apr 11, 2024
351f318
Fix import + run prettier
marcaaron Apr 11, 2024
d054329
Use as const
marcaaron Apr 12, 2024
22f6d15
Remove Log
marcaaron Apr 12, 2024
41b3924
Remove null from NewGroupChatDraft participants
marcaaron Apr 12, 2024
85454e6
Add Group Chat to reports that can be removed. Try to give the huge c…
marcaaron Apr 12, 2024
06eb201
Fix invite button padding
marcaaron Apr 12, 2024
c479153
Update with better copy
marcaaron Apr 12, 2024
e391d7d
linter
marcaaron Apr 12, 2024
ae4ed17
Fix spanish translations
marcaaron Apr 12, 2024
2440183
Fix translations again
marcaaron Apr 12, 2024
f5970a9
Fix conflicts
marcaaron Apr 12, 2024
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
3 changes: 3 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,8 @@ const ONYXKEYS = {
WORKSPACE_TAX_NAME_FORM_DRAFT: 'workspaceTaxNameFormDraft',
WORKSPACE_TAX_VALUE_FORM: 'workspaceTaxValueForm',
WORKSPACE_TAX_VALUE_FORM_DRAFT: 'workspaceTaxValueFormDraft',
NEW_CHAT_NAME_FORM: 'newChatNameForm',
NEW_CHAT_NAME_FORM_DRAFT: 'newChatNameFormDraft',
},
} as const;

Expand Down Expand Up @@ -506,6 +508,7 @@ type OnyxFormValuesMapping = {
[ONYXKEYS.FORMS.POLICY_DISTANCE_RATE_EDIT_FORM]: FormTypes.PolicyDistanceRateEditForm;
[ONYXKEYS.FORMS.WORKSPACE_TAX_NAME_FORM]: FormTypes.WorkspaceTaxNameForm;
[ONYXKEYS.FORMS.WORKSPACE_TAX_VALUE_FORM]: FormTypes.WorkspaceTaxValueForm;
[ONYXKEYS.FORMS.NEW_CHAT_NAME_FORM]: FormTypes.NewChatNameForm;
};

type OnyxFormDraftValuesMapping = {
Expand Down
17 changes: 17 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ const ROUTES = {
NEW: 'new',
NEW_CHAT: 'new/chat',
NEW_CHAT_CONFIRM: 'new/chat/confirm',
NEW_CHAT_EDIT_NAME: 'new/chat/confirm/name/edit',
NEW_ROOM: 'new/room',

REPORT: 'r',
Expand Down Expand Up @@ -222,6 +223,18 @@ const ROUTES = {
route: 'r/:reportID/participants',
getRoute: (reportID: string) => `r/${reportID}/participants` as const,
},
REPORT_PARTICIPANTS_INVITE: {
route: 'r/:reportID/participants/invite',
getRoute: (reportID: string) => `r/${reportID}/participants/invite` as const,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: why does this route not use getUrlWithBackToParam, while DETAILS and ROLE_SELECTION do?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great question. I don't have a great understanding of backTo or how that works. I removed it from the routes you mentioned. If we find out we need them we can add them later.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's mostly for the sake of the browser back button working as expected, but last I checked it wasn't really working after the "ideal nav" changes a couple months ago.

Whatever the case, more polish than blocker

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I'll move this into the "to check later" pile. I am eager to get this merged soon-ish.

},
REPORT_PARTICIPANTS_DETAILS: {
route: 'r/:reportID/participants/:accountID',
getRoute: (reportID: string, accountID: number, backTo?: string) => getUrlWithBackToParam(`r/${reportID}/participants/${accountID}`, backTo),
},
REPORT_PARTICIPANTS_ROLE_SELECTION: {
route: 'r/:reportID/participants/:accountID/role',
getRoute: (reportID: string, accountID: number, backTo?: string) => getUrlWithBackToParam(`r/${reportID}/participants/${accountID}/role`, backTo),
},
REPORT_WITH_ID_DETAILS: {
route: 'r/:reportID/details',
getRoute: (reportID: string, backTo?: string) => getUrlWithBackToParam(`r/${reportID}/details`, backTo),
Expand All @@ -234,6 +247,10 @@ const ROUTES = {
route: 'r/:reportID/settings/room-name',
getRoute: (reportID: string) => `r/${reportID}/settings/room-name` as const,
},
REPORT_SETTINGS_GROUP_NAME: {
route: 'r/:reportID/settings/group-name',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure if there is a better url for this. Maybe r/:reportID/settings/name is better than group-name 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'd think it might be simpler to combine REPORT_SETTINGS_ROOM_NAME and REPORT_SETTINGS_GROUP_NAME into a single REPORT_SETTINGS_NAME route at r/:reportID/settings/name that works with any report type.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. That feels worth exploring as a follow up. Updating the Group name is a lot looser than updating the Room name. Gonna leave this for now I think.

getRoute: (reportID: string) => `r/${reportID}/settings/group-name` as const,
},
REPORT_SETTINGS_NOTIFICATION_PREFERENCES: {
route: 'r/:reportID/settings/notification-preferences',
getRoute: (reportID: string) => `r/${reportID}/settings/notification-preferences` as const,
Expand Down
9 changes: 8 additions & 1 deletion src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ const SCREENS = {
REPORT_SETTINGS: {
ROOT: 'Report_Settings_Root',
ROOM_NAME: 'Report_Settings_Room_Name',
GROUP_NAME: 'Report_Settings_Group_Name',
NOTIFICATION_PREFERENCES: 'Report_Settings_Notification_Preferences',
WRITE_CAPABILITY: 'Report_Settings_Write_Capability',
VISIBILITY: 'Report_Settings_Visibility',
Expand Down Expand Up @@ -266,6 +267,7 @@ const SCREENS = {
ROOT: 'NewChat_Root',
NEW_CHAT: 'chat',
NEW_CHAT_CONFIRM: 'NewChat_Confirm',
NEW_CHAT_EDIT_NAME: 'NewChat_Edit_Name',
marcaaron marked this conversation as resolved.
Show resolved Hide resolved
NEW_ROOM: 'room',
},

Expand Down Expand Up @@ -302,7 +304,12 @@ const SCREENS = {
PROFILE_ROOT: 'Profile_Root',
PROCESS_MONEY_REQUEST_HOLD_ROOT: 'ProcessMoneyRequestHold_Root',
REPORT_DESCRIPTION_ROOT: 'Report_Description_Root',
REPORT_PARTICIPANTS_ROOT: 'ReportParticipants_Root',
REPORT_PARTICIPANTS: {
ROOT: 'ReportParticipants_Root',
INVITE: 'ReportParticipants_Invite',
DETAILS: 'ReportParticipants_Details',
ROLE: 'ReportParticipants_Role',
},
ROOM_MEMBERS_ROOT: 'RoomMembers_Root',
ROOM_INVITE_ROOT: 'RoomInvite_Root',
SEARCH_ROOT: 'Search_Root',
Expand Down
6 changes: 5 additions & 1 deletion src/components/AvatarWithImagePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,9 @@ type AvatarWithImagePickerProps = {

/** Allows to open an image without Attachment Picker. */
enablePreview?: boolean;

/** Hard disables the "View photo" option */
disableViewPhoto?: boolean;
marcaaron marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. boolean so should start with should
  2. does this count as a negated variable?
Suggested change
disableViewPhoto?: boolean;
shouldEnableViewPhoto?: boolean;

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. It's also enabled by default. We are going to remove this as a very fast follower so I updated it to shouldDisableViewPhoto for now to avoid overthinking this one.

};

function AvatarWithImagePicker({
Expand Down Expand Up @@ -144,6 +147,7 @@ function AvatarWithImagePicker({
disabled = false,
onViewPhotoPress,
enablePreview = false,
disableViewPhoto = false,
}: AvatarWithImagePickerProps) {
const theme = useTheme();
const styles = useThemeStyles();
Expand Down Expand Up @@ -355,7 +359,7 @@ function AvatarWithImagePicker({
const menuItems = createMenuItems(openPicker);

// If the current avatar isn't a default avatar, allow the "View Photo" option
marcaaron marked this conversation as resolved.
Show resolved Hide resolved
if (!isUsingDefaultAvatar) {
if (!disableViewPhoto && !isUsingDefaultAvatar) {
menuItems.push({
icon: Expensicons.Eye,
text: translate('avatarWithImagePicker.viewPhoto'),
Expand Down
31 changes: 31 additions & 0 deletions src/components/ChatActionsBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react';
import {View} from 'react-native';
import * as Report from '../libs/actions/Report';

Check warning on line 3 in src/components/ChatActionsBar.tsx

View workflow job for this annotation

GitHub Actions / Run ESLint

Unexpected parent import '../libs/actions/Report'. Use '@userActions/Report' instead
import Button from './Button';
import * as Expensicons from './Icon/Expensicons';

function ChatActionsBar({report}) {

Check failure on line 7 in src/components/ChatActionsBar.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Binding element 'report' implicitly has an 'any' type.
const isPinned = !!report.isPinned;
return (
<View style={{flexDirection: 'row', paddingHorizontal: 14, marginBottom: 20}}>
<View style={{flex: 1, paddingHorizontal: 6}}>
marcaaron marked this conversation as resolved.
Show resolved Hide resolved
<Button
onPress={() => Report.leaveGroupChat(report.reportID)}
icon={Expensicons.Exit}
style={{flex: 1}}
text="Leave"
marcaaron marked this conversation as resolved.
Show resolved Hide resolved
/>
</View>
<View style={{flex: 1, paddingHorizontal: 6}}>
<Button
onPress={() => Report.togglePinnedState(report.reportID, isPinned)}
icon={Expensicons.Pin}
style={{flex: 1}}
text={isPinned ? 'Unpin' : 'Pin'}
/>
</View>
</View>
);
}

marcaaron marked this conversation as resolved.
Show resolved Hide resolved
export default ChatActionsBar;
38 changes: 25 additions & 13 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type {ReactNode} from 'react';
import React from 'react';
import React, {useMemo} from 'react';
import type {StyleProp, TextStyle, ViewStyle} from 'react-native';
import {View} from 'react-native';
import useThemeStyles from '@hooks/useThemeStyles';
Expand All @@ -21,13 +21,35 @@ type HeaderProps = {

/** Additional header container styles */
containerStyles?: StyleProp<ViewStyle>;

/** Whether to show the subtitle on the top or bottom */
subtitleOnTop?: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
subtitleOnTop?: boolean;
shouldShowSubtitleOnTop?: boolean;

};

function Header({title = '', subtitle = '', textStyles = [], containerStyles = [], shouldShowEnvironmentBadge = false}: HeaderProps) {
function Header({title = '', subtitle = '', textStyles = [], containerStyles = [], shouldShowEnvironmentBadge = false, subtitleOnTop = true}: HeaderProps) {
marcaaron marked this conversation as resolved.
Show resolved Hide resolved
const styles = useThemeStyles();
const renderedSubtitle = useMemo(
() => (
<>
{/* If there's no subtitle then display a fragment to avoid an empty space which moves the main title */}
{typeof subtitle === 'string'
? Boolean(subtitle) && (
<Text
style={[styles.mutedTextLabel, styles.pre]}
numberOfLines={1}
>
{subtitle}
</Text>
)
: subtitle}
</>
),
[subtitle, styles],
);
return (
<View style={[styles.flex1, styles.flexRow, containerStyles]}>
<View style={styles.mw100}>
{subtitleOnTop && renderedSubtitle}
{typeof title === 'string'
? Boolean(title) && (
<Text
Expand All @@ -38,17 +60,7 @@ function Header({title = '', subtitle = '', textStyles = [], containerStyles = [
</Text>
)
: title}
{/* If there's no subtitle then display a fragment to avoid an empty space which moves the main title */}
{typeof subtitle === 'string'
? Boolean(subtitle) && (
<Text
style={[styles.mutedTextLabel, styles.pre]}
numberOfLines={1}
>
{subtitle}
</Text>
)
: subtitle}
{!subtitleOnTop && renderedSubtitle}
</View>
{shouldShowEnvironmentBadge && <EnvironmentBadge />}
</View>
Expand Down
3 changes: 3 additions & 0 deletions src/components/HeaderWithBackButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ function HeaderWithBackButton({
shouldNavigateToTopMostReport = false,
progressBarPercentage,
style,
subtitleOnTop = false,
}: HeaderWithBackButtonProps) {
const theme = useTheme();
const styles = useThemeStyles();
Expand Down Expand Up @@ -103,6 +104,7 @@ function HeaderWithBackButton({
title={title}
subtitle={stepCounter ? translate('stepCounter', stepCounter) : subtitle}
textStyles={[titleColor ? StyleUtils.getTextColorStyle(titleColor) : {}, isCentralPaneSettings && styles.textHeadlineH2]}
subtitleOnTop={subtitleOnTop}
/>
);
}, [
Expand All @@ -123,6 +125,7 @@ function HeaderWithBackButton({
title,
titleColor,
translate,
subtitleOnTop,
]);

return (
Expand Down
3 changes: 3 additions & 0 deletions src/components/HeaderWithBackButton/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ type HeaderWithBackButtonProps = Partial<ChildrenProps> & {

/** Additional styles to add to the component */
style?: StyleProp<ViewStyle>;

/** Flips the subtitle with the title */
subtitleOnTop?: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
subtitleOnTop?: boolean;
shouldShowSubtitleOnTop?: boolean;

};

export type {ThreeDotsMenuItem};
Expand Down
6 changes: 3 additions & 3 deletions src/components/LHNOptionsList/OptionRowLHN.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,7 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti

const isGroupChat = ReportUtils.isGroupChat(optionItem) || ReportUtils.isDeprecatedGroupDM(optionItem);

const fullTitle = isGroupChat ? ReportUtils.getGroupChatName(report?.participantAccountIDs ?? []) : optionItem.text;

const fullTitle = isGroupChat ? ReportUtils.getGroupChatName(report?.participantAccountIDs ?? [], false, optionItem.reportID ?? '') : optionItem.text;
const subscriptAvatarBorderColor = isFocused ? focusedBackgroundColor : theme.sidebar;
return (
<OfflineWithFeedback
Expand Down Expand Up @@ -199,7 +198,8 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti
!!optionItem.isPolicyExpenseChat ||
!!optionItem.isTaskReport ||
!!optionItem.isThread ||
!!optionItem.isMoneyRequestReport
!!optionItem.isMoneyRequestReport ||
ReportUtils.isGroupChat(report)
}
/>
{isStatusVisible && (
Expand Down
2 changes: 2 additions & 0 deletions src/components/SelectionList/BaseSelectionList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ function BaseSelectionList<TItem extends ListItem>(
textInputRef,
headerMessageStyle,
shouldHideListOnInitialRender = true,
shouldShowLeftCheckbox = true,
}: BaseSelectionListProps<TItem>,
ref: ForwardedRef<SelectionListHandle>,
) {
Expand Down Expand Up @@ -337,6 +338,7 @@ function BaseSelectionList<TItem extends ListItem>(
rightHandSideComponent={rightHandSideComponent}
keyForList={item.keyForList ?? ''}
isMultilineSupported={isRowMultilineSupported}
shouldShowLeftCheckbox={shouldShowLeftCheckbox}
/>
);
};
Expand Down
38 changes: 25 additions & 13 deletions src/components/SelectionList/UserListItem.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Str from 'expensify-common/lib/str';
import React, {useCallback} from 'react';
import {View} from 'react-native';
import Badge from '@components/Badge';
import Icon from '@components/Icon';
import * as Expensicons from '@components/Icon/Expensicons';
import MultipleAvatars from '@components/MultipleAvatars';
Expand All @@ -12,6 +13,7 @@
import useStyleUtils from '@hooks/useStyleUtils';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import BaseListItem from './BaseListItem';
import type {UserListItemProps} from './types';
Expand All @@ -27,6 +29,7 @@
onDismissError,
shouldPreventDefaultFocusOnSelectRow,
rightHandSideComponent,
shouldShowLeftCheckbox = true,
}: UserListItemProps) {
const styles = useThemeStyles();
const theme = useTheme();
Expand All @@ -52,7 +55,7 @@
isFocused={isFocused}
isDisabled={isDisabled}
showTooltip={showTooltip}
canSelectMultiple={canSelectMultiple}
canSelectMultiple={shouldShowLeftCheckbox && canSelectMultiple}
onSelectRow={onSelectRow}
onDismissError={onDismissError}
shouldPreventDefaultFocusOnSelectRow={shouldPreventDefaultFocusOnSelectRow}
Expand All @@ -70,7 +73,7 @@
>
{(hovered?: boolean) => (
<>
{canSelectMultiple && (
{shouldShowLeftCheckbox && canSelectMultiple && (
<PressableWithFeedback
accessibilityLabel={item.text ?? ''}
role={CONST.ROLE.BUTTON}
Expand Down Expand Up @@ -111,17 +114,26 @@
/>
))}
<View style={[styles.flex1, styles.flexColumn, styles.justifyContentCenter, styles.alignItemsStretch, styles.optionRow]}>
<TextWithTooltip
shouldShowTooltip={showTooltip}
text={Str.removeSMSDomain(item.text ?? '')}
style={[
styles.optionDisplayName,
isFocused ? styles.sidebarLinkActiveText : styles.sidebarLinkText,
item.isBold !== false && styles.sidebarLinkTextBold,
styles.pre,
item.alternateText ? styles.mb1 : null,
]}
/>
<View style={{flexDirection: 'row', alignItems: 'center'}}>
<TextWithTooltip
shouldShowTooltip={showTooltip}
text={Str.removeSMSDomain(item.text ?? '')}
style={[
styles.optionDisplayName,
isFocused ? styles.sidebarLinkActiveText : styles.sidebarLinkText,
item.isBold !== false && styles.sidebarLinkTextBold,
styles.pre,
item.alternateText ? styles.mb1 : null,
]}
/>
{item.isAdmin && (
<Badge
text={translate('common.admin')}
textStyles={[styles.badgeText, styles.textStrong, variables.fontSizeNormal]}

Check failure on line 132 in src/components/SelectionList/UserListItem.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Type '{ whiteSpace?: Property.WhiteSpace | undefined; lineHeight?: Property.LineHeight<number | (string & {})> | undefined; color: string; fontSize: number; }' is not assignable to type 'TextStyle | Falsy | RegisteredStyle<TextStyle> | RecursiveArray<TextStyle | Falsy | RegisteredStyle<TextStyle>> | readonly (TextStyle | ... 1 more ... | RegisteredStyle<...>)[]'.

Check failure on line 132 in src/components/SelectionList/UserListItem.tsx

View workflow job for this annotation

GitHub Actions / typecheck

Type 'number' is not assignable to type 'TextStyle | Falsy | RegisteredStyle<TextStyle> | RecursiveArray<TextStyle | Falsy | RegisteredStyle<TextStyle>> | readonly (TextStyle | ... 1 more ... | RegisteredStyle<...>)[]'.
badgeStyles={[styles.justifyContentCenter, styles.badgeSmall, item.alternateText ? styles.mb1 : null]}
marcaaron marked this conversation as resolved.
Show resolved Hide resolved
/>
)}
</View>
{!!item.alternateText && (
<TextWithTooltip
shouldShowTooltip={showTooltip}
Expand Down
9 changes: 9 additions & 0 deletions src/components/SelectionList/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ type ListItem = {

/** The search value from the selection list */
searchText?: string | null;

/** Whether to show an "Admin" badge next to the Display Name */
isAdmin?: boolean;
marcaaron marked this conversation as resolved.
Show resolved Hide resolved
};

type ListItemProps = CommonListItemProps<ListItem> & {
Expand Down Expand Up @@ -148,6 +151,9 @@ type UserListItemProps = ListItemProps & {

/** The React element that will be shown as a footer */
FooterComponent?: ReactElement;

/** Whether to show the left checkbox when selecting multiple items */
shouldShowLeftCheckbox?: boolean;
marcaaron marked this conversation as resolved.
Show resolved Hide resolved
};

type InviteMemberListItemProps = UserListItemProps;
Expand Down Expand Up @@ -303,6 +309,9 @@ type BaseSelectionListProps<TItem extends ListItem> = Partial<ChildrenProps> & {
* When false, the list will render immediately and scroll to the bottom which works great for small lists.
*/
shouldHideListOnInitialRender?: boolean;

/** Override checklist behavior */
shouldShowLeftCheckbox?: boolean;
};

type SelectionListHandle = {
Expand Down
Loading
Loading