[FIX] Load avatar on servers that prevent unauthenticated avatar access (#604)

App would show an empty space on servers that require authentication on avatar access
This commit is contained in:
David Lougheed 2019-02-07 14:58:20 -05:00 committed by Diego Mello
parent db0cd5abd1
commit e5930cc0fe
13 changed files with 136 additions and 50 deletions

View File

@ -12,7 +12,11 @@ export default class Avatar extends PureComponent {
size: PropTypes.number, size: PropTypes.number,
borderRadius: PropTypes.number, borderRadius: PropTypes.number,
type: PropTypes.string, type: PropTypes.string,
children: PropTypes.object children: PropTypes.object,
user: PropTypes.shape({
id: PropTypes.string,
token: PropTypes.string
})
} }
static defaultProps = { static defaultProps = {
@ -24,7 +28,7 @@ export default class Avatar extends PureComponent {
render() { render() {
const { const {
text, size, baseUrl, borderRadius, style, avatar, type, children text, size, baseUrl, borderRadius, style, avatar, type, children, user
} = this.props; } = this.props;
const avatarStyle = { const avatarStyle = {
@ -38,9 +42,16 @@ export default class Avatar extends PureComponent {
} }
const room = type === 'd' ? text : `@${ text }`; const room = type === 'd' ? text : `@${ text }`;
// Avoid requesting several sizes by having only two sizes on cache // Avoid requesting several sizes by having only two sizes on cache
const uriSize = size === 100 ? 100 : 50; const uriSize = size === 100 ? 100 : 50;
const uri = avatar || `${ baseUrl }/avatar/${ room }?format=png&width=${ uriSize }&height=${ uriSize }`;
let avatarAuthURLFragment = '';
if (user && user.id && user.token) {
avatarAuthURLFragment = `&rc_token=${ user.token }&rc_uid=${ user.id }`;
}
const uri = avatar || `${ baseUrl }/avatar/${ room }?format=png&width=${ uriSize }&height=${ uriSize }${ avatarAuthURLFragment }`;
const image = ( const image = (
<FastImage <FastImage

View File

@ -53,7 +53,11 @@ const imagePickerConfig = {
replying: state.messages.replyMessage && !!state.messages.replyMessage.msg, replying: state.messages.replyMessage && !!state.messages.replyMessage.msg,
editing: state.messages.editing, editing: state.messages.editing,
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '', baseUrl: state.settings.Site_Url || state.server ? state.server.server : '',
username: state.login.user && state.login.user.username user: {
id: state.login.user && state.login.user.id,
username: state.login.user && state.login.user.username,
token: state.login.user && state.login.user.token
}
}), dispatch => ({ }), dispatch => ({
editCancel: () => dispatch(editCancelAction()), editCancel: () => dispatch(editCancelAction()),
editRequest: message => dispatch(editRequestAction(message)), editRequest: message => dispatch(editRequestAction(message)),
@ -68,7 +72,11 @@ export default class MessageBox extends Component {
replyMessage: PropTypes.object, replyMessage: PropTypes.object,
replying: PropTypes.bool, replying: PropTypes.bool,
editing: PropTypes.bool, editing: PropTypes.bool,
username: PropTypes.string, user: PropTypes.shape({
id: PropTypes.string,
username: PropTypes.string,
token: PropTypes.string
}),
roomType: PropTypes.string, roomType: PropTypes.string,
editCancel: PropTypes.func.isRequired, editCancel: PropTypes.func.isRequired,
editRequest: PropTypes.func.isRequired, editRequest: PropTypes.func.isRequired,
@ -529,13 +537,13 @@ export default class MessageBox extends Component {
editRequest({ _id, msg: message, rid }); editRequest({ _id, msg: message, rid });
} else if (replying) { } else if (replying) {
const { const {
username, replyMessage, roomType, closeReply user, replyMessage, roomType, closeReply
} = this.props; } = this.props;
const permalink = await this.getPermalink(replyMessage); const permalink = await this.getPermalink(replyMessage);
let msg = `[ ](${ permalink }) `; let msg = `[ ](${ permalink }) `;
// if original message wasn't sent by current user and neither from a direct room // if original message wasn't sent by current user and neither from a direct room
if (username !== replyMessage.u.username && roomType !== 'd' && replyMessage.mention) { if (user.username !== replyMessage.u.username && roomType !== 'd' && replyMessage.mention) {
msg += `@${ replyMessage.u.username } `; msg += `@${ replyMessage.u.username } `;
} }
@ -617,7 +625,7 @@ export default class MessageBox extends Component {
renderMentionItem = (item) => { renderMentionItem = (item) => {
const { trackingType } = this.state; const { trackingType } = this.state;
const { baseUrl } = this.props; const { baseUrl, user } = this.props;
if (item.username === 'all' || item.username === 'here') { if (item.username === 'all' || item.username === 'here') {
return this.renderFixedMentionItem(item); return this.renderFixedMentionItem(item);
@ -641,6 +649,7 @@ export default class MessageBox extends Component {
size={30} size={30}
type={item.username ? 'd' : 'c'} type={item.username ? 'd' : 'c'}
baseUrl={baseUrl} baseUrl={baseUrl}
user={user}
/>, />,
<Text key='mention-item-name'>{ item.username || item.name }</Text> <Text key='mention-item-name'>{ item.username || item.name }</Text>
] ]
@ -669,12 +678,12 @@ export default class MessageBox extends Component {
renderReplyPreview = () => { renderReplyPreview = () => {
const { const {
replyMessage, replying, closeReply, username replyMessage, replying, closeReply, user
} = this.props; } = this.props;
if (!replying) { if (!replying) {
return null; return null;
} }
return <ReplyPreview key='reply-preview' message={replyMessage} close={closeReply} username={username} />; return <ReplyPreview key='reply-preview' message={replyMessage} close={closeReply} username={user.username} />;
}; };
renderFilesActions = () => { renderFilesActions = () => {

View File

@ -174,7 +174,7 @@ export default class Message extends PureComponent {
renderAvatar = () => { renderAvatar = () => {
const { const {
header, avatar, author, baseUrl header, avatar, author, baseUrl, user
} = this.props; } = this.props;
if (header) { if (header) {
return ( return (
@ -185,6 +185,7 @@ export default class Message extends PureComponent {
borderRadius={4} borderRadius={4}
avatar={avatar} avatar={avatar}
baseUrl={baseUrl} baseUrl={baseUrl}
user={user}
/> />
); );
} }

View File

@ -125,7 +125,11 @@ const renderNumber = (unread, userMentions) => {
const attrs = ['name', 'unread', 'userMentions', 'alert', 'showLastMessage', 'type']; const attrs = ['name', 'unread', 'userMentions', 'alert', 'showLastMessage', 'type'];
@connect(state => ({ @connect(state => ({
username: state.login.user && state.login.user.username, user: {
id: state.login.user && state.login.user.id,
username: state.login.user && state.login.user.username,
token: state.login.user && state.login.user.token
},
StoreLastMessage: state.settings.Store_Last_Message, StoreLastMessage: state.settings.Store_Last_Message,
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '' baseUrl: state.settings.Site_Url || state.server ? state.server.server : ''
})) }))
@ -144,7 +148,11 @@ export default class RoomItem extends React.Component {
userMentions: PropTypes.number, userMentions: PropTypes.number,
id: PropTypes.string, id: PropTypes.string,
onPress: PropTypes.func, onPress: PropTypes.func,
username: PropTypes.string, user: PropTypes.shape({
id: PropTypes.string,
username: PropTypes.string,
token: PropTypes.string
}),
avatarSize: PropTypes.number, avatarSize: PropTypes.number,
testID: PropTypes.string, testID: PropTypes.string,
height: PropTypes.number height: PropTypes.number
@ -172,14 +180,14 @@ export default class RoomItem extends React.Component {
get avatar() { get avatar() {
const { const {
type, name, avatarSize, baseUrl type, name, avatarSize, baseUrl, user
} = this.props; } = this.props;
return <Avatar text={name} size={avatarSize} type={type} baseUrl={baseUrl} style={{ marginHorizontal: 15 }} />; return <Avatar text={name} size={avatarSize} type={type} baseUrl={baseUrl} style={{ marginHorizontal: 15 }} user={user} />;
} }
get lastMessage() { get lastMessage() {
const { const {
lastMessage, type, showLastMessage, StoreLastMessage, username lastMessage, type, showLastMessage, StoreLastMessage, user
} = this.props; } = this.props;
if (!StoreLastMessage || !showLastMessage) { if (!StoreLastMessage || !showLastMessage) {
@ -190,7 +198,7 @@ export default class RoomItem extends React.Component {
} }
let prefix = ''; let prefix = '';
const me = lastMessage.u.username === username; const me = lastMessage.u.username === user.username;
if (!lastMessage.msg && Object.keys(lastMessage.attachments).length > 0) { if (!lastMessage.msg && Object.keys(lastMessage.attachments).length > 0) {
if (me) { if (me) {

View File

@ -45,11 +45,11 @@ const styles = StyleSheet.create({
}); });
const UserItem = ({ const UserItem = ({
name, username, onPress, testID, onLongPress, style, icon, baseUrl name, username, onPress, testID, onLongPress, style, icon, baseUrl, user
}) => ( }) => (
<Touch onPress={onPress} onLongPress={onLongPress} style={styles.button} testID={testID}> <Touch onPress={onPress} onLongPress={onLongPress} style={styles.button} testID={testID}>
<View style={[styles.container, style]}> <View style={[styles.container, style]}>
<Avatar text={username} size={30} type='d' style={styles.avatar} baseUrl={baseUrl} /> <Avatar text={username} size={30} type='d' style={styles.avatar} baseUrl={baseUrl} user={user} />
<View style={styles.textContainer}> <View style={styles.textContainer}>
<Text style={styles.name}>{name}</Text> <Text style={styles.name}>{name}</Text>
<Text style={styles.username}>@{username}</Text> <Text style={styles.username}>@{username}</Text>
@ -62,6 +62,10 @@ const UserItem = ({
UserItem.propTypes = { UserItem.propTypes = {
name: PropTypes.string.isRequired, name: PropTypes.string.isRequired,
username: PropTypes.string.isRequired, username: PropTypes.string.isRequired,
user: PropTypes.shape({
id: PropTypes.string,
token: PropTypes.string
}),
baseUrl: PropTypes.string.isRequired, baseUrl: PropTypes.string.isRequired,
onPress: PropTypes.func.isRequired, onPress: PropTypes.func.isRequired,
testID: PropTypes.string.isRequired, testID: PropTypes.string.isRequired,

View File

@ -80,7 +80,11 @@ const styles = StyleSheet.create({
failure: state.createChannel.failure, failure: state.createChannel.failure,
isFetching: state.createChannel.isFetching, isFetching: state.createChannel.isFetching,
result: state.createChannel.result, result: state.createChannel.result,
users: state.selectedUsers.users users: state.selectedUsers.users,
user: {
id: state.login.user && state.login.user.id,
token: state.login.user && state.login.user.token
}
}), dispatch => ({ }), dispatch => ({
create: data => dispatch(createChannelRequestAction(data)), create: data => dispatch(createChannelRequestAction(data)),
removeUser: user => dispatch(removeUserAction(user)) removeUser: user => dispatch(removeUserAction(user))
@ -106,7 +110,11 @@ export default class CreateChannelView extends LoggedView {
failure: PropTypes.bool, failure: PropTypes.bool,
isFetching: PropTypes.bool, isFetching: PropTypes.bool,
result: PropTypes.object, result: PropTypes.object,
users: PropTypes.array.isRequired users: PropTypes.array.isRequired,
user: PropTypes.shape({
id: PropTypes.string,
token: PropTypes.string
})
}; };
constructor(props) { constructor(props) {
@ -305,7 +313,7 @@ export default class CreateChannelView extends LoggedView {
renderFormSeparator = () => <View style={[sharedStyles.separator, styles.formSeparator]} /> renderFormSeparator = () => <View style={[sharedStyles.separator, styles.formSeparator]} />
renderItem = ({ item }) => { renderItem = ({ item }) => {
const { baseUrl } = this.props; const { baseUrl, user } = this.props;
return ( return (
<UserItem <UserItem
@ -314,6 +322,7 @@ export default class CreateChannelView extends LoggedView {
onPress={() => this.removeUser(item)} onPress={() => this.removeUser(item)}
testID={`create-channel-view-item-${ item.name }`} testID={`create-channel-view-item-${ item.name }`}
baseUrl={baseUrl} baseUrl={baseUrl}
user={user}
/> />
); );
} }

View File

@ -49,7 +49,11 @@ const styles = StyleSheet.create({
}); });
@connect(state => ({ @connect(state => ({
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '' baseUrl: state.settings.Site_Url || state.server ? state.server.server : '',
user: {
id: state.login.user && state.login.user.id,
token: state.login.user && state.login.user.token
}
})) }))
/** @extends React.Component */ /** @extends React.Component */
export default class NewMessageView extends LoggedView { export default class NewMessageView extends LoggedView {
@ -68,7 +72,11 @@ export default class NewMessageView extends LoggedView {
static propTypes = { static propTypes = {
componentId: PropTypes.string, componentId: PropTypes.string,
baseUrl: PropTypes.string, baseUrl: PropTypes.string,
onPressItem: PropTypes.func.isRequired onPressItem: PropTypes.func.isRequired,
user: PropTypes.shape({
id: PropTypes.string,
token: PropTypes.string
})
}; };
constructor(props) { constructor(props) {
@ -162,7 +170,7 @@ export default class NewMessageView extends LoggedView {
renderItem = ({ item, index }) => { renderItem = ({ item, index }) => {
const { search } = this.state; const { search } = this.state;
const { baseUrl } = this.props; const { baseUrl, user } = this.props;
let style = {}; let style = {};
if (index === 0) { if (index === 0) {
@ -182,6 +190,7 @@ export default class NewMessageView extends LoggedView {
baseUrl={baseUrl} baseUrl={baseUrl}
testID={`new-message-view-item-${ item.name }`} testID={`new-message-view-item-${ item.name }`}
style={style} style={style}
user={user}
/> />
); );
} }

View File

@ -36,7 +36,8 @@ import Icons from '../../lib/Icons';
name: state.login.user && state.login.user.name, name: state.login.user && state.login.user.name,
username: state.login.user && state.login.user.username, username: state.login.user && state.login.user.username,
customFields: state.login.user && state.login.user.customFields, customFields: state.login.user && state.login.user.customFields,
emails: state.login.user && state.login.user.emails emails: state.login.user && state.login.user.emails,
token: state.login.user && state.login.user.token
}, },
Accounts_CustomFields: state.settings.Accounts_CustomFields, Accounts_CustomFields: state.settings.Accounts_CustomFields,
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '' baseUrl: state.settings.Site_Url || state.server ? state.server.server : ''
@ -326,7 +327,7 @@ export default class ProfileView extends LoggedView {
return ( return (
<View style={styles.avatarButtons}> <View style={styles.avatarButtons}>
{this.renderAvatarButton({ {this.renderAvatarButton({
child: <Avatar text={`@${ user.username }`} size={50} baseUrl={baseUrl} />, child: <Avatar text={`@${ user.username }`} size={50} baseUrl={baseUrl} user={user} />,
onPress: () => this.resetAvatar(), onPress: () => this.resetAvatar(),
key: 'profile-view-reset-avatar' key: 'profile-view-reset-avatar'
})} })}
@ -345,7 +346,7 @@ export default class ProfileView extends LoggedView {
const { url, blob, contentType } = avatarSuggestions[service]; const { url, blob, contentType } = avatarSuggestions[service];
return this.renderAvatarButton({ return this.renderAvatarButton({
key: `profile-view-avatar-${ service }`, key: `profile-view-avatar-${ service }`,
child: <Avatar avatar={url} size={50} baseUrl={baseUrl} />, child: <Avatar avatar={url} size={50} baseUrl={baseUrl} user={user} />,
onPress: () => this.setAvatar({ onPress: () => this.setAvatar({
url, data: blob, service, contentType url, data: blob, service, contentType
}) })
@ -419,7 +420,7 @@ export default class ProfileView extends LoggedView {
const { const {
name, username, email, newPassword, avatarUrl, customFields, avatar, saving, showPasswordAlert name, username, email, newPassword, avatarUrl, customFields, avatar, saving, showPasswordAlert
} = this.state; } = this.state;
const { baseUrl } = this.props; const { baseUrl, user } = this.props;
return ( return (
<KeyboardView <KeyboardView
@ -438,6 +439,7 @@ export default class ProfileView extends LoggedView {
avatar={avatar && avatar.url} avatar={avatar && avatar.url}
size={100} size={100}
baseUrl={baseUrl} baseUrl={baseUrl}
user={user}
/> />
</View> </View>
<RCTextInput <RCTextInput

View File

@ -27,8 +27,10 @@ import scrollPersistTaps from '../../utils/scrollPersistTaps';
const renderSeparator = () => <View style={styles.separator} />; const renderSeparator = () => <View style={styles.separator} />;
@connect(state => ({ @connect(state => ({
userId: state.login.user && state.login.user.id, user: {
username: state.login.user && state.login.user.username, id: state.login.user && state.login.user.id,
token: state.login.user && state.login.user.token
},
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '', baseUrl: state.settings.Site_Url || state.server ? state.server.server : '',
room: state.room room: state.room
}), dispatch => ({ }), dispatch => ({
@ -50,8 +52,10 @@ export default class RoomActionsView extends LoggedView {
baseUrl: PropTypes.string, baseUrl: PropTypes.string,
rid: PropTypes.string, rid: PropTypes.string,
componentId: PropTypes.string, componentId: PropTypes.string,
userId: PropTypes.string, user: PropTypes.shape({
username: PropTypes.string, id: PropTypes.string,
token: PropTypes.string
}),
room: PropTypes.object, room: PropTypes.object,
leaveRoom: PropTypes.func leaveRoom: PropTypes.func
} }
@ -333,10 +337,10 @@ export default class RoomActionsView extends LoggedView {
updateRoomMember = async() => { updateRoomMember = async() => {
const { room } = this.state; const { room } = this.state;
const { rid } = room; const { rid } = room;
const { userId } = this.props; const { user } = this.props;
try { try {
const member = await RocketChat.getRoomMember(rid, userId); const member = await RocketChat.getRoomMember(rid, user.id);
this.setState({ member: member || {} }); this.setState({ member: member || {} });
} catch (e) { } catch (e) {
log('RoomActions updateRoomMember', e); log('RoomActions updateRoomMember', e);
@ -391,7 +395,7 @@ export default class RoomActionsView extends LoggedView {
renderRoomInfo = ({ item }) => { renderRoomInfo = ({ item }) => {
const { room, member } = this.state; const { room, member } = this.state;
const { name, t, topic } = room; const { name, t, topic } = room;
const { baseUrl } = this.props; const { baseUrl, user } = this.props;
return ( return (
this.renderTouchableItem([ this.renderTouchableItem([
@ -402,6 +406,7 @@ export default class RoomActionsView extends LoggedView {
style={styles.avatar} style={styles.avatar}
type={t} type={t}
baseUrl={baseUrl} baseUrl={baseUrl}
user={user}
> >
{t === 'd' ? <Status style={sharedStyles.status} id={member._id} /> : null } {t === 'd' ? <Status style={sharedStyles.status} id={member._id} /> : null }
</Avatar>, </Avatar>,

View File

@ -34,7 +34,10 @@ const getRoomTitle = room => (room.t === 'd'
@connect(state => ({ @connect(state => ({
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '', baseUrl: state.settings.Site_Url || state.server ? state.server.server : '',
userId: state.login.user && state.login.user.id, user: {
id: state.login.user && state.login.user.id,
token: state.login.user && state.login.user.token
},
activeUsers: state.activeUsers, // TODO: remove it activeUsers: state.activeUsers, // TODO: remove it
Message_TimeFormat: state.settings.Message_TimeFormat, Message_TimeFormat: state.settings.Message_TimeFormat,
allRoles: state.roles, allRoles: state.roles,
@ -55,7 +58,10 @@ export default class RoomInfoView extends LoggedView {
static propTypes = { static propTypes = {
componentId: PropTypes.string, componentId: PropTypes.string,
rid: PropTypes.string, rid: PropTypes.string,
userId: PropTypes.string, user: PropTypes.shape({
id: PropTypes.string,
token: PropTypes.string
}),
baseUrl: PropTypes.string, baseUrl: PropTypes.string,
activeUsers: PropTypes.object, activeUsers: PropTypes.object,
Message_TimeFormat: PropTypes.string, Message_TimeFormat: PropTypes.string,
@ -105,8 +111,8 @@ export default class RoomInfoView extends LoggedView {
if (room) { if (room) {
if (room.t === 'd') { if (room.t === 'd') {
try { try {
const { userId, activeUsers } = this.props; const { user, activeUsers } = this.props;
const roomUser = await RocketChat.getRoomMember(room.rid, userId); const roomUser = await RocketChat.getRoomMember(room.rid, user.id);
this.setState({ roomUser: roomUser || {} }); this.setState({ roomUser: roomUser || {} });
const username = room.name; const username = room.name;
@ -120,7 +126,7 @@ export default class RoomInfoView extends LoggedView {
// get all users roles // get all users roles
// needs to be changed by a better method // needs to be changed by a better method
const allUsersRoles = await RocketChat.getUserRoles(); const allUsersRoles = await RocketChat.getUserRoles();
const userRoles = allUsersRoles.find(user => user.username === username); const userRoles = allUsersRoles.find(u => u.username === username);
if (userRoles) { if (userRoles) {
this.setState({ roles: userRoles.roles || [] }); this.setState({ roles: userRoles.roles || [] });
} }
@ -246,7 +252,7 @@ export default class RoomInfoView extends LoggedView {
} }
renderAvatar = (room, roomUser) => { renderAvatar = (room, roomUser) => {
const { baseUrl } = this.props; const { baseUrl, user } = this.props;
return ( return (
<Avatar <Avatar
@ -255,6 +261,7 @@ export default class RoomInfoView extends LoggedView {
style={styles.avatar} style={styles.avatar}
type={room.t} type={room.t}
baseUrl={baseUrl} baseUrl={baseUrl}
user={user}
> >
{room.t === 'd' ? <Status style={[sharedStyles.status, styles.status]} id={roomUser._id} /> : null} {room.t === 'd' ? <Status style={[sharedStyles.status, styles.status]} id={roomUser._id} /> : null}
</Avatar> </Avatar>

View File

@ -23,7 +23,11 @@ import SearchBox from '../../containers/SearchBox';
@connect(state => ({ @connect(state => ({
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '', baseUrl: state.settings.Site_Url || state.server ? state.server.server : '',
room: state.room room: state.room,
user: {
id: state.login.user && state.login.user.id,
token: state.login.user && state.login.user.token
}
})) }))
/** @extends React.Component */ /** @extends React.Component */
export default class RoomMembersView extends LoggedView { export default class RoomMembersView extends LoggedView {
@ -48,7 +52,11 @@ export default class RoomMembersView extends LoggedView {
rid: PropTypes.string, rid: PropTypes.string,
members: PropTypes.array, members: PropTypes.array,
baseUrl: PropTypes.string, baseUrl: PropTypes.string,
room: PropTypes.object room: PropTypes.object,
user: PropTypes.shape({
id: PropTypes.string,
token: PropTypes.string
})
} }
constructor(props) { constructor(props) {
@ -243,7 +251,7 @@ export default class RoomMembersView extends LoggedView {
renderSeparator = () => <View style={styles.separator} />; renderSeparator = () => <View style={styles.separator} />;
renderItem = ({ item }) => { renderItem = ({ item }) => {
const { baseUrl } = this.props; const { baseUrl, user } = this.props;
return ( return (
<UserItem <UserItem
@ -253,6 +261,7 @@ export default class RoomMembersView extends LoggedView {
onLongPress={() => this.onLongPressUser(item)} onLongPress={() => this.onLongPressUser(item)}
baseUrl={baseUrl} baseUrl={baseUrl}
testID={`room-members-view-item-${ item.username }`} testID={`room-members-view-item-${ item.username }`}
user={user}
/> />
); );
} }

View File

@ -39,7 +39,11 @@ const styles = StyleSheet.create({
@connect(state => ({ @connect(state => ({
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '', baseUrl: state.settings.Site_Url || state.server ? state.server.server : '',
users: state.selectedUsers.users, users: state.selectedUsers.users,
loading: state.selectedUsers.loading loading: state.selectedUsers.loading,
user: {
id: state.login.user && state.login.user.id,
token: state.login.user && state.login.user.token
}
}), dispatch => ({ }), dispatch => ({
addUser: user => dispatch(addUserAction(user)), addUser: user => dispatch(addUserAction(user)),
removeUser: user => dispatch(removeUserAction(user)), removeUser: user => dispatch(removeUserAction(user)),
@ -58,7 +62,11 @@ export default class SelectedUsersView extends LoggedView {
reset: PropTypes.func.isRequired, reset: PropTypes.func.isRequired,
users: PropTypes.array, users: PropTypes.array,
loading: PropTypes.bool, loading: PropTypes.bool,
setLoadingInvite: PropTypes.func setLoadingInvite: PropTypes.func,
user: PropTypes.shape({
id: PropTypes.string,
token: PropTypes.string
})
}; };
constructor(props) { constructor(props) {
@ -209,7 +217,7 @@ export default class SelectedUsersView extends LoggedView {
} }
renderSelectedItem = ({ item }) => { renderSelectedItem = ({ item }) => {
const { baseUrl } = this.props; const { baseUrl, user } = this.props;
return ( return (
<UserItem <UserItem
name={item.fname} name={item.fname}
@ -218,6 +226,7 @@ export default class SelectedUsersView extends LoggedView {
testID={`selected-user-${ item.name }`} testID={`selected-user-${ item.name }`}
baseUrl={baseUrl} baseUrl={baseUrl}
style={{ paddingRight: 15 }} style={{ paddingRight: 15 }}
user={user}
/> />
); );
} }
@ -226,7 +235,7 @@ export default class SelectedUsersView extends LoggedView {
renderItem = ({ item, index }) => { renderItem = ({ item, index }) => {
const { search } = this.state; const { search } = this.state;
const { baseUrl } = this.props; const { baseUrl, user } = this.props;
const name = item.search ? item.name : item.fname; const name = item.search ? item.name : item.fname;
const username = item.search ? item.username : item.name; const username = item.search ? item.username : item.name;
@ -249,6 +258,7 @@ export default class SelectedUsersView extends LoggedView {
icon={this.isChecked(username) ? 'check' : null} icon={this.isChecked(username) ? 'check' : null}
baseUrl={baseUrl} baseUrl={baseUrl}
style={style} style={style}
user={user}
/> />
); );
} }

View File

@ -90,7 +90,8 @@ const keyExtractor = item => item.id;
id: state.login.user && state.login.user.id, id: state.login.user && state.login.user.id,
language: state.login.user && state.login.user.language, language: state.login.user && state.login.user.language,
status: state.login.user && state.login.user.status, status: state.login.user && state.login.user.status,
username: state.login.user && state.login.user.username username: state.login.user && state.login.user.username,
token: state.login.user && state.login.user.token
}, },
baseUrl: state.settings.Site_Url || state.server ? state.server.server : '' baseUrl: state.settings.Site_Url || state.server ? state.server.server : ''
}), dispatch => ({ }), dispatch => ({
@ -340,6 +341,7 @@ export default class Sidebar extends Component {
size={30} size={30}
style={styles.avatar} style={styles.avatar}
baseUrl={baseUrl} baseUrl={baseUrl}
user={user}
/> />
<View style={styles.headerTextContainer}> <View style={styles.headerTextContainer}>
<View style={styles.headerUsername}> <View style={styles.headerUsername}>