mirror of
https://github.com/coderaiser/cloudcmd.git
synced 2026-01-23 02:35:49 +00:00
feature(user-menu) add default user menu
This commit is contained in:
parent
7b6e767ccb
commit
76184c0251
11 changed files with 325 additions and 272 deletions
|
|
@ -17,7 +17,7 @@ module.exports.alert = (...a) => alert(title, ...a, {
|
|||
|
||||
module.exports.prompt = (...a) => tryToCatch(prompt, title, ...a);
|
||||
module.exports.confirm = (...a) => tryToCatch(confirm, title, ...a);
|
||||
module.exports.progress = (...a) => tryToCatch(progress, title, ...a);
|
||||
module.exports.progress = (...a) => progress(title, ...a);
|
||||
|
||||
module.exports.alert.noFiles = () => {
|
||||
return alert(title, 'No files selected!', {
|
||||
|
|
|
|||
|
|
@ -13,11 +13,10 @@ const Images = require('./images');
|
|||
const load = require('./load');
|
||||
const Files = require('./files');
|
||||
const RESTful = require('./rest');
|
||||
const IO = require('./io');
|
||||
const Storage = require('./storage');
|
||||
const Dialog = require('./dialog');
|
||||
|
||||
const read = callbackify(RESTful.read);
|
||||
|
||||
const currentFile = require('./current-file');
|
||||
const DOMTree = require('./dom-tree');
|
||||
|
||||
|
|
@ -27,10 +26,20 @@ const DOM = {
|
|||
...new CmdProto(),
|
||||
};
|
||||
|
||||
const read = callbackify(async (...args) => {
|
||||
const [e, data] = await RESTful.read(...args);
|
||||
|
||||
if (e)
|
||||
throw e;
|
||||
|
||||
return data;
|
||||
});
|
||||
|
||||
DOM.Images = Images;
|
||||
DOM.load = load;
|
||||
DOM.Files = Files;
|
||||
DOM.RESTful = RESTful;
|
||||
DOM.IO = IO;
|
||||
DOM.Storage = Storage;
|
||||
DOM.Dialog = Dialog;
|
||||
|
||||
|
|
|
|||
214
client/dom/io.js
Normal file
214
client/dom/io.js
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd*/
|
||||
|
||||
const itype = require('itype/legacy');
|
||||
const {promisify} = require('es6-promisify');
|
||||
|
||||
const {FS} = require('../../common/cloudfunc');
|
||||
|
||||
const Images = require('./images');
|
||||
const load = require('./load');
|
||||
|
||||
const imgPosition = {
|
||||
top: true,
|
||||
};
|
||||
|
||||
module.exports._replaceHash = replaceHash;
|
||||
function replaceHash(url) {
|
||||
/*
|
||||
* if we send ajax request -
|
||||
* no need in hash so we escape #
|
||||
*/
|
||||
return url.replace(/#/g, '%23');
|
||||
}
|
||||
|
||||
module.exports.delete = promisify((url, data, callback) => {
|
||||
const isFunc = itype.function(data);
|
||||
|
||||
if (!callback && isFunc) {
|
||||
callback = data;
|
||||
data = null;
|
||||
}
|
||||
|
||||
sendRequest({
|
||||
method : 'DELETE',
|
||||
url : FS + url,
|
||||
data,
|
||||
callback,
|
||||
imgPosition : { top: !!data },
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.patch = promisify((url, data, callback) => {
|
||||
const isFunc = itype.function(data);
|
||||
|
||||
if (!callback && isFunc) {
|
||||
callback = data;
|
||||
data = null;
|
||||
}
|
||||
|
||||
sendRequest({
|
||||
method: 'PATCH',
|
||||
url: FS + url,
|
||||
data,
|
||||
callback,
|
||||
imgPosition,
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.write = promisify((url, data, callback) => {
|
||||
const isFunc = itype.function(data);
|
||||
|
||||
if (!callback && isFunc) {
|
||||
callback = data;
|
||||
data = null;
|
||||
}
|
||||
|
||||
sendRequest({
|
||||
method: 'PUT',
|
||||
url: FS + url,
|
||||
data,
|
||||
callback,
|
||||
imgPosition,
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.read = promisify((url, dataType, callback) => {
|
||||
const notLog = !url.includes('?');
|
||||
const isFunc = itype.function(dataType);
|
||||
|
||||
if (!callback && isFunc) {
|
||||
callback = dataType;
|
||||
dataType = 'text';
|
||||
}
|
||||
|
||||
sendRequest({
|
||||
method: 'GET',
|
||||
url: FS + url,
|
||||
callback,
|
||||
notLog,
|
||||
dataType,
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.cp = promisify((data, callback) => {
|
||||
sendRequest({
|
||||
method: 'PUT',
|
||||
url: '/cp',
|
||||
data,
|
||||
callback,
|
||||
imgPosition,
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.pack = promisify((data, callback) => {
|
||||
sendRequest({
|
||||
method: 'PUT',
|
||||
url: '/pack',
|
||||
data,
|
||||
callback,
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.extract = promisify((data, callback) => {
|
||||
sendRequest({
|
||||
method : 'PUT',
|
||||
url : '/extract',
|
||||
data,
|
||||
callback,
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.mv = promisify((data, callback) => {
|
||||
sendRequest({
|
||||
method : 'PUT',
|
||||
url : '/mv',
|
||||
data,
|
||||
callback,
|
||||
imgPosition,
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.Config = {
|
||||
read: promisify((callback) => {
|
||||
sendRequest({
|
||||
method: 'GET',
|
||||
url: '/config',
|
||||
callback,
|
||||
imgPosition,
|
||||
notLog: true,
|
||||
});
|
||||
}),
|
||||
|
||||
write: promisify((data, callback) => {
|
||||
sendRequest({
|
||||
method: 'PATCH',
|
||||
url: '/config',
|
||||
data,
|
||||
callback,
|
||||
imgPosition,
|
||||
});
|
||||
}),
|
||||
};
|
||||
|
||||
module.exports.Markdown = {
|
||||
read: promisify((url, callback) => {
|
||||
sendRequest({
|
||||
method: 'GET',
|
||||
url: '/markdown' + url,
|
||||
callback,
|
||||
imgPosition,
|
||||
notLog: true,
|
||||
});
|
||||
}),
|
||||
|
||||
render: promisify((data, callback) => {
|
||||
sendRequest({
|
||||
method: 'PUT',
|
||||
url: '/markdown',
|
||||
data,
|
||||
callback,
|
||||
imgPosition,
|
||||
notLog: true,
|
||||
});
|
||||
}),
|
||||
};
|
||||
|
||||
function sendRequest(params) {
|
||||
const p = params;
|
||||
const {prefixURL} = CloudCmd;
|
||||
|
||||
p.url = prefixURL + p.url;
|
||||
p.url = encodeURI(p.url);
|
||||
|
||||
p.url = replaceHash(p.url);
|
||||
|
||||
load.ajax({
|
||||
method : p.method,
|
||||
url : p.url,
|
||||
data : p.data,
|
||||
dataType : p.dataType,
|
||||
error : (jqXHR) => {
|
||||
const response = jqXHR.responseText;
|
||||
|
||||
const {
|
||||
statusText,
|
||||
status,
|
||||
} = jqXHR;
|
||||
|
||||
const text = status === 404 ? response : statusText;
|
||||
|
||||
p.callback(Error(text));
|
||||
},
|
||||
success: (data) => {
|
||||
Images.hide();
|
||||
|
||||
if (!p.notLog)
|
||||
CloudCmd.log(data);
|
||||
|
||||
p.callback(null, data);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -1,221 +1,43 @@
|
|||
'use strict';
|
||||
|
||||
/* global CloudCmd, DOM */
|
||||
const tryToCatch = require('try-to-catch/legacy');
|
||||
|
||||
const itype = require('itype/legacy');
|
||||
const promisify = require('../../common/try-to-promisify');
|
||||
|
||||
const {FS} = require('../../common/cloudfunc');
|
||||
const {encode} = require('../../common/entity');
|
||||
|
||||
const Images = require('./images');
|
||||
const load = require('./load');
|
||||
const IO = require('./io');
|
||||
const Dialog = require('./dialog');
|
||||
|
||||
const imgPosition = {
|
||||
top: true,
|
||||
const handleError = (promise) => async (...args) => {
|
||||
const [e, data] = await tryToCatch(promise, ...args);
|
||||
|
||||
if (!e)
|
||||
return [e, data];
|
||||
|
||||
const encoded = encode(e.message);
|
||||
|
||||
Images.show.error(encoded);
|
||||
Dialog.alert(encoded);
|
||||
|
||||
return [e, data];
|
||||
};
|
||||
|
||||
module.exports._replaceHash = replaceHash;
|
||||
function replaceHash(url) {
|
||||
/*
|
||||
* if we send ajax request -
|
||||
* no need in hash so we escape #
|
||||
*/
|
||||
return url.replace(/#/g, '%23');
|
||||
}
|
||||
|
||||
module.exports.delete = promisify((url, data, callback) => {
|
||||
const isFunc = itype.function(data);
|
||||
|
||||
if (!callback && isFunc) {
|
||||
callback = data;
|
||||
data = null;
|
||||
}
|
||||
|
||||
sendRequest({
|
||||
method : 'DELETE',
|
||||
url : FS + url,
|
||||
data,
|
||||
callback,
|
||||
imgPosition : { top: !!data },
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.patch = promisify((url, data, callback) => {
|
||||
const isFunc = itype.function(data);
|
||||
|
||||
if (!callback && isFunc) {
|
||||
callback = data;
|
||||
data = null;
|
||||
}
|
||||
|
||||
sendRequest({
|
||||
method: 'PATCH',
|
||||
url: FS + url,
|
||||
data,
|
||||
callback,
|
||||
imgPosition,
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.write = promisify((url, data, callback) => {
|
||||
const isFunc = itype.function(data);
|
||||
|
||||
if (!callback && isFunc) {
|
||||
callback = data;
|
||||
data = null;
|
||||
}
|
||||
|
||||
sendRequest({
|
||||
method: 'PUT',
|
||||
url: FS + url,
|
||||
data,
|
||||
callback,
|
||||
imgPosition,
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.read = promisify((url, dataType, callback) => {
|
||||
const notLog = !url.includes('?');
|
||||
const isFunc = itype.function(dataType);
|
||||
|
||||
if (!callback && isFunc) {
|
||||
callback = dataType;
|
||||
dataType = 'text';
|
||||
}
|
||||
|
||||
sendRequest({
|
||||
method: 'GET',
|
||||
url: FS + url,
|
||||
callback,
|
||||
notLog,
|
||||
dataType,
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.cp = promisify((data, callback) => {
|
||||
sendRequest({
|
||||
method: 'PUT',
|
||||
url: '/cp',
|
||||
data,
|
||||
callback,
|
||||
imgPosition,
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.pack = promisify((data, callback) => {
|
||||
sendRequest({
|
||||
method: 'PUT',
|
||||
url: '/pack',
|
||||
data,
|
||||
callback,
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.extract = promisify((data, callback) => {
|
||||
sendRequest({
|
||||
method : 'PUT',
|
||||
url : '/extract',
|
||||
data,
|
||||
callback,
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.mv = promisify((data, callback) => {
|
||||
sendRequest({
|
||||
method : 'PUT',
|
||||
url : '/mv',
|
||||
data,
|
||||
callback,
|
||||
imgPosition,
|
||||
});
|
||||
});
|
||||
module.exports.delete = handleError(IO.delete);
|
||||
module.exports.patch = handleError(IO.patch);
|
||||
module.exports.write = handleError(IO.write);
|
||||
module.exports.read = handleError(IO.read);
|
||||
module.exports.cp = handleError(IO.cp);
|
||||
module.exports.pack = handleError(IO.pack);
|
||||
module.exports.extract = handleError(IO.extract);
|
||||
module.exports.mv = handleError(IO.mv);
|
||||
|
||||
module.exports.Config = {
|
||||
read: promisify((callback) => {
|
||||
sendRequest({
|
||||
method: 'GET',
|
||||
url: '/config',
|
||||
callback,
|
||||
imgPosition,
|
||||
notLog: true,
|
||||
});
|
||||
}),
|
||||
|
||||
write: promisify((data, callback) => {
|
||||
sendRequest({
|
||||
method: 'PATCH',
|
||||
url: '/config',
|
||||
data,
|
||||
callback,
|
||||
imgPosition,
|
||||
});
|
||||
}),
|
||||
read: handleError(IO.Config.read),
|
||||
write: handleError(IO.Config.write),
|
||||
};
|
||||
|
||||
module.exports.Markdown = {
|
||||
read: promisify((url, callback) => {
|
||||
sendRequest({
|
||||
method: 'GET',
|
||||
url: '/markdown' + url,
|
||||
callback,
|
||||
imgPosition,
|
||||
notLog: true,
|
||||
});
|
||||
}),
|
||||
|
||||
render: promisify((data, callback) => {
|
||||
sendRequest({
|
||||
method: 'PUT',
|
||||
url: '/markdown',
|
||||
data,
|
||||
callback,
|
||||
imgPosition,
|
||||
notLog: true,
|
||||
});
|
||||
}),
|
||||
read: handleError(IO.Markdown.read),
|
||||
render: handleError(IO.Markdown.render),
|
||||
};
|
||||
|
||||
function sendRequest(params) {
|
||||
const p = params;
|
||||
const {prefixURL} = CloudCmd;
|
||||
|
||||
p.url = prefixURL + p.url;
|
||||
p.url = encodeURI(p.url);
|
||||
|
||||
p.url = replaceHash(p.url);
|
||||
|
||||
load.ajax({
|
||||
method : p.method,
|
||||
url : p.url,
|
||||
data : p.data,
|
||||
dataType : p.dataType,
|
||||
error : (jqXHR) => {
|
||||
const response = jqXHR.responseText;
|
||||
|
||||
const {
|
||||
statusText,
|
||||
status,
|
||||
} = jqXHR;
|
||||
|
||||
const text = status === 404 ? response : statusText;
|
||||
const encoded = encode(text);
|
||||
|
||||
Images.show.error(encoded);
|
||||
|
||||
setTimeout(() => {
|
||||
DOM.Dialog.alert(encoded);
|
||||
}, 100);
|
||||
|
||||
p.callback(Error(text));
|
||||
},
|
||||
success: (data) => {
|
||||
Images.hide();
|
||||
|
||||
if (!p.notLog)
|
||||
CloudCmd.log(data);
|
||||
|
||||
p.callback(null, data);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,38 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
const data = `'use strict';
|
||||
|
||||
module.exports = {
|
||||
'F2 - Rename file': async ({DOM}) => {
|
||||
await DOM.renameCurrent();
|
||||
},
|
||||
};
|
||||
`;
|
||||
|
||||
module.exports = {
|
||||
'F2 - Rename file': async ({DOM}) => {
|
||||
await DOM.renameCurrent();
|
||||
},
|
||||
|
||||
'C - Create User Menu File': async ({DOM, CloudCmd}) => {
|
||||
const {
|
||||
RESTful,
|
||||
CurrentInfo,
|
||||
} = DOM;
|
||||
|
||||
const {dirPath} = CurrentInfo;
|
||||
const path = `${dirPath}.cloudcmd.menu.js`;
|
||||
|
||||
const [e] = await RESTful.write(path, data);
|
||||
|
||||
if (e)
|
||||
return;
|
||||
|
||||
await CloudCmd.refresh();
|
||||
DOM.setCurrentByName('.cloudcmd.menu.js');
|
||||
await CloudCmd.EditFile.show();
|
||||
},
|
||||
};
|
||||
|
||||
module.exports._data = data;
|
||||
|
||||
|
|
@ -1,11 +1,6 @@
|
|||
'use strict';
|
||||
|
||||
const defaultUserMenu = require('./default-menu.js');
|
||||
|
||||
module.exports = (menuFn) => {
|
||||
if (!menuFn)
|
||||
return defaultUserMenu;
|
||||
|
||||
const module = {};
|
||||
const fn = Function('module', menuFn);
|
||||
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ const runUserMenu = async (value, options, userMenu) => {
|
|||
const [e] = await tryToCatch(userMenu[value], {
|
||||
DOM,
|
||||
CloudCmd,
|
||||
tryToCatch,
|
||||
});
|
||||
|
||||
if (e)
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
const {promisify} = require('es6-promisify');
|
||||
const wraptile = require('wraptile/legacy');
|
||||
const tryToCatch = require('try-to-catch/legacy');
|
||||
|
||||
module.exports = wraptile((fn, ...args) => {
|
||||
const promise = promisify(fn);
|
||||
return tryToCatch(promise, ...args);
|
||||
});
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ module.exports = {
|
|||
'lint': () => run(['putout', 'lint:*', 'spell']),
|
||||
'lint:server': () => `eslint -c .eslintrc.server ${dirs} --ignore-pattern *.spec.js`,
|
||||
'lint:test': () => `eslint --ignore-pattern '!.*' ${dirsTest}`,
|
||||
'lint:client': () => 'eslint --env browser client --ignore-pattern .cloudcmd.menu.js',
|
||||
'lint:client': () => 'eslint --env browser client static --ignore-pattern .cloudcmd.menu.js',
|
||||
'lint:css': () => 'stylelint css/*.css',
|
||||
'spell': () => 'yaspeller .',
|
||||
'fix:lint': () => run(['putout', 'lint:*'], '--fix'),
|
||||
|
|
@ -86,6 +86,6 @@ module.exports = {
|
|||
'build:client': () => run('6to5:client'),
|
||||
'build:client:dev': () => run('6to5:client:dev'),
|
||||
'heroku-postbuild': () => run('6to5:client'),
|
||||
'putout': () => 'putout bin client server common test .cloudcmd.menu.js',
|
||||
'putout': () => 'putout bin client static server common test .cloudcmd.menu.js',
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
const {homedir} = require('os');
|
||||
const fs = require('fs');
|
||||
|
||||
const {join} = require('path');
|
||||
const {promisify} = require('util');
|
||||
|
||||
|
|
@ -11,19 +12,32 @@ const findUp = require('find-up');
|
|||
|
||||
const readFile = promisify(fs.readFile);
|
||||
|
||||
const URL = '/api/v1/user-menu';
|
||||
const DEFAULT_MENU_PATH = join(__dirname, '../static/user-menu.js');
|
||||
|
||||
module.exports = currify(async({menuName}, req, res, next) => {
|
||||
if (req.url.indexOf('/api/v1/user-menu'))
|
||||
if (req.url.indexOf(URL))
|
||||
return next();
|
||||
|
||||
const {method} = req;
|
||||
|
||||
if (method === 'GET')
|
||||
return onGET(menuName, req.query, res);
|
||||
return onGET({
|
||||
req,
|
||||
res,
|
||||
menuName,
|
||||
});
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
async function onGET(menuName, {dir}, res) {
|
||||
async function onGET({req, res, menuName}) {
|
||||
const {dir} = req.query;
|
||||
const url = req.url.replace(URL, '');
|
||||
|
||||
if (url === '/default')
|
||||
return sendDefaultMenu(res);
|
||||
|
||||
const [errorFind, currentMenuPath] = await tryToCatch(findUp, [
|
||||
menuName,
|
||||
], {cwd: dir});
|
||||
|
|
@ -33,21 +47,26 @@ async function onGET(menuName, {dir}, res) {
|
|||
.status(404)
|
||||
.send(e.message);
|
||||
|
||||
if (errorFind && errorFind.code === 'ENOENT')
|
||||
return res.send('');
|
||||
|
||||
const homeMenuPath = join(homedir(), menuName);
|
||||
const menuPath = currentMenuPath || homeMenuPath;
|
||||
const [e, data] = await tryToCatch(readFile, menuPath, 'utf8');
|
||||
|
||||
if (!e)
|
||||
return res.send(data);
|
||||
return res
|
||||
.type('js')
|
||||
.send(data);
|
||||
|
||||
if (e.code !== 'ENOENT')
|
||||
return res
|
||||
.status(404)
|
||||
.send(e.message);
|
||||
|
||||
return res.send('');
|
||||
sendDefaultMenu(res);
|
||||
}
|
||||
|
||||
function sendDefaultMenu(res) {
|
||||
res.sendFile(DEFAULT_MENU_PATH, {
|
||||
cacheControl: false,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
42
static/user-menu.js
Normal file
42
static/user-menu.js
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
'F2 - Rename file': async ({DOM}) => {
|
||||
await DOM.renameCurrent();
|
||||
},
|
||||
|
||||
'C - Create User Menu File': async ({DOM, CloudCmd}) => {
|
||||
const {CurrentInfo} = DOM;
|
||||
|
||||
const {dirPath} = CurrentInfo;
|
||||
const path = `${dirPath}.cloudcmd.menu.js`;
|
||||
const {prefix} = CloudCmd;
|
||||
|
||||
const data = await readDefaultMenu({prefix});
|
||||
await createDefaultMenu({
|
||||
path,
|
||||
data,
|
||||
DOM,
|
||||
CloudCmd,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
async function createDefaultMenu({path, data, DOM, CloudCmd}) {
|
||||
const {IO} = DOM;
|
||||
|
||||
await IO.write(path, data);
|
||||
await CloudCmd.refresh();
|
||||
|
||||
DOM.setCurrentByName('.cloudcmd.menu.js');
|
||||
|
||||
await CloudCmd.EditFile.show();
|
||||
}
|
||||
|
||||
async function readDefaultMenu({prefix}) {
|
||||
const res = await fetch(`${prefix}/api/v1/user-menu/default`);
|
||||
const data = await res.text();
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue