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

Add support for viewing full screen Group Chat custom avatars #41586

Merged
merged 38 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
7ce2242
enable view photo for group chat
nexarvo May 3, 2024
b12d3ef
create variable for filename
nexarvo May 6, 2024
349ea43
Merge branch 'main' into feat/39850
nexarvo May 12, 2024
5b6a7c6
add support for new chat view photo
nexarvo May 17, 2024
66d8edc
revert removing extension
nexarvo May 20, 2024
7d122da
use file name for new group chat draft
nexarvo May 20, 2024
91f73c8
add newGroupChat query param for report avatar
nexarvo May 23, 2024
20294f6
clean code
nexarvo May 23, 2024
c9993e8
Merge branch 'main' into feat/39850
nexarvo May 24, 2024
e4ae8b4
remove shouldDisableViewPhoto param
nexarvo May 24, 2024
b26a166
add: conditional for route depending on isNewGroupChat
nexarvo May 24, 2024
1e29cab
add: parser to convert isNewGroupChat to boolean
nexarvo May 24, 2024
0b0da6c
update: made isNewGroupChat query param optional
nexarvo May 24, 2024
10eade0
refactor: clean code
nexarvo May 24, 2024
232e787
fix: lint issues
nexarvo May 24, 2024
8ff95be
fix: lint issues
nexarvo May 24, 2024
284d1f0
fix: minor logic issues
nexarvo May 27, 2024
3bf6bcf
fix: shouldShowNotFoundPage condition
nexarvo May 29, 2024
2992240
Merge branch 'main' into feat/39850
nexarvo May 29, 2024
a4315b7
Merge branch 'main' into feat/39850
nexarvo Jun 4, 2024
f6f582c
fix: handle edge cases for group chat name
nexarvo Jun 4, 2024
cf3f942
fix: report title edge cases
nexarvo Jun 6, 2024
b91c010
fix: changes WIP
nexarvo Jun 6, 2024
9c5b15e
Merge branch 'main' into feat/39850
nexarvo Jun 10, 2024
c0db9ef
fix: remove policy from not found
nexarvo Jun 10, 2024
6d6953f
fix: lint issues
nexarvo Jun 10, 2024
9d4a66f
add: originalFileName to report onyx
nexarvo Jun 12, 2024
38d7f5b
fix: null checks for title
nexarvo Jun 12, 2024
530df19
fix: lint issues
nexarvo Jun 12, 2024
bc18cf6
add: handle offline behaviour for view photo
nexarvo Jul 4, 2024
55b8487
Merge branch 'main' into feat/39850
nexarvo Jul 4, 2024
db65135
add: isNewGroupChat to types after merge main
nexarvo Jul 4, 2024
86fb5e7
fix: view photo when chat created offline(optimistic)
nexarvo Jul 7, 2024
12d1da7
fix: lint issues
nexarvo Jul 7, 2024
3695b6b
Merge branch 'main' into feat/39850
nexarvo Jul 17, 2024
16ac2ff
Merge branch 'main' into feat/39850
nexarvo Jul 17, 2024
f2e6e7b
making a single getAllReports call and merging main
nexarvo Jul 17, 2024
1c3e7db
verify parameters of buildOptimisticChatReport
nexarvo Jul 18, 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
7 changes: 6 additions & 1 deletion src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,12 @@ const ROUTES = {
},
REPORT_AVATAR: {
route: 'r/:reportID/avatar',
getRoute: (reportID: string) => `r/${reportID}/avatar` as const,
getRoute: (reportID: string, isNewGroupChat?: boolean) => {
if (isNewGroupChat) {
return `r/${reportID}/avatar?isNewGroupChat=${isNewGroupChat}` as const;
}
return `r/${reportID}/avatar` as const;
},
},
EDIT_CURRENCY_REQUEST: {
route: 'r/:threadReportID/edit/currency',
Expand Down
6 changes: 1 addition & 5 deletions src/components/AvatarWithImagePicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,6 @@ type AvatarWithImagePickerProps = {
/** Allows to open an image without Attachment Picker. */
enablePreview?: boolean;

/** Hard disables the "View photo" option */
shouldDisableViewPhoto?: boolean;

/** Optionally override the default "Edit" icon */
editIcon?: IconAsset;

Expand Down Expand Up @@ -157,7 +154,6 @@ function AvatarWithImagePicker({
disabled = false,
onViewPhotoPress,
enablePreview = false,
shouldDisableViewPhoto = false,
editIcon = Expensicons.Pencil,
shouldUseStyleUtilityForAnchorPosition = false,
}: AvatarWithImagePickerProps) {
Expand Down Expand Up @@ -370,7 +366,7 @@ function AvatarWithImagePicker({
const menuItems = createMenuItems(openPicker);

// If the current avatar isn't a default avatar and we are not overriding this behavior allow the "View Photo" option
if (!shouldDisableViewPhoto && !isUsingDefaultAvatar) {
if (!isUsingDefaultAvatar) {
menuItems.push({
icon: Expensicons.Eye,
text: translate('avatarWithImagePicker.viewPhoto'),
Expand Down
7 changes: 6 additions & 1 deletion src/libs/Navigation/linkingConfig/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,12 @@ const config: LinkingOptions<RootStackParamList>['config'] = {
[SCREENS.ATTACHMENTS]: ROUTES.ATTACHMENTS.route,
[SCREENS.PROFILE_AVATAR]: ROUTES.PROFILE_AVATAR.route,
[SCREENS.WORKSPACE_AVATAR]: ROUTES.WORKSPACE_AVATAR.route,
[SCREENS.REPORT_AVATAR]: ROUTES.REPORT_AVATAR.route,
[SCREENS.REPORT_AVATAR]: {
path: ROUTES.REPORT_AVATAR.route,
parse: {
isNewGroupChat: (isNewGroupChat: string) => isNewGroupChat === 'true',
},
},
[SCREENS.TRANSACTION_RECEIPT]: ROUTES.TRANSACTION_RECEIPT.route,
[SCREENS.WORKSPACE_JOIN_USER]: ROUTES.WORKSPACE_JOIN_USER.route,
[SCREENS.REPORT]: ROUTES.REPORT_WITH_ID.route,
Expand Down
1 change: 1 addition & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1019,6 +1019,7 @@ type AuthScreensParamList = CentralPaneScreensParamList &
};
[SCREENS.REPORT_AVATAR]: {
reportID: string;
isNewGroupChat: boolean;
};
[SCREENS.NOT_FOUND]: undefined;
[NAVIGATORS.LEFT_MODAL_NAVIGATOR]: NavigatorScreenParams<LeftModalNavigatorParamList>;
Expand Down
6 changes: 6 additions & 0 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,7 @@ type OptimisticChatReport = Pick<
| 'description'
| 'writeCapability'
| 'avatarUrl'
| 'avatarFileName'
| 'invoiceReceiver'
| 'isHidden'
> & {
Expand Down Expand Up @@ -4637,6 +4638,7 @@ function buildOptimisticChatReport(
parentReportID = '',
description = '',
avatarUrl = '',
avatarFileName = '',
Copy link
Contributor

Choose a reason for hiding this comment

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

After adding this new param we need to check all calls to buildOptimisticChatReport the 15th param should be avatarFileName. This is not the case in buildOptimisticWorkspaceChats. (Plaese double check all calls)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@s77rt just checked this. This is fine at all the places

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also conflicts are also resolved

Copy link
Contributor

Choose a reason for hiding this comment

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

This is not fixed yet

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What is not fixed? I have verified in all places wherebuildOptimisticChatReport is used.

Copy link
Contributor

Choose a reason for hiding this comment

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

In buildOptimisticWorkspaceChats we call buildOptimisticWorkspaceChats and the 15th param is expenseReportId but that param is for avatarFileName and expenseReportId should be the 16th

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@s77rt Sorry, for the miss, please have a look.

optimisticReportID = '',
shouldShowParticipants = true,
): OptimisticChatReport {
Expand Down Expand Up @@ -4678,6 +4680,7 @@ function buildOptimisticChatReport(
description,
writeCapability,
avatarUrl,
avatarFileName,
};

if (chatType === CONST.REPORT.CHAT_TYPE.INVOICE) {
Expand All @@ -4695,6 +4698,7 @@ function buildOptimisticGroupChatReport(
participantAccountIDs: number[],
reportName: string,
avatarUri: string,
avatarFileName: string,
optimisticReportID?: string,
notificationPreference?: NotificationPreference,
) {
Expand All @@ -4713,6 +4717,7 @@ function buildOptimisticGroupChatReport(
undefined,
undefined,
avatarUri,
avatarFileName,
optimisticReportID,
);
}
Expand Down Expand Up @@ -5205,6 +5210,7 @@ function buildTransactionThread(
'',
'',
'',
'',
false,
);
}
Expand Down
11 changes: 10 additions & 1 deletion src/libs/actions/Report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,7 @@ function updateGroupChatAvatar(reportID: string, file?: File | CustomRNImageMani
key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
value: {
avatarUrl: file?.uri ?? '',
avatarFileName: file?.name ?? '',
pendingFields: {
avatar: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
},
Expand All @@ -693,6 +694,7 @@ function updateGroupChatAvatar(reportID: string, file?: File | CustomRNImageMani
key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
value: {
avatarUrl: currentReportData?.[reportID]?.avatarUrl ?? null,
avatarFileName: currentReportData?.[reportID]?.avatarFileName ?? null,
pendingFields: {
avatar: null,
},
Expand Down Expand Up @@ -980,7 +982,14 @@ function navigateToAndOpenReport(
if (isEmptyObject(chat)) {
if (isGroupChat) {
// If we are creating a group chat then participantAccountIDs is expected to contain currentUserAccountID
newChat = ReportUtils.buildOptimisticGroupChatReport(participantAccountIDs, reportName ?? '', avatarUri ?? '', optimisticReportID, CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN);
newChat = ReportUtils.buildOptimisticGroupChatReport(
participantAccountIDs,
reportName ?? '',
avatarUri ?? '',
avatarFile?.name ?? '',
optimisticReportID,
CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN,
);
} else {
newChat = ReportUtils.buildOptimisticChatReport(
[...participantAccountIDs, currentUserAccountID],
Expand Down
2 changes: 1 addition & 1 deletion src/pages/NewChatConfirmPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,9 @@ function NewChatConfirmPage({newGroupDraft, allPersonalDetails}: NewChatConfirmP
}}
size={CONST.AVATAR_SIZE.XLARGE}
avatarStyle={styles.avatarXLarge}
shouldDisableViewPhoto
nexarvo marked this conversation as resolved.
Show resolved Hide resolved
nexarvo marked this conversation as resolved.
Show resolved Hide resolved
editIcon={Expensicons.Camera}
editIconStyle={styles.smallEditIconAccount}
onViewPhotoPress={() => Navigation.navigate(ROUTES.REPORT_AVATAR.getRoute(optimisticReportID.current, true))}
shouldUseStyleUtilityForAnchorPosition
style={styles.w100}
/>
Expand Down
38 changes: 30 additions & 8 deletions src/pages/ReportAvatar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type {StackScreenProps} from '@react-navigation/stack';
import React from 'react';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import {useOnyx, withOnyx} from 'react-native-onyx';
import AttachmentModal from '@components/AttachmentModal';
import Navigation from '@libs/Navigation/Navigation';
import type {AuthScreensParamList} from '@libs/Navigation/types';
Expand All @@ -20,24 +20,46 @@ type ReportAvatarOnyxProps = {

type ReportAvatarProps = ReportAvatarOnyxProps & StackScreenProps<AuthScreensParamList, typeof SCREENS.REPORT_AVATAR>;

function ReportAvatar({report = {} as Report, policies, isLoadingApp = true}: ReportAvatarProps) {
function ReportAvatar({report = {} as Report, policies, isLoadingApp = true, route}: ReportAvatarProps) {
const policy = policies?.[`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID ?? '-1'}`];
const policyName = ReportUtils.getPolicyName(report, false, policy);
const avatarURL = ReportUtils.getWorkspaceAvatar(report);
let title;
let avatarURL;
let fileName;
// eslint-disable-next-line rulesdir/no-negated-variables
let shouldShowNotFoundPage;

const shouldUseGroupChatDraft = !!route.params.isNewGroupChat;

const [groupChatDraft] = useOnyx(ONYXKEYS.NEW_GROUP_CHAT_DRAFT, {initWithStoredValues: shouldUseGroupChatDraft});

if (shouldUseGroupChatDraft) {
avatarURL = groupChatDraft?.avatarUri ?? undefined;
fileName = groupChatDraft?.avatarFileName ?? undefined;
// When user enters custom group name, it typically stored in groupChatDraft.reportName
// If that is null then we will use ReportUtils.getGroupChatName to get the name
/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */
title = groupChatDraft?.reportName || ReportUtils.getGroupChatName(groupChatDraft?.participants.map((participant) => participant.accountID) ?? [], true);
shouldShowNotFoundPage = !isLoadingApp && !groupChatDraft;
} else {
avatarURL = policy ? ReportUtils.getWorkspaceAvatar(report) : report?.avatarUrl;
// In the case of default workspace avatar, originalFileName prop takes policyID as value to get the color of the avatar
fileName = policy ? policy?.originalFileName ?? policy?.id ?? report?.policyID : report?.avatarFileName;
title = policy ? ReportUtils.getPolicyName(report, false, policy) : ReportUtils.getReportName(report);
shouldShowNotFoundPage = !isLoadingApp && !report?.reportID;
}

return (
<AttachmentModal
headerTitle={policyName}
headerTitle={title}
defaultOpen
source={UserUtils.getFullSizeAvatar(avatarURL, 0)}
onModalClose={() => {
Navigation.goBack(ROUTES.REPORT_WITH_ID_DETAILS.getRoute(report?.reportID ?? '-1'));
}}
isWorkspaceAvatar
maybeIcon
// In the case of default workspace avatar, originalFileName prop takes policyID as value to get the color of the avatar
originalFileName={policy?.originalFileName ?? policy?.id ?? report?.policyID}
shouldShowNotFoundPage={!report?.reportID && !isLoadingApp}
originalFileName={fileName}
shouldShowNotFoundPage={shouldShowNotFoundPage}
isLoading={(!report?.reportID || !policy?.id) && !!isLoadingApp}
/>
);
Expand Down
2 changes: 1 addition & 1 deletion src/pages/ReportDetailsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,6 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
isUsingDefaultAvatar={!report.avatarUrl}
size={CONST.AVATAR_SIZE.XLARGE}
avatarStyle={styles.avatarXLarge}
shouldDisableViewPhoto
onImageRemoved={() => {
// Calling this without a file will remove the avatar
Report.updateGroupChatAvatar(report.reportID ?? '');
Expand All @@ -429,6 +428,7 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
onErrorClose={() => Report.clearAvatarErrors(report.reportID ?? '-1')}
shouldUseStyleUtilityForAnchorPosition
style={[styles.w100, styles.mb3]}
onViewPhotoPress={() => Navigation.navigate(ROUTES.REPORT_AVATAR.getRoute(report.reportID))}
/>
);
}
Expand Down
5 changes: 5 additions & 0 deletions src/types/onyx/Report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ type Report = OnyxCommon.OnyxValueWithOfflineFeedback<
/** The URL of the Group Chat report custom avatar */
avatarUrl?: string;

/** The file name of the Group Chat report custom avatar
* This field is not coming from backend, so it's for client side only
*/
avatarFileName?: string;

/** The specific type of chat */
chatType?: ValueOf<typeof CONST.REPORT.CHAT_TYPE>;

Expand Down
Loading