Skip to content

Commit

Permalink
Merge pull request #53 from terrysahaidak/tr-search-messages
Browse files Browse the repository at this point in the history
Add ability to search messages
  • Loading branch information
terrysahaidak authored Oct 9, 2016
2 parents 3a53eca + 7b19090 commit 67af67a
Show file tree
Hide file tree
Showing 10 changed files with 394 additions and 29 deletions.
4 changes: 4 additions & 0 deletions app/api/gitter.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@ export function readMessages(token, userId, roomId, chat) {
})
}

export function searchRoomMessages(token, roomId, query) {
return callApi(`rooms/${roomId}/chatMessages?q=${query}&limit=30`, token)
}

/**
* Private functions
*/
Expand Down
9 changes: 8 additions & 1 deletion app/components/Room/Message.js
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,16 @@ class Message extends Component {
}
}

const noop = () => {}

Message.defaultProps = {
sending: false,
failed: false
failed: false,
onLayout: noop,
onLongPress: noop,
onPress: noop,
onUsernamePress: noop,
onUserAvatarPress: noop
}

Message.propTypes = {
Expand Down
47 changes: 37 additions & 10 deletions app/components/Room/SendMessageField.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,39 @@ export default class SendMessageField extends Component {
this.sendMessage = this.sendMessage.bind(this)
this.focus = this.focus.bind(this)
this.blur = this.blur.bind(this)
this.handleChangeSize = this.handleChangeSize.bind(this)
this.handleChangeText = this.handleChangeText.bind(this)

this.state = {
height: 56
height: 56,
value: ''
}
}

componentWillMount() {
this.setState({value: this.props.value})
}

componentWillReceiveProps({value}) {
if (!this.state.value.length) {
this.setState({value})
}
}

// componentDidMount() {
// setTimeout(() => this.setState({height: }))
// }

handleChangeSize(e) {
this.setState({height: e.nativeEvent.layout.height + 30})
}

handleChangeText(value) {
const {onChange} = this.props
this.setState({value})
onChange(value)
}

focus() {
this.refs.textInput.focus()
}
Expand All @@ -30,29 +57,29 @@ export default class SendMessageField extends Component {
return
}
onSending()
this.setState({height: 56})
this.setState({height: 56, value: ''})
}

