import React, { useState, useEffect } from 'react'; import PropTypes from 'prop-types'; import { formatInnerLink } from '../../utils/helpers/'; import { usePopup, useUser } from '../../utils/hooks/'; import { SiteContext } from '../../utils/contexts/'; import { PageActions, MediaPageActions } from '../../utils/actions/'; import { MediaPageStore } from '../../utils/stores/'; import { CircleIconButton, MaterialIcon, NavigationContentApp, NavigationMenuList, PopupMain } from '../_shared/'; import { ReportForm } from '../report-form/ReportForm'; function downloadOptions(mediaData, allowDownload) { const site = SiteContext._currentValue; const encodingsInfo = mediaData.encodings_info; const options = {}; let k, g; for (k in encodingsInfo) { if (encodingsInfo.hasOwnProperty(k)) { if (Object.keys(encodingsInfo[k]).length) { for (g in encodingsInfo[k]) { if (encodingsInfo[k].hasOwnProperty(g)) { if ('success' === encodingsInfo[k][g].status && 100 === encodingsInfo[k][g].progress && null !== encodingsInfo[k][g].url) { options[encodingsInfo[k][g].title] = { text: k + ' - ' + g.toUpperCase() + ' (' + encodingsInfo[k][g].size + ')', link: formatInnerLink(encodingsInfo[k][g].url, site.url), linkAttr: { target: '_blank', download: mediaData.title + '_' + k + '_' + g.toUpperCase(), }, }; } } } } } } options.original_media_url = { text: 'Original file (' + mediaData.size + ')', link: formatInnerLink(mediaData.original_media_url, site.url), linkAttr: { target: '_blank', download: mediaData.title, }, }; return Object.values(options); } function optionsItems(userCan, mediaData, allowDownload, downloadLink, mediaReported) { const items = []; const mediaType = mediaData.media_type; const mediaIsVideo = 'video' === mediaType; const mediaReportedTimes = mediaData.reported_times; if (allowDownload && userCan.downloadMedia) { if (!mediaIsVideo) { if (downloadLink) { items.push({ itemType: 'link', link: downloadLink, text: 'Download', icon: 'arrow_downward', itemAttr: { className: 'visible-only-in-small', }, linkAttr: { target: '_blank', download: mediaData.title, }, }); } } else { items.push({ itemType: 'open-subpage', text: 'Download', icon: 'arrow_downward', itemAttr: { className: 'visible-only-in-small', }, buttonAttr: { className: 'change-page', 'data-page-id': 'videoDownloadOptions', }, }); } } if (mediaIsVideo && userCan.editMedia) { items.push({ itemType: 'open-subpage', text: 'Status info', icon: 'info', buttonAttr: { className: 'change-page', 'data-page-id': 'mediaStatusInfo', }, }); } if (userCan.reportMedia) { if (mediaReported) { items.push({ itemType: 'div', text: 'Reported', icon: 'flag', divAttr: { className: 'reported-label loggedin-media-reported', }, }); } else { items.push({ itemType: 'open-subpage', text: 'Report', icon: 'flag', buttonAttr: { className: 'change-page' + (mediaReportedTimes ? ' loggedin-media-reported' : ''), 'data-page-id': 'loggedInReportMedia', }, }); } } return items; } function getPopupPages(userCan, mediaData, allowDownload, downloadLink, mediaReported, submitReportForm, cancelReportForm) { const mediaUrl = mediaData.url; const mediaType = mediaData.media_type; const mediaState = mediaData.state || 'N/A'; const mediaEncodingStatus = mediaData.encoding_status || 'N/A'; const mediaReportedTimes = mediaData.reported_times; const mediaIsReviewed = mediaData.is_reviewed; const mediaIsVideo = 'video' === mediaType; const navItems = optionsItems(userCan, mediaData, allowDownload, downloadLink, mediaReported); const pages = {}; if (navItems.length) { pages.main = (
); } if (userCan.reportMedia) { pages.loggedInReportMedia = mediaReported ? null : (
); } if (userCan.editMedia) { pages.mediaStatusInfo = (
); } if (allowDownload && userCan.downloadMedia && mediaIsVideo) { pages.videoDownloadOptions = (
); } return pages; } const defaultContainerClassname = 'more-options active-options'; export function MediaMoreOptionsIcon(props) { const { userCan } = useUser(); const site = SiteContext._currentValue; const downloadLink = formatInnerLink(MediaPageStore.get('media-original-url'), site.url); const mediaData = MediaPageStore.get('media-data'); const mediaIsVideo = 'video' === mediaData.media_type; const [popupContentRef, PopupContent, PopupTrigger] = usePopup(); const [visible, setVisible] = useState(false); const [reported, setReported] = useState(false); const [popupPages, setPopupPages] = useState({}); const [popupCurrentPage, setPopupCurrentPage] = useState('main'); const [containerClassname, setContainerClassname] = useState(defaultContainerClassname); function submitReportForm(reportDescription) { MediaPageActions.reportMedia(reportDescription); } function cancelReportFormSubmission() { popupContentRef.current.toggle(); } function onPopupPageChange(newPage) { setPopupCurrentPage(newPage); } function onPopupHide() { setPopupCurrentPage('main'); } function onCompleteMediaReport() { popupContentRef.current.tryToHide(); // FIXME: Without delay creates conflict [ Uncaught Error: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch. ]. setTimeout(function () { PageActions.addNotification('Media Reported', 'reportedMedia'); setReported(true); MediaPageStore.removeListener('reported_media', onCompleteMediaReport); }, 100); } useEffect(() => { if (!reported) { if (visible) { MediaPageStore.on('reported_media', onCompleteMediaReport); } else { MediaPageStore.removeListener('reported_media', onCompleteMediaReport); } } }, [visible]); useEffect(() => { setVisible(Object.keys(popupPages).length && props.allowDownload && userCan.downloadMedia); }, [popupPages]); useEffect(() => { let classname = defaultContainerClassname; if (props.allowDownload && userCan.downloadMedia && 'videoDownloadOptions' === popupCurrentPage) { classname += ' video-downloads'; } if ( 1 === Object.keys(popupPages).length && props.allowDownload && userCan.downloadMedia && (mediaIsVideo || downloadLink) ) { classname += ' visible-only-in-small'; } setContainerClassname(classname); }, [popupCurrentPage]); useEffect(() => { setPopupPages( getPopupPages( userCan, mediaData, props.allowDownload, downloadLink, reported, submitReportForm, cancelReportFormSubmission ) ); }, [reported]); useEffect(() => { setPopupPages( getPopupPages( userCan, mediaData, props.allowDownload, downloadLink, reported, submitReportForm, cancelReportFormSubmission ) ); return () => { if (visible && !reported) { MediaPageStore.removeListener('reported_media', onCompleteMediaReport); } }; }, []); return !visible ? null : (
); } MediaMoreOptionsIcon.propTypes = { allowDownload: PropTypes.bool.isRequired, }; MediaMoreOptionsIcon.defaultProps = { allowDownload: false, };