Other attachments
This commit is contained in:
parent
562738bec6
commit
ab627b8d54
|
@ -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;
|
|
@ -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()} {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;
|
|
@ -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) }}
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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' }
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue