mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-09-24 13:03:30 +08:00
弹窗组件归类
This commit is contained in:
88
src/components/popup/AboutThis.vue
Normal file
88
src/components/popup/AboutThis.vue
Normal file
@@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<q-card>
|
||||
<q-card-section class="q-gutter-md flex items-center">
|
||||
<q-avatar square size="48px">
|
||||
<img src="logo/quickcommand.png" />
|
||||
</q-avatar>
|
||||
<span class="text-h5"
|
||||
>{{ pluginInfo.pluginName }} v{{ pluginInfo.version }}</span
|
||||
>
|
||||
</q-card-section>
|
||||
<q-card-section> {{ pluginInfo.description }} </q-card-section>
|
||||
<q-card-section>
|
||||
<div v-for="group in Object.keys(links)" :key="group" class="q-gutter-sm">
|
||||
<q-btn
|
||||
flat
|
||||
color="primary"
|
||||
v-for="item in links[group]"
|
||||
:key="item"
|
||||
@click="visit(item.url)"
|
||||
:label="item.name"
|
||||
><q-tooltip>{{ item.desc }} </q-tooltip></q-btn
|
||||
>
|
||||
<br />
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-actions align="right">
|
||||
<q-btn flat label="确定" color="primary" v-close-popup />
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const links = {
|
||||
plugin: [
|
||||
{
|
||||
name: "帮助",
|
||||
url: "",
|
||||
desc: "查看插件使用帮助",
|
||||
},
|
||||
{
|
||||
name: "源码",
|
||||
url: "https://github.com/fofolee/uTools-quickcommand",
|
||||
desc: "本插件完全开源,记得 Star 哟",
|
||||
},
|
||||
{
|
||||
name: "论坛",
|
||||
url: "https://yuanliao.info/d/424-242-242",
|
||||
desc: "到猿料论坛参与讨论吧",
|
||||
},
|
||||
],
|
||||
tech: [
|
||||
{
|
||||
name: "Vue.js",
|
||||
url: "https://v3.cn.vuejs.org/",
|
||||
desc: "基于 Vue.js 开发",
|
||||
},
|
||||
{
|
||||
name: "Quasar Framework",
|
||||
url: "https://quasar.dev/",
|
||||
desc: "基于 Quasar Framework 开发",
|
||||
},
|
||||
{
|
||||
name: "Google Fonts",
|
||||
url: "https://fonts.google.com/",
|
||||
desc: "文字图标来自 Google Fonts",
|
||||
},
|
||||
{
|
||||
name: "Icon8s",
|
||||
url: "https://icons8.com/",
|
||||
desc: "彩色图标来自 Icon8s",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
pluginInfo: window.pluginInfo(),
|
||||
links: links,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
visit(url) {
|
||||
utools.shellOpenExternal(url);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
213
src/components/popup/IconPicker.vue
Normal file
213
src/components/popup/IconPicker.vue
Normal file
@@ -0,0 +1,213 @@
|
||||
<template>
|
||||
<div>
|
||||
<q-dialog v-model="showIconPicker" class="q-gutter" :position="position">
|
||||
<q-card>
|
||||
<q-card-section class="text-h5 text-center">更改图标</q-card-section>
|
||||
<q-card-section>
|
||||
<q-select
|
||||
ref="icon8"
|
||||
v-model="icon8sIcon"
|
||||
:options="options"
|
||||
label="搜索ICON8S"
|
||||
options-dense
|
||||
use-input
|
||||
:loading="loading"
|
||||
input-debounce="1000"
|
||||
@input-value="searchIcon8s"
|
||||
@update:model-value="getIcon8sIcon"
|
||||
transition-show="jump-down"
|
||||
transition-hide="jump-up"
|
||||
virtual-scroll-slice-size="30"
|
||||
standout="bg-primary text-white"
|
||||
>
|
||||
<template v-slot:no-option>
|
||||
<q-item>
|
||||
<q-item-section class="text-grey">
|
||||
键入关键词搜索
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</template>
|
||||
<template v-slot:selected>
|
||||
<!-- {{ icon8sIcon?.name || "" }} -->
|
||||
</template>
|
||||
<template v-slot:prepend>
|
||||
<q-avatar size="24px" v-if="dataUrl && icon8sIcon">
|
||||
<q-img :src="dataUrl" />
|
||||
</q-avatar>
|
||||
<q-icon v-else name="image" />
|
||||
</template>
|
||||
<template v-slot:option="scope">
|
||||
<q-item v-bind="scope.itemProps">
|
||||
<q-item-section avatar>
|
||||
<q-img :src="getIcon8sIconUrl(scope.opt, 1)" />
|
||||
</q-item-section>
|
||||
<q-item-section>
|
||||
<q-item-label v-html="scope.opt.name" />
|
||||
</q-item-section>
|
||||
</q-item> </template
|
||||
></q-select>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-file
|
||||
standout="bg-primary text-white"
|
||||
:display-value="localIconFile || ''"
|
||||
@click="getLocalIcon"
|
||||
label="选择本地资源"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-avatar size="24px" v-if="dataUrl && localIconFile">
|
||||
<q-img :src="dataUrl" />
|
||||
</q-avatar>
|
||||
<q-icon v-else name="folder" />
|
||||
</template>
|
||||
</q-file>
|
||||
</q-card-section>
|
||||
<q-card-section>
|
||||
<q-input
|
||||
standout="bg-primary text-white"
|
||||
v-model="netWorkIconUrl"
|
||||
@blur="getRemoteIcon"
|
||||
type="text"
|
||||
label="网络图片地址"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<q-avatar size="24px" v-if="dataUrl && netWorkIconUrl">
|
||||
<q-img :src="dataUrl" />
|
||||
</q-avatar>
|
||||
<q-icon v-else name="cloud" /> </template
|
||||
></q-input>
|
||||
</q-card-section>
|
||||
<q-card-actions align="right">
|
||||
<q-btn flat color="primary" @click="showIconPicker = false"
|
||||
>确定</q-btn
|
||||
>
|
||||
</q-card-actions>
|
||||
</q-card>
|
||||
</q-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref } from "vue";
|
||||
import pictureCompress from "picture-compressor";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
showIconPicker: false,
|
||||
localIconFile: ref(null),
|
||||
icon8sIcon: ref(null),
|
||||
netWorkIconUrl: "",
|
||||
options: ref(null),
|
||||
loading: false,
|
||||
icon8: {
|
||||
platform: "color",
|
||||
amount: "300",
|
||||
baseUrl: "https://search.icons8.com/api/iconsets/v5/search",
|
||||
},
|
||||
dataUrl: null,
|
||||
};
|
||||
},
|
||||
props: {
|
||||
position: String,
|
||||
},
|
||||
methods: {
|
||||
setIcon(dataUrl) {
|
||||
this.dataUrl = dataUrl;
|
||||
this.$emit("iconChanged", dataUrl);
|
||||
},
|
||||
|
||||
searchIcon8s(val) {
|
||||
if (!val) return;
|
||||
this.loading = true;
|
||||
let language = /[\u4e00-\u9fa5]/.test(val) ? "zh" : "en";
|
||||
let apiUrl = `${this.icon8.baseUrl}?term=${val}&amount=${this.icon8.amount}&offset=0&platform=${this.icon8.platform}&language=${language}`;
|
||||
fetch(apiUrl)
|
||||
.then((res) => res.json())
|
||||
.then((res) => {
|
||||
this.options = res.icons;
|
||||
this.$refs.icon8.showPopup();
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
|
||||
getIcon8sIconUrl(icon, size) {
|
||||
return `https://img.icons8.com/color/${size}x/${icon.commonName}.png`;
|
||||
},
|
||||
|
||||
getIcon8sIcon() {
|
||||
let imgUrl = this.getIcon8sIconUrl(this.icon8sIcon, 2);
|
||||
this.getRemoteIcon(imgUrl);
|
||||
},
|
||||
|
||||
getLocalIcon(e) {
|
||||
// q-file 无法获取 .app 的路径,改用 utools.showOpenDialog
|
||||
e.preventDefault();
|
||||
this.localIconFile = utools.showOpenDialog({
|
||||
title: "请选择图片文件或者可执行文件",
|
||||
filters: [
|
||||
{
|
||||
name: "localFile",
|
||||
extensions: [
|
||||
"png",
|
||||
"jpg",
|
||||
"jpeg",
|
||||
"bmp",
|
||||
"ico",
|
||||
"gif",
|
||||
"svg",
|
||||
"app",
|
||||
"exe",
|
||||
],
|
||||
},
|
||||
],
|
||||
})[0];
|
||||
if (
|
||||
this.localIconFile.slice(-4) === ".app" ||
|
||||
this.localIconFile.slice(-4) === ".exe"
|
||||
)
|
||||
return this.setIcon(utools.getFileIcon(this.localIconFile));
|
||||
this.compressingPic(window.getBase64Ico(this.localIconFile)).then(
|
||||
(dataUrl) => {
|
||||
dataUrl && this.setIcon(dataUrl);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
getRemoteIcon(url = this.netWorkIconUrl) {
|
||||
this.getImg(url, (dataUrl) => {
|
||||
dataUrl && this.setIcon(dataUrl);
|
||||
});
|
||||
},
|
||||
|
||||
getImg(imgUrl, callback) {
|
||||
let imgInfo = window.getFileInfo({
|
||||
type: "file",
|
||||
argvs: imgUrl,
|
||||
readfile: false,
|
||||
});
|
||||
let imgPath = window.getQuickcommandTempFile(imgInfo.ext);
|
||||
quickcommand
|
||||
.downloadFile(imgUrl, imgPath)
|
||||
.then(() => {
|
||||
this.compressingPic(window.getBase64Ico(imgPath)).then((src) => {
|
||||
callback(src);
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
quickcommand.showMessageBox("图片地址有误!", "error");
|
||||
});
|
||||
},
|
||||
async compressingPic(img, width = 80) {
|
||||
let compressedImage = await pictureCompress({
|
||||
img: img,
|
||||
width: width,
|
||||
height: width,
|
||||
type: "png",
|
||||
quality: 1,
|
||||
});
|
||||
return compressedImage.img;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
84
src/components/popup/PanelSetting.vue
Normal file
84
src/components/popup/PanelSetting.vue
Normal file
@@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<q-card style="width: 400px">
|
||||
<q-card-section>
|
||||
<div class="row q-gutter-md">
|
||||
<div class="col-auto justify-center content-center flex q-pa-md">
|
||||
<q-avatar square class="commandLogo">
|
||||
<q-img
|
||||
:src="features.icon"
|
||||
@click="$refs.icon.showIconPicker = true"
|
||||
/></q-avatar>
|
||||
</div>
|
||||
<div class="col">
|
||||
<q-select
|
||||
hide-dropdown-icon
|
||||
label-color="primary"
|
||||
transition-show="jump-down"
|
||||
transition-hide="jump-up"
|
||||
v-model="features.cmds"
|
||||
max-values="3"
|
||||
type="text"
|
||||
placeholder="键入后回车"
|
||||
use-input
|
||||
use-chips
|
||||
multiple
|
||||
new-value-mode="add-unique"
|
||||
input-debounce="0"
|
||||
label="关键字"
|
||||
@blur="features.cmds.length || features.cmds.push(currentTag)"
|
||||
/>
|
||||
<q-input
|
||||
label-color="primary"
|
||||
v-model="features.explain"
|
||||
type="text"
|
||||
placeholder="请输入描述"
|
||||
label="描述"
|
||||
@blur="features.explain || (features.explain = ' ')"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<q-card-actions align="right">
|
||||
<q-btn flat label="取消" color="grey" v-close-popup />
|
||||
<q-btn flat label="确定" color="primary" v-close-popup @click="markTag" />
|
||||
</q-card-actions>
|
||||
<IconPicker
|
||||
ref="icon"
|
||||
@iconChanged="(dataUrl) => (features.icon = dataUrl)"
|
||||
position="right"
|
||||
/>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import IconPicker from "components/popup/IconPicker";
|
||||
|
||||
export default {
|
||||
components: { IconPicker },
|
||||
data() {
|
||||
return {
|
||||
features: {
|
||||
explain: `进入${this.currentTag}的面板视图`,
|
||||
icon: "logo/quickcommand.png",
|
||||
cmds: [this.currentTag],
|
||||
platform: ["win32", "darwin", "linux"],
|
||||
code: `panel_${window.hexEncode(this.currentTag)}`,
|
||||
},
|
||||
};
|
||||
},
|
||||
props: {
|
||||
currentTag: String,
|
||||
},
|
||||
methods: {
|
||||
markTag() {
|
||||
this.$utools.whole.setFeature(_.cloneDeep(this.features));
|
||||
this.$root.$refs.view.activatedQuickPanels.push(this.currentTag);
|
||||
quickcommand.showMessageBox(
|
||||
`主输入框输入『${this.features.cmds.join("、")}』即可直接进入『${
|
||||
this.currentTag
|
||||
}』的面板视图`
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
77
src/components/popup/UserInfo.vue
Normal file
77
src/components/popup/UserInfo.vue
Normal file
@@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<div class="row no-wrap q-pa-md">
|
||||
<div class="column items-center">
|
||||
<q-avatar size="48px">
|
||||
<img :src="userInfo.avatar" />
|
||||
<q-badge
|
||||
v-if="userInfo.type === 'member'"
|
||||
floating
|
||||
color="deep-orange"
|
||||
label="v"
|
||||
rounded
|
||||
/>
|
||||
</q-avatar>
|
||||
<div
|
||||
class="text-subtitle1 q-mt-md q-mb-xs"
|
||||
v-html="userInfo.nickname"
|
||||
></div>
|
||||
</div>
|
||||
<q-separator vertical inset class="q-mx-lg" />
|
||||
<div class="column items-start q-gutter-xs">
|
||||
<q-chip dense square>
|
||||
<q-avatar color="indigo" text-color="white">{{
|
||||
allQuickCommandsLength
|
||||
}}</q-avatar>
|
||||
Quickcommands
|
||||
<q-tooltip>当前拥有的「快捷命令」数</q-tooltip>
|
||||
</q-chip>
|
||||
<q-chip dense square>
|
||||
<q-avatar color="green-8" text-color="white">{{
|
||||
allFeaturesLength
|
||||
}}</q-avatar>
|
||||
Features
|
||||
<q-tooltip>当前启用的「快捷命令」数</q-tooltip>
|
||||
</q-chip>
|
||||
<q-chip dense square>
|
||||
<q-avatar color="primary" text-color="white">
|
||||
{{ userLevel.number }}</q-avatar
|
||||
>Level
|
||||
<q-tooltip
|
||||
>使用本插件次数越多,等级越高,uTools VIP 有额外加成哟
|
||||
<br />不要问我为什么 VIP 有加成,因为我白嫖了一个永久 VIP <br />
|
||||
所以怎么也加点「会员特权」吧<br />
|
||||
至于这个等级有啥用,我也不知道╮(╯▽╰)╭
|
||||
</q-tooltip>
|
||||
</q-chip>
|
||||
<q-linear-progress
|
||||
color="cyan-6"
|
||||
stripe
|
||||
rounded
|
||||
style="width: 130px"
|
||||
size="10px"
|
||||
:value="userLevel.process"
|
||||
><q-tooltip
|
||||
>距离下一级还剩{{ (1 - userLevel.process) * 100 }}%</q-tooltip
|
||||
></q-linear-progress
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
userInfo: utools.getUser(),
|
||||
userLevel: {
|
||||
number: 1,
|
||||
process: 0.4,
|
||||
},
|
||||
};
|
||||
},
|
||||
props: {
|
||||
allFeaturesLength: Number,
|
||||
allQuickCommandsLength: Number,
|
||||
},
|
||||
};
|
||||
</script>
|
Reference in New Issue
Block a user