Skip to content
13 changes: 13 additions & 0 deletions assets/images/avatars/deleted-room.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 7 additions & 3 deletions src/components/Avatar.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, {PureComponent} from 'react';
import {Image, View, StyleSheet} from 'react-native';
import {Image, View} from 'react-native';
import PropTypes from 'prop-types';
import styles from '../styles/styles';
import RoomAvatar from '../../assets/images/avatars/room.svg';
import RoomAvatar from './RoomAvatar';

const propTypes = {
/** Url source for the avatar */
Expand All @@ -19,6 +19,9 @@ const propTypes = {

/** Whether this avatar is for a default room */
isDefaultChatRoom: PropTypes.bool,

/** Whether this avatar is for an archived default room */
isArchivedRoom: PropTypes.bool,
};

const defaultProps = {
Expand All @@ -27,6 +30,7 @@ const defaultProps = {
containerStyles: [],
size: 'default',
isDefaultChatRoom: false,
isArchivedRoom: false,
};

class Avatar extends PureComponent {
Expand All @@ -42,7 +46,7 @@ class Avatar extends PureComponent {
return (
<View pointerEvents="none" style={this.props.containerStyles}>
{this.props.isDefaultChatRoom
? <RoomAvatar style={StyleSheet.flatten(imageStyle)} />
? <RoomAvatar avatarStyle={imageStyle} isArchived={this.props.isArchivedRoom} />
: <Image source={{uri: this.props.source}} style={imageStyle} />}
</View>
);
Expand Down
13 changes: 11 additions & 2 deletions src/components/MultipleAvatars.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,21 @@ const propTypes = {

/** Whether this avatar is for a default room */
isDefaultChatRoom: PropTypes.bool,

/** Whether this avatar is for an archived room */
isArchivedRoom: PropTypes.bool,
};

const defaultProps = {
avatarImageURLs: [],
size: 'default',
secondAvatarStyle: [styles.secondAvatarHovered],
isDefaultChatRoom: false,
isArchivedRoom: false,
};

const MultipleAvatars = ({
avatarImageURLs, size, secondAvatarStyle, isDefaultChatRoom,
avatarImageURLs, size, secondAvatarStyle, isDefaultChatRoom, isArchivedRoom,
}) => {
const avatarContainerStyles = size === 'small' ? styles.emptyAvatarSmall : styles.emptyAvatar;
const singleAvatarStyles = size === 'small' ? styles.singleAvatarSmall : styles.singleAvatar;
Expand All @@ -44,7 +48,12 @@ const MultipleAvatars = ({
if (avatarImageURLs.length === 1) {
return (
<View style={avatarContainerStyles}>
<Avatar source={avatarImageURLs[0]} size={size} isDefaultChatRoom={isDefaultChatRoom} />
<Avatar
source={avatarImageURLs[0]}
size={size}
isDefaultChatRoom={isDefaultChatRoom}
isArchivedRoom={isArchivedRoom}
/>
</View>
);
}
Expand Down
31 changes: 31 additions & 0 deletions src/components/RoomAvatar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React, {PureComponent} from 'react';
import {StyleSheet} from 'react-native';
import PropTypes from 'prop-types';
import ActiveRoomAvatar from '../../assets/images/avatars/room.svg';
import DeletedRoomAvatar from '../../assets/images/avatars/deleted-room.svg';

const propTypes = {
/** Extra styles to pass to Image */
avatarStyle: PropTypes.arrayOf(PropTypes.object),

/** Whether the room this avatar is for is deleted or not */
isArchived: PropTypes.bool,
};

const defaultProps = {
avatarStyle: [],
isArchived: false,
};

class RoomAvatar extends PureComponent {
render() {
return (this.props.isArchived
? <DeletedRoomAvatar style={StyleSheet.flatten(this.props.avatarStyle)} />
: <ActiveRoomAvatar style={StyleSheet.flatten(this.props.avatarStyle)} />
);
}
}

RoomAvatar.defaultProps = defaultProps;
RoomAvatar.propTypes = propTypes;
export default RoomAvatar;
2 changes: 2 additions & 0 deletions src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export default {
privacy: 'Privacy',
privacyPolicy: 'Privacy Policy',
delete: 'Delete',
deleted: 'deleted',
contacts: 'Contacts',
recents: 'Recents',
close: 'Close',
Expand Down Expand Up @@ -107,6 +108,7 @@ export default {
blockedFromConcierge: 'Communication is barred',
youAppearToBeOffline: 'You appear to be offline.',
fileUploadFailed: 'Upload Failed. File is not supported.',
roomIsArchived: 'This chat room has been deleted',
},
contextMenuItem: {
copyToClipboard: 'Copy to Clipboard',
Expand Down
2 changes: 2 additions & 0 deletions src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export default {
and: 'y',
details: 'Detalles',
delete: 'Eliminar',
deleted: 'eliminado',
contacts: 'Contactos',
recents: 'Recientes',
close: 'Cerrar',
Expand Down Expand Up @@ -102,6 +103,7 @@ export default {
writeSomething: 'Escribe algo...',
blockedFromConcierge: 'Comunicación no permitida',
youAppearToBeOffline: 'Parece que estás desconectado.',
roomIsArchived: 'Esta sala de chat ha sido eliminada',
},
reportActionContextMenu: {
copyToClipboard: 'Copiar al Portapapeles',
Expand Down
5 changes: 4 additions & 1 deletion src/libs/OptionsListUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import lodashOrderBy from 'lodash/orderBy';
import Str from 'expensify-common/lib/str';
import ONYXKEYS from '../ONYXKEYS';
import CONST from '../CONST';
import {getReportParticipantsTitle, isDefaultRoom, getDefaultRoomSubtitle} from './reportUtils';
import {
getReportParticipantsTitle, isDefaultRoom, getDefaultRoomSubtitle, isArchivedRoom,
} from './reportUtils';
import {translate} from './translate';
import Permissions from './Permissions';
import md5 from './md5';
Expand Down Expand Up @@ -250,6 +252,7 @@ function createOption(personalDetailList, report, draftComments, {
isIOUReportOwner: lodashGet(iouReport, 'ownerEmail', '') === currentUserLogin,
iouReportAmount: lodashGet(iouReport, 'total', 0),
isDefaultChatRoom,
isArchivedRoom: isArchivedRoom(report),
};
}

Expand Down
16 changes: 14 additions & 2 deletions src/libs/actions/Report.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import * as API from '../API';
import CONST from '../../CONST';
import Log from '../Log';
import {
isConciergeChatReport, isDefaultRoom, isReportMessageAttachment, sortReportsByLastVisited,
isConciergeChatReport, isDefaultRoom, isReportMessageAttachment, sortReportsByLastVisited, isArchivedRoom,
} from '../reportUtils';
import Timers from '../Timers';
import {dangerouslyGetReportActionsMaxSequenceNumber, isReportMissingActions} from './ReportActions';
Expand Down Expand Up @@ -138,7 +138,13 @@ function getParticipantEmailsFromReport({sharedReportList}) {
*/
function getChatReportName(fullReport, chatType) {
if (isDefaultRoom({chatType})) {
return `#${fullReport.reportName}`;
return `#${fullReport.reportName}${(isArchivedRoom({
chatType,
stateNum: fullReport.stateNum,
statusNum: fullReport.reportStatus,
})
? ` (${translateLocal('common.deleted')})`
: '')}`;
}

const {sharedReportList} = fullReport;
Expand Down Expand Up @@ -181,6 +187,9 @@ function getSimplifiedReportObject(report) {
? lodashGet(report, ['reportNameValuePairs', 'notificationPreferences', currentUserAccountID], 'daily')
: '';

// Used for archived rooms, will store the policy name that the room used to belong to.
const oldPolicyName = lodashGet(report, ['reportNameValuePairs', 'oldPolicyName'], '');

return {
reportID: report.reportID,
reportName,
Expand All @@ -201,6 +210,9 @@ function getSimplifiedReportObject(report) {
lastActorEmail,
hasOutstandingIOU: false,
notificationPreference,
stateNum: report.state,
statusNum: report.status,
oldPolicyName,
};
}

Expand Down
19 changes: 19 additions & 0 deletions src/libs/reportUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,21 @@ function isDefaultRoom(report) {
], lodashGet(report, ['chatType'], ''));
}

/**
* Whether the provided report is an archived room
* @param {Object} report
* @param {Number} report.stateNum
* @param {Number} report.statusNum
* @returns {Boolean}
*/
function isArchivedRoom(report) {
if (!isDefaultRoom(report)) {
return false;
}

return report.statusNum === 2 && report.stateNum === 2;
}

/**
* Get either the policyName or domainName the chat is tied to
* @param {Object} report
Expand All @@ -116,6 +131,9 @@ function getDefaultRoomSubtitle(report, policiesMap) {
// The domainAll rooms are just #domainName, so we ignore the prefix '#' to get the domainName
return report.reportName.substring(1);
}
if (isArchivedRoom(report)) {
return report.oldPolicyName;
}
return lodashGet(
policiesMap,
[`${ONYXKEYS.COLLECTION.POLICY}${report.policyID}`, 'name'],
Expand Down Expand Up @@ -143,5 +161,6 @@ export {
sortReportsByLastVisited,
isDefaultRoom,
getDefaultRoomSubtitle,
isArchivedRoom,
isConciergeChatReport,
};
66 changes: 36 additions & 30 deletions src/pages/ReportDetailsPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import HeaderWithCloseButton from '../components/HeaderWithCloseButton';
import styles from '../styles/styles';
import DisplayNames from '../components/DisplayNames';
import {getPersonalDetailsForLogins} from '../libs/OptionsListUtils';
import {getDefaultRoomSubtitle, isDefaultRoom} from '../libs/reportUtils';
import {getDefaultRoomSubtitle, isDefaultRoom, isArchivedRoom} from '../libs/reportUtils';
import {participantPropTypes} from './home/sidebar/optionPropTypes';
import Picker from '../components/Picker';
import {updateNotificationPreference} from '../libs/actions/Report';
Expand Down Expand Up @@ -88,14 +88,15 @@ class ReportDetailsPage extends Component {
},
};

this.menuItems = [
{
translationKey: 'reportDetailsPage.members',
icon: Users,
subtitle: props.report.participants.length,
action: () => { Navigation.navigate(ROUTES.getReportParticipantsRoute(props.report.reportID)); },
},
];
this.menuItems = isArchivedRoom(this.props.report) ? []
: [
{
translationKey: 'reportDetailsPage.members',
icon: Users,
subtitle: props.report.participants.length,
action: () => { Navigation.navigate(ROUTES.getReportParticipantsRoute(props.report.reportID)); },
},
];
}

render() {
Expand Down Expand Up @@ -128,6 +129,7 @@ class ReportDetailsPage extends Component {
>
<Avatar
isDefaultChatRoom={isDefaultRoom(this.props.report)}
isArchivedRoom={isArchivedRoom(this.props.report)}
containerStyles={[styles.singleAvatarLarge, styles.mb4]}
imageStyles={[styles.singleAvatarLarge]}
source={{uri: this.props.report.icons[0]}}
Expand All @@ -149,28 +151,32 @@ class ReportDetailsPage extends Component {
</Text>
</View>
</View>
<View style={styles.mt4}>
<Text style={[styles.formLabel]} numberOfLines={1}>
{this.props.translate('common.notifications')}
</Text>
</View>
<View>
<Text style={[styles.mb3]}>
{this.props.translate('reportDetailsPage.notificationPreferencesDescription')}
</Text>
<View style={[styles.mb5]}>
<Picker
onChange={(notificationPreference) => {
updateNotificationPreference(
this.props.report.reportID,
notificationPreference,
);
}}
items={Object.values(this.notificationPreferencesOptions)}
value={this.props.report.notificationPreference}
/>
{!isArchivedRoom(this.props.report) && (
<View>
<View style={styles.mt4}>
<Text style={[styles.formLabel]} numberOfLines={1}>
{this.props.translate('common.notifications')}
</Text>
</View>
<View>
<Text style={[styles.mb3]}>
{this.props.translate('reportDetailsPage.notificationPreferencesDescription')}
</Text>
<View style={[styles.mb5]}>
<Picker
onChange={(notificationPreference) => {
updateNotificationPreference(
this.props.report.reportID,
notificationPreference,
);
}}
items={Object.values(this.notificationPreferencesOptions)}
value={this.props.report.notificationPreference}
/>
</View>
</View>
</View>
</View>
)}
</View>
{this.menuItems.map((item) => {
const keyTitle = item.translationKey ? this.props.translate(item.translationKey) : item.title;
Expand Down
3 changes: 2 additions & 1 deletion src/pages/home/HeaderView.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import VideoChatButtonAndMenu from '../../components/VideoChatButtonAndMenu';
import IOUBadge from '../../components/IOUBadge';
import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize';
import CONST from '../../CONST';
import {getDefaultRoomSubtitle, isDefaultRoom} from '../../libs/reportUtils';
import {getDefaultRoomSubtitle, isDefaultRoom, isArchivedRoom} from '../../libs/reportUtils';
import Text from '../../components/Text';

const propTypes = {
Expand Down Expand Up @@ -122,6 +122,7 @@ const HeaderView = (props) => {
avatarImageURLs={props.report.icons}
secondAvatarStyle={[styles.secondAvatarHovered]}
isDefaultChatRoom={isDefaultChatRoom}
isArchivedRoom={isArchivedRoom(props.report)}
/>
<View style={[styles.flex1, styles.flexColumn]}>
<DisplayNames
Expand Down
Loading