支持偏好设置

This commit is contained in:
muwoo 2021-12-08 21:28:16 +08:00
parent 64f2eba2fa
commit fc7e3e91bd
8 changed files with 541 additions and 24 deletions

View File

@ -3,7 +3,7 @@
"pluginName": "rubick 系统菜单",
"description": "rubick 系统菜单",
"main": "index.html",
"logo": "logo.jpg",
"logo": "httpss://static.91jkys.com/upload/202112/08/8a1abbb051bf4b05bbc9bbf66ade63f2.png",
"version": "0.0.0",
"preload":"preload.js",
"pluginType": "ui",

View File

@ -20,7 +20,7 @@
</template>
设置
</a-menu-item>
<a-menu-item key="user">
<a-menu-item key="account">
<template #icon>
<UserOutlined />
</template>

View File

@ -1,6 +1,8 @@
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
import Market from "../views/market/index.vue";
import Installed from "../views/installed/index.vue";
import Account from "../views/account/index.vue";
import Settings from "../views/settings/index.vue";
const routes: Array<RouteRecordRaw> = [
{
@ -13,6 +15,16 @@ const routes: Array<RouteRecordRaw> = [
name: "installed",
component: Installed,
},
{
path: "/account",
name: "account",
component: Account,
},
{
path: "/settings",
name: "settings",
component: Settings,
},
{
path: "/:catchAll(.*)",
name: "market",

View File

@ -0,0 +1,21 @@
<template>
<div class="account">
<a-result status="404" title="玩命开发中" sub-title="个人中心正在开发中敬请期待...">
</a-result>
</div>
</template>
<script>
export default {
};
</script>
<style lang="less">
.account {
box-sizing: border-box;
width: 100%;
overflow-x: hidden;
background: #f3efef;
height: calc(~"100vh - 46px");
}
</style>

View File

@ -1,10 +1,17 @@
<template>
<div class="installed">
<div class="installed-list">
<div :class="currentSelect === index ? 'item active' : 'item'" :key="index" v-for="(plugin, index) in localPlugins">
<div
:class="currentSelect === index ? 'item active' : 'item'"
:key="index"
v-for="(plugin, index) in localPlugins"
>
<img :src="plugin.logo" />
<div class="info">
<div class="title">{{ plugin.pluginName }} <span class="desc">v{{ plugin.version }}</span></div>
<div class="title">
{{ plugin.pluginName }}
<span class="desc">v{{ plugin.version }}</span>
</div>
<div class="desc">{{ plugin.description }}</div>
</div>
</div>
@ -17,27 +24,44 @@
<a-tag>{{ pluginDetail.version }}</a-tag>
</div>
<div class="desc">
开发者{{`${pluginDetail.author || '未知'}`}}
开发者{{ `${pluginDetail.author || "未知"}` }}
</div>
<div class="desc">
{{pluginDetail.description}}
{{ pluginDetail.description }}
</div>
</div>
<div class="right">
<a-button type="danger" size="small" shape="round" @click="deletePlugin(pluginDetail)">移除</a-button>
<a-button
type="danger"
size="small"
shape="round"
@click="deletePlugin(pluginDetail)"
>移除</a-button
>
</div>
</div>
<a-tabs default-active-key="1">
<a-tab-pane key="1" tab="功能关键字">
<div class="feature-container">
<div class="desc-item" :key="index" v-for="(item, index) in pluginDetail.features">
<div>{{item.explain}}</div>
<div
class="desc-item"
:key="index"
v-for="(item, index) in pluginDetail.features"
>
<div>{{ item.explain }}</div>
<a-tag
:key="cmd"
@click="openPlugin({cmd, plugin: pluginDetail, feature: item, router: $router})"
@click="
openPlugin({
cmd,
plugin: pluginDetail,
feature: item,
router: $router,
})
"
v-for="cmd in item.cmds"
>
{{cmd}}
{{ cmd }}
</a-tag>
</div>
</div>
@ -74,12 +98,18 @@ const pluginDetail = computed(() => {
});
const readme = computed(() => {
if(!pluginDetail.value.name) return "";
const str = fs.readFileSync(
path.resolve(baseDir, "node_modules", pluginDetail.value.name, "readme.md"),
"utf-8"
if (!pluginDetail.value.name) return "";
const readmePath = path.resolve(
baseDir,
"node_modules",
pluginDetail.value.name,
"readme.md"
);
return md.render(str);
if (fs.existsSync(readmePath)) {
const str = fs.readFileSync(readmePath, "utf-8");
return md.render(str);
}
return "";
});
const deletePlugin = async (plugin) => {
@ -93,7 +123,7 @@ const deletePlugin = async (plugin) => {
box-sizing: border-box;
width: 100%;
overflow: hidden;
background: #F3EFEF;
background: #f3efef;
height: calc(~"100vh - 46px");
display: flex;
.installed-list {
@ -139,7 +169,8 @@ const deletePlugin = async (plugin) => {
color: #999;
}
}
.detail-container, .feature-container {
.detail-container,
.feature-container {
height: 380px;
overflow: auto;
img {

View File

@ -14,11 +14,12 @@
/>
</a-button>
</template>
<a-list-item-meta
:description="item.description"
>
<a-list-item-meta>
<template #description>
<span class="ellipse">{{ item.description }}</span>
</template>
<template #title>
<span>{{ item.pluginName }}</span>
<span class="ellipse">{{ item.pluginName }}</span>
</template>
<template #avatar>
<a-avatar :src="item.logo" />
@ -45,8 +46,10 @@
<ArrowLeftOutlined />
</div>
<div class="info">
<img src="https://static.91jkys.com/activity/img/2adb63c2e5d54dc1b26001958fcdb044.jpg"
class="plugin-icon" />
<img
src="https://static.91jkys.com/activity/img/2adb63c2e5d54dc1b26001958fcdb044.jpg"
class="plugin-icon"
/>
<div class="plugin-desc">
<div class="title">
备忘快贴
@ -104,6 +107,13 @@ const visible = ref(false);
.title {
margin-bottom: 30px;
}
.ellipse {
display: inline-block;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
}
&:after{
content: " ";
display: block;

View File

@ -0,0 +1,340 @@
<template>
<div class="settings">
<div class="left-menu">
<a-menu v-model:selectedKeys="currentSelect" mode="inline">
<a-menu-item key="normal">
<template #icon>
<ToolOutlined />
</template>
基本设置
</a-menu-item>
<a-menu-item key="global">
<template #icon>
<LaptopOutlined />
</template>
全局快捷键
</a-menu-item>
</a-menu>
</div>
<div class="settings-detail">
<div v-if="currentSelect[0] === 'normal'">
<div class="setting-item">
<div class="title">
快捷键(需要使用 option/ctrl/shift/command 键修饰)
</div>
<div class="settings-item-li">
<div class="label">显示/隐藏快捷键</div>
<div
class="value"
tabIndex="-1"
@keyup="(e) => changeShortCut(e, 'showAndHidden')"
>
{{ config.perf.shortCut.showAndHidden }}
</div>
</div>
<div class="settings-item-li">
<div class="label">插件分离快捷键</div>
<div
class="value"
tabIndex="-1"
@keyup="(e) => changeShortCut(e, 'separate')"
>
{{ config.perf.shortCut.separate }}
</div>
</div>
<div class="settings-item-li">
<div class="label">返回主界面</div>
<div
class="value"
tabIndex="-1"
@keyup="(e) => changeShortCut(e, 'quit')"
>
{{ config.perf.shortCut.quit }}
</div>
</div>
</div>
<div class="setting-item">
<div class="title">通用</div>
<div class="settings-item-li">
<div class="label">开机启动</div>
<a-switch
v-model:checked="config.perf.common.start"
checked-children="开"
un-checked-children="关"
></a-switch>
</div>
<div class="settings-item-li">
<div class="label">空格执行</div>
<a-switch
v-model:checked="config.perf.common.space"
checked-children="开"
un-checked-children="关"
></a-switch>
</div>
</div>
<div class="setting-item">
<div class="title">本地搜索启动</div>
<div class="settings-item-li">
<div class="label">搜索启动应用&文件</div>
<a-switch
v-model:checked="config.perf.local.search"
checked-children="开"
un-checked-children="关"
></a-switch>
</div>
</div>
</div>
<div v-if="currentSelect[0] === 'global'">
<a-collapse>
<a-collapse-panel key="1" header="说明及示例">
<div>
按下快捷键自动搜索对应关键字当关键字结果完全匹配且结果唯一时会直接指向该功能
</div>
<h3 style="margin-top: 10px;">示例</h3>
<a-divider style="margin: 5px 0;" />
<a-list item-layout="horizontal" :data-source="examples">
<template #renderItem="{ item }">
<a-list-item>
<a-list-item-meta :description="item.desc">
<template #title>
<div>{{ item.title }}</div>
</template>
</a-list-item-meta>
</a-list-item>
</template>
</a-list>
</a-collapse-panel>
</a-collapse>
<div class="feature-container">
<div class="keywords item">
<div>快捷键</div>
<a-tooltip placement="top" trigger="click">
<template #title>
<span>先按功能键CtrlShiftAltOptionCommand再按其他普通键或按
F1-F12 单键
</span>
</template>
<div
:key="index"
v-for="(item, index) in config.global"
class="value"
tabIndex="-1"
@keyup="(e) => changeGlobalKey(e, index)"
>
{{ item.key }}
</div>
</a-tooltip>
</div>
<div class="short-cut item">
<div>功能关键字</div>
<a-input
:key="index"
:value="item.value"
v-for="(item, index) in config.global"
class="value"
:disabled="!item.key"
@change="(e) => changeGlobalValue(index, e.target.value)"
/>
</div>
</div>
<div @click="addConfig" class="add-global">+ 新增全局快捷功能</div>
</div>
</div>
</div>
</template>
<script setup>
import { ToolOutlined, LaptopOutlined } from "@ant-design/icons-vue";
import { ref, watch } from "vue";
import keycodes from "./keycode";
const { remote, ipcRenderer } = window.require("electron");
const examples = [
{
title: "快捷键 「 Alt + W」 关键字 「 微信」",
desc: "按下Alt + W 直接打开本地微信应用",
},
{
title: "快捷键 「 Alt + Q」 关键字 「 取色」",
desc: "按下Alt + Q 直接打开屏幕取色功能",
},
];
const currentSelect = ref(["normal"]);
const config = ref({});
config.value = remote.getGlobal("OP_CONFIG").get();
const changeShortCut = (e, key) => {
if (e.altKey && e.keyCode !== 18) {
const compose = `Option+${keycodes[e.keyCode].toUpperCase()}`;
config.value.perf.shortCut[key] = compose;
}
if (e.ctrlKey && e.keyCode !== 17) {
const compose = `Ctrl+${keycodes[e.keyCode].toUpperCase()}`;
config.value.config.perf.shortCut[key] = compose;
}
if (e.shiftKey && e.keyCode !== 16) {
const compose = `Shift+${keycodes[e.keyCode].toUpperCase()}`;
config.value.config.perf.shortCut[key] = compose;
}
if (e.metaKey && e.keyCode !== 93) {
const compose = `Command+${keycodes[e.keyCode].toUpperCase()}`;
config.value.config.perf.shortCut[key] = compose;
}
};
const changeGlobalKey = (e, index) => {
let compose;
if (e.altKey && e.keyCode !== 18) {
compose = `Alt+${keycodes[e.keyCode].toUpperCase()}`;
}
if (e.ctrlKey && e.keyCode !== 17) {
compose = `Ctrl+${keycodes[e.keyCode].toUpperCase()}`;
}
if (e.shiftKey && e.keyCode !== 16) {
compose = `Shift+${keycodes[e.keyCode].toUpperCase()}`;
}
if (e.metaKey && e.keyCode !== 93) {
compose = `Command+${keycodes[e.keyCode].toUpperCase()}`;
}
if (compose) {
config.value.global[index].key = compose;
}
// f1 - f12
if (e.keyCode >= 112 && e.keyCode <= 123) {
compose = keycodes[e.keyCode].toUpperCase();
}
if (compose) {
config.value.global[index].key = compose;
}
};
const addConfig = () => {
console.log(config.value);
config.value = {
...config.value,
global: [
...config.value.global,
{
key: "",
value: "",
}
]
};
};
watch(
config,
() => {
console.log(config.value);
// remote.getGlobal("OP_CONFIG").set("perf", config.value.perf);
// remote.getGlobal("OP_CONFIG").set("superPanel", config.value.superPanel);
// remote.getGlobal("OP_CONFIG").set("global", config.value.global);
ipcRenderer.send("re-register");
},
{
deep: true,
}
);
</script>
<style lang="less">
.settings {
box-sizing: border-box;
width: 100%;
overflow-x: hidden;
background: #f3efef;
height: calc(~"100vh - 46px");
display: flex;
.left-menu {
width: 200px;
height: 100%;
.search-container {
padding: 10px;
}
.ant-input-affix-wrapper {
border: none;
}
.ant-menu {
background: #F3EFEF;
.ant-menu-item-selected {
background-color: #E2E2E2;
color: #141414;
&:after {
display: none;
}
}
}
}
.settings-detail {
padding: 20px;
box-sizing: border-box;
flex: 1;
overflow: auto;
height: 100%;
background: #fff;
.setting-item {
margin-bottom: 20px;
.ant-form-item {
margin-bottom: 0;
}
.title {
color: #6c9fe2;
font-size: 15px;
margin-bottom: 10px;
}
.settings-item-li {
padding-left: 20px;
display: flex;
width: 100%;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
.label {
color: #646464;
}
.value {
width: 300px;
text-align: center;
border: 1px solid #ddd;
color: #6c9fe2;
font-size: 14px;
height: 24px;
font-weight: lighter;
}
}
}
}
.feature-container {
display: flex;
align-items: center;
justify-content: space-between;
margin-top: 10px;
font-size: 14px;
.item {
flex: 1;
}
.short-cut {
margin-left: 20px;
}
.value {
text-align: center;
border: 1px solid #ddd;
color: #6c9fe2;
font-size: 14px;
height: 24px;
font-weight: lighter;
margin-top: 10px;
}
}
.add-global {
color: #6c9fe2;
margin-top: 20px;
width: 100%;
text-align: center;
cursor: pointer;
}
}
</style>

View File

@ -0,0 +1,103 @@
export default {
0: "That key has no keycode",
3: "break",
8: "backspace / delete",
9: "tab",
12: "clear",
13: "enter",
16: "shift",
17: "ctrl",
18: "alt",
19: "pause/break",
20: "caps lock",
21: "hangul",
25: "hanja",
27: "escape",
28: "conversion",
29: "non-conversion",
32: "space",
33: "page up",
34: "page down",
35: "End",
36: "Home",
37: "Left",
38: "Up",
39: "Right",
40: "Down",
45: "Insert",
46: "Delete",
48: "0",
49: "1",
50: "2",
51: "3",
52: "4",
53: "5",
54: "6",
55: "7",
56: "8",
57: "9",
65: "A",
66: "B",
67: "C",
68: "D",
69: "E",
70: "F",
71: "G",
72: "H",
73: "I",
74: "J",
75: "K",
76: "L",
77: "M",
78: "N",
79: "O",
80: "P",
81: "Q",
82: "R",
83: "S",
84: "T",
85: "U",
86: "V",
87: "W",
88: "X",
89: "Y",
90: "Z",
112: "F1",
113: "F2",
114: "F3",
115: "F4",
116: "F5",
117: "F6",
118: "F7",
119: "F8",
120: "F9",
121: "F10",
122: "F11",
123: "F12",
186: ";",
187: "=",
188: ",",
189: "-",
190: ".",
191: "/",
192: "`",
219: "[",
220: "\\",
221: "]",
222: "'",
223: "`",
224: "left or right ⌘ key (firefox)",
225: "altgr",
226: "< /git >, left back slash",
230: "GNOME Compose Key",
231: "ç",
233: "XF86Forward",
234: "XF86Back",
235: "non-conversion",
240: "alphanumeric",
242: "hiragana/katakana",
243: "half-width/full-width",
244: "kanji",
251: "unlock trackpad (Chrome/Edge)",
255: "toggle touchpad"
};