[NEW] lastmessage (#236)

* attempt to add last message

* Custom emoji

* status
This commit is contained in:
Guilherme Gazzo 2018-02-16 16:34:25 -02:00 committed by GitHub
parent 9222d4567a
commit 9e1b37be11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 1765 additions and 788 deletions

View File

@ -3,7 +3,7 @@ import { Provider } from 'react-redux';
import { createStore, combineReducers } from 'redux';
const reducers = combineReducers({settings:() => ({})});
const reducers = combineReducers({login:() => ({user: {}}), settings:() => ({})});
const store = createStore(reducers);
import React from 'react';

View File

@ -34,9 +34,11 @@ exports[`render channel 1`] = `
Array [
Object {
"alignItems": "center",
"borderBottomColor": "#ddd",
"borderBottomWidth": 0.5,
"flexDirection": "row",
"paddingHorizontal": 16,
"paddingVertical": 10,
"paddingVertical": 12,
},
undefined,
]
@ -48,13 +50,12 @@ exports[`render channel 1`] = `
Object {
"alignItems": "center",
"justifyContent": "center",
"overflow": "hidden",
},
Object {
"backgroundColor": "#00BCD4",
"borderRadius": 4,
"height": 40,
"width": 40,
"height": 46,
"width": 46,
},
undefined,
]
@ -75,7 +76,7 @@ exports[`render channel 1`] = `
"color": "#ffffff",
},
Object {
"fontSize": 20,
"fontSize": 23,
},
],
Object {
@ -93,44 +94,70 @@ exports[`render channel 1`] = `
style={
Object {
"flex": 1,
"height": "100%",
"marginLeft": 16,
"marginRight": 4,
}
}
>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
style={
Array [
Object {
"color": "#444",
"flex": 1,
"fontSize": 16,
},
undefined,
]
}
>
general
</Text>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
<View
style={
Object {
"color": "#888",
"alignItems": "center",
"flex": 1,
"fontSize": 10,
"flexDirection": "row",
"justifyContent": "center",
"width": "100%",
}
}
>
Nov 10
</Text>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
style={
Array [
Object {
"color": "#444",
"flex": 1,
"fontSize": 18,
"marginRight": 8,
},
undefined,
]
}
>
general
</Text>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
style={
Object {
"alignItems": "center",
"color": "#888",
"fontSize": 10,
"justifyContent": "center",
}
}
>
Nov 10
</Text>
</View>
<View
style={
Object {
"alignItems": "flex-end",
"flex": 1,
"flexDirection": "row",
"justifyContent": "flex-end",
"width": "100%",
}
}
/>
</View>
</View>
</View>
@ -171,9 +198,11 @@ exports[`render no icon 1`] = `
Array [
Object {
"alignItems": "center",
"borderBottomColor": "#ddd",
"borderBottomWidth": 0.5,
"flexDirection": "row",
"paddingHorizontal": 16,
"paddingVertical": 10,
"paddingVertical": 12,
},
undefined,
]
@ -185,13 +214,12 @@ exports[`render no icon 1`] = `
Object {
"alignItems": "center",
"justifyContent": "center",
"overflow": "hidden",
},
Object {
"backgroundColor": "#3F51B5",
"borderRadius": 4,
"height": 40,
"width": 40,
"height": 46,
"width": 46,
},
undefined,
]
@ -212,7 +240,7 @@ exports[`render no icon 1`] = `
"color": "#ffffff",
},
Object {
"fontSize": 20,
"fontSize": 23,
},
],
Object {
@ -230,44 +258,70 @@ exports[`render no icon 1`] = `
style={
Object {
"flex": 1,
"height": "100%",
"marginLeft": 16,
"marginRight": 4,
}
}
>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
style={
Array [
Object {
"color": "#444",
"flex": 1,
"fontSize": 16,
},
undefined,
]
}
>
name
</Text>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
<View
style={
Object {
"color": "#888",
"alignItems": "center",
"flex": 1,
"fontSize": 10,
"flexDirection": "row",
"justifyContent": "center",
"width": "100%",
}
}
>
Nov 10
</Text>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
style={
Array [
Object {
"color": "#444",
"flex": 1,
"fontSize": 18,
"marginRight": 8,
},
undefined,
]
}
>
name
</Text>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
style={
Object {
"alignItems": "center",
"color": "#888",
"fontSize": 10,
"justifyContent": "center",
}
}
>
Nov 10
</Text>
</View>
<View
style={
Object {
"alignItems": "flex-end",
"flex": 1,
"flexDirection": "row",
"justifyContent": "flex-end",
"width": "100%",
}
}
/>
</View>
</View>
</View>
@ -308,9 +362,11 @@ exports[`render private group 1`] = `
Array [
Object {
"alignItems": "center",
"borderBottomColor": "#ddd",
"borderBottomWidth": 0.5,
"flexDirection": "row",
"paddingHorizontal": 16,
"paddingVertical": 10,
"paddingVertical": 12,
},
undefined,
]
@ -322,13 +378,12 @@ exports[`render private group 1`] = `
Object {
"alignItems": "center",
"justifyContent": "center",
"overflow": "hidden",
},
Object {
"backgroundColor": "#FF9800",
"borderRadius": 4,
"height": 40,
"width": 40,
"height": 46,
"width": 46,
},
undefined,
]
@ -349,7 +404,7 @@ exports[`render private group 1`] = `
"color": "#ffffff",
},
Object {
"fontSize": 20,
"fontSize": 23,
},
],
Object {
@ -367,44 +422,70 @@ exports[`render private group 1`] = `
style={
Object {
"flex": 1,
"height": "100%",
"marginLeft": 16,
"marginRight": 4,
}
}
>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
style={
Array [
Object {
"color": "#444",
"flex": 1,
"fontSize": 16,
},
undefined,
]
}
>
private-group
</Text>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
<View
style={
Object {
"color": "#888",
"alignItems": "center",
"flex": 1,
"fontSize": 10,
"flexDirection": "row",
"justifyContent": "center",
"width": "100%",
}
}
>
Nov 10
</Text>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
style={
Array [
Object {
"color": "#444",
"flex": 1,
"fontSize": 18,
"marginRight": 8,
},
undefined,
]
}
>
private-group
</Text>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
style={
Object {
"alignItems": "center",
"color": "#888",
"fontSize": 10,
"justifyContent": "center",
}
}
>
Nov 10
</Text>
</View>
<View
style={
Object {
"alignItems": "flex-end",
"flex": 1,
"flexDirection": "row",
"justifyContent": "flex-end",
"width": "100%",
}
}
/>
</View>
</View>
</View>
@ -446,9 +527,11 @@ exports[`render unread +999 1`] = `
Array [
Object {
"alignItems": "center",
"borderBottomColor": "#ddd",
"borderBottomWidth": 0.5,
"flexDirection": "row",
"paddingHorizontal": 16,
"paddingVertical": 10,
"paddingVertical": 12,
},
undefined,
]
@ -460,13 +543,12 @@ exports[`render unread +999 1`] = `
Object {
"alignItems": "center",
"justifyContent": "center",
"overflow": "hidden",
},
Object {
"backgroundColor": "#3F51B5",
"borderRadius": 4,
"height": 40,
"width": 40,
"height": 46,
"width": 46,
},
undefined,
]
@ -482,7 +564,7 @@ exports[`render unread +999 1`] = `
"color": "#ffffff",
},
Object {
"fontSize": 20,
"fontSize": 23,
},
]
}
@ -490,70 +572,120 @@ exports[`render unread +999 1`] = `
NA
</Text>
<View
style={
Array [
Object {
"borderRadius": 16,
"height": 16,
"width": 16,
},
Object {
"borderColor": "#fff",
"borderWidth": 3,
"bottom": -3,
"position": "absolute",
"right": -3,
},
Object {
"backgroundColor": "#cbced1",
},
]
}
/>
</View>
<View
style={
Object {
"flex": 1,
"height": "100%",
"marginLeft": 16,
"marginRight": 4,
}
}
>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
style={
Array [
Object {
"color": "#444",
"flex": 1,
"fontSize": 16,
},
undefined,
]
}
>
name
</Text>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
<View
style={
Object {
"color": "#888",
"alignItems": "center",
"flex": 1,
"fontSize": 10,
"flexDirection": "row",
"justifyContent": "center",
"width": "100%",
}
}
>
Nov 10
</Text>
</View>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
style={
Object {
"backgroundColor": "#1d74f5",
"borderRadius": 3,
"color": "#fff",
"fontSize": 14,
"minWidth": 20,
"overflow": "hidden",
"paddingHorizontal": 5,
"paddingVertical": 2,
"textAlign": "center",
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
style={
Array [
Object {
"color": "#444",
"flex": 1,
"fontSize": 18,
"marginRight": 8,
},
undefined,
]
}
>
name
</Text>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
style={
Object {
"alignItems": "center",
"color": "#888",
"fontSize": 10,
"justifyContent": "center",
}
}
>
Nov 10
</Text>
</View>
<View
style={
Object {
"alignItems": "flex-end",
"flex": 1,
"flexDirection": "row",
"justifyContent": "flex-end",
"width": "100%",
}
}
}
>
999+
</Text>
>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
style={
Object {
"alignItems": "center",
"backgroundColor": "#1d74f5",
"borderRadius": 4,
"color": "#fff",
"fontSize": 14,
"justifyContent": "center",
"minWidth": 25,
"overflow": "hidden",
"paddingHorizontal": 5,
"paddingVertical": 4,
"textAlign": "center",
}
}
>
999+
</Text>
</View>
</View>
</View>
</View>
</View>
@ -593,9 +725,11 @@ exports[`render unread 1`] = `
Array [
Object {
"alignItems": "center",
"borderBottomColor": "#ddd",
"borderBottomWidth": 0.5,
"flexDirection": "row",
"paddingHorizontal": 16,
"paddingVertical": 10,
"paddingVertical": 12,
},
undefined,
]
@ -607,13 +741,12 @@ exports[`render unread 1`] = `
Object {
"alignItems": "center",
"justifyContent": "center",
"overflow": "hidden",
},
Object {
"backgroundColor": "#3F51B5",
"borderRadius": 4,
"height": 40,
"width": 40,
"height": 46,
"width": 46,
},
undefined,
]
@ -629,7 +762,7 @@ exports[`render unread 1`] = `
"color": "#ffffff",
},
Object {
"fontSize": 20,
"fontSize": 23,
},
]
}
@ -637,70 +770,120 @@ exports[`render unread 1`] = `
NA
</Text>
<View
style={
Array [
Object {
"borderRadius": 16,
"height": 16,
"width": 16,
},
Object {
"borderColor": "#fff",
"borderWidth": 3,
"bottom": -3,
"position": "absolute",
"right": -3,
},
Object {
"backgroundColor": "#cbced1",
},
]
}
/>
</View>
<View
style={
Object {
"flex": 1,
"height": "100%",
"marginLeft": 16,
"marginRight": 4,
}
}
>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
style={
Array [
Object {
"color": "#444",
"flex": 1,
"fontSize": 16,
},
undefined,
]
}
>
name
</Text>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
<View
style={
Object {
"color": "#888",
"alignItems": "center",
"flex": 1,
"fontSize": 10,
"flexDirection": "row",
"justifyContent": "center",
"width": "100%",
}
}
>
Nov 10
</Text>
</View>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
style={
Object {
"backgroundColor": "#1d74f5",
"borderRadius": 3,
"color": "#fff",
"fontSize": 14,
"minWidth": 20,
"overflow": "hidden",
"paddingHorizontal": 5,
"paddingVertical": 2,
"textAlign": "center",
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
style={
Array [
Object {
"color": "#444",
"flex": 1,
"fontSize": 18,
"marginRight": 8,
},
undefined,
]
}
>
name
</Text>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
style={
Object {
"alignItems": "center",
"color": "#888",
"fontSize": 10,
"justifyContent": "center",
}
}
>
Nov 10
</Text>
</View>
<View
style={
Object {
"alignItems": "flex-end",
"flex": 1,
"flexDirection": "row",
"justifyContent": "flex-end",
"width": "100%",
}
}
}
>
1
</Text>
>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
style={
Object {
"alignItems": "center",
"backgroundColor": "#1d74f5",
"borderRadius": 4,
"color": "#fff",
"fontSize": 14,
"justifyContent": "center",
"minWidth": 25,
"overflow": "hidden",
"paddingHorizontal": 5,
"paddingVertical": 4,
"textAlign": "center",
}
}
>
1
</Text>
</View>
</View>
</View>
</View>
</View>
@ -740,9 +923,11 @@ exports[`renders correctly 1`] = `
Array [
Object {
"alignItems": "center",
"borderBottomColor": "#ddd",
"borderBottomWidth": 0.5,
"flexDirection": "row",
"paddingHorizontal": 16,
"paddingVertical": 10,
"paddingVertical": 12,
},
undefined,
]
@ -754,13 +939,12 @@ exports[`renders correctly 1`] = `
Object {
"alignItems": "center",
"justifyContent": "center",
"overflow": "hidden",
},
Object {
"backgroundColor": "#3F51B5",
"borderRadius": 4,
"height": 40,
"width": 40,
"height": 46,
"width": 46,
},
undefined,
]
@ -776,7 +960,7 @@ exports[`renders correctly 1`] = `
"color": "#ffffff",
},
Object {
"fontSize": 20,
"fontSize": 23,
},
]
}
@ -784,49 +968,96 @@ exports[`renders correctly 1`] = `
NA
</Text>
<View
style={
Array [
Object {
"borderRadius": 16,
"height": 16,
"width": 16,
},
Object {
"borderColor": "#fff",
"borderWidth": 3,
"bottom": -3,
"position": "absolute",
"right": -3,
},
Object {
"backgroundColor": "#cbced1",
},
]
}
/>
</View>
<View
style={
Object {
"flex": 1,
"height": "100%",
"marginLeft": 16,
"marginRight": 4,
}
}
>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
style={
Array [
Object {
"color": "#444",
"flex": 1,
"fontSize": 16,
},
undefined,
]
}
>
name
</Text>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
<View
style={
Object {
"color": "#888",
"alignItems": "center",
"flex": 1,
"fontSize": 10,
"flexDirection": "row",
"justifyContent": "center",
"width": "100%",
}
}
>
Nov 10
</Text>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
style={
Array [
Object {
"color": "#444",
"flex": 1,
"fontSize": 18,
"marginRight": 8,
},
undefined,
]
}
>
name
</Text>
<Text
accessible={true}
allowFontScaling={true}
ellipsizeMode="tail"
numberOfLines={1}
style={
Object {
"alignItems": "center",
"color": "#888",
"fontSize": 10,
"justifyContent": "center",
}
}
>
Nov 10
</Text>
</View>
<View
style={
Object {
"alignItems": "flex-end",
"flex": 1,
"flexDirection": "row",
"justifyContent": "flex-end",
"width": "100%",
}
}
/>
</View>
</View>
</View>

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -1,4 +1,4 @@
package com.rocketchatrn;
package chat.rocket.reactnative;
import android.content.Intent;
import android.content.pm.ResolveInfo;

