From b12dbcda2cb9d40acc033cb06e44b2815123f99e Mon Sep 17 00:00:00 2001 From: skatz Date: Thu, 17 Oct 2019 09:24:46 +0300 Subject: [PATCH 1/4] added linebreaks in long messages --- src/components/Home/Chat/ChatInput.js | 388 +++++++++--------- .../Home/Conversations/Conversation.js | 160 ++++---- 2 files changed, 280 insertions(+), 268 deletions(-) diff --git a/src/components/Home/Chat/ChatInput.js b/src/components/Home/Chat/ChatInput.js index ec5cc8e..d84fac3 100644 --- a/src/components/Home/Chat/ChatInput.js +++ b/src/components/Home/Chat/ChatInput.js @@ -10,202 +10,212 @@ import TagFacesIcon from '@material-ui/icons/TagFaces' import AttachFileIcon from '@material-ui/icons/AttachFile' const useStyles = makeStyles({ - root: { - width: '100%', - position: 'relative', - color: 'rgba(0, 0, 0, 0.87)', - cursor: 'text', - display: 'inline-flex', - fontSize: 17, - boxSizing: 'border-box', - alignItems: 'center', - fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif', - lineHeight: '1.1875em', - border: '1px solid #abb3ea', - '&:focus-within': { - background: 'rgb(245, 246, 251)', - borderColor: '#3f51b5', + root: { + width: '100%', + position: 'relative', + color: 'rgba(0, 0, 0, 0.87)', + cursor: 'text', + display: 'inline-flex', + fontSize: 17, + boxSizing: 'border-box', + alignItems: 'center', + fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif', + lineHeight: '1.1875em', + border: '1px solid #abb3ea', + '&:focus-within': { + background: 'rgb(245, 246, 251)', + borderColor: '#3f51b5', + }, + }, + input: { + whiteSpace: 'pre-wrap', + outline: 'none', + font: 'inherit', + color: 'currentColor', + width: '100%', + border: 0, + minHeight: 64, + maxHeight: 300, + overflowY: 'auto', + overflowX: 'hidden', + margin: 0, + minWidth: 0, + background: 'none', + display: 'inline-block', + padding: 20, + boxSizing: 'border-box', + '&::-webkit-scrollbar': { + width: '6px!important', + height: '6px!important', + }, + '&::-webkit-scrollbar-track': { + background: 'hsla(0,0%,100%,.08)', + }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: 'rgba(0,0,0,.2)', + }, + }, + actions: { + display: 'flex', + alignSelf: 'flex-end', + padding: 8, + borderLeft: '1px solid rgba(171, 179, 234, 0.5)', }, - }, - input: { - whiteSpace: 'pre', - outline: 'none', - font: 'inherit', - color: 'currentColor', - width: '100%', - border: 0, - minHeight: 64, - maxHeight: 300, - overflowY: 'auto', - overflowX: 'hidden', - margin: 0, - minWidth: 0, - background: 'none', - display: 'inline-block', - padding: 20, - boxSizing: 'border-box', - }, - actions: { - display: 'flex', - alignSelf: 'flex-end', - padding: 8, - borderLeft: '1px solid rgba(171, 179, 234, 0.5)', - }, }) export default function ChatInput({ value: text, onChange, onSubmit, required, attachFile }) { - const [showEmojis, setShowEmojis] = React.useState(false) - const [contentHtml, setContentHtml] = React.useState('') - const [range, setRange] = React.useState(null) - const formRef = useRef() - const contentEditableRef = useRef() - const classes = useStyles() - - useEffect(() => { - const value = [...contentEditableRef.current.childNodes].map((e) => { - if (e.nodeName === 'IMG') { - return e.getAttribute('alt') - } else { - return e.nodeValue - } - }).join('') - onChange(value) - }, [contentHtml]) - - - function setCurrentRange(currentRange) { - const cloneCurrentRange = currentRange.cloneRange() - const selection = window.getSelection() - currentRange.collapse(true) - selection.removeAllRanges() - selection.addRange(cloneCurrentRange) - } - - function onKeyPress(e) { - if (e.which === 13 && !e.shiftKey) { - e.preventDefault() - if (text) { - formRef.current.dispatchEvent(new Event('submit', { cancelable: true })) - } + const [showEmojis, setShowEmojis] = React.useState(false) + const [contentHtml, setContentHtml] = React.useState('') + const [range, setRange] = React.useState(null) + const formRef = useRef() + const contentEditableRef = useRef() + const classes = useStyles() + + useEffect(() => { + const value = [...contentEditableRef.current.childNodes].map((e) => { + if (e.nodeName === 'IMG') { + return e.getAttribute('alt') + } else { + return e.nodeValue + } + }).join('') + onChange(value) + }, [contentHtml]) + + + function setCurrentRange(currentRange) { + const cloneCurrentRange = currentRange.cloneRange() + const selection = window.getSelection() + currentRange.collapse(true) + selection.removeAllRanges() + selection.addRange(cloneCurrentRange) + } + + function onKeyPress(e) { + if (e.which === 13 && !e.shiftKey) { + e.preventDefault() + if (text) { + formRef.current.dispatchEvent(new Event('submit', { cancelable: true })) + } + } + } + + function submitForm(e) { + e.preventDefault() + setShowEmojis(false) + setContentHtml('') + onSubmit(text) + } + + function toggleShowEmojis() { + setShowEmojis(!showEmojis) + } + + function addEmoji(emoji) { + const html = createEmojiImg({ emoji }) + + if (document.activeElement !== contentEditableRef.current) { + contentEditableRef.current.focus() + if (range) { + setCurrentRange(range) + } + } + + document.execCommand('insertHTML', false, html) } - } - - function submitForm(e) { - e.preventDefault() - setShowEmojis(false) - setContentHtml('') - onSubmit(text) - } - - function toggleShowEmojis() { - setShowEmojis(!showEmojis) - } - - function addEmoji(emoji) { - const html = createEmojiImg({ emoji }) - - if (document.activeElement !== contentEditableRef.current) { - contentEditableRef.current.focus() - if (range) { - setCurrentRange(range) - } + + function onChangeFileInput(e) { + attachFile(e.target.files.length ? e.target.files.item(0) : null) + e.target.value = '' } - document.execCommand('insertHTML', false, html) - } - - function onChangeFileInput(e) { - attachFile(e.target.files.length ? e.target.files.item(0) : null) - e.target.value = '' - } - - function onChangeContentEditable(e) { - setContentHtml(e.target.value) - saveCurrentRange() - } - - function onPaste(e) { - e.preventDefault() - const text = (e.originalEvent || e).clipboardData.getData('text/plain') - const html = createTextHTML(text) - document.execCommand('insertHTML', false, html) - } - - function saveCurrentRange() { - try { - const currentRange = window.getSelection().getRangeAt(0).cloneRange() - setRange(currentRange) - } catch (e) { - setRange(null) + function onChangeContentEditable(e) { + setContentHtml(e.target.value) + saveCurrentRange() } - } - - return ( -
- - - { - showEmojis && ( - - - - ) - } -
- - - - - - - - - - -
- - ) + + function onPaste(e) { + e.preventDefault() + const text = (e.originalEvent || e).clipboardData.getData('text/plain') + const html = createTextHTML(text) + document.execCommand('insertHTML', false, html) + } + + function saveCurrentRange() { + try { + const currentRange = window.getSelection().getRangeAt(0).cloneRange() + setRange(currentRange) + } catch (e) { + setRange(null) + } + } + + return ( +
+ + + { + showEmojis && ( + + + + ) + } +
+ + + + + + + + + + +
+ + ) } diff --git a/src/components/Home/Conversations/Conversation.js b/src/components/Home/Conversations/Conversation.js index 01f4382..1b2d4cd 100644 --- a/src/components/Home/Conversations/Conversation.js +++ b/src/components/Home/Conversations/Conversation.js @@ -13,98 +13,100 @@ import ConversationAvatar from './ConversationAvatar' import { ConversationTitle } from './ConversationTitle' const useStyles = makeStyles({ - root: { - cursor: 'pointer', - '&:hover': { - background: 'rgba(155, 155, 157, 0.21)', + root: { + cursor: 'pointer', + '&:hover': { + background: 'rgba(155, 155, 157, 0.21)', + }, + display: 'flex', + }, + activeConversation: { + background: 'rgba(155, 155, 157, 0.21)', + }, + counter: { + top: '50%', + alignSelf: 'center', + }, + ellipsis: { + overflow: 'hidden', + textOverflow: 'ellipsis', + maxHeight: '24px', + whiteSpace: 'nowrap', }, - display: 'flex', - }, - activeConversation: { - background: 'rgba(155, 155, 157, 0.21)', - }, - counter: { - top: '50%', - alignSelf: 'center', - }, - ellipsis: { - overflow: 'hidden', - textOverflow: 'ellipsis', - }, }) const Conversation = ({ data: conversation }) => { - const [lastMessage, setLastMessage] = useState('') - const classes = useStyles() - const { id } = conversation - const count = useSelector(store => store.conversations.unreadMessagesCount[id]) - const currentUser = useSelector(store => store.auth.user) - const lastSeen = _get(conversation, `members[${currentUser.uid}].lastSeen`) - const { uid: currentUserId } = currentUser - const dispatch = useDispatch() - const activeConversation = useSelector(store => store.conversations.activeConversation) + const [lastMessage, setLastMessage] = useState('') + const classes = useStyles() + const { id } = conversation + const count = useSelector(store => store.conversations.unreadMessagesCount[id]) + const currentUser = useSelector(store => store.auth.user) + const lastSeen = _get(conversation, `members[${currentUser.uid}].lastSeen`) + const { uid: currentUserId } = currentUser + const dispatch = useDispatch() + const activeConversation = useSelector(store => store.conversations.activeConversation) - function setActive() { - dispatch(setActiveConversation(id)) - } + function setActive() { + dispatch(setActiveConversation(id)) + } - useEffect(() => { - return db - .collection('conversations') - .doc(id) - .collection('messages') - .where('date', '>=', lastSeen || new Date(0)) - .onSnapshot((snapshot) => { - const snapshotData = (snapshot.docs || []).map((doc) => doc.data()) - const count = snapshotData.reduce((count, message) => message.from === currentUserId ? count : count + 1, 0) - dispatch({ type: 'SET_UNREAD_MESSAGES_COUNT', payload: { id, count } }) - }) + useEffect(() => { + return db + .collection('conversations') + .doc(id) + .collection('messages') + .where('date', '>=', lastSeen || new Date(0)) + .onSnapshot((snapshot) => { + const snapshotData = (snapshot.docs || []).map((doc) => doc.data()) + const count = snapshotData.reduce((count, message) => message.from === currentUserId ? count : count + 1, 0) + dispatch({ type: 'SET_UNREAD_MESSAGES_COUNT', payload: { id, count } }) + }) - }, [dispatch, id, lastSeen, currentUserId]) + }, [dispatch, id, lastSeen, currentUserId]) - useEffect(() => { - return db - .collection('conversations') - .doc(id) - .collection('messages') - .orderBy('date', 'desc') - .limit(1) - .onSnapshot((snapshot) => { - if (snapshot.docs.length) { - setLastMessage(snapshot.docs[0].data().text) - } - }) + useEffect(() => { + return db + .collection('conversations') + .doc(id) + .collection('messages') + .orderBy('date', 'desc') + .limit(1) + .onSnapshot((snapshot) => { + if (snapshot.docs.length) { + setLastMessage(snapshot.docs[0].data().text) + } + }) - }, [id, currentUserId]) + }, [id, currentUserId]) - return ( - + return ( + - - - + + + - } - secondary={( - {lastMessage} - )} /> - { - Boolean(count) && ( - - ) - } + } + secondary={( + {lastMessage} + )} /> + { + Boolean(count) && ( + + ) + } - - ) + + ) } export default Conversation From 5a67e1f056fa67362504ef6b5e65200bfb1b8aeb Mon Sep 17 00:00:00 2001 From: skatz Date: Thu, 17 Oct 2019 09:38:36 +0300 Subject: [PATCH 2/4] .editorconfig added --- .editorConfig | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .editorConfig diff --git a/.editorConfig b/.editorConfig new file mode 100644 index 0000000..91b82ac --- /dev/null +++ b/.editorConfig @@ -0,0 +1,8 @@ +root = true + +[*.js] +charset = utf-8 +indent_style = space +indent_size = 4 +insert_final_newline = false +trim_trailing_whitespace = false From 2b776606b4bb4e2475894ede0df9e8cbd881e944 Mon Sep 17 00:00:00 2001 From: skatz Date: Thu, 17 Oct 2019 14:59:39 +0300 Subject: [PATCH 3/4] added video support --- src/components/Home/Chat/Chat.js | 142 ++++---- src/components/Home/Chat/Messages.js | 493 ++++++++++++++------------- 2 files changed, 330 insertions(+), 305 deletions(-) diff --git a/src/components/Home/Chat/Chat.js b/src/components/Home/Chat/Chat.js index b47a257..35bfdf9 100644 --- a/src/components/Home/Chat/Chat.js +++ b/src/components/Home/Chat/Chat.js @@ -10,87 +10,93 @@ import { useSelector } from 'react-redux' import { selectActiveConversation } from '../../../state/actions/conversations' import FileDialog from './FileDialog' +export const fileTypes = { + image: 'image', + video: 'video', +} + const useStyles = makeStyles({ - root: { - flex: 1, - display: 'flex', - justifyContent: 'space-between', - flexDirection: 'column', - position: 'relative', - width: '100%', - height: '100%', - }, + root: { + flex: 1, + display: 'flex', + justifyContent: 'space-between', + flexDirection: 'column', + position: 'relative', + width: '100%', + height: '100%', + }, }) const Chat = () => { - const classes = useStyles() - const listRef = useRef() - const [isDragOn, setIsDragOn] = useState(false) - const [file, setFile] = React.useState(null) - - const currentUser = useSelector(store => store.auth.user) - const activeConversation = useSelector(selectActiveConversation) - - async function onSendMessage(text) { - listRef.current.scrollTop = listRef.current.scrollHeight - setIsDragOn(false) - setFile(null) - - const msgId = uuid() - - const messageRef = db - .collection('conversations') - .doc(activeConversation.id) - .collection('messages') - .doc(msgId) - - await messageRef.set({ - id: msgId, - text, - ...(file ? { file: 'pending' } : {}), - from: currentUser.uid, - date: new Date(), - }) - - if (file) { - const fileRef = await storage.ref(`conversations/${activeConversation.id}/${msgId}`).put(file).then((snapshot) => snapshot.ref.getDownloadURL()) - await messageRef.set({ file: fileRef }, { merge: true }) + const classes = useStyles() + const listRef = useRef() + const [isDragOn, setIsDragOn] = useState(false) + const [file, setFile] = React.useState(null) + + const currentUser = useSelector(store => store.auth.user) + const activeConversation = useSelector(selectActiveConversation) + + async function onSendMessage(text) { + listRef.current.scrollTop = listRef.current.scrollHeight + setIsDragOn(false) + setFile(null) + + const msgId = uuid() + + const messageRef = db + .collection('conversations') + .doc(activeConversation.id) + .collection('messages') + .doc(msgId) + + await messageRef.set({ + id: msgId, + text, + ...(file ? { file: 'pending' } : {}), + ...(file ? { fileType: Object.keys(fileTypes).find(type => file.type.includes(type)) } : {}), + from: currentUser.uid, + date: new Date(), + }) + + if (file) { + const fileRef = await storage.ref(`conversations/${activeConversation.id}/${msgId}`).put(file).then((snapshot) => snapshot.ref.getDownloadURL()) + await messageRef.set({ file: fileRef }, { merge: true }) + } } - } - function onDragEnter() { - setIsDragOn(true) - } + function onDragEnter() { + setIsDragOn(true) + } - function onDragLeave() { - setIsDragOn(false) - } + function onDragLeave() { + setIsDragOn(false) + } - return ( -
- + return ( +
+ - + - + - setFile(null)} - onDone={onSendMessage} /> + setFile(null)} + onDone={onSendMessage} /> - { - isDragOn && ( - - ) - } + { + isDragOn && ( + + ) + } -
- ) +
+ ) } export default Chat diff --git a/src/components/Home/Chat/Messages.js b/src/components/Home/Chat/Messages.js index 1b64ef5..6a15a9e 100644 --- a/src/components/Home/Chat/Messages.js +++ b/src/components/Home/Chat/Messages.js @@ -18,277 +18,296 @@ import Drawer from '@material-ui/core/Drawer' import Fab from '@material-ui/core/Fab' import CloseIcon from '@material-ui/icons/Close' import EmojiText from './EmujiText' +import { fileTypes } from './Chat' const useStyles = makeStyles({ - root: { - flex: 1, - position: 'relative', - overflow: 'hidden', - }, - opacity: { - opacity: 0.3, - }, - list: { - height: '100%', - width: '100%', - overflow: 'auto', - padding: 0, - position: 'relative', - scrollPadding: 10, - '& li': { - overflowAnchor: 'none', + root: { + flex: 1, + position: 'relative', + overflow: 'hidden', }, - }, - anchor: { - overflowAnchor: 'auto', - height: 1, - }, - progress: { - margin: 'auto', - position: 'absolute', - display: 'flex', - width: '100%', - justifyContent: 'center', - zIndex: 100, - }, - avatar: { - alignSelf: 'baseline', - maxWidth: 'initial', - margin: '0 10px', - }, - img: { - maxWidth: 190, - }, - downloadIcon: { - position: 'absolute', - right: 0, - top: 0, - }, - imgContainer: { - display: 'flex', - position: 'relative', - }, - day: { - position: 'sticky', - top: 60, - fontSize: 16, - textAlign: 'center', - '& span': { - color: '#3f51b5', - background: 'rgba(255, 255, 255, 1)', + opacity: { + opacity: 0.3, }, - margin: '20px auto', - display: 'flex', - justifyContent: 'center', - zIndex: 1, - }, - paper: { - background: 'rgba(0, 0, 0, 0.5)', - position: 'absolute', - height: '100%', - top: 0, - zIndex: 'initial', - width: '100%', - }, - docked: { - height: '100%', - }, - zoomImg: { - height: '100%', - display: 'flex', - width: '100%', - justifyContent: 'center', - alignItems: 'center', - '& img': { - display: 'block', - height: '90%', + list: { + height: '100%', + width: '100%', + overflow: 'auto', + padding: 0, + position: 'relative', + scrollPadding: 10, + '& li': { + overflowAnchor: 'none', + }, + }, + anchor: { + overflowAnchor: 'auto', + height: 1, + }, + progress: { + margin: 'auto', + position: 'absolute', + display: 'flex', + width: '100%', + justifyContent: 'center', + zIndex: 100, + }, + avatar: { + alignSelf: 'baseline', + maxWidth: 'initial', + margin: '0 10px', + }, + img: { + maxWidth: 190, + }, + downloadIcon: { + position: 'absolute', + right: 0, + top: 0, + }, + imgContainer: { + display: 'flex', + position: 'relative', + }, + day: { + position: 'sticky', + top: 60, + fontSize: 16, + textAlign: 'center', + '& span': { + color: '#3f51b5', + background: 'rgba(255, 255, 255, 1)', + }, + margin: '20px auto', + display: 'flex', + justifyContent: 'center', + zIndex: 1, + }, + paper: { + background: 'rgba(0, 0, 0, 0.5)', + position: 'absolute', + height: '100%', + top: 0, + zIndex: 'initial', + width: '100%', + }, + docked: { + height: '100%', + }, + zoomImg: { + height: '100%', + display: 'flex', + width: '100%', + justifyContent: 'center', + alignItems: 'center', + '& img': { + display: 'block', + height: '90%', + }, + }, + zoomImgCloseIcon: { + position: 'absolute', + top: 10, + left: 10, + }, + ListItemText: { + whiteSpace: 'pre-line', + background: 'rgba(63, 81, 181, 0.03)', + borderRadius: 8, + padding: 10, + boxShadow: '0 0 2px 0px #3f51b5', + wordBreak: 'break-all', + flex: 'none', + maxWidth: 'calc(70% - 60px)', + boxSizing: 'border-box', + }, + listItem: { + flex: 'initial', + flexDirection: 'row-reverse', + }, + listItemSelf: { + flex: 'initial', + flexDirection: 'row', + }, + video: { + width: '100%', + height: ' auto', }, - }, - zoomImgCloseIcon: { - position: 'absolute', - top: 10, - left: 10, - }, - ListItemText: { - whiteSpace: 'pre-line', - background: 'rgba(63, 81, 181, 0.03)', - borderRadius: 8, - padding: 10, - boxShadow: '0 0 2px 0px #3f51b5', - wordBreak: 'break-all', - flex: 'none', - maxWidth: 'calc(70% - 60px)', - boxSizing: 'border-box', - }, - listItem: { - flex: 'initial', - flexDirection: 'row-reverse', - }, - listItemSelf: { - flex: 'initial', - flexDirection: 'row', - }, }) const Messages = ({ isDragOn }, listRef) => { - const classes = useStyles() - const dispatch = useDispatch() + const classes = useStyles() + const dispatch = useDispatch() - const [zoomImg, setZoomImg] = useState(null) - const [allLoaded, setAllLoaded] = useState(false) - const [scrollTop, setScrollTop] = useState(false) + const [zoomImg, setZoomImg] = useState(null) + const [allLoaded, setAllLoaded] = useState(false) + const [scrollTop, setScrollTop] = useState(false) - const isLoadingMessages = useSelector(store => store.conversations.isLoadingMessages) - const conversationId = useSelector(store => store.conversations.activeConversation) - const currentUserId = useSelector(store => store.auth.user.uid) - const users = useSelector(store => store.users.users) - const messagesObject = useSelector(store => store.conversations.messages[store.conversations.activeConversation]) || {} - const messages = _sortBy(Object.values(messagesObject || {}), 'date') || [] - const shouldFetchMessages = messages.length < 10 + const isLoadingMessages = useSelector(store => store.conversations.isLoadingMessages) + const conversationId = useSelector(store => store.conversations.activeConversation) + const currentUserId = useSelector(store => store.auth.user.uid) + const users = useSelector(store => store.users.users) + const messagesObject = useSelector(store => store.conversations.messages[store.conversations.activeConversation]) || {} + const messages = _sortBy(Object.values(messagesObject || {}), 'date') || [] + const shouldFetchMessages = messages.length < 10 - useEffect(() => { - listRef.current.scrollTop = listRef.current.scrollHeight + useEffect(() => { + listRef.current.scrollTop = listRef.current.scrollHeight - if (shouldFetchMessages) { - loadPrevious() - } + if (shouldFetchMessages) { + loadPrevious() + } - return db.collection('conversations') - .doc(conversationId) - .collection('messages') - .orderBy('date', 'desc') - .limit(1) - .onSnapshot(onGetMessages) + return db.collection('conversations') + .doc(conversationId) + .collection('messages') + .orderBy('date', 'desc') + .limit(1) + .onSnapshot(onGetMessages) - }, [conversationId, currentUserId, dispatch, shouldFetchMessages]) + }, [conversationId, currentUserId, dispatch, shouldFetchMessages]) - function updateLastSeen() { - return db - .collection('conversations') - .doc(conversationId) - .set({ - members: { - [currentUserId]: { - lastSeen: new Date(), - }, - }, - }, { merge: true }) - } + function updateLastSeen() { + return db + .collection('conversations') + .doc(conversationId) + .set({ + members: { + [currentUserId]: { + lastSeen: new Date(), + }, + }, + }, { merge: true }) + } - function onGetMessages(snapshot) { - updateLastSeen() + function onGetMessages(snapshot) { + updateLastSeen() - const messagesList = (snapshot.docs || []).map((doc) => doc.data()) + const messagesList = (snapshot.docs || []).map((doc) => doc.data()) - dispatch(setMessages({ - id: conversationId, - messages: messagesList.reduce((prev, doc) => ({ ...prev, [doc.id]: doc }), {}), - })) + dispatch(setMessages({ + id: conversationId, + messages: messagesList.reduce((prev, doc) => ({ ...prev, [doc.id]: doc }), {}), + })) - } + } - async function loadPrevious() { - dispatch(setIsLoadingMessages(true)) + async function loadPrevious() { + dispatch(setIsLoadingMessages(true)) - const snapshot = await db.collection('conversations') - .doc(conversationId) - .collection('messages') - .orderBy('date', 'desc') - .limit(10) - .where('date', '<', _get(messages, '[0].date') || new Date()) - .get() + const snapshot = await db.collection('conversations') + .doc(conversationId) + .collection('messages') + .orderBy('date', 'desc') + .limit(10) + .where('date', '<', _get(messages, '[0].date') || new Date()) + .get() - if (!snapshot.size) { - setAllLoaded(true) - } - onGetMessages(snapshot) + if (!snapshot.size) { + setAllLoaded(true) + } + onGetMessages(snapshot) - dispatch(setIsLoadingMessages(false)) - } + dispatch(setIsLoadingMessages(false)) + } - async function onScrollList(e) { - const isScrollingUp = scrollTop > e.currentTarget.scrollTop - setScrollTop(e.currentTarget.scrollTop) + async function onScrollList(e) { + const isScrollingUp = scrollTop > e.currentTarget.scrollTop + setScrollTop(e.currentTarget.scrollTop) - if (e.currentTarget.scrollTop < 30 && - isScrollingUp && - messages.length && - !allLoaded && - !isLoadingMessages) { + if (e.currentTarget.scrollTop < 30 && + isScrollingUp && + messages.length && + !allLoaded && + !isLoadingMessages) { - if (e.currentTarget.scrollTop === 0) { - e.currentTarget.scrollTop = 1 - } + if (e.currentTarget.scrollTop === 0) { + e.currentTarget.scrollTop = 1 + } - await loadPrevious() + await loadPrevious() + } } - } - const dayGroups = _groupBy(messages, function (message) { - return moment(message.date.toDate()).startOf('day').format('DD/MM/YY') - }) + const dayGroups = _groupBy(messages, function (message) { + return moment(message.date.toDate()).startOf('day').format('DD/MM/YY') + }) - return ( -
- - { - Object.entries(dayGroups).map(([day, messages]) => ( - - {day} - { - messages.map((message) => ( - - - - - - { - message.file && ( - message.file !== 'pending' ? ( -
- -
- ) : - ) - } + return ( +
+ + { + Object.entries(dayGroups).map(([day, messages]) => ( + + {day} + { + messages.map((message) => ( + + + + + + { + message.file && ( + message.file !== 'pending' ? ( +
+ { + message.fileType && ( + message.fileType === fileTypes.image ? ( + + ) : message.fileType === fileTypes.video ? ( + + ) :

none

+ ) + } +
+ ) : + ) + } - } - secondary={moment(message.date.toDate()).format('HH:mm:ss')} /> -
+ } + secondary={moment(message.date.toDate()).format('HH:mm:ss')} /> + -
- )) - } -
- )) - } -
- - setZoomImg(null)}> + + )) + } + + )) + } +
+ + setZoomImg(null)}> -
setZoomImg(null)}> - - - - e.stopPropagation()} /> -
+
setZoomImg(null)}> + + + + e.stopPropagation()} /> +
-
-
- ) +
+
+ ) } export default forwardRef(Messages) From 72c64e1981798d4d39beb3b39dba5f2296c9c3a4 Mon Sep 17 00:00:00 2001 From: YairTawil Date: Thu, 17 Oct 2019 19:31:29 +0300 Subject: [PATCH 4/4] rm editorConifg --- .editorConfig | 8 - src/components/Home/Chat/Chat.js | 142 ++--- src/components/Home/Chat/ChatInput.js | 394 +++++++------- src/components/Home/Chat/Messages.js | 510 +++++++++--------- .../Home/Conversations/Conversation.js | 162 +++--- 5 files changed, 604 insertions(+), 612 deletions(-) delete mode 100644 .editorConfig diff --git a/.editorConfig b/.editorConfig deleted file mode 100644 index 91b82ac..0000000 --- a/.editorConfig +++ /dev/null @@ -1,8 +0,0 @@ -root = true - -[*.js] -charset = utf-8 -indent_style = space -indent_size = 4 -insert_final_newline = false -trim_trailing_whitespace = false diff --git a/src/components/Home/Chat/Chat.js b/src/components/Home/Chat/Chat.js index 35bfdf9..d311092 100644 --- a/src/components/Home/Chat/Chat.js +++ b/src/components/Home/Chat/Chat.js @@ -11,92 +11,92 @@ import { selectActiveConversation } from '../../../state/actions/conversations' import FileDialog from './FileDialog' export const fileTypes = { - image: 'image', - video: 'video', + image: 'image', + video: 'video', } const useStyles = makeStyles({ - root: { - flex: 1, - display: 'flex', - justifyContent: 'space-between', - flexDirection: 'column', - position: 'relative', - width: '100%', - height: '100%', - }, + root: { + flex: 1, + display: 'flex', + justifyContent: 'space-between', + flexDirection: 'column', + position: 'relative', + width: '100%', + height: '100%', + }, }) const Chat = () => { - const classes = useStyles() - const listRef = useRef() - const [isDragOn, setIsDragOn] = useState(false) - const [file, setFile] = React.useState(null) - - const currentUser = useSelector(store => store.auth.user) - const activeConversation = useSelector(selectActiveConversation) - - async function onSendMessage(text) { - listRef.current.scrollTop = listRef.current.scrollHeight - setIsDragOn(false) - setFile(null) - - const msgId = uuid() - - const messageRef = db - .collection('conversations') - .doc(activeConversation.id) - .collection('messages') - .doc(msgId) - - await messageRef.set({ - id: msgId, - text, - ...(file ? { file: 'pending' } : {}), - ...(file ? { fileType: Object.keys(fileTypes).find(type => file.type.includes(type)) } : {}), - from: currentUser.uid, - date: new Date(), - }) - - if (file) { - const fileRef = await storage.ref(`conversations/${activeConversation.id}/${msgId}`).put(file).then((snapshot) => snapshot.ref.getDownloadURL()) - await messageRef.set({ file: fileRef }, { merge: true }) - } + const classes = useStyles() + const listRef = useRef() + const [isDragOn, setIsDragOn] = useState(false) + const [file, setFile] = React.useState(null) + + const currentUser = useSelector(store => store.auth.user) + const activeConversation = useSelector(selectActiveConversation) + + async function onSendMessage(text) { + listRef.current.scrollTop = listRef.current.scrollHeight + setIsDragOn(false) + setFile(null) + + const msgId = uuid() + + const messageRef = db + .collection('conversations') + .doc(activeConversation.id) + .collection('messages') + .doc(msgId) + + await messageRef.set({ + id: msgId, + text, + ...(file ? { file: 'pending' } : {}), + ...(file ? { fileType: Object.keys(fileTypes).find(type => file.type.includes(type)) } : {}), + from: currentUser.uid, + date: new Date(), + }) + + if (file) { + const fileRef = await storage.ref(`conversations/${activeConversation.id}/${msgId}`).put(file).then((snapshot) => snapshot.ref.getDownloadURL()) + await messageRef.set({ file: fileRef }, { merge: true }) } + } - function onDragEnter() { - setIsDragOn(true) - } + function onDragEnter() { + setIsDragOn(true) + } - function onDragLeave() { - setIsDragOn(false) - } + function onDragLeave() { + setIsDragOn(false) + } - return ( -
- + return ( +
+ - + - + - setFile(null)} - onDone={onSendMessage} /> + setFile(null)} + onDone={onSendMessage} /> - { - isDragOn && ( - - ) - } + { + isDragOn && ( + + ) + } -
- ) +
+ ) } export default Chat diff --git a/src/components/Home/Chat/ChatInput.js b/src/components/Home/Chat/ChatInput.js index d84fac3..e3fa57d 100644 --- a/src/components/Home/Chat/ChatInput.js +++ b/src/components/Home/Chat/ChatInput.js @@ -10,212 +10,212 @@ import TagFacesIcon from '@material-ui/icons/TagFaces' import AttachFileIcon from '@material-ui/icons/AttachFile' const useStyles = makeStyles({ - root: { - width: '100%', - position: 'relative', - color: 'rgba(0, 0, 0, 0.87)', - cursor: 'text', - display: 'inline-flex', - fontSize: 17, - boxSizing: 'border-box', - alignItems: 'center', - fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif', - lineHeight: '1.1875em', - border: '1px solid #abb3ea', - '&:focus-within': { - background: 'rgb(245, 246, 251)', - borderColor: '#3f51b5', - }, + root: { + width: '100%', + position: 'relative', + color: 'rgba(0, 0, 0, 0.87)', + cursor: 'text', + display: 'inline-flex', + fontSize: 17, + boxSizing: 'border-box', + alignItems: 'center', + fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif', + lineHeight: '1.1875em', + border: '1px solid #abb3ea', + '&:focus-within': { + background: 'rgb(245, 246, 251)', + borderColor: '#3f51b5', }, - input: { - whiteSpace: 'pre-wrap', - outline: 'none', - font: 'inherit', - color: 'currentColor', - width: '100%', - border: 0, - minHeight: 64, - maxHeight: 300, - overflowY: 'auto', - overflowX: 'hidden', - margin: 0, - minWidth: 0, - background: 'none', - display: 'inline-block', - padding: 20, - boxSizing: 'border-box', - '&::-webkit-scrollbar': { - width: '6px!important', - height: '6px!important', - }, - '&::-webkit-scrollbar-track': { - background: 'hsla(0,0%,100%,.08)', - }, - '&::-webkit-scrollbar-thumb': { - backgroundColor: 'rgba(0,0,0,.2)', - }, + }, + input: { + whiteSpace: 'pre-wrap', + outline: 'none', + font: 'inherit', + color: 'currentColor', + width: '100%', + border: 0, + minHeight: 64, + maxHeight: 300, + overflowY: 'auto', + overflowX: 'hidden', + margin: 0, + minWidth: 0, + background: 'none', + display: 'inline-block', + padding: 20, + boxSizing: 'border-box', + '&::-webkit-scrollbar': { + width: '6px!important', + height: '6px!important', }, - actions: { - display: 'flex', - alignSelf: 'flex-end', - padding: 8, - borderLeft: '1px solid rgba(171, 179, 234, 0.5)', + '&::-webkit-scrollbar-track': { + background: 'hsla(0,0%,100%,.08)', }, + '&::-webkit-scrollbar-thumb': { + backgroundColor: 'rgba(0,0,0,.2)', + }, + }, + actions: { + display: 'flex', + alignSelf: 'flex-end', + padding: 8, + borderLeft: '1px solid rgba(171, 179, 234, 0.5)', + }, }) export default function ChatInput({ value: text, onChange, onSubmit, required, attachFile }) { - const [showEmojis, setShowEmojis] = React.useState(false) - const [contentHtml, setContentHtml] = React.useState('') - const [range, setRange] = React.useState(null) - const formRef = useRef() - const contentEditableRef = useRef() - const classes = useStyles() - - useEffect(() => { - const value = [...contentEditableRef.current.childNodes].map((e) => { - if (e.nodeName === 'IMG') { - return e.getAttribute('alt') - } else { - return e.nodeValue - } - }).join('') - onChange(value) - }, [contentHtml]) - - - function setCurrentRange(currentRange) { - const cloneCurrentRange = currentRange.cloneRange() - const selection = window.getSelection() - currentRange.collapse(true) - selection.removeAllRanges() - selection.addRange(cloneCurrentRange) + const [showEmojis, setShowEmojis] = React.useState(false) + const [contentHtml, setContentHtml] = React.useState('') + const [range, setRange] = React.useState(null) + const formRef = useRef() + const contentEditableRef = useRef() + const classes = useStyles() + + useEffect(() => { + const value = [...contentEditableRef.current.childNodes].map((e) => { + if (e.nodeName === 'IMG') { + return e.getAttribute('alt') + } else { + return e.nodeValue + } + }).join('') + onChange(value) + }, [contentHtml]) + + + function setCurrentRange(currentRange) { + const cloneCurrentRange = currentRange.cloneRange() + const selection = window.getSelection() + currentRange.collapse(true) + selection.removeAllRanges() + selection.addRange(cloneCurrentRange) + } + + function onKeyPress(e) { + if (e.which === 13 && !e.shiftKey) { + e.preventDefault() + if (text) { + formRef.current.dispatchEvent(new Event('submit', { cancelable: true })) + } } - - function onKeyPress(e) { - if (e.which === 13 && !e.shiftKey) { - e.preventDefault() - if (text) { - formRef.current.dispatchEvent(new Event('submit', { cancelable: true })) - } - } + } + + function submitForm(e) { + e.preventDefault() + setShowEmojis(false) + setContentHtml('') + onSubmit(text) + } + + function toggleShowEmojis() { + setShowEmojis(!showEmojis) + } + + function addEmoji(emoji) { + const html = createEmojiImg({ emoji }) + + if (document.activeElement !== contentEditableRef.current) { + contentEditableRef.current.focus() + if (range) { + setCurrentRange(range) + } } - function submitForm(e) { - e.preventDefault() - setShowEmojis(false) - setContentHtml('') - onSubmit(text) + document.execCommand('insertHTML', false, html) + } + + function onChangeFileInput(e) { + attachFile(e.target.files.length ? e.target.files.item(0) : null) + e.target.value = '' + } + + function onChangeContentEditable(e) { + setContentHtml(e.target.value) + saveCurrentRange() + } + + function onPaste(e) { + e.preventDefault() + const text = (e.originalEvent || e).clipboardData.getData('text/plain') + const html = createTextHTML(text) + document.execCommand('insertHTML', false, html) + } + + function saveCurrentRange() { + try { + const currentRange = window.getSelection().getRangeAt(0).cloneRange() + setRange(currentRange) + } catch (e) { + setRange(null) } - - function toggleShowEmojis() { - setShowEmojis(!showEmojis) - } - - function addEmoji(emoji) { - const html = createEmojiImg({ emoji }) - - if (document.activeElement !== contentEditableRef.current) { - contentEditableRef.current.focus() - if (range) { - setCurrentRange(range) - } - } - - document.execCommand('insertHTML', false, html) - } - - function onChangeFileInput(e) { - attachFile(e.target.files.length ? e.target.files.item(0) : null) - e.target.value = '' - } - - function onChangeContentEditable(e) { - setContentHtml(e.target.value) - saveCurrentRange() - } - - function onPaste(e) { - e.preventDefault() - const text = (e.originalEvent || e).clipboardData.getData('text/plain') - const html = createTextHTML(text) - document.execCommand('insertHTML', false, html) - } - - function saveCurrentRange() { - try { - const currentRange = window.getSelection().getRangeAt(0).cloneRange() - setRange(currentRange) - } catch (e) { - setRange(null) - } - } - - return ( -
- - - { - showEmojis && ( - - - - ) - } -
- - - - - - - - - - -
- - ) + } + + return ( +
+ + + { + showEmojis && ( + + + + ) + } +
+ + + + + + + + + + +
+ + ) } diff --git a/src/components/Home/Chat/Messages.js b/src/components/Home/Chat/Messages.js index 6a15a9e..b8acc8b 100644 --- a/src/components/Home/Chat/Messages.js +++ b/src/components/Home/Chat/Messages.js @@ -21,293 +21,293 @@ import EmojiText from './EmujiText' import { fileTypes } from './Chat' const useStyles = makeStyles({ - root: { - flex: 1, - position: 'relative', - overflow: 'hidden', + root: { + flex: 1, + position: 'relative', + overflow: 'hidden', + }, + opacity: { + opacity: 0.3, + }, + list: { + height: '100%', + width: '100%', + overflow: 'auto', + padding: 0, + position: 'relative', + scrollPadding: 10, + '& li': { + overflowAnchor: 'none', }, - opacity: { - opacity: 0.3, + }, + anchor: { + overflowAnchor: 'auto', + height: 1, + }, + progress: { + margin: 'auto', + position: 'absolute', + display: 'flex', + width: '100%', + justifyContent: 'center', + zIndex: 100, + }, + avatar: { + alignSelf: 'baseline', + maxWidth: 'initial', + margin: '0 10px', + }, + img: { + maxWidth: 190, + }, + downloadIcon: { + position: 'absolute', + right: 0, + top: 0, + }, + imgContainer: { + display: 'flex', + position: 'relative', + }, + day: { + position: 'sticky', + top: 60, + fontSize: 16, + textAlign: 'center', + '& span': { + color: '#3f51b5', + background: 'rgba(255, 255, 255, 1)', }, - list: { - height: '100%', - width: '100%', - overflow: 'auto', - padding: 0, - position: 'relative', - scrollPadding: 10, - '& li': { - overflowAnchor: 'none', - }, - }, - anchor: { - overflowAnchor: 'auto', - height: 1, - }, - progress: { - margin: 'auto', - position: 'absolute', - display: 'flex', - width: '100%', - justifyContent: 'center', - zIndex: 100, - }, - avatar: { - alignSelf: 'baseline', - maxWidth: 'initial', - margin: '0 10px', - }, - img: { - maxWidth: 190, - }, - downloadIcon: { - position: 'absolute', - right: 0, - top: 0, - }, - imgContainer: { - display: 'flex', - position: 'relative', - }, - day: { - position: 'sticky', - top: 60, - fontSize: 16, - textAlign: 'center', - '& span': { - color: '#3f51b5', - background: 'rgba(255, 255, 255, 1)', - }, - margin: '20px auto', - display: 'flex', - justifyContent: 'center', - zIndex: 1, - }, - paper: { - background: 'rgba(0, 0, 0, 0.5)', - position: 'absolute', - height: '100%', - top: 0, - zIndex: 'initial', - width: '100%', - }, - docked: { - height: '100%', - }, - zoomImg: { - height: '100%', - display: 'flex', - width: '100%', - justifyContent: 'center', - alignItems: 'center', - '& img': { - display: 'block', - height: '90%', - }, - }, - zoomImgCloseIcon: { - position: 'absolute', - top: 10, - left: 10, - }, - ListItemText: { - whiteSpace: 'pre-line', - background: 'rgba(63, 81, 181, 0.03)', - borderRadius: 8, - padding: 10, - boxShadow: '0 0 2px 0px #3f51b5', - wordBreak: 'break-all', - flex: 'none', - maxWidth: 'calc(70% - 60px)', - boxSizing: 'border-box', - }, - listItem: { - flex: 'initial', - flexDirection: 'row-reverse', - }, - listItemSelf: { - flex: 'initial', - flexDirection: 'row', - }, - video: { - width: '100%', - height: ' auto', + margin: '20px auto', + display: 'flex', + justifyContent: 'center', + zIndex: 1, + }, + paper: { + background: 'rgba(0, 0, 0, 0.5)', + position: 'absolute', + height: '100%', + top: 0, + zIndex: 'initial', + width: '100%', + }, + docked: { + height: '100%', + }, + zoomImg: { + height: '100%', + display: 'flex', + width: '100%', + justifyContent: 'center', + alignItems: 'center', + '& img': { + display: 'block', + height: '90%', }, + }, + zoomImgCloseIcon: { + position: 'absolute', + top: 10, + left: 10, + }, + ListItemText: { + whiteSpace: 'pre-line', + background: 'rgba(63, 81, 181, 0.03)', + borderRadius: 8, + padding: 10, + boxShadow: '0 0 2px 0px #3f51b5', + wordBreak: 'break-all', + flex: 'none', + maxWidth: 'calc(70% - 60px)', + boxSizing: 'border-box', + }, + listItem: { + flex: 'initial', + flexDirection: 'row-reverse', + }, + listItemSelf: { + flex: 'initial', + flexDirection: 'row', + }, + video: { + width: '100%', + height: ' auto', + }, }) const Messages = ({ isDragOn }, listRef) => { - const classes = useStyles() - const dispatch = useDispatch() + const classes = useStyles() + const dispatch = useDispatch() - const [zoomImg, setZoomImg] = useState(null) - const [allLoaded, setAllLoaded] = useState(false) - const [scrollTop, setScrollTop] = useState(false) + const [zoomImg, setZoomImg] = useState(null) + const [allLoaded, setAllLoaded] = useState(false) + const [scrollTop, setScrollTop] = useState(false) - const isLoadingMessages = useSelector(store => store.conversations.isLoadingMessages) - const conversationId = useSelector(store => store.conversations.activeConversation) - const currentUserId = useSelector(store => store.auth.user.uid) - const users = useSelector(store => store.users.users) - const messagesObject = useSelector(store => store.conversations.messages[store.conversations.activeConversation]) || {} - const messages = _sortBy(Object.values(messagesObject || {}), 'date') || [] - const shouldFetchMessages = messages.length < 10 + const isLoadingMessages = useSelector(store => store.conversations.isLoadingMessages) + const conversationId = useSelector(store => store.conversations.activeConversation) + const currentUserId = useSelector(store => store.auth.user.uid) + const users = useSelector(store => store.users.users) + const messagesObject = useSelector(store => store.conversations.messages[store.conversations.activeConversation]) || {} + const messages = _sortBy(Object.values(messagesObject || {}), 'date') || [] + const shouldFetchMessages = messages.length < 10 - useEffect(() => { - listRef.current.scrollTop = listRef.current.scrollHeight + useEffect(() => { + listRef.current.scrollTop = listRef.current.scrollHeight - if (shouldFetchMessages) { - loadPrevious() - } + if (shouldFetchMessages) { + loadPrevious() + } - return db.collection('conversations') - .doc(conversationId) - .collection('messages') - .orderBy('date', 'desc') - .limit(1) - .onSnapshot(onGetMessages) + return db.collection('conversations') + .doc(conversationId) + .collection('messages') + .orderBy('date', 'desc') + .limit(1) + .onSnapshot(onGetMessages) - }, [conversationId, currentUserId, dispatch, shouldFetchMessages]) + }, [conversationId, currentUserId, dispatch, shouldFetchMessages]) - function updateLastSeen() { - return db - .collection('conversations') - .doc(conversationId) - .set({ - members: { - [currentUserId]: { - lastSeen: new Date(), - }, - }, - }, { merge: true }) - } + function updateLastSeen() { + return db + .collection('conversations') + .doc(conversationId) + .set({ + members: { + [currentUserId]: { + lastSeen: new Date(), + }, + }, + }, { merge: true }) + } - function onGetMessages(snapshot) { - updateLastSeen() + function onGetMessages(snapshot) { + updateLastSeen() - const messagesList = (snapshot.docs || []).map((doc) => doc.data()) + const messagesList = (snapshot.docs || []).map((doc) => doc.data()) - dispatch(setMessages({ - id: conversationId, - messages: messagesList.reduce((prev, doc) => ({ ...prev, [doc.id]: doc }), {}), - })) + dispatch(setMessages({ + id: conversationId, + messages: messagesList.reduce((prev, doc) => ({ ...prev, [doc.id]: doc }), {}), + })) - } + } - async function loadPrevious() { - dispatch(setIsLoadingMessages(true)) + async function loadPrevious() { + dispatch(setIsLoadingMessages(true)) - const snapshot = await db.collection('conversations') - .doc(conversationId) - .collection('messages') - .orderBy('date', 'desc') - .limit(10) - .where('date', '<', _get(messages, '[0].date') || new Date()) - .get() + const snapshot = await db.collection('conversations') + .doc(conversationId) + .collection('messages') + .orderBy('date', 'desc') + .limit(10) + .where('date', '<', _get(messages, '[0].date') || new Date()) + .get() - if (!snapshot.size) { - setAllLoaded(true) - } - onGetMessages(snapshot) - - dispatch(setIsLoadingMessages(false)) + if (!snapshot.size) { + setAllLoaded(true) } + onGetMessages(snapshot) - async function onScrollList(e) { - const isScrollingUp = scrollTop > e.currentTarget.scrollTop - setScrollTop(e.currentTarget.scrollTop) + dispatch(setIsLoadingMessages(false)) + } - if (e.currentTarget.scrollTop < 30 && - isScrollingUp && - messages.length && - !allLoaded && - !isLoadingMessages) { + async function onScrollList(e) { + const isScrollingUp = scrollTop > e.currentTarget.scrollTop + setScrollTop(e.currentTarget.scrollTop) - if (e.currentTarget.scrollTop === 0) { - e.currentTarget.scrollTop = 1 - } + if (e.currentTarget.scrollTop < 30 && + isScrollingUp && + messages.length && + !allLoaded && + !isLoadingMessages) { - await loadPrevious() - } - } + if (e.currentTarget.scrollTop === 0) { + e.currentTarget.scrollTop = 1 + } - const dayGroups = _groupBy(messages, function (message) { - return moment(message.date.toDate()).startOf('day').format('DD/MM/YY') - }) + await loadPrevious() + } + } - return ( -
- - { - Object.entries(dayGroups).map(([day, messages]) => ( - - {day} - { - messages.map((message) => ( - - - - - - { - message.file && ( - message.file !== 'pending' ? ( -
- { - message.fileType && ( - message.fileType === fileTypes.image ? ( - - ) : message.fileType === fileTypes.video ? ( - - ) :

none

- ) - } -
- ) : - ) - } + const dayGroups = _groupBy(messages, function (message) { + return moment(message.date.toDate()).startOf('day').format('DD/MM/YY') + }) - } - secondary={moment(message.date.toDate()).format('HH:mm:ss')} /> -
+ return ( +
+ + { + Object.entries(dayGroups).map(([day, messages]) => ( + + {day} + { + messages.map((message) => ( + + + + + + { + message.file && ( + message.file !== 'pending' ? ( +
+ { + message.fileType && ( + message.fileType === fileTypes.image ? ( + + ) : message.fileType === fileTypes.video ? ( + + ) :

none

+ ) + } +
+ ) : + ) + } -
- )) - } -
- )) - } -
- - setZoomImg(null)}> + } + secondary={moment(message.date.toDate()).format('HH:mm:ss')} /> + -
setZoomImg(null)}> - - - - e.stopPropagation()} /> -
+ + )) + } + + )) + } +
+ + setZoomImg(null)}> - +
setZoomImg(null)}> + + + + e.stopPropagation()} />
- ) + + +
+ ) } export default forwardRef(Messages) diff --git a/src/components/Home/Conversations/Conversation.js b/src/components/Home/Conversations/Conversation.js index 1b2d4cd..d67009b 100644 --- a/src/components/Home/Conversations/Conversation.js +++ b/src/components/Home/Conversations/Conversation.js @@ -13,100 +13,100 @@ import ConversationAvatar from './ConversationAvatar' import { ConversationTitle } from './ConversationTitle' const useStyles = makeStyles({ - root: { - cursor: 'pointer', - '&:hover': { - background: 'rgba(155, 155, 157, 0.21)', - }, - display: 'flex', - }, - activeConversation: { - background: 'rgba(155, 155, 157, 0.21)', - }, - counter: { - top: '50%', - alignSelf: 'center', - }, - ellipsis: { - overflow: 'hidden', - textOverflow: 'ellipsis', - maxHeight: '24px', - whiteSpace: 'nowrap', + root: { + cursor: 'pointer', + '&:hover': { + background: 'rgba(155, 155, 157, 0.21)', }, + display: 'flex', + }, + activeConversation: { + background: 'rgba(155, 155, 157, 0.21)', + }, + counter: { + top: '50%', + alignSelf: 'center', + }, + ellipsis: { + overflow: 'hidden', + textOverflow: 'ellipsis', + maxHeight: '24px', + whiteSpace: 'nowrap', + }, }) const Conversation = ({ data: conversation }) => { - const [lastMessage, setLastMessage] = useState('') - const classes = useStyles() - const { id } = conversation - const count = useSelector(store => store.conversations.unreadMessagesCount[id]) - const currentUser = useSelector(store => store.auth.user) - const lastSeen = _get(conversation, `members[${currentUser.uid}].lastSeen`) - const { uid: currentUserId } = currentUser - const dispatch = useDispatch() - const activeConversation = useSelector(store => store.conversations.activeConversation) + const [lastMessage, setLastMessage] = useState('') + const classes = useStyles() + const { id } = conversation + const count = useSelector(store => store.conversations.unreadMessagesCount[id]) + const currentUser = useSelector(store => store.auth.user) + const lastSeen = _get(conversation, `members[${currentUser.uid}].lastSeen`) + const { uid: currentUserId } = currentUser + const dispatch = useDispatch() + const activeConversation = useSelector(store => store.conversations.activeConversation) - function setActive() { - dispatch(setActiveConversation(id)) - } + function setActive() { + dispatch(setActiveConversation(id)) + } - useEffect(() => { - return db - .collection('conversations') - .doc(id) - .collection('messages') - .where('date', '>=', lastSeen || new Date(0)) - .onSnapshot((snapshot) => { - const snapshotData = (snapshot.docs || []).map((doc) => doc.data()) - const count = snapshotData.reduce((count, message) => message.from === currentUserId ? count : count + 1, 0) - dispatch({ type: 'SET_UNREAD_MESSAGES_COUNT', payload: { id, count } }) - }) + useEffect(() => { + return db + .collection('conversations') + .doc(id) + .collection('messages') + .where('date', '>=', lastSeen || new Date(0)) + .onSnapshot((snapshot) => { + const snapshotData = (snapshot.docs || []).map((doc) => doc.data()) + const count = snapshotData.reduce((count, message) => message.from === currentUserId ? count : count + 1, 0) + dispatch({ type: 'SET_UNREAD_MESSAGES_COUNT', payload: { id, count } }) + }) - }, [dispatch, id, lastSeen, currentUserId]) + }, [dispatch, id, lastSeen, currentUserId]) - useEffect(() => { - return db - .collection('conversations') - .doc(id) - .collection('messages') - .orderBy('date', 'desc') - .limit(1) - .onSnapshot((snapshot) => { - if (snapshot.docs.length) { - setLastMessage(snapshot.docs[0].data().text) - } - }) + useEffect(() => { + return db + .collection('conversations') + .doc(id) + .collection('messages') + .orderBy('date', 'desc') + .limit(1) + .onSnapshot((snapshot) => { + if (snapshot.docs.length) { + setLastMessage(snapshot.docs[0].data().text) + } + }) - }, [id, currentUserId]) + }, [id, currentUserId]) - return ( - + return ( + - - - + + + - } - secondary={( - {lastMessage} - )} /> - { - Boolean(count) && ( - - ) - } + } + secondary={( + {lastMessage} + )} /> + { + Boolean(count) && ( + + ) + } - - ) + + ) } export default Conversation