connect dropped files data to publish form

This commit is contained in:
btzr-io 2020-05-11 21:11:54 -05:00 committed by Sean Yesmunt
parent b1ca99be91
commit 5d0faa740e
5 changed files with 106 additions and 38 deletions

View file

@ -1,21 +1,48 @@
// @flow
import React from 'react';
import * as PAGES from 'constants/pages';
import * as PUBLISH_TYPES from 'constants/publish_types';
import useDragDrop from 'effects/use-drag-drop';
import classnames from 'classnames';
import { getTree } from 'util/web-file-system';
import { withRouter } from 'react-router';
type Props = {
filePath: string | WebFile,
// Lazy fix for flow errors:
// Todo -> add appropiate types
filePath: ?any,
clearPublish: () => void,
updatePublishForm: ({}) => void,
// React router
history: {
entities: {}[],
goBack: () => void,
goForward: () => void,
index: number,
length: number,
location: { pathname: string },
push: string => void,
},
};
const PUBLISH_URL = `/$/${PAGES.PUBLISH}`;
function FileDrop(props: Props) {
const { history, filePath, updatePublishForm } = props;
const { drag, dropData } = useDragDrop();
const [show, setShow] = React.useState(false);
const [files, setFiles] = React.useState([]);
const [selectedFile, setSelectedFile] = React.useState('');
const [error, setError] = React.useState(false);
const navigateToPublish = React.useCallback(() => {
// Navigate only if location is not publish area:
// - Prevent spam in history
if (history.location.pathname !== PUBLISH_URL) {
history.push(PUBLISH_URL);
}
}, [history]);
React.useEffect(() => {
// Handle drop...
if (dropData) {
@ -38,17 +65,42 @@ function FileDrop(props: Props) {
} else if (!drag && !files.length) {
setShow(false);
}
// Filew dropped on drop area
if (!drag && files.length) {
if (files.length === 1) {
// Handle single file publish
files[0].entry.file(webFile => {
setSelectedFile(webFile);
updatePublishForm({ filePath: { publish: PUBLISH_TYPES.DROP, webFile } });
});
}
}
// Handle files
}, [drag, files, error]);
// Wait for publish state update:
React.useEffect(() => {
// Publish form has a file
if (selectedFile && filePath && filePath.webFile !== undefined) {
// Update completed
if (selectedFile.path === filePath.webFile.path) {
// Done! close the drop area:
setFiles([]);
// Go to publish area
navigateToPublish();
}
}
}, [filePath, selectedFile, navigateToPublish]);
return (
<div className={classnames('file-drop', show && 'file-drop--show')}>
<p>Drop your files here!</p>
{files.map(file => (
<div key={file.path}>{file.path}</div>
{files.map(({ entry }) => (
<div key={entry.name}>{entry.name}</div>
))}
</div>
);
}
export default FileDrop;
export default withRouter(FileDrop);

View file

@ -1,5 +1,6 @@
// @flow
import * as ICONS from 'constants/icons';
import * as PUBLISH_TYPES from 'constants/publish_types';
import React, { useState, useEffect } from 'react';
import { regexInvalidURI } from 'lbry-redux';
import FileSelector from 'component/common/file-selector';
@ -11,7 +12,9 @@ import I18nMessage from '../i18nMessage';
type Props = {
name: ?string,
filePath: string | WebFile,
// Lazy fix for flow errors:
// Todo -> add types back
filePath: ?any, // string || WebFile
isStillEditing: boolean,
balance: number,
updatePublishForm: ({}) => void,
@ -47,6 +50,7 @@ function PublishFile(props: Props) {
const { available } = ffmpegStatus;
const [oversized, setOversized] = useState(false);
const [selectedFile, setSelectedFile] = useState(null);
const RECOMMENDED_BITRATE = 6000000;
const TV_PUBLISH_SIZE_LIMIT: number = 1073741824;
const UPLOAD_SIZE_MESSAGE = 'Lbry.tv uploads are limited to 1 GB. Download the app for unrestricted publishing.';
@ -63,13 +67,36 @@ function PublishFile(props: Props) {
updateOptimizeState(0, 0, false);
setOversized(false);
}
// Process dropped file
if (filePath && filePath.publish === PUBLISH_TYPES.DROP && filePath.webFile !== undefined) {
setSelectedFile(filePath.webFile);
}
/*
// Process a post:
// See: https://github.com/lbryio/lbry-desktop/issues/4105
if(filePath && filePath.publish === PUBLISH_TYPES.POST) {
console.info("Writing a post...")
}
*/
}, [filePath]);
// File selected by user
useEffect(() => {
if (selectedFile !== undefined || selectedFile !== null) {
handleFileChange(selectedFile);
}
}, [selectedFile]);
let currentFile = '';
if (filePath) {
// Desktiop publish
if (typeof filePath === 'string') {
currentFile = filePath;
} else {
} else if (filePath.webFile === undefined && typeof filePath.name === 'string') {
// Web publish
currentFile = filePath.name;
}
}
@ -176,7 +203,9 @@ function PublishFile(props: Props) {
// @endif
}
function handleFileChange(file: WebFile) {
// Lazy fix for flow errors:
// Todo -> add types back: ( file: WebFile )
function handleFileChange(file) {
const { showToast } = props;
window.URL = window.URL || window.webkitURL;
// if electron, we'll set filePath to the path string because SDK is handling publishing.

View file

@ -0,0 +1,4 @@
// Publish from drag-drop UI
export const DROP = 'drop';
// Publish a post ( text / markdown )
export const POST = 'post';

View file

@ -1,18 +1,19 @@
.file-drop {
height: 0;
width: 0;
top: 0;
left: 0;
position: fixed;
z-index: 5;
background: var(--color-background-overlay);
opacity: 0;
height: 100%;
width: 100%;
overflow: hidden;
pointer-events: none;
z-index: 5;
transition: opacity 0.3s ease;
&.file-drop--show {
height: 100%;
width: 100%;
opacity: 1;
pointer-events: all;
transition: opacity 0.3s ease;
}
}

View file

@ -1,5 +1,4 @@
// Some functions to work with the new html5 file system API:
import path from 'path';
// Wrapper for webkitGetAsEntry
// Note: webkitGetAsEntry might be renamed to GetAsEntry
@ -28,31 +27,14 @@ const readDirectory = directory => {
});
};
// Some files hide more that one dataTransferItem:
// This is a safe way to get the absolute path on electron
const getFilePath = (name, files) => {
let filePath = null;
for (let file of files) {
if (file.name === name) {
filePath = file.path;
break;
}
}
return filePath;
};
// Get only files from the dataTransfer items list
// Get file system entries from the dataTransfer items list:
export const getFiles = dataTransfer => {
let entries = [];
const { items, files } = dataTransfer;
const { items } = dataTransfer;
for (let i = 0; i < items.length; i++) {
const entry = getAsEntry(items[i]);
if (entry !== null && entry.isFile) {
// Has valid path
const filePath = getFilePath(entry.name, files);
if (filePath) {
entries.push({ entry, filePath });
}
entries.push({ entry });
}
}
return entries;
@ -70,18 +52,18 @@ export const getTree = async dataTransfer => {
const entry = getAsEntry(items[0]);
// Handle entry
if (entry) {
const root = { entry, path: files[0].path };
const root = { entry };
// Handle directory
if (root.entry.isDirectory) {
const directoryEntries = await readDirectory(root.entry);
if (entry.isDirectory) {
const directoryEntries = await readDirectory(entry);
directoryEntries.forEach(item => {
if (item.isFile) {
tree.push({ entry: item, path: path.join(root.path, item.name) });
tree.push({ entry: item, rootPath: root.path });
}
});
}
// Hanlde file
if (root.entry.isFile) {
if (entry.isFile) {
tree.push(root);
}
}