Skip to content

Commit

Permalink
feat: new member ui, member list in conversation settings
Browse files Browse the repository at this point in the history
Signed-off-by: clegirar <clemntgirard@gmail.com>
  • Loading branch information
clegirar committed Jul 18, 2022
1 parent 0151795 commit 92a0f62
Show file tree
Hide file tree
Showing 14 changed files with 368 additions and 34 deletions.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 1 addition & 6 deletions js/packages/components/dropdowns/Dropdown.priv.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,12 +123,7 @@ export const DropdownPriv = forwardRef(
</TouchableOpacity>

<Animated.ScrollView
style={[
{
maxHeight: animateHeight,
},
styles.scrollView,
]}
style={[styles.scrollView, { maxHeight: animateHeight }]}
nestedScrollEnabled
showsVerticalScrollIndicator={false}
>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Icon } from '@ui-kitten/components'
import React from 'react'
import { StyleSheet, TouchableOpacity, View } from 'react-native'

import { UnifiedText } from '@berty/components/shared-components/UnifiedText'
import { useStyles } from '@berty/contexts/styles'
import { useThemeColor } from '@berty/hooks'

import { MemberTransport } from './MemberTransport.priv'

// eslint-disable-next-line @typescript-eslint/no-unused-vars
export const AddConversationBoosterButton: React.FC = () => {
const colors = useThemeColor()
const { padding, margin } = useStyles()
return (
<TouchableOpacity style={[padding.medium, styles.container]}>
<View style={[styles.content]}>
<MemberTransport memberStatus='connected' memberTransport='node' />
<UnifiedText style={[margin.left.medium]}>Add a conversation booster</UnifiedText>
</View>
<Icon name='arrow-ios-forward' width={20} height={20} fill={colors['main-text']} />
</TouchableOpacity>
)
}

const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
content: {
flexDirection: 'row',
alignItems: 'center',
},
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React from 'react'
import { View, StyleSheet } from 'react-native'

import { MemberAvatar } from '@berty/components/avatars'
import { Maybe } from '@berty/utils/type/maybe'

import { IMemberStatus } from './interfaces'

interface MemberAvatarWithStatusProps extends IMemberStatus {
publicKey: Maybe<string>
convPK: Maybe<string>
}

const MemberStatus: React.FC<IMemberStatus> = ({ memberStatus }) => {
let backgroundColor
switch (memberStatus) {
case 'connected':
backgroundColor = '#4CD31D'
break
case 'reconnecting':
backgroundColor = '#FF9900'
break
case 'disconnected':
backgroundColor = '#AFAFAF'
break
}

return (
<View style={[styles.container]}>
<View style={[styles.status, { backgroundColor }]} />
</View>
)
}

export const MemberAvatarWithStatus: React.FC<MemberAvatarWithStatusProps> = ({
publicKey,
convPK,
memberStatus,
}) => {
return (
<>
<MemberAvatar publicKey={publicKey} conversationPublicKey={convPK} size={32} />
<MemberStatus memberStatus={memberStatus} />
</>
)
}

const size = 8
const containerSize = size + 4
const styles = StyleSheet.create({
container: {
position: 'relative',
borderRadius: containerSize,
width: containerSize,
height: containerSize,
top: 10,
right: 10,
backgroundColor: '#FFFFFF',
justifyContent: 'center',
},
status: {
borderRadius: size,
width: size,
height: size,
alignSelf: 'center',
},
})
54 changes: 54 additions & 0 deletions js/packages/components/dropdowns/members/MemberName.priv.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Icon } from '@ui-kitten/components'
import React from 'react'
import { StyleSheet, View } from 'react-native'

import { UnifiedText } from '@berty/components/shared-components/UnifiedText'
import { useStyles } from '@berty/contexts/styles'

import { IMemberUserTypes } from './interfaces'

interface MemberNameProps extends IMemberUserTypes {
displayName: string | null | undefined
}

const MemberUserTypes: React.FC<IMemberUserTypes> = ({ memberUserType }) => {
const { margin, text } = useStyles()

let value, icon
switch (memberUserType) {
case 'replication':
value = 'Replication node'
icon = 'server'
break
case 'user':
value = 'User device'
icon = 'message-circle'
break
}

return (
<View style={[styles.container]}>
<Icon name={icon} pack='feather' width={11} fill='#A8A8AA' />
<UnifiedText style={[margin.left.scale(4), text.size.small, styles.text]}>
{value}
</UnifiedText>
</View>
)
}

export const MemberName: React.FC<MemberNameProps> = ({ displayName, memberUserType }) => {
return (
<View>
<UnifiedText>{displayName ?? ''}</UnifiedText>
<MemberUserTypes memberUserType={memberUserType} />
</View>
)
}

const styles = StyleSheet.create({
container: {
flexDirection: 'row',
alignItems: 'center',
},
text: { color: '#A8A8AA', fontFamily: 'Regular Open Sans' },
})
50 changes: 50 additions & 0 deletions js/packages/components/dropdowns/members/MemberTransport.priv.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Icon } from '@ui-kitten/components'
import React from 'react'
import { StyleSheet, View } from 'react-native'

import { useThemeColor } from '@berty/hooks'

import { IMemberStatus, IMemberTransports } from './interfaces'

