Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

Rev 4017 | Rev 4038 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
3207 stevensc 1
/* eslint-disable react/prop-types */
4017 stevensc 2
import React, { useEffect, useState, useRef } from "react";
3
import parse from "html-react-parser"
1034 stevensc 4
import { useDispatch } from "react-redux";
1021 stevensc 5
import { axios } from "../../../utils";
4017 stevensc 6
 
7
// Import Icons
4037 stevensc 8
import { FaRegHeart, FaHeart } from 'react-icons/fa'
2839 stevensc 9
import { RiShareForwardLine } from 'react-icons/ri'
3630 stevensc 10
import { BiMessage, BiShareAlt } from "react-icons/bi";
3466 stevensc 11
import { EmailIcon, EmailShareButton, FacebookIcon, FacebookShareButton, RedditIcon, RedditShareButton, TelegramIcon, TelegramShareButton, TwitterIcon, TwitterShareButton, WhatsappIcon, WhatsappShareButton } from "react-share";
1 www 12
 
4017 stevensc 13
// Redux types
14
import { shareModalTypes } from "../../../redux/share-modal/shareModal.types";
15
import { feedTypes } from "../../../redux/feed/feed.types";
16
 
1034 stevensc 17
// Redux actions
18
import { openShareModal } from "../../../redux/share-modal/shareModal.actions";
19
import { addNotification } from "../../../redux/notification/notification.actions";
3630 stevensc 20
import FeedModal from "./FeedModal";
21
import FeedHeader from "./FeedHeader";
3943 stevensc 22
import FeedCommentSection from "./feed-comment/FeedCommentSection";
1034 stevensc 23
 
