Rev 5115 | Rev 5946 | Ir a la última revisión | Autoría | Comparar con el anterior | Ultima modificación | Ver Log |
/* eslint-disable camelcase */
/* eslint-disable react/prop-types */
import React, { useEffect, useRef, useState } from 'react'
import ThumbUpAltOutlinedIcon from '@mui/icons-material/ThumbUpAltOutlined'
import ThumbUpAltIcon from '@mui/icons-material/ThumbUpAlt'
import ChatOutlinedIcon from '@mui/icons-material/ChatOutlined'
import ShareOutlinedIcon from '@mui/icons-material/ShareOutlined'
import SendOutlinedIcon from '@mui/icons-material/SendOutlined'
import RecommendIcon from '@mui/icons-material/Recommend'
import InputOption from './InputOption'
import parse from 'html-react-parser'
import Avatar from '../../../../shared/Avatar/Avatar'
import AccessTimeIcon from '@mui/icons-material/AccessTime'
import { axios } from '../../../../utils'
import { addNotification } from '../../../../redux/notification/notification.actions'
import { openShareModal } from '../../../../redux/share-modal/shareModal.actions'
import { shareModalTypes } from '../../../../redux/share-modal/shareModal.types'
import { feedTypes } from '../../../../redux/feed/feed.types'
import FeedCommentSection from '../../../components/feed/feed-comment/FeedCommentSection'
import { connect, useDispatch } from 'react-redux'
import withExternalShare from './withExternalShare'
import ConfirmModal from '../../../../shared/confirm-modal/ConfirmModal'
import { deleteFeed } from '../../../../redux/feed/feed.actions'
import FeedModal from '../../../components/feed/FeedModal'
const Feed = (props) => {
const {
isShare = false,
feed_unique,
feed_is_liked,
feed_like_url,
feed_unlike_url,
feed_share_url,
feed_share_external_url,
feed_delete_url,
feed_likes,
owner_url,
owner_image,
owner_name,
owner_description,
owner_shared,
owner_comments,
owner_time_elapse,
owner_file_image_preview,
owner_file_video,
owner_file_image,
owner_file_document,
comment_add_url,
comments,
shared_name,
shared_image,
shared_time_elapse,
shared_description,
shared_file_video,
shared_file_image_preview,
shared_file_image,
owner_external_shared,
shared_file_document,
shared_url,
feed_increment_external_counter_url,
addNotification, // REDUX ACTION
openShareModal // REDUX ACTION
} = props
const [feedIsLiked, setFeedIsLiked] = useState(feed_is_liked)
const [likesState, setLikesState] = useState(feed_likes)
const [totalComments, setTotalComments] = useState(owner_comments)
const [externalShare, setExternalShare] = useState(owner_external_shared)
const [sharedState, setSharedState] = useState(owner_shared)
const [showComments, setShowComments] = useState(false)
const [showModal, setShowModal] = useState(false)
const handleLike = (url) => {
axios.post(url)
.then(({ data: response }) => {
if (!response.success) {
addNotification({ style: 'danger', msg: response.data })
return
}
setLikesState(response.data.likes)
setFeedIsLiked(!feedIsLiked)
})
}
const handleShare = () => openShareModal(feed_share_url, shareModalTypes.SHARE, feedTypes.DASHBOARD, feed_unique)
const handleExternalShare = (value) => setExternalShare(value)
const displayCommentSection = () => setShowComments(!showComments)
const ExternalShareButton = withExternalShare(InputOption, feed_share_external_url, {
Icon: SendOutlinedIcon,
color: 'gray',
title: 'Send',
shareUrl: feed_increment_external_counter_url,
setValue: handleExternalShare
})
useEffect(() => setSharedState(owner_shared), [owner_shared])
return (
<>
{showModal && <FeedModal isShow={true} feed={props} handleClose={() => setShowModal(false)} />}
<div className='feed'>
<Feed.Header
image={owner_image}
name={owner_name}
timeElapsed={owner_time_elapse}
viewUrl={owner_url}
deleteUrl={feed_delete_url}
feedUnique={feed_unique}
/>
<div className='feed__body' onClick={() => (owner_file_image || owner_file_video || owner_file_document) && setShowModal(true)}>
<Feed.Content
ownerDescription={owner_description}
ownerFileImage={owner_file_image}
ownerFileImagepreview={owner_file_image_preview}
ownerFileVideo={owner_file_video}
ownerFileDocument={owner_file_document}
sharedItem={{
name: shared_name,
image: shared_image,
time_elapse: shared_time_elapse,
description: shared_description,
file_video: shared_file_video,
file_image_preview: shared_file_image_preview,
file_image: shared_file_image,
file_document: shared_file_document,
shared_url
}}
/>
</div>
{!isShare &&
<div className="px-3 d-flex align-items-center justify-content-between">
{!!likesState &&
<div className="d-inline-flex align-items-center" style={{ gap: '.5rem' }}>
<RecommendIcon style={{ color: '#7405f9' }} />
<span>{likesState}</span>
</div>}
<div className="d-inline-flex align-items-center" style={{ gap: '5px' }}>
{!!totalComments && <span>{`${totalComments} ${LABELS.COMMENTS.toLowerCase()}`}</span>}
{!!sharedState && <span>{`${sharedState} ${LABELS.SHARED.toLowerCase()}`}</span>}
{!!externalShare && <span>{`${externalShare} ${LABELS.SENDS.toLowerCase()}`}</span>}
</div>
</div>
}
{
!isShare &&
<div className='feed__buttons'>
<InputOption
Icon={feedIsLiked ? ThumbUpAltIcon : ThumbUpAltOutlinedIcon}
title={LABELS.LIKE}
color={feedIsLiked ? '#7405f9' : 'gray'}
onClick={() => handleLike(feedIsLiked ? feed_unlike_url : feed_like_url)}
/>
<InputOption
Icon={ChatOutlinedIcon}
title={LABELS.COMMENT}
color='gray'
onClick={displayCommentSection}
/>
<InputOption
Icon={ShareOutlinedIcon}
title={LABELS.SHARE}
color='gray'
onClick={handleShare}
/>
<ExternalShareButton />
</div>
}
<div className='px-2 pb-2'>
<FeedCommentSection
feedId={feed_unique}
image={owner_image}
addUrl={comment_add_url}
updateTotalComments={(total) => setTotalComments(total)}
comments={comments}
isShow={showComments}
/>
</div>
</div>
</>
)
}
const Content = ({
ownerDescription,
ownerFileImage,
ownerFileImagepreview,
ownerFileVideo,
ownerFileDocument,
sharedItem
}) => {
const [isReadMoreActive, setIsReadMoreActive] = useState(false)
const readMoreHandler = () => setIsReadMoreActive(!isReadMoreActive)
const htmlParsedText = (fullStringText) => {
const fullText = parse(fullStringText)
if (fullStringText.length > 500) {
const shortenedString = fullStringText.substr(0, 500)
const shortenedText = parse(`${shortenedString}... `)
return (
<>
{isReadMoreActive ? fullText : shortenedText}
<span className='cursor-pointer' onClick={readMoreHandler}>
{isReadMoreActive ? LABELS.READ_LESS : LABELS.READ_MORE}
</span>
</>
)
}
return <p>{fullText}</p>
}
return (
<>
{ownerDescription && htmlParsedText(ownerDescription)}
{ownerFileImage &&
<img src={ownerFileImage} className="Entradas" loading='lazy' />
}
{ownerFileVideo &&
<video
src={ownerFileVideo}
controls
poster={ownerFileImagepreview}
preload="none"
/>
}
{ownerFileDocument &&
<a href={ownerFileDocument} target="_blank" rel="noreferrer">
{LABELS.DOWNLOAD}
</a>
}
{sharedItem.name &&
<div className="py-3 px-md-3">
<Feed
isShare={true}
owner_name={sharedItem.name}
owner_image={sharedItem.image}
owner_time_elapse={sharedItem.time_elapse}
owner_description={sharedItem.description}
owner_file_video={sharedItem.file_video}
owner_file_image_preview={sharedItem.file_image_preview}
owner_file_image={sharedItem.file_image}
owner_file_document={sharedItem.file_document}
owner_url={sharedItem.shared_url}
/>
</div>
}
</>
)
}
const Header = ({
image = '',
name = '',
timeElapsed = '',
deleteUrl = '',
viewUrl = '',
feedUnique = ''
}) => {
const [showConfirmModal, setShowConfirmModal] = useState(false)
const [displayOption, setDisplayOption] = useState(false)
const deleteButton = useRef()
const dispatch = useDispatch()
const handleShowConfirmModal = () => setShowConfirmModal(!showConfirmModal)
const deleteFeedHandler = () => {
axios.post(deleteUrl)
.then((res) => {
const { data } = res
if (!data.success) {
dispatch(addNotification({ style: 'danger', msg: data.data }))
return
}
dispatch(addNotification({ style: 'success', msg: data.data }))
handleShowConfirmModal()
dispatch(deleteFeed(feedUnique))
})
}
useEffect(() => {
const handleClickOutside = (event) => {
if (deleteButton.current && !deleteButton.current.contains(event.target)) {
setDisplayOption(false)
}
}
document.addEventListener('mousedown', handleClickOutside)
return () => {
document.removeEventListener('mousedown', handleClickOutside)
}
}, [deleteButton])
return (
<div className='feed__header'>
<div className="d-inline-flex" style={{ gap: '.5rem' }}>
<Avatar
imageUrl={image}
name={name}
size='xl'
/>
<div className='feed__info'>
<a href={viewUrl}>
<h2>{name}</h2>
</a>
<div className='time__elapse'>
<p>
{timeElapsed}
</p>
<AccessTimeIcon className='time__elapse-icon' />
</div>
</div>
</div>
{deleteUrl &&
<div className="cursor-pointer d-flex align-items-center position-relative">
<img
src='/images/icons/options.png'
className='cursor-pointer img-icon options'
onClick={() => setDisplayOption(!displayOption)}
/>
<div className={`feed-options ${displayOption ? 'active' : ''}`}>
<ul>
<li>
<button
className="option-btn"
onClick={handleShowConfirmModal}
ref={deleteButton}
>
<i className="fa fa-trash-o mr-1" />
{LABELS.DELETE}
</button>
</li>
</ul>
</div>
<ConfirmModal
show={showConfirmModal}
onClose={() => handleShowConfirmModal(false)}
onAccept={deleteFeedHandler}
acceptLabel={LABELS.ACCEPT}
/>
</div>}
</div>
)
}
Feed.Content = Content
Feed.Header = Header
const mapDispatchToProps = {
addNotification: (notification) => addNotification(notification),
openShareModal: (postUrl, modalType, feedType) => openShareModal(postUrl, modalType, feedType)
}
export default connect(null, mapDispatchToProps)(Feed)