Better handling of uploaded files. #7688

Merged
Ruk33 merged 2 commits from 7687-535-upload-form-bugs into master 2022-09-19 22:42:16 +02:00
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); // 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) {

View file

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

View file

@ -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);
jessopb commented 2022-09-16 18:33:59 +02:00 (Migrated from github.com)
Review

The purpose of these lines was to do the math to guess Mbps and judge whether file needs to be transcoded (is a video, and size is large compared to duration). Is that done somewhere else now?

The purpose of these lines was to do the math to guess Mbps and judge whether file needs to be transcoded (is a video, and size is large compared to duration). Is that done somewhere else now?
Ruk33 commented 2022-09-16 21:15:17 +02:00 (Migrated from github.com)
Review

@jessopb yes, it was removed so this logic happens only in one place (publishFile/view.jsx)

@jessopb yes, it was removed so this logic happens only in one place (publishFile/view.jsx)
jessopb commented 2022-09-16 22:34:45 +02:00 (Migrated from github.com)
Review

Ok. The messaging seems wrong. Your video may not be the best format. is always the message which is the message for (isVid && !duration) so something isn't working.

Ok. The messaging seems wrong. `Your video may not be the best format.` is always the message which is the message for (isVid && !duration) so something isn't working.

View file

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