4017 stevensc 24
const Feed = ({ feed, owner_shared, image }) => {
1034 stevensc 25
 
1 www 26
  // Destructuring feed data
27
  const {
28
    feed_unique,
29
    owner_name,
30
    owner_url,
31
    owner_image,
32
    owner_time_elapse,
33
    owner_file_image,
34
    owner_file_video,
35
    owner_file_document,
2572 stevensc 36
    feed_likes,
1 www 37
    feed_like_url,
38
    feed_unlike_url,
39
    feed_is_liked,
3207 stevensc 40
    feed_highlighted,
1 www 41
    feed_share_url,
42
    feed_delete_url,
43
    comments,
44
    comment_add_url,
3303 stevensc 45
    feed_share_external_url
1040 stevensc 46
  } = feed;
1 www 47
 
1034 stevensc 48
  const dispatch = useDispatch()
1 www 49
 
1291 stevensc 50
  const [totalComments, setTotalComments] = useState(comments.length || 0);
1 www 51
  const [feedIsLiked, setFeedIsLiked] = useState(feed_is_liked);
1034 stevensc 52
  const [sharedState, setSharedState] = useState(owner_shared);
1047 stevensc 53
  const [likesState, setLikesState] = useState(feed_likes);
3795 stevensc 54
  const [shareUrl, setShareUrl] = useState('');
3962 stevensc 55
  const [showComments, setShowComments] = useState(false);
3630 stevensc 56
 
3308 stevensc 57
  const [shareOptions, setShareOptions] = useState(false)
56 steven 58
  const [show, setShow] = useState(false);
1 www 59
 
1034 stevensc 60
 
3630 stevensc 61
  const shareContainer = useRef(null);
1030 stevensc 62
 
3630 stevensc 63
  useEffect(() => setSharedState(owner_shared), [owner_shared]);
3202 stevensc 64
 
3310 stevensc 65
  useEffect(() => {
66
    const handleClickOutside = (event) => {
67
      if (shareContainer.current && !shareContainer.current.contains(event.target)) {
3323 stevensc 68
        setShareOptions(false)
3310 stevensc 69
      }
70
    }
71
    document.addEventListener("mousedown", handleClickOutside);
72
 
73
    return () => {
74
      document.removeEventListener("mousedown", handleClickOutside);
75
    };
76
  }, [shareContainer]);
77
 
4016 stevensc 78
  const getShareUrl = new Promise((resolve, reject) => {
79
    if (shareOptions) {
4017 stevensc 80
      axios.get(feed_share_external_url)
4016 stevensc 81
        .then(({ data }) => {
82
          if (!data.success) {
83
            dispatch(addNotification({ style: 'danger', msg: data.data }))
84
            setShareOptions(false)
85
            return reject(data.data)
86
          }
87
          setShareUrl(data.data)
88
          return resolve(data.data)
89
        })
90
        .catch((err) => reject(err))
4015 stevensc 91
    }
4016 stevensc 92
  });
4015 stevensc 93
 
3797 stevensc 94
 
1072 stevensc 95
  const likeHandler = (likeUrl) => {
1043 stevensc 96
    axios.post(likeUrl)
1046 stevensc 97
      .then((res) => {
98
        const { success, data } = res.data;
1043 stevensc 99
        if (!success) {
100
          setFeedIsLiked((previousState) => !previousState);
101
          dispatch(addNotification({
102
            style: "danger",
103
            msg: data,
104
          }));
1049 stevensc 105
        } else {
106
          setLikesState(data.likes)
107
          setFeedIsLiked(!feedIsLiked);
1043 stevensc 108
        }
109
      });
1 www 110
  };
111
 
3962 stevensc 112
  const displayComments = () => setShowComments(!showComments)
113
 
3630 stevensc 114
  const btnShareHandler = () => dispatch(openShareModal(feed_share_url, shareModalTypes.SHARE, feedTypes.DASHBOARD, feed_unique))
1 www 115
 
116
  return (
4017 stevensc 117
    <>
3630 stevensc 118
      <FeedModal
119
        isShow={show}
120
        handleClose={() => setShow(false)}
121
        feed={feed}
122
      />
3504 stevensc 123
      <div className={`postContainer ${feed_highlighted ? 'highlighted' : ''}`}>
3630 stevensc 124
        <FeedHeader
125
          ownerName={owner_name}
126
          ownerImage={owner_image}
127
          ownerTimeElapse={owner_time_elapse}
128
          ownerUrl={owner_url}
129
          feedDeleteUrl={feed_delete_url}
130
          feedUnique={feed_unique}
131
        />
132
        <div onClick={() =>
133
          (owner_file_image || owner_file_video || owner_file_document)
134
          && setShow(true)
135
        }
718 steven 136
        >
4017 stevensc 137
          <Feed.Content
138
            isShare={feed.shared_name ? true : false}
139
            ownerFileImage={feed.owner_file_image}
140
            ownerFileVideo={feed.owner_file_video}
141
            ownerFileImagePreview={feed.owner_file_image_preview}
142
            ownerFileDocument={feed.owner_file_document}
143
            ownerDescription={feed.owner_description}
144
            sharedItem={{
145
              name: feed.shared_name,
146
              image: feed.shared_image,
147
              time_elapse: feed.shared_time_elapse,
148
              description: feed.shared_description,
149
              file_video: feed.shared_file_video,
150
              file_image_preview: feed.shared_file_image_preview,
151
              file_image: feed.shared_file_image,
152
              file_document: feed.shared_file_document
153
            }}
154
          />
718 steven 155
        </div>
1 www 156
        <div className="job-status-bar">
2833 stevensc 157
          <ul className="reactions-list">
1 www 158
            <li>
1082 stevensc 159
              <button
160
                type="button"
161
                id={feedIsLiked ? `btn-unlike-${feed_unique}` : `btn-like-${feed_unique}`}
162
                data-feed-unique={feed_unique}
163
                className={feedIsLiked ? "btn-unlike" : "btn-like"}
3202 stevensc 164
                onClick={() => likeHandler(feedIsLiked ? feed_unlike_url : feed_like_url)}
1082 stevensc 165
              >
4037 stevensc 166
                {feedIsLiked ? <FaHeart className="mr-1" /> : <FaRegHeart className="mr-1" />}
2571 stevensc 167
                {likesState}
1082 stevensc 168
              </button>
1068 stevensc 169
            </li>
170
            <li>
1080 stevensc 171
              <button
172
                type="button"
1 www 173
                id={`btn-comments-${feed_unique}`}
174
                className="btn-indicator"
3962 stevensc 175
                onClick={displayComments}
1 www 176
              >
2839 stevensc 177
                <BiMessage className="mr-1" />
2571 stevensc 178
                {totalComments}
1080 stevensc 179
              </button>
1 www 180
            </li>
181
            <li>
1080 stevensc 182
              <button
183
                type="button"
1 www 184
                id={`btn-share-${feed_unique}`}
185
                className="btn-indicator"
2211 stevensc 186
                onClick={btnShareHandler}
187
              >
2839 stevensc 188
                <RiShareForwardLine className="mr-1" />
2571 stevensc 189
                {sharedState}
2211 stevensc 190
              </button>
191
            </li>
3307 stevensc 192
            <li className="position-relative">
193
              <button
194
                type="button"
195
                className="btn-indicator"
3354 stevensc 196
                onClick={() => setShareOptions(!shareOptions)}
3305 stevensc 197
              >
3307 stevensc 198
                <BiShareAlt />
199
              </button>
3773 stevensc 200
              {shareOptions &&
3310 stevensc 201
                <div className="ext_share" ref={shareContainer}>
4016 stevensc 202
                  <FacebookShareButton beforeOnClick={() => getShareUrl} url={shareUrl}>
3308 stevensc 203
                    <FacebookIcon size={32} round />
204
                  </FacebookShareButton>
4016 stevensc 205
                  <TwitterShareButton beforeOnClick={() => getShareUrl} url={shareUrl}>
3309 stevensc 206
                    <TwitterIcon size={32} round />
207
                  </TwitterShareButton>
4016 stevensc 208
                  <TelegramShareButton beforeOnClick={() => getShareUrl} url={shareUrl}>
3309 stevensc 209
                    <TelegramIcon size={32} round />
210
                  </TelegramShareButton>
4016 stevensc 211
                  <WhatsappShareButton beforeOnClick={() => getShareUrl} url={shareUrl}>
3309 stevensc 212
                    <WhatsappIcon size={32} round />
213
                  </WhatsappShareButton>
4016 stevensc 214
                  <RedditShareButton beforeOnClick={() => getShareUrl} url={shareUrl}>
3309 stevensc 215
                    <RedditIcon size={32} round />
216
                  </RedditShareButton>
4016 stevensc 217
                  <EmailShareButton beforeOnClick={() => getShareUrl} url={shareUrl}>
3309 stevensc 218
                    <EmailIcon size={32} round />
219
                  </EmailShareButton>
3308 stevensc 220
                </div>
221
              }
3303 stevensc 222
            </li>
1 www 223
          </ul>
224
        </div>
3943 stevensc 225
        <FeedCommentSection
226
          feedId={feed.feed_unique}
227
          image={image}
228
          addUrl={comment_add_url}
229
          updateTotalComments={(total) => setTotalComments(total)}
3946 stevensc 230
          comments={comments}
3962 stevensc 231
          isShow={showComments}
3943 stevensc 232
        />
3503 stevensc 233
      </div >
4017 stevensc 234
    </>
1 www 235
  );
236
};
237
 
