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

Update "be the first person to comment" screen #4921

Merged
merged 38 commits into from
Nov 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
19193c3
chat avatars for "be the first to comment" screen
MirFahad58 Aug 28, 2021
21fe129
custom avatar added for custom chat rooms using props as resuseable c…
MirFahad58 Aug 29, 2021
eb61ec0
fixed the lint
MirFahad58 Aug 29, 2021
fdfb878
custom text and other user name with pronouns added
MirFahad58 Aug 29, 2021
1a905ea
localisation added for chat begin screen
MirFahad58 Aug 29, 2021
e615ff3
focused on 1st step as user gets in
MirFahad58 Aug 30, 2021
854e82d
change place holder to say hello
MirFahad58 Aug 30, 2021
ba1bbf3
fixing show say hello first time Alone
MirFahad58 Aug 30, 2021
f9aa030
Merge branch 'main' into fahad-beTheFirstPersonToComment
MirFahad58 Aug 31, 2021
0ce0349
fixes for multi chat
MirFahad58 Aug 31, 2021
c3512c7
style fixes
MirFahad58 Sep 1, 2021
d72f9b7
updated the changes according to review
MirFahad58 Sep 12, 2021
92b0eba
Merge branch 'main' into fahad-beTheFirstPersonToComment
MirFahad58 Sep 12, 2021
d78baa5
number opacity fix
MirFahad58 Sep 20, 2021
29ab6ff
required changes updated
MirFahad58 Sep 26, 2021
024de31
removed the --fix
MirFahad58 Sep 26, 2021
a267581
changes for review.
MirFahad58 Sep 28, 2021
71cbcf0
auto open keyboard and other fixes
MirFahad58 Oct 3, 2021
97dcd15
lint fixed
MirFahad58 Oct 3, 2021
bd04568
Merge branch 'main' into fahad-beTheFirstPersonToComment
MirFahad58 Oct 5, 2021
57b3da4
canFocusInputOnScreenFocus revert
MirFahad58 Oct 5, 2021
4b57887
removed isFocussed and added in component
MirFahad58 Oct 5, 2021
698cfd1
update code styles changes
MirFahad58 Oct 10, 2021
9a58bf8
spelling issue resolved
MirFahad58 Oct 19, 2021
0a4e789
component spelling mistake
MirFahad58 Oct 19, 2021
0b423d9
added for beginningOfChatHistory in es.js and other changes
MirFahad58 Oct 19, 2021
be900c5
font weight bold in android.
MirFahad58 Oct 19, 2021
12f0f52
done with requested changes
MirFahad58 Oct 20, 2021
60e6bee
translation added
MirFahad58 Oct 20, 2021
0cf355c
updated and removed the icon as prop.
MirFahad58 Oct 25, 2021
55d4275
avatar updated
MirFahad58 Oct 26, 2021
08f9532
requested updates
MirFahad58 Nov 13, 2021
1cd7eb8
Merge branch 'main' into fahad-beTheFirstPersonToComment
MirFahad58 Nov 13, 2021
0b7a37a
updates
MirFahad58 Nov 13, 2021
acf319a
linted
MirFahad58 Nov 13, 2021
a3ea9f9
Merge branch 'main' into fahad-beTheFirstPersonToComment
MirFahad58 Nov 16, 2021
8fddba5
code linted
MirFahad58 Nov 17, 2021
8353261
bold text for #private room
MirFahad58 Nov 17, 2021
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
2 changes: 2 additions & 0 deletions src/CONST.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ const CONST = {
DAILY: 'daily',
ALWAYS: 'always',
},
MAX_PREVIEW_AVATARS: 4,
},
MODAL: {
MODAL_TYPE: {
Expand Down Expand Up @@ -428,6 +429,7 @@ const CONST = {
LARGE: 'large',
DEFAULT: 'default',
},

PHONE_MAX_LENGTH: 15,
PHONE_MIN_LENGTH: 5,
REGEX: {
Expand Down
72 changes: 72 additions & 0 deletions src/components/EmptyStateAvatars.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React, {memo} from 'react';
import PropTypes from 'prop-types';
import {Image, View} from 'react-native';
import _ from 'underscore';
import styles from '../styles/styles';
import Text from './Text';
import CONST from '../CONST';
import Avatar from './Avatar';

const propTypes = {
/** Array of avatar URL */
avatarImageURLs: PropTypes.arrayOf(PropTypes.string),

MirFahad58 marked this conversation as resolved.
Show resolved Hide resolved
/** Whether this avatar is for a custom/default room */
isDefaultChatRoom: PropTypes.bool,
};

const defaultProps = {
avatarImageURLs: [],
isDefaultChatRoom: false,
};

const EmptyStateAvatars = (props) => {
if (!props.avatarImageURLs.length) {
return null;
}

if (props.avatarImageURLs.length === 1 || props.isDefaultChatRoom) {
return (
<Avatar
source={props.avatarImageURLs[0]}
imageStyles={[styles.avatarLarge]}
isDefaultChatRoom={props.isDefaultChatRoom}
/>
);
}

// avatarImageURLsToDisplay
const avatarImageURLsToDisplay = props.avatarImageURLs.slice(0, CONST.REPORT.MAX_PREVIEW_AVATARS);

return (
<View pointerEvents="none">
<View style={[styles.flexRow, styles.wAuto, styles.ml3]}>
{_.map(avatarImageURLsToDisplay, (val, index) => (
<View key={val} style={[styles.justifyContentCenter, styles.alignItemsCenter]}>
<Image source={{uri: val}} style={[styles.emptyStateAvatar]} />

{index === CONST.REPORT.MAX_PREVIEW_AVATARS - 1 && props.avatarImageURLs.length - CONST.REPORT.MAX_PREVIEW_AVATARS !== 0 && (
<>
<View
style={[
styles.emptyStateAvatar,
styles.screenBlur,
]}
/>
<Text style={styles.avatarInnerTextChat}>
{`+${props.avatarImageURLs.length - CONST.REPORT.MAX_PREVIEW_AVATARS}`}
</Text>
</>
)}
</View>
))}
</View>
</View>
);
};

EmptyStateAvatars.defaultProps = defaultProps;
EmptyStateAvatars.propTypes = propTypes;
MirFahad58 marked this conversation as resolved.
Show resolved Hide resolved
EmptyStateAvatars.displayName = 'EmptyStateAvatars';

export default memo(EmptyStateAvatars);
105 changes: 105 additions & 0 deletions src/components/ReportWelcomeText.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import React from 'react';
import PropTypes from 'prop-types';
import lodashGet from 'lodash/get';
import Str from 'expensify-common/lib/str';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import styles from '../styles/styles';
import Text from './Text';
import withLocalize, {withLocalizePropTypes} from './withLocalize';
import compose from '../libs/compose';
import {getPersonalDetailsForLogins} from '../libs/OptionsListUtils';
import ONYXKEYS from '../ONYXKEYS';


const personalDetailsPropTypes = PropTypes.shape({
/** The login of the person (either email or phone number) */
login: PropTypes.string.isRequired,

/** The URL of the person's avatar (there should already be a default avatar if
the person doesn't have their own avatar uploaded yet) */
avatar: PropTypes.string.isRequired,

/** This is either the user's full name, or their login if full name is an empty string */
displayName: PropTypes.string.isRequired,
});

const propTypes = {
/** Whether it is a default Chat Room */
shouldIncludeParticipants: PropTypes.bool,

/** The report currently being looked at */
report: PropTypes.oneOfType([PropTypes.object]),

/** All of the personal details for everyone */
personalDetails: PropTypes.objectOf(personalDetailsPropTypes).isRequired,

...withLocalizePropTypes,
};

const defaultProps = {
report: {},
shouldIncludeParticipants: true,
};

const ReportWelcomeText = (props) => {
const participants = lodashGet(props.report, 'participants', []);
const isMultipleParticipant = participants.length > 1;
const displayNamesWithTooltips = _.map(
getPersonalDetailsForLogins(participants, props.personalDetails),
({
displayName, firstName, login, pronouns,
}) => {
const longName = displayName || Str.removeSMSDomain(login);
const longNameLocalized = Str.isSMSLogin(longName) ? props.toLocalPhone(longName) : longName;
const shortName = firstName || longNameLocalized;
return {
displayName: isMultipleParticipant ? shortName : longNameLocalized,
tooltip: Str.removeSMSDomain(login),
pronouns,
};
},
);
const chatUsers = props.shouldIncludeParticipants ? displayNamesWithTooltips : [{displayName: props.report.reportName}];

return (
<Text style={[styles.mt3, styles.w70, styles.textAlignCenter]}>
<Text>
{!props.shouldIncludeParticipants
? `${props.translate('reportActionsView.beginningOfChatHistoryPrivatePartOne')}`
: `${props.translate('reportActionsView.beginningOfChatHistory')} `}
</Text>
{!props.shouldIncludeParticipants && <Text style={[styles.textStrong]}>{` ${lodashGet(chatUsers, '[0].displayName', '')}`}</Text>}
{!props.shouldIncludeParticipants && <Text>{props.translate('reportActionsView.beginningOfChatHistoryPrivatePartTwo')}</Text>}
{props.shouldIncludeParticipants
&& (
<>
{_.map(chatUsers, ({displayName, pronouns}, index) => (
<Text key={displayName}>
<Text style={[styles.textStrong]}>
{displayName}
</Text>
{!_.isEmpty(pronouns) && <Text>{` (${pronouns})`}</Text>}
{(index === chatUsers.length - 1) && <Text>.</Text>}
{(index === chatUsers.length - 2) && <Text>{` ${props.translate('common.and')} `}</Text>}
{(index < chatUsers.length - 2) && <Text>, </Text>}
</Text>
))}
</>
)}
</Text>
);
};

ReportWelcomeText.defaultProps = defaultProps;
ReportWelcomeText.propTypes = propTypes;
ReportWelcomeText.displayName = 'ReportWelcomeText';

export default compose(
withLocalize,
withOnyx({
personalDetails: {
key: ONYXKEYS.PERSONAL_DETAILS,
},
}),
)(ReportWelcomeText);
5 changes: 4 additions & 1 deletion src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ export default {
sendAttachment: 'Send attachment',
addAttachment: 'Add attachment',
writeSomething: 'Write something...',
sayHello: 'Say hello!',
blockedFromConcierge: 'Communication is barred',
youAppearToBeOffline: 'You appear to be offline.',
fileUploadFailed: 'Upload failed. File is not supported.',
Expand All @@ -156,7 +157,9 @@ export default {
deleteConfirmation: 'Are you sure you want to delete this comment?',
},
reportActionsView: {
beFirstPersonToComment: 'Be the first person to comment',
beginningOfChatHistory: 'This is the beginning of your chat history with',
beginningOfChatHistoryPrivatePartOne: 'This is the beginning of the private',
beginningOfChatHistoryPrivatePartTwo: ' room, invite others by @mentioning them.',
},
reportActionsViewMarkerBadge: {
newMsg: ({count}) => `${count} new message${count > 1 ? 's' : ''}`,
Expand Down
5 changes: 4 additions & 1 deletion src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ export default {
sendAttachment: 'Enviar adjunto',
addAttachment: 'Agregar archivo adjunto',
writeSomething: 'Escribe algo...',
sayHello: 'Di hola!',
blockedFromConcierge: 'Comunicación no permitida',
youAppearToBeOffline: 'Parece que estás desconectado.',
fileUploadFailed: 'Subida fallida. El archivo no es compatible.',
Expand All @@ -156,7 +157,9 @@ export default {
deleteConfirmation: '¿Estás seguro de que quieres eliminar este comentario?',
},
reportActionsView: {
beFirstPersonToComment: 'Sé el primero en comentar',
beginningOfChatHistory: 'Aquí comienza tu historial de conversaciones con',
beginningOfChatHistoryPrivatePartOne: 'Este es el principio de la sala privada',
beginningOfChatHistoryPrivatePartTwo: ', invita a otros @mencionándolos.',
},
reportActionsViewMarkerBadge: {
newMsg: ({count}) => `${count} mensaje${count > 1 ? 's' : ''} nuevo${count > 1 ? 's' : ''}`,
Expand Down
6 changes: 5 additions & 1 deletion src/pages/home/report/ReportActionCompose.js
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,10 @@ class ReportActionCompose extends React.Component {
return this.props.translate('reportActionCompose.blockedFromConcierge');
}

if (_.size(this.props.reportActions) === 1) {
return this.props.translate('reportActionCompose.sayHello');
}

return this.props.translate('reportActionCompose.writeSomething');
}

Expand Down Expand Up @@ -614,7 +618,7 @@ class ReportActionCompose extends React.Component {
)}
</AttachmentPicker>
<TextInputFocusable
autoFocus={this.shouldFocusInputOnScreenFocus}
autoFocus={this.shouldFocusInputOnScreenFocus || _.size(this.props.reportActions) === 1}
MirFahad58 marked this conversation as resolved.
Show resolved Hide resolved
multiline
ref={this.setTextInputRef}
textAlignVertical="top"
Expand Down
17 changes: 13 additions & 4 deletions src/pages/home/report/ReportActionsView.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {withOnyx} from 'react-native-onyx';
import PropTypes from 'prop-types';
import _ from 'underscore';
import lodashGet from 'lodash/get';
import Text from '../../../components/Text';
import * as Report from '../../../libs/actions/Report';
import ReportActionItem from './ReportActionItem';
import styles from '../../../styles/styles';
Expand All @@ -31,6 +30,9 @@ import PopoverReportActionContextMenu from './ContextMenu/PopoverReportActionCon
import variables from '../../../styles/variables';
import MarkerBadge from './MarkerBadge';
import Performance from '../../../libs/Performance';
import EmptyStateAvatars from '../../../components/EmptyStateAvatars';
import * as ReportUtils from '../../../libs/reportUtils';
import ReportWelcomeText from '../../../components/ReportWelcomeText';
import ONYXKEYS from '../../../ONYXKEYS';

const propTypes = {
Expand Down Expand Up @@ -503,6 +505,8 @@ class ReportActionsView extends React.Component {
}

render() {
const isDefaultChatRoom = ReportUtils.isDefaultRoom(this.props.report);

// Comments have not loaded at all yet do nothing
if (!_.size(this.props.reportActions)) {
return null;
Expand All @@ -512,9 +516,14 @@ class ReportActionsView extends React.Component {
if (_.size(this.props.reportActions) === 1) {
return (
<View style={[styles.chatContent, styles.chatContentEmpty]}>
<Text>
{this.props.translate('reportActionsView.beFirstPersonToComment')}
</Text>
<View style={[styles.justifyContentCenter, styles.alignItemsCenter, styles.flex1]}>
<EmptyStateAvatars
avatarImageURLs={this.props.report.icons}
secondAvatarStyle={[styles.secondAvatarHovered]}
isDefaultChatRoom={isDefaultChatRoom}
/>
<ReportWelcomeText report={this.props.report} shouldIncludeParticipants={!isDefaultChatRoom} />
</View>
</View>
);
}
Expand Down
28 changes: 28 additions & 0 deletions src/styles/styles.js
Original file line number Diff line number Diff line change
Expand Up @@ -1577,6 +1577,34 @@ const styles = {
height: 80,
},

emptyStateAvatar: {
height: variables.componentSizeLarge,
width: variables.componentSizeLarge,
borderRadius: 100,
borderColor: themeColors.componentBG,
borderWidth: 4,
marginLeft: -16,
},

screenBlur: {
position: 'absolute',
top: 0,
right: 0,
bottom: 0,
left: 0,
backgroundColor: colors.dark,
opacity: 0.5,
MirFahad58 marked this conversation as resolved.
Show resolved Hide resolved
},

avatarInnerTextChat: {
color: themeColors.textReversed,
fontSize: variables.fontSizeNormal,
left: 1,
textAlign: 'center',
fontWeight: 'normal',
position: 'absolute',
},

displayName: {
fontSize: variables.fontSizeLarge,
fontFamily: fontFamily.GTA_BOLD,
Expand Down
16 changes: 10 additions & 6 deletions src/styles/utilities/sizing.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,24 @@ export default {
height: '100%',
},

mnh100: {
minHeight: '100%',
w20: {
width: '20%',
},

w100: {
width: '100%',
mnh100: {
minHeight: '100%',
},

w50: {
width: '50%',
},

w20: {
width: '20%',
w70: {
width: '70%',
},

w100: {
width: '100%',
},

mwn: {
Expand Down