完善编辑命令界面

This commit is contained in:
fofolee
2022-04-07 00:37:56 +08:00
parent 5d630b5c1f
commit c6cce49b82
5 changed files with 540 additions and 237 deletions

View File

@@ -110,7 +110,7 @@
<q-badge rounded :color="cmdBadgeColor()"
><q-icon
class="q-mr-xs"
:name="commandTypes.keyword.icon"
:name="commandTypes.key.icon"
/>{{ getShortStrByByte(cmd) }}</q-badge
>
<q-tooltip>
@@ -217,7 +217,7 @@ export default {
maxCmdStingLen: 8,
commandTypes: commandTypes,
cmdBadgeSheet: {
keyword: "primary",
key: "primary",
files: "light-blue",
window: "indigo",
regex: "cyan",

View File

@@ -1,10 +1,9 @@
<template>
<div class="relative">
<!-- 命令设置栏 -->
<q-scroll-area
:thumb-style="{
width: '3px',
}"
<CommandMenu
ref="menu"
:quickcommandInfo="quickcommandInfo"
class="absolute-left shadow-10"
:style="{
width: sideBarWidth,
@@ -12,154 +11,7 @@
zIndex: 1,
}"
v-if="showSidebar"
>
<div class="row q-pa-md q-gutter-md">
<q-btn
dense
flat
color="grey"
icon="arrow_back_ios_new"
@click="closeEditor"
/>
<q-img class="commandLogo" width="64px" :src="commandIcon" />
<div class="row">
<div>
<!-- 说明 -->
<q-input
standout="bg-primary text-white"
square
v-model="quickcommandInfo.features.explain"
type="text"
label="说明"
>
<template v-slot:prepend>
<q-icon name="drive_file_rename_outline" />
</template>
</q-input>
<!-- 匹配类型 -->
<q-select
standout="bg-primary text-white"
square
options-dense
@update:model-value="cmdMatch = null"
:options="commandTypesOptions"
v-model="cmdType"
type="text"
label="匹配类型"
>
<template v-slot:prepend>
<q-icon :name="cmdType.icon" />
</template>
<template v-slot:option="scope">
<q-item v-bind="scope.itemProps" v-on="scope.itemEvents">
<q-item-section avatar>
<q-icon :name="scope.opt.icon" />
</q-item-section>
<q-item-section>
<q-item-label v-html="scope.opt.name" />
<q-item-label caption>{{ scope.opt.desc }}</q-item-label>
</q-item-section>
</q-item>
</template></q-select
>
<!-- 匹配规则 -->
<q-select
v-if="cmdType.valueType === 'array'"
standout="bg-primary text-white"
square
v-model="cmdMatch"
use-input
use-chips
multiple
hide-dropdown-icon
input-debounce="0"
new-value-mode="add-unique"
type="text"
placeholder="回车添加"
:label="cmdType.matchLabel"
>
<template v-slot:prepend>
<q-icon name="square_foot" />
</template>
</q-select>
<q-input
v-else
autogrow
standout="bg-primary text-white"
square
v-model="cmdMatch"
hide-bottom-space
@blur="cmdMatchVerify"
:readonly="cmdType.valueType === 'null'"
type="text"
:label="cmdType.matchLabel"
>
<template v-slot:prepend>
<q-icon name="square_foot" />
</template>
</q-input>
<!-- 标签 -->
<q-select
standout="bg-primary text-white"
square
v-model="quickcommandInfo.tags"
type="text"
label="标签"
use-input
use-chips
multiple
new-value-mode="add-unique"
input-debounce="0"
:options="allQuickCommandTags"
/>
<!-- 特殊变量 -->
<q-select
standout="bg-primary text-white"
square
label="特殊变量"
/>
<!-- 输出 -->
<q-select
standout="bg-primary text-white"
square
options-dense
color="primary"
v-model="quickcommandInfo.output"
:display-value="outputTypes[quickcommandInfo.output].label"
:options="outputTypesOptions"
label="输出"
>
<template v-slot:prepend>
<q-icon :name="outputTypes[quickcommandInfo.output].icon" />
</template>
<template v-slot:option="scope">
<q-item v-bind="scope.itemProps">
<q-item-section avatar>
<q-icon :name="outputTypes[scope.opt].icon" />
</q-item-section>
<q-item-section>
<q-item-label v-html="outputTypes[scope.opt].label" />
</q-item-section>
</q-item> </template
></q-select>
<!-- 平台 -->
<q-select
standout="bg-primary text-white"
square
:options="['win32', 'darwin', 'linux']"
use-chips
@blur="platformVerify()"
v-model="quickcommandInfo.features.platform"
multiple
options-dense
label="平台"
><template v-slot:prepend> <q-icon name="window" /> </template
></q-select>
</div>
</div>
</div>
<div></div>
</q-scroll-area>
></CommandMenu>
<!-- 编程语言栏 -->
<div
class="absolute-top"
@@ -185,13 +37,13 @@
>
<template v-slot:append>
<q-avatar size="lg" square>
<img :src="currentProgramLogo" />
<img :src="getLanguageIcon(quickcommandInfo.program)" />
</q-avatar>
</template>
<template v-slot:option="scope">
<q-item v-bind="scope.itemProps">
<q-item-section avatar>
<img width="32" :src="'/logo/' + scope.opt + '.png'" />
<img width="32" :src="getLanguageIcon(scope.opt)" />
</q-item-section>
<q-item-section>
<q-item-label v-html="scope.opt" />
@@ -252,6 +104,7 @@
<q-btn
flat
v-if="!isRunCodePage"
:disable="!canCommandSave"
color="primary"
icon="save"
@click="saveCurrentCommand()"
@@ -299,30 +152,20 @@
<script>
import MonocaEditor from "components/MonocaEditor";
import commandTypes from "../js/options/commandTypes.js";
import outputTypes from "../js/options/outputTypes.js";
let commandTypesOptions = Object.values(commandTypes);
import CommandMenu from "components/CommandMenu";
export default {
components: { MonocaEditor },
components: { MonocaEditor, CommandMenu },
data() {
return {
programLanguages: Object.keys(this.$programmings),
currentMatchType: "关键字",
sideBarWidth: "240px",
sideBarWidth: "290px",
languageBarHeight: "40px",
commandTypes: commandTypes,
commandTypesOptions: commandTypesOptions,
cmdType: commandTypesOptions[0],
cmdMatch: "",
outputTypes: outputTypes,
outputTypesOptions: Object.keys(outputTypes),
specilaVar: "{{input}}",
canCommandSave: this.action.type === "edit" ? true : false,
quickcommandInfo: {
features: {
explain: "",
platform: [],
platform: ["win32", "linux", "darwin"],
},
program: "quickcommand",
cmd: "",
@@ -346,8 +189,8 @@ export default {
resultMaxLength: 10000,
showSidebar: this.action.type !== "run",
isRunCodePage: this.action.type === "run",
parent: this.$parent.$parent.$parent.$parent,
commandString: this.$q.platform.is.mac ? "⌘" : "ctrl",
configurationPage: this.$parent.$parent.$parent.$parent,
};
},
props: {
@@ -355,16 +198,11 @@ export default {
},
mounted() {
this.init();
this.$refs.menu?.init();
},
computed: {
commandIcon() {
return this.quickcommandInfo.features?.icon || this.currentProgramLogo;
},
currentProgramLogo() {
return "/logo/" + this.quickcommandInfo.program + ".png";
},
allQuickCommandTags() {
return this.configurationPage.allQuickCommandTags.filter(
return this.parentPage.allQuickCommandTags.filter(
(x) => x !== "默认" && x !== "未分类" && x !== "搜索结果"
);
},
@@ -382,14 +220,13 @@ export default {
this.quickcommandInfo,
JSON.parse(JSON.stringify(quickCommandInfo))
);
// 获取当前命令的匹配类型及匹配规则
let currentQuickCommandCmds = this.getCommandType();
// 设置匹配类型下拉框的值Object及匹配规则的值
this.cmdType = this.commandTypes[currentQuickCommandCmds.type];
this.cmdMatch = currentQuickCommandCmds.match;
// monoca 相关
this.setLanguage(this.quickcommandInfo.program);
this.$refs.editor.setEditorValue(quickCommandInfo.cmd);
// 默认命令不可编辑
if (this.quickcommandInfo.tags?.includes("默认") && !utools.isDev()) {
this.canCommandSave = false;
}
// 只有新建或运行时才保存记录
if (this.action.type === "edit") return;
utools.onPluginOut(() => {
@@ -411,6 +248,7 @@ export default {
},
programChanged(value) {
this.setLanguage(value);
this.$refs.menu?.setIcon(value);
},
// 匹配编程语言
matchLanguage() {
@@ -426,6 +264,9 @@ export default {
let highlight = this.$programmings[language].highlight;
this.$refs.editor.setEditorLanguage(highlight ? highlight : language);
},
getLanguageIcon(program) {
return `/logo/${program}.png`;
},
// 打开文档
showHelp() {
utools.createBrowserWindow("./helps/quickcommand.html", {
@@ -523,7 +364,7 @@ export default {
// 替换特殊变量
async replaceTempInputVals(cmd) {
let tempInputVals = [];
let specilaVals = [
let needInputVal = [
"input",
"subinput",
"pwd",
@@ -531,7 +372,7 @@ export default {
"WindowInfo",
"MatchedFiles",
];
specilaVals.forEach((x) => {
needInputVal.forEach((x) => {
let m = cmd.match(new RegExp("{{" + x + ".*?}}", "g"));
m &&
m.forEach((y) => tempInputVals.includes(y) || tempInputVals.push(y));
@@ -568,47 +409,6 @@ export default {
},
// 保存
saveCurrentCommand() {},
// 判断命令类型
getCommandType() {
let data = {};
let cmds = this.quickcommandInfo.features.cmds;
if (cmds.length === 1) {
let { type, match } = cmds[0];
data.type = type ? type : "keyword";
data.match =
data.type === "keyword" ? cmds[0] : match?.app ? match.app : match;
} else {
data.type = cmds.filter((x) => !x.length).length
? "professional"
: "keyword";
data.match =
data.type === "keyword" ? cmds : JSON.stringify(cmds, null, 4);
}
return data;
},
// 正则不和规则自动加斜杠
cmdMatchVerify() {
this.cmdType.valueType === "regex" &&
!/^\/.*?\/[igm]*$/.test(this.cmdMatch) &&
(this.cmdMatch = `/${this.cmdMatch}/`);
},
// 平台为空自动补充
platformVerify() {
this.quickcommandInfo.features.platform > 0 ||
this.quickcommandInfo.features.platform.push(window.processPlatform);
},
},
};
</script>
<style scoped>
.commandLogo {
cursor: pointer;
transition: 10s;
filter: drop-shadow(2px 1px 1px grey);
}
.commandLogo:hover {
transition: 10s;
transform: rotate(360deg);
}
</style>

View File

@@ -0,0 +1,352 @@
<template>
<q-scroll-area
:thumb-style="{
width: '3px',
}"
>
<div class="row q-pa-md q-gutter-md">
<q-btn
dense
flat
color="grey"
icon="arrow_back_ios_new"
@click="$parent.closeEditor"
/>
<q-img
class="commandLogo"
width="64px"
:src="currentCommand.features.icon"
/>
<div class="row">
<div>
<!-- 说明 -->
<q-input
stack-label
label-color="primary"
borderless
square
v-model="currentCommand.features.explain"
type="text"
placeholder="请输入说明"
label="说明"
>
<template v-slot:prepend>
<q-icon color="primary" name="drive_file_rename_outline" />
</template>
</q-input>
<!-- 匹配类型 -->
<q-select
hide-dropdown-icon
stack-label
label-color="primary"
transition-show="jump-down"
transition-hide="jump-up"
borderless
square
@update:model-value="
(val) =>
(cmdMatch =
val.name === 'professional'
? JSON.stringify(val.jsonSample, null, 4)
: null)
"
:options="commandTypesOptions"
v-model="cmdType"
type="text"
label="匹配类型"
>
<template v-slot:prepend>
<q-icon color="primary" :name="cmdType.icon" />
</template>
<template v-slot:option="scope">
<q-item v-bind="scope.itemProps">
<q-item-section avatar>
<q-icon :name="scope.opt.icon" />
</q-item-section>
<q-item-section>
<q-item-label v-html="scope.opt.name" />
<q-item-label caption>{{ scope.opt.desc }}</q-item-label>
</q-item-section>
</q-item>
</template>
</q-select>
<!-- 匹配规则 -->
<q-select
hide-dropdown-icon
stack-label
label-color="primary"
transition-show="jump-down"
transition-hide="jump-up"
v-if="cmdType.valueType === 'array'"
borderless
square
v-model="cmdMatch"
max-values="3"
type="text"
placeholder="键入后回车"
use-input
use-chips
multiple
new-value-mode="add-unique"
input-debounce="0"
:label="cmdType.matchLabel"
>
<template v-slot:prepend>
<q-icon color="primary" name="square_foot" />
</template>
</q-select>
<q-input
v-else
autogrow
borderless
square
v-model="cmdMatch"
hide-bottom-space
@blur="regexVerify"
:readonly="!cmdType.valueType"
type="text"
:label="cmdType.matchLabel"
>
<template v-slot:prepend>
<q-icon color="primary" name="square_foot" />
</template>
</q-input>
<!-- 标签 -->
<q-select
hide-dropdown-icon
stack-label
label-color="primary"
transition-show="jump-down"
transition-hide="jump-up"
borderless
square
v-model="currentCommand.tags"
max-values="3"
type="text"
label="标签"
placeholder="键入后回车"
use-input
use-chips
multiple
new-value-mode="add-unique"
input-debounce="0"
:options="allQuickCommandTags"
>
<template v-slot:prepend>
<q-icon color="primary" name="label" />
</template>
</q-select>
<!-- 特殊变量 -->
<q-select
hide-dropdown-icon
stack-label
label-color="primary"
transition-show="jump-down"
transition-hide="jump-up"
borderless
square
:options="specialVarsOptions"
v-model="specialVar"
input-debounce="0"
type="text"
label="特殊变量"
>
<template v-slot:prepend>
<q-icon color="primary" name="attach_money" />
</template>
<template v-slot:option="scope">
<q-item v-bind="scope.itemProps">
<q-item-section>
<q-item-label v-html="scope.opt.name" />
<q-item-label caption>{{ scope.opt.desc }}</q-item-label>
</q-item-section>
</q-item>
</template></q-select
>
<!-- 输出 -->
<q-select
hide-dropdown-icon
stack-label
label-color="primary"
transition-show="jump-down"
transition-hide="jump-up"
borderless
square
color="primary"
v-model="currentCommand.output"
:display-value="outputTypes[currentCommand.output].label"
:options="outputTypesOptions"
label="输出"
>
<template v-slot:prepend>
<q-icon
color="primary"
:name="outputTypes[currentCommand.output].icon"
/>
</template>
<template v-slot:option="scope">
<q-item v-bind="scope.itemProps">
<q-item-section avatar>
<q-icon :name="outputTypes[scope.opt].icon" />
</q-item-section>
<q-item-section>
<q-item-label v-html="outputTypes[scope.opt].label" />
</q-item-section>
</q-item>
</template>
</q-select>
<!-- 平台 -->
<q-select
hide-dropdown-icon
stack-label
label-color="primary"
transition-show="jump-down"
transition-hide="jump-up"
borderless
square
:options="['win32', 'linux', 'darwin']"
use-chips
@blur="platformVerify()"
v-model="currentCommand.features.platform"
multiple
label="平台"
>
<template v-slot:prepend>
<q-icon color="primary" name="window" />
</template>
</q-select>
</div>
</div>
</div>
</q-scroll-area>
</template>
<script>
import commandTypes from "../js/options/commandTypes.js";
import outputTypes from "../js/options/outputTypes.js";
import specialVars from "../js/options/specialVars.js";
let commandTypesOptions = Object.values(commandTypes);
export default {
data() {
return {
currentCommand: {
tags: [],
output: "text",
features: {
explain: "",
platform: ["win32", "linux", "darwin"],
icon: "",
},
},
commandTypes: commandTypes,
commandTypesOptions: commandTypesOptions,
currentMatchType: "关键字",
cmdType: commandTypesOptions[0],
cmdMatch: "",
outputTypes: outputTypes,
outputTypesOptions: Object.keys(outputTypes),
specialVar: "{{}}",
specialVarsOptions: Object.values(specialVars),
allQuickCommandTags: this.$parent.parent.allQuickCommandTags,
};
},
props: {
quickcommandInfo: Object,
},
mounted() {
window.CommandMenu = this;
},
computed: {},
methods: {
init() {
let currentQuickCommandCmds = this.getCommandType();
this.cmdType = this.commandTypes[currentQuickCommandCmds.type];
this.cmdMatch = currentQuickCommandCmds.match;
Object.assign(
this.currentCommand,
JSON.parse(JSON.stringify(this.quickcommandInfo))
);
this.setIcon(this.currentCommand.program);
this.platformVerify();
},
// 没有图标,或者使用了语言图标
setIcon(language) {
this.currentCommand.features.icon?.slice(0, 5) === "data:" ||
(this.currentCommand.features.icon =
this.$parent.getLanguageIcon(language));
},
getCommandType() {
let data = { type: "key", match: [] };
let cmds = this.quickcommandInfo.features?.cmds;
if (!cmds) return data;
if (cmds.length === 1) {
let { type, match } = cmds[0];
data.type = type ? type : "key";
data.match =
data.type === "key" ? cmds : match?.app ? match.app : match;
} else {
data.type = cmds.filter((x) => !x.length).length
? "professional"
: "key";
data.match = data.type === "key" ? cmds : JSON.stringify(cmds, null, 4);
}
return data;
},
// 平台为空自动补充
platformVerify() {
this.currentCommand.features.platform?.length > 0 ||
this.currentCommand.features.platform.push(window.processPlatform);
},
// 正则不和规则自动加斜杠
regexVerify() {
console.log(1);
if (
this.cmdType.valueType === "regex" &&
!/^\/.*?\/[igm]*$/.test(this.cmdMatch)
)
this.cmdMatch = `/${this.cmdMatch}/`;
},
// 保存各类数据
SaveMenuData() {
let updateData = {
features: this.currentCommand.features,
output: this.currentCommand.output,
tags: this.currentCommand.tags,
};
// 说明为空填充一个空格
updateData.features.explain || (updateData.features.explain = " ");
if (!updateData.features.code) {
// 生成唯一code
let uid = Number(
Math.random().toString().substr(3, 3) + Date.now()
).toString(36);
updateData.features.code = `${this.cmdType.name}_${uid}`;
}
let verify = this.cmdType.verify(this.cmdMatch);
if (verify !== true) {
return quickcommand.showMessageBox(verify, "error");
}
updateData.features.cmds = this.cmdType.matchToCmds(
this.cmdMatch,
updateData.features.explain
);
return updateData;
},
},
};
</script>
<style scoped>
.commandLogo {
cursor: pointer;
transition: 10s;
filter: drop-shadow(2px 1px 1px grey);
}
.commandLogo:hover {
transition: 10s;
transform: rotate(360deg);
}
</style>