diff --git a/app/containers/message/Url.js b/app/containers/message/Url.js new file mode 100644 index 000000000..d2484d58b --- /dev/null +++ b/app/containers/message/Url.js @@ -0,0 +1,71 @@ +import React from 'react'; +import { View, Text, TouchableOpacity, Linking, StyleSheet, Image } from 'react-native'; +import PropTypes from 'prop-types'; + +const styles = StyleSheet.create({ + button: { + flex: 1, + height: 80, + flexDirection: 'row', + alignItems: 'center', + marginVertical: 2 + }, + quoteSign: { + borderWidth: 2, + borderRadius: 4, + borderColor: '#a0a0a0', + height: '100%', + marginRight: 5 + }, + image: { + height: 80, + width: 80, + resizeMode: 'cover', + borderRadius: 6 + }, + textContainer: { + flex: 1, + height: '100%', + flexDirection: 'column', + padding: 4, + justifyContent: 'flex-start', + alignItems: 'flex-start' + }, + title: { + fontWeight: 'bold', + fontSize: 12 + }, + description: { + fontSize: 12 + } +}); + +const Url = ({ url }) => { + if (!url) { + return null; + } + + const onPress = () => { + Linking.openURL(url.url); + }; + + return ( + onPress()} style={styles.button}> + + + + {url.title} + {url.description} + + + ); +}; + +Url.propTypes = { + url: PropTypes.object.isRequired +}; + +export default Url; diff --git a/app/containers/message/index.js b/app/containers/message/index.js index 5304b73a6..8333fc798 100644 --- a/app/containers/message/index.js +++ b/app/containers/message/index.js @@ -10,6 +10,7 @@ import Avatar from '../Avatar'; import Audio from './Audio'; import Video from './Video'; import Markdown from './Markdown'; +import Url from './Url'; const styles = StyleSheet.create({ content: { @@ -51,7 +52,6 @@ export default class Message extends React.Component { onLongPress() { const { item } = this.props; - console.warn(item) this.props.actionsShow(JSON.parse(JSON.stringify(item))); } @@ -87,21 +87,14 @@ export default class Message extends React.Component { ); } - renderMetaUrl() { + renderUrl() { if (this.props.item.urls.length === 0) { return null; } - return ( - - - - - Title - Description - - - ); + return this.props.item.urls.map(url => ( + + )); } render() { @@ -139,7 +132,7 @@ export default class Message extends React.Component { /> {this.attachments()} {this.renderMessageContent()} - {this.renderMetaUrl()} + {this.renderUrl()} ); diff --git a/app/lib/realm.js b/app/lib/realm.js index cc399bcde..4cf7c12b2 100644 --- a/app/lib/realm.js +++ b/app/lib/realm.js @@ -115,15 +115,16 @@ const attachment = { } }; -// const url = { -// name: 'url', -// properties: { -// url: { type: 'string', optional: true }, -// title: { type: 'string', optional: true }, -// description: { type: 'string', optional: true }, -// author: { type: 'string', optional: true } -// } -// }; +const url = { + name: 'url', + properties: { + _id: 'int', + url: { type: 'string', optional: true }, + title: { type: 'string', optional: true }, + description: { type: 'string', optional: true }, + image: { type: 'string', optional: true } + } +}; const messagesEditedBySchema = { @@ -152,7 +153,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' }, _updatedAt: { type: 'date', optional: true }, temp: { type: 'bool', optional: true }, pinned: { type: 'bool', optional: true }, @@ -176,7 +177,7 @@ const realm = new Realm({ messagesEditedBySchema, permissionsSchema, permissionsRolesSchema, - // url + url ], deleteRealmIfMigrationNeeded: true }); diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index 22db66ba7..20074c71a 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -70,6 +70,9 @@ const RocketChat = { message.temp = false; message._server = server; message.attachments = message.attachments || []; + if (message.urls) { + message.urls = RocketChat._parseUrls(message.urls); + } message.starred = message.starred && message.starred.length > 0; realm.create('messages', message, true); }); @@ -246,6 +249,25 @@ const RocketChat = { return call('raix:push-setuser', pushId); }, + _parseUrls(urls) { + urls = urls.filter(url => url.meta && !url.ignoreParse); + urls = urls.map((url, index) => { + const tmp = {}; + const { meta } = url; + tmp._id = index; + tmp.title = meta.ogTitle || meta.twitterTitle || meta.title || meta.pageTitle || meta.oembedTitle; + tmp.description = meta.ogDescription || meta.twitterDescription || meta.description || meta.oembedAuthorName; + let decodedOgImage; + if (meta.ogImage) { + decodedOgImage = meta.ogImage.replace(/&/g, '&'); + } + tmp.image = decodedOgImage || meta.twitterImage || meta.oembedThumbnailUrl; + tmp.url = url.url; + return tmp; + }); + return urls; + }, + loadMessagesForRoom(rid, end, cb) { return new Promise((resolve, reject) => { Meteor.call('loadHistory', rid, end, 20, (err, data) => { @@ -256,13 +278,14 @@ const RocketChat = { return reject(err); } if (data && data.messages.length) { - console.log(data) realm.write(() => { data.messages.forEach((message) => { message.temp = false; message._server = { id: reduxStore.getState().server.server }; message.attachments = message.attachments || []; - message.urls = message.urls || []; + if (message.urls) { + message.urls = RocketChat._parseUrls(message.urls); + } // write('messages', message); message.starred = !!message.starred; realm.create('messages', message, true);