4017 stevensc 238
const Content = ({
239
  showDescription = true,
240
  ownerFileImage,
241
  ownerFileVideo,
242
  ownerFileImagePreview,
243
  ownerFileDocument,
244
  ownerDescription,
245
  isShare,
246
  sharedItem
247
}) => {
248
 
249
  return (
250
    <div className="job_descp">
251
      {showDescription &&
252
        <Feed.Description ownerDescription={ownerDescription} />
253
      }
254
      {ownerFileImage &&
255
        <img src={ownerFileImage} className="Entradas" loading='lazy' />
256
      }
257
      {ownerFileVideo &&
258
        <video
259
          src={ownerFileVideo}
260
          controls
261
          poster={ownerFileImagePreview}
262
          preload="none"
263
        />
264
      }
265
      {ownerFileDocument &&
266
        <a href={ownerFileDocument} target="_blank" rel="noreferrer">
267
          Descargar
268
        </a>
269
      }
270
      {isShare &&
271
        <Feed.SharedContent
272
          name={sharedItem.name}
273
          image={sharedItem.image}
274
          timeElapse={sharedItem.time_elapse}
275
          description={sharedItem.description}
276
          fileVideo={sharedItem.file_video}
277
          fileImagePreview={sharedItem.file_image_preview}
278
          fileImage={sharedItem.file_image}
279
          fileDocument={sharedItem.file_document}
280
        />
281
      }
282
    </div>
283
  )
284
}
285
 
