Skip to content

Commit

Permalink
Merge pull request Expensify#48757 from tsa321/groupAvatar
Browse files Browse the repository at this point in the history
Add support for viewing group avatar photo
  • Loading branch information
marcaaron authored Sep 17, 2024
2 parents ed4c2e4 + 1dce9ac commit 539327d
Show file tree
Hide file tree
Showing 6 changed files with 57 additions and 36 deletions.
6 changes: 6 additions & 0 deletions src/libs/ReportUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ type OptimisticChatReport = Pick<
| 'description'
| 'writeCapability'
| 'avatarUrl'
| 'avatarFileName'
| 'invoiceReceiver'
| 'isHidden'
> & {
Expand Down Expand Up @@ -5078,6 +5079,7 @@ function buildOptimisticChatReport(
parentReportID = '',
description = '',
avatarUrl = '',
avatarFileName = '',
optimisticReportID = '',
): OptimisticChatReport {
const isWorkspaceChatType = chatType && isWorkspaceChat(chatType);
Expand Down Expand Up @@ -5118,6 +5120,7 @@ function buildOptimisticChatReport(
description,
writeCapability,
avatarUrl,
avatarFileName,
};

if (chatType === CONST.REPORT.CHAT_TYPE.INVOICE) {
Expand All @@ -5135,6 +5138,7 @@ function buildOptimisticGroupChatReport(
participantAccountIDs: number[],
reportName: string,
avatarUri: string,
avatarFilename: string,
optimisticReportID?: string,
notificationPreference?: NotificationPreference,
) {
Expand All @@ -5153,6 +5157,7 @@ function buildOptimisticGroupChatReport(
undefined,
undefined,
avatarUri,
avatarFilename,
optimisticReportID,
);
}
Expand Down Expand Up @@ -5562,6 +5567,7 @@ function buildOptimisticWorkspaceChats(policyID: string, policyName: string, exp
undefined,
undefined,
undefined,
undefined,
expenseReportId,
);
const expenseChatReportID = expenseChatData.reportID;
Expand Down
16 changes: 13 additions & 3 deletions src/libs/actions/Report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -697,7 +697,8 @@ function updateGroupChatAvatar(reportID: string, file?: File | CustomRNImageMani
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
value: {
avatarUrl: file?.uri ?? '',
avatarUrl: file ? file?.uri ?? '' : null,
avatarFileName: file ? file?.name ?? '' : null,
pendingFields: {
avatar: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE,
},
Expand All @@ -708,12 +709,14 @@ function updateGroupChatAvatar(reportID: string, file?: File | CustomRNImageMani
},
];

const fetchedReport = ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`];
const failureData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
value: {
avatarUrl: ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]?.avatarUrl ?? null,
avatarUrl: fetchedReport?.avatarUrl ?? null,
avatarFileName: fetchedReport?.avatarFileName ?? null,
pendingFields: {
avatar: null,
},
Expand Down Expand Up @@ -1011,7 +1014,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.ALWAYS);
newChat = ReportUtils.buildOptimisticGroupChatReport(
participantAccountIDs,
reportName ?? '',
avatarUri ?? '',
avatarFile?.name ?? '',
optimisticReportID,
CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS,
);
} else {
newChat = ReportUtils.buildOptimisticChatReport(
[...participantAccountIDs, currentUserAccountID],
Expand Down
64 changes: 32 additions & 32 deletions src/pages/ReportAvatar.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
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 React, {useMemo} from 'react';
import {useOnyx} from 'react-native-onyx';
import AttachmentModal from '@components/AttachmentModal';
import Navigation from '@libs/Navigation/Navigation';
import type {AuthScreensParamList} from '@libs/Navigation/types';
Expand All @@ -10,50 +9,51 @@ import * as UserUtils from '@libs/UserUtils';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type SCREENS from '@src/SCREENS';
import type {Policy, Report} from '@src/types/onyx';

type ReportAvatarOnyxProps = {
report: OnyxEntry<Report>;
isLoadingApp: OnyxEntry<boolean>;
policies: OnyxCollection<Policy>;
};
type ReportAvatarProps = StackScreenProps<AuthScreensParamList, typeof SCREENS.REPORT_AVATAR>;

type ReportAvatarProps = ReportAvatarOnyxProps & StackScreenProps<AuthScreensParamList, typeof SCREENS.REPORT_AVATAR>;
function ReportAvatar({route}: ReportAvatarProps) {
const reportIDFromRoute = route.params?.reportID ?? '-1';
const policyIDFromRoute = route.params?.policyID ?? '-1';
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportIDFromRoute}`);
const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyIDFromRoute}`);
const [isLoadingApp] = useOnyx(ONYXKEYS.IS_LOADING_APP, {initialValue: true});

function ReportAvatar({report = {} as Report, route, policies, isLoadingApp = true}: ReportAvatarProps) {
const policyID = route.params.policyID ?? '-1';
const policy = policies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`];
const policyName = ReportUtils.getPolicyName(report, false, policy);
const avatarURL = ReportUtils.getWorkspaceIcon(report).source;
const attachment = useMemo(() => {
if (ReportUtils.isGroupChat(report) && !ReportUtils.isThread(report)) {
return {
source: report?.avatarUrl ? UserUtils.getFullSizeAvatar(report.avatarUrl, 0) : ReportUtils.getDefaultGroupAvatar(report?.reportID ?? ''),
headerTitle: ReportUtils.getReportName(report),
originalFileName: report?.avatarFileName ?? '',
isWorkspaceAvatar: false,
};
}

return {
source: UserUtils.getFullSizeAvatar(ReportUtils.getWorkspaceIcon(report).source, 0),
headerTitle: ReportUtils.getPolicyName(report, false, policy),
// 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 ?? '',
isWorkspaceAvatar: true,
};
}, [report, policy]);

return (
<AttachmentModal
headerTitle={policyName}
headerTitle={attachment.headerTitle}
defaultOpen
source={UserUtils.getFullSizeAvatar(avatarURL, 0)}
source={attachment.source}
onModalClose={() => {
Navigation.goBack(ROUTES.REPORT_WITH_ID_DETAILS.getRoute(report?.reportID ?? '-1'));
}}
isWorkspaceAvatar
isWorkspaceAvatar={attachment.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}
originalFileName={attachment.originalFileName}
shouldShowNotFoundPage={!report?.reportID && !isLoadingApp}
isLoading={(!report?.reportID || !policy?.id) && !!isLoadingApp}
/>
);
}

