Skip to content

Commit c2f7725

Browse files
committed
[ptmt#3] Optimize rendering for SimpleChat, add embeds
1 parent 1451ac0 commit c2f7725

File tree

7 files changed

+84
-28
lines changed

7 files changed

+84
-28
lines changed

Examples/SimpleChatClient/actions.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,9 @@ export function init(): any {
7070
if (!getState().selectedChannel) {
7171
dispatch(onChannelSelect(payload.servers[0].channels[0].id));
7272
}
73+
if (getState().selectedChannel && !getState().messages) {
74+
dispatch(onChannelSelect(getState().selectedChannel));
75+
}
7376
})
7477
)
7578
.catch(e => {

Examples/SimpleChatClient/components/ChatLayout.js

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ var {
1010
Text,
1111
TouchableOpacity,
1212
TouchableHighlight,
13-
TextInput
13+
TextInput,
14+
LayoutAnimation
1415
} = React;
1516

1617
import LoadingIndicator from './LoadingIndicator';
@@ -52,9 +53,23 @@ class ChatLayout extends React.Component {
5253
if (!text) {
5354
return;
5455
}
56+
LayoutAnimation.spring();
5557
this.props.actions.sendMessage(text);
5658
this.setState({currentMessage: ''});
5759
}
60+
render1() {
61+
const messages = this.props.messages ?
62+
<View style={{backgroundColor: 'black', flex: 1}} /> :
63+
<Text key={'loading_indicator'}>Loading messages...</Text>;
64+
65+
console.log('MESSAGES', messages);
66+
67+
return (
68+
<View style={{flex: 1}}>
69+
{messages}
70+
</View>
71+
);
72+
}
5873
render() {
5974
const servers = this.props.servers && this.props.servers.map((server, serverKey) => {
6075
return (
@@ -84,7 +99,7 @@ class ChatLayout extends React.Component {
8499
<View style={{flex: 1}}>
85100
{messages && messages.length > 0 ?
86101
<MessagesListView messages={messages} /> :
87-
<LoadingIndicator visible={messages}>Loading messages...</LoadingIndicator>
102+
<LoadingIndicator>Loading messages...</LoadingIndicator>
88103
}
89104
</View>
90105
<View style={styles.inputWrapper}>

Examples/SimpleChatClient/components/LoadingIndicator.js

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,9 @@ import React, {
88
} from 'react-native-desktop';
99

1010
export default class LoadingIndicator extends React.Component {
11-
componentWillUnmount() {
12-
console.log('on unmount');
13-
}
14-
render(): ReactElement {
15-
const visibilityStyle = this.props.visible ? { opacity: 0} : {};
16-
console.log(this.props.children, visibilityStyle)
11+
render() {
1712
return (
18-
<View style={[styles.container, visibilityStyle]}>
13+
<View style={[styles.container]}>
1914
<ActivityIndicatorIOS size="large" style={{width: 40, alignSelf: 'center'}}/>
2015
<Text>{this.props.children}</Text>
2116
</View>

Examples/SimpleChatClient/components/Message.js

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,46 @@ import React, {
55
View,
66
Text,
77
Image,
8-
StyleSheet,
9-
Animated
8+
StyleSheet
109
} from 'react-native-desktop';
1110

1211
import Markdown from './SuperSimpleMarkdown';
1312

1413
export default class Message extends React.Component {
15-
render(): ReactElement {
14+
render() {
1615
const date = new Date(this.props.timestamp);
1716
const time = ('0' + date.getHours()).slice(-2) + ':' + ('0' + date.getMinutes()).slice(-2);
18-
const attachImage = this.props.attachments && this.props.attachments.length > 0 ?
17+
const attachedImage = this.props.attachments && this.props.attachments.length > 0 && this.props.attachments[0].url ?
1918
this.props.attachments[0].url : null;
19+
20+
const attachedEmbeds = this.props.embeds && this.props.embeds.length > 0 && this.props.embeds[0].thumbnail ?
21+
this.props.embeds[0] : null;
22+
2023
return (
2124
<View style={[styles.message]} key={this.props.id}>
2225
<Text style={styles.messageTimestamp}>{time}</Text>
2326
<Text style={styles.messageUsername} numberOfLines={1}>{'<'}{this.props.author.username}{'>'}</Text>
24-
{attachImage &&
25-
<Image resizeMode={'contain'} source={{uri: attachImage}} style={{width: 300, height: 300}} />
27+
{attachedImage &&
28+
<Image resizeMode={'contain'} source={{uri: attachedImage}} style={{width: 300, height: 300}} />
2629
}
2730
<Markdown>{parseMentions(this.props.content, this.props.mentions)}</Markdown>
31+
{attachedEmbeds &&
32+
<Preview {...attachedEmbeds} />
33+
}
34+
</View>
35+
);
36+
} //
37+
}
38+
39+
class Preview extends React.Component {
40+
render() {
41+
return (
42+
<View style={{flex: 1, margin: 10, borderColor: '#eee', borderWidth: 1, padding: 3}}>
43+
<Text style={{fontSize: 12, textAlign:'center', fontWeight: 'bold'}}>{this.props.title}</Text>
44+
<View style={{flexDirection: 'row', flex: 1, justifyContent: 'center', alignContent: 'center'}}>
45+
<Image resizeMode={'contain'} source={{uri: this.props.thumbnail.url}} style={{margin: 5, width: 80, height: 80}} />
46+
<Text style={{fontSize: 12, color: '#777', margin: 10, width: 200}}>{this.props.description}</Text>
47+
</View>
2848
</View>
2949
);
3050
}
@@ -40,6 +60,7 @@ function parseMentions(text: string, mentions: Array<any>): string {
4060
}
4161
matches.forEach(mention => {
4262
const id = mention.substring(2, mention.length - 1);
63+
// TODO: ignore links
4364
text = text.replace(mention, '**@' + mentions.filter(m => m.id === id)[0].username + '**');
4465
});
4566
return text;

Examples/SimpleChatClient/components/MessagesListView.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import React, {
55
Text,
66
StyleSheet,
7-
ListView,
7+
ListView
88
} from 'react-native-desktop';
99

1010
import Message from './Message';
@@ -26,7 +26,6 @@ export default class MessagesListView extends React.Component {
2626
});
2727
}
2828
render() {
29-
3029
return (
3130
<ListView
3231
style={styles.container}

Examples/SimpleChatClient/components/SuperSimpleMarkdown.js

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ const {
1111
export default class Markdown extends React.Component {
1212

1313
componentWillMount() {
14+
1415
const rules = generateRules(styles);
1516
const mixedRules = { ...rules, ...SimpleMarkdown.defaultRules};
1617
const parser = SimpleMarkdown.parserFor(mixedRules);
@@ -100,7 +101,7 @@ const generateRules = styles => {
100101
return React.createElement(Text, {
101102
key: state.key,
102103
style: [styles.text, styles.link],
103-
children: node.content
104+
children: node.content[0].content
104105
});
105106
}
106107
},
@@ -143,14 +144,20 @@ const generateRules = styles => {
143144
},
144145
text: {
145146
react: function(node, output, state) {
147+
148+
var textStyles = [styles.text];
149+
if (typeof node.content.split !== 'function') {
150+
return React.createElement(Text, {
151+
style: textStyles
152+
}, node.content);
153+
}
146154
//Breaking words up in order to allow for text reflowing in flexbox
147155
var words = node.content.split(' ');
148156
words = words.map((word, i) => {
149157
var elements = [];
150158
if (i != words.length - 1) {
151159
word = word + ' ';
152160
}
153-
var textStyles = [styles.text];
154161
if (!state.withinText) {
155162
textStyles.push(styles.plainText);
156163
}
@@ -159,21 +166,24 @@ const generateRules = styles => {
159166
}, word);
160167
});
161168
return words;
162-
// return React.createElement(Text, {
163-
// style: styles.text
164-
// }, node.content);
165169
}
166170
},
167171
heading: {
168172
react: function(node, output, state) {
173+
var textStyles = [styles.text];
174+
if (typeof node.content.split !== 'function') {
175+
return React.createElement(Text, {
176+
style: textStyles
177+
}, node.content);
178+
}
179+
169180
//Breaking words up in order to allow for text reflowing in flexbox
170181
var words = node.content.split(' ');
171182
words = words.map((word, i) => {
172183
var elements = [];
173184
if (i != words.length - 1) {
174185
word = word + ' ';
175186
}
176-
var textStyles = [styles.text];
177187
if (!state.withinText) {
178188
textStyles.push(styles.plainText);
179189
}

Libraries/CustomComponents/ListView/ListView.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ var React = require('React');
3131
var RCTUIManager = require('NativeModules').UIManager;
3232
var RCTScrollViewManager = require('NativeModules').ScrollViewManager;
3333
var ScrollView = require('ScrollView');
34-
var View = require('View');
3534
var ScrollResponder = require('ScrollResponder');
3635
var StaticRenderer = require('StaticRenderer');
3736
var TimerMixin = require('react-timer-mixin');
@@ -338,23 +337,37 @@ var ListView = React.createClass({
338337
}
339338

340339
for (var rowIdx = 0; rowIdx < rowIDs.length; rowIdx++) {
341-
var rowID = rowIDs[rowIdx];
340+
341+
// Inverting index if this is inverting ListView
342+
var rowID = this.props.autoScrollToBottom ?
343+
rowIDs[rowIdx] :
344+
rowIDs.length - 1 - rowIdx;
345+
342346
var comboID = sectionID + rowID;
343347
var shouldUpdateRow = rowCount >= this.state.prevRenderedRowsCount &&
344-
dataSource.rowShouldUpdate(sectionIdx, rowIdx);
348+
dataSource.rowShouldUpdate(sectionIdx, rowID);
345349
var row =
346350
<StaticRenderer
347351
key={'r_' + comboID}
348352
shouldUpdate={!!shouldUpdateRow}
349353
render={this.props.renderRow.bind(
350354
null,
351-
dataSource.getRowData(sectionIdx, rowIdx),
355+
dataSource.getRowData(sectionIdx, rowID),
352356
sectionID,
353357
rowID,
354358
this.onRowHighlighted
355359
)}
356360
/>;
357-
bodyComponents.push(row);
361+
362+
/*
363+
* Prepend items
364+
*/
365+
if (this.props.autoScrollToBottom) {
366+
bodyComponents = [row].concat(bodyComponents);
367+
} else {
368+
bodyComponents.push(row);
369+
}
370+
358371
totalIndex++;
359372

360373
if (this.props.renderSeparator &&

0 commit comments

Comments
 (0)