286
const Description = ({ ownerDescription }) => {
287
 
288
  const [isReadMoreActive, setIsReadMoreActive] = useState(false);
289
 
290
  const readMoreHandler = () => setIsReadMoreActive(!isReadMoreActive)
291
 
292
  const htmlParsedText = (fullStringText) => {
293
    const fullText = parse(fullStringText)
294
    if (fullStringText.length > 500) {
295
      const shortenedString = fullStringText.substr(0, 500);
296
      const shortenedText = parse(`${shortenedString}... `);
297
      return (
298
        <p>
299
          {isReadMoreActive ? fullText : shortenedText}
300
          <span className='cursor-pointer' onClick={readMoreHandler}>
301
            {isReadMoreActive ? " Leer menos" : " Leer más"}
302
          </span>
303
        </p>
304
      );
305
    }
306
    return <p>{fullText}</p>
307
  };
308
 
309
  return (
310
    <div className="show-read-more">
311
      {htmlParsedText(ownerDescription)}
312
    </div>
313
  )
314
}
315
 
316
const SharedContent = ({
317
  name,
318
  image,
319
  timeElapse,
320
  description,
321
  fileVideo,
322
  fileImagePreview,
323
  fileImage,
324
  fileDocument,
325
}) => {
326
 
327
  const [isReadMoreActive, setIsReadMoreActive] = useState(false);
328
 
329
  const readMoreHandler = () => setIsReadMoreActive(!isReadMoreActive)
330
 
331
  const htmlParsedText = (fullStringText) => {
332
    const fullText = parse(fullStringText)
333
    if (fullStringText.length > 500) {
334
      const shortenedString = fullStringText.substr(0, 500);
335
      const shortenedText = parse(`${shortenedString}... `);
336
      return (
337
        <p>
338
          {isReadMoreActive ? fullText : shortenedText}
339
          <span className='cursor-pointer' onClick={readMoreHandler}>
340
            {isReadMoreActive ? " Leer menos" : " Leer más"}
341
          </span>
342
        </p>
343
      );
344
    }
345
    return <p>{fullText}</p>
346
  };
347
 
348
  return (
349
    <div className="shared-post-bar">
350
      <div className="post-bar">
351
        <div className="post_topbar">
352
          <div className="usy-dt">
353
            <img
354
              src={image}
355
              alt=""
356
              style={{ width: "50px", height: "auto" }}
357
            />
358
            <div className="usy-name">
359
              <h3>{name}</h3>
360
              <span>
361
                {timeElapse}
362
              </span>
363
            </div>
364
          </div>
365
        </div>
366
        <div className="job_descp">
367
          <div className="show-read-more">
368
            {htmlParsedText(description)}
369
          </div>
370
          {fileImage &&
371
            <img src={fileImage} className="Entradas" loading='lazy' />
372
          }
373
          {fileVideo &&
374
            <video
375
              src={fileVideo}
376
              controls
377
              poster={fileImagePreview}
378
              preload="none"
379
            />
380
          }
381
          {fileDocument &&
382
            <a href={fileDocument} target="_blank" rel="noreferrer">
383
              Descargar
384
            </a>
385
          }
386
        </div>
387
      </div>
388
    </div>
389
  )
390
}
391
 
392
Feed.SharedContent = SharedContent
393
Feed.Description = Description
394
Feed.Content = Content
395
 
396
export default React.memo(Feed);