render() {
const {value, onChange} = this.props
const {value, height} = this.state
return (
<View style={s.container}>
<View style={s.innerContainer}>
<TextInput
ref="textInput"
multiline
style={[s.textInput, {height: this.state.height > 90 ? 90 : Math.max(56, this.state.height)}]}
style={[s.textInput, {height: height > 90 ? 90 : Math.max(56, height)}]}
value={value}
keyboardShouldPersistTaps={false}
underlineColorAndroid="white"
onChange={(event) => onChange(event.nativeEvent.text)}
onChangeText={this.handleChangeText}
placeholder="Type your message here..." />
<Text
ref="hidden"
onLayout={e => this.setState({height: e.nativeEvent.layout.height})}
style={s.hidden}>
{value}
</Text>
ref="hidden"
onLayout={this.handleChangeSize}
style={s.hidden}>
{value}
</Text>
</View>
<Button
background="SelectableBackgroundBorderless"
Expand Down
31 changes: 31 additions & 0 deletions app/components/SearchMessages/MessagesList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React, {PropTypes} from 'react'
import {ScrollView} from 'react-native'
import Message from '../Room/Message'

const MessagesList = ({
items,
onLongPress,
onPress,
onUserAvatarPress
}) => (
<ScrollView>
{items.map(item =>
<Message
{...item}
onLongPress={onLongPress}
onPress={onPress}
onUserAvatarPress={onUserAvatarPress}
onLayout={() => {}}
key={item.id} />
)}
</ScrollView>
)

MessagesList.propTypes = {
items: PropTypes.array,
onPress: PropTypes.func,
onLongPress: PropTypes.func,
onUserAvatarPress: PropTypes.func
}

export default MessagesList
30 changes: 30 additions & 0 deletions app/modules/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ export const CLEAR_SEARCH = 'search/CLEAR_SEARCH'
export const SEARCH_ROOM_USERS = 'search/SEARCH_ROOM_USERS'
export const SEARCH_ROOM_USERS_OK = 'search/SEARCH_ROOM_USERS_OK'
export const SEARCH_ROOM_USERS_FAILED = 'search/SEARCH_ROOM_USERS_FAILED'
export const SEARCH_ROOM_MESSAGES = 'search/SEARCH_ROOM_MESSAGES'
export const SEARCH_ROOM_MESSAGES_OK = 'search/SEARCH_ROOM_MESSAGES_OK'
export const SEARCH_ROOM_MESSAGES_FAILED = 'search/SEARCH_ROOM_MESSAGES_FAILED'

/**
* Actions
Expand Down Expand Up @@ -81,6 +84,20 @@ export function searchRoomUsers(roomId, query) {
}
}

export function searchRoomMessages(roomId, query) {
return async (dispatch, getState) => {
const {token} = getState().auth
dispatch({type: SEARCH_ROOM_MESSAGES, roomId, query})

try {
const payload = await Api.searchRoomMessages(token, roomId, query)
dispatch({type: SEARCH_ROOM_MESSAGES_OK, payload})
} catch (error) {
dispatch({type: SEARCH_ROOM_MESSAGES_FAILED, error})
}
}
}

/**
* Reducer
*/
Expand All @@ -89,10 +106,12 @@ const initialState = {
isLoadingUsers: false,
isLoadingRooms: false,
isLoadingRoomUser: false,
isLoadingRoomMessages: false,
inputValue: '',
usersResult: [],
roomsResult: [],
roomUsersResult: [],
roomMessagesResult: [],
error: false,
errors: {}
}
Expand Down Expand Up @@ -140,6 +159,17 @@ export default function search(state = initialState, action) {
roomUsersResult: action.payload
}

case SEARCH_ROOM_MESSAGES:
return {...state,
isLoadingRoomMessages: true
}

case SEARCH_ROOM_MESSAGES_OK:
return {...state,
isLoadingRoomMessages: false,
roomMessagesResult: action.payload || []
}

case SEARCH_ROOM_USERS_FAILED:
case SEARCH_USERS_FAILED:
case SEARCH_ROOMS_FAILED:
Expand Down
13 changes: 9 additions & 4 deletions app/screens/Message.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,11 @@ class Message extends Component {
}

renderMessage() {
const {messages, route: {messageId}, viewer} = this.props
const message = messages[messageId]
const {messages, route: {messageId, fromSearch}, viewer, roomMessagesResult} = this.props
const message = fromSearch
? roomMessagesResult.find(item => item.id === messageId)
: messages[messageId]

return (
<Msg
username={viewer.username}
Expand Down Expand Up @@ -93,14 +96,16 @@ Message.propTypes = {
route: PropTypes.object,
messages: PropTypes.object,
readBy: PropTypes.object,
viewer: PropTypes.object
viewer: PropTypes.object,
roomMessagesResult: PropTypes.array
}

function mapStateToProps(state) {
return {
messages: state.messages.entities,
readBy: state.readBy.byMessage,
viewer: state.viewer.user
viewer: state.viewer.user,
roomMessagesResult: state.search.roomMessagesResult
}
}

Expand Down
33 changes: 19 additions & 14 deletions app/screens/RoomScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,20 +301,15 @@ class Room extends Component {

handleToolbarActionSelected(index) {
const {dispatch, route: {roomId}} = this.props
if (index === 0) {
return this.roomInfoDrawer.openDrawer()
}
if (index === 1) {
return dispatch(changeFavoriteStatus(roomId))
}
if (index === 2) {
return dispatch(markAllAsRead(roomId))
}
if (index === 3) {
return this.handleNotificationSettingsChange()
}
if (index === 4) {
return this.leaveRoom()
switch (index) {
case 0: return dispatch(Navigation.goTo({name: 'searchMessages', roomId}))
case 1: return this.roomInfoDrawer.openDrawer()
case 2: return dispatch(changeFavoriteStatus(roomId))
case 3: return dispatch(markAllAsRead(roomId))
case 4: return this.handleNotificationSettingsChange()
case 5: return this.leaveRoom()
default:
break
}
}

Expand Down Expand Up @@ -450,6 +445,11 @@ class Room extends Component {
if (!!room && room.roomMember) {
if (room.hasOwnProperty('favourite')) {
actions = [{
title: 'Search',
icon: require('image!ic_search_white_24dp'),
show: 'always'
},
{
title: 'Open room info',
icon: require('image!ic_info_outline_white_24dp'),
show: 'never'
Expand All @@ -472,6 +472,11 @@ class Room extends Component {
}]
} else {
actions = [{
title: 'Search',
icon: require('image!ic_search_white_24dp'),
show: 'always'
},
{
title: 'Open room info',
icon: require('image!ic_info_outline_white_24dp'),
show: 'never'
Expand Down
Loading

0 comments on commit 67af67a

Please sign in to comment.