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:
parent
3fd38be789
commit
0e2a9a1033
4 changed files with 45 additions and 14 deletions
|
@ -307,7 +307,7 @@ app.on('before-quit', () => {
|
||||||
// const file = new File([result.buffer], result.name);
|
// const file = new File([result.buffer], result.name);
|
||||||
// NOTE: if path points to a folder, an empty
|
// NOTE: if path points to a folder, an empty
|
||||||
// file will be given.
|
// 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) => {
|
return new Promise((resolve, reject) => {
|
||||||
fs.stat(path, (error, stats) => {
|
fs.stat(path, (error, stats) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -327,6 +327,15 @@ ipcMain.handle('get-file-from-path', (event, path) => {
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!readContents) {
|
||||||
|
resolve({
|
||||||
|
name,
|
||||||
|
mime: mime.getType(name) || undefined,
|
||||||
|
path,
|
||||||
|
buffer: new ArrayBuffer(0),
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Encoding null ensures data results in a Buffer.
|
// Encoding null ensures data results in a Buffer.
|
||||||
fs.readFile(path, { encoding: null }, (err, data) => {
|
fs.readFile(path, { encoding: null }, (err, data) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
|
@ -16,12 +16,14 @@ type Props = {
|
||||||
disabled?: boolean,
|
disabled?: boolean,
|
||||||
autoFocus?: boolean,
|
autoFocus?: boolean,
|
||||||
filters?: Array<{ name: string, extension: string[] }>,
|
filters?: Array<{ name: string, extension: string[] }>,
|
||||||
|
readFile?: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
class FileSelector extends React.PureComponent<Props> {
|
class FileSelector extends React.PureComponent<Props> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
autoFocus: false,
|
autoFocus: false,
|
||||||
type: 'file',
|
type: 'file',
|
||||||
|
readFile: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
fileInput: React.ElementRef<any>;
|
fileInput: React.ElementRef<any>;
|
||||||
|
@ -75,7 +77,7 @@ class FileSelector extends React.PureComponent<Props> {
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
const path = result && result.filePaths[0];
|
const path = result && result.filePaths[0];
|
||||||
if (path) {
|
if (path) {
|
||||||
return ipcRenderer.invoke('get-file-from-path', path);
|
return ipcRenderer.invoke('get-file-from-path', path, this.props.readFile);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
|
|
|
@ -80,9 +80,6 @@ function FileDrop(props: Props) {
|
||||||
navigateToPublish();
|
navigateToPublish();
|
||||||
updatePublishForm({
|
updatePublishForm({
|
||||||
filePath: selectedFile.path || selectedFile.name,
|
filePath: selectedFile.path || selectedFile.name,
|
||||||
fileDur: 0,
|
|
||||||
fileSize: 0,
|
|
||||||
fileVid: false,
|
|
||||||
});
|
});
|
||||||
}, NAVIGATE_TIME_OUT);
|
}, NAVIGATE_TIME_OUT);
|
||||||
}, HIDE_TIME_OUT);
|
}, HIDE_TIME_OUT);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import type { Node } from 'react';
|
import type { Node } from 'react';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import { ipcRenderer } from 'electron';
|
||||||
import { regexInvalidURI } from 'util/lbryURI';
|
import { regexInvalidURI } from 'util/lbryURI';
|
||||||
import PostEditor from 'component/postEditor';
|
import PostEditor from 'component/postEditor';
|
||||||
import FileSelector from 'component/common/file-selector';
|
import FileSelector from 'component/common/file-selector';
|
||||||
|
@ -91,6 +92,27 @@ function PublishFile(props: Props) {
|
||||||
}
|
}
|
||||||
}, [currentFileType, mode, isStillEditing, updatePublishForm]);
|
}, [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(() => {
|
useEffect(() => {
|
||||||
const isOptimizeAvail = currentFile && currentFile !== '' && isVid && ffmpegAvail;
|
const isOptimizeAvail = currentFile && currentFile !== '' && isVid && ffmpegAvail;
|
||||||
const finalOptimizeState = isOptimizeAvail && userOptimize;
|
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;
|
window.URL = window.URL || window.webkitURL;
|
||||||
|
|
||||||
// select file, start to select a new one, then cancel
|
// select file, start to select a new one, then cancel
|
||||||
|
@ -259,17 +281,17 @@ function PublishFile(props: Props) {
|
||||||
setPublishMode(PUBLISH_MODES.FILE);
|
setPublishMode(PUBLISH_MODES.FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
const publishFormParams: { filePath: string, name?: string, optimize?: boolean } = {
|
// Strip off extension and replace invalid characters
|
||||||
filePath: fileWithPath.path,
|
|
||||||
};
|
|
||||||
// Strip off extention and replace invalid characters
|
|
||||||
let fileName = name || (file.name && file.name.substring(0, file.name.lastIndexOf('.'))) || '';
|
|
||||||
|
|
||||||
if (!isStillEditing) {
|
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;
|
const showFileUpload = mode === PUBLISH_MODES.FILE;
|
||||||
|
@ -317,6 +339,7 @@ function PublishFile(props: Props) {
|
||||||
onFileChosen={handleFileChange}
|
onFileChosen={handleFileChange}
|
||||||
// https://stackoverflow.com/questions/19107685/safari-input-type-file-accept-video-ignores-mp4-files
|
// https://stackoverflow.com/questions/19107685/safari-input-type-file-accept-video-ignores-mp4-files
|
||||||
placeholder={__('Select file to upload')}
|
placeholder={__('Select file to upload')}
|
||||||
|
readFile={false}
|
||||||
/>
|
/>
|
||||||
{getUploadMessage()}
|
{getUploadMessage()}
|
||||||
</>
|
</>
|
||||||
|
|
Loading…
Reference in a new issue