Skip to content

Commit ef2def5

Browse files
authored
Merge pull request Expensify#72446 from samranahm/revert-72436-revert-66883-65210/edit-room-avatar
feat: allow users to change user created workspace room avatar
2 parents 43731be + 332d571 commit ef2def5

29 files changed

Lines changed: 288 additions & 20 deletions

src/CONST/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1337,6 +1337,7 @@ const CONST = {
13371337
REMOVE_FROM_ROOM: 'REMOVEFROMROOM',
13381338
LEAVE_ROOM: 'LEAVEROOM',
13391339
UPDATE_ROOM_DESCRIPTION: 'UPDATEROOMDESCRIPTION',
1340+
UPDATE_ROOM_AVATAR: 'UPDATEROOMAVATAR',
13401341
},
13411342
REJECTEDTRANSACTION_THREAD: 'REJECTEDTRANSACTION_THREAD',
13421343
REJECTED_TRANSACTION_MARKASRESOLVED: 'REJECTEDTRANSACTIONMARKASRESOLVED',

src/components/AvatarButtonWithIcon.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ type AvatarButtonWithIconProps = {
6161

6262
/** Optionally override the default "Edit" icon */
6363
editIcon?: IconAsset;
64+
65+
/** The name associated with avatar */
66+
name?: string;
6467
};
6568

6669
/**
@@ -82,6 +85,7 @@ function AvatarButtonWithIcon({
8285
disabled = false,
8386
editIcon = Expensicons.Pencil,
8487
anchorRef,
88+
name = '',
8589
}: AvatarButtonWithIconProps) {
8690
const theme = useTheme();
8791
const styles = useThemeStyles();
@@ -110,6 +114,7 @@ function AvatarButtonWithIcon({
110114
fallbackIcon={fallbackIcon}
111115
size={size}
112116
type={type}
117+
name={name}
113118
/>
114119
) : (
115120
<DefaultAvatar />

src/components/AvatarWithImagePicker.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ type AvatarWithImagePickerProps = Omit<AvatarButtonWithIconProps, 'text' | 'onPr
6969

7070
/** Allows to open an image without Attachment Picker. */
7171
enablePreview?: boolean;
72+
73+
/** The name associated with avatar */
74+
name?: string;
7275
};
7376

