[NEW] Room actions: Mentioned messages and Room Members (#242)
* Mentioned messages * Starred and pinned actions debounce * Room members * Open room on member touch
This commit is contained in:
parent
477609375c
commit
4823e3a2e4
|
@ -37,6 +37,7 @@ module.exports = {
|
|||
"react/no-unused-prop-types": [2, {
|
||||
"skipShapeProps": true
|
||||
}],
|
||||
"react/no-did-mount-set-state": 0,
|
||||
"react/no-multi-comp": [0],
|
||||
"react/jsx-indent": [2, "tab"],
|
||||
"react/jsx-indent-props": [2, "tab"],
|
||||
|
|
|
@ -136,12 +136,15 @@ exports[`render channel 1`] = `
|
|||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
Nov 10
|
||||
|
@ -300,12 +303,15 @@ exports[`render no icon 1`] = `
|
|||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
Nov 10
|
||||
|
@ -464,12 +470,15 @@ exports[`render private group 1`] = `
|
|||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
Nov 10
|
||||
|
@ -640,12 +649,15 @@ exports[`render unread +999 1`] = `
|
|||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
Nov 10
|
||||
|
@ -838,12 +850,15 @@ exports[`render unread 1`] = `
|
|||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
Nov 10
|
||||
|
@ -1036,12 +1051,15 @@ exports[`renders correctly 1`] = `
|
|||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
Nov 10
|
||||
|
|
|
@ -299,12 +299,15 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
Nov 10
|
||||
|
@ -471,12 +474,17 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
Object {
|
||||
"color": "#1d74f5",
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
Nov 10
|
||||
|
@ -641,12 +649,15 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
Nov 10
|
||||
|
@ -836,12 +847,17 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
Object {
|
||||
"color": "#1d74f5",
|
||||
},
|
||||
]
|
||||
}
|
||||
>
|
||||
Nov 10
|
||||
|
@ -1029,12 +1045,15 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
Nov 10
|
||||
|
@ -1222,12 +1241,15 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
Nov 10
|
||||
|
@ -1415,12 +1437,15 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
Nov 10
|
||||
|
@ -1608,12 +1633,15 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
Nov 10
|
||||
|
@ -1801,12 +1829,15 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
Nov 10
|
||||
|
@ -1971,12 +2002,15 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
Nov 10
|
||||
|
@ -2141,12 +2175,15 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
ellipsizeMode="tail"
|
||||
numberOfLines={1}
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
}
|
||||
Array [
|
||||
Object {
|
||||
"alignItems": "center",
|
||||
"color": "#888",
|
||||
"fontSize": 10,
|
||||
"justifyContent": "center",
|
||||
},
|
||||
undefined,
|
||||
]
|
||||
}
|
||||
>
|
||||
Nov 10
|
||||
|
|
|
@ -93,8 +93,9 @@ export const SERVER = createRequestTypes('SERVER', [
|
|||
export const METEOR = createRequestTypes('METEOR_CONNECT', [...defaultTypes, 'DISCONNECT', 'DISCONNECT_BY_USER']);
|
||||
export const LOGOUT = 'LOGOUT'; // logout is always success
|
||||
export const ACTIVE_USERS = createRequestTypes('ACTIVE_USERS', ['SET', 'REQUEST']);
|
||||
export const STARRED_MESSAGES = createRequestTypes('STARRED_MESSAGES', ['OPEN', 'CLOSE', 'MESSAGE_RECEIVED', 'MESSAGE_UNSTARRED']);
|
||||
export const PINNED_MESSAGES = createRequestTypes('PINNED_MESSAGES', ['OPEN', 'CLOSE', 'MESSAGE_RECEIVED', 'MESSAGE_UNPINNED']);
|
||||
export const STARRED_MESSAGES = createRequestTypes('STARRED_MESSAGES', ['OPEN', 'CLOSE', 'MESSAGES_RECEIVED', 'MESSAGE_UNSTARRED']);
|
||||
export const PINNED_MESSAGES = createRequestTypes('PINNED_MESSAGES', ['OPEN', 'CLOSE', 'MESSAGES_RECEIVED', 'MESSAGE_UNPINNED']);
|
||||
export const MENTIONED_MESSAGES = createRequestTypes('MENTIONED_MESSAGES', ['OPEN', 'CLOSE', 'MESSAGES_RECEIVED']);
|
||||
|
||||
export const INCREMENT = 'INCREMENT';
|
||||
export const DECREMENT = 'DECREMENT';
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import * as types from './actionsTypes';
|
||||
|
||||
export function openMentionedMessages(rid) {
|
||||
return {
|
||||
type: types.MENTIONED_MESSAGES.OPEN,
|
||||
rid
|
||||
};
|
||||
}
|
||||
|
||||
export function closeMentionedMessages() {
|
||||
return {
|
||||
type: types.MENTIONED_MESSAGES.CLOSE
|
||||
};
|
||||
}
|
||||
|
||||
export function mentionedMessagesReceived(messages) {
|
||||
return {
|
||||
type: types.MENTIONED_MESSAGES.MESSAGES_RECEIVED,
|
||||
messages
|
||||
};
|
||||
}
|
|
@ -13,10 +13,10 @@ export function closePinnedMessages() {
|
|||
};
|
||||
}
|
||||
|
||||
export function pinnedMessageReceived(message) {
|
||||
export function pinnedMessagesReceived(messages) {
|
||||
return {
|
||||
type: types.PINNED_MESSAGES.MESSAGE_RECEIVED,
|
||||
message
|
||||
type: types.PINNED_MESSAGES.MESSAGES_RECEIVED,
|
||||
messages
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -13,10 +13,10 @@ export function closeStarredMessages() {
|
|||
};
|
||||
}
|
||||
|
||||
export function starredMessageReceived(message) {
|
||||
export function starredMessagesReceived(messages) {
|
||||
return {
|
||||
type: types.STARRED_MESSAGES.MESSAGE_RECEIVED,
|
||||
message
|
||||
type: types.STARRED_MESSAGES.MESSAGES_RECEIVED,
|
||||
messages
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -143,7 +143,7 @@ const Reply = ({ attachment, timeFormat }) => {
|
|||
{renderTitle()}
|
||||
{renderText()}
|
||||
{renderFields()}
|
||||
{attachment.attachments.map(attach => <Reply key={attach.text} attachment={attach} timeFormat={timeFormat} />)}
|
||||
{attachment.attachments && attachment.attachments.map(attach => <Reply key={attach.text} attachment={attach} timeFormat={timeFormat} />)}
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
|
|
|
@ -4,7 +4,7 @@ import { View, TouchableHighlight, Text, TouchableOpacity, Vibration, ViewPropTy
|
|||
import { connect } from 'react-redux';
|
||||
import Icon from 'react-native-vector-icons/MaterialIcons';
|
||||
import moment from 'moment';
|
||||
import equal from 'deep-equal';
|
||||
// import equal from 'deep-equal';
|
||||
import { KeyboardUtils } from 'react-native-keyboard-input';
|
||||
|
||||
import { actionsShow, errorActionsShow, toggleReactionPicker } from '../../actions/messages';
|
||||
|
@ -52,22 +52,16 @@ export default class Message extends React.Component {
|
|||
this.state = { reactionsModal: false };
|
||||
this.onClose = this.onClose.bind(this);
|
||||
}
|
||||
componentWillReceiveProps() {
|
||||
this.extraStyle = this.extraStyle || {};
|
||||
if (this.props.item.status === messageStatus.TEMP || this.props.item.status === messageStatus.ERROR) {
|
||||
this.extraStyle.opacity = 0.3;
|
||||
}
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps, nextState) {
|
||||
if (!equal(this.props.reactions, nextProps.reactions)) {
|
||||
return true;
|
||||
}
|
||||
if (this.state.reactionsModal !== nextState.reactionsModal) {
|
||||
return true;
|
||||
}
|
||||
return this.props.item._updatedAt.toGMTString() !== nextProps.item._updatedAt.toGMTString() || this.props.item.status !== nextProps.item.status;
|
||||
}
|
||||
// shouldComponentUpdate(nextProps, nextState) {
|
||||
// if (!equal(this.props.reactions, nextProps.reactions)) {
|
||||
// return true;
|
||||
// }
|
||||
// if (this.state.reactionsModal !== nextState.reactionsModal) {
|
||||
// return true;
|
||||
// }
|
||||
// return this.props.item._updatedAt.toGMTString() !== nextProps.item._updatedAt.toGMTString() || this.props.item.status !== nextProps.item.status;
|
||||
// }
|
||||
|
||||
onPress = () => {
|
||||
KeyboardUtils.dismiss();
|
||||
|
@ -129,6 +123,10 @@ export default class Message extends React.Component {
|
|||
return this.props.item.t === 'rm';
|
||||
}
|
||||
|
||||
isTemp() {
|
||||
return this.props.item.status === messageStatus.TEMP || this.props.item.status === messageStatus.ERROR;
|
||||
}
|
||||
|
||||
hasError() {
|
||||
return this.props.item.status === messageStatus.ERROR;
|
||||
}
|
||||
|
@ -241,7 +239,7 @@ export default class Message extends React.Component {
|
|||
>
|
||||
<View style={styles.flex}>
|
||||
{this.renderError()}
|
||||
<View style={[this.extraStyle, styles.flex]}>
|
||||
<View style={[this.isTemp() && { opacity: 0.3 }, styles.flex]}>
|
||||
<Avatar
|
||||
style={styles.avatar}
|
||||
text={item.avatar ? '' : username}
|
||||
|
|
|
@ -10,6 +10,8 @@ import SelectUsersView from '../../views/SelectUsersView';
|
|||
import NewServerView from '../../views/NewServerView';
|
||||
import StarredMessagesView from '../../views/StarredMessagesView';
|
||||
import PinnedMessagesView from '../../views/PinnedMessagesView';
|
||||
import MentionedMessagesView from '../../views/MentionedMessagesView';
|
||||
import RoomMembersView from '../../views/RoomMembersView';
|
||||
|
||||
const AuthRoutes = StackNavigator(
|
||||
{
|
||||
|
@ -57,6 +59,20 @@ const AuthRoutes = StackNavigator(
|
|||
title: 'Pinned Messages',
|
||||
headerTintColor: '#292E35'
|
||||
}
|
||||
},
|
||||
MentionedMessages: {
|
||||
screen: MentionedMessagesView,
|
||||
navigationOptions: {
|
||||
title: 'Mentioned Messages',
|
||||
headerTintColor: '#292E35'
|
||||
}
|
||||
},
|
||||
RoomMembers: {
|
||||
screen: RoomMembersView,
|
||||
navigationOptions: {
|
||||
title: 'Room Members',
|
||||
headerTintColor: '#292E35'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -28,6 +28,7 @@ const settingsSchema = {
|
|||
|
||||
const permissionsRolesSchema = {
|
||||
name: 'permissionsRoles',
|
||||
primaryKey: 'value',
|
||||
properties: {
|
||||
value: 'string'
|
||||
}
|
||||
|
@ -56,6 +57,7 @@ const roomsSchema = {
|
|||
|
||||
const subscriptionRolesSchema = {
|
||||
name: 'subscriptionRolesSchema',
|
||||
primaryKey: 'value',
|
||||
properties: {
|
||||
value: 'string'
|
||||
}
|
||||
|
@ -70,9 +72,9 @@ const subscriptionSchema = {
|
|||
t: 'string',
|
||||
ts: { type: 'date', optional: true },
|
||||
ls: { type: 'date', optional: true },
|
||||
name: 'string',
|
||||
name: { type: 'string', indexed: true },
|
||||
fname: { type: 'string', optional: true },
|
||||
rid: 'string',
|
||||
rid: { type: 'string', indexed: true },
|
||||
open: { type: 'bool', optional: true },
|
||||
alert: { type: 'bool', optional: true },
|
||||
roles: { type: 'list', objectType: 'subscriptionRolesSchema' },
|
||||
|
@ -83,7 +85,10 @@ const subscriptionSchema = {
|
|||
roomUpdatedAt: { type: 'date', optional: true },
|
||||
ro: { type: 'bool', optional: true },
|
||||
lastOpen: { type: 'date', optional: true },
|
||||
lastMessage: { type: 'messages', optional: true }
|
||||
lastMessage: { type: 'messages', optional: true },
|
||||
description: { type: 'string', optional: true },
|
||||
announcement: { type: 'string', optional: true },
|
||||
topic: { type: 'string', optional: true }
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -136,6 +141,7 @@ const attachment = {
|
|||
|
||||
const url = {
|
||||
name: 'url',
|
||||
primaryKey: 'url',
|
||||
properties: {
|
||||
// _id: { type: 'int', optional: true },
|
||||
url: { type: 'string', optional: true },
|
||||
|
@ -147,6 +153,7 @@ const url = {
|
|||
|
||||
const messagesReactionsUsernamesSchema = {
|
||||
name: 'messagesReactionsUsernames',
|
||||
primaryKey: 'value',
|
||||
properties: {
|
||||
value: 'string'
|
||||
}
|
||||
|
@ -163,6 +170,7 @@ const messagesReactionsSchema = {
|
|||
|
||||
const messagesEditedBySchema = {
|
||||
name: 'messagesEditedBy',
|
||||
primaryKey: '_id',
|
||||
properties: {
|
||||
_id: { type: 'string', optional: true },
|
||||
username: { type: 'string', optional: true }
|
||||
|
@ -176,7 +184,7 @@ const messagesSchema = {
|
|||
_id: 'string',
|
||||
msg: { type: 'string', optional: true },
|
||||
t: { type: 'string', optional: true },
|
||||
rid: 'string',
|
||||
rid: { type: 'string', indexed: true },
|
||||
ts: 'date',
|
||||
u: 'users',
|
||||
// mentions: [],
|
||||
|
@ -209,6 +217,7 @@ const frequentlyUsedEmojiSchema = {
|
|||
|
||||
const customEmojiAliasesSchema = {
|
||||
name: 'customEmojiAliases',
|
||||
primaryKey: 'value',
|
||||
properties: {
|
||||
value: 'string'
|
||||
}
|
||||
|
|
|
@ -13,8 +13,9 @@ import { someoneTyping, roomMessageReceived } from '../actions/room';
|
|||
import { setUser, setLoginServices, removeLoginServices } from '../actions/login';
|
||||
import { disconnect, disconnect_by_user, connectSuccess, connectFailure } from '../actions/connect';
|
||||
import { requestActiveUser } from '../actions/activeUsers';
|
||||
import { starredMessageReceived, starredMessageUnstarred } from '../actions/starredMessages';
|
||||
import { pinnedMessageReceived, pinnedMessageUnpinned } from '../actions/pinnedMessages';
|
||||
import { starredMessagesReceived, starredMessageUnstarred } from '../actions/starredMessages';
|
||||
import { pinnedMessagesReceived, pinnedMessageUnpinned } from '../actions/pinnedMessages';
|
||||
import { mentionedMessagesReceived } from '../actions/mentionedMessages';
|
||||
import Ddp from './ddp';
|
||||
|
||||
export { Accounts } from 'react-native-meteor';
|
||||
|
@ -64,7 +65,7 @@ const RocketChat = {
|
|||
const status = (ddpMessage.fields && ddpMessage.fields.status) || 'offline';
|
||||
|
||||
if (user && user.id === ddpMessage.id) {
|
||||
return reduxStore.dispatch(setUser({ status }));
|
||||
reduxStore.dispatch(setUser({ status }));
|
||||
}
|
||||
|
||||
if (this._setUserTimer) {
|
||||
|
@ -153,25 +154,74 @@ const RocketChat = {
|
|||
|
||||
this.ddp.on('rocketchat_starred_message', (ddpMessage) => {
|
||||
if (ddpMessage.msg === 'added') {
|
||||
this.starredMessages = this.starredMessages || [];
|
||||
|
||||
if (this.starredMessagesTimer) {
|
||||
clearTimeout(this.starredMessagesTimer);
|
||||
this.starredMessagesTimer = null;
|
||||
}
|
||||
|
||||
this.starredMessagesTimer = setTimeout(() => {
|
||||
reduxStore.dispatch(starredMessagesReceived(this.starredMessages));
|
||||
this.starredMessagesTimer = null;
|
||||
return this.starredMessages = [];
|
||||
}, 1000);
|
||||
const message = ddpMessage.fields;
|
||||
message._id = ddpMessage.id;
|
||||
const starredMessage = this._buildMessage(message);
|
||||
return reduxStore.dispatch(starredMessageReceived(starredMessage));
|
||||
this.starredMessages = [...this.starredMessages, starredMessage];
|
||||
}
|
||||
if (ddpMessage.msg === 'removed') {
|
||||
return reduxStore.dispatch(starredMessageUnstarred(ddpMessage.id));
|
||||
if (reduxStore.getState().starredMessages.isOpen) {
|
||||
return reduxStore.dispatch(starredMessageUnstarred(ddpMessage.id));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.ddp.on('rocketchat_pinned_message', (ddpMessage) => {
|
||||
if (ddpMessage.msg === 'added') {
|
||||
this.pinnedMessages = this.pinnedMessages || [];
|
||||
|
||||
if (this.pinnedMessagesTimer) {
|
||||
clearTimeout(this.pinnedMessagesTimer);
|
||||
this.pinnedMessagesTimer = null;
|
||||
}
|
||||
|
||||
this.pinnedMessagesTimer = setTimeout(() => {
|
||||
reduxStore.dispatch(pinnedMessagesReceived(this.pinnedMessages));
|
||||
this.pinnedMessagesTimer = null;
|
||||
return this.pinnedMessages = [];
|
||||
}, 1000);
|
||||
const message = ddpMessage.fields;
|
||||
message._id = ddpMessage.id;
|
||||
const pinnedMessage = this._buildMessage(message);
|
||||
return reduxStore.dispatch(pinnedMessageReceived(pinnedMessage));
|
||||
this.pinnedMessages = [...this.pinnedMessages, pinnedMessage];
|
||||
}
|
||||
if (ddpMessage.msg === 'removed') {
|
||||
return reduxStore.dispatch(pinnedMessageUnpinned(ddpMessage.id));
|
||||
if (reduxStore.getState().pinnedMessages.isOpen) {
|
||||
return reduxStore.dispatch(pinnedMessageUnpinned(ddpMessage.id));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.ddp.on('rocketchat_mentioned_message', (ddpMessage) => {
|
||||
if (ddpMessage.msg === 'added') {
|
||||
this.mentionedMessages = this.mentionedMessages || [];
|
||||
|
||||
if (this.mentionedMessagesTimer) {
|
||||
clearTimeout(this.mentionedMessagesTimer);
|
||||
this.mentionedMessagesTimer = null;
|
||||
}
|
||||
|
||||
this.mentionedMessagesTimer = setTimeout(() => {
|
||||
reduxStore.dispatch(mentionedMessagesReceived(this.mentionedMessages));
|
||||
this.mentionedMessagesTimer = null;
|
||||
return this.mentionedMessages = [];
|
||||
}, 1000);
|
||||
const message = ddpMessage.fields;
|
||||
message._id = ddpMessage.id;
|
||||
const mentionedMessage = this._buildMessage(message);
|
||||
this.mentionedMessages = [...this.mentionedMessages, mentionedMessage];
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -324,6 +374,7 @@ const RocketChat = {
|
|||
message.status = messagesStatus.SENT;
|
||||
normalizeMessage(message);
|
||||
message.urls = message.urls ? RocketChat._parseUrls(message.urls) : [];
|
||||
message._updatedAt = new Date();
|
||||
// loadHistory returns message.starred as object
|
||||
// stream-room-messages returns message.starred as an array
|
||||
message.starred = message.starred && (Array.isArray(message.starred) ? message.starred.length > 0 : !!message.starred);
|
||||
|
@ -497,6 +548,9 @@ const RocketChat = {
|
|||
subscription.roomUpdatedAt = room._updatedAt;
|
||||
subscription.lastMessage = normalizeMessage(room.lastMessage);
|
||||
subscription.ro = room.ro;
|
||||
subscription.description = room.description;
|
||||
subscription.topic = room.topic;
|
||||
subscription.announcement = room.announcement;
|
||||
}
|
||||
if (subscription.roles) {
|
||||
subscription.roles = subscription.roles.map(role => ({ value: role }));
|
||||
|
@ -667,6 +721,9 @@ const RocketChat = {
|
|||
},
|
||||
toggleFavorite(rid, f) {
|
||||
return call('toggleFavorite', rid, !f);
|
||||
},
|
||||
getRoomMembers(rid, allUsers) {
|
||||
return call('getUsersOfRoom', rid, allUsers);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -83,6 +83,9 @@ const styles = StyleSheet.create({
|
|||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
updateAlert: {
|
||||
color: '#1d74f5'
|
||||
},
|
||||
status: {
|
||||
position: 'absolute',
|
||||
bottom: -3,
|
||||
|
@ -173,7 +176,7 @@ export default class RoomItem extends React.PureComponent {
|
|||
|
||||
get lastMessage() {
|
||||
const {
|
||||
lastMessage, alert, type
|
||||
lastMessage, type
|
||||
} = this.props;
|
||||
|
||||
if (!this.props.StoreLastMessage) {
|
||||
|
@ -183,7 +186,6 @@ export default class RoomItem extends React.PureComponent {
|
|||
return 'No Message';
|
||||
}
|
||||
|
||||
|
||||
let prefix = '';
|
||||
|
||||
if (lastMessage.u.username === this.props.user.username) {
|
||||
|
@ -193,13 +195,7 @@ export default class RoomItem extends React.PureComponent {
|
|||
}
|
||||
|
||||
const msg = `${ prefix }${ lastMessage.msg.replace(/[\n\t\r]/igm, '') }`;
|
||||
|
||||
const maxChars = 35;
|
||||
|
||||
|
||||
if (alert) {
|
||||
return `**${ msg.slice(0, maxChars) }${ msg.replace(/:[a-z0-9]+:/gi, ':::').length > maxChars ? '...' : '' }**`;
|
||||
}
|
||||
return `${ msg.slice(0, maxChars) }${ msg.replace(/:[a-z0-9]+:/gi, ':::').length > maxChars ? '...' : '' }`;
|
||||
}
|
||||
|
||||
|
@ -237,7 +233,7 @@ export default class RoomItem extends React.PureComponent {
|
|||
<View style={styles.roomNameView}>
|
||||
<View style={styles.firstRow}>
|
||||
<Text style={[styles.roomName, alert && styles.alert]} ellipsizeMode='tail' numberOfLines={1}>{ name }</Text>
|
||||
{_updatedAt ? <Text style={styles.update} ellipsizeMode='tail' numberOfLines={1}>{ date }</Text> : null}
|
||||
{_updatedAt ? <Text style={[styles.update, alert && styles.updateAlert]} ellipsizeMode='tail' numberOfLines={1}>{ date }</Text> : null}
|
||||
</View>
|
||||
<View style={styles.row}>
|
||||
<Markdown
|
||||
|
|
|
@ -14,6 +14,7 @@ import customEmojis from './customEmojis';
|
|||
import activeUsers from './activeUsers';
|
||||
import starredMessages from './starredMessages';
|
||||
import pinnedMessages from './pinnedMessages';
|
||||
import mentionedMessages from './mentionedMessages';
|
||||
|
||||
export default combineReducers({
|
||||
settings,
|
||||
|
@ -30,5 +31,6 @@ export default combineReducers({
|
|||
customEmojis,
|
||||
activeUsers,
|
||||
starredMessages,
|
||||
pinnedMessages
|
||||
pinnedMessages,
|
||||
mentionedMessages
|
||||
});
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import { MENTIONED_MESSAGES } from '../actions/actionsTypes';
|
||||
|
||||
const initialState = {
|
||||
messages: []
|
||||
};
|
||||
|
||||
export default function server(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
case MENTIONED_MESSAGES.MESSAGES_RECEIVED:
|
||||
return {
|
||||
...state,
|
||||
messages: [...state.messages, ...action.messages]
|
||||
};
|
||||
case MENTIONED_MESSAGES.CLOSE:
|
||||
return initialState;
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
|
@ -1,15 +1,21 @@
|
|||
import { PINNED_MESSAGES } from '../actions/actionsTypes';
|
||||
|
||||
const initialState = {
|
||||
messages: []
|
||||
messages: [],
|
||||
isOpen: false
|
||||
};
|
||||
|
||||
export default function server(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
case PINNED_MESSAGES.MESSAGE_RECEIVED:
|
||||
case PINNED_MESSAGES.OPEN:
|
||||
return {
|
||||
...state,
|
||||
messages: [...state.messages, action.message]
|
||||
isOpen: true
|
||||
};
|
||||
case PINNED_MESSAGES.MESSAGES_RECEIVED:
|
||||
return {
|
||||
...state,
|
||||
messages: [...state.messages, ...action.messages]
|
||||
};
|
||||
case PINNED_MESSAGES.MESSAGE_UNPINNED:
|
||||
return {
|
||||
|
|
|
@ -1,15 +1,21 @@
|
|||
import { STARRED_MESSAGES } from '../actions/actionsTypes';
|
||||
|
||||
const initialState = {
|
||||
messages: []
|
||||
messages: [],
|
||||
isOpen: false
|
||||
};
|
||||
|
||||
export default function server(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
case STARRED_MESSAGES.MESSAGE_RECEIVED:
|
||||
case STARRED_MESSAGES.OPEN:
|
||||
return {
|
||||
...state,
|
||||
messages: [...state.messages, action.message]
|
||||
isOpen: true
|
||||
};
|
||||
case STARRED_MESSAGES.MESSAGES_RECEIVED:
|
||||
return {
|
||||
...state,
|
||||
messages: [...state.messages, ...action.messages]
|
||||
};
|
||||
case STARRED_MESSAGES.MESSAGE_UNSTARRED:
|
||||
return {
|
||||
|
|
|
@ -11,6 +11,7 @@ import state from './state';
|
|||
import activeUsers from './activeUsers';
|
||||
import starredMessages from './starredMessages';
|
||||
import pinnedMessages from './pinnedMessages';
|
||||
import mentionedMessages from './mentionedMessages';
|
||||
|
||||
const root = function* root() {
|
||||
yield all([
|
||||
|
@ -25,7 +26,8 @@ const root = function* root() {
|
|||
state(),
|
||||
activeUsers(),
|
||||
starredMessages(),
|
||||
pinnedMessages()
|
||||
pinnedMessages(),
|
||||
mentionedMessages()
|
||||
]);
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
import { take, takeLatest } from 'redux-saga/effects';
|
||||
import * as types from '../actions/actionsTypes';
|
||||
import RocketChat from '../lib/rocketchat';
|
||||
|
||||
const watchMentionedMessagesRoom = function* watchMentionedMessagesRoom({ rid }) {
|
||||
const sub = yield RocketChat.subscribe('mentionedMessages', rid, 50);
|
||||
yield take(types.MENTIONED_MESSAGES.CLOSE);
|
||||
sub.unsubscribe().catch(e => alert(e));
|
||||
};
|
||||
|
||||
const root = function* root() {
|
||||
yield takeLatest(types.MENTIONED_MESSAGES.OPEN, watchMentionedMessagesRoom);
|
||||
};
|
||||
export default root;
|
|
@ -0,0 +1,71 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FlatList, Text, View } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { openMentionedMessages, closeMentionedMessages } from '../../actions/mentionedMessages';
|
||||
import styles from './styles';
|
||||
import Message from '../../containers/message';
|
||||
|
||||
@connect(
|
||||
state => ({
|
||||
messages: state.mentionedMessages.messages,
|
||||
user: state.login.user,
|
||||
baseUrl: state.settings.Site_Url || state.server ? state.server.server : ''
|
||||
}),
|
||||
dispatch => ({
|
||||
openMentionedMessages: rid => dispatch(openMentionedMessages(rid)),
|
||||
closeMentionedMessages: () => dispatch(closeMentionedMessages())
|
||||
})
|
||||
)
|
||||
export default class MentionedMessagesView extends React.PureComponent {
|
||||
static propTypes = {
|
||||
navigation: PropTypes.object,
|
||||
messages: PropTypes.array,
|
||||
user: PropTypes.object,
|
||||
baseUrl: PropTypes.string,
|
||||
openMentionedMessages: PropTypes.func,
|
||||
closeMentionedMessages: PropTypes.func
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.props.openMentionedMessages(this.props.navigation.state.params.rid);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
this.props.closeMentionedMessages();
|
||||
}
|
||||
|
||||
renderEmpty = () => (
|
||||
<View style={styles.listEmptyContainer}>
|
||||
<Text>No mentioned messages</Text>
|
||||
</View>
|
||||
)
|
||||
|
||||
renderItem = ({ item }) => (
|
||||
<Message
|
||||
item={item}
|
||||
style={styles.message}
|
||||
reactions={item.reactions}
|
||||
user={this.props.user}
|
||||
baseUrl={this.props.baseUrl}
|
||||
Message_TimeFormat='MMMM Do YYYY, h:mm:ss a'
|
||||
onLongPress={() => {}}
|
||||
/>
|
||||
)
|
||||
|
||||
render() {
|
||||
if (this.props.messages.length === 0) {
|
||||
return this.renderEmpty();
|
||||
}
|
||||
return (
|
||||
<FlatList
|
||||
key='mentioned-messages-view-list'
|
||||
data={this.props.messages}
|
||||
renderItem={this.renderItem}
|
||||
style={styles.list}
|
||||
keyExtractor={item => item._id}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
import { StyleSheet } from 'react-native';
|
||||
|
||||
export default StyleSheet.create({
|
||||
list: {
|
||||
flex: 1,
|
||||
backgroundColor: '#ffffff'
|
||||
},
|
||||
message: {
|
||||
transform: [{ scaleY: 1 }]
|
||||
},
|
||||
listEmptyContainer: {
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: '#ffffff'
|
||||
}
|
||||
});
|
|
@ -43,7 +43,7 @@ export default class PinnedMessagesView extends React.PureComponent {
|
|||
};
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
componentDidMount() {
|
||||
this.props.openPinnedMessages(this.props.navigation.state.params.rid);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { View, SectionList, Text, StyleSheet } from 'react-native';
|
||||
import { View, SectionList, Text } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/Ionicons';
|
||||
import MaterialIcon from 'react-native-vector-icons/MaterialIcons';
|
||||
import { connect } from 'react-redux';
|
||||
|
@ -9,6 +9,7 @@ import styles from './styles';
|
|||
import Avatar from '../../containers/Avatar';
|
||||
import Touch from '../../utils/touch';
|
||||
import database from '../../lib/realm';
|
||||
import RocketChat from '../../lib/rocketchat';
|
||||
|
||||
@connect(state => ({
|
||||
baseUrl: state.settings.Site_Url || state.server ? state.server.server : ''
|
||||
|
@ -29,25 +30,19 @@ export default class RoomActionsView extends React.PureComponent {
|
|||
};
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
componentDidMount() {
|
||||
this.updateRoom();
|
||||
this.updateSections();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.rooms.addListener(this.updateRoom);
|
||||
}
|
||||
|
||||
updateRoom = () => {
|
||||
const [room] = this.rooms;
|
||||
this.setState({ room });
|
||||
this.props.navigation.setParams({
|
||||
f: room.f
|
||||
});
|
||||
this.updateSections();
|
||||
}
|
||||
|
||||
updateSections = () => {
|
||||
updateSections = async() => {
|
||||
const { rid, t } = this.state.room;
|
||||
const sections = [{
|
||||
data: [{ icon: 'ios-star', name: 'USER' }],
|
||||
|
@ -61,7 +56,12 @@ export default class RoomActionsView extends React.PureComponent {
|
|||
}, {
|
||||
data: [
|
||||
{ icon: 'ios-attach', name: 'Files' },
|
||||
{ icon: 'ios-at-outline', name: 'Mentions' },
|
||||
{
|
||||
icon: 'ios-at-outline',
|
||||
name: 'Mentions',
|
||||
route: 'MentionedMessages',
|
||||
params: { rid }
|
||||
},
|
||||
{
|
||||
icon: 'ios-star-outline',
|
||||
name: 'Starred',
|
||||
|
@ -90,7 +90,16 @@ export default class RoomActionsView extends React.PureComponent {
|
|||
renderItem: this.renderItem
|
||||
});
|
||||
} else if (t === 'c' || t === 'p') {
|
||||
sections[2].data.unshift({ icon: 'ios-people', name: 'Members', description: '42 members' });
|
||||
const membersResult = await RocketChat.getRoomMembers(rid, false);
|
||||
const members = membersResult.records;
|
||||
|
||||
sections[2].data.unshift({
|
||||
icon: 'ios-people',
|
||||
name: 'Members',
|
||||
description: (members.length === 1 ? `${ members.length } member` : `${ members.length } members`),
|
||||
route: 'RoomMembers',
|
||||
params: { rid, members }
|
||||
});
|
||||
sections.push({
|
||||
data: [
|
||||
{ icon: 'ios-volume-off', name: 'Mute channel' },
|
||||
|
@ -102,21 +111,28 @@ export default class RoomActionsView extends React.PureComponent {
|
|||
this.setState({ sections });
|
||||
}
|
||||
|
||||
renderRoomInfo = ({ item }) => this.renderTouchableItem([
|
||||
<Avatar
|
||||
key='avatar'
|
||||
text={this.state.room.name}
|
||||
size={50}
|
||||
style={StyleSheet.flatten(styles.avatar)}
|
||||
baseUrl={this.props.baseUrl}
|
||||
type={this.state.room.t}
|
||||
/>,
|
||||
<View key='name' style={styles.roomTitleContainer}>
|
||||
<Text style={styles.roomTitle}>{this.state.room.fname}</Text>
|
||||
<Text style={styles.roomDescription}>@{this.state.room.name}</Text>
|
||||
</View>,
|
||||
<Icon key='icon' name='ios-arrow-forward' size={20} style={styles.sectionItemIcon} color='#cbced1' />
|
||||
], item)
|
||||
renderRoomInfo = ({ item }) => {
|
||||
const {
|
||||
fname, name, t, topic
|
||||
} = this.state.room;
|
||||
return (
|
||||
this.renderTouchableItem([
|
||||
<Avatar
|
||||
key='avatar'
|
||||
text={name}
|
||||
size={50}
|
||||
style={styles.avatar}
|
||||
baseUrl={this.props.baseUrl}
|
||||
type={t}
|
||||
/>,
|
||||
<View key='name' style={styles.roomTitleContainer}>
|
||||
<Text style={styles.roomTitle}>{t === 'd' ? fname : name}</Text>
|
||||
<Text style={styles.roomDescription} ellipsizeMode='tail' numberOfLines={1}>{t === 'd' ? `@${ name }` : topic}</Text>
|
||||
</View>,
|
||||
<Icon key='icon' name='ios-arrow-forward' size={20} style={styles.sectionItemIcon} color='#cbced1' />
|
||||
], item)
|
||||
);
|
||||
}
|
||||
|
||||
renderTouchableItem = (subview, item) => (
|
||||
<Touch
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { FlatList, Text, View, TextInput } from 'react-native';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import styles from './styles';
|
||||
import Avatar from '../../containers/Avatar';
|
||||
import Status from '../../containers/status';
|
||||
import Touch from '../../utils/touch';
|
||||
import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
||||
import RocketChat from '../../lib/rocketchat';
|
||||
import { goRoom } from '../../containers/routes/NavigationService';
|
||||
import database from '../../lib/realm';
|
||||
|
||||
@connect(state => ({
|
||||
user: state.login.user,
|
||||
baseUrl: state.settings.Site_Url || state.server ? state.server.server : ''
|
||||
}))
|
||||
export default class MentionedMessagesView extends React.PureComponent {
|
||||
static propTypes = {
|
||||
navigation: PropTypes.object
|
||||
}
|
||||
|
||||
static navigationOptions = ({ navigation }) => {
|
||||
const params = navigation.state.params || {};
|
||||
const label = params.allUsers ? 'All' : 'Online';
|
||||
if (params.allUsers === undefined) {
|
||||
return;
|
||||
}
|
||||
return {
|
||||
headerRight: (
|
||||
<Touch
|
||||
onPress={params.onPressToogleStatus}
|
||||
underlayColor='#ffffff'
|
||||
activeOpacity={0.5}
|
||||
accessibilityLabel={label}
|
||||
accessibilityTraits='button'
|
||||
style={styles.headerButtonTouchable}
|
||||
>
|
||||
<View style={styles.headerButton}>
|
||||
<Text style={styles.headerButtonText}>{label}</Text>
|
||||
</View>
|
||||
</Touch>
|
||||
)
|
||||
};
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const { rid, members } = props.navigation.state.params;
|
||||
this.state = {
|
||||
allUsers: false,
|
||||
filtering: false,
|
||||
rid,
|
||||
members,
|
||||
membersFiltered: []
|
||||
};
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
this.props.navigation.setParams({
|
||||
onPressToogleStatus: this.onPressToogleStatus,
|
||||
allUsers: this.state.allUsers
|
||||
});
|
||||
}
|
||||
|
||||
onSearchChangeText = (text) => {
|
||||
let membersFiltered = [];
|
||||
if (text) {
|
||||
membersFiltered = this.state.members.filter(m => m.username.toLowerCase().match(text.toLowerCase()));
|
||||
}
|
||||
this.setState({ filtering: !!text, membersFiltered });
|
||||
}
|
||||
|
||||
onPressToogleStatus = async() => {
|
||||
const allUsers = !this.state.allUsers;
|
||||
this.props.navigation.setParams({ allUsers });
|
||||
const membersResult = await RocketChat.getRoomMembers(this.state.rid, allUsers);
|
||||
const members = membersResult.records;
|
||||
this.setState({ allUsers, members });
|
||||
}
|
||||
|
||||
onPressItem = async(item) => {
|
||||
const subscriptions = database.objects('subscriptions').filtered('name = $0', item.username);
|
||||
if (subscriptions.length) {
|
||||
goRoom({ rid: subscriptions[0].rid, name: subscriptions[0].name });
|
||||
} else {
|
||||
const room = await RocketChat.createDirectMessage(item.username);
|
||||
goRoom({ room: room.rid, name: item.username });
|
||||
}
|
||||
}
|
||||
|
||||
renderSearchBar = () => (
|
||||
<View style={styles.searchBoxView}>
|
||||
<TextInput
|
||||
underlineColorAndroid='transparent'
|
||||
style={styles.searchBox}
|
||||
onChangeText={text => this.onSearchChangeText(text)}
|
||||
returnKeyType='search'
|
||||
placeholder='Search'
|
||||
clearButtonMode='while-editing'
|
||||
blurOnSubmit
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
|
||||
renderSeparator = () => <View style={styles.separator} />;
|
||||
|
||||
renderItem = ({ item }) => (
|
||||
<Touch
|
||||
onPress={() => this.onPressItem(item)}
|
||||
underlayColor='#ffffff'
|
||||
activeOpacity={0.5}
|
||||
accessibilityLabel={`Start a conversation with ${ item.username }`}
|
||||
accessibilityTraits='button'
|
||||
>
|
||||
<View style={styles.item}>
|
||||
<Avatar text={item.username} size={30} type='d' style={styles.avatar}>{<Status style={styles.status} id={item._id} />}</Avatar>
|
||||
<Text style={styles.username}>{item.username}</Text>
|
||||
</View>
|
||||
</Touch>
|
||||
)
|
||||
|
||||
render() {
|
||||
const { filtering, members, membersFiltered } = this.state;
|
||||
return (
|
||||
<FlatList
|
||||
key='room-members-view-list'
|
||||
data={filtering ? membersFiltered : members}
|
||||
renderItem={this.renderItem}
|
||||
style={styles.list}
|
||||
keyExtractor={item => item._id}
|
||||
ItemSeparatorComponent={this.renderSeparator}
|
||||
ListHeaderComponent={this.renderSearchBar}
|
||||
{...scrollPersistTaps}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
import { StyleSheet } from 'react-native';
|
||||
|
||||
export default StyleSheet.create({
|
||||
list: {
|
||||
flex: 1,
|
||||
backgroundColor: '#ffffff'
|
||||
},
|
||||
item: {
|
||||
flexDirection: 'row',
|
||||
paddingVertical: 8,
|
||||
paddingHorizontal: 16,
|
||||
alignItems: 'center'
|
||||
},
|
||||
avatar: {
|
||||
marginRight: 16
|
||||
},
|
||||
status: {
|
||||
position: 'absolute',
|
||||
bottom: -3,
|
||||
right: -3,
|
||||
borderWidth: 2,
|
||||
borderColor: '#fff',
|
||||
borderRadius: 12,
|
||||
width: 12,
|
||||
height: 12
|
||||
},
|
||||
separator: {
|
||||
height: StyleSheet.hairlineWidth,
|
||||
backgroundColor: '#ddd'
|
||||
},
|
||||
username: {
|
||||
flex: 1,
|
||||
fontSize: 16,
|
||||
color: '#444'
|
||||
},
|
||||
headerButtonTouchable: {
|
||||
borderRadius: 4
|
||||
},
|
||||
headerButton: {
|
||||
padding: 6,
|
||||
backgroundColor: 'transparent',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
headerButtonText: {
|
||||
color: '#292E35'
|
||||
},
|
||||
searchBoxView: {
|
||||
backgroundColor: '#eee'
|
||||
},
|
||||
searchBox: {
|
||||
backgroundColor: '#fff',
|
||||
margin: 5,
|
||||
borderRadius: 5,
|
||||
padding: 5,
|
||||
paddingLeft: 10,
|
||||
color: '#aaa'
|
||||
}
|
||||
});
|
|
@ -27,7 +27,7 @@ export class DataSource extends OldList.DataSource {
|
|||
}
|
||||
}
|
||||
|
||||
const ds = new DataSource({ rowHasChanged: (r1, r2) => r1._id !== r2._id });
|
||||
const ds = new DataSource({ rowHasChanged: (r1, r2) => r1._id !== r2._id || r1._updatedAt.toISOString() !== r2._updatedAt.toISOString() });
|
||||
|
||||
export class List extends React.Component {
|
||||
static propTypes = {
|
||||
|
|
|
@ -78,7 +78,7 @@ export default class RoomView extends React.Component {
|
|||
this.onReactionPress = this.onReactionPress.bind(this);
|
||||
}
|
||||
|
||||
async componentWillMount() {
|
||||
async componentDidMount() {
|
||||
this.props.navigation.setParams({
|
||||
title: this.name
|
||||
});
|
||||
|
|
|
@ -43,7 +43,7 @@ export default class StarredMessagesView extends React.PureComponent {
|
|||
};
|
||||
}
|
||||
|
||||
componentWillMount() {
|
||||
componentDidMount() {
|
||||
this.props.openStarredMessages(this.props.navigation.state.params.rid);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue