// @flow import { SITE_NAME, WEB_PUBLISH_SIZE_LIMIT_GB, SIMPLE_SITE } from 'config'; import React, { useState, useEffect } from 'react'; import Lbry from 'lbry'; import { toHex } from 'util/hex'; import { regexInvalidURI } from 'util/lbryURI'; import FileSelector from 'component/common/file-selector'; import Button from 'component/button'; import Card from 'component/common/card'; import { FormField } from 'component/common/form'; import Spinner from 'component/spinner'; import * as PUBLISH_MODES from 'constants/publish_types'; import PublishName from 'component/publish/shared/publishName'; import classnames from 'classnames'; import { SOURCE_SELECT } from 'constants/publish_sources'; import { NEW_LIVESTREAM_REPLAY_API } from 'constants/livestream'; type Props = { uri: ?string, mode: ?string, name: ?string, title: ?string, filePath: string | WebFile, isStillEditing: boolean, balance: number, doUpdatePublishForm: ({}) => void, disabled: boolean, doToast: ({ message: string, isError?: boolean }) => void, size: number, duration: number, isVid: boolean, setPublishMode: (string) => void, setOverMaxBitrate: (boolean) => void, fileSource: string, myClaimForUri: ?StreamClaim, activeChannelClaim: ?ChannelClaim, // inEditMode: boolean, }; function PublishFile(props: Props) { const { uri, mode, name, title, balance, filePath, isStillEditing, doUpdatePublishForm: updatePublishForm, doToast, disabled, size, duration, isVid, setPublishMode, // setPrevFileText, // setWaitForFile, setOverMaxBitrate, fileSource, myClaimForUri, activeChannelClaim, // inEditMode, } = props; const RECOMMENDED_BITRATE = 8500000; const MAX_BITRATE = 16500000; const TV_PUBLISH_SIZE_LIMIT_BYTES = WEB_PUBLISH_SIZE_LIMIT_GB * 1073741824; const TV_PUBLISH_SIZE_LIMIT_GB_STR = String(WEB_PUBLISH_SIZE_LIMIT_GB); const MARKDOWN_FILE_EXTENSIONS = ['txt', 'md', 'markdown']; const [oversized, setOversized] = useState(false); const [currentFile, setCurrentFile] = useState(null); const [currentFileType, setCurrentFileType] = useState(null); const UPLOAD_SIZE_MESSAGE = __('%SITE_NAME% uploads are limited to %limit% GB.', { SITE_NAME, limit: TV_PUBLISH_SIZE_LIMIT_GB_STR, }); const bitRate = getBitrate(size, duration); const bitRateIsOverMax = bitRate > MAX_BITRATE; const [livestreamData, setLivestreamData] = React.useState([]); const hasLivestreamData = livestreamData && Boolean(livestreamData.length); const claimChannelId = (myClaimForUri && myClaimForUri.signing_channel && myClaimForUri.signing_channel.claim_id) || (activeChannelClaim && activeChannelClaim.claim_id); const activeChannelName = activeChannelClaim && activeChannelClaim.name; // const [isCheckingLivestreams, setCheckingLivestreams] = React.useState(false); // Reset filePath if publish mode changed useEffect(() => { if (mode === PUBLISH_MODES.POST) { if (currentFileType !== 'text/markdown' && !isStillEditing) { updatePublishForm({ filePath: '' }); } } else if (mode === PUBLISH_MODES.LIVESTREAM) { updatePublishForm({ filePath: '' }); } }, [currentFileType, mode, isStillEditing, updatePublishForm]); useEffect(() => { updatePublishForm({ title: title }); }, [filePath]); /* const normalizeUrlForProtocol = (url) => { if (url.startsWith('https://')) { return url; } else { if (url.startsWith('http://')) { return url; } else if (url) { return `https://${url}`; } } }; */ useEffect(() => { if (!filePath || filePath === '') { setCurrentFile(''); setOversized(false); setOverMaxBitrate(false); updateFileInfo(0, 0, false); } else if (typeof filePath !== 'string') { // Update currentFile file if (filePath.name !== currentFile && filePath.path !== currentFile) { handleFileChange(filePath); } } }, [filePath, currentFile, doToast, updatePublishForm]); useEffect(() => { setOverMaxBitrate(bitRateIsOverMax); }, [bitRateIsOverMax]); async function fetchLivestreams(channelId, channelName) { // setCheckingLivestreams(true); let signedMessage; try { await Lbry.channel_sign({ channel_id: channelId, hexdata: toHex(channelName || ''), }).then((data) => { signedMessage = data; }); } catch (e) { throw e; } if (signedMessage) { const encodedChannelName = encodeURIComponent(channelName || ''); const newEndpointUrl = `${NEW_LIVESTREAM_REPLAY_API}?channel_claim_id=${String(channelId)}` + `&signature=${signedMessage.signature}&signature_ts=${signedMessage.signing_ts}&channel_name=${ encodedChannelName || '' }`; const responseFromNewApi = await fetch(newEndpointUrl); const data = (await responseFromNewApi.json()).data; let newData = []; if (data && data.length > 0) { for (const dataItem of data) { if (dataItem.Status.toLowerCase() === 'inprogress' || dataItem.Status.toLowerCase() === 'ready') { const objectToPush = { data: { fileLocation: dataItem.URL, fileDuration: dataItem.Status.toLowerCase() === 'inprogress' ? __('Processing...(') + dataItem.PercentComplete + '%)' : (dataItem.Duration / 1000000000).toString(), thumbnails: dataItem.ThumbnailURLs !== null ? dataItem.ThumbnailURLs : [], uploadedAt: dataItem.Created, }, }; newData.push(objectToPush); } } } setLivestreamData(newData); // setCheckingLivestreams(false); } } useEffect(() => { if (activeChannelClaim && activeChannelClaim.claim_id && activeChannelName) { fetchLivestreams(activeChannelClaim.claim_id, activeChannelName); } }, [claimChannelId, activeChannelName]); useEffect(() => { if (activeChannelClaim && activeChannelClaim.claim_id && activeChannelName) { fetchLivestreams(activeChannelClaim.claim_id, activeChannelName); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [claimChannelId, activeChannelName]); function updateFileInfo(duration, size, isvid) { updatePublishForm({ fileDur: duration, fileSize: size, fileVid: isvid }); } function getBitrate(size, duration) { const s = Number(size); const d = Number(duration); if (s && d) { return (s * 8) / d; } else { return 0; } } function linkReplays() { return (

{__('Would you like to publish a ')}