feature (upload): upload button for phone and tablets

This commit is contained in:
= 2019-04-19 01:31:12 +10:00
parent 6c5771c4f5
commit 8afd06e055
6 changed files with 175 additions and 14 deletions

View file

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
aria-hidden="true"
data-prefix="fas"
data-icon="arrow-alt-to-bottom"
role="img"
viewBox="0 0 384 512"
class="svg-inline--fa fa-arrow-alt-to-bottom fa-w-12 fa-9x"
version="1.1"
id="svg7697"
sodipodi:docname="upload_white.svg"
inkscape:version="0.92.4 5da689c313, 2019-01-14">
<metadata
id="metadata7703">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs7701" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1894"
inkscape:window-height="1027"
id="namedview7699"
showgrid="false"
inkscape:zoom="0.92187498"
inkscape:cx="217.54882"
inkscape:cy="144.42132"
inkscape:window-x="10"
inkscape:window-y="37"
inkscape:window-maximized="0"
inkscape:current-layer="svg7697" />
<path
d="m 157.23297,360.4641 v -186 H 57.532969 c -17.8,0 -28.174568,-11.17176 -14.1,-22.1 L 177.63297,48.164103 c 8.37772,-6.50491 18.92228,-6.50491 27.3,0 l 134.2,104.199997 c 14.07457,10.92824 3.7,22.1 -14.1,22.1 h -99.8 v 186 c 0,13.3 -13.5475,19.67043 -24,24 -6.1592,2.55123 -20,0 -20,0 -13.3,0 -23.86429,-10.70069 -24,-24 z"
class=""
id="path7695"
style="fill:#f2f2f2;fill-opacity:1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="scsssssscsass" />
<path
d="M 360.22371,413.25476 H 24.223716 c -13.3,0 -23.9999994,6.7 -23.9999994,20 v 12 c 0,13.3 10.6999994,20 23.9999994,20 H 360.22371 c 13.3,0 24,-6.7 24,-20 v -12 c 0,-13.3 -10.7,-20 -24,-20 z"
class=""
id="path7695-3"
style="fill:#f2f2f2;fill-opacity:1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="sssssssss" />
</svg>

After

Width:  |  Height:  |  Size: 2.4 KiB

View file

