Skip to content

Commit

Permalink
feat: conversation mark as read
Browse files Browse the repository at this point in the history
Signed-off-by: Godefroy Ponsinet <godefroy.ponsinet@outlook.com>
  • Loading branch information
90dy committed Dec 11, 2018
1 parent d087adc commit 78756c5
Show file tree
Hide file tree
Showing 24 changed files with 996 additions and 177 deletions.
113 changes: 78 additions & 35 deletions client/react-native/common/components/Library/PublicKeyWithActions.js
@@ -1,12 +1,20 @@
import { ScrollView, TextInput, Platform, Clipboard, TouchableNativeFeedback, TouchableOpacity } from 'react-native'
import {
ScrollView,
TextInput,
Platform,
Clipboard,
TouchableNativeFeedback,
TouchableOpacity,
} from 'react-native'
import { btoa } from 'b64-lite'
import React, { PureComponent } from 'react'

import { Button, Flex, TextInputMultilineFix, Text } from './index'
import { RelayContext } from '../../relay'
import { colors } from '../../constants'
import {
extractPublicKeyFromId, makeShareableUrl,
extractPublicKeyFromId,
makeShareableUrl,
shareLinkOther,
shareLinkSelf,
} from '../../helpers/contacts'
Expand Down Expand Up @@ -133,22 +141,37 @@ export default class PublicKeyWithActions extends PureComponent {
}

const modeButtons = [
{ element: () => <Text icon={'edit'} big color={mode === 'key' ? colors.white : colors.grey1} /> },
{
element: () => <Text icon={'material-qrcode-scan'} big
color={mode === 'qrcode' ? colors.white : colors.grey1} />,
element: () => (
<Text
icon={'edit'}
big
color={mode === 'key' ? colors.white : colors.grey1}
/>
),
},
{
element: () => (
<Text
icon={'material-qrcode-scan'}
big
color={mode === 'qrcode' ? colors.white : colors.grey1}
/>
),
},
]