View File

@ -1,4 +1,4 @@
package com.rocketchatrn;
package chat.rocket.reactnative;
import android.content.Context;
import android.content.Intent;

View File

@ -44,7 +44,8 @@ public class MainApplication extends Application implements ReactApplication {
new ReactVideoPackage(),
new SplashScreenReactPackage(),
new RCTToastPackage(),
new KeyboardInputPackage(MainApplication.this)
new KeyboardInputPackage(MainApplication.this),
new RocketChatNativePackage()
);
}
};

View File

@ -1,4 +1,4 @@
package com.rocketchatrn;
package chat.rocket.reactnative;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;

View File

@ -8,7 +8,7 @@ import avatarInitialsAndColor from '../utils/avatarInitialsAndColor';
const styles = StyleSheet.create({
iconContainer: {
overflow: 'hidden',
// overflow: 'hidden',
justifyContent: 'center',
alignItems: 'center'
},
@ -31,7 +31,8 @@ export default class Avatar extends React.PureComponent {
avatar: PropTypes.string,
size: PropTypes.number,
borderRadius: PropTypes.number,
type: PropTypes.string
type: PropTypes.string,
children: PropTypes.object
};
render() {
const {
@ -68,6 +69,7 @@ export default class Avatar extends React.PureComponent {
<View style={[styles.iconContainer, iconContainerStyle, style]}>
<Text style={[styles.avatarInitials, avatarInitialsStyle]} allowFontScaling={false}>{initials}</Text>
{image}
{this.props.children}
</View>);
}

View File

@ -18,6 +18,7 @@ import {
} from '../actions/messages';
import { showToast } from '../utils/info';
const returnAnArray = obj => obj || [];
@connect(
state => ({
showActions: state.messages.showActions,
@ -171,11 +172,11 @@ export default class MessageActions extends React.Component {
}
setPermissions(permissions) {
this.hasEditPermission = permissions['edit-message']
this.hasEditPermission = returnAnArray(permissions['edit-message'])
.some(item => this.mergedRoles.indexOf(item) !== -1);
this.hasDeletePermission = permissions['delete-message']
this.hasDeletePermission = returnAnArray(permissions['delete-message'])
.some(item => this.mergedRoles.indexOf(item) !== -1);
this.hasForceDeletePermission = permissions['force-delete-message']
this.hasForceDeletePermission = returnAnArray(permissions['force-delete-message'])
.some(item => this.mergedRoles.indexOf(item) !== -1);
}

View File

@ -1,5 +1,5 @@
import React from 'react';
import { Text, StyleSheet } from 'react-native';
import { Text, StyleSheet, ViewPropTypes } from 'react-native';
import PropTypes from 'prop-types';
import EasyMarkdown from 'react-native-easy-markdown'; // eslint-disable-line
import SimpleMarkdown from 'simple-markdown';
@ -17,13 +17,15 @@ const BlockCode = ({ node, state }) => (
);
const mentionStyle = { color: '#13679a' };
const Markdown = ({ msg, customEmojis }) => {
const Markdown = ({
msg, customEmojis, style, markdownStyle, customRules, renderInline
}) => {
if (!msg) {
return null;
}
msg = emojify(msg, { output: 'unicode' });
const rules = {
const defaultRules = {
username: {
order: -1,
match: SimpleMarkdown.inlineRegex(/^@[0-9a-zA-Z-_.]+/),
@ -121,11 +123,13 @@ const Markdown = ({ msg, customEmojis }) => {
};
const codeStyle = StyleSheet.flatten(styles.codeStyle);
style = StyleSheet.flatten(style);
return (
<EasyMarkdown
style={{ marginBottom: 0 }}
rules={rules}
markdownStyles={{ code: codeStyle }}
style={{ marginBottom: 0, ...style }}
markdownStyles={{ code: codeStyle, ...markdownStyle }}
rules={{ ...defaultRules, ...customRules }}
renderInline={renderInline}
>{msg}
</EasyMarkdown>
);
@ -133,7 +137,12 @@ const Markdown = ({ msg, customEmojis }) => {
Markdown.propTypes = {
msg: PropTypes.string.isRequired,
customEmojis: PropTypes.object
customEmojis: PropTypes.object,
// eslint-disable-next-line react/no-typos
style: ViewPropTypes.style,
markdownStyle: PropTypes.object,
customRules: PropTypes.object,
renderInline: PropTypes.bool
};
BlockCode.propTypes = {

39
app/containers/status.js Normal file
View File

@ -0,0 +1,39 @@
import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { StyleSheet, View, ViewPropTypes } from 'react-native';
import { STATUS_COLORS } from '../constants/colors';
const styles = StyleSheet.create({
status: {
borderRadius: 16,
width: 16,
height: 16
}
});
@connect(state => ({
activeUsers: state.activeUsers
}))
export default class Status extends React.Component {
static propTypes = {
style: ViewPropTypes.style,
id: PropTypes.string,
activeUsers: PropTypes.object
};
shouldComponentUpdate(nextProps) {
const userId = this.props.id;
return this.status !== nextProps.activeUsers[userId];
}
get status() {
const userId = this.props.id;
return (this.props.activeUsers && this.props.activeUsers[userId]) || 'offline';
}
render() {
return (<View style={[styles.status, this.props.style, { backgroundColor: STATUS_COLORS[this.status] }]} />);
}
}

View File

@ -49,6 +49,7 @@ const roomsSchema = {
properties: {
_id: 'string',
t: 'string',
lastMessage: 'messages',
_updatedAt: { type: 'date', optional: true }
}
};
@ -80,7 +81,8 @@ const subscriptionSchema = {
// userMentions: 0,
// groupMentions: 0,
roomUpdatedAt: { type: 'date', optional: true },
ro: { type: 'bool', optional: true }
ro: { type: 'bool', optional: true },
lastMessage: { type: 'messages', optional: true }
}
};
@ -134,7 +136,7 @@ const attachment = {
const url = {
name: 'url',
properties: {
_id: 'int',
// _id: { type: 'int', optional: true },
url: { type: 'string', optional: true },
title: { type: 'string', optional: true },
description: { type: 'string', optional: true },
@ -183,7 +185,7 @@ const messagesSchema = {
groupable: { type: 'bool', optional: true },
avatar: { type: 'string', optional: true },
attachments: { type: 'list', objectType: 'attachment' },
urls: { type: 'list', objectType: 'url' },
urls: { type: 'list', objectType: 'url', default: [] },
_updatedAt: { type: 'date', optional: true },
status: { type: 'int', optional: true },
pinned: { type: 'bool', optional: true },

View File

@ -128,11 +128,12 @@ const RocketChat = {
const sub = database.objects('subscriptions').filtered('rid == $0', data._id)[0];
database.write(() => {
sub.roomUpdatedAt = data._updatedAt;
sub.lastMessage = data.lastMessage;
sub.ro = data.ro;
});
}
});
});
}).catch(console.log);
},
me({ server, token, userId }) {
@ -428,6 +429,7 @@ const RocketChat = {
const room = rooms.find(({ _id }) => _id === subscription.rid);
if (room) {
subscription.roomUpdatedAt = room._updatedAt;
subscription.lastMessage = room.lastMessage;
subscription.ro = room.ro;
}
if (subscription.roles) {
@ -435,10 +437,14 @@ const RocketChat = {
}
return subscription;
});
database.write(() => {
data.forEach(subscription =>
database.create('subscriptions', subscription, true));
data.forEach(subscription => database.create('subscriptions', subscription, true));
// rooms.forEach(room => database.create('rooms', room, true));
});
this.ddp.subscribe('stream-notify-user', `${ login.user.id }/subscriptions-changed`, false);
this.ddp.subscribe('stream-notify-user', `${ login.user.id }/rooms-changed`, false);
return data;

View File

@ -2,36 +2,60 @@ import React from 'react';
import moment from 'moment';
import PropTypes from 'prop-types';
import { View, Text, StyleSheet } from 'react-native';
import { connect } from 'react-redux';
import SimpleMarkdown from 'simple-markdown';
import Avatar from '../containers/Avatar';
import Status from '../containers/status';
import Touch from '../utils/touch/index'; //eslint-disable-line
import Markdown from '../containers/message/Markdown';
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
paddingHorizontal: 16,
paddingVertical: 10,
alignItems: 'center'
paddingVertical: 12,
alignItems: 'center',
borderBottomWidth: 0.5,
borderBottomColor: '#ddd'
},
number: {
minWidth: 20,
borderRadius: 3,
minWidth: 25,
borderRadius: 4,
backgroundColor: '#1d74f5',
color: '#fff',
textAlign: 'center',
overflow: 'hidden',
fontSize: 14,
paddingVertical: 4,
paddingHorizontal: 5,
paddingVertical: 2
textAlign: 'center',
alignItems: 'center',
justifyContent: 'center'
},
roomNameView: {
flex: 1,
height: '100%',
marginLeft: 16,
marginRight: 4
},
roomName: {
flex: 1,
fontSize: 16,
color: '#444'
fontSize: 18,
color: '#444',
marginRight: 8
},
lastMessage: {
flex: 1,
flexShrink: 1,
marginRight: 8,
maxHeight: 20,
overflow: 'hidden',
flexDirection: 'row',
alignItems: 'flex-start',
justifyContent: 'flex-start'
},
alert: {
fontWeight: 'bold'
@ -39,30 +63,144 @@ const styles = StyleSheet.create({
favorite: {
// backgroundColor: '#eee'
},
update: {
row: {
width: '100%',
flex: 1,
flexDirection: 'row',
alignItems: 'flex-end',
justifyContent: 'flex-end'
},
firstRow: {
width: '100%',
flex: 1,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center'
},
update: {
fontSize: 10,
// height: 10,
color: '#888'
color: '#888',
alignItems: 'center',
justifyContent: 'center'
},
status: {
position: 'absolute',
bottom: -3,
right: -3,
borderWidth: 3,
borderColor: '#fff'
}
});
const markdownStyle = { block: { marginBottom: 0, flexWrap: 'wrap', flexDirection: 'row' } };
const parseInline = (parse, content, state) => {
const isCurrentlyInline = state.inline || false;
state.inline = true;
const result = parse(content, state);
state.inline = isCurrentlyInline;
return result;
};
const parseCaptureInline = (capture, parse, state) => ({ content: parseInline(parse, capture[1], state) });
const customRules = {
strong: {
order: -4,
match: SimpleMarkdown.inlineRegex(/^\*\*([\s\S]+?)\*\*(?!\*)/),
parse: parseCaptureInline,
react: (node, output, state) => ({
type: 'strong',
key: state.key,
props: {
children: output(node.content, state)
}
})
},
text: {
order: -3,
match: SimpleMarkdown.inlineRegex(/^[\s\S]+?(?=[^0-9A-Za-z\s\u00c0-\uffff]|\n\n| {2,}\n|\w+:\S|$)/),
parse: capture => ({ content: capture[0] }),
react: node => node.content
}
};
const renderNumber = (unread, userMentions) => {
if (!unread || unread <= 0) {
return;
}
if (unread >= 1000) {
unread = '999+';
}
if (userMentions > 0) {
unread = `@ ${ unread }`;
}
return (
<Text style={styles.number}>
{ unread }
</Text>
);
};
@connect(state => ({
user: state.login && state.login.user,
StoreLastMessage: state.settings.Store_Last_Message,
customEmojis: state.customEmojis
}))
export default class RoomItem extends React.PureComponent {
static propTypes = {
type: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
StoreLastMessage: PropTypes.bool,
_updatedAt: PropTypes.instanceOf(Date),
lastMessage: PropTypes.object,
favorite: PropTypes.bool,
alert: PropTypes.bool,
unread: PropTypes.number,
userMentions: PropTypes.number,
baseUrl: PropTypes.string,
onPress: PropTypes.func
id: PropTypes.string,
onPress: PropTypes.func,
customEmojis: PropTypes.object,
user: PropTypes.object
}
get icon() {
const { type, name, baseUrl } = this.props;
return <Avatar text={name} baseUrl={baseUrl} size={40} type={type} />;
const {
type, name, id
} = this.props;
return (<Avatar text={name} size={46} type={type}>{type === 'd' ? <Status style={styles.status} id={id} /> : null }</Avatar>);
}
get lastMessage() {
const {
lastMessage, alert, type
} = this.props;
if (!this.props.StoreLastMessage) {
return '';
}
if (!lastMessage) {
return 'No Message';
}
let prefix = '';
if (lastMessage.u.username === this.props.user.username) {
prefix = 'You: ';
} else if (type !== 'd') {
prefix = `${ lastMessage.u.username }: `;
}
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 ? '...' : '' }`;
}
formatDate = date => moment(date).calendar(null, {
@ -72,29 +210,9 @@ export default class RoomItem extends React.PureComponent {
sameElse: 'MMM D'
})
renderNumber = (unread, userMentions) => {
if (!unread || unread <= 0) {
return;
}
if (unread >= 1000) {
unread = '999+';
}
if (userMentions > 0) {
unread = `@ ${ unread }`;
}
return (
<Text style={styles.number}>
{ unread }
</Text>
);
}
render() {
const {
favorite, alert, unread, userMentions, name, _updatedAt
favorite, unread, userMentions, name, _updatedAt, customEmojis, alert
} = this.props;
const date = this.formatDate(_updatedAt);
@ -117,10 +235,23 @@ export default class RoomItem extends React.PureComponent {
<View style={[styles.container, favorite && styles.favorite]}>
{this.icon}
<View style={styles.roomNameView}>
<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}
<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}
</View>
<View style={styles.row}>
<Markdown
msg={this.lastMessage}
customEmojis={customEmojis}
style={styles.lastMessage}
markdownStyle={markdownStyle}
customRules={customRules}
renderInline
numberOfLines={1}
/>
{renderNumber(unread, userMentions)}
</View>
</View>
{this.renderNumber(unread, userMentions)}
</View>
</Touch>
);

View File

@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Text, View, Button, LayoutAnimation } from 'react-native';
import { Text, View, Button } from 'react-native';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import equal from 'deep-equal';
@ -51,8 +51,8 @@ export default class RoomView extends React.Component {
Message_TimeFormat: PropTypes.string,
loading: PropTypes.bool,
actionMessage: PropTypes.object,
toggleReactionPicker: PropTypes.func.isRequired,
layoutAnimation: PropTypes.instanceOf(Date)
toggleReactionPicker: PropTypes.func.isRequired
// layoutAnimation: PropTypes.instanceOf(Date)
};
static navigationOptions = ({ navigation }) => ({
@ -90,11 +90,11 @@ export default class RoomView extends React.Component {
this.rooms.addListener(this.updateRoom);
}
componentWillReceiveProps(nextProps) {
if (this.props.layoutAnimation !== nextProps.layoutAnimation) {
LayoutAnimation.spring();
}
}
// componentWillReceiveProps(nextProps) {
// // if (this.props.layoutAnimation !== nextProps.layoutAnimation) {
// // LayoutAnimation.spring();
// // }
// }
shouldComponentUpdate(nextProps, nextState) {
return !(equal(this.props, nextProps) && equal(this.state, nextState));
}

View File

@ -18,6 +18,7 @@ import styles from './styles';
const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
@connect(state => ({
user: state.login.user,
server: state.server.server,
login: state.login,
Site_Url: state.settings.Site_Url,
@ -31,6 +32,7 @@ const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
export default class RoomsListView extends React.Component {
static propTypes = {
navigation: PropTypes.object.isRequired,
user: PropTypes.object,
Site_Url: PropTypes.string,
server: PropTypes.string,
searchText: PropTypes.string
@ -69,7 +71,9 @@ export default class RoomsListView extends React.Component {
this.search(props.searchText);
}
}
// componentWillUpdate() {
// LayoutAnimation.easeInEaseOut();
// }
componentWillUnmount() {
this.data.removeAllListeners();
}
@ -79,6 +83,12 @@ export default class RoomsListView extends React.Component {
this.search(text);
}
getLastMessage = (subscription) => {
const [room] = database.objects('rooms').filtered('_id = $0', subscription.rid).slice();
console.log('ROOM', room);
return room && room.lastMessage;
}
search(text) {
const searchText = text.trim();
if (searchText === '') {
@ -197,20 +207,23 @@ export default class RoomsListView extends React.Component {
</View>
);
renderItem = item => (
<RoomItem
renderItem = (item) => {
const id = item.rid.replace(this.props.user.id, '').trim();
return (<RoomItem
alert={item.alert}
unread={item.unread}
userMentions={item.userMentions}
favorite={item.f}
lastMessage={item.lastMessage}
name={item.name}
_updatedAt={item.roomUpdatedAt}
key={item._id}
id={id}
type={item.t}
baseUrl={this.props.Site_Url}
onPress={() => this._onPressItem(item)}
/>
)
/>);
}
renderList = () => (
<ListView

2
package-lock.json generated
View File

@ -12505,7 +12505,7 @@
}
},
"react-native-easy-markdown": {
"version": "git+https://github.com/diegolmello/react-native-easy-markdown.git#ed1afe45f870524f6c23a4ca1df97770f0979c74",
"version": "git+https://github.com/diegolmello/react-native-easy-markdown.git#600a79faf4fdac2c21cfebeb01f96b997674dabe",
"requires": {
"simple-markdown": "0.1.2"
},