mirror of
https://github.com/fofolee/uTools-quickcommand.git
synced 2025-06-06 13:04:10 +08:00
二列卡片视图布局调整
This commit is contained in:
parent
ffdb737750
commit
4baab60804
BIN
plugin/platform/linux.png
Normal file
BIN
plugin/platform/linux.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
plugin/platform/macos.png
Normal file
BIN
plugin/platform/macos.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 998 B |
BIN
plugin/platform/windows.png
Normal file
BIN
plugin/platform/windows.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
@ -5,7 +5,7 @@
|
||||
'card-wrapper': 1,
|
||||
'card-wrapper-hover': isWarpperHover,
|
||||
}"
|
||||
v-show="!cardStyleVars.hideCard"
|
||||
v-show="canRunInConfigurationPage || cardStyle.code > 1"
|
||||
:id="commandInfo.features.code"
|
||||
@mouseenter="isWarpperHover = true"
|
||||
@mouseleave="if (!$refs.controlButtons?.isMenuOpen) isWarpperHover = false;"
|
||||
@ -14,7 +14,8 @@
|
||||
<ControlButtons
|
||||
ref="controlButtons"
|
||||
v-model:isVisible="isWarpperHover"
|
||||
v-show="cardStyleVars.showButtons"
|
||||
v-show="cardStyle.code > 1"
|
||||
:toggleBtnSize="cardStyle.code === 3 ? 'xs' : 'sm'"
|
||||
:isActivated="isCommandActivated"
|
||||
:isRunButtonVisible="canRunInConfigurationPage"
|
||||
:commandInfo="commandInfo"
|
||||
@ -24,8 +25,8 @@
|
||||
:commandInfo="commandInfo"
|
||||
:isActivated="isCommandActivated"
|
||||
:isPlatformSupported="isPlatformSupported"
|
||||
:cardStyleVars="cardStyleVars"
|
||||
:isHovered="isWarpperHover"
|
||||
:cardStyleCode="cardStyle.code"
|
||||
@click="handleCardClick"
|
||||
/>
|
||||
</div>
|
||||
@ -46,20 +47,6 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
// 控制卡片样式的具体参数
|
||||
cardStyleVars() {
|
||||
return {
|
||||
showButtons: this.cardStyle.code > 1,
|
||||
showPlatforms: this.cardStyle.code > 2,
|
||||
showLanguages: this.cardStyle.code > 1,
|
||||
showBiggerTitle: this.cardStyle.code > 2,
|
||||
logoPosition:
|
||||
this.cardStyle.code > 1 ? "justify-start" : "justify-center",
|
||||
fontPosition:
|
||||
this.cardStyle.code > 1 ? "justify-end" : "justify-center",
|
||||
hideCard: this.cardStyle.code === 1 && !this.canRunInConfigurationPage,
|
||||
};
|
||||
},
|
||||
isPlatformSupported() {
|
||||
let { platform } = this.commandInfo.features;
|
||||
return !_.isEmpty(platform) && !platform.includes(window.processPlatform)
|
||||
@ -85,7 +72,7 @@ export default {
|
||||
methods: {
|
||||
// 命令卡片点击事件
|
||||
handleCardClick() {
|
||||
// 视图模式直接运行命令
|
||||
// mini视图模式直接运行命令
|
||||
if (this.cardStyle.code === 1) {
|
||||
return this.$refs.controlButtons.runCommand();
|
||||
}
|
||||
@ -125,8 +112,9 @@ export default {
|
||||
}
|
||||
|
||||
.card-wrapper {
|
||||
transition: transform 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
will-change: transform;
|
||||
transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
will-change: transform, width;
|
||||
transform-origin: center center;
|
||||
}
|
||||
|
||||
.card-wrapper-hover {
|
||||
|
@ -4,169 +4,73 @@
|
||||
v-ripple
|
||||
:class="{ [`text-${disabledColor}`]: !isActivated, command: 1 }"
|
||||
>
|
||||
<q-card-section>
|
||||
<!-- logo -->
|
||||
<div class="row" :class="cardStyleVars.logoPosition">
|
||||
<q-avatar
|
||||
square
|
||||
size="48px"
|
||||
:class="{
|
||||
featureIco: 1,
|
||||
featureIcoHover: isHovered,
|
||||
'feature-disabled': !isActivated,
|
||||
}"
|
||||
>
|
||||
<img :src="commandInfo.features.icon" />
|
||||
</q-avatar>
|
||||
</div>
|
||||
|
||||
<!-- 名称 -->
|
||||
<div :class="'row ' + cardStyleVars.fontPosition">
|
||||
<div
|
||||
class="ellipsis"
|
||||
:style="{
|
||||
fontSize: cardStyleVars.showBiggerTitle ? '16px' : '14px',
|
||||
}"
|
||||
v-html="commandInfo.features.explain.trim() || '<br/>'"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 匹配模式 -->
|
||||
<div class="row">
|
||||
<div
|
||||
:class="
|
||||
'matchTypesBox flex q-gutter-xs ' + cardStyleVars.fontPosition
|
||||
"
|
||||
>
|
||||
<span v-for="cmd in commandInfo.features.cmds" :key="cmd">
|
||||
<CommandTypeTag
|
||||
:cmd="cmd"
|
||||
:isGrayColor="!isPlatformSupported || !isActivated"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 语言类型和适配系统 -->
|
||||
<div
|
||||
class="row justify-end items-center q-gutter-xs"
|
||||
v-show="cardStyleVars.showLanguages"
|
||||
>
|
||||
<span :class="`text-${programColor}`">●</span>
|
||||
<span class="text-subtitle2">{{ commandInfo.program }}</span>
|
||||
|
||||
<div class="q-gutter-xs" v-show="cardStyleVars.showPlatforms">
|
||||
<span
|
||||
v-for="platform in commandInfo.features.platform"
|
||||
:key="platform"
|
||||
:class="`iconfont icon-${platformTypes[platform].icon} text-${programColor}`"
|
||||
style="font-size: 12px"
|
||||
></span>
|
||||
</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
<component
|
||||
:is="currentLayout"
|
||||
:commandInfo="commandInfo"
|
||||
:isActivated="isActivated"
|
||||
:isPlatformSupported="isPlatformSupported"
|
||||
:isHovered="isHovered"
|
||||
:style="iconHaloStyle"
|
||||
/>
|
||||
</q-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import commandTypes from "js/options/commandTypes.js";
|
||||
import platformTypes from "js/options/platformTypes.js";
|
||||
import CommandTypeTag from "./CommandTypeTag.vue";
|
||||
import ListLayout from "./layouts/ListLayout.vue";
|
||||
import DenseLayout from "./layouts/DenseLayout.vue";
|
||||
import MiniLayout from "./layouts/MiniLayout.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CommandTypeTag,
|
||||
ListLayout,
|
||||
DenseLayout,
|
||||
MiniLayout,
|
||||
},
|
||||
props: {
|
||||
commandInfo: Object,
|
||||
isActivated: Boolean,
|
||||
cardStyleVars: Object,
|
||||
cardStyleCode: Number,
|
||||
isPlatformSupported: Boolean,
|
||||
isHovered: Boolean,
|
||||
},
|
||||
emits: ["click"],
|
||||
data() {
|
||||
return {
|
||||
commandTypes,
|
||||
platformTypes,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
programColor() {
|
||||
return this.isActivated
|
||||
? this.$root.programs[this.commandInfo.program].color
|
||||
: this.disabledColor;
|
||||
currentLayout() {
|
||||
switch (this.cardStyleCode) {
|
||||
case 3:
|
||||
return "ListLayout";
|
||||
case 2:
|
||||
return "DenseLayout";
|
||||
case 1:
|
||||
return "MiniLayout";
|
||||
default:
|
||||
return "DenseLayout";
|
||||
}
|
||||
},
|
||||
disabledColor() {
|
||||
return this.$q.dark.isActive ? "grey-6" : "grey-5";
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
// 设置图标URL作为光晕背景
|
||||
this.$el.style.setProperty(
|
||||
"--icon-url",
|
||||
`url(${this.commandInfo.features.icon})`
|
||||
);
|
||||
},
|
||||
watch: {
|
||||
"commandInfo.features.icon"(newVal) {
|
||||
this.$el.style.setProperty("--icon-url", `url(${newVal})`);
|
||||
iconHaloStyle() {
|
||||
return {
|
||||
"--icon-url": `url(${this.commandInfo.features.icon})`,
|
||||
};
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.ellipsis {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.matchTypesBox {
|
||||
height: 23px;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.featureIco {
|
||||
transition: all 0.8s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
will-change: transform;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.featureIcoHover {
|
||||
transform: scale(1.08) translateY(-2px);
|
||||
}
|
||||
|
||||
.featureIco::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
transition: all 0.8s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
opacity: 0;
|
||||
background-image: var(--icon-url);
|
||||
background-size: contain;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
filter: blur(8px) brightness(1.1);
|
||||
transform: scale(1.05);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.featureIcoHover::after {
|
||||
opacity: 0.8;
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.feature-disabled {
|
||||
opacity: 0.5;
|
||||
filter: grayscale(100%);
|
||||
/* 保留卡片基础样式 */
|
||||
.q-card.command {
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
transition: all 0.3s ease;
|
||||
background: rgba(255, 255, 255, 0.3) !important;
|
||||
backdrop-filter: blur(calc(var(--glass-effect-strength) * 1px)) !important;
|
||||
-webkit-backdrop-filter: blur(
|
||||
calc(var(--glass-effect-strength) * 1px)
|
||||
) !important;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
box-shadow: 0 4px 16px 0 rgba(31, 38, 135, 0.07);
|
||||
}
|
||||
</style>
|
||||
|
@ -1,64 +1,69 @@
|
||||
<template>
|
||||
<span v-if="typeof cmd === 'string'">
|
||||
<q-badge rounded :class="badgeClass">
|
||||
<q-icon class="q-mr-xs" :name="commandTypes.key.icon" />
|
||||
<span class="badge-text">{{ cmd }}</span>
|
||||
</q-badge>
|
||||
<q-tooltip>
|
||||
<div class="text-subtitle2">{{ cmd }}</div>
|
||||
</q-tooltip>
|
||||
</span>
|
||||
<span v-else-if="cmd.type === 'window' && cmd.match">
|
||||
<q-badge rounded :class="badgeClass">
|
||||
<q-icon class="q-mr-xs" :name="commandTypes.window.icon" />
|
||||
<span class="badge-text">{{ cmd.match.app[0] }}</span>
|
||||
</q-badge>
|
||||
<q-tooltip>
|
||||
<div class="text-subtitle2" v-for="app in cmd.match.app" :key="app">
|
||||
{{ app }}
|
||||
</div>
|
||||
</q-tooltip>
|
||||
</span>
|
||||
<span v-else-if="cmd.type === 'files'">
|
||||
<q-badge rounded :class="badgeClass">
|
||||
<q-icon class="q-mr-xs" :name="commandTypes.files.icon" />
|
||||
<span class="badge-text">{{ cmd.match || "所有文件" }}</span>
|
||||
</q-badge>
|
||||
<q-tooltip>
|
||||
<div class="text-subtitle2">
|
||||
{{ cmd.match || "所有文件" }}
|
||||
</div>
|
||||
</q-tooltip>
|
||||
</span>
|
||||
<span v-else-if="cmd.type === 'regex'">
|
||||
<q-badge rounded :class="badgeClass">
|
||||
<q-icon class="q-mr-xs" :name="commandTypes.regex.icon" />
|
||||
<span class="badge-text">{{ cmd.match }}</span>
|
||||
</q-badge>
|
||||
<q-tooltip>
|
||||
<div class="text-subtitle2">
|
||||
{{ cmd.match }}
|
||||
</div>
|
||||
</q-tooltip>
|
||||
</span>
|
||||
<span v-else-if="cmd.type === 'over'">
|
||||
<q-badge rounded :class="badgeClass">
|
||||
<q-icon class="q-mr-xs" :name="commandTypes.over.icon" />所有文本
|
||||
</q-badge>
|
||||
</span>
|
||||
<span v-else-if="cmd.type === 'img'">
|
||||
<q-badge rounded :class="badgeClass">
|
||||
<q-icon class="q-mr-xs" :name="commandTypes.img.icon" />图片
|
||||
</q-badge>
|
||||
</span>
|
||||
<div class="matchTypesBox">
|
||||
<div v-for="cmd in cmds" :key="cmd">
|
||||
<span v-if="typeof cmd === 'string'">
|
||||
<q-badge rounded :class="getBadgeClass(cmd)">
|
||||
<q-icon class="q-mr-xs" :name="commandTypes.key.icon" />
|
||||
<span class="badge-text">{{ cmd }}</span>
|
||||
</q-badge>
|
||||
<q-tooltip>
|
||||
<div class="text-subtitle2">{{ cmd }}</div>
|
||||
</q-tooltip>
|
||||
</span>
|
||||
<span v-else-if="cmd.type === 'window' && cmd.match">
|
||||
<q-badge rounded :class="getBadgeClass(cmd)">
|
||||
<q-icon class="q-mr-xs" :name="commandTypes.window.icon" />
|
||||
<span class="badge-text">{{ cmd.match.app[0] }}</span>
|
||||
</q-badge>
|
||||
<q-tooltip>
|
||||
<div class="text-subtitle2" v-for="app in cmd.match.app" :key="app">
|
||||
{{ app }}
|
||||
</div>
|
||||
</q-tooltip>
|
||||
</span>
|
||||
<span v-else-if="cmd.type === 'files'">
|
||||
<q-badge rounded :class="getBadgeClass(cmd)">
|
||||
<q-icon class="q-mr-xs" :name="commandTypes.files.icon" />
|
||||
<span class="badge-text">{{ cmd.match || "所有文件" }}</span>
|
||||
</q-badge>
|
||||
<q-tooltip>
|
||||
<div class="text-subtitle2">
|
||||
{{ cmd.match || "所有文件" }}
|
||||
</div>
|
||||
</q-tooltip>
|
||||
</span>
|
||||
<span v-else-if="cmd.type === 'regex'">
|
||||
<q-badge rounded :class="getBadgeClass(cmd)">
|
||||
<q-icon class="q-mr-xs" :name="commandTypes.regex.icon" />
|
||||
<span class="badge-text">{{ cmd.match }}</span>
|
||||
</q-badge>
|
||||
<q-tooltip>
|
||||
<div class="text-subtitle2">
|
||||
{{ cmd.match }}
|
||||
</div>
|
||||
</q-tooltip>
|
||||
</span>
|
||||
<span v-else-if="cmd.type === 'over'">
|
||||
<q-badge rounded :class="getBadgeClass(cmd)">
|
||||
<q-icon class="q-mr-xs" :name="commandTypes.over.icon" />所有文本
|
||||
</q-badge>
|
||||
</span>
|
||||
<span v-else-if="cmd.type === 'img'">
|
||||
<q-badge rounded :class="getBadgeClass(cmd)">
|
||||
<q-icon class="q-mr-xs" :name="commandTypes.img.icon" />图片
|
||||
</q-badge>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import commandTypes from "js/options/commandTypes.js";
|
||||
|
||||
export default {
|
||||
name: "CommandTypeTag",
|
||||
props: {
|
||||
cmd: [String, Object],
|
||||
cmds: Array,
|
||||
isGrayColor: Boolean,
|
||||
},
|
||||
data() {
|
||||
@ -66,21 +71,28 @@ export default {
|
||||
commandTypes,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
badgeClass() {
|
||||
return this.isGrayColor
|
||||
? this.$q.dark.isActive
|
||||
? "text-grey-6 bg-grey-9"
|
||||
: "bg-grey-5"
|
||||
: "bg-" + this.commandTypes[this.cmd.type || "key"].color;
|
||||
methods: {
|
||||
getBadgeClass(cmd) {
|
||||
if (this.isGrayColor) {
|
||||
return this.$q.dark.isActive ? "text-grey-6 bg-grey-9" : "bg-grey-4";
|
||||
}
|
||||
const color = this.commandTypes[cmd.type || "key"].color;
|
||||
return "bg-" + color + (this.$q.dark.isActive ? "-10" : "-4");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.matchTypesBox {
|
||||
height: 23px;
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.q-badge {
|
||||
font-size: 13px;
|
||||
font-size: 12px;
|
||||
margin: 0 1px;
|
||||
max-width: 120px;
|
||||
white-space: nowrap;
|
||||
@ -93,4 +105,19 @@ export default {
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
|
||||
.tags-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 4px;
|
||||
width: fit-content;
|
||||
max-width: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.tag-wrapper {
|
||||
display: inline-flex;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,12 +1,13 @@
|
||||
<template>
|
||||
<div>
|
||||
<!-- 开关按钮 -->
|
||||
<div class="absolute" style="z-index: 1; left: 20px; bottom: 16px">
|
||||
<div class="absolute" style="z-index: 1; left: 19px; bottom: 16px">
|
||||
<q-toggle
|
||||
:model-value="isActivated"
|
||||
checked-icon="flash_on"
|
||||
color="orange-6"
|
||||
@click="toggleCommandActivated"
|
||||
:size="toggleBtnSize"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -24,8 +25,8 @@
|
||||
icon="play_arrow"
|
||||
v-show="isRunButtonVisible"
|
||||
@click="runCommand"
|
||||
size="12px"
|
||||
>
|
||||
<q-tooltip anchor="top middle" self="center middle">运行</q-tooltip>
|
||||
</q-btn>
|
||||
|
||||
<q-btn
|
||||
@ -36,8 +37,8 @@
|
||||
:color="!!cronExp ? 'amber' : 'blue-9'"
|
||||
:icon="!!cronExp ? 'timer' : 'insights'"
|
||||
@click="isMenuOpen = true"
|
||||
size="12px"
|
||||
>
|
||||
<q-tooltip anchor="top middle" self="center middle">设置</q-tooltip>
|
||||
<q-menu
|
||||
transition-show="jump-down"
|
||||
transition-hide="jump-up"
|
||||
@ -93,8 +94,8 @@
|
||||
color="red"
|
||||
icon="close"
|
||||
@click="removeCommand"
|
||||
size="12px"
|
||||
>
|
||||
<q-tooltip anchor="top middle" self="center middle">删除</q-tooltip>
|
||||
</q-btn>
|
||||
</div>
|
||||
|
||||
@ -121,6 +122,7 @@ export default {
|
||||
isActivated: Boolean,
|
||||
commandInfo: Object,
|
||||
isRunButtonVisible: Boolean,
|
||||
toggleBtnSize: String,
|
||||
},
|
||||
emits: ["update:isVisible", "commandChanged"],
|
||||
data() {
|
||||
|
96
src/components/card/layouts/DenseLayout.vue
Normal file
96
src/components/card/layouts/DenseLayout.vue
Normal file
@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<q-card-section>
|
||||
<!-- logo -->
|
||||
<div class="row">
|
||||
<q-avatar
|
||||
square
|
||||
size="48px"
|
||||
:class="{
|
||||
featureIco: 1,
|
||||
featureIcoHover: isHovered,
|
||||
'feature-disabled': !isActivated,
|
||||
}"
|
||||
>
|
||||
<img :src="commandInfo.features.icon" />
|
||||
</q-avatar>
|
||||
</div>
|
||||
|
||||
<!-- 名称 -->
|
||||
<div class="row justify-end">
|
||||
<div
|
||||
class="text-ellipsis"
|
||||
v-html="commandInfo.features.explain.trim() || '<br/>'"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 匹配模式 -->
|
||||
<div class="row justify-end">
|
||||
<CommandTypeTag
|
||||
:cmds="commandInfo.features.cmds"
|
||||
:isGrayColor="!isPlatformSupported || !isActivated"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 语言类型 -->
|
||||
<div
|
||||
:class="{
|
||||
'platform-icons': 1,
|
||||
'platform-icons-disabled': !isActivated,
|
||||
}"
|
||||
>
|
||||
<q-img
|
||||
v-for="platform in commandInfo.features.platform"
|
||||
:key="platform"
|
||||
:src="platformTypes[platform].icon"
|
||||
width="16px"
|
||||
/>
|
||||
<div>|</div>
|
||||
<q-img :src="$root.programs[commandInfo.program].icon" width="16px" />
|
||||
<div class="text-subtitle2">{{ programName }}</div>
|
||||
</div>
|
||||
</q-card-section>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommandTypeTag from "../CommandTypeTag.vue";
|
||||
import platformTypes from "js/options/platformTypes.js";
|
||||
|
||||
export default {
|
||||
name: "DenseLayout",
|
||||
components: { CommandTypeTag },
|
||||
props: {
|
||||
commandInfo: Object,
|
||||
isActivated: Boolean,
|
||||
isPlatformSupported: Boolean,
|
||||
isHovered: Boolean,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
platformTypes,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
program() {
|
||||
return this.$root.programs[this.commandInfo.program];
|
||||
},
|
||||
programName() {
|
||||
return this.program.shortName ?? this.program.name;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.platform-icons {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.text-ellipsis {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 100%;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
90
src/components/card/layouts/ListLayout.vue
Normal file
90
src/components/card/layouts/ListLayout.vue
Normal file
@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<div class="wrapper">
|
||||
<!-- logo -->
|
||||
<div class="row items-center q-gutter-sm">
|
||||
<q-avatar
|
||||
square
|
||||
size="38px"
|
||||
:class="{
|
||||
featureIco: 1,
|
||||
featureIcoHover: isHovered,
|
||||
'feature-disabled': !isActivated,
|
||||
}"
|
||||
>
|
||||
<img :src="commandInfo.features.icon" />
|
||||
</q-avatar>
|
||||
<div class="column">
|
||||
<!-- 名称 -->
|
||||
<div
|
||||
class="text-ellipsis"
|
||||
v-html="commandInfo.features.explain.trim() || '<br/>'"
|
||||
/>
|
||||
<!-- 匹配模式 -->
|
||||
<CommandTypeTag
|
||||
:cmds="commandInfo.features.cmds"
|
||||
:isGrayColor="!isPlatformSupported || !isActivated"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 语言类型 -->
|
||||
<div
|
||||
:class="{
|
||||
'platform-icons': 1,
|
||||
'platform-icons-disabled': !isActivated,
|
||||
}"
|
||||
>
|
||||
<q-img
|
||||
v-for="platform in commandInfo.features.platform"
|
||||
:key="platform"
|
||||
:src="platformTypes[platform].icon"
|
||||
width="16px"
|
||||
/>
|
||||
<div>|</div>
|
||||
<q-img :src="program.icon" width="16px" />
|
||||
<div class="text-subtitle2">{{ program.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommandTypeTag from "../CommandTypeTag.vue";
|
||||
import platformTypes from "js/options/platformTypes.js";
|
||||
|
||||
export default {
|
||||
name: "ListLayout",
|
||||
components: { CommandTypeTag },
|
||||
props: {
|
||||
commandInfo: Object,
|
||||
isActivated: Boolean,
|
||||
isPlatformSupported: Boolean,
|
||||
isHovered: Boolean,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
platformTypes,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
program() {
|
||||
return this.$root.programs[this.commandInfo.program];
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 网格布局 */
|
||||
.wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
padding: 10px 12px;
|
||||
}
|
||||
|
||||
.text-ellipsis {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
74
src/components/card/layouts/MiniLayout.vue
Normal file
74
src/components/card/layouts/MiniLayout.vue
Normal file
@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<div class="mini-layout">
|
||||
<!-- logo -->
|
||||
<div class="row justify-center">
|
||||
<q-avatar
|
||||
square
|
||||
size="48px"
|
||||
:class="{
|
||||
featureIco: 1,
|
||||
featureIcoHover: isHovered,
|
||||
}"
|
||||
>
|
||||
<img :src="commandInfo.features.icon" />
|
||||
</q-avatar>
|
||||
</div>
|
||||
|
||||
<!-- 名称 -->
|
||||
<div class="row justify-center w-100">
|
||||
<div
|
||||
class="text-ellipsis text-center"
|
||||
v-html="commandInfo.features.explain.trim() || '<br/>'"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- 匹配模式 -->
|
||||
<div class="row justify-center w-100">
|
||||
<CommandTypeTag :cmds="commandInfo.features.cmds" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CommandTypeTag from "../CommandTypeTag.vue";
|
||||
import platformTypes from "js/options/platformTypes.js";
|
||||
import { computed } from "vue";
|
||||
|
||||
export default {
|
||||
name: "MiniLayout",
|
||||
components: { CommandTypeTag },
|
||||
props: {
|
||||
commandInfo: Object,
|
||||
isHovered: Boolean,
|
||||
},
|
||||
setup() {
|
||||
return {
|
||||
platformTypes,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.mini-layout {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.w-100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.text-ellipsis {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
max-width: 90%;
|
||||
margin: 0 auto;
|
||||
padding: 0 8px;
|
||||
font-size: 14px;
|
||||
}
|
||||
</style>
|
@ -1,31 +1,4 @@
|
||||
/* app global css */
|
||||
@font-face {
|
||||
font-family: "iconfont";
|
||||
src: url("../fonts/iconfont.woff2?t=1649900426635") format("woff2"),
|
||||
url("../fonts/iconfont.woff?t=1649900426635") format("woff"),
|
||||
url("../fonts/iconfont.ttf?t=1649900426635") format("truetype");
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
font-family: "iconfont" !important;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-linux:before {
|
||||
content: "\e6c1";
|
||||
}
|
||||
|
||||
.icon-macos1:before {
|
||||
content: "\e6b2";
|
||||
}
|
||||
|
||||
.icon-windows1:before {
|
||||
content: "\e6bb";
|
||||
}
|
||||
|
||||
:root {
|
||||
--q-dark: #464646;
|
||||
--q-dark-page: #303133;
|
||||
@ -221,3 +194,53 @@ body.body--dark.glass-effect-menu .q-menu {
|
||||
.body--dark .q-menu .q-field__control {
|
||||
background: rgba(0, 0, 0, 0.3) !important;
|
||||
}
|
||||
|
||||
/* 添加图标光晕效果 */
|
||||
.featureIco {
|
||||
transition: all 0.8s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
will-change: transform;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.featureIcoHover {
|
||||
transform: scale(1.08) translateY(-2px);
|
||||
}
|
||||
|
||||
.featureIco::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
transition: all 0.8s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
opacity: 0;
|
||||
background-image: var(--icon-url);
|
||||
background-size: contain;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
filter: blur(8px) brightness(1.1);
|
||||
transform: scale(1.05);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.featureIcoHover::after {
|
||||
opacity: 0.8;
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.feature-disabled,
|
||||
.platform-icons-disabled {
|
||||
opacity: 0.5;
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
|
||||
.platform-icons {
|
||||
display: flex;
|
||||
gap: 2px;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -2,17 +2,17 @@ const platformTypes = {
|
||||
win32: {
|
||||
name: "win32",
|
||||
label: "Windows",
|
||||
icon: "windows1"
|
||||
icon: "platform/windows.png"
|
||||
},
|
||||
darwin: {
|
||||
name: "darwin",
|
||||
label: "MacOS",
|
||||
icon: "macos1"
|
||||
icon: "platform/macos.png"
|
||||
},
|
||||
linux: {
|
||||
name: "linux",
|
||||
label: "Linux",
|
||||
icon: "linux"
|
||||
icon: "platform/linux.png"
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,127 +3,133 @@
|
||||
*/
|
||||
|
||||
const programs = {
|
||||
quickcommand: {
|
||||
name: "quickcommand",
|
||||
highlight: "javascript",
|
||||
bin: "",
|
||||
argv: "",
|
||||
ext: "",
|
||||
color: "primary",
|
||||
icon: "logo/quickcommand.png",
|
||||
},
|
||||
html: {
|
||||
name: "html",
|
||||
bin: "",
|
||||
argv: "",
|
||||
ext: "",
|
||||
color: "deep-orange",
|
||||
icon: "logo/html.png",
|
||||
},
|
||||
shell: {
|
||||
name: "shell",
|
||||
bin: "bash",
|
||||
argv: "",
|
||||
ext: "sh",
|
||||
color: "green-6",
|
||||
icon: "logo/shell.png",
|
||||
},
|
||||
applescript: {
|
||||
name: "applescript",
|
||||
bin: "osascript",
|
||||
argv: "",
|
||||
ext: "scpt",
|
||||
color: "cyan-10",
|
||||
icon: "logo/applescript.png",
|
||||
},
|
||||
cmd: {
|
||||
name: "cmd",
|
||||
highlight: "bat",
|
||||
bin: "",
|
||||
argv: "",
|
||||
ext: "bat",
|
||||
color: "orange-10",
|
||||
icon: "logo/cmd.png",
|
||||
},
|
||||
powershell: {
|
||||
name: "powershell",
|
||||
bin: "powershell",
|
||||
argv: "-NoProfile -File",
|
||||
ext: "ps1",
|
||||
color: "amber-14",
|
||||
icon: "logo/powershell.png",
|
||||
},
|
||||
python: {
|
||||
name: "python",
|
||||
bin: "python",
|
||||
argv: "-u",
|
||||
ext: "py",
|
||||
color: "light-blue-10",
|
||||
icon: "logo/python.png",
|
||||
},
|
||||
javascript: {
|
||||
name: "javascript",
|
||||
bin: "node",
|
||||
argv: "",
|
||||
ext: "js",
|
||||
color: "teal",
|
||||
icon: "logo/javascript.png",
|
||||
},
|
||||
ruby: {
|
||||
name: "ruby",
|
||||
bin: "ruby",
|
||||
argv: "",
|
||||
ext: "rb",
|
||||
color: "red-10",
|
||||
icon: "logo/ruby.png",
|
||||
},
|
||||
php: {
|
||||
name: "php",
|
||||
bin: "php",
|
||||
argv: "",
|
||||
ext: "php",
|
||||
color: "deep-purple",
|
||||
icon: "logo/php.png",
|
||||
},
|
||||
c: {
|
||||
name: "c",
|
||||
bin: "gcc",
|
||||
argv: "-o",
|
||||
ext: "c",
|
||||
color: "blue-7",
|
||||
icon: "logo/c.png",
|
||||
},
|
||||
csharp: {
|
||||
name: "csharp",
|
||||
bin: "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\csc.exe",
|
||||
argv: "/Nologo",
|
||||
ext: "cs",
|
||||
color: "light-blue-13",
|
||||
icon: "logo/csharp.png",
|
||||
},
|
||||
lua: {
|
||||
name: "lua",
|
||||
bin: "lua",
|
||||
argv: "",
|
||||
ext: "lua",
|
||||
color: "light-green-8",
|
||||
icon: "logo/lua.png",
|
||||
},
|
||||
perl: {
|
||||
name: "perl",
|
||||
bin: "perl",
|
||||
argv: "",
|
||||
ext: "pl",
|
||||
color: "purple",
|
||||
icon: "logo/perl.png"
|
||||
},
|
||||
custom: {
|
||||
name: "custom",
|
||||
bin: "",
|
||||
argv: "",
|
||||
ext: "",
|
||||
color: "indigo-6",
|
||||
icon: "logo/custom.png",
|
||||
},
|
||||
quickcommand: {
|
||||
name: "quickcommand",
|
||||
highlight: "javascript",
|
||||
bin: "",
|
||||
argv: "",
|
||||
ext: "",
|
||||
color: "primary",
|
||||
icon: "logo/quickcommand.png",
|
||||
shortName: "qc",
|
||||
},
|
||||
html: {
|
||||
name: "html",
|
||||
bin: "",
|
||||
argv: "",
|
||||
ext: "",
|
||||
color: "deep-orange",
|
||||
icon: "logo/html.png",
|
||||
},
|
||||
shell: {
|
||||
name: "shell",
|
||||
bin: "bash",
|
||||
argv: "",
|
||||
ext: "sh",
|
||||
color: "green-6",
|
||||
icon: "logo/shell.png",
|
||||
},
|
||||
applescript: {
|
||||
name: "applescript",
|
||||
bin: "osascript",
|
||||
argv: "",
|
||||
ext: "scpt",
|
||||
color: "cyan-10",
|
||||
icon: "logo/applescript.png",
|
||||
shortName: "ascpt",
|
||||
},
|
||||
cmd: {
|
||||
name: "cmd",
|
||||
highlight: "bat",
|
||||
bin: "",
|
||||
argv: "",
|
||||
ext: "bat",
|
||||
color: "orange-10",
|
||||
icon: "logo/cmd.png",
|
||||
},
|
||||
powershell: {
|
||||
name: "powershell",
|
||||
bin: "powershell",
|
||||
argv: "-NoProfile -File",
|
||||
ext: "ps1",
|
||||
color: "amber-14",
|
||||
icon: "logo/powershell.png",
|
||||
shortName: "ps",
|
||||
},
|
||||
python: {
|
||||
name: "python",
|
||||
bin: "python",
|
||||
argv: "-u",
|
||||
ext: "py",
|
||||
color: "light-blue-10",
|
||||
icon: "logo/python.png",
|
||||
shortName: "py",
|
||||
},
|
||||
javascript: {
|
||||
name: "javascript",
|
||||
bin: "node",
|
||||
argv: "",
|
||||
ext: "js",
|
||||
color: "teal",
|
||||
icon: "logo/javascript.png",
|
||||
shortName: "js",
|
||||
},
|
||||
ruby: {
|
||||
name: "ruby",
|
||||
bin: "ruby",
|
||||
argv: "",
|
||||
ext: "rb",
|
||||
color: "red-10",
|
||||
icon: "logo/ruby.png",
|
||||
},
|
||||
php: {
|
||||
name: "php",
|
||||
bin: "php",
|
||||
argv: "",
|
||||
ext: "php",
|
||||
color: "deep-purple",
|
||||
icon: "logo/php.png",
|
||||
},
|
||||
c: {
|
||||
name: "c",
|
||||
bin: "gcc",
|
||||
argv: "-o",
|
||||
ext: "c",
|
||||
color: "blue-7",
|
||||
icon: "logo/c.png",
|
||||
},
|
||||
csharp: {
|
||||
name: "csharp",
|
||||
bin: "C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\csc.exe",
|
||||
argv: "/Nologo",
|
||||
ext: "cs",
|
||||
color: "light-blue-13",
|
||||
icon: "logo/csharp.png",
|
||||
shortName: "c#",
|
||||
},
|
||||
lua: {
|
||||
name: "lua",
|
||||
bin: "lua",
|
||||
argv: "",
|
||||
ext: "lua",
|
||||
color: "light-green-8",
|
||||
icon: "logo/lua.png",
|
||||
},
|
||||
perl: {
|
||||
name: "perl",
|
||||
bin: "perl",
|
||||
argv: "",
|
||||
ext: "pl",
|
||||
color: "purple",
|
||||
icon: "logo/perl.png",
|
||||
},
|
||||
custom: {
|
||||
name: "custom",
|
||||
bin: "",
|
||||
argv: "",
|
||||
ext: "",
|
||||
color: "indigo-6",
|
||||
icon: "logo/custom.png",
|
||||
},
|
||||
};
|
||||
export default programs
|
||||
export default programs;
|
||||
|
@ -20,7 +20,7 @@
|
||||
<!-- 面板视图不显示标签栏 -->
|
||||
<q-scroll-area
|
||||
v-show="commandCardStyle !== 'mini'"
|
||||
class="absolute-left"
|
||||
class="absolute-left tag-bar"
|
||||
:thumb-style="{
|
||||
width: '2px',
|
||||
}"
|
||||
@ -101,7 +101,7 @@
|
||||
</q-tab-panels>
|
||||
<!-- 底栏 -->
|
||||
<div
|
||||
class="absolute-bottom"
|
||||
class="absolute-bottom footer-bar"
|
||||
:style="{
|
||||
height: footerBarHeight,
|
||||
left: tabBarWidth,
|
||||
@ -153,23 +153,17 @@
|
||||
>
|
||||
<template v-slot:normal>
|
||||
<q-icon name="dashboard" />
|
||||
<q-tooltip>按两列排列的基础视图</q-tooltip>
|
||||
<q-tooltip>双列视图</q-tooltip>
|
||||
</template>
|
||||
<template v-slot:dense>
|
||||
<q-icon name="apps" />
|
||||
<q-tooltip
|
||||
>按三列排列的紧凑视图,但不会显示适用的操作系统</q-tooltip
|
||||
>
|
||||
<q-tooltip>三列视图</q-tooltip>
|
||||
</template>
|
||||
<template v-slot:mini>
|
||||
<q-icon name="view_comfy" />
|
||||
<q-tooltip
|
||||
>按四列排列的面板视图<br />
|
||||
老版本的「快捷面板」已被弃用,取而代之的是新版的「面板视图」<br />
|
||||
注意:<br />
|
||||
1.未启用、匹配类型为窗口的命令在此视图下不显示<br />
|
||||
2.只显示图标描述和匹配类型<br />
|
||||
3.点击卡片时会直接运行命令而不是编辑命令</q-tooltip
|
||||
>五列面板视图<br />
|
||||
未启用、匹配类型为窗口的命令在此视图下不显示</q-tooltip
|
||||
>
|
||||
</template>
|
||||
</q-btn-toggle>
|
||||
@ -739,7 +733,7 @@ export default {
|
||||
|
||||
/* 面板过渡效果 */
|
||||
.q-tab-panels {
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
@ -804,4 +798,41 @@ body.body--dark.glass-effect-menu .absolute-bottom {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* 底栏过渡动画 */
|
||||
.footer-bar {
|
||||
transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
will-change: left;
|
||||
}
|
||||
|
||||
/* 底栏输入框样式 */
|
||||
.absolute-bottom .q-field__control {
|
||||
background: rgba(255, 255, 255, 0.15) !important;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.body--dark .absolute-bottom .q-field__control {
|
||||
background: rgba(0, 0, 0, 0.2) !important;
|
||||
}
|
||||
|
||||
/* 标签栏过渡动画 */
|
||||
.tag-bar {
|
||||
transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
will-change: width, opacity;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* 标签栏隐藏时的样式 */
|
||||
.tag-bar[style*="display: none"] {
|
||||
opacity: 0;
|
||||
width: 0 !important;
|
||||
}
|
||||
|
||||
/* 面板过渡效果 */
|
||||
.q-tab-panels {
|
||||
transition: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
background: none !important;
|
||||
}
|
||||
|
||||
/* ... 其他样式保持不变 ... */
|
||||
</style>
|
||||
|
Loading…
x
Reference in New Issue
Block a user