@ -12,6 +12,7 @@ import img_pause from "../assets/img/pause.svg";
import img_error from "../assets/img/error.svg";
import img_loading_white from "../assets/img/loader_white.svg";
import img_download_white from "../assets/img/download_white.svg";
import img_upload_white from "../assets/img/upload_white.svg";
import img_todo_white from '../assets/img/todo_white.svg';
import img_calendar_white from '../assets/img/calendar_white.svg';
import img_calendar from '../assets/img/calendar.svg';
@ -68,6 +69,8 @@ export const Icon = (props) => {
img = img_loader;
}else if(props.name === 'download_white'){
img = img_download_white;
}else if(props.name === 'upload_white'){
img = img_upload_white;
}else if(props.name === 'play'){
img = img_play;
}else if(props.name === 'pause'){

View file

@ -102,22 +102,35 @@ export const onDelete = function(path, type){
.catch((err) => notify.send(err, 'error'));
};
/*
* The upload method has a few strategies:
* 1. user is coming from drag and drop + browser provides support to read entire folders
* 2. user is coming from drag and drop + browser DOES NOT provides support to read entire folders
* 3. user is coming from a upload form button as he doesn't have drag and drop with files
*/
export const onUpload = function(path, e){
const MAX_POOL_SIZE = 15;
let PRIOR_STATUS = {};
if(e.dataTransfer.types && e.dataTransfer.types.length >= 0){
if(e.dataTransfer.types[0] === "text/uri-list"){
return
}
}
extract_upload_directory_the_way_that_works_but_non_official(e.dataTransfer.items || [], [])
.then((files) => {
if(files.length === 0){
return extract_upload_crappy_hack_but_official_way(e.dataTransfer);
let extractFiles = null;
if(e.dataTransfer === undefined){ // case 3
extractFiles = extract_upload_crappy_hack_but_official_way(e.target);
} else {
if(e.dataTransfer.types && e.dataTransfer.types.length >= 0){
if(e.dataTransfer.types[0] === "text/uri-list"){
return
}
return Promise.resolve(files);
})
.then((files) => {
}
extractFiles = extract_upload_directory_the_way_that_works_but_non_official(e.dataTransfer.items || [], []) // case 1
.then((files) => {
if(files.length === 0){ // case 2
return extract_upload_crappy_hack_but_official_way(e.dataTransfer);
}
return Promise.resolve(files);
})
}
extractFiles.then((files) => {
var failed = [],
currents = [];

View file

@ -9,6 +9,7 @@ import { sort, onCreate, onRename, onDelete, onUpload, onSearch, createLink } fr
import { NgIf, Loader, EventReceiver, LoggedInOnly, ErrorPage } from '../components/';
import { notify, debounce, goToFiles, goToViewer, event, settings_get, settings_put } from '../helpers/';
import { BreadCrumb, FileSystem, FrequentlyAccess, Submenu } from './filespage/';
import { MobileFileUpload } from './filespage/filezone';
import InfiniteScroll from 'react-infinite-scroller';
const PAGE_NUMBER_INIT = 2;
@ -252,6 +253,7 @@ export class FilesPage extends React.Component {
<NgIf cond={!!this.state.loading}>
<Loader/>
</NgIf>
<MobileFileUpload path={this.state.path} />
</div>
</div>
<div className="upload-footer">

View file

@ -1,8 +1,9 @@
import React from 'react';
import PropTypes from 'prop-types';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
import { DropTarget } from 'react-dnd';
import { EventEmitter } from '../../components/';
import { EventEmitter, Icon } from '../../components/';
import './filezone.scss';
@EventEmitter
@ -27,7 +28,35 @@ export class FileZone extends React.Component{
);
}
}
FileZone.propTypes = {
path: PropTypes.string.isRequired
}
@EventEmitter
export class MobileFileUpload extends React.Component{
constructor(props){
super(props);
}
onUpload(e){
this.props.emit("file.upload", this.props.path, e);
}
render(){
if(/(Android|iPad|iPhone)/.test(navigator.userAgent) === false){
return null;
}
return (
<ReactCSSTransitionGroup transitionName="mobilefileupload" transitionLeave={false} transitionEnter={false} transitionAppear={true} transitionAppearTimeout={550}>
<div className="component_mobilefileupload">
<form>
<input onChange={this.onUpload.bind(this)} type="file" name="file" id="mobilefileupload" multiple/>
<label htmlFor="mobilefileupload">
<Icon name="upload_white"/>
</label>
</form>
</div>
</ReactCSSTransitionGroup>
);
}
}

View file

@ -1,3 +1,5 @@
@import "../../assets/css/mixin.scss";
.component_filezone{
border: 2px dashed;
padding: 25px 0;
@ -9,3 +11,47 @@
border: 2px dashed var(--primary);
}
}
.component_mobilefileupload{
display: inline;
position: fixed;
bottom: 25px;
right: 25px;
input[type="file"]{
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
input[type="file"]:focus + label, input[type="file"] + label:hover {
opacity: 0.95;
}
input[type="file"] + label {
display: inline-block;
cursor: pointer;
background: var(--color);
border-radius: 50%;
@include ripple(var(--emphasis-secondary), var(--primary));
box-shadow: rgba(0, 0, 0, 0.14) 0px 4px 5px 0px, rgba(0, 0, 0, 0.12) 0px 1px 10px 0px, rgba(0, 0, 0, 0.2) 0px 2px 4px -1px;
width: 50px;
height: 50px;
.component_icon{
width: 24px;
height: 24px;
padding: 13px;
}
}
}
.mobilefileupload-appear{
transform: translateX(75px);
transition: transform 0.25s ease;
}
.mobilefileupload-appear-active{
transition-delay: 0.3s;
transform: translateX(0px);
}