diff --git a/assets/info-icon.png b/assets/info-icon.png new file mode 100644 index 0000000..d670537 Binary files /dev/null and b/assets/info-icon.png differ diff --git a/components/ChannelList/ChannelList.jsx b/components/ChannelList/ChannelList.jsx index 64ab873..3196413 100644 --- a/components/ChannelList/ChannelList.jsx +++ b/components/ChannelList/ChannelList.jsx @@ -38,6 +38,10 @@ export default class ChannelList extends React.Component { if (this.props.onPressChannel) this.props.onPressChannel(id, name); } + onLongPressChannel = (id, name) => { + if (this.props.onLongPressChannel) this.props.onLongPressChannel(id, name); + } + updateSubscription = (id, index) => { if (['all', 'subs', 'myPosts'].includes(id)) return; @@ -105,7 +109,9 @@ export default class ChannelList extends React.Component { - this.onPressChannel(channel.id, channel.name)}> + this.onPressChannel(channel.id, channel.name)} + onLongPress={() => this.onLongPressChannel(channel.id, channel.name)}> {channel.name} @@ -147,5 +153,6 @@ export default class ChannelList extends React.Component { ChannelList.propTypes = { onPressChannel: PropTypes.func, + onLongPressChannel: PropTypes.func, channels: PropTypes.array, } diff --git a/components/ChannelProfile/ChannelProfile.jsx b/components/ChannelProfile/ChannelProfile.jsx new file mode 100644 index 0000000..d13041b --- /dev/null +++ b/components/ChannelProfile/ChannelProfile.jsx @@ -0,0 +1,59 @@ +import React from 'react'; +import { Modal, View, TouchableOpacity } from 'react-native'; +import { Text, Icon } from 'native-base'; + +import styles from '../../components/ChannelProfile/ChannelProfileStyle'; + +export default class ChannelProfile extends React.Component { + + onClose = () => { + const { onClose } = this.props; + onClose(); + } + + render() { + const { + channel: channelData, + isModalOpen, + } = this.props; + + if (!channelData) return null; + if (!channelData.description) return null; + + return ( + + + + + + + + + + + + {`${channelData.name}`} + + + + {channelData.description && {`${channelData.description}`}} + + + + + + ) + } +} \ No newline at end of file diff --git a/components/ChannelProfile/ChannelProfileStyle.js b/components/ChannelProfile/ChannelProfileStyle.js new file mode 100644 index 0000000..a53ebe9 --- /dev/null +++ b/components/ChannelProfile/ChannelProfileStyle.js @@ -0,0 +1,30 @@ +import { StyleSheet, Dimensions } from 'react-native'; + +import userProfileStyles from '../../components/UserProfile/UserProfileStyle' + +export default (styles = StyleSheet.create({ + modal: { + ...userProfileStyles.modal + }, + card: { + ...userProfileStyles.card + }, + cancelRow: { + ...userProfileStyles.cancelRow + }, + cancelIcon: { + ...userProfileStyles.cancelIcon + }, + name: { + ...userProfileStyles.name + }, + infoBlock: { + ...userProfileStyles.infoBlock, + }, + cardChannelDescription: { + height: 200 + }, + channelInfoText: { + textAlign: 'center' + } +})); \ No newline at end of file diff --git a/components/Comment/Comment.jsx b/components/Comment/Comment.jsx index e4941a1..febc8a8 100644 --- a/components/Comment/Comment.jsx +++ b/components/Comment/Comment.jsx @@ -1,7 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import Autolink from 'react-native-autolink'; -import { Dimensions, TouchableOpacity, View, Modal } from 'react-native'; +import { ScrollView, TouchableOpacity, View, Modal } from 'react-native'; import { Text, Thumbnail, ListItem, Card, CardItem, Container, Content, Left, Icon, Button @@ -10,6 +10,7 @@ import _ from 'lodash'; import { AppLoading } from "expo"; import * as Font from 'expo-font'; import date from 'date-fns'; +import Popover from 'react-native-popover-view'; import styles from "./CommentStyle"; import {getProfilePicture} from "../../helpers/imageCache" @@ -25,6 +26,7 @@ export default class Comment extends React.Component { profilePicture: null, showEditButtons: false, editing: false, + showLikedList: false } } @@ -85,10 +87,58 @@ export default class Comment extends React.Component { updateComment && updateComment(commentId, {}, "deleteComment"); } + toggleLike = () => { + const { + data, + loggedInUser, + updateComment + } = this.props; + + if (data.usersLiked.find((user) => user._id === loggedInUser._id)) { + data.usersLiked = data.usersLiked.filter(user => user._id !== loggedInUser._id); + } else { + console.log("pushing") + data.usersLiked.push({ + _id: loggedInUser._id, + firstname: loggedInUser.firstName, + lastName: loggedInUser.lastName + }); + } + + if (data.likes < 0) data.likes = 0; // (Grebel's a positive community, come on!) + console.log("Updating resource") + updateComment && updateComment(data._id, data, 'toggleCommentLike'); + console.log("Updating resource") + } + + generateLikesList = () => { + let { + usersLiked + } = this.props.data; + + if (usersLiked.filter(e => e._id == this.props.loggedInUser._id).length) { + usersLiked = usersLiked.filter(user => user._id !== this.props.loggedInUser._id); + usersLiked.unshift({ firstName: 'You' }); // a wee hack + } + + return ( + + + + {usersLiked.map((user, i) => { + return ( + {user.firstName} {user.lastName || ''} + ) + })} + + ) + } + render() { const { showEditButtons, - editing + editing, + showLikedList } = this.state; const { @@ -101,6 +151,7 @@ export default class Comment extends React.Component { author, content, createdAt, + usersLiked, } = data; var authorName; @@ -125,6 +176,11 @@ export default class Comment extends React.Component { ) } + const isLiked = usersLiked.filter(e => e._id == this.props.loggedInUser._id).length > 0; + + var likeIcon = isLiked ? require('../../assets/liked-cookie.png') : require('../../assets/cookie-icon.png'); + var likesDialog = usersLiked.length > 0 ? usersLiked.length : ''; + return ( @@ -146,10 +202,31 @@ export default class Comment extends React.Component { {`${createdAt} `} - + + + + this.setState({ showLikedList: true })} + ref={ref => this.dialogRef = ref} + hitSlop={{ top: 40, bottom: 10, left: 30, right: 40 }} + > + {`${likesDialog}`} + + + + + + + this.setState({ showLikedList: false })} + > + {this.generateLikesList()} + diff --git a/components/Comment/CommentStyle.js b/components/Comment/CommentStyle.js index c15cfd4..b114694 100644 --- a/components/Comment/CommentStyle.js +++ b/components/Comment/CommentStyle.js @@ -27,18 +27,21 @@ export default (styles = StyleSheet.create({ justifyContent: 'flex-start', alignItems: 'flex-start' }, + textAuthor: { paddingLeft: 5, fontWeight: 'bold' }, textContent: { - paddingLeft: 5 + paddingLeft: 5, + fontSize: 16, + flex: 1 }, editButtonsContainer: { flex: 1, flexDirection: 'column', justifyContent: 'flex-end', - alignItems: 'center', + alignItems: 'bottom', backgroundColor: '#00000050' }, view: { @@ -66,5 +69,47 @@ export default (styles = StyleSheet.create({ flexDirection: 'row', justifyContent: 'space-between', paddingBottom: 5 - } + }, + icon: { + width: 25, + height: 25, + marginRight: 0, + paddingRight: 0 + }, + iconContainer: { + flexDirection: 'column', + padding: 5, + flex: 0 + }, + likesDialog: { + fontSize: 12, + paddingBottom: 3, + flex: 1, + textAlignVertical: 'bottom', + alignSelf: 'center' + }, + + likedList: { + padding: 20, + display: 'flex', + flexDirection: 'column', + justifyContent: 'flex-start', + alignItems: 'flex-start', + }, + likedListIcon: { + width: 25, + height: 25, + marginBottom: 10, + alignSelf: 'center' + }, + line: { + width: '100%', + borderBottomWidth: 1, + borderBottomColor: '#C0C0C0', + paddingLeft: 20, + paddingRight: 20 + }, + likedListItem: { + padding: 5 + } })); diff --git a/components/CommentEditor/CommentEditor.jsx b/components/CommentEditor/CommentEditor.jsx index 0ecb302..77b6430 100644 --- a/components/CommentEditor/CommentEditor.jsx +++ b/components/CommentEditor/CommentEditor.jsx @@ -52,10 +52,6 @@ export default class CommentEditor extends React.Component { } render() { - const { - showEditButtons, - editing - } = this.state; const { author @@ -90,6 +86,7 @@ export default class CommentEditor extends React.Component { onChangeText={this.textUpdate} value={this.state.commentText} multiline = {true} + scrollEnabled = {false} /> {this.state.commentText ? diff --git a/components/CommentEditor/CommentEditorStyle.js b/components/CommentEditor/CommentEditorStyle.js index 09b4639..42bb932 100644 --- a/components/CommentEditor/CommentEditorStyle.js +++ b/components/CommentEditor/CommentEditorStyle.js @@ -34,9 +34,10 @@ export default (styles = StyleSheet.create({ }, textContent: { paddingLeft: 5, - height: 38, flexGrow: 1, - flexShrink: 1 + flexShrink: 1, + minHeight:38, + fontSize: 16 }, editButtonsContainer: { flex: 1, diff --git a/components/Post/Post.jsx b/components/Post/Post.jsx index 7748fc8..4fb81e6 100644 --- a/components/Post/Post.jsx +++ b/components/Post/Post.jsx @@ -375,7 +375,7 @@ export default class Post extends React.Component { - + {poll ? (this.props.onPressPost ? diff --git a/components/Post/PostStyle.js b/components/Post/PostStyle.js index 11276cb..dd8328e 100644 --- a/components/Post/PostStyle.js +++ b/components/Post/PostStyle.js @@ -18,6 +18,9 @@ export default (styles = StyleSheet.create({ paddingTop: 0, paddingBottom: 0, }, + autolinkContent: { + fontSize: 16 + }, postFooter: { marginTop: 3, marginBottom: 3 diff --git a/components/UserProfile/UserProfileStyle.js b/components/UserProfile/UserProfileStyle.js index 9543e72..4e27d7d 100644 --- a/components/UserProfile/UserProfileStyle.js +++ b/components/UserProfile/UserProfileStyle.js @@ -48,7 +48,8 @@ export default (styles = StyleSheet.create({ fontWeight: "400", fontSize: 26, marginTop: 10, - marginBottom: 15 + marginBottom: 15, + textAlign: 'center' }, infoBlock: { alignSelf: 'flex-start', diff --git a/views/Comments/Comments.jsx b/views/Comments/Comments.jsx index 90c2093..7d008ec 100644 --- a/views/Comments/Comments.jsx +++ b/views/Comments/Comments.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Container, Content, Text } from 'native-base'; +import { Container, Content, Text} from 'native-base'; import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view' import * as Font from 'expo-font'; @@ -12,6 +12,7 @@ import defaultStyles from "../../styles/styles"; import _ from 'lodash' import CommentEditor from '../../components/CommentEditor/CommentEditor'; import Spinner from '../../components/Spinner/Spinner' +import { ScrollView, KeyboardAvoidingView, } from 'react-native'; export default class CommentsView extends React.Component { @@ -80,7 +81,7 @@ export default class CommentsView extends React.Component { } updateResource = async (id, data, type) => { - + console.log(type) const { navigation, } = this.props; @@ -104,6 +105,22 @@ export default class CommentsView extends React.Component { console.error(err); alert("Error updating post. Sorry about that!"); }); + } else if (['toggleCommentLike'].includes(type)) { + const addLike = data.usersLiked.some(user => user._id === loggedInUser._id); + console.log(addLike) + ApiClient.post(`/posts/${postData._id}/comment/${id}/like`, { addLike }, {authorized: true}) + .then(() => { + postData.comments.forEach((comment) =>{ + if(comment._id === id){ + comment = data; + } + }); + this.setState({ postData}); + }) + .catch(err => { + console.error(err); + alert("Error updating post. Sorry about that!"); + }); } else if (type === 'editPoll') { @@ -242,7 +259,7 @@ export default class CommentsView extends React.Component { showFullDate={true} navigation={this.props.navigation} /> - + {_.map(_.orderBy(comments, comment => comment.createdAt.valueOf()), (comment, key) => { var enableCommentEditing = comment.author._id === loggedInUser._id; @@ -255,13 +272,15 @@ export default class CommentsView extends React.Component { enableEditing={enableCommentEditing} enableDeleting={ loggedInUser.role && loggedInUser.role.includes("admin")} showUserProfile={this.showUserProfile} + loggedInUser={loggedInUser} /> ) })} - - + + + -