feat multiselection: select multiple files and act on them
fix breadcrumb: fixed breadcrumb history not working properly when clicking on "sdcard" fix dialogs/menus: fixed clicking out of menus and dialogs triggering actions other than hiding the dialog/event
@ -85,7 +85,7 @@ module.exports = function(grunt) {
|
|||||||
cwd: 'src',
|
cwd: 'src',
|
||||||
dest: 'build',
|
dest: 'build',
|
||||||
src: ['index.html', 'manifest.webapp',
|
src: ['index.html', 'manifest.webapp',
|
||||||
'fonts/**', 'img/**', 'js/libs/**']
|
'fonts/**', 'img/**', 'js/libs/**', 'icon/**']
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -17,6 +17,8 @@ Please read the Features section below and issues to make sure your issue is not
|
|||||||
- [x] Create new files and directories
|
- [x] Create new files and directories
|
||||||
- [x] File Size
|
- [x] File Size
|
||||||
- [x] Directory Child Count
|
- [x] Directory Child Count
|
||||||
|
- [x] Actions on multiple files (selection)
|
||||||
|
- [ ] Copy/Cut and Paste files
|
||||||
- [ ] File Preview
|
- [ ] File Preview
|
||||||
- [ ] Filter Files
|
- [ ] Filter Files
|
||||||
- [ ] Search
|
- [ ] Search
|
||||||
|
BIN
build/icon/Icon-128.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
build/icon/Icon-16.png
Normal file
After Width: | Height: | Size: 753 B |
BIN
build/icon/Icon-48.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
build/icon/Icon-60.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
build/icon/Icon.png
Normal file
After Width: | Height: | Size: 60 KiB |
19
build/img/Select.svg
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg width="32px" height="34px" viewBox="0 0 32 34" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||||
|
<!-- Generator: Sketch 3.3.3 (12072) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>Select</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Components" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||||
|
<g id="Toolbar" sketch:type="MSArtboardGroup" transform="translate(-257.000000, -7.000000)" stroke-linecap="round" stroke="#63B0CD" stroke-width="3">
|
||||||
|
<g sketch:type="MSLayerGroup" id="Buttons">
|
||||||
|
<g transform="translate(26.000000, 7.000000)" sketch:type="MSShapeGroup">
|
||||||
|
<g id="Select" transform="translate(232.000000, 2.000000)">
|
||||||
|
<rect id="Rectangle-31" stroke-dasharray="7,8,7,8" x="0" y="1" width="29" height="29" rx="4"></rect>
|
||||||
|
<path d="M6,17 L10,23 L24,0" id="Path-26" stroke-linejoin="round"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
@ -1,106 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<svg
|
|
||||||
xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"
|
|
||||||
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:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
|
||||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
|
||||||
width="128px"
|
|
||||||
height="128px"
|
|
||||||
viewBox="0 0 128 128"
|
|
||||||
version="1.1"
|
|
||||||
id="svg2"
|
|
||||||
inkscape:version="0.48.2 r9819"
|
|
||||||
sodipodi:docname="icon.svg">
|
|
||||||
<metadata
|
|
||||||
id="metadata14">
|
|
||||||
<rdf:RDF>
|
|
||||||
<cc:Work
|
|
||||||
rdf:about="">
|
|
||||||
<dc:format>image/svg+xml</dc:format>
|
|
||||||
<dc:type
|
|
||||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
|
||||||
</cc:Work>
|
|
||||||
</rdf:RDF>
|
|
||||||
</metadata>
|
|
||||||
<sodipodi:namedview
|
|
||||||
pagecolor="#ffffff"
|
|
||||||
bordercolor="#666666"
|
|
||||||
borderopacity="1"
|
|
||||||
objecttolerance="10"
|
|
||||||
gridtolerance="10"
|
|
||||||
guidetolerance="10"
|
|
||||||
inkscape:pageopacity="0"
|
|
||||||
inkscape:pageshadow="2"
|
|
||||||
inkscape:window-width="1142"
|
|
||||||
inkscape:window-height="849"
|
|
||||||
id="namedview12"
|
|
||||||
showgrid="false"
|
|
||||||
inkscape:zoom="1.84375"
|
|
||||||
inkscape:cx="-32.542373"
|
|
||||||
inkscape:cy="64"
|
|
||||||
inkscape:window-x="672"
|
|
||||||
inkscape:window-y="146"
|
|
||||||
inkscape:window-maximized="0"
|
|
||||||
inkscape:current-layer="Page-1" />
|
|
||||||
<!-- Generator: Sketch 3.0.2 (7799) - http://www.bohemiancoding.com/sketch -->
|
|
||||||
<title
|
|
||||||
id="title4">empty</title>
|
|
||||||
<description
|
|
||||||
id="description6">Created with Sketch.</description>
|
|
||||||
<defs
|
|
||||||
id="defs8">
|
|
||||||
<linearGradient
|
|
||||||
id="linearGradient3761">
|
|
||||||
<stop
|
|
||||||
style="stop-color:#4e748b;stop-opacity:1;"
|
|
||||||
offset="0"
|
|
||||||
id="stop3763" />
|
|
||||||
<stop
|
|
||||||
style="stop-color:#393e3f;stop-opacity:1;"
|
|
||||||
offset="1"
|
|
||||||
id="stop3765" />
|
|
||||||
</linearGradient>
|
|
||||||
<linearGradient
|
|
||||||
inkscape:collect="always"
|
|
||||||
xlink:href="#linearGradient3761"
|
|
||||||
id="linearGradient3767"
|
|
||||||
x1="129.66949"
|
|
||||||
y1="65.8983"
|
|
||||||
x2="129.66949"
|
|
||||||
y2="188.59828"
|
|
||||||
gradientUnits="userSpaceOnUse" />
|
|
||||||
</defs>
|
|
||||||
<path
|
|
||||||
sodipodi:type="arc"
|
|
||||||
style="fill:url(#linearGradient3767);fill-opacity:1;fill-rule:evenodd;stroke:none"
|
|
||||||
id="path2991"
|
|
||||||
sodipodi:cx="129.35593"
|
|
||||||
sodipodi:cy="128.27118"
|
|
||||||
sodipodi:rx="63.18644"
|
|
||||||
sodipodi:ry="63.18644"
|
|
||||||
d="m 192.54237,128.27118 a 63.18644,63.18644 0 1 1 -126.372883,0 63.18644,63.18644 0 1 1 126.372883,0 z"
|
|
||||||
transform="translate(-65.355927,-64.271179)" />
|
|
||||||
<g
|
|
||||||
id="Page-1"
|
|
||||||
sketch:type="MSPage"
|
|
||||||
transform="matrix(0.9,0,0,0.9,6.4,6.4)"
|
|
||||||
style="fill:none;stroke:none">
|
|
||||||
<circle
|
|
||||||
id="empty"
|
|
||||||
sketch:type="MSShapeGroup"
|
|
||||||
cx="64"
|
|
||||||
cy="64"
|
|
||||||
r="58"
|
|
||||||
sodipodi:cx="64"
|
|
||||||
sodipodi:cy="64"
|
|
||||||
sodipodi:rx="58"
|
|
||||||
sodipodi:ry="58"
|
|
||||||
style="stroke:#bcc6c5;stroke-width:11;stroke-linecap:round;stroke-dasharray:20, 20;fill:none;fill-opacity:1"
|
|
||||||
d="M 122,64 C 122,96.032515 96.032515,122 64,122 31.967485,122 6,96.032515 6,64 6,31.967485 31.967485,6 64,6 c 32.032515,0 58,25.967485 58,58 z" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 804 B |
Before Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 3.3 KiB |
294
build/main.js
@ -22213,7 +22213,9 @@ function rename(file, name) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function active(file) {
|
function active() {
|
||||||
|
var file = arguments.length <= 0 || arguments[0] === undefined ? null : arguments[0];
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: _actionsTypes.ACTIVE_FILE,
|
type: _actionsTypes.ACTIVE_FILE,
|
||||||
file: file
|
file: file
|
||||||
@ -22221,6 +22223,7 @@ function active(file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function deleteFile(file) {
|
function deleteFile(file) {
|
||||||
|
console.log('constructing deleteFile action', file);
|
||||||
return {
|
return {
|
||||||
type: _actionsTypes.DELETE_FILE,
|
type: _actionsTypes.DELETE_FILE,
|
||||||
file: file
|
file: file
|
||||||
@ -22237,6 +22240,7 @@ exports.refresh = refresh;
|
|||||||
exports.toggle = toggle;
|
exports.toggle = toggle;
|
||||||
exports.details = details;
|
exports.details = details;
|
||||||
exports.list = list;
|
exports.list = list;
|
||||||
|
exports.selectView = selectView;
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||||
|
|
||||||
@ -22252,27 +22256,36 @@ function refresh() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function toggle(state) {
|
function toggle() {
|
||||||
return {
|
return {
|
||||||
type: _actionsTypes.FILES_VIEW,
|
type: _actionsTypes.FILES_VIEW,
|
||||||
view: 'toggle'
|
view: 'toggle'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function details(state) {
|
function details() {
|
||||||
return {
|
return {
|
||||||
type: _actionsTypes.FILES_VIEW,
|
type: _actionsTypes.FILES_VIEW,
|
||||||
view: 'details'
|
view: 'details'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function list(state) {
|
function list() {
|
||||||
return {
|
return {
|
||||||
type: _actionsTypes.FILES_VIEW,
|
type: _actionsTypes.FILES_VIEW,
|
||||||
view: 'list'
|
view: 'list'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function selectView() {
|
||||||
|
var active = arguments.length <= 0 || arguments[0] === undefined ? true : arguments[0];
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: _actionsTypes.SELECT_VIEW,
|
||||||
|
active: active
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
},{"actions/types":223,"store":"store"}],219:[function(require,module,exports){
|
},{"actions/types":223,"store":"store"}],219:[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
@ -22407,6 +22420,7 @@ var TYPES = {
|
|||||||
|
|
||||||
LIST_FILES: Symbol('LIST_FILES'),
|
LIST_FILES: Symbol('LIST_FILES'),
|
||||||
FILES_VIEW: Symbol('FILES_VIEW'),
|
FILES_VIEW: Symbol('FILES_VIEW'),
|
||||||
|
SELECT_VIEW: Symbol('SELECT_VIEW'),
|
||||||
|
|
||||||
NAVIGATION: Symbol('NAVIGATION'),
|
NAVIGATION: Symbol('NAVIGATION'),
|
||||||
TOGGLE: Symbol('TOGGLE'),
|
TOGGLE: Symbol('TOGGLE'),
|
||||||
@ -22422,7 +22436,7 @@ var TYPES = {
|
|||||||
|
|
||||||
MENU: Symbol('MENU'),
|
MENU: Symbol('MENU'),
|
||||||
|
|
||||||
DIALOG: Symbol('DEBUG'),
|
DIALOG: Symbol('DIALOG'),
|
||||||
|
|
||||||
SETTINGS: Symbol('SETTINGS'),
|
SETTINGS: Symbol('SETTINGS'),
|
||||||
|
|
||||||
@ -22540,6 +22554,14 @@ var createDirectory = _asyncToGenerator(function* () {
|
|||||||
|
|
||||||
exports.createDirectory = createDirectory;
|
exports.createDirectory = createDirectory;
|
||||||
|
|
||||||
|
var remove = _asyncToGenerator(function* (file) {
|
||||||
|
var parent = yield root();
|
||||||
|
|
||||||
|
return parent.remove(file);
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.remove = remove;
|
||||||
|
|
||||||
var move = _asyncToGenerator(function* (file, newPath) {
|
var move = _asyncToGenerator(function* (file, newPath) {
|
||||||
var path = (file.path || '').replace(/^\//, ''); // remove starting slash
|
var path = (file.path || '').replace(/^\//, ''); // remove starting slash
|
||||||
var oldPath = path + file.name;
|
var oldPath = path + file.name;
|
||||||
@ -22667,12 +22689,13 @@ var Breadcrumb = (function (_Component) {
|
|||||||
_createClass(Breadcrumb, [{
|
_createClass(Breadcrumb, [{
|
||||||
key: 'render',
|
key: 'render',
|
||||||
value: function render() {
|
value: function render() {
|
||||||
var directories = this.props.cwd.split('/');
|
var directories = this.props.cwd.split('/').filter(function (a) {
|
||||||
|
return a;
|
||||||
|
});
|
||||||
directories.unshift('sdcard');
|
directories.unshift('sdcard');
|
||||||
|
|
||||||
var els = directories.map(function (dir, index, arr) {
|
var els = directories.map(function (dir, index, arr) {
|
||||||
var path = arr.slice(1, index + 1).join('/');
|
var path = arr.slice(1, index + 1).join('/');
|
||||||
var slash = index > 0 ? '/' : '';
|
|
||||||
|
|
||||||
return _react2['default'].createElement(
|
return _react2['default'].createElement(
|
||||||
'span',
|
'span',
|
||||||
@ -22680,18 +22703,21 @@ var Breadcrumb = (function (_Component) {
|
|||||||
_react2['default'].createElement(
|
_react2['default'].createElement(
|
||||||
'i',
|
'i',
|
||||||
null,
|
null,
|
||||||
slash
|
'/'
|
||||||
),
|
),
|
||||||
dir
|
dir
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
var lastDirectories = this.props.lwd.split('/');
|
var lastDirectories = this.props.lwd.split('/').filter(function (a) {
|
||||||
|
return a;
|
||||||
|
});
|
||||||
if (lastDirectories.length > directories.length - 1) {
|
if (lastDirectories.length > directories.length - 1) {
|
||||||
lastDirectories.splice(0, directories.length - 1);
|
lastDirectories.splice(0, directories.length - 1);
|
||||||
|
|
||||||
var _history = lastDirectories.map(function (dir, index, arr) {
|
var _history = lastDirectories.map(function (dir, index, arr) {
|
||||||
var current = directories.slice(1).concat(arr.slice(0, index + 1));
|
var current = directories.slice(1).concat(arr.slice(0, index + 1));
|
||||||
var path = current.join('/');
|
var path = current.join('/').replace(/^\//, ''); // remove starting slash
|
||||||
|
|
||||||
return _react2['default'].createElement(
|
return _react2['default'].createElement(
|
||||||
'span',
|
'span',
|
||||||
@ -22865,11 +22891,24 @@ var Directory = (function (_Component) {
|
|||||||
_createClass(Directory, [{
|
_createClass(Directory, [{
|
||||||
key: 'render',
|
key: 'render',
|
||||||
value: function render() {
|
value: function render() {
|
||||||
|
var checkId = 'file-' + this.props.index;
|
||||||
|
|
||||||
|
var input = undefined,
|
||||||
|
label = undefined;
|
||||||
|
if (this.props.selectView) {
|
||||||
|
input = _react2['default'].createElement('input', { type: 'checkbox', id: checkId, checked: this.props.selected, readOnly: true });
|
||||||
|
label = _react2['default'].createElement('label', { htmlFor: checkId });
|
||||||
|
}
|
||||||
|
|
||||||
|
var clickHandler = this.props.selectView ? this.select.bind(this) : this.peek.bind(this);
|
||||||
|
|
||||||
return _react2['default'].createElement(
|
return _react2['default'].createElement(
|
||||||
'div',
|
'div',
|
||||||
{ className: 'directory', ref: 'container',
|
{ className: 'directory', ref: 'container',
|
||||||
onClick: this.peek.bind(this),
|
onClick: clickHandler,
|
||||||
onContextMenu: this.contextMenu.bind(this) },
|
onContextMenu: this.contextMenu.bind(this) },
|
||||||
|
input,
|
||||||
|
label,
|
||||||
_react2['default'].createElement('i', null),
|
_react2['default'].createElement('i', null),
|
||||||
_react2['default'].createElement(
|
_react2['default'].createElement(
|
||||||
'p',
|
'p',
|
||||||
@ -22907,6 +22946,19 @@ var Directory = (function (_Component) {
|
|||||||
_store2['default'].dispatch((0, _actionsMenu.show)('directoryMenu', { style: { left: left, top: top } }));
|
_store2['default'].dispatch((0, _actionsMenu.show)('directoryMenu', { style: { left: left, top: top } }));
|
||||||
_store2['default'].dispatch((0, _actionsFile.active)(this.props.index));
|
_store2['default'].dispatch((0, _actionsFile.active)(this.props.index));
|
||||||
}
|
}
|
||||||
|
}, {
|
||||||
|
key: 'select',
|
||||||
|
value: function select() {
|
||||||
|
var current = (_store2['default'].getState().get('activeFile') || []).slice(0);
|
||||||
|
var index = this.props.index;
|
||||||
|
|
||||||
|
if (current.indexOf(index) > -1) {
|
||||||
|
current.splice(current.indexOf(index), 1);
|
||||||
|
} else {
|
||||||
|
current.push(index);
|
||||||
|
}
|
||||||
|
_store2['default'].dispatch((0, _actionsFile.active)(current));
|
||||||
|
}
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
return Directory;
|
return Directory;
|
||||||
@ -22973,29 +23025,20 @@ var FileList = (function (_Component) {
|
|||||||
_createClass(FileList, [{
|
_createClass(FileList, [{
|
||||||
key: 'render',
|
key: 'render',
|
||||||
value: function render() {
|
value: function render() {
|
||||||
var files = this.props.files;
|
var _props = this.props;
|
||||||
|
var files = _props.files;
|
||||||
|
var selectView = _props.selectView;
|
||||||
|
var activeFile = _props.activeFile;
|
||||||
|
|
||||||
|
activeFile = activeFile || [];
|
||||||
var settings = _store2['default'].getState().get('settings');
|
var settings = _store2['default'].getState().get('settings');
|
||||||
|
|
||||||
if (settings.showDirectoriesFirst) {
|
|
||||||
files = files.sort(function (a, b) {
|
|
||||||
if ((0, _utils.type)(a) === 'Directory') return -1;
|
|
||||||
if ((0, _utils.type)(b) === 'Directory') return 1;
|
|
||||||
return 0;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!settings.showHiddenFiles) {
|
|
||||||
files = files.filter(function (file) {
|
|
||||||
return file.name[0] !== '.';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var els = files.map(function (file, index) {
|
var els = files.map(function (file, index) {
|
||||||
|
var selected = activeFile.indexOf(index) > -1;
|
||||||
if ((0, _utils.type)(file) === 'File') {
|
if ((0, _utils.type)(file) === 'File') {
|
||||||
return _react2['default'].createElement(_file2['default'], { key: index, index: index, name: file.name, size: file.size });
|
return _react2['default'].createElement(_file2['default'], { selectView: selectView, selected: selected, key: index, index: index, name: file.name, size: file.size });
|
||||||
} else {
|
} else {
|
||||||
return _react2['default'].createElement(_directory2['default'], { key: index, index: index, name: file.name, children: file.children });
|
return _react2['default'].createElement(_directory2['default'], { selectView: selectView, selected: selected, key: index, index: index, name: file.name, children: file.children });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -23016,7 +23059,9 @@ exports['default'] = FileList;
|
|||||||
|
|
||||||
function props(state) {
|
function props(state) {
|
||||||
return {
|
return {
|
||||||
files: state.get('files')
|
files: state.get('files'),
|
||||||
|
selectView: state.get('selectView'),
|
||||||
|
activeFile: state.get('activeFile')
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23069,10 +23114,24 @@ var File = (function (_Component) {
|
|||||||
_createClass(File, [{
|
_createClass(File, [{
|
||||||
key: 'render',
|
key: 'render',
|
||||||
value: function render() {
|
value: function render() {
|
||||||
|
var checkId = 'file-' + this.props.index;
|
||||||
|
|
||||||
|
var input = undefined,
|
||||||
|
label = undefined;
|
||||||
|
if (this.props.selectView) {
|
||||||
|
input = _react2['default'].createElement('input', { type: 'checkbox', id: checkId, defaultChecked: this.props.selected, readOnly: true });
|
||||||
|
label = _react2['default'].createElement('label', { htmlFor: checkId });
|
||||||
|
}
|
||||||
|
|
||||||
|
var clickHandler = this.props.selectView ? this.select.bind(this) : null;
|
||||||
|
|
||||||
return _react2['default'].createElement(
|
return _react2['default'].createElement(
|
||||||
'div',
|
'div',
|
||||||
{ className: 'file', ref: 'container',
|
{ className: 'file', ref: 'container',
|
||||||
|
onClick: clickHandler,
|
||||||
onContextMenu: this.contextMenu.bind(this) },
|
onContextMenu: this.contextMenu.bind(this) },
|
||||||
|
input,
|
||||||
|
label,
|
||||||
_react2['default'].createElement('i', null),
|
_react2['default'].createElement('i', null),
|
||||||
_react2['default'].createElement(
|
_react2['default'].createElement(
|
||||||
'p',
|
'p',
|
||||||
@ -23102,6 +23161,19 @@ var File = (function (_Component) {
|
|||||||
_store2['default'].dispatch((0, _actionsMenu.show)('fileMenu', { style: { left: left, top: top } }));
|
_store2['default'].dispatch((0, _actionsMenu.show)('fileMenu', { style: { left: left, top: top } }));
|
||||||
_store2['default'].dispatch((0, _actionsFile.active)(this.props.index));
|
_store2['default'].dispatch((0, _actionsFile.active)(this.props.index));
|
||||||
}
|
}
|
||||||
|
}, {
|
||||||
|
key: 'select',
|
||||||
|
value: function select() {
|
||||||
|
var current = (_store2['default'].getState().get('activeFile') || []).slice(0);
|
||||||
|
var index = this.props.index;
|
||||||
|
|
||||||
|
if (current.indexOf(index) > -1) {
|
||||||
|
current.splice(current.indexOf(index), 1);
|
||||||
|
} else {
|
||||||
|
current.push(index);
|
||||||
|
}
|
||||||
|
_store2['default'].dispatch((0, _actionsFile.active)(current));
|
||||||
|
}
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
return File;
|
return File;
|
||||||
@ -23482,6 +23554,9 @@ var FileMenu = (0, _reactRedux.connect)(function (state) {
|
|||||||
var DirectoryMenu = (0, _reactRedux.connect)(function (state) {
|
var DirectoryMenu = (0, _reactRedux.connect)(function (state) {
|
||||||
return state.get('directoryMenu');
|
return state.get('directoryMenu');
|
||||||
})(_componentsMenu2['default']);
|
})(_componentsMenu2['default']);
|
||||||
|
var MoreMenu = (0, _reactRedux.connect)(function (state) {
|
||||||
|
return state.get('moreMenu');
|
||||||
|
})(_componentsMenu2['default']);
|
||||||
|
|
||||||
var RenameDialog = (0, _reactRedux.connect)(function (state) {
|
var RenameDialog = (0, _reactRedux.connect)(function (state) {
|
||||||
return state.get('renameDialog');
|
return state.get('renameDialog');
|
||||||
@ -23518,6 +23593,7 @@ var Root = (function (_Component) {
|
|||||||
_react2['default'].createElement(_componentsToolbar2['default'], null),
|
_react2['default'].createElement(_componentsToolbar2['default'], null),
|
||||||
_react2['default'].createElement(FileMenu, null),
|
_react2['default'].createElement(FileMenu, null),
|
||||||
_react2['default'].createElement(DirectoryMenu, null),
|
_react2['default'].createElement(DirectoryMenu, null),
|
||||||
|
_react2['default'].createElement(MoreMenu, null),
|
||||||
_react2['default'].createElement(RenameDialog, null),
|
_react2['default'].createElement(RenameDialog, null),
|
||||||
_react2['default'].createElement(DeleteDialog, null),
|
_react2['default'].createElement(DeleteDialog, null),
|
||||||
_react2['default'].createElement(ErrorDialog, null),
|
_react2['default'].createElement(ErrorDialog, null),
|
||||||
@ -23527,7 +23603,12 @@ var Root = (function (_Component) {
|
|||||||
}, {
|
}, {
|
||||||
key: 'touchStart',
|
key: 'touchStart',
|
||||||
value: function touchStart(e) {
|
value: function touchStart(e) {
|
||||||
if (!e.target.closest('.menu')) {
|
var active = document.querySelector('.active');
|
||||||
|
var inside = e.target.closest('.menu') || e.target.closest('.dialog');
|
||||||
|
if (!inside && active) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
_store2['default'].dispatch((0, _actionsMenu.hideAll)());
|
_store2['default'].dispatch((0, _actionsMenu.hideAll)());
|
||||||
_store2['default'].dispatch((0, _actionsDialog.hideAll)());
|
_store2['default'].dispatch((0, _actionsDialog.hideAll)());
|
||||||
}
|
}
|
||||||
@ -23565,10 +23646,14 @@ var _actionsFilesView = require('actions/files-view');
|
|||||||
|
|
||||||
var _actionsDialog = require('actions/dialog');
|
var _actionsDialog = require('actions/dialog');
|
||||||
|
|
||||||
|
var _actionsMenu = require('actions/menu');
|
||||||
|
|
||||||
var _store = require('store');
|
var _store = require('store');
|
||||||
|
|
||||||
var _store2 = _interopRequireDefault(_store);
|
var _store2 = _interopRequireDefault(_store);
|
||||||
|
|
||||||
|
var _menu = require('./menu');
|
||||||
|
|
||||||
var Toolbar = (function (_Component) {
|
var Toolbar = (function (_Component) {
|
||||||
_inherits(Toolbar, _Component);
|
_inherits(Toolbar, _Component);
|
||||||
|
|
||||||
@ -23587,13 +23672,25 @@ var Toolbar = (function (_Component) {
|
|||||||
_react2['default'].createElement('button', { className: 'icon-plus', onClick: this.newFile }),
|
_react2['default'].createElement('button', { className: 'icon-plus', onClick: this.newFile }),
|
||||||
_react2['default'].createElement('button', { className: 'icon-view', onClick: (0, _store.bind)((0, _actionsFilesView.toggle)()) }),
|
_react2['default'].createElement('button', { className: 'icon-view', onClick: (0, _store.bind)((0, _actionsFilesView.toggle)()) }),
|
||||||
_react2['default'].createElement('button', { className: 'icon-refresh', onClick: (0, _store.bind)((0, _actionsFilesView.refresh)()) }),
|
_react2['default'].createElement('button', { className: 'icon-refresh', onClick: (0, _store.bind)((0, _actionsFilesView.refresh)()) }),
|
||||||
_react2['default'].createElement('button', { className: 'icon-share', onClick: this.share }),
|
_react2['default'].createElement('button', { className: 'icon-select', onClick: (0, _store.bind)((0, _actionsFilesView.selectView)('toggle')) }),
|
||||||
_react2['default'].createElement('button', { className: 'icon-more', onClick: this.showMore })
|
_react2['default'].createElement('button', { className: 'icon-more', onClick: this.showMore.bind(this), ref: 'more' })
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'showMore',
|
key: 'showMore',
|
||||||
value: function showMore() {}
|
value: function showMore() {
|
||||||
|
var rect = _react2['default'].findDOMNode(this.refs.more).getBoundingClientRect();
|
||||||
|
var x = rect.x;
|
||||||
|
var y = rect.y;
|
||||||
|
var width = rect.width;
|
||||||
|
var height = rect.height;
|
||||||
|
|
||||||
|
var left = x + width - _menu.MENU_WIDTH,
|
||||||
|
top = y + height;
|
||||||
|
|
||||||
|
var transform = 'translate(0, -100%)';
|
||||||
|
_store2['default'].dispatch((0, _actionsMenu.show)('moreMenu', { style: { left: left, top: top, transform: transform } }));
|
||||||
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'newFile',
|
key: 'newFile',
|
||||||
value: function newFile() {
|
value: function newFile() {
|
||||||
@ -23611,7 +23708,7 @@ var Toolbar = (function (_Component) {
|
|||||||
exports['default'] = Toolbar;
|
exports['default'] = Toolbar;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"actions/dialog":216,"actions/files-view":218,"react":205,"store":"store"}],235:[function(require,module,exports){
|
},{"./menu":231,"actions/dialog":216,"actions/files-view":218,"actions/menu":220,"react":205,"store":"store"}],235:[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
Object.defineProperty(exports, '__esModule', {
|
Object.defineProperty(exports, '__esModule', {
|
||||||
@ -23646,6 +23743,7 @@ exports['default'] = {
|
|||||||
var action = (0, _actionsFile.create)(cwd + input.value);
|
var action = (0, _actionsFile.create)(cwd + input.value);
|
||||||
this.props.dispatch(action);
|
this.props.dispatch(action);
|
||||||
this.props.dispatch((0, _actionsDialog.hideAll)());
|
this.props.dispatch((0, _actionsDialog.hideAll)());
|
||||||
|
this.props.dispatch((0, _actionsFile.active)());
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
text: 'Directory',
|
text: 'Directory',
|
||||||
@ -23656,6 +23754,7 @@ exports['default'] = {
|
|||||||
var action = (0, _actionsFile.create)(cwd + input.value, true);
|
var action = (0, _actionsFile.create)(cwd + input.value, true);
|
||||||
this.props.dispatch(action);
|
this.props.dispatch(action);
|
||||||
this.props.dispatch((0, _actionsDialog.hideAll)());
|
this.props.dispatch((0, _actionsDialog.hideAll)());
|
||||||
|
this.props.dispatch((0, _actionsFile.active)());
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
@ -23674,6 +23773,7 @@ exports['default'] = {
|
|||||||
var activeFile = _store2['default'].getState().get('activeFile');
|
var activeFile = _store2['default'].getState().get('activeFile');
|
||||||
this.props.dispatch((0, _actionsFile.rename)(activeFile, input.value));
|
this.props.dispatch((0, _actionsFile.rename)(activeFile, input.value));
|
||||||
this.props.dispatch((0, _actionsDialog.hideAll)());
|
this.props.dispatch((0, _actionsDialog.hideAll)());
|
||||||
|
this.props.dispatch((0, _actionsFile.active)());
|
||||||
},
|
},
|
||||||
className: 'success'
|
className: 'success'
|
||||||
}]
|
}]
|
||||||
@ -23690,6 +23790,7 @@ exports['default'] = {
|
|||||||
var activeFile = _store2['default'].getState().get('activeFile');
|
var activeFile = _store2['default'].getState().get('activeFile');
|
||||||
this.props.dispatch((0, _actionsFile.deleteFile)(activeFile));
|
this.props.dispatch((0, _actionsFile.deleteFile)(activeFile));
|
||||||
this.props.dispatch((0, _actionsDialog.hideAll)());
|
this.props.dispatch((0, _actionsDialog.hideAll)());
|
||||||
|
this.props.dispatch((0, _actionsFile.active)());
|
||||||
},
|
},
|
||||||
className: 'success'
|
className: 'success'
|
||||||
}]
|
}]
|
||||||
@ -23774,9 +23875,32 @@ var entryMenu = {
|
|||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var moreMenu = {
|
||||||
|
items: [{
|
||||||
|
name: 'Delete',
|
||||||
|
action: function action() {
|
||||||
|
var files = _store2['default'].getState().get('files');
|
||||||
|
var active = _store2['default'].getState().get('activeFile');
|
||||||
|
|
||||||
|
var description = undefined;
|
||||||
|
if (active.length) {
|
||||||
|
var count = active.length;
|
||||||
|
description = 'Are you sure you want to remove ' + count + ' files?';
|
||||||
|
} else {
|
||||||
|
var _name = files[active].name;
|
||||||
|
description = 'Are you sure you want to remove ' + _name + '?';
|
||||||
|
}
|
||||||
|
|
||||||
|
_store2['default'].dispatch((0, _actionsMenu.hideAll)());
|
||||||
|
_store2['default'].dispatch((0, _actionsDialog.show)('deleteDialog', { description: description }));
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
exports['default'] = {
|
exports['default'] = {
|
||||||
fileMenu: Object.assign({}, entryMenu),
|
fileMenu: Object.assign({}, entryMenu),
|
||||||
directoryMenu: Object.assign({}, entryMenu)
|
directoryMenu: Object.assign({}, entryMenu),
|
||||||
|
moreMenu: moreMenu
|
||||||
};
|
};
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
@ -23790,7 +23914,7 @@ Object.defineProperty(exports, '__esModule', {
|
|||||||
var _actionsTypes = require('actions/types');
|
var _actionsTypes = require('actions/types');
|
||||||
|
|
||||||
exports['default'] = function (state, action) {
|
exports['default'] = function (state, action) {
|
||||||
if (state === undefined) state = -1;
|
if (state === undefined) state = null;
|
||||||
|
|
||||||
if (action.type === _actionsTypes.ACTIVE_FILE) {
|
if (action.type === _actionsTypes.ACTIVE_FILE) {
|
||||||
return action.file;
|
return action.file;
|
||||||
@ -23846,6 +23970,10 @@ var _settings = require('./settings');
|
|||||||
|
|
||||||
var _settings2 = _interopRequireDefault(_settings);
|
var _settings2 = _interopRequireDefault(_settings);
|
||||||
|
|
||||||
|
var _selectView = require('./select-view');
|
||||||
|
|
||||||
|
var _selectView2 = _interopRequireDefault(_selectView);
|
||||||
|
|
||||||
exports['default'] = function (state, action) {
|
exports['default'] = function (state, action) {
|
||||||
if (state === undefined) state = new _immutable2['default'].Map();
|
if (state === undefined) state = new _immutable2['default'].Map();
|
||||||
|
|
||||||
@ -23854,11 +23982,13 @@ exports['default'] = function (state, action) {
|
|||||||
lwd: (0, _lwd2['default'])(state, action), // last working directory
|
lwd: (0, _lwd2['default'])(state, action), // last working directory
|
||||||
cwd: (0, _cwd2['default'])(state.get('cwd'), action),
|
cwd: (0, _cwd2['default'])(state.get('cwd'), action),
|
||||||
files: (0, _files2['default'])(state.get('files'), action),
|
files: (0, _files2['default'])(state.get('files'), action),
|
||||||
|
selectView: (0, _selectView2['default'])(state.get('selectView'), action),
|
||||||
activeFile: (0, _activeFile2['default'])(state.get('activeFile'), action),
|
activeFile: (0, _activeFile2['default'])(state.get('activeFile'), action),
|
||||||
navigation: (0, _navigation2['default'])(state.get('navigation'), action),
|
navigation: (0, _navigation2['default'])(state.get('navigation'), action),
|
||||||
settings: (0, _settings2['default'])(state.get('settings'), action),
|
settings: (0, _settings2['default'])(state.get('settings'), action),
|
||||||
fileMenu: (0, _menu2['default'])(state, action, 'fileMenu'),
|
fileMenu: (0, _menu2['default'])(state, action, 'fileMenu'),
|
||||||
directoryMenu: (0, _menu2['default'])(state, action, 'directoryMenu'),
|
directoryMenu: (0, _menu2['default'])(state, action, 'directoryMenu'),
|
||||||
|
moreMenu: (0, _menu2['default'])(state, action, 'moreMenu'),
|
||||||
renameDialog: (0, _dialog2['default'])(state, action, 'renameDialog'),
|
renameDialog: (0, _dialog2['default'])(state, action, 'renameDialog'),
|
||||||
deleteDialog: (0, _dialog2['default'])(state, action, 'deleteDialog'),
|
deleteDialog: (0, _dialog2['default'])(state, action, 'deleteDialog'),
|
||||||
errorDialog: (0, _dialog2['default'])(state, action, 'errorDialog'),
|
errorDialog: (0, _dialog2['default'])(state, action, 'errorDialog'),
|
||||||
@ -23868,7 +23998,7 @@ exports['default'] = function (state, action) {
|
|||||||
|
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"./active-file":238,"./cwd":240,"./dialog":241,"./files":242,"./lwd":243,"./menu":244,"./navigation":245,"./settings":246,"immutable":247}],240:[function(require,module,exports){
|
},{"./active-file":238,"./cwd":240,"./dialog":241,"./files":242,"./lwd":243,"./menu":244,"./navigation":245,"./select-view":246,"./settings":247,"immutable":248}],240:[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
Object.defineProperty(exports, '__esModule', {
|
Object.defineProperty(exports, '__esModule', {
|
||||||
@ -23958,7 +24088,7 @@ exports['default'] = function (state, action, id) {
|
|||||||
|
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"actions/types":223,"immutable":247,"lodash/object/omit":37}],242:[function(require,module,exports){
|
},{"actions/types":223,"immutable":248,"lodash/object/omit":37}],242:[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
Object.defineProperty(exports, '__esModule', {
|
Object.defineProperty(exports, '__esModule', {
|
||||||
@ -23987,6 +24117,22 @@ exports['default'] = function (state, action) {
|
|||||||
if (state === undefined) state = [];
|
if (state === undefined) state = [];
|
||||||
|
|
||||||
if (action.type === _actionsTypes.LIST_FILES) {
|
if (action.type === _actionsTypes.LIST_FILES) {
|
||||||
|
|
||||||
|
var settings = _store2['default'].getState().get('settings');
|
||||||
|
|
||||||
|
if (settings.showDirectoriesFirst) {
|
||||||
|
action.files = action.files.sort(function (a, b) {
|
||||||
|
if ((0, _utils.type)(a) === 'Directory') return -1;
|
||||||
|
if ((0, _utils.type)(a) === 'File') return 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!settings.showHiddenFiles) {
|
||||||
|
action.files = action.files.filter(function (file) {
|
||||||
|
return file.name[0] !== '.';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return action.files;
|
return action.files;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -24006,17 +24152,52 @@ exports['default'] = function (state, action) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action.type === _actionsTypes.DELETE_FILE) {
|
if (action.type === _actionsTypes.DELETE_FILE) {
|
||||||
var file = state[action.file];
|
|
||||||
|
|
||||||
(0, _apiFiles.sdcard)()['delete']((file.path || '') + '/' + file.name);
|
|
||||||
var copy = state.slice(0);
|
var copy = state.slice(0);
|
||||||
|
|
||||||
|
if (action.file.length) {
|
||||||
|
var _iteratorNormalCompletion = true;
|
||||||
|
var _didIteratorError = false;
|
||||||
|
var _iteratorError = undefined;
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (var _iterator = action.file[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||||
|
var index = _step.value;
|
||||||
|
|
||||||
|
del(state, index);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
_didIteratorError = true;
|
||||||
|
_iteratorError = err;
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (!_iteratorNormalCompletion && _iterator['return']) {
|
||||||
|
_iterator['return']();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (_didIteratorError) {
|
||||||
|
throw _iteratorError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
copy = copy.filter(function (a, i) {
|
||||||
|
return action.file.indexOf(i) === -1;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
del(state, action.file);
|
||||||
copy.splice(action.file, 1);
|
copy.splice(action.file, 1);
|
||||||
|
}
|
||||||
|
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function del(state, index) {
|
||||||
|
var file = state[index];
|
||||||
|
return (0, _apiFiles.remove)((file.path || '') + '/' + file.name)['catch'](_utils.reportError);
|
||||||
|
}
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"actions/dialog":216,"actions/files-view":218,"actions/types":223,"api/files":224,"store":"store","utils":"utils"}],243:[function(require,module,exports){
|
},{"actions/dialog":216,"actions/files-view":218,"actions/types":223,"api/files":224,"store":"store","utils":"utils"}],243:[function(require,module,exports){
|
||||||
@ -24081,7 +24262,7 @@ exports['default'] = function (state, action, id) {
|
|||||||
|
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"actions/types":223,"immutable":247,"lodash/object/omit":37}],245:[function(require,module,exports){
|
},{"actions/types":223,"immutable":248,"lodash/object/omit":37}],245:[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
Object.defineProperty(exports, '__esModule', {
|
Object.defineProperty(exports, '__esModule', {
|
||||||
@ -24109,6 +24290,27 @@ Object.defineProperty(exports, '__esModule', {
|
|||||||
value: true
|
value: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var _actionsTypes = require('actions/types');
|
||||||
|
|
||||||
|
exports['default'] = function (state, action) {
|
||||||
|
if (state === undefined) state = false;
|
||||||
|
|
||||||
|
if (action.type === _actionsTypes.SELECT_VIEW) {
|
||||||
|
return action.active === 'toggle' ? !state : action.active;
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = exports['default'];
|
||||||
|
|
||||||
|
},{"actions/types":223}],247:[function(require,module,exports){
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
Object.defineProperty(exports, '__esModule', {
|
||||||
|
value: true
|
||||||
|
});
|
||||||
|
|
||||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||||
|
|
||||||
var _actionsTypes = require('actions/types');
|
var _actionsTypes = require('actions/types');
|
||||||
@ -24134,7 +24336,7 @@ exports['default'] = function (state, action) {
|
|||||||
|
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"actions/types":223,"lodash/object/omit":37}],247:[function(require,module,exports){
|
},{"actions/types":223,"lodash/object/omit":37}],248:[function(require,module,exports){
|
||||||
/**
|
/**
|
||||||
* Copyright (c) 2014-2015, Facebook, Inc.
|
* Copyright (c) 2014-2015, Facebook, Inc.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
@ -29109,7 +29311,7 @@ function bind(action) {
|
|||||||
|
|
||||||
exports['default'] = store;
|
exports['default'] = store;
|
||||||
|
|
||||||
},{"./dialogs":235,"./menus":237,"actions/changedir":215,"immutable":247,"reducers/all":239,"redux":207}],"utils":[function(require,module,exports){
|
},{"./dialogs":235,"./menus":237,"actions/changedir":215,"immutable":248,"reducers/all":239,"redux":207}],"utils":[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
Object.defineProperty(exports, '__esModule', {
|
Object.defineProperty(exports, '__esModule', {
|
||||||
@ -29168,15 +29370,13 @@ var sizes = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function humanSize(size) {
|
function humanSize(size) {
|
||||||
console.log(size);
|
|
||||||
for (var key in sizes) {
|
for (var key in sizes) {
|
||||||
var value = sizes[key];
|
var value = sizes[key];
|
||||||
|
|
||||||
console.log(value);
|
|
||||||
if (size > value) {
|
if (size > value) {
|
||||||
return Math.round(size / value) + key;
|
return Math.round(size / value) + key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
},{"actions/dialog":216,"store":"store"}]},{},[215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,"store","utils"]);
|
},{"actions/dialog":216,"store":"store"}]},{},[215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,"store","utils"]);
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
"description": "Keep an eye on your files with a full-featured file-manager",
|
"description": "Keep an eye on your files with a full-featured file-manager",
|
||||||
"launch_path": "/index.html",
|
"launch_path": "/index.html",
|
||||||
"icons": {
|
"icons": {
|
||||||
"16": "/img/icons/icon16x16.png",
|
"16": "/icon/Icon-16.png",
|
||||||
"48": "/img/icons/icon48x48.png",
|
"48": "/icon/Icon-48.png",
|
||||||
"60": "/img/icons/icon60x60.png",
|
"60": "/icon/Icon-60.png",
|
||||||
"128": "/img/icons/icon128x128.png"
|
"128": "/icon/Icon-128.png"
|
||||||
},
|
},
|
||||||
"developer": {
|
"developer": {
|
||||||
"name": "Mahdi Dibaiee",
|
"name": "Mahdi Dibaiee",
|
||||||
|
@ -31,11 +31,11 @@
|
|||||||
width: 26px;
|
width: 26px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
}
|
}
|
||||||
.icon-share {
|
.icon-select {
|
||||||
display: block;
|
display: block;
|
||||||
background: url(/img/Share.svg) no-repeat;
|
background: url(/img/Select.svg) no-repeat;
|
||||||
width: 25px;
|
width: 32px;
|
||||||
height: 27px;
|
height: 34px;
|
||||||
}
|
}
|
||||||
.icon-more {
|
.icon-more {
|
||||||
display: block;
|
display: block;
|
||||||
@ -104,21 +104,26 @@ input {
|
|||||||
font-weight: 200;
|
font-weight: 200;
|
||||||
font-size: 1.6rem;
|
font-size: 1.6rem;
|
||||||
}
|
}
|
||||||
input[type="checkbox"] {
|
label {
|
||||||
width: 0;
|
clear: left;
|
||||||
height: 0;
|
|
||||||
}
|
}
|
||||||
input[type="checkbox"]::before {
|
label::after {
|
||||||
content: '';
|
content: '';
|
||||||
display: block;
|
display: block;
|
||||||
border: 1px solid #f0f0f0;
|
float: right;
|
||||||
background: transparent;
|
margin-right: 13px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
width: 10px;
|
width: 10px;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
box-sizing: border-box;
|
background: transparent;
|
||||||
|
border: 1px solid #9b9b93;
|
||||||
}
|
}
|
||||||
input[type="checkbox"]::before:checked {
|
input[type='checkbox'] {
|
||||||
|
clear: right;
|
||||||
|
float: right;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
input:checked + label::after {
|
||||||
background: #63b0cd;
|
background: #63b0cd;
|
||||||
}
|
}
|
||||||
.file,
|
.file,
|
||||||
@ -259,28 +264,6 @@ nav li:last-of-type {
|
|||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
nav li label {
|
|
||||||
clear: left;
|
|
||||||
}
|
|
||||||
nav li label::after {
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
float: right;
|
|
||||||
margin-right: 13px;
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
background: transparent;
|
|
||||||
border: 1px solid #9b9b93;
|
|
||||||
}
|
|
||||||
nav li input {
|
|
||||||
clear: right;
|
|
||||||
float: right;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
nav li input:checked + label::after {
|
|
||||||
background: #63b0cd;
|
|
||||||
}
|
|
||||||
nav i {
|
nav i {
|
||||||
display: block;
|
display: block;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
BIN
src/icon/Icon-128.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
src/icon/Icon-16.png
Normal file
After Width: | Height: | Size: 753 B |
BIN
src/icon/Icon-48.png
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
src/icon/Icon-60.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
src/icon/Icon.png
Normal file
After Width: | Height: | Size: 60 KiB |
19
src/img/Select.svg
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg width="32px" height="34px" viewBox="0 0 32 34" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||||
|
<!-- Generator: Sketch 3.3.3 (12072) - http://www.bohemiancoding.com/sketch -->
|
||||||
|
<title>Select</title>
|
||||||
|
<desc>Created with Sketch.</desc>
|
||||||
|
<defs></defs>
|
||||||
|
<g id="Components" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||||
|
<g id="Toolbar" sketch:type="MSArtboardGroup" transform="translate(-257.000000, -7.000000)" stroke-linecap="round" stroke="#63B0CD" stroke-width="3">
|
||||||
|
<g sketch:type="MSLayerGroup" id="Buttons">
|
||||||
|
<g transform="translate(26.000000, 7.000000)" sketch:type="MSShapeGroup">
|
||||||
|
<g id="Select" transform="translate(232.000000, 2.000000)">
|
||||||
|
<rect id="Rectangle-31" stroke-dasharray="7,8,7,8" x="0" y="1" width="29" height="29" rx="4"></rect>
|
||||||
|
<path d="M6,17 L10,23 L24,0" id="Path-26" stroke-linejoin="round"></path>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.2 KiB |
@ -21,7 +21,7 @@ export function rename(file, name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function active(file) {
|
export function active(file = null) {
|
||||||
return {
|
return {
|
||||||
type: ACTIVE_FILE,
|
type: ACTIVE_FILE,
|
||||||
file
|
file
|
||||||
@ -29,6 +29,7 @@ export function active(file) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function deleteFile(file) {
|
export function deleteFile(file) {
|
||||||
|
console.log('constructing deleteFile action', file);
|
||||||
return {
|
return {
|
||||||
type: DELETE_FILE,
|
type: DELETE_FILE,
|
||||||
file
|
file
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { LIST_FILES, FILES_VIEW, REFRESH } from 'actions/types';
|
import { LIST_FILES, FILES_VIEW, SELECT_VIEW, REFRESH } from 'actions/types';
|
||||||
import store from 'store';
|
import store from 'store';
|
||||||
|
|
||||||
export function refresh() {
|
export function refresh() {
|
||||||
@ -7,23 +7,30 @@ export function refresh() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function toggle(state) {
|
export function toggle() {
|
||||||
return {
|
return {
|
||||||
type: FILES_VIEW,
|
type: FILES_VIEW,
|
||||||
view: 'toggle'
|
view: 'toggle'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function details(state) {
|
export function details() {
|
||||||
return {
|
return {
|
||||||
type: FILES_VIEW,
|
type: FILES_VIEW,
|
||||||
view: 'details'
|
view: 'details'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function list(state) {
|
export function list() {
|
||||||
return {
|
return {
|
||||||
type: FILES_VIEW,
|
type: FILES_VIEW,
|
||||||
view: 'list'
|
view: 'list'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function selectView(active = true) {
|
||||||
|
return {
|
||||||
|
type: SELECT_VIEW,
|
||||||
|
active
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3,6 +3,7 @@ const TYPES = {
|
|||||||
|
|
||||||
LIST_FILES: Symbol('LIST_FILES'),
|
LIST_FILES: Symbol('LIST_FILES'),
|
||||||
FILES_VIEW: Symbol('FILES_VIEW'),
|
FILES_VIEW: Symbol('FILES_VIEW'),
|
||||||
|
SELECT_VIEW: Symbol('SELECT_VIEW'),
|
||||||
|
|
||||||
NAVIGATION: Symbol('NAVIGATION'),
|
NAVIGATION: Symbol('NAVIGATION'),
|
||||||
TOGGLE: Symbol('TOGGLE'),
|
TOGGLE: Symbol('TOGGLE'),
|
||||||
@ -18,7 +19,7 @@ const TYPES = {
|
|||||||
|
|
||||||
MENU: Symbol('MENU'),
|
MENU: Symbol('MENU'),
|
||||||
|
|
||||||
DIALOG: Symbol('DEBUG'),
|
DIALOG: Symbol('DIALOG'),
|
||||||
|
|
||||||
SETTINGS: Symbol('SETTINGS'),
|
SETTINGS: Symbol('SETTINGS'),
|
||||||
|
|
||||||
|
@ -75,6 +75,12 @@ export async function createDirectory(...args) {
|
|||||||
return parent.createDirectory(...args);
|
return parent.createDirectory(...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function remove(file) {
|
||||||
|
let parent = await root();
|
||||||
|
|
||||||
|
return parent.remove(file);
|
||||||
|
}
|
||||||
|
|
||||||
export async function move(file, newPath) {
|
export async function move(file, newPath) {
|
||||||
let path = (file.path || '').replace(/^\//, ''); // remove starting slash
|
let path = (file.path || '').replace(/^\//, ''); // remove starting slash
|
||||||
let oldPath = path + file.name;
|
let oldPath = path + file.name;
|
||||||
|
@ -7,26 +7,26 @@ import { bind } from 'store';
|
|||||||
@connect(props)
|
@connect(props)
|
||||||
export default class Breadcrumb extends Component {
|
export default class Breadcrumb extends Component {
|
||||||
render() {
|
render() {
|
||||||
let directories = this.props.cwd.split('/');
|
let directories = this.props.cwd.split('/').filter(a => a);
|
||||||
directories.unshift('sdcard');
|
directories.unshift('sdcard');
|
||||||
|
|
||||||
let els = directories.map((dir, index, arr) => {
|
let els = directories.map((dir, index, arr) => {
|
||||||
let path = arr.slice(1, index + 1).join('/');
|
let path = arr.slice(1, index + 1).join('/');
|
||||||
let slash = index > 0 ? '/' : '';
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span key={index} onClick={bind(changedir(path))}>
|
<span key={index} onClick={bind(changedir(path))}>
|
||||||
<i>{slash}</i>{dir}
|
<i>/</i>{dir}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
let lastDirectories = this.props.lwd.split('/');
|
let lastDirectories = this.props.lwd.split('/').filter(a => a);
|
||||||
if (lastDirectories.length > directories.length - 1) {
|
if (lastDirectories.length > directories.length - 1) {
|
||||||
lastDirectories.splice(0, directories.length - 1);
|
lastDirectories.splice(0, directories.length - 1);
|
||||||
|
|
||||||
let history = lastDirectories.map((dir, index, arr) => {
|
let history = lastDirectories.map((dir, index, arr) => {
|
||||||
let current = directories.slice(1).concat(arr.slice(0, index + 1));
|
let current = directories.slice(1).concat(arr.slice(0, index + 1));
|
||||||
let path = current.join('/');
|
let path = current.join('/').replace(/^\//, ''); // remove starting slash
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span key={directories.length + index} className='history' onClick={bind(changedir(path))}>
|
<span key={directories.length + index} className='history' onClick={bind(changedir(path))}>
|
||||||
|
@ -9,10 +9,25 @@ const MENU_TOP_SPACE = 20;
|
|||||||
|
|
||||||
export default class Directory extends Component {
|
export default class Directory extends Component {
|
||||||
render() {
|
render() {
|
||||||
|
let checkId = `file-${this.props.index}`;
|
||||||
|
|
||||||
|
let input, label;
|
||||||
|
if (this.props.selectView) {
|
||||||
|
input = <input type='checkbox' id={checkId} checked={this.props.selected} readOnly />;
|
||||||
|
label = <label htmlFor={checkId}></label>;
|
||||||
|
}
|
||||||
|
|
||||||
|
let clickHandler = this.props.selectView ? this.select.bind(this)
|
||||||
|
: this.peek.bind(this);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='directory' ref='container'
|
<div className='directory' ref='container'
|
||||||
onClick={this.peek.bind(this)}
|
onClick={clickHandler}
|
||||||
onContextMenu={this.contextMenu.bind(this)}>
|
onContextMenu={this.contextMenu.bind(this)}>
|
||||||
|
|
||||||
|
{input}
|
||||||
|
{label}
|
||||||
|
|
||||||
<i></i>
|
<i></i>
|
||||||
<p>{this.props.name}</p>
|
<p>{this.props.name}</p>
|
||||||
<span>{this.props.children} items</span>
|
<span>{this.props.children} items</span>
|
||||||
@ -37,4 +52,16 @@ export default class Directory extends Component {
|
|||||||
store.dispatch(show('directoryMenu', {style: {left, top}}));
|
store.dispatch(show('directoryMenu', {style: {left, top}}));
|
||||||
store.dispatch(active(this.props.index));
|
store.dispatch(active(this.props.index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select() {
|
||||||
|
let current = (store.getState().get('activeFile') || []).slice(0);
|
||||||
|
let index = this.props.index;
|
||||||
|
|
||||||
|
if (current.indexOf(index) > -1) {
|
||||||
|
current.splice(current.indexOf(index), 1);
|
||||||
|
} else {
|
||||||
|
current.push(index)
|
||||||
|
}
|
||||||
|
store.dispatch(active(current));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,29 +12,16 @@ export default class FileList extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
let { files } = this.props;
|
let { files, selectView, activeFile } = this.props;
|
||||||
|
activeFile = activeFile || [];
|
||||||
let settings = store.getState().get('settings');
|
let settings = store.getState().get('settings');
|
||||||
|
|
||||||
if (settings.showDirectoriesFirst) {
|
|
||||||
files = files.sort((a, b) => {
|
|
||||||
if (type(a) === 'Directory') return -1;
|
|
||||||
if (type(b) === 'Directory') return 1;
|
|
||||||
return 0;
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!settings.showHiddenFiles) {
|
|
||||||
files = files.filter(file => {
|
|
||||||
return file.name[0] !== '.';
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
let els = files.map((file, index) => {
|
let els = files.map((file, index) => {
|
||||||
|
let selected = activeFile.indexOf(index) > -1;
|
||||||
if (type(file) === 'File') {
|
if (type(file) === 'File') {
|
||||||
return <File key={index} index={index} name={file.name} size={file.size} />;
|
return <File selectView={selectView} selected={selected} key={index} index={index} name={file.name} size={file.size} />;
|
||||||
} else {
|
} else {
|
||||||
return <Directory key={index} index={index} name={file.name} children={file.children} />
|
return <Directory selectView={selectView} selected={selected} key={index} index={index} name={file.name} children={file.children} />
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -48,7 +35,9 @@ export default class FileList extends Component {
|
|||||||
|
|
||||||
function props(state) {
|
function props(state) {
|
||||||
return {
|
return {
|
||||||
files: state.get('files')
|
files: state.get('files'),
|
||||||
|
selectView: state.get('selectView'),
|
||||||
|
activeFile: state.get('activeFile')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,9 +13,25 @@ export default class File extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
let checkId = `file-${this.props.index}`;
|
||||||
|
|
||||||
|
let input, label;
|
||||||
|
if (this.props.selectView) {
|
||||||
|
input = <input type='checkbox' id={checkId} defaultChecked={this.props.selected} readOnly />;
|
||||||
|
label = <label htmlFor={checkId}></label>;
|
||||||
|
}
|
||||||
|
|
||||||
|
let clickHandler = this.props.selectView ? this.select.bind(this)
|
||||||
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='file' ref='container'
|
<div className='file' ref='container'
|
||||||
|
onClick={clickHandler}
|
||||||
onContextMenu={this.contextMenu.bind(this)}>
|
onContextMenu={this.contextMenu.bind(this)}>
|
||||||
|
|
||||||
|
{input}
|
||||||
|
{label}
|
||||||
|
|
||||||
<i></i>
|
<i></i>
|
||||||
<p>{this.props.name}</p>
|
<p>{this.props.name}</p>
|
||||||
<span>{humanSize(this.props.size)}</span>
|
<span>{humanSize(this.props.size)}</span>
|
||||||
@ -34,4 +50,16 @@ export default class File extends Component {
|
|||||||
store.dispatch(show('fileMenu', {style: {left, top}}));
|
store.dispatch(show('fileMenu', {style: {left, top}}));
|
||||||
store.dispatch(active(this.props.index));
|
store.dispatch(active(this.props.index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select() {
|
||||||
|
let current = (store.getState().get('activeFile') || []).slice(0);
|
||||||
|
let index = this.props.index;
|
||||||
|
|
||||||
|
if (current.indexOf(index) > -1) {
|
||||||
|
current.splice(current.indexOf(index), 1);
|
||||||
|
} else {
|
||||||
|
current.push(index)
|
||||||
|
}
|
||||||
|
store.dispatch(active(current));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ window.changedir = changedir;
|
|||||||
|
|
||||||
let FileMenu = connect(state => state.get('fileMenu'))(Menu);
|
let FileMenu = connect(state => state.get('fileMenu'))(Menu);
|
||||||
let DirectoryMenu = connect(state => state.get('directoryMenu'))(Menu);
|
let DirectoryMenu = connect(state => state.get('directoryMenu'))(Menu);
|
||||||
|
let MoreMenu = connect(state => state.get('moreMenu'))(Menu);
|
||||||
|
|
||||||
let RenameDialog = connect(state => state.get('renameDialog'))(Dialog);
|
let RenameDialog = connect(state => state.get('renameDialog'))(Dialog);
|
||||||
let DeleteDialog = connect(state => state.get('deleteDialog'))(Dialog);
|
let DeleteDialog = connect(state => state.get('deleteDialog'))(Dialog);
|
||||||
@ -36,6 +37,7 @@ export default class Root extends Component {
|
|||||||
|
|
||||||
<FileMenu />
|
<FileMenu />
|
||||||
<DirectoryMenu />
|
<DirectoryMenu />
|
||||||
|
<MoreMenu />
|
||||||
|
|
||||||
<RenameDialog />
|
<RenameDialog />
|
||||||
<DeleteDialog />
|
<DeleteDialog />
|
||||||
@ -46,7 +48,12 @@ export default class Root extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
touchStart(e) {
|
touchStart(e) {
|
||||||
if (!e.target.closest('.menu')) {
|
let active = document.querySelector('.active');
|
||||||
|
let inside = e.target.closest('.menu') || e.target.closest('.dialog');
|
||||||
|
if (!inside && active) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
store.dispatch(hideAllMenus());
|
store.dispatch(hideAllMenus());
|
||||||
store.dispatch(hideAllDialogs());
|
store.dispatch(hideAllDialogs());
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { toggle as toggleView, refresh } from 'actions/files-view';
|
import { toggle as toggleView, refresh, selectView } from 'actions/files-view';
|
||||||
import { show as showDialog } from 'actions/dialog';
|
import { show as showDialog } from 'actions/dialog';
|
||||||
|
import { show as showMenu } from 'actions/menu';
|
||||||
import store, { bind } from 'store';
|
import store, { bind } from 'store';
|
||||||
|
import { MENU_WIDTH } from './menu';
|
||||||
|
|
||||||
export default class Toolbar extends Component {
|
export default class Toolbar extends Component {
|
||||||
render() {
|
render() {
|
||||||
@ -10,14 +12,21 @@ export default class Toolbar extends Component {
|
|||||||
<button className='icon-plus' onClick={this.newFile} />
|
<button className='icon-plus' onClick={this.newFile} />
|
||||||
<button className='icon-view' onClick={bind(toggleView())} />
|
<button className='icon-view' onClick={bind(toggleView())} />
|
||||||
<button className='icon-refresh' onClick={bind(refresh())} />
|
<button className='icon-refresh' onClick={bind(refresh())} />
|
||||||
<button className='icon-share' onClick={this.share} />
|
<button className='icon-select' onClick={bind(selectView('toggle'))} />
|
||||||
<button className='icon-more' onClick={this.showMore} />
|
<button className='icon-more' onClick={this.showMore.bind(this)} ref='more' />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
showMore() {
|
showMore() {
|
||||||
|
let rect = React.findDOMNode(this.refs.more).getBoundingClientRect();
|
||||||
|
let {x, y, width, height} = rect;
|
||||||
|
|
||||||
|
let left = x + width - MENU_WIDTH,
|
||||||
|
top = y + height;
|
||||||
|
|
||||||
|
let transform = 'translate(0, -100%)';
|
||||||
|
store.dispatch(showMenu('moreMenu', {style: {left, top, transform}}));
|
||||||
}
|
}
|
||||||
|
|
||||||
newFile() {
|
newFile() {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { hide, hideAll } from 'actions/dialog';
|
import { hide, hideAll } from 'actions/dialog';
|
||||||
import { rename, deleteFile, create } from 'actions/file';
|
import { rename, deleteFile, create, active } from 'actions/file';
|
||||||
import store, { bind } from 'store';
|
import store, { bind } from 'store';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -18,6 +18,7 @@ export default {
|
|||||||
let action = create(cwd + input.value);
|
let action = create(cwd + input.value);
|
||||||
this.props.dispatch(action);
|
this.props.dispatch(action);
|
||||||
this.props.dispatch(hideAll());
|
this.props.dispatch(hideAll());
|
||||||
|
this.props.dispatch(active());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -29,6 +30,7 @@ export default {
|
|||||||
let action = create(cwd + input.value, true);
|
let action = create(cwd + input.value, true);
|
||||||
this.props.dispatch(action);
|
this.props.dispatch(action);
|
||||||
this.props.dispatch(hideAll());
|
this.props.dispatch(hideAll());
|
||||||
|
this.props.dispatch(active());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -50,6 +52,7 @@ export default {
|
|||||||
let activeFile = store.getState().get('activeFile');
|
let activeFile = store.getState().get('activeFile');
|
||||||
this.props.dispatch(rename(activeFile, input.value))
|
this.props.dispatch(rename(activeFile, input.value))
|
||||||
this.props.dispatch(hideAll());
|
this.props.dispatch(hideAll());
|
||||||
|
this.props.dispatch(active());
|
||||||
},
|
},
|
||||||
className: 'success'
|
className: 'success'
|
||||||
}
|
}
|
||||||
@ -69,6 +72,7 @@ export default {
|
|||||||
let activeFile = store.getState().get('activeFile');
|
let activeFile = store.getState().get('activeFile');
|
||||||
this.props.dispatch(deleteFile(activeFile));
|
this.props.dispatch(deleteFile(activeFile));
|
||||||
this.props.dispatch(hideAll());
|
this.props.dispatch(hideAll());
|
||||||
|
this.props.dispatch(active());
|
||||||
},
|
},
|
||||||
className: 'success'
|
className: 'success'
|
||||||
}
|
}
|
||||||
|
1571
src/js/libs/l10n.js
@ -30,7 +30,32 @@ const entryMenu = {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const moreMenu = {
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
name: 'Delete',
|
||||||
|
action() {
|
||||||
|
let files = store.getState().get('files');
|
||||||
|
let active = store.getState().get('activeFile');
|
||||||
|
|
||||||
|
let description;
|
||||||
|
if (active.length) {
|
||||||
|
const count = active.length;
|
||||||
|
description = `Are you sure you want to remove ${count} files?`;
|
||||||
|
} else {
|
||||||
|
const name = files[active].name;
|
||||||
|
description = `Are you sure you want to remove ${name}?`;
|
||||||
|
}
|
||||||
|
|
||||||
|
store.dispatch(hideAll());
|
||||||
|
store.dispatch(show('deleteDialog', {description}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
fileMenu: Object.assign({}, entryMenu),
|
fileMenu: Object.assign({}, entryMenu),
|
||||||
directoryMenu: Object.assign({}, entryMenu)
|
directoryMenu: Object.assign({}, entryMenu),
|
||||||
|
moreMenu
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { ACTIVE_FILE } from 'actions/types';
|
import { ACTIVE_FILE } from 'actions/types';
|
||||||
|
|
||||||
export default function(state = -1, action) {
|
export default function(state = null, action) {
|
||||||
if (action.type === ACTIVE_FILE) {
|
if (action.type === ACTIVE_FILE) {
|
||||||
return action.file;
|
return action.file;
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import activeFile from './active-file';
|
|||||||
import menu from './menu';
|
import menu from './menu';
|
||||||
import dialog from './dialog';
|
import dialog from './dialog';
|
||||||
import settings from './settings';
|
import settings from './settings';
|
||||||
|
import selectView from './select-view';
|
||||||
|
|
||||||
export default function(state = new Immutable.Map(), action) {
|
export default function(state = new Immutable.Map(), action) {
|
||||||
console.log('action', action);
|
console.log('action', action);
|
||||||
@ -14,14 +15,16 @@ export default function(state = new Immutable.Map(), action) {
|
|||||||
lwd: lwd(state, action), // last working directory
|
lwd: lwd(state, action), // last working directory
|
||||||
cwd: cwd(state.get('cwd'), action),
|
cwd: cwd(state.get('cwd'), action),
|
||||||
files: files(state.get('files'), action),
|
files: files(state.get('files'), action),
|
||||||
|
selectView: selectView(state.get('selectView'), action),
|
||||||
activeFile: activeFile(state.get('activeFile'), action),
|
activeFile: activeFile(state.get('activeFile'), action),
|
||||||
navigation: navigation(state.get('navigation'), action),
|
navigation: navigation(state.get('navigation'), action),
|
||||||
settings: settings(state.get('settings'), action),
|
settings: settings(state.get('settings'), action),
|
||||||
fileMenu: menu(state, action, 'fileMenu'),
|
fileMenu: menu(state, action, 'fileMenu'),
|
||||||
directoryMenu: menu(state, action, 'directoryMenu'),
|
directoryMenu: menu(state, action, 'directoryMenu'),
|
||||||
|
moreMenu: menu(state, action, 'moreMenu'),
|
||||||
renameDialog: dialog(state, action, 'renameDialog'),
|
renameDialog: dialog(state, action, 'renameDialog'),
|
||||||
deleteDialog: dialog(state, action, 'deleteDialog'),
|
deleteDialog: dialog(state, action, 'deleteDialog'),
|
||||||
errorDialog: dialog(state, action, 'errorDialog'),
|
errorDialog: dialog(state, action, 'errorDialog'),
|
||||||
createDialog: dialog(state, action, 'createDialog')
|
createDialog: dialog(state, action, 'createDialog'),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,30 @@
|
|||||||
import { LIST_FILES, RENAME_FILE, DELETE_FILE, CREATE_FILE } from 'actions/types';
|
import { LIST_FILES, RENAME_FILE, DELETE_FILE, CREATE_FILE } from 'actions/types';
|
||||||
import { refresh } from 'actions/files-view';
|
import { refresh } from 'actions/files-view';
|
||||||
import { move, sdcard, createFile, createDirectory } from 'api/files';
|
import { move, remove, sdcard, createFile, createDirectory } from 'api/files';
|
||||||
import { show } from 'actions/dialog';
|
import { show } from 'actions/dialog';
|
||||||
import store, { bind } from 'store';
|
import store, { bind } from 'store';
|
||||||
import { reportError } from 'utils';
|
import { reportError, type } from 'utils';
|
||||||
|
|
||||||
let boundRefresh = bind(refresh());
|
let boundRefresh = bind(refresh());
|
||||||
|
|
||||||
export default function(state = [], action) {
|
export default function(state = [], action) {
|
||||||
if (action.type === LIST_FILES) {
|
if (action.type === LIST_FILES) {
|
||||||
|
|
||||||
|
let settings = store.getState().get('settings');
|
||||||
|
|
||||||
|
if (settings.showDirectoriesFirst) {
|
||||||
|
action.files = action.files.sort((a, b) => {
|
||||||
|
if (type(a) === 'Directory') return -1;
|
||||||
|
if (type(a) === 'File') return 1;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!settings.showHiddenFiles) {
|
||||||
|
action.files = action.files.filter(file => {
|
||||||
|
return file.name[0] !== '.';
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
return action.files;
|
return action.files;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,13 +44,26 @@ export default function(state = [], action) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (action.type === DELETE_FILE) {
|
if (action.type === DELETE_FILE) {
|
||||||
let file = state[action.file];
|
|
||||||
|
|
||||||
sdcard().delete((file.path || '') + '/' + file.name);
|
|
||||||
let copy = state.slice(0);
|
let copy = state.slice(0);
|
||||||
|
|
||||||
|
if (action.file.length) {
|
||||||
|
for (let index of action.file) {
|
||||||
|
del(state, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
copy = copy.filter((a, i) => action.file.indexOf(i) === -1);
|
||||||
|
} else {
|
||||||
|
del(state, action.file);
|
||||||
copy.splice(action.file, 1);
|
copy.splice(action.file, 1);
|
||||||
|
}
|
||||||
|
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function del(state, index) {
|
||||||
|
let file = state[index];
|
||||||
|
return remove((file.path || '') + '/' + file.name).catch(reportError);
|
||||||
|
}
|
||||||
|
9
src/js/reducers/select-view.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import { SELECT_VIEW } from 'actions/types';
|
||||||
|
|
||||||
|
export default function(state = false, action) {
|
||||||
|
if (action.type === SELECT_VIEW) {
|
||||||
|
return action.active === 'toggle' ? !state : action.active;
|
||||||
|
}
|
||||||
|
|
||||||
|
return state;
|
||||||
|
}
|
@ -37,11 +37,9 @@ const sizes = {
|
|||||||
'B': -1
|
'B': -1
|
||||||
}
|
}
|
||||||
export function humanSize(size) {
|
export function humanSize(size) {
|
||||||
console.log(size);
|
|
||||||
for (let key in sizes) {
|
for (let key in sizes) {
|
||||||
let value = sizes[key];
|
let value = sizes[key];
|
||||||
|
|
||||||
console.log(value);
|
|
||||||
if (size > value) {
|
if (size > value) {
|
||||||
return Math.round(size / value) + key;
|
return Math.round(size / value) + key;
|
||||||
}
|
}
|
||||||
|
@ -52,39 +52,6 @@ nav {
|
|||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
|
||||||
clear: left;
|
|
||||||
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
|
|
||||||
float: right;
|
|
||||||
|
|
||||||
margin-right: 13px;
|
|
||||||
|
|
||||||
border-radius: 50%;
|
|
||||||
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
|
|
||||||
background: transparent;
|
|
||||||
|
|
||||||
border: 1px solid @overlay;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
clear: right;
|
|
||||||
float: right;
|
|
||||||
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
input:checked + label::after {
|
|
||||||
background: @blue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
i {
|
i {
|
||||||
|
@ -37,11 +37,11 @@
|
|||||||
height: 28px;
|
height: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-share {
|
.icon-select {
|
||||||
.icon;
|
.icon;
|
||||||
background: url(/img/Share.svg) no-repeat;
|
background: url(/img/Select.svg) no-repeat;
|
||||||
width: 25px;
|
width: 32px;
|
||||||
height: 27px;
|
height: 34px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-more {
|
.icon-more {
|
||||||
|
@ -14,27 +14,35 @@ input {
|
|||||||
.light-medium;
|
.light-medium;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="checkbox"] {
|
label {
|
||||||
width: 0;
|
clear: left;
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="checkbox"]::before {
|
&::after {
|
||||||
content: '';
|
content: '';
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
border: 1px solid @gray;
|
float: right;
|
||||||
|
|
||||||
background: transparent;
|
margin-right: 13px;
|
||||||
|
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
|
||||||
width: 10px;
|
width: 10px;
|
||||||
height: 10px;
|
height: 10px;
|
||||||
|
|
||||||
box-sizing: border-box;
|
background: transparent;
|
||||||
|
|
||||||
&:checked {
|
border: 1px solid @overlay;
|
||||||
background: @blue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type='checkbox'] {
|
||||||
|
clear: right;
|
||||||
|
float: right;
|
||||||
|
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:checked + label::after {
|
||||||
|
background: @blue;
|
||||||
|
}
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
"description": "Keep an eye on your files with a full-featured file-manager",
|
"description": "Keep an eye on your files with a full-featured file-manager",
|
||||||
"launch_path": "/index.html",
|
"launch_path": "/index.html",
|
||||||
"icons": {
|
"icons": {
|
||||||
"16": "/img/icons/icon16x16.png",
|
"16": "/icon/Icon-16.png",
|
||||||
"48": "/img/icons/icon48x48.png",
|
"48": "/icon/Icon-48.png",
|
||||||
"60": "/img/icons/icon60x60.png",
|
"60": "/icon/Icon-60.png",
|
||||||
"128": "/img/icons/icon128x128.png"
|
"128": "/icon/Icon-128.png"
|
||||||
},
|
},
|
||||||
"developer": {
|
"developer": {
|
||||||
"name": "Mahdi Dibaiee",
|
"name": "Mahdi Dibaiee",
|
||||||
|