mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-23 10:45:47 +00:00
feature(load-module) add
This commit is contained in:
parent
146b32b215
commit
4b528280ba
24 changed files with 1352 additions and 1491 deletions
1
.babelrc
1
.babelrc
|
|
@ -9,6 +9,7 @@
|
|||
"plugins": [
|
||||
"@babel/plugin-transform-object-assign",
|
||||
"@babel/plugin-proposal-object-rest-spread",
|
||||
"@babel/plugin-syntax-dynamic-import",
|
||||
"module:fast-async",
|
||||
"module:babel-plugin-macros",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
{
|
||||
"parser": "babel-eslint",
|
||||
"env": {
|
||||
"es6": true,
|
||||
"node": true,
|
||||
|
|
@ -14,7 +15,7 @@
|
|||
"indent": ["error", 4],
|
||||
"semi": "error",
|
||||
"no-console": 0,
|
||||
"no-use-before-define": ["error", "nofunc"]
|
||||
"no-use-before-define": 0,
|
||||
},
|
||||
"extends": [
|
||||
"eslint:recommended"
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ yarn-error.log
|
|||
yarn.lock
|
||||
now.json
|
||||
|
||||
dist*/modules
|
||||
|
||||
modules/jquery-mouse-wheel
|
||||
|
||||
modules/jquery/dist
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ const devtool = isDev ? 'eval' : 'source-map';
|
|||
const notEmpty = (a) => a;
|
||||
const clean = (array) => array.filter(notEmpty);
|
||||
|
||||
const noParse = (a) => /\.spec\.js$/.test(a);
|
||||
|
||||
const babelDev = {
|
||||
babelrc: false,
|
||||
plugins: [
|
||||
|
|
@ -55,8 +57,8 @@ const plugins = [
|
|||
];
|
||||
|
||||
const splitChunks = {
|
||||
chunks: 'all',
|
||||
name: 'cloudcmd.common',
|
||||
chunks: 'async',
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
|
|
@ -96,6 +98,7 @@ module.exports = {
|
|||
],
|
||||
module: {
|
||||
rules,
|
||||
noParse,
|
||||
},
|
||||
plugins,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
'use strict';
|
||||
|
||||
/* global Util, DOM */
|
||||
/* global DOM */
|
||||
|
||||
const itype = require('itype/legacy');
|
||||
const Emitify = require('emitify/legacy');
|
||||
const inherits = require('inherits');
|
||||
const rendy = require('rendy/legacy');
|
||||
const wraptile = require('wraptile/legacy');
|
||||
const exec = require('execon');
|
||||
|
||||
const {kebabToCamelCase} = require('../common/util');
|
||||
const isDev = process.env.NODE_ENV === 'development';
|
||||
|
||||
const Images = require('./dom/images');
|
||||
const {
|
||||
unregisterSW,
|
||||
|
|
@ -27,22 +29,21 @@ const {
|
|||
buildFromJSON,
|
||||
} = require('../common/cloudfunc');
|
||||
|
||||
/* global Util, DOM */
|
||||
const loadModule = require('./load-module');
|
||||
|
||||
inherits(CloudCmdProto, Emitify);
|
||||
|
||||
module.exports = new CloudCmdProto(Util, DOM);
|
||||
module.exports = new CloudCmdProto(DOM);
|
||||
|
||||
function CloudCmdProto(Util, DOM) {
|
||||
function CloudCmdProto(DOM) {
|
||||
let Key;
|
||||
let Debug;
|
||||
let Listeners;
|
||||
|
||||
const log = (str) => {
|
||||
if (!Debug)
|
||||
const log = (...a) => {
|
||||
if (!isDev )
|
||||
return;
|
||||
|
||||
console.log(str);
|
||||
console.log(...a);
|
||||
};
|
||||
|
||||
Emitify.call(this);
|
||||
|
|
@ -75,16 +76,6 @@ function CloudCmdProto(Util, DOM) {
|
|||
right: 'asc',
|
||||
};
|
||||
|
||||
log.enable = () => {
|
||||
Debug = true;
|
||||
};
|
||||
|
||||
log.disable = () => {
|
||||
Debug = false;
|
||||
};
|
||||
|
||||
const kebabToCamelCase = Util.kebabToCamelCase;
|
||||
|
||||
/**
|
||||
* Функция привязываеться ко всем ссылкам и
|
||||
* загружает содержимое каталогов
|
||||
|
|
@ -127,49 +118,6 @@ function CloudCmdProto(Util, DOM) {
|
|||
}, panel, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* function load modules
|
||||
* @params = {name, path, func, dobefore, arg}
|
||||
*/
|
||||
function loadModule(params) {
|
||||
if (!params)
|
||||
return;
|
||||
|
||||
let path = params.path;
|
||||
const name = params.name || path && kebabToCamelCase(path);
|
||||
const func = params.func;
|
||||
const funcName = params.funcName;
|
||||
const doBefore = params.dobefore;
|
||||
|
||||
const isContain = /\.js/.test(path);
|
||||
|
||||
if (!isContain)
|
||||
path += '.js';
|
||||
|
||||
if (CloudCmd[name])
|
||||
return;
|
||||
|
||||
CloudCmd[name] = (...args) => {
|
||||
const prefix = CloudCmd.PREFIX;
|
||||
const pathFull = prefix + CloudCmd.DIRCLIENT_MODULES + path;
|
||||
|
||||
exec(doBefore);
|
||||
|
||||
const done = (error) => {
|
||||
const Proto = CloudCmd[name];
|
||||
|
||||
if (error || !itype.function(Proto))
|
||||
return;
|
||||
|
||||
CloudCmd[name] = new Proto(...args);
|
||||
};
|
||||
|
||||
return DOM.load.js(pathFull, func || done);
|
||||
};
|
||||
|
||||
CloudCmd[name][funcName] = CloudCmd[name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Конструктор CloudClient, который
|
||||
* выполняет весь функционал по
|
||||
|
|
@ -180,7 +128,6 @@ function CloudCmdProto(Util, DOM) {
|
|||
initModules,
|
||||
baseInit,
|
||||
loadPlugins,
|
||||
loadStyle,
|
||||
exec.with(CloudCmd.route, location.hash),
|
||||
], noop);
|
||||
|
||||
|
|
@ -217,13 +164,6 @@ function CloudCmdProto(Util, DOM) {
|
|||
exec.if(document.body.scrollIntoViewIfNeeded, func, funcBefore);
|
||||
};
|
||||
|
||||
function loadStyle(callback) {
|
||||
const prefix = CloudCmd.PREFIX;
|
||||
const name = prefix + '/dist/cloudcmd.common.css';
|
||||
|
||||
DOM.load.css(name, callback);
|
||||
}
|
||||
|
||||
function loadPlugins(callback) {
|
||||
const prefix = CloudCmd.PREFIX;
|
||||
const plugins = prefix + '/plugins.js';
|
||||
|
|
@ -263,7 +203,6 @@ function CloudCmdProto(Util, DOM) {
|
|||
}
|
||||
|
||||
DOM.setCurrentFile(current);
|
||||
|
||||
CloudCmd.execFromModule(module, 'show');
|
||||
};
|
||||
|
||||
|
|
@ -303,14 +242,10 @@ function CloudCmdProto(Util, DOM) {
|
|||
};
|
||||
|
||||
const load = (name, path, dobefore) => {
|
||||
const isTmpl = path === 'template';
|
||||
const funcName = isTmpl ? 'get' : 'show';
|
||||
|
||||
loadModule({
|
||||
name,
|
||||
path,
|
||||
dobefore,
|
||||
funcName,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -372,16 +307,11 @@ function CloudCmdProto(Util, DOM) {
|
|||
];
|
||||
}
|
||||
|
||||
this.execFromModule = (moduleName, funcName, ...args) => {
|
||||
const obj = CloudCmd[moduleName];
|
||||
const isObj = itype.object(obj);
|
||||
this.execFromModule = async (moduleName, funcName, ...args) => {
|
||||
await CloudCmd[moduleName]();
|
||||
|
||||
exec.if(isObj, () => {
|
||||
const obj = CloudCmd[moduleName];
|
||||
const func = obj[funcName];
|
||||
|
||||
func(...args);
|
||||
}, obj);
|
||||
const func = CloudCmd[moduleName][funcName];
|
||||
func(...args);
|
||||
};
|
||||
|
||||
this.refresh = (options = {}, callback) => {
|
||||
|
|
|
|||
53
client/load-module.js
Normal file
53
client/load-module.js
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd */
|
||||
|
||||
const exec = require('execon');
|
||||
const tryToCatch = require('try-to-catch/legacy');
|
||||
const {
|
||||
kebabToCamelCase,
|
||||
} = require('../common/util');
|
||||
|
||||
/**
|
||||
* function load modules
|
||||
* @params = {name, path, func, dobefore, arg}
|
||||
*/
|
||||
module.exports = function loadModule(params) {
|
||||
if (!params)
|
||||
return;
|
||||
|
||||
let path = params.path;
|
||||
const name = params.name || path && kebabToCamelCase(path);
|
||||
const doBefore = params.dobefore;
|
||||
|
||||
if (CloudCmd[name])
|
||||
return;
|
||||
|
||||
CloudCmd[name] = () => {
|
||||
exec(doBefore);
|
||||
return import(`./modules/${path}` /* webpackChunkName: "cloudcmd-" */).then(async (module) => {
|
||||
const newModule = async (f) => f && f();
|
||||
|
||||
Object.assign(newModule, module);
|
||||
CloudCmd[name] = newModule;
|
||||
|
||||
CloudCmd.log('init', name);
|
||||
await module.init();
|
||||
|
||||
return newModule;
|
||||
});
|
||||
};
|
||||
|
||||
CloudCmd[name].show = async (...args) => {
|
||||
CloudCmd.log('show', name, args);
|
||||
const m = CloudCmd[name];
|
||||
|
||||
const [e, a] = await tryToCatch(m);
|
||||
|
||||
if (e)
|
||||
return console.error(e);
|
||||
|
||||
a.show(...args);
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -2,10 +2,9 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
CloudCmd.Cloud = CloudProto;
|
||||
|
||||
const exec = require('execon');
|
||||
const currify = require('currify/legacy');
|
||||
const {promisify} = require('es6-promisify');
|
||||
|
||||
const {log} = CloudCmd;
|
||||
|
||||
|
|
@ -15,11 +14,9 @@ const Images = require('../dom/images');
|
|||
|
||||
const upload = currify(_upload);
|
||||
|
||||
function CloudProto(callback) {
|
||||
loadFiles(callback);
|
||||
|
||||
return module.exports;
|
||||
}
|
||||
module.exports.init = async () => {
|
||||
await loadFiles();
|
||||
};
|
||||
|
||||
module.exports.uploadFile = (filename, data) => {
|
||||
const mimetype = '';
|
||||
|
|
@ -52,7 +49,7 @@ function _upload(callback, file) {
|
|||
});
|
||||
}
|
||||
|
||||
function loadFiles(callback) {
|
||||
const loadFiles = promisify((callback) => {
|
||||
const js = '//api.filepicker.io/v2/filepicker.js';
|
||||
|
||||
load.js(js, () => {
|
||||
|
|
@ -65,5 +62,5 @@ function loadFiles(callback) {
|
|||
exec(callback);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -7,21 +7,22 @@ require('../../css/config.css');
|
|||
const rendy = require('rendy/legacy');
|
||||
const exec = require('execon');
|
||||
const currify = require('currify/legacy');
|
||||
const wraptile = require('wraptile/legacy');
|
||||
const squad = require('squad/legacy');
|
||||
const input = require('../input');
|
||||
const {promisify} = require('es6-promisify');
|
||||
|
||||
const input = require('../input');
|
||||
const Images = require('../dom/images');
|
||||
const Events = require('../dom/events');
|
||||
const Files = require('../dom/files');
|
||||
|
||||
const {getTitle} = require('../../common/cloudfunc');
|
||||
|
||||
const {Dialog, setTitle} = DOM;
|
||||
|
||||
const TITLE = 'Config';
|
||||
const alert = currify(Dialog.alert, TITLE);
|
||||
|
||||
const Config = module.exports;
|
||||
const loadSocket = promisify(DOM.loadSocket);
|
||||
|
||||
const showLoad = () => {
|
||||
Images.show.load('top');
|
||||
|
|
@ -37,33 +38,18 @@ const addChange = currify((fn, input) => {
|
|||
return input;
|
||||
});
|
||||
|
||||
CloudCmd.Config = ConfigProto;
|
||||
const Config = {};
|
||||
|
||||
let Loading = true;
|
||||
|
||||
function ConfigProto() {
|
||||
const noop = () => {};
|
||||
|
||||
if (!CloudCmd.config('configDialog'))
|
||||
return {
|
||||
show: noop
|
||||
};
|
||||
|
||||
Loading = true;
|
||||
|
||||
module.exports.init = async () => {
|
||||
showLoad();
|
||||
exec.series([
|
||||
CloudCmd.View,
|
||||
(callback) => {
|
||||
Loading = false;
|
||||
exec(callback);
|
||||
DOM.loadSocket(initSocket);
|
||||
},
|
||||
show
|
||||
]);
|
||||
|
||||
return module.exports;
|
||||
}
|
||||
await CloudCmd.View();
|
||||
await loadSocket();
|
||||
initSocket();
|
||||
Loading = false;
|
||||
};
|
||||
|
||||
const config = CloudCmd.config;
|
||||
|
||||
|
|
@ -113,10 +99,7 @@ function initSocket() {
|
|||
|
||||
function authCheck(socket) {
|
||||
socket.emit('auth', config('username'), config('password'));
|
||||
|
||||
socket.on('reject', () => {
|
||||
alert('Wrong credentials!');
|
||||
});
|
||||
socket.on('reject', wraptile(alert, 'Wrong credentials!'));
|
||||
}
|
||||
|
||||
Config.save = saveHttp;
|
||||
|
|
@ -124,6 +107,9 @@ Config.save = saveHttp;
|
|||
module.exports.show = show;
|
||||
|
||||
function show() {
|
||||
if (!CloudCmd.config('configDialog'))
|
||||
return;
|
||||
|
||||
const prefix = CloudCmd.PREFIX;
|
||||
const funcs = [
|
||||
exec.with(Files.get, 'config-tmpl'),
|
||||
|
|
@ -193,9 +179,11 @@ function fillTemplate(error, template) {
|
|||
});
|
||||
}
|
||||
|
||||
module.exports.hide = () => {
|
||||
module.exports.hide = hide;
|
||||
|
||||
function hide() {
|
||||
CloudCmd.View.hide();
|
||||
};
|
||||
}
|
||||
|
||||
function onChange(el) {
|
||||
const obj = {};
|
||||
|
|
@ -249,7 +237,7 @@ function onNameChange(name) {
|
|||
function onKey({keyCode, target}) {
|
||||
switch (keyCode) {
|
||||
case Key.ESC:
|
||||
Config.hide();
|
||||
hide();
|
||||
break;
|
||||
|
||||
case Key.ENTER:
|
||||
|
|
|
|||
|
|
@ -2,54 +2,46 @@
|
|||
|
||||
/* global CloudCmd */
|
||||
|
||||
const exec = require('execon');
|
||||
const Events = require('../dom/events');
|
||||
|
||||
const {Key} = CloudCmd;
|
||||
|
||||
CloudCmd.EditFileVim = function EditFileVimProto(callback) {
|
||||
const EditFileVim = this;
|
||||
|
||||
const ConfigView = {
|
||||
bindKeys: false,
|
||||
beforeClose: () => {
|
||||
Events.rmKey(listener);
|
||||
CloudCmd.EditFile.isChanged();
|
||||
}
|
||||
};
|
||||
|
||||
function init(callback) {
|
||||
exec.series([
|
||||
CloudCmd.EditFile,
|
||||
callback || EditFileVim.show,
|
||||
]);
|
||||
const ConfigView = {
|
||||
bindKeys: false,
|
||||
beforeClose: () => {
|
||||
Events.rmKey(listener);
|
||||
CloudCmd.EditFile.isChanged();
|
||||
}
|
||||
|
||||
this.show = () => {
|
||||
Events.addKey(listener);
|
||||
|
||||
CloudCmd.EditFile
|
||||
.show(ConfigView)
|
||||
.getEditor()
|
||||
.setKeyMap('vim');
|
||||
};
|
||||
|
||||
this.hide = () => {
|
||||
CloudCmd.Edit.hide();
|
||||
};
|
||||
|
||||
function listener(event) {
|
||||
const {
|
||||
keyCode,
|
||||
shiftKey,
|
||||
} = event;
|
||||
|
||||
if (shiftKey && keyCode === Key.ESC) {
|
||||
event.preventDefault();
|
||||
EditFileVim.hide();
|
||||
}
|
||||
}
|
||||
|
||||
init(callback);
|
||||
};
|
||||
|
||||
module.exports.init = async () => {
|
||||
await CloudCmd.EditFile();
|
||||
};
|
||||
|
||||
module.exports.show = () => {
|
||||
Events.addKey(listener);
|
||||
|
||||
CloudCmd.EditFile
|
||||
.show(ConfigView)
|
||||
.getEditor()
|
||||
.setKeyMap('vim');
|
||||
};
|
||||
|
||||
module.exports.hide = hide;
|
||||
|
||||
function hide() {
|
||||
CloudCmd.Edit.hide();
|
||||
}
|
||||
|
||||
function listener(event) {
|
||||
const {
|
||||
keyCode,
|
||||
shiftKey,
|
||||
} = event;
|
||||
|
||||
if (shiftKey && keyCode === Key.ESC) {
|
||||
event.preventDefault();
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,204 +3,183 @@
|
|||
/* global CloudCmd, DOM*/
|
||||
|
||||
const Format = require('format-io/legacy');
|
||||
const currify = require('currify/legacy');
|
||||
const store = require('fullstore/legacy');
|
||||
const squad = require('squad/legacy');
|
||||
const exec = require('execon');
|
||||
const supermenu = require('supermenu');
|
||||
|
||||
const call = currify((fn, callback) => {
|
||||
fn();
|
||||
callback();
|
||||
});
|
||||
const Info = DOM.CurrentInfo;
|
||||
const Dialog = DOM.Dialog;
|
||||
const config = CloudCmd.config;
|
||||
|
||||
CloudCmd.EditFile = function EditFileProto(callback) {
|
||||
const Info = DOM.CurrentInfo;
|
||||
const Dialog = DOM.Dialog;
|
||||
const EditFile = exec.bind();
|
||||
const config = CloudCmd.config;
|
||||
let Menu;
|
||||
|
||||
const TITLE = 'Edit';
|
||||
const Images = DOM.Images;
|
||||
|
||||
let MSG_CHANGED;
|
||||
const ConfigView = {
|
||||
beforeClose: () => {
|
||||
exec.ifExist(Menu, 'hide');
|
||||
isChanged();
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.init = async () => {
|
||||
await CloudCmd.Edit();
|
||||
|
||||
let Menu;
|
||||
const editor = CloudCmd.Edit.getEditor();
|
||||
authCheck(editor);
|
||||
setListeners(editor);
|
||||
};
|
||||
|
||||
function getName() {
|
||||
const {name, isDir} = Info;
|
||||
|
||||
const TITLE = 'Edit';
|
||||
const Images = DOM.Images;
|
||||
if (isDir)
|
||||
return `${name}.json`;
|
||||
|
||||
let MSG_CHANGED;
|
||||
const ConfigView = {
|
||||
beforeClose: () => {
|
||||
exec.ifExist(Menu, 'hide');
|
||||
EditFile.isChanged();
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
module.exports.show = (options) => {
|
||||
const config = {
|
||||
...ConfigView,
|
||||
...options,
|
||||
};
|
||||
|
||||
function init(callback) {
|
||||
const editor = store();
|
||||
|
||||
const getMainEditor = () => CloudCmd.Edit.getEditor();
|
||||
const getEditor = squad(editor, getMainEditor);
|
||||
const auth = squad(authCheck, editor);
|
||||
const listeners = squad(setListeners, editor);
|
||||
|
||||
const show = callback ? exec : EditFile.show;
|
||||
|
||||
exec.series([
|
||||
CloudCmd.Edit,
|
||||
call(getEditor),
|
||||
call(auth),
|
||||
call(listeners),
|
||||
show,
|
||||
], callback);
|
||||
}
|
||||
Images.show.load();
|
||||
|
||||
function getName() {
|
||||
const {name, isDir} = Info;
|
||||
|
||||
if (isDir)
|
||||
return `${name}.json`;
|
||||
|
||||
return name;
|
||||
}
|
||||
CloudCmd.Edit
|
||||
.getEditor()
|
||||
.setOption('keyMap', 'default');
|
||||
|
||||
EditFile.show = (options) => {
|
||||
const config = {
|
||||
...ConfigView,
|
||||
...options,
|
||||
};
|
||||
Info.getData((error, data) => {
|
||||
const path = Info.path;
|
||||
const name = getName();
|
||||
|
||||
Images.show.load();
|
||||
if (error)
|
||||
return Images.hide();
|
||||
|
||||
setMsgChanged(name);
|
||||
|
||||
CloudCmd.Edit
|
||||
.getEditor()
|
||||
.setOption('keyMap', 'default');
|
||||
.setValueFirst(path, data)
|
||||
.setModeForPath(name)
|
||||
.enableKey();
|
||||
|
||||
Info.getData((error, data) => {
|
||||
const path = Info.path;
|
||||
const name = getName();
|
||||
|
||||
if (error)
|
||||
return Images.hide();
|
||||
|
||||
setMsgChanged(name);
|
||||
|
||||
CloudCmd.Edit
|
||||
.getEditor()
|
||||
.setValueFirst(path, data)
|
||||
.setModeForPath(name)
|
||||
.enableKey();
|
||||
|
||||
CloudCmd.Edit.show(config);
|
||||
});
|
||||
|
||||
return CloudCmd.Edit;
|
||||
};
|
||||
CloudCmd.Edit.show(config);
|
||||
});
|
||||
|
||||
EditFile.hide = () => {
|
||||
CloudCmd.Edit.hide();
|
||||
};
|
||||
|
||||
function setListeners(editor) {
|
||||
const element = CloudCmd.Edit.getElement();
|
||||
|
||||
DOM.Events.addOnce('contextmenu', element, setMenu);
|
||||
|
||||
editor.on('save', (value) => {
|
||||
DOM.setCurrentSize(Format.size(value));
|
||||
});
|
||||
}
|
||||
|
||||
function authCheck(spawn) {
|
||||
spawn.emit('auth', config('username'), config('password'));
|
||||
spawn.on('reject', () => {
|
||||
Dialog.alert(TITLE, 'Wrong credentials!');
|
||||
});
|
||||
}
|
||||
|
||||
function setMenu(event) {
|
||||
const position = {
|
||||
x: event.clientX,
|
||||
y: event.clientY
|
||||
};
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
if (Menu)
|
||||
return;
|
||||
|
||||
const options = {
|
||||
beforeShow: (params) => {
|
||||
params.x -= 18;
|
||||
params.y -= 27;
|
||||
},
|
||||
|
||||
afterClick: () => {
|
||||
const editor = CloudCmd.Edit.getEditor();
|
||||
editor.focus();
|
||||
}
|
||||
};
|
||||
|
||||
const element = CloudCmd.Edit.getElement();
|
||||
|
||||
Menu = supermenu(element, options, getMenuData());
|
||||
Menu.show(position.x, position.y);
|
||||
}
|
||||
|
||||
function getMenuData() {
|
||||
const editor = CloudCmd.Edit.getEditor();
|
||||
|
||||
return {
|
||||
'Save Ctrl+S' : () => {
|
||||
editor.save();
|
||||
},
|
||||
'Go To Line Ctrl+G' : () => {
|
||||
editor.goToLine();
|
||||
},
|
||||
'Cut Ctrl+X' : () => {
|
||||
editor.cutToClipboard();
|
||||
},
|
||||
'Copy Ctrl+C' : () => {
|
||||
editor.copyToClipboard();
|
||||
},
|
||||
'Paste Ctrl+V' : () => {
|
||||
editor.pasteFromClipboard();
|
||||
},
|
||||
'Delete Del' : () => {
|
||||
editor.remove('right');
|
||||
},
|
||||
'Select All Ctrl+A' : () => {
|
||||
editor.selectAll();
|
||||
},
|
||||
'Beautify Ctrl+B' : () => {
|
||||
editor.beautify();
|
||||
},
|
||||
'Minify Ctrl+M' : () => {
|
||||
editor.minify();
|
||||
},
|
||||
'Close Esc' : () => {
|
||||
EditFile.hide();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function setMsgChanged(name) {
|
||||
MSG_CHANGED = 'Do you want to save changes to ' + name + '?';
|
||||
}
|
||||
|
||||
EditFile.isChanged = () => {
|
||||
const editor = CloudCmd.Edit.getEditor();
|
||||
const is = editor.isChanged();
|
||||
|
||||
if (!is)
|
||||
return;
|
||||
|
||||
const cancel = false;
|
||||
Dialog.confirm(TITLE, MSG_CHANGED, {cancel})
|
||||
.then(() => {
|
||||
editor.save();
|
||||
});
|
||||
};
|
||||
|
||||
init(callback);
|
||||
|
||||
return EditFile;
|
||||
return CloudCmd.Edit;
|
||||
};
|
||||
|
||||
module.exports.hide = hide;
|
||||
|
||||
function hide() {
|
||||
CloudCmd.Edit.hide();
|
||||
}
|
||||
|
||||
function setListeners(editor) {
|
||||
const element = CloudCmd.Edit.getElement();
|
||||
|
||||
DOM.Events.addOnce('contextmenu', element, setMenu);
|
||||
|
||||
editor.on('save', (value) => {
|
||||
DOM.setCurrentSize(Format.size(value));
|
||||
});
|
||||
}
|
||||
|
||||
function authCheck(spawn) {
|
||||
spawn.emit('auth', config('username'), config('password'));
|
||||
spawn.on('reject', () => {
|
||||
Dialog.alert(TITLE, 'Wrong credentials!');
|
||||
});
|
||||
}
|
||||
|
||||
function setMenu(event) {
|
||||
const position = {
|
||||
x: event.clientX,
|
||||
y: event.clientY
|
||||
};
|
||||
|
||||
event.preventDefault();
|
||||
|
||||
if (Menu)
|
||||
return;
|
||||
|
||||
const options = {
|
||||
beforeShow: (params) => {
|
||||
params.x -= 18;
|
||||
params.y -= 27;
|
||||
},
|
||||
|
||||
afterClick: () => {
|
||||
CloudCmd.Edit
|
||||
.getEditor()
|
||||
.focus();
|
||||
}
|
||||
};
|
||||
|
||||
const element = CloudCmd.Edit.getElement();
|
||||
|
||||
Menu = supermenu(element, options, getMenuData());
|
||||
Menu.show(position.x, position.y);
|
||||
}
|
||||
|
||||
function getMenuData() {
|
||||
const editor = CloudCmd.Edit.getEditor();
|
||||
|
||||
return {
|
||||
'Save Ctrl+S' : () => {
|
||||
editor.save();
|
||||
},
|
||||
'Go To Line Ctrl+G' : () => {
|
||||
editor.goToLine();
|
||||
},
|
||||
'Cut Ctrl+X' : () => {
|
||||
editor.cutToClipboard();
|
||||
},
|
||||
'Copy Ctrl+C' : () => {
|
||||
editor.copyToClipboard();
|
||||
},
|
||||
'Paste Ctrl+V' : () => {
|
||||
editor.pasteFromClipboard();
|
||||
},
|
||||
'Delete Del' : () => {
|
||||
editor.remove('right');
|
||||
},
|
||||
'Select All Ctrl+A' : () => {
|
||||
editor.selectAll();
|
||||
},
|
||||
'Beautify Ctrl+B' : () => {
|
||||
editor.beautify();
|
||||
},
|
||||
'Minify Ctrl+M' : () => {
|
||||
editor.minify();
|
||||
},
|
||||
'Close Esc' : () => {
|
||||
hide();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function setMsgChanged(name) {
|
||||
MSG_CHANGED = 'Do you want to save changes to ' + name + '?';
|
||||
}
|
||||
|
||||
module.exports.isChanged = isChanged;
|
||||
|
||||
function isChanged() {
|
||||
const editor = CloudCmd.Edit.getEditor();
|
||||
const is = editor.isChanged();
|
||||
|
||||
if (!is)
|
||||
return;
|
||||
|
||||
const cancel = false;
|
||||
Dialog.confirm(TITLE, MSG_CHANGED, {cancel})
|
||||
.then(() => {
|
||||
editor.save();
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,137 +2,122 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
const exec = require('execon');
|
||||
const currify = require('currify/legacy');
|
||||
const {promisify} = require('es6-promisify');
|
||||
|
||||
const load = require('../dom/load');
|
||||
|
||||
const {MAX_FILE_SIZE: maxSize} = require('../../common/cloudfunc');
|
||||
const {time, timeEnd} = require('../../common/util');
|
||||
|
||||
CloudCmd.Edit = EditProto;
|
||||
const Name = 'Edit';
|
||||
const EditorName = CloudCmd.config('editor');
|
||||
|
||||
function EditProto(callback) {
|
||||
const Name = 'Edit';
|
||||
const EditorName = CloudCmd.config('editor');
|
||||
const loadFiles = currify(_loadFiles);
|
||||
|
||||
let Loading = true;
|
||||
let Element;
|
||||
let editor;
|
||||
|
||||
const ConfigView = {
|
||||
afterShow: () => {
|
||||
editor
|
||||
.moveCursorTo(0, 0)
|
||||
.focus();
|
||||
}
|
||||
};
|
||||
|
||||
const Edit = exec.bind();
|
||||
|
||||
function init(callback) {
|
||||
const element = createElement();
|
||||
|
||||
exec.series([
|
||||
CloudCmd.View,
|
||||
loadFiles(element)
|
||||
], callback);
|
||||
let Loading = true;
|
||||
let Element;
|
||||
let editor;
|
||||
|
||||
const ConfigView = {
|
||||
afterShow: () => {
|
||||
editor
|
||||
.moveCursorTo(0, 0)
|
||||
.focus();
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.init = async () => {
|
||||
const element = createElement();
|
||||
|
||||
function createElement() {
|
||||
const element = load({
|
||||
name: 'div',
|
||||
style:
|
||||
'width : 100%;' +
|
||||
'height : 100%;' +
|
||||
'font-family: "Droid Sans Mono";' +
|
||||
'position : absolute;',
|
||||
notAppend: true
|
||||
});
|
||||
|
||||
Element = element;
|
||||
|
||||
return element;
|
||||
}
|
||||
await CloudCmd.View();
|
||||
await loadFiles(element);
|
||||
};
|
||||
|
||||
function createElement() {
|
||||
const element = load({
|
||||
name: 'div',
|
||||
style:
|
||||
'width : 100%;' +
|
||||
'height : 100%;' +
|
||||
'font-family: "Droid Sans Mono";' +
|
||||
'position : absolute;',
|
||||
notAppend: true
|
||||
});
|
||||
|
||||
function checkFn(name, fn) {
|
||||
if (typeof fn !== 'function')
|
||||
throw Error(name + ' should be a function!');
|
||||
}
|
||||
Element = element;
|
||||
|
||||
function initConfig(options = {}) {
|
||||
const config = Object.assign({}, options, ConfigView);
|
||||
|
||||
if (!options.afterShow)
|
||||
return config;
|
||||
|
||||
checkFn('options.afterShow', options.afterShow);
|
||||
|
||||
const afterShow = {config};
|
||||
|
||||
config.afterShow = () => {
|
||||
afterShow();
|
||||
options.afterShow();
|
||||
};
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
Edit.show = (options) => {
|
||||
if (Loading)
|
||||
return;
|
||||
|
||||
CloudCmd.View.show(Element, initConfig(options));
|
||||
|
||||
Edit.getEditor()
|
||||
.setOptions({
|
||||
fontSize: 16,
|
||||
});
|
||||
|
||||
return Edit;
|
||||
};
|
||||
|
||||
Edit.getEditor = () => {
|
||||
return editor;
|
||||
};
|
||||
|
||||
Edit.getElement = () => {
|
||||
return Element;
|
||||
};
|
||||
|
||||
Edit.hide = () => {
|
||||
CloudCmd.View.hide();
|
||||
return Edit;
|
||||
};
|
||||
|
||||
function _loadFiles(element, callback) {
|
||||
const socketPath = CloudCmd.PREFIX;
|
||||
const prefix = socketPath + '/' + EditorName;
|
||||
const url = prefix + '/' + EditorName + '.js';
|
||||
|
||||
time(Name + ' load');
|
||||
|
||||
load.js(url, () => {
|
||||
const word = window[EditorName];
|
||||
const options = {
|
||||
maxSize,
|
||||
prefix,
|
||||
socketPath,
|
||||
};
|
||||
|
||||
word(element, options, (ed) => {
|
||||
timeEnd(Name + ' load');
|
||||
editor = ed;
|
||||
Loading = false;
|
||||
|
||||
exec(callback);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
init(callback);
|
||||
|
||||
return Edit;
|
||||
return element;
|
||||
}
|
||||
|
||||
function checkFn(name, fn) {
|
||||
if (typeof fn !== 'function')
|
||||
throw Error(name + ' should be a function!');
|
||||
}
|
||||
|
||||
function initConfig(options = {}) {
|
||||
const config = Object.assign({}, options, ConfigView);
|
||||
|
||||
if (!options.afterShow)
|
||||
return config;
|
||||
|
||||
checkFn('options.afterShow', options.afterShow);
|
||||
|
||||
const afterShow = {config};
|
||||
|
||||
config.afterShow = () => {
|
||||
afterShow();
|
||||
options.afterShow();
|
||||
};
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
module.exports.show = (options) => {
|
||||
if (Loading)
|
||||
return;
|
||||
|
||||
CloudCmd.View.show(Element, initConfig(options));
|
||||
|
||||
getEditor()
|
||||
.setOptions({
|
||||
fontSize: 16,
|
||||
});
|
||||
};
|
||||
|
||||
module.exports.getEditor = getEditor;
|
||||
|
||||
function getEditor() {
|
||||
return editor;
|
||||
}
|
||||
|
||||
module.exports.getElement = () => {
|
||||
return Element;
|
||||
};
|
||||
|
||||
module.exports.hide = () => {
|
||||
CloudCmd.View.hide();
|
||||
};
|
||||
|
||||
const loadFiles = promisify((element, callback) => {
|
||||
const socketPath = CloudCmd.PREFIX;
|
||||
const prefix = socketPath + '/' + EditorName;
|
||||
const url = prefix + '/' + EditorName + '.js';
|
||||
|
||||
time(Name + ' load');
|
||||
|
||||
load.js(url, () => {
|
||||
const word = window[EditorName];
|
||||
const options = {
|
||||
maxSize,
|
||||
prefix,
|
||||
socketPath,
|
||||
};
|
||||
|
||||
word(element, options, (ed) => {
|
||||
timeEnd(Name + ' load');
|
||||
editor = ed;
|
||||
Loading = false;
|
||||
|
||||
callback();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -2,16 +2,11 @@
|
|||
|
||||
/* global CloudCmd */
|
||||
|
||||
CloudCmd.Help = HelpProto;
|
||||
|
||||
const Images = require('../dom/images');
|
||||
|
||||
function HelpProto() {
|
||||
module.exports.init = () => {
|
||||
Images.show.load('top');
|
||||
show();
|
||||
|
||||
return exports;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.show = show;
|
||||
module.exports.hide = hide;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
/* global Console */
|
||||
|
||||
const exec = require('execon');
|
||||
const {promisify} = require('es6-promisify');
|
||||
const currify = require('currify/legacy');
|
||||
const Images = require('../dom/images');
|
||||
const {
|
||||
|
|
@ -15,144 +16,130 @@ const {
|
|||
|
||||
const rmLastSlash = (a) => a.replace(/\/$/, '') || '/';
|
||||
|
||||
CloudCmd.Konsole = ConsoleProto;
|
||||
let konsole;
|
||||
const {config} = CloudCmd;
|
||||
|
||||
function ConsoleProto() {
|
||||
let konsole;
|
||||
const {config} = CloudCmd;
|
||||
const cd = currify((fn, dir) => fn(`cd ${rmLastSlash(dir)}`));
|
||||
|
||||
const Name = 'Konsole';
|
||||
const TITLE = 'Console';
|
||||
|
||||
let Element;
|
||||
let Loaded;
|
||||
|
||||
module.exports.init = async () => {
|
||||
Images.show.load('top');
|
||||
|
||||
const noop = () => {};
|
||||
const cd = currify((fn, dir) => fn(`cd ${rmLastSlash(dir)}`));
|
||||
|
||||
if (!config('console'))
|
||||
return {
|
||||
show: noop
|
||||
};
|
||||
|
||||
const Name = 'Konsole';
|
||||
const TITLE = 'Console';
|
||||
|
||||
let Element;
|
||||
let Loaded;
|
||||
|
||||
const Konsole = this;
|
||||
|
||||
function init() {
|
||||
Images.show.load('top');
|
||||
|
||||
exec.series([
|
||||
CloudCmd.View,
|
||||
load,
|
||||
create,
|
||||
Konsole.show,
|
||||
]);
|
||||
|
||||
Element = DOM.load({
|
||||
name : 'div',
|
||||
className : 'console'
|
||||
});
|
||||
}
|
||||
|
||||
this.hide = () => {
|
||||
CloudCmd.View.hide();
|
||||
};
|
||||
|
||||
this.clear = () => {
|
||||
konsole.clear();
|
||||
};
|
||||
|
||||
function getPrefix() {
|
||||
return CloudCmd.PREFIX + '/console';
|
||||
}
|
||||
|
||||
function getEnv() {
|
||||
return {
|
||||
ACTIVE_DIR: DOM.getCurrentDirPath.bind(DOM),
|
||||
PASSIVE_DIR: DOM.getNotCurrentDirPath.bind(DOM),
|
||||
CURRENT_NAME: DOM.getCurrentName.bind(DOM),
|
||||
CURRENT_PATH: () => {
|
||||
return Info.path;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function onPath(path) {
|
||||
if (Info.dirPath === path)
|
||||
return;
|
||||
|
||||
CloudCmd.loadDir({
|
||||
path,
|
||||
});
|
||||
}
|
||||
|
||||
const getDirPath = () => {
|
||||
if (config('syncConsolePath'))
|
||||
return Info.dirPath;
|
||||
};
|
||||
|
||||
function create(callback) {
|
||||
const options = {
|
||||
cwd: getDirPath(),
|
||||
env: getEnv(),
|
||||
prefix: getPrefix(),
|
||||
socketPath: CloudCmd.PREFIX,
|
||||
};
|
||||
|
||||
konsole = Console(Element, options, (spawn) => {
|
||||
spawn.on('connect', exec.with(authCheck, spawn));
|
||||
spawn.on('path', config.if('syncConsolePath', onPath));
|
||||
|
||||
CloudCmd.on('active-dir', config.if('syncConsolePath', cd(spawn.handler)));
|
||||
|
||||
exec(callback);
|
||||
});
|
||||
|
||||
konsole.addShortCuts({
|
||||
'P': () => {
|
||||
const command = konsole.getPromptText();
|
||||
const path = DOM.getCurrentDirPath();
|
||||
|
||||
konsole.setPromptText(command + path);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function authCheck(spawn) {
|
||||
spawn.emit('auth', config('username'), config('password'));
|
||||
|
||||
spawn.on('reject', () => {
|
||||
Dialog.alert(TITLE, 'Wrong credentials!');
|
||||
});
|
||||
}
|
||||
|
||||
this.show = (callback) => {
|
||||
if (!Loaded)
|
||||
return;
|
||||
|
||||
CloudCmd.View.show(Element, {
|
||||
afterShow: () => {
|
||||
konsole.focus();
|
||||
exec(callback);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function load(callback) {
|
||||
const prefix = getPrefix();
|
||||
const url = prefix + '/console.js';
|
||||
|
||||
DOM.load.js(url, (error) => {
|
||||
if (error)
|
||||
return Dialog.alert(TITLE, error.message);
|
||||
|
||||
Loaded = true;
|
||||
Util.timeEnd(Name + ' load');
|
||||
exec(callback);
|
||||
});
|
||||
|
||||
Util.time(Name + ' load');
|
||||
}
|
||||
|
||||
init();
|
||||
await CloudCmd.View();
|
||||
await load();
|
||||
await create();
|
||||
};
|
||||
|
||||
module.exports.hide = () => {
|
||||
CloudCmd.View.hide();
|
||||
};
|
||||
|
||||
module.exports.clear = () => {
|
||||
konsole.clear();
|
||||
};
|
||||
|
||||
function getPrefix() {
|
||||
return CloudCmd.PREFIX + '/console';
|
||||
}
|
||||
|
||||
function getEnv() {
|
||||
return {
|
||||
ACTIVE_DIR: DOM.getCurrentDirPath.bind(DOM),
|
||||
PASSIVE_DIR: DOM.getNotCurrentDirPath.bind(DOM),
|
||||
CURRENT_NAME: DOM.getCurrentName.bind(DOM),
|
||||
CURRENT_PATH: () => {
|
||||
return Info.path;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function onPath(path) {
|
||||
if (Info.dirPath === path)
|
||||
return;
|
||||
|
||||
CloudCmd.loadDir({
|
||||
path,
|
||||
});
|
||||
}
|
||||
|
||||
const getDirPath = () => {
|
||||
if (config('syncConsolePath'))
|
||||
return Info.dirPath;
|
||||
};
|
||||
|
||||
const create = promisify((callback) => {
|
||||
const options = {
|
||||
cwd: getDirPath(),
|
||||
env: getEnv(),
|
||||
prefix: getPrefix(),
|
||||
socketPath: CloudCmd.PREFIX,
|
||||
};
|
||||
|
||||
Element = DOM.load({
|
||||
name : 'div',
|
||||
className : 'console'
|
||||
});
|
||||
|
||||
konsole = Console(Element, options, (spawn) => {
|
||||
spawn.on('connect', exec.with(authCheck, spawn));
|
||||
spawn.on('path', config.if('syncConsolePath', onPath));
|
||||
|
||||
CloudCmd.on('active-dir', config.if('syncConsolePath', cd(spawn.handler)));
|
||||
|
||||
exec(callback);
|
||||
});
|
||||
|
||||
konsole.addShortCuts({
|
||||
'P': () => {
|
||||
const command = konsole.getPromptText();
|
||||
const path = DOM.getCurrentDirPath();
|
||||
|
||||
konsole.setPromptText(command + path);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function authCheck(spawn) {
|
||||
spawn.emit('auth', config('username'), config('password'));
|
||||
|
||||
spawn.on('reject', () => {
|
||||
Dialog.alert(TITLE, 'Wrong credentials!');
|
||||
});
|
||||
}
|
||||
|
||||
module.exports.show = (callback) => {
|
||||
if (!Loaded)
|
||||
return;
|
||||
|
||||
if (!config('console'))
|
||||
return;
|
||||
|
||||
CloudCmd.View.show(Element, {
|
||||
afterShow: () => {
|
||||
konsole.focus();
|
||||
exec(callback);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const load = promisify((callback) => {
|
||||
const prefix = getPrefix();
|
||||
const url = prefix + '/console.js';
|
||||
|
||||
DOM.load.js(url, (error) => {
|
||||
if (error)
|
||||
return Dialog.alert(TITLE, error.message);
|
||||
|
||||
Loaded = true;
|
||||
Util.timeEnd(Name + ' load');
|
||||
exec(callback);
|
||||
});
|
||||
|
||||
Util.time(Name + ' load');
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -2,24 +2,14 @@
|
|||
|
||||
/*global CloudCmd */
|
||||
|
||||
CloudCmd.Markdown = MarkdownProto;
|
||||
|
||||
const exec = require('execon');
|
||||
|
||||
const Images = require('../dom/images');
|
||||
const load = require('../dom/load');
|
||||
const {Markdown} = require('../dom/rest');
|
||||
|
||||
function MarkdownProto(name, options) {
|
||||
module.exports.init = async () => {
|
||||
Images.show.load('top');
|
||||
|
||||
exec.series([
|
||||
CloudCmd.View,
|
||||
exec.with(show, name, options),
|
||||
]);
|
||||
|
||||
return module.exports;
|
||||
}
|
||||
await CloudCmd.View();
|
||||
};
|
||||
|
||||
module.exports.show = show;
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
CloudCmd.Menu = MenuProto;
|
||||
|
||||
const exec = require('execon');
|
||||
const wrap = require('wraptile/legacy');
|
||||
const supermenu = require('supermenu');
|
||||
|
|
@ -12,324 +10,320 @@ const {FS} = require('../../common/cloudfunc');
|
|||
const load = require('../dom/load');
|
||||
const RESTful = require('../dom/rest');
|
||||
|
||||
function MenuProto(position) {
|
||||
const config = CloudCmd.config;
|
||||
const Buffer = DOM.Buffer;
|
||||
const Info = DOM.CurrentInfo;
|
||||
const Key = CloudCmd.Key;
|
||||
const Events = DOM.Events;
|
||||
const Dialog = DOM.Dialog;
|
||||
const Images = DOM.Images;
|
||||
const Menu = this;
|
||||
const TITLE = 'Cloud Commander';
|
||||
const alertNoFiles = wrap(Dialog.alert.noFiles)(TITLE);
|
||||
const uploadTo = wrap(_uploadTo);
|
||||
const config = CloudCmd.config;
|
||||
const Buffer = DOM.Buffer;
|
||||
const Info = DOM.CurrentInfo;
|
||||
const Key = CloudCmd.Key;
|
||||
const Events = DOM.Events;
|
||||
const Dialog = DOM.Dialog;
|
||||
const Images = DOM.Images;
|
||||
const TITLE = 'Cloud Commander';
|
||||
const alertNoFiles = wrap(Dialog.alert.noFiles)(TITLE);
|
||||
const uploadTo = wrap(_uploadTo);
|
||||
|
||||
let MenuShowedName;
|
||||
let MenuContext;
|
||||
let MenuContextFile;
|
||||
|
||||
module.exports.ENABLED = false;
|
||||
|
||||
module.exports.init = () => {
|
||||
const {isAuth, menuDataFile} = getFileMenuData();
|
||||
|
||||
let MenuShowedName;
|
||||
let MenuContext;
|
||||
let MenuContextFile;
|
||||
const NOT_FILE = true;
|
||||
const fm = DOM.getFM();
|
||||
const menuData = getMenuData(isAuth);
|
||||
const options = getOptions(NOT_FILE);
|
||||
const optionsFile = getOptions();
|
||||
|
||||
this.ENABLED = false;
|
||||
MenuContext = supermenu(fm, options, menuData);
|
||||
MenuContextFile = supermenu(fm, optionsFile, menuDataFile);
|
||||
|
||||
function init(position) {
|
||||
const {isAuth, menuDataFile} = getFileMenuData();
|
||||
|
||||
const NOT_FILE = true;
|
||||
const fm = DOM.getFM();
|
||||
const menuData = getMenuData(isAuth);
|
||||
const options = getOptions(NOT_FILE);
|
||||
const optionsFile = getOptions();
|
||||
|
||||
MenuContext = supermenu(fm, options, menuData);
|
||||
MenuContextFile = supermenu(fm, optionsFile, menuDataFile);
|
||||
|
||||
Menu.show(position);
|
||||
Events.addKey(listener);
|
||||
}
|
||||
Events.addKey(listener);
|
||||
};
|
||||
|
||||
module.exports.hide = hide;
|
||||
|
||||
function hide() {
|
||||
MenuContext.hide();
|
||||
MenuContextFile.hide();
|
||||
}
|
||||
|
||||
module.exports.show = (position) => {
|
||||
const {x, y} = getPosition(position);
|
||||
|
||||
this.hide = () => {
|
||||
MenuContext.hide();
|
||||
MenuContextFile.hide();
|
||||
};
|
||||
MenuContext.show(x, y);
|
||||
MenuContextFile.show(x, y);
|
||||
|
||||
this.show = (position) => {
|
||||
const {x, y} = getPosition(position);
|
||||
|
||||
MenuContext.show(x, y);
|
||||
MenuContextFile.show(x, y);
|
||||
|
||||
Images.hide();
|
||||
};
|
||||
|
||||
function getPosition(position) {
|
||||
if (position)
|
||||
return {
|
||||
x: position.x,
|
||||
y: position.y,
|
||||
};
|
||||
|
||||
return getCurrentPosition();
|
||||
}
|
||||
|
||||
function getMenuNameByEl(el) {
|
||||
if (!el)
|
||||
return 'context';
|
||||
|
||||
const name = DOM.getCurrentName(el);
|
||||
|
||||
if (name === '..')
|
||||
return 'context';
|
||||
|
||||
return 'contextFile';
|
||||
}
|
||||
|
||||
function getOptions(notFile) {
|
||||
let name, func;
|
||||
|
||||
if (notFile) {
|
||||
name = 'context';
|
||||
func = Key.unsetBind;
|
||||
} else {
|
||||
name = 'contextFile';
|
||||
}
|
||||
|
||||
const options = {
|
||||
icon : true,
|
||||
beforeClose : Key.setBind,
|
||||
beforeShow : exec.with(beforeShow, func),
|
||||
beforeClick,
|
||||
name,
|
||||
};
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
function getMenuData(isAuth) {
|
||||
const menu = {
|
||||
'Paste': Buffer.paste,
|
||||
'New': {
|
||||
'File': DOM.promptNewFile,
|
||||
'Directory': DOM.promptNewDir
|
||||
},
|
||||
'Upload': () => {
|
||||
CloudCmd.Upload.show();
|
||||
},
|
||||
'Upload From Cloud': uploadFromCloud,
|
||||
'(Un)Select All': DOM.toggleAllSelectedFiles
|
||||
};
|
||||
|
||||
if (isAuth)
|
||||
menu['Log Out'] = CloudCmd.logOut;
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
function getFileMenuData() {
|
||||
const isAuth = CloudCmd.config('auth');
|
||||
const show = wrap((name) => {
|
||||
CloudCmd[name].show();
|
||||
});
|
||||
|
||||
const menuBottom = getMenuData(isAuth);
|
||||
const menuTop = {
|
||||
'View': show('View'),
|
||||
'Edit': show('EditFile'),
|
||||
'Rename': () => {
|
||||
setTimeout(DOM.renameCurrent, 100);
|
||||
},
|
||||
'Delete': () => {
|
||||
CloudCmd.Operation.show('delete');
|
||||
},
|
||||
'Pack': () => {
|
||||
CloudCmd.Operation.show('pack');
|
||||
},
|
||||
'Extract': () => {
|
||||
CloudCmd.Operation.show('extract');
|
||||
},
|
||||
'Download': preDownload,
|
||||
'Upload To Cloud': uploadTo('Cloud'),
|
||||
'Cut': () => {
|
||||
isCurrent(Buffer.cut, alertNoFiles);
|
||||
},
|
||||
'Copy': () => {
|
||||
isCurrent(Buffer.copy, alertNoFiles);
|
||||
},
|
||||
};
|
||||
|
||||
const menuDataFile = {
|
||||
...menuTop,
|
||||
...menuBottom,
|
||||
};
|
||||
|
||||
Images.hide();
|
||||
};
|
||||
|
||||
function getPosition(position) {
|
||||
if (position)
|
||||
return {
|
||||
isAuth,
|
||||
menuDataFile,
|
||||
x: position.x,
|
||||
y: position.y,
|
||||
};
|
||||
|
||||
return getCurrentPosition();
|
||||
}
|
||||
|
||||
function getMenuNameByEl(el) {
|
||||
if (!el)
|
||||
return 'context';
|
||||
|
||||
const name = DOM.getCurrentName(el);
|
||||
|
||||
if (name === '..')
|
||||
return 'context';
|
||||
|
||||
return 'contextFile';
|
||||
}
|
||||
|
||||
function getOptions(notFile) {
|
||||
let name, func;
|
||||
|
||||
if (notFile) {
|
||||
name = 'context';
|
||||
func = Key.unsetBind;
|
||||
} else {
|
||||
name = 'contextFile';
|
||||
}
|
||||
|
||||
function isCurrent(yesFn, noFn) {
|
||||
if (Info.name !== '..')
|
||||
return yesFn();
|
||||
|
||||
noFn();
|
||||
const options = {
|
||||
icon : true,
|
||||
beforeClose : Key.setBind,
|
||||
beforeShow : exec.with(beforeShow, func),
|
||||
beforeClick,
|
||||
name,
|
||||
};
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
function getMenuData(isAuth) {
|
||||
const menu = {
|
||||
'Paste': Buffer.paste,
|
||||
'New': {
|
||||
'File': DOM.promptNewFile,
|
||||
'Directory': DOM.promptNewDir
|
||||
},
|
||||
'Upload': () => {
|
||||
CloudCmd.Upload.show();
|
||||
},
|
||||
'Upload From Cloud': uploadFromCloud,
|
||||
'(Un)Select All': DOM.toggleAllSelectedFiles
|
||||
};
|
||||
|
||||
if (isAuth)
|
||||
menu['Log Out'] = CloudCmd.logOut;
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
function getFileMenuData() {
|
||||
const isAuth = CloudCmd.config('auth');
|
||||
const show = wrap((name) => {
|
||||
CloudCmd[name].show();
|
||||
});
|
||||
|
||||
const menuBottom = getMenuData(isAuth);
|
||||
const menuTop = {
|
||||
'View': show('View'),
|
||||
'Edit': show('EditFile'),
|
||||
'Rename': () => {
|
||||
setTimeout(DOM.renameCurrent, 100);
|
||||
},
|
||||
'Delete': () => {
|
||||
CloudCmd.Operation.show('delete');
|
||||
},
|
||||
'Pack': () => {
|
||||
CloudCmd.Operation.show('pack');
|
||||
},
|
||||
'Extract': () => {
|
||||
CloudCmd.Operation.show('extract');
|
||||
},
|
||||
'Download': preDownload,
|
||||
'Upload To Cloud': uploadTo('Cloud'),
|
||||
'Cut': () => {
|
||||
isCurrent(Buffer.cut, alertNoFiles);
|
||||
},
|
||||
'Copy': () => {
|
||||
isCurrent(Buffer.copy, alertNoFiles);
|
||||
},
|
||||
};
|
||||
|
||||
const menuDataFile = {
|
||||
...menuTop,
|
||||
...menuBottom,
|
||||
};
|
||||
|
||||
return {
|
||||
isAuth,
|
||||
menuDataFile,
|
||||
};
|
||||
}
|
||||
|
||||
function isCurrent(yesFn, noFn) {
|
||||
if (Info.name !== '..')
|
||||
return yesFn();
|
||||
|
||||
noFn();
|
||||
}
|
||||
|
||||
function isPath(x, y) {
|
||||
const {panel} = Info;
|
||||
const isEmptyRoot = !panel;
|
||||
|
||||
if (isEmptyRoot)
|
||||
return false;
|
||||
|
||||
const el = document.elementFromPoint(x, y);
|
||||
const elements = panel.querySelectorAll('[data-name="js-path"] *');
|
||||
const is = ~[].indexOf.call(elements, el);
|
||||
|
||||
return is;
|
||||
}
|
||||
|
||||
function beforeShow(callback, params) {
|
||||
const name = params.name;
|
||||
let el = DOM.getCurrentByPosition({
|
||||
x: params.x,
|
||||
y: params.y
|
||||
});
|
||||
|
||||
const menuName = getMenuNameByEl(el);
|
||||
let notShow = menuName === 'contextFile';
|
||||
|
||||
if (params.name === 'contextFile') {
|
||||
notShow = !notShow;
|
||||
}
|
||||
|
||||
function isPath(x, y) {
|
||||
const {panel} = Info;
|
||||
const isEmptyRoot = !panel;
|
||||
|
||||
if (isEmptyRoot)
|
||||
return false;
|
||||
|
||||
const el = document.elementFromPoint(x, y);
|
||||
const elements = panel.querySelectorAll('[data-name="js-path"] *');
|
||||
const is = ~[].indexOf.call(elements, el);
|
||||
|
||||
return is;
|
||||
}
|
||||
if (!notShow)
|
||||
MenuShowedName = name;
|
||||
|
||||
function beforeShow(callback, params) {
|
||||
const name = params.name;
|
||||
let el = DOM.getCurrentByPosition({
|
||||
x: params.x,
|
||||
y: params.y
|
||||
});
|
||||
|
||||
const menuName = getMenuNameByEl(el);
|
||||
let notShow = menuName === 'contextFile';
|
||||
|
||||
if (params.name === 'contextFile') {
|
||||
notShow = !notShow;
|
||||
}
|
||||
|
||||
if (!notShow)
|
||||
MenuShowedName = name;
|
||||
|
||||
exec(callback);
|
||||
|
||||
if (!notShow)
|
||||
notShow = isPath(params.x, params.y);
|
||||
|
||||
return notShow;
|
||||
}
|
||||
exec(callback);
|
||||
|
||||
function beforeClick(name) {
|
||||
return MenuShowedName !== name;
|
||||
}
|
||||
if (!notShow)
|
||||
notShow = isPath(params.x, params.y);
|
||||
|
||||
function _uploadTo(nameModule) {
|
||||
Info.getData((error, data) => {
|
||||
if (error)
|
||||
return;
|
||||
|
||||
const name = Info.name;
|
||||
const execFrom = CloudCmd.execFromModule;
|
||||
|
||||
execFrom(nameModule, 'uploadFile', name, data);
|
||||
});
|
||||
|
||||
CloudCmd.log('Uploading to ' + name + '...');
|
||||
}
|
||||
|
||||
function uploadFromCloud() {
|
||||
Images.show.load('top');
|
||||
|
||||
CloudCmd.execFromModule('Cloud', 'saveFile', (currentName, data) => {
|
||||
const path = DOM.getCurrentDirPath() + currentName;
|
||||
|
||||
RESTful.write(path, data, (error) => {
|
||||
if (error)
|
||||
return;
|
||||
|
||||
CloudCmd.refresh({currentName});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function preDownload() {
|
||||
download(config('packer'));
|
||||
}
|
||||
|
||||
function download(type) {
|
||||
const TIME = 30 * 1000;
|
||||
const prefixUr = CloudCmd.PREFIX_URL;
|
||||
const PACK = '/pack';
|
||||
const date = Date.now();
|
||||
const files = DOM.getActiveFiles();
|
||||
|
||||
if (!files.length)
|
||||
return alertNoFiles();
|
||||
|
||||
files.forEach((file) => {
|
||||
const selected = DOM.isSelected(file);
|
||||
const isDir = DOM.isCurrentIsDir(file);
|
||||
const path = DOM.getCurrentPath(file);
|
||||
|
||||
CloudCmd.log('downloading file ' + path + '...');
|
||||
/*
|
||||
* if we send ajax request -
|
||||
* no need in hash so we escape #
|
||||
* and all other characters, like "%"
|
||||
*/
|
||||
const encodedPath = encodeURI(path).replace(/#/g, '%23');
|
||||
const id = load.getIdBySrc(path);
|
||||
|
||||
let src;
|
||||
|
||||
if (isDir)
|
||||
src = prefixUr + PACK + encodedPath + DOM.getPackerExt(type);
|
||||
else
|
||||
src = prefixUr + FS + encodedPath + '?download';
|
||||
|
||||
const element = load({
|
||||
id : id + '-' + date,
|
||||
name : 'iframe',
|
||||
async : false,
|
||||
className : 'hidden',
|
||||
src,
|
||||
});
|
||||
|
||||
const {body} = document;
|
||||
const removeChild = body.removeChild.bind(body, element);
|
||||
|
||||
setTimeout(removeChild, TIME);
|
||||
|
||||
if (selected)
|
||||
DOM.toggleSelectedFile(file);
|
||||
});
|
||||
}
|
||||
|
||||
function getCurrentPosition() {
|
||||
const current = Info.element;
|
||||
const rect = current.getBoundingClientRect();
|
||||
|
||||
const position = {
|
||||
x: Math.round(rect.left + rect.width / 3),
|
||||
y: Math.round(rect.top)
|
||||
};
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
function listener(event) {
|
||||
const F9 = Key.F9;
|
||||
const ESC = Key.ESC;
|
||||
const key = event.keyCode;
|
||||
const isBind = Key.isBind();
|
||||
|
||||
if (!isBind)
|
||||
return notShow;
|
||||
}
|
||||
|
||||
function beforeClick(name) {
|
||||
return MenuShowedName !== name;
|
||||
}
|
||||
|
||||
function _uploadTo(nameModule) {
|
||||
Info.getData((error, data) => {
|
||||
if (error)
|
||||
return;
|
||||
|
||||
if (key === ESC)
|
||||
return Menu.hide();
|
||||
|
||||
if (key === F9) {
|
||||
const position = getCurrentPosition();
|
||||
MenuContext.show(position.x, position.y);
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
const name = Info.name;
|
||||
const execFrom = CloudCmd.execFromModule;
|
||||
|
||||
execFrom(nameModule, 'uploadFile', name, data);
|
||||
});
|
||||
|
||||
init(position);
|
||||
CloudCmd.log('Uploading to ' + name + '...');
|
||||
}
|
||||
|
||||
function uploadFromCloud() {
|
||||
Images.show.load('top');
|
||||
|
||||
CloudCmd.execFromModule('Cloud', 'saveFile', (currentName, data) => {
|
||||
const path = DOM.getCurrentDirPath() + currentName;
|
||||
|
||||
RESTful.write(path, data, (error) => {
|
||||
if (error)
|
||||
return;
|
||||
|
||||
CloudCmd.refresh({currentName});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function preDownload() {
|
||||
download(config('packer'));
|
||||
}
|
||||
|
||||
function download(type) {
|
||||
const TIME = 30 * 1000;
|
||||
const prefixUr = CloudCmd.PREFIX_URL;
|
||||
const PACK = '/pack';
|
||||
const date = Date.now();
|
||||
const files = DOM.getActiveFiles();
|
||||
|
||||
if (!files.length)
|
||||
return alertNoFiles();
|
||||
|
||||
files.forEach((file) => {
|
||||
const selected = DOM.isSelected(file);
|
||||
const isDir = DOM.isCurrentIsDir(file);
|
||||
const path = DOM.getCurrentPath(file);
|
||||
|
||||
CloudCmd.log('downloading file ' + path + '...');
|
||||
/*
|
||||
* if we send ajax request -
|
||||
* no need in hash so we escape #
|
||||
* and all other characters, like "%"
|
||||
*/
|
||||
const encodedPath = encodeURI(path).replace(/#/g, '%23');
|
||||
const id = load.getIdBySrc(path);
|
||||
|
||||
let src;
|
||||
|
||||
if (isDir)
|
||||
src = prefixUr + PACK + encodedPath + DOM.getPackerExt(type);
|
||||
else
|
||||
src = prefixUr + FS + encodedPath + '?download';
|
||||
|
||||
const element = load({
|
||||
id : id + '-' + date,
|
||||
name : 'iframe',
|
||||
async : false,
|
||||
className : 'hidden',
|
||||
src,
|
||||
});
|
||||
|
||||
const {body} = document;
|
||||
const removeChild = body.removeChild.bind(body, element);
|
||||
|
||||
setTimeout(removeChild, TIME);
|
||||
|
||||
if (selected)
|
||||
DOM.toggleSelectedFile(file);
|
||||
});
|
||||
}
|
||||
|
||||
function getCurrentPosition() {
|
||||
const current = Info.element;
|
||||
const rect = current.getBoundingClientRect();
|
||||
|
||||
const position = {
|
||||
x: Math.round(rect.left + rect.width / 3),
|
||||
y: Math.round(rect.top)
|
||||
};
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
function listener(event) {
|
||||
const F9 = Key.F9;
|
||||
const ESC = Key.ESC;
|
||||
const key = event.keyCode;
|
||||
const isBind = Key.isBind();
|
||||
|
||||
if (!isBind)
|
||||
return;
|
||||
|
||||
if (key === ESC)
|
||||
return hide();
|
||||
|
||||
if (key === F9) {
|
||||
const position = getCurrentPosition();
|
||||
MenuContext.show(position.x, position.y);
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
const test = require('tape');
|
||||
const getNextCurrentName = require('./get-next-current-name');
|
||||
|
||||
test('get-next-current-name', (t) => {
|
||||
const names = [
|
||||
'..',
|
||||
'hello',
|
||||
'1',
|
||||
'2',
|
||||
];
|
||||
|
||||
const removedNames = [
|
||||
'1'
|
||||
];
|
||||
|
||||
const name = getNextCurrentName('hello', names, removedNames);
|
||||
|
||||
t.equal(name, 'hello', 'should equal');
|
||||
t.end();
|
||||
});
|
||||
|
||||
test('get-next-current-name: all files removed', (t) => {
|
||||
const names = [
|
||||
'..',
|
||||
'hello',
|
||||
'1',
|
||||
'2',
|
||||
];
|
||||
|
||||
const removedNames = [
|
||||
'1',
|
||||
'2',
|
||||
'hello',
|
||||
];
|
||||
|
||||
const name = getNextCurrentName('2', names, removedNames);
|
||||
|
||||
t.equal(name, '..', 'should equal');
|
||||
t.end();
|
||||
});
|
||||
|
||||
|
|
@ -5,10 +5,10 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
CloudCmd.Operation = OperationProto;
|
||||
|
||||
const currify = require('currify/legacy');
|
||||
const wraptile = require('wraptile/legacy');
|
||||
const {promisify} = require('es6-promisify');
|
||||
const exec = require('execon');
|
||||
|
||||
const {
|
||||
|
|
@ -22,455 +22,453 @@ const getNextCurrentName = require('./get-next-current-name');
|
|||
|
||||
const removeQuery = (a) => a.replace(/\?.*/, '');
|
||||
|
||||
function OperationProto(operation, data) {
|
||||
const Name = 'Operation';
|
||||
const {
|
||||
TITLE,
|
||||
config,
|
||||
} = CloudCmd;
|
||||
const {Dialog, Images} = DOM;
|
||||
const initOperations = wraptile(_initOperations);
|
||||
const authCheck = wraptile(_authCheck);
|
||||
const Name = 'Operation';
|
||||
const {
|
||||
TITLE,
|
||||
config,
|
||||
} = CloudCmd;
|
||||
const {Dialog, Images} = DOM;
|
||||
const initOperations = wraptile(_initOperations);
|
||||
const authCheck = wraptile(_authCheck);
|
||||
|
||||
const Operation = {};
|
||||
|
||||
let Loaded;
|
||||
|
||||
let {
|
||||
cp: copyFn,
|
||||
mv: moveFn,
|
||||
delete: deleteFn,
|
||||
extract: extractFn,
|
||||
} = RESTful;
|
||||
|
||||
let packZipFn = RESTful.pack;
|
||||
let packTarFn = RESTful.pack;
|
||||
|
||||
const Info = DOM.CurrentInfo;
|
||||
const showLoad = Images.show.load.bind(null, 'top');
|
||||
|
||||
const processFiles = currify(_processFiles);
|
||||
|
||||
const noFilesCheck = () => {
|
||||
const {length} = DOM.getActiveFiles();
|
||||
const is = Boolean(!length);
|
||||
|
||||
let Loaded;
|
||||
if (is)
|
||||
return Dialog.alert.noFiles(TITLE);
|
||||
|
||||
let {
|
||||
cp: copyFn,
|
||||
mv: moveFn,
|
||||
delete: deleteFn,
|
||||
extract: extractFn,
|
||||
} = RESTful;
|
||||
return is;
|
||||
};
|
||||
|
||||
let packZipFn = RESTful.pack;
|
||||
let packTarFn = RESTful.pack;
|
||||
module.exports.init = promisify((callback) => {
|
||||
showLoad();
|
||||
|
||||
const Info = DOM.CurrentInfo;
|
||||
const showLoad = Images.show.load.bind(null, 'top');
|
||||
const Operation = this;
|
||||
const processFiles = currify(_processFiles);
|
||||
|
||||
const noFilesCheck = () => {
|
||||
const {length} = DOM.getActiveFiles();
|
||||
const is = Boolean(!length);
|
||||
|
||||
if (is)
|
||||
return Dialog.alert.noFiles(TITLE);
|
||||
|
||||
return is;
|
||||
};
|
||||
|
||||
function init() {
|
||||
showLoad();
|
||||
|
||||
exec.series([
|
||||
DOM.loadSocket,
|
||||
(callback) => {
|
||||
if (!config('progress'))
|
||||
return callback();
|
||||
|
||||
load(initOperations(CloudCmd.PREFIX, callback));
|
||||
},
|
||||
() => {
|
||||
Loaded = true;
|
||||
Images.hide();
|
||||
Operation.show(operation, data);
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
function _authCheck(spawn, ok) {
|
||||
const accept = wraptile(ok);
|
||||
const alertDialog = wraptile(Dialog.alert);
|
||||
|
||||
spawn.on('accept', accept(spawn));
|
||||
spawn.on('reject', alertDialog (TITLE, 'Wrong credentials!'));
|
||||
spawn.emit('auth', config('username'), config('password'));
|
||||
}
|
||||
|
||||
function _initOperations(socketPrefix, fn) {
|
||||
const prefix = `${socketPrefix}/fileop`;
|
||||
fileop({prefix, socketPrefix}, (e, operator) => {
|
||||
fn();
|
||||
|
||||
operator.on('connect', authCheck(operator, onConnect));
|
||||
operator.on('disconnect', onDisconnect);
|
||||
});
|
||||
}
|
||||
|
||||
function onConnect(operator) {
|
||||
packTarFn = (data, callback) => {
|
||||
operator.tar(data.from, data.to, data.names)
|
||||
.then(setListeners({noContinue: true}, callback));
|
||||
};
|
||||
|
||||
packZipFn = (data, callback) => {
|
||||
operator.zip(data.from, data.to, data.names)
|
||||
.then(setListeners({noContinue: true}, callback));
|
||||
};
|
||||
|
||||
deleteFn = (from, files, callback) => {
|
||||
from = removeQuery(from);
|
||||
operator.remove(from, files)
|
||||
.then(setListeners(callback));
|
||||
};
|
||||
|
||||
copyFn = (data, callback) => {
|
||||
operator.copy(data.from, data.to, data.names)
|
||||
.then(setListeners(callback));
|
||||
};
|
||||
|
||||
moveFn = (data, callback) => {
|
||||
operator.move(data.from, data.to, data.names)
|
||||
.then(setListeners(callback));
|
||||
};
|
||||
|
||||
extractFn = (data, callback) => {
|
||||
operator.extract(data.from, data.to)
|
||||
.then(setListeners({noContinue: true}, callback));
|
||||
};
|
||||
}
|
||||
|
||||
function onDisconnect() {
|
||||
packZipFn = RESTful.pack;
|
||||
packTarFn = RESTful.pack;
|
||||
deleteFn = RESTful.delete;
|
||||
copyFn = RESTful.cp;
|
||||
moveFn = RESTful.mv;
|
||||
extractFn = RESTful.extract;
|
||||
}
|
||||
|
||||
function getPacker(type) {
|
||||
if (type === 'zip')
|
||||
return packZipFn;
|
||||
|
||||
return packTarFn;
|
||||
}
|
||||
|
||||
this.hide = () => {
|
||||
CloudCmd.View.hide();
|
||||
};
|
||||
|
||||
this.show = (operation, data) => {
|
||||
if (!Loaded)
|
||||
return;
|
||||
|
||||
if (operation === 'copy')
|
||||
return Operation.copy(data);
|
||||
|
||||
if (operation === 'move')
|
||||
return Operation.move(data);
|
||||
|
||||
if (operation === 'delete')
|
||||
return Operation.delete();
|
||||
|
||||
if (operation === 'delete:silent')
|
||||
return Operation.deleteSilent();
|
||||
|
||||
if (operation === 'pack')
|
||||
return Operation.pack();
|
||||
|
||||
if (operation === 'extract')
|
||||
return Operation.extract();
|
||||
};
|
||||
|
||||
this.copy = processFiles({
|
||||
type: 'copy',
|
||||
});
|
||||
|
||||
this.move = processFiles({
|
||||
type: 'move'
|
||||
});
|
||||
|
||||
this.delete = () => {
|
||||
promptDelete();
|
||||
};
|
||||
|
||||
this.deleteSilent = () => {
|
||||
deleteSilent();
|
||||
};
|
||||
|
||||
this.pack = () => {
|
||||
const isZip = config('packer') === 'zip';
|
||||
twopack('pack', isZip ? 'zip' : 'tar');
|
||||
};
|
||||
|
||||
this.extract = () => {
|
||||
twopack('extract');
|
||||
};
|
||||
|
||||
/**
|
||||
* prompt and delete current file or selected files
|
||||
*
|
||||
* @currentFile
|
||||
*/
|
||||
function promptDelete() {
|
||||
if (noFilesCheck())
|
||||
return;
|
||||
|
||||
const msgAsk = 'Do you really want to delete the ';
|
||||
const msgSel = 'selected ';
|
||||
|
||||
const files = DOM.getActiveFiles();
|
||||
const names = DOM.getFilenames(files);
|
||||
const n = names.length;
|
||||
|
||||
let msg;
|
||||
if (n) {
|
||||
let name = '';
|
||||
|
||||
for (let i = 0; i < 5 && i < n; i++)
|
||||
name += '\n' + names[i];
|
||||
|
||||
if (n >= 5)
|
||||
name += '\n...';
|
||||
|
||||
msg = msgAsk + msgSel + n + ' files/directories?\n' + encode(name);
|
||||
} else {
|
||||
const current = DOM.getCurrentFile();
|
||||
const isDir = DOM.isCurrentIsDir(current);
|
||||
const getType = (isDir) => {
|
||||
return isDir ? 'directory' : 'file';
|
||||
};
|
||||
|
||||
const type = getType(isDir) + ' ';
|
||||
|
||||
const name = DOM.getCurrentName(current);
|
||||
msg = msgAsk + msgSel + type + name + '?';
|
||||
}
|
||||
|
||||
const cancel = false;
|
||||
|
||||
Dialog.confirm(TITLE, msg, {cancel}).then(() => {
|
||||
deleteSilent(files);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* delete current or selected files
|
||||
*
|
||||
* @files
|
||||
*/
|
||||
function deleteSilent(files = DOM.getActiveFiles()) {
|
||||
const query = '?files';
|
||||
const path = Info.dirPath;
|
||||
|
||||
if (noFilesCheck())
|
||||
return;
|
||||
|
||||
showLoad();
|
||||
|
||||
const removedNames = DOM.getFilenames(files);
|
||||
const names = DOM.CurrentInfo.files.map(DOM.getCurrentName);
|
||||
const prevCurrent = DOM.getCurrentName();
|
||||
const currentName = getNextCurrentName(prevCurrent, names, removedNames);
|
||||
|
||||
deleteFn(path + query, removedNames, (e) => {
|
||||
const Storage = DOM.Storage;
|
||||
const dirPath = Info.dirPath;
|
||||
|
||||
!e && CloudCmd.refresh({
|
||||
currentName
|
||||
});
|
||||
|
||||
Storage.removeMatch(dirPath);
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* process files (copy or move)
|
||||
* @param data
|
||||
* @param operation
|
||||
*/
|
||||
function _processFiles(options, data) {
|
||||
let selFiles, files;
|
||||
let panel;
|
||||
let shouldAsk;
|
||||
let sameName;
|
||||
let ok;
|
||||
|
||||
let from = '';
|
||||
let to = '';
|
||||
|
||||
let names = [];
|
||||
|
||||
if (data) {
|
||||
from = data.from;
|
||||
to = data.to;
|
||||
names = data.names;
|
||||
panel = Info.panel;
|
||||
} else {
|
||||
from = Info.dirPath;
|
||||
to = DOM.getNotCurrentDirPath();
|
||||
selFiles = DOM.getSelectedFiles();
|
||||
names = DOM.getFilenames(selFiles);
|
||||
data = {};
|
||||
shouldAsk = true;
|
||||
panel = Info.panelPassive;
|
||||
}
|
||||
|
||||
if (!names.length)
|
||||
names.push(DOM.getCurrentName());
|
||||
|
||||
const name = names[0];
|
||||
|
||||
sameName = DOM.getCurrentByName(name, panel);
|
||||
|
||||
if (!data && noFilesCheck())
|
||||
return;
|
||||
|
||||
const {type} = options;
|
||||
|
||||
const isCopy = type === 'copy';
|
||||
const option = isCopy ? 'confirmCopy' : 'confirmMove';
|
||||
const title = isCopy ? 'Copy' : 'Rename/Move';
|
||||
const operation = isCopy ? copyFn : moveFn;
|
||||
|
||||
if (shouldAsk && config(option))
|
||||
return message(title, to, names.map(encode))
|
||||
.then(ask);
|
||||
|
||||
ask(to);
|
||||
|
||||
function ask(to) {
|
||||
ok = from !== to && to;
|
||||
|
||||
if (ok && !shouldAsk || !sameName)
|
||||
return go();
|
||||
|
||||
const str = `"${ name }" already exist. Overwrite?`;
|
||||
const cancel = false;
|
||||
|
||||
Dialog.confirm(TITLE, str, {cancel}).then(go);
|
||||
|
||||
function go() {
|
||||
showLoad();
|
||||
|
||||
files = {
|
||||
from,
|
||||
to,
|
||||
names,
|
||||
};
|
||||
|
||||
operation(files, () => {
|
||||
DOM.Storage.remove(from, () => {
|
||||
const {
|
||||
panel,
|
||||
panelPassive,
|
||||
} = Info;
|
||||
|
||||
const setCurrent = () => {
|
||||
const currentName = name || data.names[0];
|
||||
DOM.setCurrentByName(currentName);
|
||||
};
|
||||
|
||||
if (!Info.isOnePanel)
|
||||
CloudCmd.refresh({
|
||||
panel: panelPassive,
|
||||
noCurrent: true,
|
||||
});
|
||||
|
||||
CloudCmd.refresh({panel}, setCurrent);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkEmpty(name, operation) {
|
||||
if (!operation)
|
||||
throw Error(name + ' could not be empty!');
|
||||
}
|
||||
|
||||
function twopack(operation, type) {
|
||||
let op;
|
||||
let fileFrom;
|
||||
let currentName = Info.name;
|
||||
|
||||
const Images = DOM.Images;
|
||||
const path = Info.path;
|
||||
const dirPath = Info.dirPath;
|
||||
const activeFiles = DOM.getActiveFiles();
|
||||
const names = DOM.getFilenames(activeFiles);
|
||||
|
||||
checkEmpty('operation', operation);
|
||||
|
||||
if (!names.length)
|
||||
return Dialog.alert.noFiles(TITLE);
|
||||
|
||||
switch(operation) {
|
||||
case 'extract':
|
||||
op = extractFn;
|
||||
|
||||
fileFrom = {
|
||||
from: path,
|
||||
to: dirPath
|
||||
};
|
||||
|
||||
currentName = removeExtension(currentName);
|
||||
|
||||
break;
|
||||
|
||||
case 'pack':
|
||||
op = getPacker(type);
|
||||
|
||||
if (names.length > 1)
|
||||
currentName = Info.dir;
|
||||
|
||||
currentName += DOM.getPackerExt(type);
|
||||
|
||||
fileFrom = {
|
||||
from: dirPath,
|
||||
to: dirPath + currentName,
|
||||
names,
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
Images.show.load('top');
|
||||
|
||||
op(fileFrom, (error) => {
|
||||
!error && CloudCmd.refresh({
|
||||
currentName
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function message(msg, to, names) {
|
||||
const n = names.length;
|
||||
const name = names[0];
|
||||
|
||||
msg += ' ';
|
||||
|
||||
if (names.length > 1)
|
||||
msg += n + ' file(s)';
|
||||
else
|
||||
msg += '"' + name + '"';
|
||||
|
||||
msg += ' to';
|
||||
|
||||
const cancel = false;
|
||||
|
||||
return Dialog.prompt(TITLE, msg, to, {cancel});
|
||||
}
|
||||
|
||||
function load(callback) {
|
||||
const prefix = CloudCmd.PREFIX;
|
||||
const file = `${prefix}/fileop/fileop.js`;
|
||||
|
||||
DOM.load.js(file, (error) => {
|
||||
if (error) {
|
||||
Dialog.alert(TITLE, error.message);
|
||||
return exec(callback);
|
||||
}
|
||||
exec.series([
|
||||
DOM.loadSocket,
|
||||
(callback) => {
|
||||
if (!config('progress'))
|
||||
return callback();
|
||||
|
||||
load(initOperations(CloudCmd.PREFIX, callback));
|
||||
},
|
||||
(callback) => {
|
||||
Loaded = true;
|
||||
Util.timeEnd(Name + ' load');
|
||||
exec(callback);
|
||||
});
|
||||
|
||||
Util.time(Name + ' load');
|
||||
}
|
||||
Images.hide();
|
||||
callback();
|
||||
}
|
||||
], callback);
|
||||
});
|
||||
|
||||
function _authCheck(spawn, ok) {
|
||||
const accept = wraptile(ok);
|
||||
const alertDialog = wraptile(Dialog.alert);
|
||||
|
||||
init();
|
||||
spawn.on('accept', accept(spawn));
|
||||
spawn.on('reject', alertDialog (TITLE, 'Wrong credentials!'));
|
||||
spawn.emit('auth', config('username'), config('password'));
|
||||
}
|
||||
|
||||
function _initOperations(socketPrefix, fn) {
|
||||
const prefix = `${socketPrefix}/fileop`;
|
||||
fileop({prefix, socketPrefix}, (e, operator) => {
|
||||
fn();
|
||||
|
||||
operator.on('connect', authCheck(operator, onConnect));
|
||||
operator.on('disconnect', onDisconnect);
|
||||
});
|
||||
}
|
||||
|
||||
function onConnect(operator) {
|
||||
packTarFn = (data, callback) => {
|
||||
operator.tar(data.from, data.to, data.names)
|
||||
.then(setListeners({noContinue: true}, callback));
|
||||
};
|
||||
|
||||
packZipFn = (data, callback) => {
|
||||
operator.zip(data.from, data.to, data.names)
|
||||
.then(setListeners({noContinue: true}, callback));
|
||||
};
|
||||
|
||||
deleteFn = (from, files, callback) => {
|
||||
from = removeQuery(from);
|
||||
operator.remove(from, files)
|
||||
.then(setListeners(callback));
|
||||
};
|
||||
|
||||
copyFn = (data, callback) => {
|
||||
operator.copy(data.from, data.to, data.names)
|
||||
.then(setListeners(callback));
|
||||
};
|
||||
|
||||
moveFn = (data, callback) => {
|
||||
operator.move(data.from, data.to, data.names)
|
||||
.then(setListeners(callback));
|
||||
};
|
||||
|
||||
extractFn = (data, callback) => {
|
||||
operator.extract(data.from, data.to)
|
||||
.then(setListeners({noContinue: true}, callback));
|
||||
};
|
||||
}
|
||||
|
||||
function onDisconnect() {
|
||||
packZipFn = RESTful.pack;
|
||||
packTarFn = RESTful.pack;
|
||||
deleteFn = RESTful.delete;
|
||||
copyFn = RESTful.cp;
|
||||
moveFn = RESTful.mv;
|
||||
extractFn = RESTful.extract;
|
||||
}
|
||||
|
||||
function getPacker(type) {
|
||||
if (type === 'zip')
|
||||
return packZipFn;
|
||||
|
||||
return packTarFn;
|
||||
}
|
||||
|
||||
module.exports.hide = () => {
|
||||
CloudCmd.View.hide();
|
||||
};
|
||||
|
||||
module.exports.show = (operation, data) => {
|
||||
if (!Loaded)
|
||||
return;
|
||||
|
||||
if (operation === 'copy')
|
||||
return Operation.copy(data);
|
||||
|
||||
if (operation === 'move')
|
||||
return Operation.move(data);
|
||||
|
||||
if (operation === 'delete')
|
||||
return Operation.delete();
|
||||
|
||||
if (operation === 'delete:silent')
|
||||
return Operation.deleteSilent();
|
||||
|
||||
if (operation === 'pack')
|
||||
return Operation.pack();
|
||||
|
||||
if (operation === 'extract')
|
||||
return Operation.extract();
|
||||
};
|
||||
|
||||
Operation.copy = processFiles({
|
||||
type: 'copy',
|
||||
});
|
||||
|
||||
Operation.move = processFiles({
|
||||
type: 'move'
|
||||
});
|
||||
|
||||
Operation.delete = () => {
|
||||
promptDelete();
|
||||
};
|
||||
|
||||
Operation.deleteSilent = () => {
|
||||
deleteSilent();
|
||||
};
|
||||
|
||||
Operation.pack = () => {
|
||||
const isZip = config('packer') === 'zip';
|
||||
twopack('pack', isZip ? 'zip' : 'tar');
|
||||
};
|
||||
|
||||
Operation.extract = () => {
|
||||
twopack('extract');
|
||||
};
|
||||
|
||||
/**
|
||||
* prompt and delete current file or selected files
|
||||
*
|
||||
* @currentFile
|
||||
*/
|
||||
function promptDelete() {
|
||||
if (noFilesCheck())
|
||||
return;
|
||||
|
||||
const msgAsk = 'Do you really want to delete the ';
|
||||
const msgSel = 'selected ';
|
||||
|
||||
const files = DOM.getActiveFiles();
|
||||
const names = DOM.getFilenames(files);
|
||||
const n = names.length;
|
||||
|
||||
let msg;
|
||||
if (n) {
|
||||
let name = '';
|
||||
|
||||
for (let i = 0; i < 5 && i < n; i++)
|
||||
name += '\n' + names[i];
|
||||
|
||||
if (n >= 5)
|
||||
name += '\n...';
|
||||
|
||||
msg = msgAsk + msgSel + n + ' files/directories?\n' + encode(name);
|
||||
} else {
|
||||
const current = DOM.getCurrentFile();
|
||||
const isDir = DOM.isCurrentIsDir(current);
|
||||
const getType = (isDir) => {
|
||||
return isDir ? 'directory' : 'file';
|
||||
};
|
||||
|
||||
const type = getType(isDir) + ' ';
|
||||
|
||||
const name = DOM.getCurrentName(current);
|
||||
msg = msgAsk + msgSel + type + name + '?';
|
||||
}
|
||||
|
||||
const cancel = false;
|
||||
|
||||
Dialog.confirm(TITLE, msg, {cancel}).then(() => {
|
||||
deleteSilent(files);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* delete current or selected files
|
||||
*
|
||||
* @files
|
||||
*/
|
||||
function deleteSilent(files = DOM.getActiveFiles()) {
|
||||
const query = '?files';
|
||||
const path = Info.dirPath;
|
||||
|
||||
if (noFilesCheck())
|
||||
return;
|
||||
|
||||
showLoad();
|
||||
|
||||
const removedNames = DOM.getFilenames(files);
|
||||
const names = DOM.CurrentInfo.files.map(DOM.getCurrentName);
|
||||
const prevCurrent = DOM.getCurrentName();
|
||||
const currentName = getNextCurrentName(prevCurrent, names, removedNames);
|
||||
|
||||
deleteFn(path + query, removedNames, (e) => {
|
||||
const Storage = DOM.Storage;
|
||||
const dirPath = Info.dirPath;
|
||||
|
||||
!e && CloudCmd.refresh({
|
||||
currentName
|
||||
});
|
||||
|
||||
Storage.removeMatch(dirPath);
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* process files (copy or move)
|
||||
* @param data
|
||||
* @param operation
|
||||
*/
|
||||
function _processFiles(options, data) {
|
||||
let selFiles, files;
|
||||
let panel;
|
||||
let shouldAsk;
|
||||
let sameName;
|
||||
let ok;
|
||||
|
||||
let from = '';
|
||||
let to = '';
|
||||
|
||||
let names = [];
|
||||
|
||||
if (data) {
|
||||
from = data.from;
|
||||
to = data.to;
|
||||
names = data.names;
|
||||
panel = Info.panel;
|
||||
} else {
|
||||
from = Info.dirPath;
|
||||
to = DOM.getNotCurrentDirPath();
|
||||
selFiles = DOM.getSelectedFiles();
|
||||
names = DOM.getFilenames(selFiles);
|
||||
data = {};
|
||||
shouldAsk = true;
|
||||
panel = Info.panelPassive;
|
||||
}
|
||||
|
||||
if (!names.length)
|
||||
names.push(DOM.getCurrentName());
|
||||
|
||||
const name = names[0];
|
||||
|
||||
sameName = DOM.getCurrentByName(name, panel);
|
||||
|
||||
if (!data && noFilesCheck())
|
||||
return;
|
||||
|
||||
const {type} = options;
|
||||
|
||||
const isCopy = type === 'copy';
|
||||
const option = isCopy ? 'confirmCopy' : 'confirmMove';
|
||||
const title = isCopy ? 'Copy' : 'Rename/Move';
|
||||
const operation = isCopy ? copyFn : moveFn;
|
||||
|
||||
if (shouldAsk && config(option))
|
||||
return message(title, to, names.map(encode))
|
||||
.then(ask);
|
||||
|
||||
ask(to);
|
||||
|
||||
function ask(to) {
|
||||
ok = from !== to && to;
|
||||
|
||||
if (ok && !shouldAsk || !sameName)
|
||||
return go();
|
||||
|
||||
const str = `"${ name }" already exist. Overwrite?`;
|
||||
const cancel = false;
|
||||
|
||||
Dialog.confirm(TITLE, str, {cancel}).then(go);
|
||||
|
||||
function go() {
|
||||
showLoad();
|
||||
|
||||
files = {
|
||||
from,
|
||||
to,
|
||||
names,
|
||||
};
|
||||
|
||||
operation(files, () => {
|
||||
DOM.Storage.remove(from, () => {
|
||||
const {
|
||||
panel,
|
||||
panelPassive,
|
||||
} = Info;
|
||||
|
||||
const setCurrent = () => {
|
||||
const currentName = name || data.names[0];
|
||||
DOM.setCurrentByName(currentName);
|
||||
};
|
||||
|
||||
if (!Info.isOnePanel)
|
||||
CloudCmd.refresh({
|
||||
panel: panelPassive,
|
||||
noCurrent: true,
|
||||
});
|
||||
|
||||
CloudCmd.refresh({panel}, setCurrent);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkEmpty(name, operation) {
|
||||
if (!operation)
|
||||
throw Error(name + ' could not be empty!');
|
||||
}
|
||||
|
||||
function twopack(operation, type) {
|
||||
let op;
|
||||
let fileFrom;
|
||||
let currentName = Info.name;
|
||||
|
||||
const Images = DOM.Images;
|
||||
const path = Info.path;
|
||||
const dirPath = Info.dirPath;
|
||||
const activeFiles = DOM.getActiveFiles();
|
||||
const names = DOM.getFilenames(activeFiles);
|
||||
|
||||
checkEmpty('operation', operation);
|
||||
|
||||
if (!names.length)
|
||||
return Dialog.alert.noFiles(TITLE);
|
||||
|
||||
switch(operation) {
|
||||
case 'extract':
|
||||
op = extractFn;
|
||||
|
||||
fileFrom = {
|
||||
from: path,
|
||||
to: dirPath
|
||||
};
|
||||
|
||||
currentName = removeExtension(currentName);
|
||||
|
||||
break;
|
||||
|
||||
case 'pack':
|
||||
op = getPacker(type);
|
||||
|
||||
if (names.length > 1)
|
||||
currentName = Info.dir;
|
||||
|
||||
currentName += DOM.getPackerExt(type);
|
||||
|
||||
fileFrom = {
|
||||
from: dirPath,
|
||||
to: dirPath + currentName,
|
||||
names,
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
Images.show.load('top');
|
||||
|
||||
op(fileFrom, (error) => {
|
||||
!error && CloudCmd.refresh({
|
||||
currentName
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function message(msg, to, names) {
|
||||
const n = names.length;
|
||||
const name = names[0];
|
||||
|
||||
msg += ' ';
|
||||
|
||||
if (names.length > 1)
|
||||
msg += n + ' file(s)';
|
||||
else
|
||||
msg += '"' + name + '"';
|
||||
|
||||
msg += ' to';
|
||||
|
||||
const cancel = false;
|
||||
|
||||
return Dialog.prompt(TITLE, msg, to, {cancel});
|
||||
}
|
||||
|
||||
function load(callback) {
|
||||
const prefix = CloudCmd.PREFIX;
|
||||
const file = `${prefix}/fileop/fileop.js`;
|
||||
|
||||
DOM.load.js(file, (error) => {
|
||||
if (error) {
|
||||
Dialog.alert(TITLE, error.message);
|
||||
return exec(callback);
|
||||
}
|
||||
|
||||
Loaded = true;
|
||||
Util.timeEnd(Name + ' load');
|
||||
exec(callback);
|
||||
});
|
||||
|
||||
Util.time(Name + ' load');
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,18 +2,18 @@
|
|||
|
||||
/* global CloudCmd, gritty */
|
||||
|
||||
const {promisify} = require('es6-promisify');
|
||||
|
||||
require('../../css/terminal.css');
|
||||
|
||||
const exec = require('execon');
|
||||
const load = require('../dom/load');
|
||||
const DOM = require('../dom');
|
||||
const Images = require('../dom/images');
|
||||
const {Dialog} = DOM;
|
||||
|
||||
const TITLE = 'Terminal';
|
||||
|
||||
CloudCmd.Terminal = TerminalProto;
|
||||
|
||||
const {Dialog} = DOM;
|
||||
const {Key} = CloudCmd;
|
||||
|
||||
let Element;
|
||||
|
|
@ -22,30 +22,26 @@ let Terminal;
|
|||
|
||||
const {config} = CloudCmd;
|
||||
|
||||
function TerminalProto() {
|
||||
const noop = () => {};
|
||||
|
||||
if (!config('terminal'))
|
||||
return {
|
||||
show: noop
|
||||
};
|
||||
const loadAll = promisify((callback) => {
|
||||
const prefix = getPrefix();
|
||||
const url = prefix + '/gritty.js';
|
||||
|
||||
DOM.load.js(url, (error) => {
|
||||
if (error)
|
||||
return Dialog.alert(TITLE, error.message);
|
||||
|
||||
Loaded = true;
|
||||
exec(callback);
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.init = async () => {
|
||||
Images.show.load('top');
|
||||
|
||||
exec.series([
|
||||
CloudCmd.View,
|
||||
loadAll,
|
||||
create,
|
||||
show,
|
||||
]);
|
||||
|
||||
Element = load({
|
||||
name: 'div',
|
||||
className : 'terminal',
|
||||
});
|
||||
|
||||
return module.exports;
|
||||
}
|
||||
await CloudCmd.View();
|
||||
await loadAll();
|
||||
await create();
|
||||
};
|
||||
|
||||
module.exports.show = show;
|
||||
module.exports.hide = hide;
|
||||
|
|
@ -67,7 +63,12 @@ function getEnv() {
|
|||
};
|
||||
}
|
||||
|
||||
function create(callback) {
|
||||
function create() {
|
||||
Element = load({
|
||||
name: 'div',
|
||||
className : 'terminal',
|
||||
});
|
||||
|
||||
const options = {
|
||||
env: getEnv(),
|
||||
prefix: getPrefix(),
|
||||
|
|
@ -86,12 +87,11 @@ function create(callback) {
|
|||
});
|
||||
|
||||
socket.on('connect', exec.with(authCheck, socket));
|
||||
exec(callback);
|
||||
}
|
||||
|
||||
function authCheck(spawn) {
|
||||
spawn.emit('auth', config('username'), config('password'));
|
||||
|
||||
|
||||
spawn.on('reject', () => {
|
||||
Dialog.alert(TITLE, 'Wrong credentials!');
|
||||
});
|
||||
|
|
@ -101,6 +101,9 @@ function show(callback) {
|
|||
if (!Loaded)
|
||||
return;
|
||||
|
||||
if (!config('terminal'))
|
||||
return;
|
||||
|
||||
CloudCmd.View.show(Element, {
|
||||
afterShow: () => {
|
||||
if (Terminal)
|
||||
|
|
@ -111,16 +114,3 @@ function show(callback) {
|
|||
});
|
||||
}
|
||||
|
||||
function loadAll(callback) {
|
||||
const prefix = getPrefix();
|
||||
const url = prefix + '/gritty.js';
|
||||
|
||||
DOM.load.js(url, (error) => {
|
||||
if (error)
|
||||
return Dialog.alert(TITLE, error.message);
|
||||
|
||||
Loaded = true;
|
||||
exec(callback);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,25 +2,15 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
const exec = require('execon');
|
||||
|
||||
const load = require('../dom/load');
|
||||
const Files = require('../dom/files');
|
||||
const Images = require('../dom/images');
|
||||
const uploadFiles = require('../dom/upload-files');
|
||||
|
||||
CloudCmd.Upload = UploadProto;
|
||||
|
||||
function UploadProto() {
|
||||
module.exports.init = async () => {
|
||||
Images.show.load('top');
|
||||
|
||||
exec.series([
|
||||
CloudCmd.View,
|
||||
show
|
||||
]);
|
||||
|
||||
return exports;
|
||||
}
|
||||
await CloudCmd.View();
|
||||
};
|
||||
|
||||
module.exports.show = show;
|
||||
module.exports.hide = hide;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ const itype = require('itype/legacy');
|
|||
const rendy = require('rendy/legacy');
|
||||
const exec = require('execon');
|
||||
const currify = require('currify/legacy');
|
||||
const {promisify} = require('es6-promisify');
|
||||
|
||||
const {time} = require('../../common/util');
|
||||
const {FS} = require('../../common/cloudfunc');
|
||||
|
|
@ -23,10 +24,7 @@ const lifo = currify((fn, el, cb, name) => fn(name, el, cb));
|
|||
const addEvent = lifo(Events.add);
|
||||
const getRegExp = (ext) => RegExp(`\\.${ext}$`, 'i');
|
||||
|
||||
CloudCmd.View = ViewProto;
|
||||
|
||||
module.exports = exec.bind();
|
||||
|
||||
//module.exports = exec.bind();
|
||||
module.exports.show = show;
|
||||
module.exports.hide = hide;
|
||||
|
||||
|
|
@ -77,9 +75,7 @@ const Config = {
|
|||
}
|
||||
};
|
||||
|
||||
function ViewProto(callback) {
|
||||
const func = callback || exec.with(show, null);
|
||||
|
||||
module.exports.init = promisify((fn) => {
|
||||
Loading = true;
|
||||
|
||||
exec.series([
|
||||
|
|
@ -87,9 +83,9 @@ function ViewProto(callback) {
|
|||
loadAll,
|
||||
(callback) => {
|
||||
Loading = false;
|
||||
exec(callback);
|
||||
callback();
|
||||
}
|
||||
], func);
|
||||
], fn);
|
||||
|
||||
Config.parent = Overlay = load({
|
||||
id : 'js-view',
|
||||
|
|
@ -103,9 +99,7 @@ function ViewProto(callback) {
|
|||
];
|
||||
|
||||
events.forEach(addEvent(Overlay, onOverLayClick));
|
||||
|
||||
return module.exports;
|
||||
}
|
||||
});
|
||||
|
||||
function show(data, options) {
|
||||
const prefixUrl = CloudCmd.PREFIX_URL + FS;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ module.exports.unregisterSW = unregisterSW;
|
|||
|
||||
async function registerSW(prefix) {
|
||||
prefix = prefix ? `/${prefix}/` : `/`;
|
||||
|
||||
if (!navigator.serviceWorker)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@ const preval = require('preval.macro');
|
|||
const tryToCatch = require('try-to-catch/legacy');
|
||||
const currify = require('currify/legacy');
|
||||
|
||||
const isDev = process.env.NODE_ENV === 'development';
|
||||
|
||||
const tryWrap = (a) => (...b) => tryToCatch(a, ...b);
|
||||
|
||||
const wait = currify((f, e) => e.waitUntil(f()));
|
||||
const respondWith = currify((f, e) => e.respondWith(f(e)));
|
||||
const getPathName = (url) => new URL(url).pathname;
|
||||
|
|
@ -62,10 +66,10 @@ async function onFetch(event) {
|
|||
const cache = await caches.open(NAME);
|
||||
const response = await cache.match(request);
|
||||
|
||||
if (response)
|
||||
if (!isDev && response)
|
||||
return response;
|
||||
|
||||
const [e, resp] = await tryToCatch(fetch, request.clone());
|
||||
const [e, resp] = await tryToRequest(request);
|
||||
|
||||
if (e)
|
||||
return console.error(e, response, pathname);
|
||||
|
|
@ -92,3 +96,28 @@ async function addToCache(request, response) {
|
|||
return cache.put(request, response);
|
||||
}
|
||||
|
||||
async function tryToRequest(req) {
|
||||
const {url} = req;
|
||||
const path = url.replace(`${location.origin}/`, '');
|
||||
const get = tryWrap(fetch);
|
||||
const prefix = getPrefix();
|
||||
|
||||
if (prefix && /^dist/.test(path))
|
||||
return await get(createRequest(`${prefix}${path}`));
|
||||
|
||||
return await get(req.clone());
|
||||
}
|
||||
|
||||
function getPrefix() {
|
||||
const {
|
||||
href,
|
||||
origin,
|
||||
} = location;
|
||||
|
||||
const prefix = href
|
||||
.replace(origin, '')
|
||||
.replace('sw.js', '');
|
||||
|
||||
return prefix;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -158,9 +158,11 @@
|
|||
"devDependencies": {
|
||||
"@babel/core": "^7.0.0-beta.49",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.49",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.0.0-beta.51",
|
||||
"@babel/plugin-transform-object-assign": "^7.0.0-beta.49",
|
||||
"@babel/preset-env": "^7.0.0-beta.49",
|
||||
"@cloudcmd/clipboard": "^1.0.0",
|
||||
"babel-eslint": "^8.2.3",
|
||||
"babel-loader": "^8.0.0-beta",
|
||||
"babel-plugin-macros": "^2.2.1",
|
||||
"clean-css-loader": "^1.0.1",
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
'use strict';
|
||||
|
||||
const version = require('../../package').version;
|
||||
const format = require('format-io');
|
||||
|
||||
const version = require('../../package').version;
|
||||
const config = require('../config');
|
||||
|
||||
const getMemory = () => {
|
||||
const rss = process.memoryUsage().rss;
|
||||
return format.size(rss);
|
||||
|
|
@ -11,5 +13,6 @@ const getMemory = () => {
|
|||
module.exports = () => ({
|
||||
version,
|
||||
memory: getMemory(),
|
||||
prefix: config('prefix'),
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue