Better handling of uploaded files. (#7688)

* Better handling of uploaded files.

* Read file when uploading it so we can properly read metadata.
This commit is contained in:
Franco Montenegro 2022-09-19 16:42:16 -04:00 committed by GitHub
parent 3fd38be789
commit 0e2a9a1033
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 14 deletions

View file

@ -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) {

View file

@ -16,12 +16,14 @@ type Props = {
disabled?: boolean,
autoFocus?: boolean,
filters?: Array<{ name: string, extension: string[] }>,
readFile?: boolean,
};
class FileSelector extends React.PureComponent<Props> {
static defaultProps = {
autoFocus: false,
type: 'file',
readFile: true,
};
fileInput: React.ElementRef<any>;
@ -75,7 +77,7 @@ class FileSelector extends React.PureComponent<Props> {
.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) => {

View file

@ -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);

View file

@ -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()}
</>