7477
const anchorAlignment = {horizontal: CONST.MODAL.ANCHOR_ORIGIN_HORIZONTAL.CENTER, vertical: CONST.MODAL.ANCHOR_ORIGIN_VERTICAL.TOP};
@@ -96,6 +99,7 @@ function AvatarWithImagePicker({
9699
onViewPhotoPress,
97100
enablePreview = false,
98101
editIcon = Expensicons.Pencil,
102+
name = '',
99103
}: AvatarWithImagePickerProps) {
100104
const styles = useThemeStyles();
101105
const isFocused = useIsFocused();
@@ -264,6 +268,7 @@ function AvatarWithImagePicker({
264268
type={type}
265269
disabledStyle={disabledStyle}
266270
editIconStyle={editIconStyle}
271+
name={name}
267272
/>
268273
</OfflineWithFeedback>
269274
<PopoverMenu

src/components/RoomHeaderAvatars.tsx

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,33 @@
11
import React, {memo} from 'react';
22
import {View} from 'react-native';
3+
import type {OnyxEntry} from 'react-native-onyx';
34
import useStyleUtils from '@hooks/useStyleUtils';
45
import useThemeStyles from '@hooks/useThemeStyles';
6+
import {clearAvatarErrors, getCurrentUserAccountID, updatePolicyRoomAvatar} from '@libs/actions/Report';
57
import Navigation from '@libs/Navigation/Navigation';
8+
import {isUserCreatedPolicyRoom} from '@libs/ReportUtils';
9+
import {isDefaultAvatar} from '@libs/UserUtils';
610
import CONST from '@src/CONST';
711
import ROUTES from '@src/ROUTES';
12+
import type {Policy, Report} from '@src/types/onyx';
813
import type {Icon} from '@src/types/onyx/OnyxCommon';
914
import Avatar from './Avatar';
15+
import AvatarWithImagePicker from './AvatarWithImagePicker';
1016
import * as Expensicons from './Icon/Expensicons';
1117
import PressableWithoutFocus from './Pressable/PressableWithoutFocus';
1218
import Text from './Text';
1319

1420
type RoomHeaderAvatarsProps = {
1521
icons: Icon[];
16-
reportID: string;
22+
report: Report;
23+
policy: OnyxEntry<Policy>;
24+
participants: number[];
1725
};
1826

19-
function RoomHeaderAvatars({icons, reportID}: RoomHeaderAvatarsProps) {
27+
function RoomHeaderAvatars({icons, report, policy, participants}: RoomHeaderAvatarsProps) {
2028
const navigateToAvatarPage = (icon: Icon) => {
2129
if (icon.type === CONST.ICON_TYPE_WORKSPACE && icon.id) {
22-
Navigation.navigate(ROUTES.REPORT_AVATAR.getRoute(reportID, icon.id.toString()));
30+
Navigation.navigate(ROUTES.REPORT_AVATAR.getRoute(report?.reportID, icon.id.toString()));
2331
return;
2432
}
2533

@@ -30,6 +38,8 @@ function RoomHeaderAvatars({icons, reportID}: RoomHeaderAvatarsProps) {
3038

3139
const styles = useThemeStyles();
3240
const StyleUtils = useStyleUtils();
41+
const currentUserAccountID = getCurrentUserAccountID();
42+
const canEditRoomAvatar = isUserCreatedPolicyRoom(report) && participants.includes(currentUserAccountID) && !!policy && policy.role !== CONST.POLICY.ROLE.AUDITOR;
3343

3444
if (!icons.length) {
3545
return null;
@@ -42,6 +52,31 @@ function RoomHeaderAvatars({icons, reportID}: RoomHeaderAvatarsProps) {
4252
return;
4353
}
4454

55+
if (canEditRoomAvatar) {
56+
return (
57+
<AvatarWithImagePicker
58+
source={icon.source || report.avatarUrl}
59+
avatarID={icon.id}
60+
isUsingDefaultAvatar={!report.avatarUrl || isDefaultAvatar(icon.source)}
61+
size={CONST.AVATAR_SIZE.X_LARGE}
62+
avatarStyle={[styles.avatarXLarge, styles.alignSelfCenter]}
63+
onViewPhotoPress={() => Navigation.navigate(ROUTES.REPORT_AVATAR.getRoute(report.reportID))}
64+
onImageRemoved={() => updatePolicyRoomAvatar(report.reportID)}
65+
onImageSelected={(file) => updatePolicyRoomAvatar(report.reportID, file)}
66+
editIcon={Expensicons.Camera}
67+
editIconStyle={styles.smallEditIconAccount}
68+
pendingAction={report.pendingFields?.avatar}
69+
errors={report.errorFields?.avatar ?? null}
70+
errorRowStyles={styles.mt6}
71+
onErrorClose={() => clearAvatarErrors(report.reportID)}
72+
style={[styles.w100, styles.mb3, styles.alignItemsStart, styles.sectionMenuItemTopDescription]}
73+
type={icon.type}
74+
editorMaskImage={Expensicons.ImageCropSquareMask}
75+
name={icon.name}
76+
/>
77+
);
78+
}
79+
4580
return (
4681
<PressableWithoutFocus
4782
style={styles.noOutline}

src/languages/de.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7170,6 +7170,8 @@ ${amount} für ${merchant} - ${date}`,
71707170
roomChangeLog: {
71717171
updateRoomDescription: 'setze die Raumbeschreibung auf:',
71727172
clearRoomDescription: 'Raumbeschreibung gelöscht',
7173+
changedRoomAvatar: 'Hat das Raum-Avatar geändert',
7174+
removedRoomAvatar: 'Hat das Raum-Avatar entfernt',
71737175
},
71747176
delegate: {
71757177
switchAccount: 'Konten wechseln:',

src/languages/en.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7118,6 +7118,8 @@ const translations = {
71187118
roomChangeLog: {
71197119
updateRoomDescription: 'set the room description to:',
71207120
clearRoomDescription: 'cleared the room description',
7121+
changedRoomAvatar: 'changed the room avatar',
7122+
removedRoomAvatar: 'removed the room avatar',
71217123
},
71227124
delegate: {
71237125
switchAccount: 'Switch accounts:',

src/languages/es.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7614,6 +7614,8 @@ ${amount} para ${merchant} - ${date}`,
76147614
roomChangeLog: {
76157615
updateRoomDescription: 'establece la descripción de la sala a:',
76167616
clearRoomDescription: 'la descripción de la habitación ha sido borrada',
7617+
changedRoomAvatar: 'Cambió el avatar de la sala',
7618+
removedRoomAvatar: 'Eliminó el avatar de la sala',
76177619
},
76187620
delegate: {
76197621
switchAccount: 'Cambiar de cuenta:',

src/languages/fr.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7173,6 +7173,8 @@ ${amount} pour ${merchant} - ${date}`,
71737173
roomChangeLog: {
71747174
updateRoomDescription: 'définir la description de la salle sur :',
71757175
clearRoomDescription: 'effacé la description de la salle',
7176+
changedRoomAvatar: 'A changé l’avatar de la salle',
7177+
removedRoomAvatar: 'A supprimé l’avatar de la salle',
71767178
},
71777179
delegate: {
71787180
switchAccount: 'Changer de compte :',

src/languages/it.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7178,6 +7178,8 @@ ${amount} per ${merchant} - ${date}`,
71787178
roomChangeLog: {
71797179
updateRoomDescription: 'imposta la descrizione della stanza su:',
71807180
clearRoomDescription: 'cancellato la descrizione della stanza',
7181+
changedRoomAvatar: "Ha cambiato l'avatar della stanza",
7182+
removedRoomAvatar: "Ha rimosso l'avatar della stanza",
71817183
},
71827184
delegate: {
71837185
switchAccount: 'Cambia account:',

src/languages/ja.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7107,6 +7107,8 @@ ${date} - ${merchant}に${amount}`,
71077107
roomChangeLog: {
71087108
updateRoomDescription: '部屋の説明を次のように設定します:',
71097109
clearRoomDescription: '部屋の説明をクリアしました',
7110+
changedRoomAvatar: 'ルームのアバターを変更しました',
7111+
removedRoomAvatar: 'ルームのアバターを削除しました',
71107112
},
71117113
delegate: {
71127114
switchAccount: 'アカウントを切り替える:',

0 commit comments

Comments
 (0)