export const MemberTransport: React.FC<IMemberStatus & IMemberTransports> = ({
memberStatus,
memberTransport,
}) => {
const colors = useThemeColor()

const iconSize = 16
let iconColor
switch (memberStatus) {
case 'connected':
iconColor = colors['background-header']
break
case 'disconnected':
iconColor = '#9E9FA8'
break
case 'reconnecting':
iconColor = '#FF9900'
break
}
return (
<View style={[styles.container]}>
<Icon
pack='custom'
name={`transport-${memberTransport}`}
width={iconSize}
height={iconSize}
fill={iconColor}
/>
</View>
)
}
const containerSize = 28
const styles = StyleSheet.create({
container: {
width: containerSize,
height: containerSize,
borderRadius: containerSize,
backgroundColor: '#E9EAF1',
justifyContent: 'center',
alignItems: 'center',
},
})
77 changes: 62 additions & 15 deletions js/packages/components/dropdowns/members/MembersDropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { pickBy } from 'lodash'
import React from 'react'
import { StyleSheet, TouchableOpacity, View } from 'react-native'

import beapi from '@berty/api'
import { useStyles } from '@berty/contexts/styles'
import { useThemeColor } from '@berty/hooks'

import { MemberAvatar } from '../../avatars'
import { UnifiedText } from '../../shared-components/UnifiedText'
import { DropdownPriv } from '../Dropdown.priv'
import { MemberAvatarWithStatus } from './MemberAvatarWithStatus.priv'
import { MemberName } from './MemberName.priv'
import { MembersDropdownHeader } from './MembersDropdownHeader.priv'
import { MemberTransport } from './MemberTransport.priv'

interface MembersDropdownProps {
items: beapi.messenger.IMember[]
Expand All @@ -18,9 +21,52 @@ interface MembersDropdownProps {
accessibilityLabel?: string
}

interface MemberItemProps {
onPress: () => void
item: beapi.messenger.IMember
convPK: string
}

const MemberItem: React.FC<MemberItemProps> = ({ onPress, convPK, item }) => {
const { padding } = useStyles()

// TODO change it and recup it in redux store
const memberStatus = 'reconnecting'
const memberUserType = 'replication'
const memberTransport = 'wifi'
return (
<TouchableOpacity
onPress={onPress}
style={[styles.item, padding.horizontal.medium]}
key={item.publicKey}
>
<View style={[styles.content]}>
<MemberAvatarWithStatus
publicKey={item.publicKey}
convPK={convPK}
memberStatus={memberStatus}
/>
<MemberName displayName={item.displayName} memberUserType={memberUserType} />
</View>
<MemberTransport memberStatus={memberStatus} memberTransport={memberTransport} />
</TouchableOpacity>
)
}

export const MembersDropdown: React.FC<MembersDropdownProps> = props => {
const { padding, margin, border } = useStyles()
const { border } = useStyles()
const colors = useThemeColor()
const [value, setValue] = React.useState<string>('')

const lowSearchValue = value.toLowerCase()
const searchCheck = React.useCallback(
searchIn => searchIn.toLowerCase().includes(lowSearchValue),
[lowSearchValue],
)
const searchMembers = React.useMemo(
() => (value.length ? pickBy(props.items, val => searchCheck(val.displayName)) : props.items),
[props.items, searchCheck, value],
)

return (
<View
Expand All @@ -35,19 +81,15 @@ export const MembersDropdown: React.FC<MembersDropdownProps> = props => {
placeholder={props.placeholder}
accessibilityLabel={props.accessibilityLabel}
>
{props.items.map(item => (
<TouchableOpacity
<MembersDropdownHeader inputValue={value} setInputValue={setValue} />
{/* TODO: enable it when replication node is up */}
{/* <AddConversationBoosterButton /> */}
{Object.values(searchMembers).map(item => (
<MemberItem
onPress={() => props.onChangeItem(item)}
style={[styles.item, padding.horizontal.medium]}
key={item.publicKey}
>
<MemberAvatar
publicKey={item?.publicKey}
conversationPublicKey={props.publicKey}
size={25}
/>
<UnifiedText style={[margin.left.medium]}>{item.displayName ?? ''}</UnifiedText>
</TouchableOpacity>
convPK={props.publicKey}
item={item}
/>
))}
</DropdownPriv>
</View>
Expand All @@ -68,5 +110,10 @@ const styles = StyleSheet.create({
alignItems: 'center',
paddingVertical: 12,
flex: 1,
justifyContent: 'space-between',
},
content: {
flexDirection: 'row',
alignItems: 'center',
},
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react'
import { View } from 'react-native'

import { SmallClearableInput } from '@berty/components/inputs'
import { useStyles } from '@berty/contexts/styles'

interface MembersDropdownHeaderProps {
inputValue: string
setInputValue: (value: string) => void
}

export const MembersDropdownHeader: React.FC<MembersDropdownHeaderProps> = ({
inputValue,
setInputValue,
}) => {
const { margin } = useStyles()

return (
<View style={[margin.horizontal.medium]}>
<SmallClearableInput
value={inputValue}
onChangeText={setInputValue}
placeholder='Search member'
iconName='search-outline'
/>
</View>
)
}
9 changes: 9 additions & 0 deletions js/packages/components/dropdowns/members/interfaces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export interface IMemberUserTypes {
memberUserType: 'replication' | 'user'
}
export interface IMemberTransports {
memberTransport: 'wifi' | '4g' | 'node' | 'ble' // TODO replace by proto GroupDevicesStatus.Transport enum
}
export interface IMemberStatus {
memberStatus: 'connected' | 'disconnected' | 'reconnecting' // TODO replace by proto GroupDevicesStatus.Type enum
}
1 change: 1 addition & 0 deletions js/packages/components/inputs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export { MediumClearableInput } from './medium/MediumClearableInput'
export { LargeInputWithIcon } from './large/LargeInputWithIcon'
export { LargeInput } from './large/LargeInput'
export { SmallInput } from './small/SmallInput'
export { SmallClearableInput } from './small/SmallClearableInput'
export { ChatTextInput } from './chat/ChatTextInput'

0 comments on commit 92a0f62

Please sign in to comment.