diff --git a/app/constants/colors.ts b/app/constants/colors.ts index b28416b86cc..5b93cd924b1 100644 --- a/app/constants/colors.ts +++ b/app/constants/colors.ts @@ -65,6 +65,8 @@ export const themes: any = { previewBackground: '#1F2329', previewTintColor: '#ffffff', backdropOpacity: 0.3, + chevronActive: '#0C0D0F', + chevronInactive: '#CBCED1', attachmentLoadingOpacity: 0.7, ...mentions }, @@ -112,6 +114,8 @@ export const themes: any = { passcodeDotFull: '#6C727A', previewBackground: '#030b1b', previewTintColor: '#ffffff', + chevronActive: '#ffffff', + chevronInactive: '#414850', backdropOpacity: 0.9, attachmentLoadingOpacity: 0.3, ...mentions @@ -160,6 +164,8 @@ export const themes: any = { passcodeDotFull: '#6C727A', previewBackground: '#000000', previewTintColor: '#ffffff', + chevronActive: '#ffffff', + chevronInactive: '#414850', backdropOpacity: 0.9, attachmentLoadingOpacity: 0.3, ...mentions diff --git a/app/presentation/DirectoryItem/index.tsx b/app/presentation/DirectoryItem/index.tsx index 234c1e3123c..01050ae8fec 100644 --- a/app/presentation/DirectoryItem/index.tsx +++ b/app/presentation/DirectoryItem/index.tsx @@ -25,6 +25,7 @@ interface IDirectoryItem { rightLabel?: string; rid?: string; theme: string; + featured?: boolean; teamMain?: boolean; } @@ -46,6 +47,7 @@ const DirectoryItem = ({ type, rid, theme, + featured = false, teamMain }: IDirectoryItem): JSX.Element => ( @@ -57,6 +59,11 @@ const DirectoryItem = ({ {title} + {featured && ( + + Featured + + )} {description ? ( diff --git a/app/presentation/DirectoryItem/styles.ts b/app/presentation/DirectoryItem/styles.ts index 55fa36c47c9..a178b3e6dfe 100644 --- a/app/presentation/DirectoryItem/styles.ts +++ b/app/presentation/DirectoryItem/styles.ts @@ -40,5 +40,10 @@ export default StyleSheet.create({ fontSize: 14, paddingLeft: 10, ...sharedStyles.textRegular + }, + featured: { + borderRadius: 2, + paddingVertical: 1, + paddingHorizontal: 2 } }); diff --git a/app/views/DirectoryView/Options.tsx b/app/views/DirectoryView/Options.tsx index 11206806191..4172e5615b1 100644 --- a/app/views/DirectoryView/Options.tsx +++ b/app/views/DirectoryView/Options.tsx @@ -50,6 +50,10 @@ export default class DirectoryOptions extends PureComponent { const { changeType, type: propType, theme } = this.props; + const handleChangeType = () => { + changeType(itemType); + this.close(); + }; let text = 'Users'; let icon = 'user'; if (itemType === 'channels') { @@ -63,11 +67,7 @@ export default class DirectoryOptions extends PureComponent changeType(itemType)} - style={styles.dropdownItemButton} - theme={theme} - accessibilityLabel={I18n.t(text)}> + {I18n.t(text)} diff --git a/app/views/DirectoryView/index.tsx b/app/views/DirectoryView/index.tsx index 2213497bee8..640bf65b3af 100644 --- a/app/views/DirectoryView/index.tsx +++ b/app/views/DirectoryView/index.tsx @@ -51,6 +51,7 @@ class DirectoryView extends React.Component { constructor(props: IDirectoryViewProps) { super(props); + console.log(props); this.state = { data: [], loading: false, @@ -58,6 +59,10 @@ class DirectoryView extends React.Component { total: -1, showOptionsDropdown: false, globalUsers: true, + sortBy: 'usersCount', + sortDirection: -1, + headerType: 'name', + statsType: 'Users', type: props.directoryDefaultView }; } @@ -89,13 +94,13 @@ class DirectoryView extends React.Component { this.setState({ loading: true }); try { - const { data, type, globalUsers } = this.state; + const { data, type, globalUsers, sortBy, sortDirection } = this.state; const query = { text, type, workspace: globalUsers ? 'all' : 'local' }; const directories = await RocketChat.getDirectory({ query, offset: data.length, count: 50, - sort: type === 'users' ? { username: 1 } : { usersCount: -1 } + sort: { [sortBy]: sortDirection } }); if (directories.success) { this.setState({ @@ -121,10 +126,13 @@ class DirectoryView extends React.Component { if (type === 'users') { logEvent(events.DIRECTORY_SEARCH_USERS); + this.setState({ headerType: 'username', statsType: 'Joined at', sortBy: 'username', sortDirection: 1 }); } else if (type === 'channels') { logEvent(events.DIRECTORY_SEARCH_CHANNELS); + this.setState({ headerType: 'name', statsType: 'Users', sortBy: 'usersCount', sortDirection: -1 }); } else if (type === 'teams') { logEvent(events.DIRECTORY_SEARCH_TEAMS); + this.setState({ headerType: 'name', statsType: 'Channels', sortBy: 'name', sortDirection: 1 }); } }; @@ -177,8 +185,34 @@ class DirectoryView extends React.Component { } }; + handleSort = (type: string) => { + const { sortBy, sortDirection } = this.state; + if (type === 'Users') { + type = 'usersCount'; + } else if (type === 'Channels') { + return; + } + if (type === sortBy) { + this.setState({ sortDirection: -sortDirection }, () => this.search()); + return; + } + this.setState({ sortBy: type, sortDirection: 1 }, () => this.search()); + }; + + getChevronColor = (type: string, chevronType: number, theme: string) => { + const { sortBy, sortDirection } = this.state; + if ( + (type === 'Users' && sortBy === 'usersCount') || + (type === 'name' && sortBy === 'name') || + (type === 'username' && sortBy === 'username') + ) { + return chevronType === sortDirection ? themes[theme].chevronActive : themes[theme].chevronInactive; + } + return themes[theme].chevronInactive; + }; + renderHeader = () => { - const { type } = this.state; + const { type, headerType, statsType } = this.state; const { theme } = this.props; let text = 'Users'; let icon = 'user'; @@ -212,6 +246,47 @@ class DirectoryView extends React.Component { /> + + this.handleSort(headerType)} style={[styles.headingText]} theme={theme}> + {I18n.t('Name')} + + + + + + + {type !== 'users' && ( + this.handleSort(statsType)} style={[styles.headingStats]} theme={theme}> + {I18n.t(statsType)} + {type === 'channels' && ( + + + + + )} + + )} + ); }; @@ -219,7 +294,6 @@ class DirectoryView extends React.Component { renderItem = ({ item, index }: any) => { const { data, type } = this.state; const { baseUrl, user, theme } = this.props; - let style; if (index === data.length - 1) { style = { @@ -259,6 +333,7 @@ class DirectoryView extends React.Component { rightLabel={I18n.t('N_channels', { n: item.roomsCount })} type={item.t} teamMain={item.teamMain} + featured={item.featured} {...commonProps} /> ); @@ -269,6 +344,7 @@ class DirectoryView extends React.Component { description={item.topic} rightLabel={I18n.t('N_users', { n: item.usersCount })} type={item.t} + featured={item.featured} {...commonProps} /> ); diff --git a/app/views/DirectoryView/styles.ts b/app/views/DirectoryView/styles.ts index 543e6babba8..2c516fc800d 100644 --- a/app/views/DirectoryView/styles.ts +++ b/app/views/DirectoryView/styles.ts @@ -12,6 +12,32 @@ export default StyleSheet.create({ separator: { marginLeft: 60 }, + headingContainer: { + flex: 1, + flexDirection: 'row', + justifyContent: 'space-between', + paddingVertical: 6 + }, + headingText: { + flexDirection: 'row', + alignItems: 'flex-end', + marginLeft: 60 + }, + headingStats: { + flexDirection: 'row', + alignItems: 'flex-end', + marginRight: 18 + }, + sortIcons: { + marginLeft: 2 + }, + chevronUp: { + position: 'absolute', + bottom: 7 + }, + chevronDown: { + bottom: 0 + }, toggleDropdownContainer: { height: 46, flexDirection: 'row',