fix hawk: a lot of bugfixes here and there
This commit is contained in:
parent
d3d539abac
commit
dea2e7591c
23
Gruntfile.js
23
Gruntfile.js
@ -2,6 +2,7 @@ module.exports = function(grunt) {
|
|||||||
require('grunt-task-loader')(grunt);
|
require('grunt-task-loader')(grunt);
|
||||||
|
|
||||||
grunt.initConfig({
|
grunt.initConfig({
|
||||||
|
pkg: require('./package.json'),
|
||||||
browserify: {
|
browserify: {
|
||||||
dev: {
|
dev: {
|
||||||
files: [{
|
files: [{
|
||||||
@ -53,15 +54,6 @@ module.exports = function(grunt) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mochify: {
|
|
||||||
options: {
|
|
||||||
reporter: 'land'
|
|
||||||
},
|
|
||||||
tests: {
|
|
||||||
src: 'test/**/*.js',
|
|
||||||
options: '<%= browserify.dev.options %>'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
less: {
|
less: {
|
||||||
dev: {
|
dev: {
|
||||||
files: [{
|
files: [{
|
||||||
@ -90,12 +82,11 @@ module.exports = function(grunt) {
|
|||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mochaTest: {
|
zip: {
|
||||||
tests: {
|
release: {
|
||||||
src: ['tests/**/*.js'],
|
dest: 'releases/hawk-<%= pkg.version %>.zip',
|
||||||
options: {
|
src: 'build/**/*',
|
||||||
reporter: 'landing'
|
cwd: 'build/'
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
@ -116,6 +107,6 @@ module.exports = function(grunt) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
grunt.registerTask('default', ['browserify:dev', 'less:dev', 'copy']);
|
grunt.registerTask('default', ['browserify:dev', 'less:dev', 'copy']);
|
||||||
grunt.registerTask('production', ['browserify:prod', 'less:prod', 'copy']);
|
grunt.registerTask('production', ['browserify', 'less:prod', 'copy', 'zip']);
|
||||||
grunt.registerTask('test', 'mochaTest');
|
grunt.registerTask('test', 'mochaTest');
|
||||||
};
|
};
|
||||||
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 46 KiB |
File diff suppressed because it is too large
Load Diff
@ -1,3 +0,0 @@
|
|||||||
appname = Hawk
|
|
||||||
app_description.innerHTML = This app is empty. Fill it with your own stuff!
|
|
||||||
message = Hello world
|
|
@ -1 +0,0 @@
|
|||||||
@import url(en-US.properties)
|
|
133
build/main.js
133
build/main.js
@ -29964,16 +29964,18 @@ var children = _asyncToGenerator(function* (dir, gatherInfo) {
|
|||||||
for (var _iterator = childs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
for (var _iterator = childs[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
|
||||||
var child = _step.value;
|
var child = _step.value;
|
||||||
|
|
||||||
if ((0, _utils.type)(child) !== 'Directory') continue;
|
if ((0, _utils.type)(child) === 'Directory') {
|
||||||
|
var subchildren = undefined;
|
||||||
|
try {
|
||||||
|
subchildren = yield child.getFilesAndDirectories();
|
||||||
|
} catch (e) {
|
||||||
|
subchildren = [];
|
||||||
|
}
|
||||||
|
|
||||||
var subchildren = undefined;
|
child.children = subchildren.length;
|
||||||
try {
|
} else {
|
||||||
subchildren = yield child.getFilesAndDirectories();
|
child.path = dir + '/';
|
||||||
} catch (e) {
|
|
||||||
subchildren = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
child.children = subchildren.length;
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
_didIteratorError = true;
|
_didIteratorError = true;
|
||||||
@ -29989,6 +29991,8 @@ var children = _asyncToGenerator(function* (dir, gatherInfo) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
return childs;
|
return childs;
|
||||||
@ -30073,7 +30077,7 @@ var copy = _asyncToGenerator(function* (file, newPath) {
|
|||||||
child.path = oldPath + '/';
|
child.path = oldPath + '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
yield move(child, newPath + '/' + child.name);
|
yield copy(child, newPath + '/' + child.name);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
_didIteratorError2 = true;
|
_didIteratorError2 = true;
|
||||||
@ -30354,12 +30358,6 @@ var _actionsChangedir = require('actions/changedir');
|
|||||||
|
|
||||||
var _actionsChangedir2 = _interopRequireDefault(_actionsChangedir);
|
var _actionsChangedir2 = _interopRequireDefault(_actionsChangedir);
|
||||||
|
|
||||||
var _actionsMenu = require('actions/menu');
|
|
||||||
|
|
||||||
var _actionsFile = require('actions/file');
|
|
||||||
|
|
||||||
var _menu = require('./menu');
|
|
||||||
|
|
||||||
var _store = require('store');
|
var _store = require('store');
|
||||||
|
|
||||||
var _store2 = _interopRequireDefault(_store);
|
var _store2 = _interopRequireDefault(_store);
|
||||||
@ -30368,8 +30366,6 @@ var _mixinsEntry = require('./mixins/entry');
|
|||||||
|
|
||||||
var _mixinsEntry2 = _interopRequireDefault(_mixinsEntry);
|
var _mixinsEntry2 = _interopRequireDefault(_mixinsEntry);
|
||||||
|
|
||||||
var MENU_TOP_SPACE = 20;
|
|
||||||
|
|
||||||
var Directory = (function (_Component) {
|
var Directory = (function (_Component) {
|
||||||
_inherits(Directory, _Component);
|
_inherits(Directory, _Component);
|
||||||
|
|
||||||
@ -30430,7 +30426,7 @@ var Directory = (function (_Component) {
|
|||||||
exports['default'] = Directory;
|
exports['default'] = Directory;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"./menu":233,"./mixins/entry":234,"actions/changedir":217,"actions/file":219,"actions/menu":221,"react":207,"store":"store"}],230:[function(require,module,exports){
|
},{"./mixins/entry":234,"actions/changedir":217,"react":207,"store":"store"}],230:[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
Object.defineProperty(exports, '__esModule', {
|
Object.defineProperty(exports, '__esModule', {
|
||||||
@ -30505,7 +30501,7 @@ var FileList = (function (_Component) {
|
|||||||
var settings = _store2['default'].getState().get('settings');
|
var settings = _store2['default'].getState().get('settings');
|
||||||
|
|
||||||
var els = files.map(function (file, index) {
|
var els = files.map(function (file, index) {
|
||||||
var selected = activeFile.length && activeFile.indexOf(file) > -1;
|
var selected = activeFile.indexOf(file) > -1;
|
||||||
if ((0, _utils.type)(file) === 'File') {
|
if ((0, _utils.type)(file) === 'File') {
|
||||||
return _react2['default'].createElement(_file2['default'], { selectView: selectView, selected: selected, 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 {
|
||||||
@ -30574,12 +30570,6 @@ var _react = require('react');
|
|||||||
|
|
||||||
var _react2 = _interopRequireDefault(_react);
|
var _react2 = _interopRequireDefault(_react);
|
||||||
|
|
||||||
var _actionsMenu = require('actions/menu');
|
|
||||||
|
|
||||||
var _actionsFile = require('actions/file');
|
|
||||||
|
|
||||||
var _menu = require('./menu');
|
|
||||||
|
|
||||||
var _store = require('store');
|
var _store = require('store');
|
||||||
|
|
||||||
var _store2 = _interopRequireDefault(_store);
|
var _store2 = _interopRequireDefault(_store);
|
||||||
@ -30590,8 +30580,6 @@ var _mixinsEntry = require('./mixins/entry');
|
|||||||
|
|
||||||
var _mixinsEntry2 = _interopRequireDefault(_mixinsEntry);
|
var _mixinsEntry2 = _interopRequireDefault(_mixinsEntry);
|
||||||
|
|
||||||
var MENU_TOP_SPACE = 20;
|
|
||||||
|
|
||||||
var File = (function (_Component) {
|
var File = (function (_Component) {
|
||||||
_inherits(File, _Component);
|
_inherits(File, _Component);
|
||||||
|
|
||||||
@ -30610,7 +30598,7 @@ var File = (function (_Component) {
|
|||||||
var input = undefined,
|
var input = undefined,
|
||||||
label = undefined;
|
label = undefined;
|
||||||
if (this.props.selectView) {
|
if (this.props.selectView) {
|
||||||
input = _react2['default'].createElement('input', { type: 'checkbox', id: checkId, defaultChecked: this.props.selected, readOnly: true });
|
input = _react2['default'].createElement('input', { type: 'checkbox', id: checkId, checked: this.props.selected, readOnly: true });
|
||||||
label = _react2['default'].createElement('label', { htmlFor: checkId });
|
label = _react2['default'].createElement('label', { htmlFor: checkId });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30658,7 +30646,7 @@ var File = (function (_Component) {
|
|||||||
exports['default'] = File;
|
exports['default'] = File;
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{"./menu":233,"./mixins/entry":234,"actions/file":219,"actions/menu":221,"react":207,"store":"store","utils":"utils"}],232:[function(require,module,exports){
|
},{"./mixins/entry":234,"react":207,"store":"store","utils":"utils"}],232:[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
Object.defineProperty(exports, '__esModule', {
|
Object.defineProperty(exports, '__esModule', {
|
||||||
@ -30780,6 +30768,7 @@ var Menu = (function (_Component) {
|
|||||||
var items = _props.items;
|
var items = _props.items;
|
||||||
var active = _props.active;
|
var active = _props.active;
|
||||||
var style = _props.style;
|
var style = _props.style;
|
||||||
|
var id = _props.id;
|
||||||
|
|
||||||
items = items || [];
|
items = items || [];
|
||||||
|
|
||||||
@ -30797,7 +30786,7 @@ var Menu = (function (_Component) {
|
|||||||
|
|
||||||
return _react2['default'].createElement(
|
return _react2['default'].createElement(
|
||||||
'div',
|
'div',
|
||||||
{ className: className, style: style },
|
{ className: className, style: style, id: id },
|
||||||
_react2['default'].createElement(
|
_react2['default'].createElement(
|
||||||
'ul',
|
'ul',
|
||||||
null,
|
null,
|
||||||
@ -30818,25 +30807,48 @@ exports['default'] = Menu;
|
|||||||
Object.defineProperty(exports, '__esModule', {
|
Object.defineProperty(exports, '__esModule', {
|
||||||
value: true
|
value: true
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
|
||||||
|
|
||||||
|
var _react = require('react');
|
||||||
|
|
||||||
|
var _react2 = _interopRequireDefault(_react);
|
||||||
|
|
||||||
|
var _actionsFile = require('actions/file');
|
||||||
|
|
||||||
|
var _actionsMenu = require('actions/menu');
|
||||||
|
|
||||||
|
var _componentsMenu = require('components/menu');
|
||||||
|
|
||||||
|
var MENU_TOP_SPACE = 20;
|
||||||
|
|
||||||
exports['default'] = {
|
exports['default'] = {
|
||||||
contextMenu: function contextMenu(e) {
|
contextMenu: function contextMenu(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
var file = store.getState().get('files')[this.props.index];
|
var file = store.getState().get('files')[this.props.index];
|
||||||
var rect = React.findDOMNode(this.refs.container).getBoundingClientRect();
|
var rect = _react2['default'].findDOMNode(this.refs.container).getBoundingClientRect();
|
||||||
var x = rect.x;
|
var x = rect.x;
|
||||||
var y = rect.y;
|
var y = rect.y;
|
||||||
var width = rect.width;
|
var width = rect.width;
|
||||||
var height = rect.height;
|
var height = rect.height;
|
||||||
|
|
||||||
var left = x + width / 2 - MENU_WIDTH / 2,
|
var left = x + width / 2 - _componentsMenu.MENU_WIDTH / 2,
|
||||||
top = y + height / 2 + MENU_TOP_SPACE;
|
top = y + height / 2 + MENU_TOP_SPACE;
|
||||||
store.dispatch(show('fileMenu', { style: { left: left, top: top } }));
|
|
||||||
store.dispatch(active([file]));
|
var dialogHeight = document.getElementById('fileMenu').offsetHeight;
|
||||||
|
|
||||||
|
var diff = window.innerHeight - (dialogHeight + top);
|
||||||
|
if (diff <= 0) {
|
||||||
|
top -= Math.abs(diff);
|
||||||
|
}
|
||||||
|
|
||||||
|
store.dispatch((0, _actionsMenu.show)('fileMenu', { style: { left: left, top: top } }));
|
||||||
|
store.dispatch((0, _actionsFile.active)([file]));
|
||||||
},
|
},
|
||||||
|
|
||||||
select: function select() {
|
select: function select() {
|
||||||
var current = store.getState().get('activeFile').slice(0);
|
var current = (store.getState().get('activeFile') || []).slice(0);
|
||||||
var file = store.getState().get('files')[this.props.index];
|
var file = store.getState().get('files')[this.props.index];
|
||||||
|
|
||||||
if (current.indexOf(file) > -1) {
|
if (current.indexOf(file) > -1) {
|
||||||
@ -30844,12 +30856,12 @@ exports['default'] = {
|
|||||||
} else {
|
} else {
|
||||||
current.push(file);
|
current.push(file);
|
||||||
}
|
}
|
||||||
store.dispatch(active(current));
|
store.dispatch((0, _actionsFile.active)(current));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
module.exports = exports['default'];
|
module.exports = exports['default'];
|
||||||
|
|
||||||
},{}],235:[function(require,module,exports){
|
},{"actions/file":219,"actions/menu":221,"components/menu":233,"react":207}],235:[function(require,module,exports){
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
Object.defineProperty(exports, '__esModule', {
|
Object.defineProperty(exports, '__esModule', {
|
||||||
@ -30917,7 +30929,7 @@ var Navigation = (function (_Component) {
|
|||||||
_react2['default'].createElement(
|
_react2['default'].createElement(
|
||||||
'li',
|
'li',
|
||||||
null,
|
null,
|
||||||
_react2['default'].createElement('input', { id: 'filter-all', name: 'filter', value: '', type: 'radio', defaultChecked: !settings.filter }),
|
_react2['default'].createElement('input', { id: 'filter-all', name: 'filter', 'data-value': '', type: 'radio', defaultChecked: !settings.filter }),
|
||||||
_react2['default'].createElement(
|
_react2['default'].createElement(
|
||||||
'label',
|
'label',
|
||||||
{ htmlFor: 'filter-all' },
|
{ htmlFor: 'filter-all' },
|
||||||
@ -30927,7 +30939,7 @@ var Navigation = (function (_Component) {
|
|||||||
_react2['default'].createElement(
|
_react2['default'].createElement(
|
||||||
'li',
|
'li',
|
||||||
null,
|
null,
|
||||||
_react2['default'].createElement('input', { id: 'filter-image', name: 'filter', value: 'image', type: 'radio', defaultChecked: settings.filter === 'image' }),
|
_react2['default'].createElement('input', { id: 'filter-image', name: 'filter', 'data-value': 'image', type: 'radio', defaultChecked: settings.filter === 'image' }),
|
||||||
_react2['default'].createElement(
|
_react2['default'].createElement(
|
||||||
'label',
|
'label',
|
||||||
{ htmlFor: 'filter-image' },
|
{ htmlFor: 'filter-image' },
|
||||||
@ -30937,7 +30949,7 @@ var Navigation = (function (_Component) {
|
|||||||
_react2['default'].createElement(
|
_react2['default'].createElement(
|
||||||
'li',
|
'li',
|
||||||
null,
|
null,
|
||||||
_react2['default'].createElement('input', { id: 'filter-video', name: 'filter', value: 'video', type: 'radio', defaultChecked: settings.filter === 'video' }),
|
_react2['default'].createElement('input', { id: 'filter-video', name: 'filter', 'data-value': 'video', type: 'radio', defaultChecked: settings.filter === 'video' }),
|
||||||
_react2['default'].createElement(
|
_react2['default'].createElement(
|
||||||
'label',
|
'label',
|
||||||
{ htmlFor: 'filter-video' },
|
{ htmlFor: 'filter-video' },
|
||||||
@ -30947,7 +30959,7 @@ var Navigation = (function (_Component) {
|
|||||||
_react2['default'].createElement(
|
_react2['default'].createElement(
|
||||||
'li',
|
'li',
|
||||||
null,
|
null,
|
||||||
_react2['default'].createElement('input', { id: 'filter-audio', name: 'filter', value: 'audio', type: 'radio', defaultChecked: settings.filter === 'audio' }),
|
_react2['default'].createElement('input', { id: 'filter-audio', name: 'filter', 'data-value': 'audio', type: 'radio', defaultChecked: settings.filter === 'audio' }),
|
||||||
_react2['default'].createElement(
|
_react2['default'].createElement(
|
||||||
'label',
|
'label',
|
||||||
{ htmlFor: 'filter-audio' },
|
{ htmlFor: 'filter-audio' },
|
||||||
@ -31078,7 +31090,7 @@ var Navigation = (function (_Component) {
|
|||||||
key: 'onChange',
|
key: 'onChange',
|
||||||
value: function onChange(e) {
|
value: function onChange(e) {
|
||||||
var key = e.target.name || e.target.id;
|
var key = e.target.name || e.target.id;
|
||||||
var value = e.target.value === undefined ? e.target.checked : e.target.value;
|
var value = typeof e.target.dataset.value !== 'undefined' ? e.target.dataset.value : e.target.checked;
|
||||||
|
|
||||||
var action = (0, _actionsSettings2['default'])(_defineProperty({}, key, value));
|
var action = (0, _actionsSettings2['default'])(_defineProperty({}, key, value));
|
||||||
|
|
||||||
@ -31186,9 +31198,7 @@ window.changedir = _actionsChangedir2['default'];
|
|||||||
var FileMenu = (0, _reactRedux.connect)(function (state) {
|
var FileMenu = (0, _reactRedux.connect)(function (state) {
|
||||||
return state.get('fileMenu');
|
return state.get('fileMenu');
|
||||||
})(_componentsMenu2['default']);
|
})(_componentsMenu2['default']);
|
||||||
var DirectoryMenu = (0, _reactRedux.connect)(function (state) {
|
// let DirectoryMenu = connect(state => state.get('directoryMenu'))(Menu);
|
||||||
return state.get('directoryMenu');
|
|
||||||
})(_componentsMenu2['default']);
|
|
||||||
var MoreMenu = (0, _reactRedux.connect)(function (state) {
|
var MoreMenu = (0, _reactRedux.connect)(function (state) {
|
||||||
return state.get('moreMenu');
|
return state.get('moreMenu');
|
||||||
})(_componentsMenu2['default']);
|
})(_componentsMenu2['default']);
|
||||||
@ -31223,21 +31233,22 @@ var Root = (function (_Component) {
|
|||||||
value: function render() {
|
value: function render() {
|
||||||
return _react2['default'].createElement(
|
return _react2['default'].createElement(
|
||||||
'div',
|
'div',
|
||||||
{ onTouchStart: this.touchStart.bind(this), onClick: this.onClick.bind(this) },
|
{ onTouchStart: this.touchStart.bind(this),
|
||||||
|
onClick: this.onClick.bind(this) },
|
||||||
_react2['default'].createElement(_componentsHeader2['default'], null),
|
_react2['default'].createElement(_componentsHeader2['default'], null),
|
||||||
_react2['default'].createElement(_componentsBreadcrumb2['default'], null),
|
_react2['default'].createElement(_componentsBreadcrumb2['default'], null),
|
||||||
_react2['default'].createElement(_componentsNavigation2['default'], null),
|
_react2['default'].createElement(_componentsNavigation2['default'], null),
|
||||||
_react2['default'].createElement(_componentsFileList2['default'], null),
|
_react2['default'].createElement(_componentsFileList2['default'], null),
|
||||||
_react2['default'].createElement(_componentsToolbar2['default'], null),
|
_react2['default'].createElement(_componentsToolbar2['default'], null),
|
||||||
_react2['default'].createElement(FileMenu, null),
|
_react2['default'].createElement(FileMenu, { id: 'fileMenu' }),
|
||||||
_react2['default'].createElement(DirectoryMenu, null),
|
_react2['default'].createElement(MoreMenu, { id: 'moreMenu' }),
|
||||||
_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),
|
||||||
_react2['default'].createElement(CreateDialog, null),
|
_react2['default'].createElement(CreateDialog, null),
|
||||||
_react2['default'].createElement(SearchDialog, null),
|
_react2['default'].createElement(SearchDialog, null),
|
||||||
_react2['default'].createElement(_componentsSpinner2['default'], null),
|
_react2['default'].createElement(_componentsSpinner2['default'], null),
|
||||||
|
_react2['default'].createElement('div', { className: 'swipe-instruction tour-item' }),
|
||||||
_react2['default'].createElement(
|
_react2['default'].createElement(
|
||||||
'div',
|
'div',
|
||||||
{ className: 'tour-dialog' },
|
{ className: 'tour-dialog' },
|
||||||
@ -31621,7 +31632,7 @@ var entryMenu = {
|
|||||||
action: function action() {
|
action: function action() {
|
||||||
var files = _store2['default'].getState().get('files');
|
var files = _store2['default'].getState().get('files');
|
||||||
var active = _store2['default'].getState().get('activeFile');
|
var active = _store2['default'].getState().get('activeFile');
|
||||||
var description = 'Enter the new name for ' + active[0].name + '?';
|
var description = 'Enter the new name for ' + active[0].name;
|
||||||
|
|
||||||
_store2['default'].dispatch((0, _actionsMenu.hideAll)());
|
_store2['default'].dispatch((0, _actionsMenu.hideAll)());
|
||||||
_store2['default'].dispatch((0, _actionsDialog.show)('renameDialog', { description: description }));
|
_store2['default'].dispatch((0, _actionsDialog.show)('renameDialog', { description: description }));
|
||||||
@ -31973,7 +31984,8 @@ exports['default'] = function (state, action) {
|
|||||||
|
|
||||||
if (action.type === _actionsTypes.RENAME_FILE) {
|
if (action.type === _actionsTypes.RENAME_FILE) {
|
||||||
var all = Promise.all(action.file.map(function (file) {
|
var all = Promise.all(action.file.map(function (file) {
|
||||||
return (0, _apiFiles.move)(file, (file.path || '') + action.name);
|
var cwd = _store2['default'].getState().get('cwd');
|
||||||
|
return (0, _apiFiles.move)(file, cwd + '/' + action.name);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
all.then(boundRefresh, _utils.reportError);
|
all.then(boundRefresh, _utils.reportError);
|
||||||
@ -32214,7 +32226,11 @@ exports['default'] = function (state, action) {
|
|||||||
if (state === undefined) state = DEFAULT;
|
if (state === undefined) state = DEFAULT;
|
||||||
|
|
||||||
if (action.type === _actionsTypes.SETTINGS) {
|
if (action.type === _actionsTypes.SETTINGS) {
|
||||||
return Object.assign({}, state, (0, _lodashObjectOmit2['default'])(action, 'type'));
|
var newSettings = Object.assign({}, state, (0, _lodashObjectOmit2['default'])(action, 'type'));
|
||||||
|
|
||||||
|
localStorage.setItem('settings', JSON.stringify(newSettings));
|
||||||
|
|
||||||
|
return newSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
@ -32245,6 +32261,13 @@ exports['default'] = function (state, action) {
|
|||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case _actionsTypes.CHANGE_DIRECTORY:
|
case _actionsTypes.CHANGE_DIRECTORY:
|
||||||
case _actionsTypes.REFRESH:
|
case _actionsTypes.REFRESH:
|
||||||
|
case _actionsTypes.SETTINGS:
|
||||||
|
case _actionsTypes.CREATE_FILE:
|
||||||
|
case _actionsTypes.MOVE_FILE:
|
||||||
|
case _actionsTypes.DELETE_FILE:
|
||||||
|
case _actionsTypes.RENAME_FILE:
|
||||||
|
case _actionsTypes.COPY_FILE:
|
||||||
|
case _actionsTypes.SEARCH:
|
||||||
return true;
|
return true;
|
||||||
case _actionsTypes.LIST_FILES:
|
case _actionsTypes.LIST_FILES:
|
||||||
return false;
|
return false;
|
||||||
@ -32288,7 +32311,8 @@ var _dialogs = require('./dialogs');
|
|||||||
var _dialogs2 = _interopRequireDefault(_dialogs);
|
var _dialogs2 = _interopRequireDefault(_dialogs);
|
||||||
|
|
||||||
var DEFAULT = new _immutable2['default'].Map(Object.assign({
|
var DEFAULT = new _immutable2['default'].Map(Object.assign({
|
||||||
dir: ''
|
dir: '',
|
||||||
|
settings: JSON.parse(localStorage.getItem('settings') || '{}')
|
||||||
}, _dialogs2['default'], _menus2['default']));
|
}, _dialogs2['default'], _menus2['default']));
|
||||||
|
|
||||||
var store = (0, _redux.createStore)(_reducersAll2['default'], DEFAULT);
|
var store = (0, _redux.createStore)(_reducersAll2['default'], DEFAULT);
|
||||||
@ -32318,7 +32342,8 @@ var MESSAGES = {
|
|||||||
'icon-select': 'Select files for batch actions',
|
'icon-select': 'Select files for batch actions',
|
||||||
'icon-more': 'Actions used on selected files such as Copy, Delete, Move, …',
|
'icon-more': 'Actions used on selected files such as Copy, Delete, Move, …',
|
||||||
'drawer': 'Extra options, tools and links are here',
|
'drawer': 'Extra options, tools and links are here',
|
||||||
'icon-search': 'Search your storage for a certain file'
|
'icon-search': 'Search your storage for a certain file',
|
||||||
|
'swipe-instruction': 'Swipe from left to right to go to parent folder'
|
||||||
};
|
};
|
||||||
|
|
||||||
var DIALOG_HIDE_DELAY = 2000;
|
var DIALOG_HIDE_DELAY = 2000;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"name": "Hawk",
|
"name": "Hawk",
|
||||||
"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": "/icon/Icon-16.png",
|
"16": "/icon/Icon-16.png",
|
||||||
@ -15,17 +15,26 @@
|
|||||||
},
|
},
|
||||||
"type": "privileged",
|
"type": "privileged",
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"device-storage:sdcard": {"access": "readwrite"},
|
"device-storage:sdcard": {
|
||||||
"device-storage:videos": {"access": "readwrite"},
|
"access": "readwrite",
|
||||||
"device-storage:pictures": {"access": "readwrite"},
|
"description": "We need access to your files in order to give you the functionality of listing, reading, opening and writing files in your storage"
|
||||||
"device-storage:music": {"access": "readwrite"},
|
},
|
||||||
"device-storage:apps": {"access": "readwrite"},
|
"device-storage:videos": {
|
||||||
"webapps-manage": {}
|
"access": "readwrite",
|
||||||
|
"description": "We need access to your files in order to give you the functionality of listing, reading, opening and writing files in your storage"
|
||||||
|
},
|
||||||
|
"device-storage:pictures": {
|
||||||
|
"access": "readwrite",
|
||||||
|
"description": "We need access to your files in order to give you the functionality of listing, reading, opening and writing files in your storage"
|
||||||
|
},
|
||||||
|
"device-storage:music": {
|
||||||
|
"access": "readwrite",
|
||||||
|
"description": "We need access to your files in order to give you the functionality of listing, reading, opening and writing files in your storage"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"installs_allowed_from": [
|
"installs_allowed_from": [
|
||||||
"*"
|
"https://marketplace.firefox.com",
|
||||||
|
"https://marketplace-dev.allizom.org"
|
||||||
],
|
],
|
||||||
"locales": {
|
|
||||||
},
|
|
||||||
"default_locale": "en"
|
"default_locale": "en"
|
||||||
}
|
}
|
||||||
|
@ -172,6 +172,28 @@ input:checked + label::after {
|
|||||||
transform: scale(0);
|
transform: scale(0);
|
||||||
animation: pulse 2s ease-out infinite;
|
animation: pulse 2s ease-out infinite;
|
||||||
}
|
}
|
||||||
|
.tour .swipe-instruction {
|
||||||
|
position: fixed;
|
||||||
|
left: 50%;
|
||||||
|
top: 20%;
|
||||||
|
width: 70vw;
|
||||||
|
height: 5rem;
|
||||||
|
margin-left: -35vw;
|
||||||
|
z-index: 1;
|
||||||
|
background: white;
|
||||||
|
border-radius: 3rem;
|
||||||
|
}
|
||||||
|
.tour .swipe-instruction::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 5rem;
|
||||||
|
height: 5rem;
|
||||||
|
background: #d9d9d9;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: swipe 3s ease infinite;
|
||||||
|
}
|
||||||
.tour .tour-dialog {
|
.tour .tour-dialog {
|
||||||
display: block;
|
display: block;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
@ -196,6 +218,24 @@ input:checked + label::after {
|
|||||||
transform: scale(5);
|
transform: scale(5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@keyframes swipe {
|
||||||
|
80% {
|
||||||
|
left: calc(100% - 5rem);
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
90% {
|
||||||
|
opacity: 0;
|
||||||
|
left: calc(100% - 5rem);
|
||||||
|
}
|
||||||
|
91% {
|
||||||
|
left: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
left: 0;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
.coming-soon::after {
|
.coming-soon::after {
|
||||||
content: 'soon...';
|
content: 'soon...';
|
||||||
background: #f7c59f;
|
background: #f7c59f;
|
||||||
|
@ -37,6 +37,7 @@
|
|||||||
"grunt-contrib-watch": "^0.6.1",
|
"grunt-contrib-watch": "^0.6.1",
|
||||||
"grunt-fxos": "^0.1.2",
|
"grunt-fxos": "^0.1.2",
|
||||||
"grunt-task-loader": "^0.6.0",
|
"grunt-task-loader": "^0.6.0",
|
||||||
|
"grunt-zip": "^0.17.0",
|
||||||
"hammerjs": "^2.0.4",
|
"hammerjs": "^2.0.4",
|
||||||
"immutable": "^3.7.5",
|
"immutable": "^3.7.5",
|
||||||
"less-plugin-clean-css": "^1.5.1",
|
"less-plugin-clean-css": "^1.5.1",
|
||||||
|
Binary file not shown.
@ -32,17 +32,19 @@ export async function children(dir, gatherInfo) {
|
|||||||
|
|
||||||
if (gatherInfo) {
|
if (gatherInfo) {
|
||||||
for (let child of childs) {
|
for (let child of childs) {
|
||||||
if (type(child) !== 'Directory') continue;
|
if (type(child) === 'Directory') {
|
||||||
|
let subchildren;
|
||||||
|
try {
|
||||||
|
subchildren = await child.getFilesAndDirectories();
|
||||||
|
} catch(e) {
|
||||||
|
subchildren = [];
|
||||||
|
}
|
||||||
|
|
||||||
let subchildren;
|
child.children = subchildren.length;
|
||||||
try {
|
} else {
|
||||||
subchildren = await child.getFilesAndDirectories();
|
child.path = dir + '/';
|
||||||
} catch(e) {
|
|
||||||
subchildren = [];
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
child.children = subchildren.length;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return childs;
|
return childs;
|
||||||
@ -108,7 +110,7 @@ export async function copy(file, newPath) {
|
|||||||
child.path = oldPath + '/';
|
child.path = oldPath + '/';
|
||||||
}
|
}
|
||||||
|
|
||||||
await move(child, newPath + '/' + child.name);
|
await copy(child, newPath + '/' + child.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import changedir from 'actions/changedir';
|
import changedir from 'actions/changedir';
|
||||||
import { show } from 'actions/menu';
|
|
||||||
import { active } from 'actions/file';
|
|
||||||
import { MENU_WIDTH } from './menu';
|
|
||||||
import store from 'store';
|
import store from 'store';
|
||||||
import entry from './mixins/entry';
|
import entry from './mixins/entry';
|
||||||
|
|
||||||
const MENU_TOP_SPACE = 20;
|
|
||||||
|
|
||||||
export default class Directory extends Component {
|
export default class Directory extends Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
|
@ -19,7 +19,7 @@ export default class FileList extends Component {
|
|||||||
let settings = store.getState().get('settings');
|
let settings = store.getState().get('settings');
|
||||||
|
|
||||||
let els = files.map((file, index) => {
|
let els = files.map((file, index) => {
|
||||||
let selected = activeFile.length && activeFile.indexOf(file) > -1;
|
let selected = activeFile.indexOf(file) > -1;
|
||||||
if (type(file) === 'File') {
|
if (type(file) === 'File') {
|
||||||
return <File selectView={selectView} selected={selected} 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 {
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import { show } from 'actions/menu';
|
|
||||||
import { active } from 'actions/file';
|
|
||||||
import { MENU_WIDTH } from './menu';
|
|
||||||
import store from 'store';
|
import store from 'store';
|
||||||
import { humanSize } from 'utils';
|
import { humanSize } from 'utils';
|
||||||
import entry from './mixins/entry';
|
import entry from './mixins/entry';
|
||||||
|
|
||||||
const MENU_TOP_SPACE = 20;
|
|
||||||
|
|
||||||
export default class File extends Component {
|
export default class File extends Component {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@ -19,7 +14,7 @@ export default class File extends Component {
|
|||||||
|
|
||||||
let input, label;
|
let input, label;
|
||||||
if (this.props.selectView) {
|
if (this.props.selectView) {
|
||||||
input = <input type='checkbox' id={checkId} defaultChecked={this.props.selected} readOnly />;
|
input = <input type='checkbox' id={checkId} checked={this.props.selected} readOnly />;
|
||||||
label = <label htmlFor={checkId}></label>;
|
label = <label htmlFor={checkId}></label>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ export const MENU_WIDTH = 245;
|
|||||||
|
|
||||||
export default class Menu extends Component {
|
export default class Menu extends Component {
|
||||||
render() {
|
render() {
|
||||||
let { items, active, style } = this.props;
|
let { items, active, style, id } = this.props;
|
||||||
items = items || [];
|
items = items || [];
|
||||||
|
|
||||||
let els = items.map((item, index) => {
|
let els = items.map((item, index) => {
|
||||||
@ -16,7 +16,7 @@ export default class Menu extends Component {
|
|||||||
let className = 'menu ' + (active ? 'active' : '');
|
let className = 'menu ' + (active ? 'active' : '');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={className} style={style}>
|
<div className={className} style={style} id={id}>
|
||||||
<ul>{els}</ul>
|
<ul>{els}</ul>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,3 +1,10 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { active } from 'actions/file';
|
||||||
|
import { show } from 'actions/menu';
|
||||||
|
import { MENU_WIDTH } from 'components/menu';
|
||||||
|
|
||||||
|
const MENU_TOP_SPACE = 20;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
contextMenu(e) {
|
contextMenu(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -8,12 +15,20 @@ export default {
|
|||||||
|
|
||||||
let left = x + width / 2 - MENU_WIDTH / 2,
|
let left = x + width / 2 - MENU_WIDTH / 2,
|
||||||
top = y + height / 2 + MENU_TOP_SPACE;
|
top = y + height / 2 + MENU_TOP_SPACE;
|
||||||
|
|
||||||
|
let dialogHeight = document.getElementById('fileMenu').offsetHeight;
|
||||||
|
|
||||||
|
let diff = window.innerHeight - (dialogHeight + top);
|
||||||
|
if (diff <= 0) {
|
||||||
|
top -= Math.abs(diff);
|
||||||
|
}
|
||||||
|
|
||||||
store.dispatch(show('fileMenu', {style: {left, top}}));
|
store.dispatch(show('fileMenu', {style: {left, top}}));
|
||||||
store.dispatch(active([file]));
|
store.dispatch(active([file]));
|
||||||
},
|
},
|
||||||
|
|
||||||
select() {
|
select() {
|
||||||
let current = store.getState().get('activeFile').slice(0);
|
let current = (store.getState().get('activeFile') || []).slice(0);
|
||||||
let file = store.getState().get('files')[this.props.index];
|
let file = store.getState().get('files')[this.props.index];
|
||||||
|
|
||||||
if (current.indexOf(file) > -1) {
|
if (current.indexOf(file) > -1) {
|
||||||
|
@ -17,19 +17,19 @@ export default class Navigation extends Component {
|
|||||||
<p>Filter</p>
|
<p>Filter</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<input id='filter-all' name='filter' value='' type='radio' defaultChecked={!settings.filter} />
|
<input id='filter-all' name='filter' data-value='' type='radio' defaultChecked={!settings.filter} />
|
||||||
<label htmlFor='filter-all'>All</label>
|
<label htmlFor='filter-all'>All</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input id='filter-image' name='filter' value='image' type='radio' defaultChecked={settings.filter === 'image'} />
|
<input id='filter-image' name='filter' data-value='image' type='radio' defaultChecked={settings.filter === 'image'} />
|
||||||
<label htmlFor='filter-image'>Image</label>
|
<label htmlFor='filter-image'>Image</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input id='filter-video' name='filter' value='video' type='radio' defaultChecked={settings.filter === 'video'} />
|
<input id='filter-video' name='filter' data-value='video' type='radio' defaultChecked={settings.filter === 'video'} />
|
||||||
<label htmlFor='filter-video'>Video</label>
|
<label htmlFor='filter-video'>Video</label>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<input id='filter-audio' name='filter' value='audio' type='radio' defaultChecked={settings.filter === 'audio'} />
|
<input id='filter-audio' name='filter' data-value='audio' type='radio' defaultChecked={settings.filter === 'audio'} />
|
||||||
<label htmlFor='filter-audio'>Audio</label>
|
<label htmlFor='filter-audio'>Audio</label>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@ -77,7 +77,7 @@ export default class Navigation extends Component {
|
|||||||
|
|
||||||
onChange(e) {
|
onChange(e) {
|
||||||
let key = e.target.name || e.target.id;
|
let key = e.target.name || e.target.id;
|
||||||
let value = e.target.value === undefined ? e.target.checked : e.target.value;
|
let value = typeof e.target.dataset.value !== 'undefined' ? e.target.dataset.value : e.target.checked;
|
||||||
|
|
||||||
let action = updateSettings({
|
let action = updateSettings({
|
||||||
[key]: value
|
[key]: value
|
||||||
|
@ -19,7 +19,7 @@ window.store = store;
|
|||||||
window.changedir = changedir;
|
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 MoreMenu = connect(state => state.get('moreMenu'))(Menu);
|
||||||
|
|
||||||
let RenameDialog = connect(state => state.get('renameDialog'))(Dialog);
|
let RenameDialog = connect(state => state.get('renameDialog'))(Dialog);
|
||||||
@ -31,16 +31,16 @@ let SearchDialog = connect(state => state.get('searchDialog'))(Dialog);
|
|||||||
export default class Root extends Component {
|
export default class Root extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div onTouchStart={this.touchStart.bind(this)} onClick={this.onClick.bind(this)}>
|
<div onTouchStart={this.touchStart.bind(this)}
|
||||||
|
onClick={this.onClick.bind(this)}>
|
||||||
<Header />
|
<Header />
|
||||||
<Breadcrumb />
|
<Breadcrumb />
|
||||||
<Navigation />
|
<Navigation />
|
||||||
<FileList />
|
<FileList />
|
||||||
<Toolbar />
|
<Toolbar />
|
||||||
|
|
||||||
<FileMenu />
|
<FileMenu id='fileMenu' />
|
||||||
<DirectoryMenu />
|
<MoreMenu id='moreMenu' />
|
||||||
<MoreMenu />
|
|
||||||
|
|
||||||
<RenameDialog />
|
<RenameDialog />
|
||||||
<DeleteDialog />
|
<DeleteDialog />
|
||||||
@ -50,6 +50,8 @@ export default class Root extends Component {
|
|||||||
|
|
||||||
<Spinner />
|
<Spinner />
|
||||||
|
|
||||||
|
<div className='swipe-instruction tour-item'></div>
|
||||||
|
|
||||||
<div className='tour-dialog'>
|
<div className='tour-dialog'>
|
||||||
Hello! Tap each highlighted button to get an understanding of how they work.
|
Hello! Tap each highlighted button to get an understanding of how they work.
|
||||||
</div>
|
</div>
|
||||||
|
@ -11,7 +11,7 @@ const entryMenu = {
|
|||||||
action() {
|
action() {
|
||||||
let files = store.getState().get('files');
|
let files = store.getState().get('files');
|
||||||
let active = store.getState().get('activeFile');
|
let active = store.getState().get('activeFile');
|
||||||
const description = `Enter the new name for ${active[0].name}?`;
|
const description = `Enter the new name for ${active[0].name}`;
|
||||||
|
|
||||||
store.dispatch(hideAll());
|
store.dispatch(hideAll());
|
||||||
store.dispatch(show('renameDialog', {description}));
|
store.dispatch(show('renameDialog', {description}));
|
||||||
|
@ -46,7 +46,8 @@ export default function(state = [], action) {
|
|||||||
|
|
||||||
if (action.type === RENAME_FILE) {
|
if (action.type === RENAME_FILE) {
|
||||||
let all = Promise.all(action.file.map(file => {
|
let all = Promise.all(action.file.map(file => {
|
||||||
return move(file, (file.path || '') + action.name);
|
let cwd = store.getState().get('cwd');
|
||||||
|
return move(file, cwd + '/' + action.name);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
all.then(boundRefresh, reportError);
|
all.then(boundRefresh, reportError);
|
||||||
|
@ -8,7 +8,11 @@ const DEFAULT = {
|
|||||||
|
|
||||||
export default function(state = DEFAULT, action) {
|
export default function(state = DEFAULT, action) {
|
||||||
if (action.type === SETTINGS) {
|
if (action.type === SETTINGS) {
|
||||||
return Object.assign({}, state, omit(action, 'type'));
|
let newSettings = Object.assign({}, state, omit(action, 'type'));
|
||||||
|
|
||||||
|
localStorage.setItem('settings', JSON.stringify(newSettings));
|
||||||
|
|
||||||
|
return newSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { SPINNER, CHANGE_DIRECTORY, LIST_FILES, REFRESH, DIALOG, CREATE_FILE, DELETE_FILE } from 'actions/types';
|
import { SPINNER, CHANGE_DIRECTORY, LIST_FILES, REFRESH, DIALOG, SETTINGS,
|
||||||
|
CREATE_FILE, DELETE_FILE, RENAME_FILE, MOVE_FILE, COPY_FILE, SEARCH} from 'actions/types';
|
||||||
|
|
||||||
export default function(state = false, action) {
|
export default function(state = false, action) {
|
||||||
if (action.type === SPINNER) {
|
if (action.type === SPINNER) {
|
||||||
@ -12,6 +13,13 @@ export default function(state = false, action) {
|
|||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case CHANGE_DIRECTORY:
|
case CHANGE_DIRECTORY:
|
||||||
case REFRESH:
|
case REFRESH:
|
||||||
|
case SETTINGS:
|
||||||
|
case CREATE_FILE:
|
||||||
|
case MOVE_FILE:
|
||||||
|
case DELETE_FILE:
|
||||||
|
case RENAME_FILE:
|
||||||
|
case COPY_FILE:
|
||||||
|
case SEARCH:
|
||||||
return true;
|
return true;
|
||||||
case LIST_FILES:
|
case LIST_FILES:
|
||||||
return false;
|
return false;
|
||||||
|
@ -7,6 +7,7 @@ import dialogs from './dialogs';
|
|||||||
|
|
||||||
const DEFAULT = new Immutable.Map(Object.assign({
|
const DEFAULT = new Immutable.Map(Object.assign({
|
||||||
dir: '',
|
dir: '',
|
||||||
|
settings: JSON.parse(localStorage.getItem('settings') || '{}')
|
||||||
}, dialogs, menus));
|
}, dialogs, menus));
|
||||||
|
|
||||||
let store = createStore(reducers, DEFAULT);
|
let store = createStore(reducers, DEFAULT);
|
||||||
|
@ -4,7 +4,8 @@ const MESSAGES = {
|
|||||||
'icon-select': 'Select files for batch actions',
|
'icon-select': 'Select files for batch actions',
|
||||||
'icon-more': 'Actions used on selected files such as Copy, Delete, Move, …',
|
'icon-more': 'Actions used on selected files such as Copy, Delete, Move, …',
|
||||||
'drawer': 'Extra options, tools and links are here',
|
'drawer': 'Extra options, tools and links are here',
|
||||||
'icon-search': 'Search your storage for a certain file'
|
'icon-search': 'Search your storage for a certain file',
|
||||||
|
'swipe-instruction': 'Swipe from left to right to go to parent folder'
|
||||||
}
|
}
|
||||||
|
|
||||||
const DIALOG_HIDE_DELAY = 2000;
|
const DIALOG_HIDE_DELAY = 2000;
|
||||||
|
@ -49,6 +49,40 @@
|
|||||||
animation: pulse 2s ease-out infinite;
|
animation: pulse 2s ease-out infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.swipe-instruction {
|
||||||
|
position: fixed;
|
||||||
|
left: 50%;
|
||||||
|
top: 20%;
|
||||||
|
|
||||||
|
width: 70vw;
|
||||||
|
height: 5rem;
|
||||||
|
|
||||||
|
margin-left: -35vw;
|
||||||
|
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
background: white;
|
||||||
|
|
||||||
|
border-radius: 3rem;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
width: 5rem;
|
||||||
|
height: 5rem;
|
||||||
|
|
||||||
|
background: darken(white, 15);
|
||||||
|
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
animation: swipe 3s ease infinite;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.tour-dialog {
|
.tour-dialog {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
||||||
@ -86,3 +120,22 @@
|
|||||||
transform: scale(5);
|
transform: scale(5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes swipe {
|
||||||
|
80% {
|
||||||
|
left: ~'calc(100% - 5rem)';
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
90% {
|
||||||
|
opacity: 0;
|
||||||
|
left: ~'calc(100% - 5rem)';
|
||||||
|
}
|
||||||
|
91% {
|
||||||
|
left: 0;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
left: 0;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"name": "Hawk",
|
"name": "Hawk",
|
||||||
"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": "/icon/Icon-16.png",
|
"16": "/icon/Icon-16.png",
|
||||||
@ -15,13 +15,26 @@
|
|||||||
},
|
},
|
||||||
"type": "privileged",
|
"type": "privileged",
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"device-storage:sdcard": {"access": "readwrite"},
|
"device-storage:sdcard": {
|
||||||
"device-storage:videos": {"access": "readwrite"},
|
"access": "readwrite",
|
||||||
"device-storage:pictures": {"access": "readwrite"},
|
"description": "We need access to your files in order to give you the functionality of listing, reading, opening and writing files in your storage"
|
||||||
"device-storage:music": {"access": "readwrite"}
|
},
|
||||||
|
"device-storage:videos": {
|
||||||
|
"access": "readwrite",
|
||||||
|
"description": "We need access to your files in order to give you the functionality of listing, reading, opening and writing files in your storage"
|
||||||
|
},
|
||||||
|
"device-storage:pictures": {
|
||||||
|
"access": "readwrite",
|
||||||
|
"description": "We need access to your files in order to give you the functionality of listing, reading, opening and writing files in your storage"
|
||||||
|
},
|
||||||
|
"device-storage:music": {
|
||||||
|
"access": "readwrite",
|
||||||
|
"description": "We need access to your files in order to give you the functionality of listing, reading, opening and writing files in your storage"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"installs_allowed_from": [
|
"installs_allowed_from": [
|
||||||
"marketplace.firefox.com"
|
"https://marketplace.firefox.com",
|
||||||
|
"https://marketplace-dev.allizom.org"
|
||||||
],
|
],
|
||||||
"default_locale": "en"
|
"default_locale": "en"
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user