Other attachments

This commit is contained in:
Diego Mello 2017-12-01 16:06:19 -02:00
parent 562738bec6
commit ab627b8d54
6 changed files with 150 additions and 9 deletions

View File

@ -0,0 +1,20 @@
import React from 'react';
import { View, StyleSheet } from 'react-native';
import PropTypes from 'prop-types';
const styles = StyleSheet.create({
quoteSign: {
borderWidth: 2,
borderRadius: 4,
height: '100%',
marginRight: 5
}
});
const QuoteMark = ({ color }) => <View style={[styles.quoteSign, { borderColor: color || '#a0a0a0' }]} />;
QuoteMark.propTypes = {
color: PropTypes.string
};
export default QuoteMark;

View File

@ -0,0 +1,107 @@
import React from 'react';
import { View, Text, TouchableOpacity, StyleSheet, Linking } from 'react-native';
import PropTypes from 'prop-types';
import moment from 'moment';
import Markdown from './Markdown';
import QuoteMark from './QuoteMark';
import Avatar from '../Avatar';
const styles = StyleSheet.create({
button: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
marginTop: 2,
alignSelf: 'flex-end'
},
quoteSign: {
borderWidth: 2,
borderRadius: 4,
borderColor: '#a0a0a0',
height: '100%',
marginRight: 5
},
attachmentContainer: {
flex: 1,
flexDirection: 'column'
},
authorContainer: {
flexDirection: 'row',
alignItems: 'center'
},
avatar: {
margin: 2
},
time: {
fontSize: 10,
fontWeight: 'normal',
color: '#888',
marginLeft: 5
}
});
const onPress = (attachment) => {
const url = attachment.title_link || attachment.author_link;
if (!url) {
return;
}
Linking.openURL(attachment.title_link || attachment.author_link);
};
const Reply = ({ attachment, timeFormat }) => {
if (!attachment) {
return null;
}
const renderAvatar = () => {
if (!attachment.author_icon && !attachment.author_name) {
return null;
}
return (
<Avatar
style={styles.avatar}
text={attachment.author_name}
size={16}
avatar={attachment.author_icon}
/>
);
};
const renderAuthor = () => (
attachment.author_name ? <Text style={{ fontWeight: 'bold' }}>{attachment.author_name}</Text> : null
);
const renderTime = () => {
const time = attachment.ts ? moment(attachment.ts).format(timeFormat) : null;
return time ? <Text style={styles.time}>{ time }</Text> : null;
};
const renderText = () => (
attachment.text ? <Markdown msg={attachment.text} /> : null
);
return (
<TouchableOpacity
onPress={() => onPress(attachment)}
style={styles.button}
>
<QuoteMark color={attachment.color} />
<View style={styles.attachmentContainer}>
<View style={styles.authorContainer}>
<Text>
{renderAvatar()} &nbsp; {renderAuthor()} {renderTime()}
</Text>
</View>
{renderText()}
{attachment.attachments.map(attach => <Reply attachment={attach} timeFormat={timeFormat} />)}
</View>
</TouchableOpacity>
);
};
Reply.propTypes = {
attachment: PropTypes.object.isRequired,
timeFormat: PropTypes.string.isRequired
};
export default Reply;

View File

@ -2,10 +2,11 @@ import React from 'react';
import { View, Text, TouchableOpacity, Linking, StyleSheet, Image } from 'react-native';
import PropTypes from 'prop-types';
import QuoteMark from './QuoteMark';
const styles = StyleSheet.create({
button: {
flex: 1,
height: 80,
flexDirection: 'row',
alignItems: 'center',
marginVertical: 2
@ -49,7 +50,7 @@ const Url = ({ url }) => {
}
return (
<TouchableOpacity onPress={() => onPress(url.url)} style={styles.button}>
<View style={styles.quoteSign} />
<QuoteMark />
<Image
style={styles.image}
source={{ uri: encodeURI(url.image) }}

View File

@ -11,6 +11,7 @@ import Audio from './Audio';
import Video from './Video';
import Markdown from './Markdown';
import Url from './Url';
import Reply from './Reply';
const styles = StyleSheet.create({
content: {
@ -59,6 +60,10 @@ export default class Message extends React.Component {
return this.props.item.t === 'rm';
}
isPinned() {
return this.props.item.t === 'message_pinned';
}
attachments() {
if (this.props.item.attachments.length === 0) {
return null;
@ -74,17 +79,16 @@ export default class Message extends React.Component {
return <Video file={file} baseUrl={baseUrl} user={user} />;
}
return <Text>Other type</Text>;
return <Reply attachment={file} timeFormat={this.props.Message_TimeFormat} />;
}
renderMessageContent() {
if (this.isDeleted()) {
return <Text style={styles.textInfo}>Message removed</Text>;
} else if (this.isPinned()) {
return <Text style={styles.textInfo}>Message pinned</Text>;
}
return (
<Markdown msg={this.props.item.msg} />
);
return <Markdown msg={this.props.item.msg} />;
}
renderUrl() {
@ -130,8 +134,8 @@ export default class Message extends React.Component {
Message_TimeFormat={this.props.Message_TimeFormat}
baseUrl={this.props.baseUrl}
/>
{this.attachments()}
{this.renderMessageContent()}
{this.attachments()}
{this.renderUrl()}
</View>
</TouchableOpacity>

View File

@ -111,7 +111,14 @@ const attachment = {
title: { type: 'string', optional: true },
title_link: { type: 'string', optional: true },
title_link_download: { type: 'bool', optional: true },
type: { type: 'string', optional: true }
type: { type: 'string', optional: true },
author_icon: { type: 'string', optional: true },
author_name: { type: 'string', optional: true },
author_link: { type: 'string', optional: true },
text: { type: 'string', optional: true },
color: { type: 'string', optional: true },
ts: { type: 'date', optional: true },
attachments: { type: 'list', objectType: 'attachment' }
}
};

View File

@ -265,6 +265,8 @@ const RocketChat = {
if (message.urls) {
message.urls = RocketChat._parseUrls(message.urls);
}
// 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);
return message;
},