ReportAvatar.displayName = 'ReportAvatar';

export default withOnyx<ReportAvatarProps, ReportAvatarOnyxProps>({
report: {
key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT}${route.params.reportID ?? '-1'}`,
},
isLoadingApp: {
key: ONYXKEYS.IS_LOADING_APP,
},
policies: {
key: ONYXKEYS.COLLECTION.POLICY,
},
})(ReportAvatar);
export default ReportAvatar;
2 changes: 1 addition & 1 deletion src/pages/ReportDetailsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD
isUsingDefaultAvatar={!report.avatarUrl}
size={CONST.AVATAR_SIZE.XLARGE}
avatarStyle={styles.avatarXLarge}
shouldDisableViewPhoto
onViewPhotoPress={() => Navigation.navigate(ROUTES.REPORT_AVATAR.getRoute(report.reportID ?? '-1'))}
onImageRemoved={() => {
// Calling this without a file will remove the avatar
Report.updateGroupChatAvatar(report.reportID ?? '');
Expand Down
2 changes: 2 additions & 0 deletions src/pages/home/ReportScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro
isOptimisticReport: reportOnyx?.isOptimisticReport,
lastMentionedTime: reportOnyx?.lastMentionedTime,
avatarUrl: reportOnyx?.avatarUrl,
avatarFileName: reportOnyx?.avatarFileName,
permissions,
invoiceReceiver: reportOnyx?.invoiceReceiver,
policyAvatar: reportOnyx?.policyAvatar,
Expand Down Expand Up @@ -248,6 +249,7 @@ function ReportScreen({route, currentReportID = '', navigation}: ReportScreenPro
reportOnyx?.isOptimisticReport,
reportOnyx?.lastMentionedTime,
reportOnyx?.avatarUrl,
reportOnyx?.avatarFileName,
permissions,
reportOnyx?.invoiceReceiver,
reportOnyx?.policyAvatar,
Expand Down
3 changes: 3 additions & 0 deletions src/types/onyx/Report.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ type Report = OnyxCommon.OnyxValueWithOfflineFeedback<
/** The URL of the Group Chat report custom avatar */
avatarUrl?: string;

/** The filename of the avatar */
avatarFileName?: string;

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

Expand Down

0 comments on commit 539327d

Please sign in to comment.