Skip to content

Commit

Permalink
Better handling of uploaded files. (#7688)
Browse files Browse the repository at this point in the history
* Better handling of uploaded files.

* Read file when uploading it so we can properly read metadata.
  • Loading branch information
Ruk33 authored Sep 19, 2022
1 parent 3fd38be commit 0e2a9a1
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 14 deletions.
11 changes: 10 additions & 1 deletion electron/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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) {
Expand Down
4 changes: 3 additions & 1 deletion ui/component/common/file-selector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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>;
Expand Down Expand Up @@ -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) => {
Expand Down
3 changes: 0 additions & 3 deletions ui/component/fileDrop/view.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
41 changes: 32 additions & 9 deletions ui/component/publishFile/view.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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()}
</>
Expand Down

0 comments on commit 0e2a9a1

Please sign in to comment.