mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-06-28 20:02:44 +08:00
VarInput支持选择文件
This commit is contained in:
parent
5ea6850bb9
commit
516e6c2d16
@ -325,7 +325,8 @@ export default defineComponent({
|
||||
const tempFlow = [
|
||||
command,
|
||||
{
|
||||
code: `console.log(${command.outputVariable})`,
|
||||
//没有输出,则不打印
|
||||
code: `${command.outputVariable} && console.log(${command.outputVariable})`,
|
||||
},
|
||||
];
|
||||
// 触发运行事件
|
||||
|
@ -29,36 +29,68 @@
|
||||
class="flex-item"
|
||||
:style="{ flex: item.width || 12 }"
|
||||
>
|
||||
<div v-if="item.type === 'varInput'">
|
||||
<VariableInput
|
||||
:model-value="argvs[index]"
|
||||
@update:model-value="updateArgv(index, $event)"
|
||||
:label="item.label"
|
||||
:icon="item.icon"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="item.type === 'numInput'">
|
||||
<NumberInput
|
||||
:model-value="argvs[index]"
|
||||
@update:model-value="updateArgv(index, $event)"
|
||||
:label="item.label"
|
||||
:icon="item.icon"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="item.type === 'switch'">
|
||||
<q-toggle
|
||||
:model-value="argvs[index]"
|
||||
@update:model-value="updateArgv(index, $event)"
|
||||
:label="item.label"
|
||||
:icon="item.icon"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="item.type === 'arrayEditor'">
|
||||
<ArrayEditor
|
||||
:model-value="argvs[index]"
|
||||
@update:model-value="updateArgv(index, $event)"
|
||||
/>
|
||||
</div>
|
||||
<VariableInput
|
||||
v-if="item.type === 'varInput'"
|
||||
:model-value="argvs[index]"
|
||||
@update:model-value="updateArgv(index, $event)"
|
||||
:label="item.label"
|
||||
:icon="item.icon"
|
||||
:options="item.options"
|
||||
/>
|
||||
<NumberInput
|
||||
v-else-if="item.type === 'numInput'"
|
||||
:model-value="argvs[index]"
|
||||
@update:model-value="updateArgv(index, $event)"
|
||||
:label="item.label"
|
||||
:icon="item.icon"
|
||||
/>
|
||||
<ArrayEditor
|
||||
v-else-if="item.type === 'arrayEditor'"
|
||||
:model-value="argvs[index]"
|
||||
@update:model-value="updateArgv(index, $event)"
|
||||
:options="item.options"
|
||||
/>
|
||||
<DictEditor
|
||||
v-else-if="item.type === 'dictEditor'"
|
||||
:model-value="argvs[index]"
|
||||
@update:model-value="updateArgv(index, $event)"
|
||||
:options="item.options"
|
||||
/>
|
||||
<q-toggle
|
||||
v-else-if="item.type === 'switch'"
|
||||
:model-value="argvs[index]"
|
||||
@update:model-value="updateArgv(index, $event)"
|
||||
:label="item.label"
|
||||
:icon="item.icon"
|
||||
/>
|
||||
<q-select
|
||||
v-else-if="item.type === 'select'"
|
||||
:model-value="argvs[index]"
|
||||
@update:model-value="updateArgv(index, $event)"
|
||||
:options="item.options"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon :name="item.icon" />
|
||||
</template>
|
||||
</q-select>
|
||||
<q-input
|
||||
v-else-if="item.type === 'input'"
|
||||
:model-value="argvs[index]"
|
||||
@update:model-value="updateArgv(index, $event)"
|
||||
:label="item.label"
|
||||
:icon="item.icon"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-icon :name="item.icon" />
|
||||
</template>
|
||||
</q-input>
|
||||
<q-checkbox
|
||||
v-else-if="item.type === 'checkbox'"
|
||||
:model-value="argvs[index]"
|
||||
@update:model-value="updateArgv(index, $event)"
|
||||
:label="item.label"
|
||||
:icon="item.icon"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -69,6 +101,7 @@ import { defineComponent } from "vue";
|
||||
import VariableInput from "components/composer/common/VariableInput.vue";
|
||||
import NumberInput from "components/composer/common/NumberInput.vue";
|
||||
import ArrayEditor from "components/composer/common/ArrayEditor.vue";
|
||||
import DictEditor from "components/composer/common/DictEditor.vue";
|
||||
import { stringifyArgv, parseFunction } from "js/composer/formatString";
|
||||
|
||||
export default defineComponent({
|
||||
@ -77,6 +110,7 @@ export default defineComponent({
|
||||
VariableInput,
|
||||
NumberInput,
|
||||
ArrayEditor,
|
||||
DictEditor,
|
||||
},
|
||||
props: {
|
||||
modelValue: {
|
||||
@ -141,6 +175,8 @@ export default defineComponent({
|
||||
variableFormatPaths.push(`arg${index}`);
|
||||
} else if (item.type === "arrayEditor") {
|
||||
variableFormatPaths.push(`arg${index}[*]`);
|
||||
} else if (item.type === "dictEditor") {
|
||||
variableFormatPaths.push(`arg${index}.**`);
|
||||
}
|
||||
});
|
||||
try {
|
||||
|
@ -1,11 +1,11 @@
|
||||
<template>
|
||||
<div class="array-editor">
|
||||
<div v-for="(item, index) in items" :key="index" class="row items-center">
|
||||
<template v-if="optionsKeys">
|
||||
<template v-if="options.keys">
|
||||
<div
|
||||
v-for="key in optionsKeys"
|
||||
v-for="key in options.keys"
|
||||
:key="key"
|
||||
:class="['col', optionsKeys.length > 1 ? 'q-pr-sm' : '']"
|
||||
:class="['col', options.keys.length > 1 ? 'q-pr-sm' : '']"
|
||||
>
|
||||
<VariableInput
|
||||
:model-value="item[key]"
|
||||
@ -21,7 +21,9 @@
|
||||
:model-value="item"
|
||||
:label="`${label || '项目'} ${index + 1}`"
|
||||
:icon="icon || 'code'"
|
||||
:options="options"
|
||||
:options="{
|
||||
items: options.items,
|
||||
}"
|
||||
@update:model-value="(val) => updateItemValue(index, val)"
|
||||
/>
|
||||
</div>
|
||||
@ -81,8 +83,8 @@
|
||||
* @property {String} label - 输入框标签
|
||||
* @property {String} icon - 输入框图标
|
||||
* @property {Object} options - 配置选项
|
||||
* @property {String[]} [optionsKeys] - 多键对象模式的键名列表
|
||||
* @property {String[]} [options] - 下拉选择模式的选项列表
|
||||
* @property {String[]} [options.keys] - 多键对象模式的键名列表
|
||||
* @property {String[]} [options.items] - 下拉选择模式的选项列表
|
||||
*
|
||||
* @example
|
||||
* // 基础数组
|
||||
@ -95,7 +97,7 @@
|
||||
* ]
|
||||
*
|
||||
* // 多键对象数组
|
||||
* optionsKeys = ['name', 'age', 'email']
|
||||
* options.keys = ['name', 'age', 'email']
|
||||
* [
|
||||
* {
|
||||
* name: { value: "张三", isString: true, __varInputVal__: true },
|
||||
@ -105,7 +107,7 @@
|
||||
* ]
|
||||
*
|
||||
* // 下拉选择模式
|
||||
* options = ['选项1', '选项2', '选项3']
|
||||
* options.items = ['选项1', '选项2', '选项3']
|
||||
* [
|
||||
* {
|
||||
* value: "选项1",
|
||||
@ -136,12 +138,8 @@ export default defineComponent({
|
||||
default: "",
|
||||
},
|
||||
options: {
|
||||
type: Array,
|
||||
default: null,
|
||||
},
|
||||
optionsKeys: {
|
||||
type: Array,
|
||||
default: null,
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
emits: ["update:modelValue"],
|
||||
@ -152,9 +150,9 @@ export default defineComponent({
|
||||
},
|
||||
methods: {
|
||||
initializeItems() {
|
||||
if (this.optionsKeys) {
|
||||
if (this.options.keys) {
|
||||
const item = {};
|
||||
this.optionsKeys.forEach((key) => {
|
||||
this.options.keys.forEach((key) => {
|
||||
item[key] = {
|
||||
value: "",
|
||||
isString: false,
|
||||
@ -178,9 +176,9 @@ export default defineComponent({
|
||||
*/
|
||||
addItem() {
|
||||
let newItems = [];
|
||||
if (this.optionsKeys) {
|
||||
if (this.options.keys) {
|
||||
const newItem = {};
|
||||
this.optionsKeys.forEach((key) => {
|
||||
this.options.keys.forEach((key) => {
|
||||
newItem[key] = {
|
||||
value: "",
|
||||
isString: false,
|
||||
@ -208,9 +206,9 @@ export default defineComponent({
|
||||
const newItems = [...this.items];
|
||||
newItems.splice(index, 1);
|
||||
if (newItems.length === 0) {
|
||||
if (this.optionsKeys) {
|
||||
if (this.options.keys) {
|
||||
const newItem = {};
|
||||
this.optionsKeys.forEach((key) => {
|
||||
this.options.keys.forEach((key) => {
|
||||
newItem[key] = {
|
||||
value: "",
|
||||
isString: false,
|
||||
|
@ -137,7 +137,7 @@ export default defineComponent({
|
||||
},
|
||||
options: {
|
||||
type: Object,
|
||||
default: null,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
emits: ["update:modelValue"],
|
||||
|
@ -11,10 +11,9 @@
|
||||
v-if="hasSelectedVariable"
|
||||
flat
|
||||
dense
|
||||
round
|
||||
icon="close"
|
||||
size="sm"
|
||||
class="clear-btn q-mr-xs"
|
||||
class="clear-btn prepend-btn"
|
||||
@click="clearVariable"
|
||||
>
|
||||
<q-tooltip>清除选中的变量</q-tooltip>
|
||||
@ -22,10 +21,9 @@
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
round
|
||||
:icon="isString ? 'format_quote' : 'data_object'"
|
||||
size="sm"
|
||||
class="string-toggle"
|
||||
class="string-toggle prepend-btn"
|
||||
@click="toggleType"
|
||||
v-if="!hasSelectedVariable"
|
||||
>
|
||||
@ -37,29 +35,40 @@
|
||||
</q-btn>
|
||||
<!-- 选项下拉按钮 -->
|
||||
<q-btn-dropdown
|
||||
v-if="options && !hasSelectedVariable"
|
||||
v-if="options.items && !hasSelectedVariable"
|
||||
flat
|
||||
dense
|
||||
size="sm"
|
||||
dropdown-icon="menu"
|
||||
no-icon-animation
|
||||
class="options-dropdown"
|
||||
class="options-dropdown prepend-btn"
|
||||
>
|
||||
<q-list class="options-list">
|
||||
<q-list class="options-item-list">
|
||||
<q-item
|
||||
v-for="option in normalizedOptions"
|
||||
:key="getOptionValue(option)"
|
||||
v-for="item in normalizedItems"
|
||||
:key="getItemValue(item)"
|
||||
clickable
|
||||
v-close-popup
|
||||
@click="selectOption(option)"
|
||||
@click="selectItem(item)"
|
||||
class="option-item"
|
||||
>
|
||||
<q-item-section>
|
||||
{{ getOptionLabel(option) }}
|
||||
{{ getItemLabel(item) }}
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-btn-dropdown>
|
||||
<q-btn
|
||||
v-if="!hasSelectedVariable && options.dialog"
|
||||
flat
|
||||
dense
|
||||
icon="file_open"
|
||||
size="sm"
|
||||
class="prepend-btn"
|
||||
@click="handleFileOpen(options.dialog)"
|
||||
>
|
||||
<q-tooltip>选择文件</q-tooltip>
|
||||
</q-btn>
|
||||
<!-- 变量选择下拉 -->
|
||||
<q-btn-dropdown
|
||||
flat
|
||||
@ -68,7 +77,7 @@
|
||||
'text-primary': hasSelectedVariable,
|
||||
'text-grey-6': !hasSelectedVariable,
|
||||
}"
|
||||
class="variable-dropdown"
|
||||
class="variable-dropdown prepend-btn"
|
||||
size="sm"
|
||||
v-if="variables.length"
|
||||
>
|
||||
@ -118,8 +127,12 @@ import { defineComponent, inject } from "vue";
|
||||
* @property {Object} modelValue - 输入框的值对象
|
||||
* @property {String} label - 输入框标签
|
||||
* @property {String} icon - 输入框图标
|
||||
* @property {String[]} [options] - 可选的下拉选项列表
|
||||
*
|
||||
* @property {Object} [options] - 可选的配置对象
|
||||
* @property {Array} [options.items] - 选项列表
|
||||
* @property {Boolean} [options.dialog] - 是否显示文件选择对话框
|
||||
* @property {Object} [options.dialog] - 文件选择对话框配置
|
||||
* @property {String} [options.dialog.type] - 对话框类型,open 或 save
|
||||
* @property {Object} [options.dialog.options] - 对话框选项,对应 utools.showOpenDialog 和 utools.showSaveDialog 的 options
|
||||
* @example
|
||||
* // modelValue 对象格式
|
||||
* {
|
||||
@ -127,6 +140,18 @@ import { defineComponent, inject } from "vue";
|
||||
* isString: true, // 是否是字符串
|
||||
* __varInputVal__: true // 用于标识是变量输入框
|
||||
* }
|
||||
* @example
|
||||
* // options 对象格式
|
||||
* {
|
||||
* items: ["item1", "item2", "item3"], // 选项列表
|
||||
* dialog: {
|
||||
* type: "open", // 对话框类型,open 或 save
|
||||
* options: {
|
||||
* title: "选择文件",
|
||||
* defaultPath: "/",
|
||||
* },
|
||||
* },
|
||||
* }
|
||||
*/
|
||||
export default defineComponent({
|
||||
name: "VariableInput",
|
||||
@ -144,18 +169,8 @@ export default defineComponent({
|
||||
label: String,
|
||||
icon: String,
|
||||
options: {
|
||||
type: Array,
|
||||
default: null,
|
||||
validator(value) {
|
||||
if (!value) return true;
|
||||
// 检查数组中的每一项是否符合格式要求
|
||||
return value.every((item) => {
|
||||
return (
|
||||
typeof item === "string" || // ["xxx", "yyy"]
|
||||
(typeof item === "object" && "label" in item && "value" in item) // [{label: "xxx", value: "yyy"}]
|
||||
);
|
||||
});
|
||||
},
|
||||
type: Object,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
|
||||
@ -202,14 +217,13 @@ export default defineComponent({
|
||||
},
|
||||
|
||||
// 标准化选项格式
|
||||
normalizedOptions() {
|
||||
console.log(this.options);
|
||||
if (!this.options) return [];
|
||||
return this.options.map((option) => {
|
||||
if (typeof option === "string") {
|
||||
return { label: option, value: option };
|
||||
normalizedItems() {
|
||||
if (!this.options.items) return [];
|
||||
return this.options.items.map((item) => {
|
||||
if (typeof item === "string") {
|
||||
return { label: item, value: item };
|
||||
}
|
||||
return option;
|
||||
return item;
|
||||
});
|
||||
},
|
||||
},
|
||||
@ -245,22 +259,56 @@ export default defineComponent({
|
||||
});
|
||||
},
|
||||
|
||||
getOptionLabel(option) {
|
||||
getItemLabel(option) {
|
||||
return typeof option === "string" ? option : option.label;
|
||||
},
|
||||
|
||||
getOptionValue(option) {
|
||||
getItemValue(option) {
|
||||
return typeof option === "string" ? option : option.value;
|
||||
},
|
||||
|
||||
selectOption(option) {
|
||||
const value = this.getOptionValue(option);
|
||||
selectItem(option) {
|
||||
const value = this.getItemValue(option);
|
||||
this.$emit("update:modelValue", {
|
||||
value,
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
});
|
||||
},
|
||||
escapePath(paths) {
|
||||
if (!paths) return null;
|
||||
if (typeof paths === "string") return paths.replace(/\\/g, "\\\\");
|
||||
return paths.map((path) => path.replace(/\\/g, "\\\\"));
|
||||
},
|
||||
handleFileOpen(dialog) {
|
||||
let { type, options } = window.lodashM.cloneDeep(dialog);
|
||||
if (!type) type = "open";
|
||||
if (type === "open") {
|
||||
const files = this.escapePath(utools.showOpenDialog(options));
|
||||
if (!files) return;
|
||||
if (files.length > 1) {
|
||||
this.$emit("update:modelValue", {
|
||||
value: files,
|
||||
isString: false,
|
||||
__varInputVal__: true,
|
||||
});
|
||||
} else if (files.length === 1) {
|
||||
this.$emit("update:modelValue", {
|
||||
value: files[0],
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
const file = this.escapePath(utools.showSaveDialog(options));
|
||||
if (!file) return;
|
||||
this.$emit("update:modelValue", {
|
||||
value: file,
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@ -275,31 +323,20 @@ export default defineComponent({
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
/* 字符串切换按钮样式 */
|
||||
.string-toggle {
|
||||
.prepend-btn {
|
||||
min-width: 24px;
|
||||
padding: 4px;
|
||||
opacity: 0.6;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.string-toggle:hover {
|
||||
.prepend-btn:hover {
|
||||
opacity: 1;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
/* 变量下拉框样式 */
|
||||
.variable-dropdown {
|
||||
min-width: 32px;
|
||||
padding: 4px;
|
||||
opacity: 0.8;
|
||||
transition: all 0.3s ease;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.variable-dropdown:hover {
|
||||
opacity: 1;
|
||||
transform: scale(1.05);
|
||||
.clear-btn:hover {
|
||||
color: var(--q-negative);
|
||||
}
|
||||
|
||||
/* 变量列表样式 */
|
||||
@ -316,7 +353,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
.variable-item:hover {
|
||||
background: var(--q-primary-opacity-10);
|
||||
backg: var(--q-primary-opacity-10);
|
||||
}
|
||||
|
||||
.variable-label {
|
||||
@ -341,33 +378,7 @@ export default defineComponent({
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
/* 清空按钮样式 */
|
||||
.clear-btn {
|
||||
opacity: 0.6;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.clear-btn:hover {
|
||||
opacity: 1;
|
||||
transform: scale(1.1);
|
||||
color: var(--q-negative);
|
||||
}
|
||||
|
||||
/* 选项下拉框样式 */
|
||||
.options-dropdown {
|
||||
min-width: 32px;
|
||||
padding: 4px;
|
||||
opacity: 0.8;
|
||||
transition: all 0.3s ease;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
.options-dropdown:hover {
|
||||
opacity: 1;
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.options-list {
|
||||
.options-item-list {
|
||||
min-width: 120px;
|
||||
padding: 4px;
|
||||
}
|
||||
@ -383,11 +394,11 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
.option-item:hover {
|
||||
background: var(--q-primary-opacity-10);
|
||||
backg: var(--q-primary-opacity-10);
|
||||
}
|
||||
|
||||
/* 暗色模式适配 */
|
||||
.body--dark .option-item:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
backg: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
</style>
|
||||
|
@ -54,25 +54,24 @@
|
||||
</div>
|
||||
|
||||
<!-- 文件路径输入 -->
|
||||
<div class="row q-gutter-sm">
|
||||
<VariableInput
|
||||
:model-value="argvs.filePath"
|
||||
@update:model-value="updateArgvs('filePath', $event)"
|
||||
label="文件路径"
|
||||
icon="folder"
|
||||
class="col-grow"
|
||||
/>
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
round
|
||||
icon="folder_open"
|
||||
class="self-center"
|
||||
@click="selectFile"
|
||||
>
|
||||
<q-tooltip>选择文件</q-tooltip>
|
||||
</q-btn>
|
||||
</div>
|
||||
<VariableInput
|
||||
:model-value="argvs.filePath"
|
||||
@update:model-value="updateArgvs('filePath', $event)"
|
||||
label="文件路径"
|
||||
icon="folder"
|
||||
class="col-grow"
|
||||
:options="{
|
||||
dialog: {
|
||||
options: {
|
||||
title: '选择文件',
|
||||
properties: [
|
||||
shouldSelectDirectory ? 'openDirectory' : 'openFile',
|
||||
'showHiddenFiles',
|
||||
],
|
||||
},
|
||||
},
|
||||
}"
|
||||
/>
|
||||
|
||||
<!-- 读取操作配置 -->
|
||||
<template v-if="argvs.operation === 'read'">
|
||||
@ -584,23 +583,6 @@ export default defineComponent({
|
||||
|
||||
this.updateModelValue(argvs);
|
||||
},
|
||||
async selectFile() {
|
||||
const result = window.utools.showOpenDialog({
|
||||
title: "选择文件",
|
||||
properties: [
|
||||
this.shouldSelectDirectory ? "openDirectory" : "openFile",
|
||||
"showHiddenFiles",
|
||||
],
|
||||
buttonLabel: "选择",
|
||||
});
|
||||
if (result && result[0]) {
|
||||
this.updateArgvs("filePath", {
|
||||
value: result[0],
|
||||
isString: true,
|
||||
__varInputVal__: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
updateMode() {
|
||||
const modeMap = {
|
||||
read: 4,
|
||||
|
@ -90,7 +90,9 @@
|
||||
:model-value="argvs.headers['User-Agent']"
|
||||
@update:model-value="updateArgvs('headers.User-Agent', $event)"
|
||||
label="User Agent"
|
||||
:options="userAgentOptions"
|
||||
:options="{
|
||||
items: userAgentOptions,
|
||||
}"
|
||||
icon="devices"
|
||||
class="col-grow"
|
||||
/>
|
||||
|
@ -19,6 +19,12 @@ export const fileCommands = {
|
||||
label: "文件、文件夹或软件的绝对路径",
|
||||
type: "varInput",
|
||||
icon: "folder_open",
|
||||
options: {
|
||||
dialog: {
|
||||
type: "open",
|
||||
options: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -31,6 +37,12 @@ export const fileCommands = {
|
||||
label: "文件、文件夹或软件的绝对路径",
|
||||
type: "varInput",
|
||||
icon: "location_on",
|
||||
options: {
|
||||
dialog: {
|
||||
type: "open",
|
||||
options: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -43,6 +55,15 @@ export const fileCommands = {
|
||||
label: "文件或软件的绝对路径",
|
||||
type: "varInput",
|
||||
icon: "folder_open",
|
||||
options: {
|
||||
dialog: {
|
||||
type: "open",
|
||||
options: {
|
||||
filters: [{ extensions: ["exe", "app"] }],
|
||||
properties: ["openFile", "openDirectory"],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user