Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
primogenial
/
languages
/
wp-content
/
plugins
/
jetpack
/
jetpack_vendor
/
automattic
/
jetpack-videopress
/
src
/
client
/
hooks
:
use-uploader.js
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
/** * External dependencies */ import apiFetch from '@wordpress/api-fetch'; import { useEffect, useState } from '@wordpress/element'; import { __ } from '@wordpress/i18n'; import * as tus from 'tus-js-client'; const jwtsForKeys = {}; export const getJWT = function () { return new Promise( function ( resolve, reject ) { apiFetch( { path: '/wpcom/v2/videopress/upload-jwt', method: 'POST', } ) .then( response => { resolve( { token: response.upload_token, blogId: response.upload_blog_id, url: response.upload_url, } ); } ) .catch( error => { reject( error ); } ); } ); }; export const uploadVideo = ( { file, onProgress, onSuccess, onError, data } ) => { const upload = new tus.Upload( file, { onError: onError, onProgress: onProgress, endpoint: data.url, removeFingerprintOnSuccess: true, withCredentials: false, autoRetry: true, overridePatchMethod: false, chunkSize: 10000000, // 10 Mb. metadata: { filename: file.name, filetype: file.type, }, retryDelays: [ 0, 1000, 3000, 5000, 10000 ], onAfterResponse: function ( req, res ) { // Why is this not showing the x-headers? if ( res.getStatus() >= 400 ) { return; } const GUID_HEADER = 'x-videopress-upload-guid'; const MEDIA_ID_HEADER = 'x-videopress-upload-media-id'; const SRC_URL_HEADER = 'x-videopress-upload-src-url'; const guid = res.getHeader( GUID_HEADER ); const mediaId = res.getHeader( MEDIA_ID_HEADER ); const src = res.getHeader( SRC_URL_HEADER ); if ( guid && mediaId && src ) { onSuccess && onSuccess( { id: Number( mediaId ), guid, src }, file ); return; } const headerMap = { 'x-videopress-upload-key-token': 'token', 'x-videopress-upload-key': 'key', }; const tokenData = {}; Object.keys( headerMap ).forEach( function ( header ) { const value = res.getHeader( header ); if ( ! value ) { return; } tokenData[ headerMap[ header ] ] = value; } ); if ( tokenData.key && tokenData.token ) { jwtsForKeys[ tokenData.key ] = tokenData.token; } }, onBeforeRequest: function ( req ) { // make ALL requests be either POST or GET to honor the public-api.wordpress.com "contract". const method = req._method; if ( [ 'HEAD', 'OPTIONS' ].indexOf( method ) >= 0 ) { req._method = 'GET'; req.setHeader( 'X-HTTP-Method-Override', method ); } if ( [ 'DELETE', 'PUT', 'PATCH' ].indexOf( method ) >= 0 ) { req._method = 'POST'; req.setHeader( 'X-HTTP-Method-Override', method ); } req._xhr.open( req._method, req._url, true ); // Set the headers again, reopening the xhr resets them. Object.keys( req._headers ).map( function ( headerName ) { req.setHeader( headerName, req._headers[ headerName ] ); } ); if ( 'POST' === method ) { const hasJWT = !! data.token; if ( hasJWT ) { req.setHeader( 'x-videopress-upload-token', data.token ); } else { throw 'should never happen'; } } if ( [ 'OPTIONS', 'GET', 'HEAD', 'DELETE', 'PUT', 'PATCH' ].indexOf( method ) >= 0 ) { const url = new URL( req._url ); const path = url.pathname; const parts = path.split( '/' ); const maybeUploadkey = parts[ parts.length - 1 ]; if ( jwtsForKeys[ maybeUploadkey ] ) { req.setHeader( 'x-videopress-upload-token', jwtsForKeys[ maybeUploadkey ] ); } else if ( 'HEAD' === method ) { return getJWT( maybeUploadkey ).then( responseData => { jwtsForKeys[ maybeUploadkey ] = responseData.token; req.setHeader( 'x-videopress-upload-token', responseData.token ); return req; } ); } } return Promise.resolve( req ); }, } ); upload.findPreviousUploads().then( function ( previousUploads ) { if ( previousUploads.length ) { upload.resumeFromPreviousUpload( previousUploads[ 0 ] ); } upload.start(); } ); return upload; }; export const uploadFromLibrary = attachmentId => { const path = `videopress/v1/upload/${ attachmentId }`; return new Promise( ( resolve, reject ) => { apiFetch( { path, method: 'POST' } ) .then( result => { if ( 'uploading' === result.status || 'new' === result.status || 'resume' === result.status ) { uploadFromLibrary( attachmentId ).then( resolve ).catch( reject ); } else if ( 'complete' === result.status ) { resolve( { guid: result.uploaded_details.guid, id: result.uploaded_details.media_id, src: result.uploaded_details.upload_src, } ); } else if ( 'error' === result.status ) { reject( { data: { message: result.error }, } ); } else { reject( { // Should never happen. data: { message: __( 'Unexpected error uploading video.', 'jetpack-videopress-pkg' ) }, } ); } } ) .catch( error => { reject( { data: { message: error?.message }, } ); } ); } ); }; export const useResumableUploader = ( { onError, onProgress, onSuccess } ) => { const [ data, setData ] = useState( {} ); const [ error, setError ] = useState( null ); // collect the jwt for the key useEffect( () => { getJWT() .then( setData ) .catch( jwtError => { setError( jwtError ); onError?.( jwtError ); } ); }, [] ); const uploaded = file => uploadVideo( { file, onProgress, onSuccess, onError, data, } ); return [ uploaded, data, error ]; };