return (
<ScrollView>
<Flex.Rows style={[padding]} align='center'>
<Flex.Cols style={{ width: 330 }}>
{mode === 'key' || (readOnly)
? <TextInput
{mode === 'key' || readOnly ? (
<TextInput
placeholder={'Contact name (optional)'}
onChangeText={displayName =>
this.setState({ contact: { ...this.state.contact, displayName } })
this.setState({
contact: { ...this.state.contact, displayName },
})
}
value={displayName}
style={[
Expand All @@ -163,22 +186,29 @@ export default class PublicKeyWithActions extends PureComponent {
rounded,
]}
/>
: <Text style={{ flex: 1 }}>{' '}</Text>
}
) : (
<Text style={{ flex: 1 }} />
)}
{/* TODO: Use a lighter button group impl? */}
<ThemeProvider theme={{ colors: { primary: colors.blue } }}>
<ButtonGroup
onPress={() => this.setState({ mode: mode === 'key' ? 'qrcode' : 'key' })}
onPress={() =>
this.setState({ mode: mode === 'key' ? 'qrcode' : 'key' })
}
selectedIndex={mode === 'key' ? 0 : 1}
buttons={modeButtons}
containerStyle={{ height: 32, flex: 1 }}
selectedBackgroundColor={colors.green}
component={Platform.OS === 'android' ? TouchableNativeFeedback : TouchableOpacity}
component={
Platform.OS === 'android'
? TouchableNativeFeedback
: TouchableOpacity
}
/>
</ThemeProvider>
</Flex.Cols>
{mode === 'key'
? <TextInputMultilineFix
{mode === 'key' ? (
<TextInputMultilineFix
style={[
{
width: 330,
Expand All @@ -202,31 +232,40 @@ export default class PublicKeyWithActions extends PureComponent {
editable={!readOnly}
selectTextOnFocus
/>
: null}
) : null}

{!readOnly && mode === 'qrcode'
? <QRReader style={{ width: 248, height: 248 }} onFound={data => {
const url = parseUrl(data)
{!readOnly && mode === 'qrcode' ? (
<QRReader
style={{ width: 248, height: 248 }}
onFound={data => {
const url = parseUrl(data)

if (!url || url.pathname !== '/add-contact' || url.hashParts['public-key'] === '') {
return
}
if (
!url ||
url.pathname !== '/add-contact' ||
url.hashParts['public-key'] === ''
) {
return
}

this.setState({
mode: 'key',
contact: {
...this.state.contact,
id: url.hashParts['public-key'],
displayName: url.hashParts['display-name'] || '',
},
})
}} /> : null}
{readOnly && mode === 'qrcode'
? <QRGenerator
this.setState({
mode: 'key',
contact: {
...this.state.contact,
id: url.hashParts['public-key'],
displayName: url.hashParts['display-name'] || '',
},
})
}}
/>
) : null}
{readOnly && mode === 'qrcode' ? (
<QRGenerator
value={makeShareableUrl({ id, displayName })}
size={248}
style={[marginTop]} />
: null // TODO: implement camera
style={[marginTop]}
/>
) : null // TODO: implement camera
}

{shareButton ? (
Expand All @@ -241,7 +280,11 @@ export default class PublicKeyWithActions extends PureComponent {
onPress={this.onSubmit}
/>
) : null}
{errors.map((err, i) => <Text multiline key={i}>{err.extensions.message}</Text>)}
{errors.map((err, i) => (
<Text multiline key={i}>
{err.extensions.message}
</Text>
))}
</Flex.Rows>
</ScrollView>
)
Expand Down
Expand Up @@ -25,7 +25,7 @@ class Message extends React.PureComponent {
}

await this.props.screenProps.context.mutations.eventSeen({
eventId: this.props.data.id,
id: this.props.data.id,
})
}

Expand Down Expand Up @@ -102,6 +102,13 @@ class Input extends PureComponent {
height: 16,
}

async componentDidMount () {
const conversation = this.props.navigation.getParam('conversation')
await this.props.screenProps.context.mutations.conversationRead({
id: conversation.id,
})
}

onSubmit = () => {
const { input } = this.state
this.setState({ input: '' }, async () => {
Expand Down
39 changes: 32 additions & 7 deletions client/react-native/common/components/Screens/Chats/List.js
@@ -1,19 +1,44 @@
import { Image } from 'react-native'
import React, { PureComponent } from 'react'

import { Flex, Header, Screen, Text } from '../../Library'
import { Pagination } from '../../../relay'
import { Screen, Header, ListItem } from '../../Library'
import { borderBottom, marginLeft, padding } from '../../../styles'
import { colors } from '../../../constants'
import { fragments } from '../../../graphql'
import { conversation as utils } from '../../../utils'

const Item = fragments.Conversation(({ data, navigation, onPress }) => {
const Item = fragments.Conversation(({ data, navigation }) => {
const { id, updatedAt, readAt } = data
const isInvite = new Date(updatedAt).getTime() > 0
const isRead = new Date(readAt).getTime() > 0
return (
<ListItem
id={data.id}
title={utils.getTitle(data)}
subtitle='Last message sent 3 hours ago...' // Placeholder
<Flex.Cols
align='center'
onPress={() => navigation.push('chats/detail', { conversation: data })}
/>
style={[{ height: 72 }, padding, borderBottom]}
>
<Flex.Rows size={1} align='center'>
<Image
style={{ width: 40, height: 40, borderRadius: 20, margin: 4 }}
source={{
uri: 'https://api.adorable.io/avatars/40/' + id + '.png',
}}
/>
</Flex.Rows>
<Flex.Rows size={7} align='stretch' justify='center' style={[marginLeft]}>
<Text color={colors.black} left middle bold={!isRead}>
{utils.getTitle(data)}
</Text>
<Text color={colors.subtleGrey} tiny middle left bold={!isRead}>
{isRead
? 'No new message'
: isInvite
? 'You have been invited'
: 'You have a new message'}
</Text>
</Flex.Rows>
</Flex.Cols>
)
})

Expand Down
Expand Up @@ -8,6 +8,7 @@ export default component =>
id
createdAt
updatedAt
readAt
title
topic
members {
Expand Down
52 changes: 52 additions & 0 deletions client/react-native/common/graphql/mutations/ConversationRead.js
@@ -0,0 +1,52 @@
import { graphql } from 'react-relay'
import { commit } from '../../relay'

const ConversationReadMutation = graphql`
mutation ConversationReadMutation($id: ID!) {
ConversationRead(id: $id) {
id
createdAt
updatedAt
readAt
title
topic
members {
id
createdAt
updatedAt
status
contact {
id
createdAt
updatedAt
sigchain
status
devices {
id
createdAt
updatedAt
name
status
apiVersion
contactId
}
displayName
displayStatus
overrideDisplayName
overrideDisplayStatus
}
conversationId
contactId
}
}
}
`

export default context => (input, configs) =>
commit(
context.environment,
ConversationReadMutation,
'ConversationRead',
input,
configs
)
17 changes: 3 additions & 14 deletions client/react-native/common/graphql/mutations/EventSeen.js
@@ -1,11 +1,9 @@
import { graphql } from 'react-relay'
import { commit } from '../../relay'
import { merge } from '../../helpers'
import { conversation } from '../../utils'

const EventSeenMutation = graphql`
mutation EventSeenMutation($eventId: ID!) {
EventSeen(eventId: $eventId) {
mutation EventSeenMutation($id: ID!) {
EventSeen(id: $id) {
id
senderId
createdAt
Expand All @@ -26,13 +24,4 @@ const EventSeenMutation = graphql`
`

export default context => (input, configs) =>
commit(
context.environment,
EventSeenMutation,
'EventSeen',
merge([
{ conversation: conversation.default, message: { text: '' } },
input,
]),
configs
)
commit(context.environment, EventSeenMutation, 'EventSeen', input, configs)
1 change: 1 addition & 0 deletions client/react-native/common/graphql/mutations/index.js
Expand Up @@ -6,6 +6,7 @@ export contactRemove from './ContactRemove'
export conversationCreate from './ConversationCreate'
export conversationAddMessage from './ConversationAddMessage'
export conversationInvite from './ConversationInvite'
export conversationRead from './ConversationRead'
export eventSeen from './EventSeen'
export debugRequeueEvent from './DebugRequeueEvent'
export debugRequeueAll from './DebugRequeueAll'
Expand Up @@ -23,7 +23,7 @@ const query = graphql`

const defaultVariables = {
filter: null,
orderBy: '',
orderBy: 'updated_at',
orderDesc: false,
count: 50,
cursor: '',
Expand Down

0 comments on commit 78756c5

Please sign in to comment.