From 0e2a9a1033426ce554f45ddc7ea05bb646823593 Mon Sep 17 00:00:00 2001 From: Franco Montenegro Date: Mon, 19 Sep 2022 16:42:16 -0400 Subject: [PATCH] Better handling of uploaded files. (#7688) * Better handling of uploaded files. * Read file when uploading it so we can properly read metadata. --- electron/index.js | 11 ++++++- ui/component/common/file-selector.jsx | 4 ++- ui/component/fileDrop/view.jsx | 3 -- ui/component/publishFile/view.jsx | 41 +++++++++++++++++++++------ 4 files changed, 45 insertions(+), 14 deletions(-) diff --git a/electron/index.js b/electron/index.js index 2c28a5a61..da43fdc6c 100644 --- a/electron/index.js +++ b/electron/index.js @@ -307,7 +307,7 @@ app.on('before-quit', () => { // const file = new File([result.buffer], result.name); // NOTE: if path points to a folder, an empty // file will be given. -ipcMain.handle('get-file-from-path', (event, path) => { +ipcMain.handle('get-file-from-path', (event, path, readContents = true) => { return new Promise((resolve, reject) => { fs.stat(path, (error, stats) => { if (error) { @@ -327,6 +327,15 @@ ipcMain.handle('get-file-from-path', (event, path) => { }); return; } + if (!readContents) { + resolve({ + name, + mime: mime.getType(name) || undefined, + path, + buffer: new ArrayBuffer(0), + }); + return; + } // Encoding null ensures data results in a Buffer. fs.readFile(path, { encoding: null }, (err, data) => { if (err) { diff --git a/ui/component/common/file-selector.jsx b/ui/component/common/file-selector.jsx index 47d2e651e..9e6403185 100644 --- a/ui/component/common/file-selector.jsx +++ b/ui/component/common/file-selector.jsx @@ -16,12 +16,14 @@ type Props = { disabled?: boolean, autoFocus?: boolean, filters?: Array<{ name: string, extension: string[] }>, + readFile?: boolean, }; class FileSelector extends React.PureComponent { static defaultProps = { autoFocus: false, type: 'file', + readFile: true, }; fileInput: React.ElementRef; @@ -75,7 +77,7 @@ class FileSelector extends React.PureComponent { .then((result) => { const path = result && result.filePaths[0]; if (path) { - return ipcRenderer.invoke('get-file-from-path', path); + return ipcRenderer.invoke('get-file-from-path', path, this.props.readFile); } }) .then((result) => { diff --git a/ui/component/fileDrop/view.jsx b/ui/component/fileDrop/view.jsx index bd946aa32..52acea07b 100644 --- a/ui/component/fileDrop/view.jsx +++ b/ui/component/fileDrop/view.jsx @@ -80,9 +80,6 @@ function FileDrop(props: Props) { navigateToPublish(); updatePublishForm({ filePath: selectedFile.path || selectedFile.name, - fileDur: 0, - fileSize: 0, - fileVid: false, }); }, NAVIGATE_TIME_OUT); }, HIDE_TIME_OUT); diff --git a/ui/component/publishFile/view.jsx b/ui/component/publishFile/view.jsx index 3879a9d94..0eafc2641 100644 --- a/ui/component/publishFile/view.jsx +++ b/ui/component/publishFile/view.jsx @@ -2,6 +2,7 @@ import type { Node } from 'react'; import * as ICONS from 'constants/icons'; import React, { useState, useEffect } from 'react'; +import { ipcRenderer } from 'electron'; import { regexInvalidURI } from 'util/lbryURI'; import PostEditor from 'component/postEditor'; import FileSelector from 'component/common/file-selector'; @@ -91,6 +92,27 @@ function PublishFile(props: Props) { } }, [currentFileType, mode, isStillEditing, updatePublishForm]); + // Since the filePath can be updated from outside this component + // (for instance, when the user drags & drops a file), we need + // to check for changes in the selected file using an effect. + useEffect(() => { + if (!filePath) { + return; + } + async function readSelectedFile() { + // Read the file to get the file's duration (if possible) + // and offer transcoding it. + const readFileContents = true; + const result = await ipcRenderer.invoke('get-file-from-path', filePath, readFileContents); + const file = new File([result.buffer], result.name, { + type: result.mime, + }); + const fileWithPath = { file, path: result.path }; + processSelectedFile(fileWithPath); + } + readSelectedFile(); + }, [filePath]); + useEffect(() => { const isOptimizeAvail = currentFile && currentFile !== '' && isVid && ffmpegAvail; const finalOptimizeState = isOptimizeAvail && userOptimize; @@ -197,7 +219,7 @@ function PublishFile(props: Props) { } } - function handleFileChange(fileWithPath: FileWithPath, clearName = true) { + function processSelectedFile(fileWithPath: FileWithPath, clearName = true) { window.URL = window.URL || window.webkitURL; // select file, start to select a new one, then cancel @@ -259,17 +281,17 @@ function PublishFile(props: Props) { setPublishMode(PUBLISH_MODES.FILE); } - const publishFormParams: { filePath: string, name?: string, optimize?: boolean } = { - filePath: fileWithPath.path, - }; - // Strip off extention and replace invalid characters - let fileName = name || (file.name && file.name.substring(0, file.name.lastIndexOf('.'))) || ''; - + // Strip off extension and replace invalid characters if (!isStillEditing) { - publishFormParams.name = parseName(fileName); + const fileWithoutExtension = name || (file.name && file.name.substring(0, file.name.lastIndexOf('.'))) || ''; + updatePublishForm({ name: parseName(fileWithoutExtension) }); } + } - updatePublishForm(publishFormParams); + function handleFileChange(fileWithPath: FileWithPath) { + if (fileWithPath) { + updatePublishForm({ filePath: fileWithPath.path }); + } } const showFileUpload = mode === PUBLISH_MODES.FILE; @@ -317,6 +339,7 @@ function PublishFile(props: Props) { onFileChosen={handleFileChange} // https://stackoverflow.com/questions/19107685/safari-input-type-file-accept-video-ignores-mp4-files placeholder={__('Select file to upload')} + readFile={false} /> {getUploadMessage()}