mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-23 02:35:49 +00:00
343 lines
7.3 KiB
JavaScript
343 lines
7.3 KiB
JavaScript
/* global CloudCmd, DOM */
|
|
|
|
import exec from 'execon';
|
|
import wrap from 'wraptile';
|
|
import supermenu from 'supermenu';
|
|
import createElement from '@cloudcmd/create-element';
|
|
|
|
import {FS} from '../../common/cloudfunc.js';
|
|
import {getIdBySrc} from '../dom/load.js';
|
|
import RESTful from '../dom/rest.js';
|
|
|
|
const {
|
|
config,
|
|
Key,
|
|
} = CloudCmd;
|
|
|
|
const {
|
|
Buffer,
|
|
Events,
|
|
Dialog,
|
|
Images,
|
|
} = DOM;
|
|
|
|
const Info = DOM.CurrentInfo;
|
|
const alertNoFiles = Dialog.alert.noFiles;
|
|
const uploadTo = wrap(_uploadTo);
|
|
|
|
let MenuShowedName;
|
|
let MenuContext;
|
|
let MenuContextFile;
|
|
|
|
export const ENABLED = false;
|
|
|
|
CloudCmd.Menu = {
|
|
init,
|
|
show,
|
|
hide,
|
|
};
|
|
|
|
export function init() {
|
|
const {
|
|
isAuth,
|
|
menuDataFile,
|
|
} = getFileMenuData();
|
|
|
|
const fm = DOM.getFM();
|
|
const menuData = getMenuData(isAuth);
|
|
const options = getOptions({type: 'context'});
|
|
const optionsFile = getOptions({type: 'file'});
|
|
|
|
MenuContext = supermenu(fm, options, menuData);
|
|
MenuContextFile = supermenu(fm, optionsFile, menuDataFile);
|
|
|
|
MenuContext.addContextMenuListener();
|
|
MenuContextFile.addContextMenuListener();
|
|
|
|
Events.addKey(listener);
|
|
}
|
|
|
|
export function hide() {
|
|
MenuContext.hide();
|
|
MenuContextFile.hide();
|
|
}
|
|
|
|
export function 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({type}) {
|
|
let name;
|
|
let func;
|
|
|
|
if (type === 'context') {
|
|
name = 'context';
|
|
func = Key.unsetBind;
|
|
} else if (type === 'file') {
|
|
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,
|
|
};
|
|
|
|
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;
|
|
const el = DOM.getCurrentByPosition({
|
|
x: params.x,
|
|
y: params.y,
|
|
});
|
|
|
|
const menuName = getMenuNameByEl(el);
|
|
|
|
let isShow = menuName !== 'contextFile';
|
|
|
|
if (params.name === 'contextFile')
|
|
isShow = !isShow;
|
|
|
|
if (isShow)
|
|
MenuShowedName = name;
|
|
|
|
exec(callback);
|
|
|
|
if (isShow)
|
|
isShow = isPath(params.x, params.y);
|
|
|
|
return isShow;
|
|
}
|
|
|
|
function beforeClick(name) {
|
|
return MenuShowedName !== name;
|
|
}
|
|
|
|
function _uploadTo(nameModule) {
|
|
Info.getData((error, data) => {
|
|
if (error)
|
|
return;
|
|
|
|
const {name} = Info;
|
|
|
|
CloudCmd.execFromModule(nameModule, 'uploadFile', name, data);
|
|
});
|
|
|
|
CloudCmd.log('Uploading to ' + name + '...');
|
|
}
|
|
|
|
function uploadFromCloud() {
|
|
Images.show.load('top');
|
|
|
|
CloudCmd.execFromModule('Cloud', 'saveFile', async (currentName, data) => {
|
|
const path = DOM.getCurrentDirPath() + currentName;
|
|
const [e] = await RESTful.write(path, data);
|
|
|
|
if (e)
|
|
return;
|
|
|
|
await CloudCmd.refresh({currentName});
|
|
});
|
|
}
|
|
|
|
function preDownload() {
|
|
download(config('packer'));
|
|
}
|
|
|
|
function download(type) {
|
|
const TIME = 30 * 1000;
|
|
const {prefixURL} = CloudCmd;
|
|
const PACK = '/pack';
|
|
const date = Date.now();
|
|
const files = DOM.getActiveFiles();
|
|
|
|
if (!files.length)
|
|
return alertNoFiles();
|
|
|
|
for (const file of files) {
|
|
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 = getIdBySrc(path);
|
|
|
|
let src;
|
|
|
|
if (isDir)
|
|
src = prefixURL + PACK + encodedPath + DOM.getPackerExt(type);
|
|
else
|
|
src = prefixURL + FS + encodedPath + '?download';
|
|
|
|
const element = createElement('iframe', {
|
|
id : id + '-' + date,
|
|
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,
|
|
ESC,
|
|
} = Key;
|
|
|
|
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();
|
|
}
|
|
}
|