Compare commits

...

142 Commits

Author SHA1 Message Date
muwoo
6315ec12ae Update main.yml 2025-07-24 14:13:59 +08:00
muwoo
3ba8250d7c Update package.json 2025-07-24 14:12:18 +08:00
muwoo
706aa84374 Merge pull request #432 from magicedy/fix-key-conflicts
fix: resolve key conflicts between local-start-app and plugin-history
2025-07-24 14:11:24 +08:00
muwoo
f70bf3983e Merge pull request #444 from lanxiuyun/ctrl+ctrl
Double click the modifer to pop up window
2025-07-24 14:10:09 +08:00
muwoo
47359308fc Update package.json 2025-07-17 20:56:32 +08:00
muwoo
3f03e5578e Merge pull request #438 from siriusol/master
fix issues #437
2025-07-17 20:56:14 +08:00
lanxiuyun
7cabbe26f5 删除提示重启文本 2025-06-12 15:09:38 +08:00
lanxiuyun
5c048c6341 优化代码可读性 2025-06-12 15:08:37 +08:00
lanxiuyun
e90a30c8a4 优化 uIOhook 逻辑 2025-06-12 15:04:10 +08:00
lanxiuyun
599538db76 Update package.json 2025-06-10 14:33:16 +08:00
lanxiuyun
e9c41b6bdb Update index.vue 2025-06-10 14:23:51 +08:00
lanxiuyun
1e7a8209b7 支持双击快捷键 2025-06-10 14:14:37 +08:00
lanxiuyun
481cd44ab3 Update registerHotKey.ts 2025-06-10 10:53:13 +08:00
lanxiuyun
d41caa742b Update index.vue 2025-06-10 10:39:44 +08:00
lanxiuyun
69218a728b Update index.vue 2025-06-10 10:25:25 +08:00
Ther
73cef1512c fix #437 2025-05-24 19:42:18 +08:00
magicedy
986ad42ed7 fix: resolve key conflicts between local-start-app and plugin-history 2025-04-27 12:14:32 +08:00
muwoo
42aec3403a Merge pull request #415 from yangyangdaji/readme
readme: some fix
2025-03-04 16:45:10 +08:00
yangyangdaji
8c15dba68d readme (en) some fix
1. fix blue line between badges in github
2. change badges tooltip

Signed-off-by: yangyangdaji <1504305527@qq.com>
2025-02-27 11:55:26 +08:00
yangyangdaji
37647de7a8 readme (zh-cn) 一些修复
1. 修复一些徽章在 github 浏览时出现的蓝色蓝点
2. 修复徽章一些徽章的提示名称

Signed-off-by: yangyangdaji <1504305527@qq.com>
2025-02-27 11:51:04 +08:00
muwoo
1b2c9b3577 Merge pull request #411 from PineSongCN/master
🐛 修复 #410
2025-01-21 16:53:24 +08:00
muwoo
7cb832829d Update README.md 2025-01-21 16:52:19 +08:00
徐松
02da06c450 Update package.json version @4.3.2 2025-01-21 16:46:41 +08:00
徐松
e613fc19d4 🐛 修复 修改database url已过期源为https://gitee.com/monkeyWang/rubickdatabase/raw/master 2025-01-21 16:45:05 +08:00
徐松
c7807aeb3f 🐛 修复 https://github.com/rubickCenter/rubick/issues/410\#issuecomment-2601278762 2025-01-20 15:46:19 +08:00
muwoo
9813573679 Update package.json 2024-12-26 18:40:45 +08:00
muwoo
61ec18f0dc fix: #404 2024-12-26 18:40:27 +08:00
wangwei1240
5ca1ba1271 feat: 为了更好的安装体验,切换到依赖本地 node 环境 2024-12-11 20:06:21 +08:00
wangwei1240
8c3186afef Merge remote-tracking branch 'origin/master' 2024-12-11 20:05:20 +08:00
wangwei1240
de0e9ed8f2 fix: 更新版本 2024-12-11 20:05:00 +08:00
muwoo
ef85084730 Update package.json 2024-10-05 18:41:32 +08:00
muwoo
b4b7c81b60 Update index.ts 2024-10-05 18:41:16 +08:00
muwoo
4b79cce2f4 Update package.json 2024-09-30 21:19:07 +08:00
muwoo
ae10dac5f7 Merge pull request #396 from clevertension/master
fix #395: the plugin windows error with data retrieve
2024-09-30 21:18:23 +08:00
clevertension
1e0babe22d fix #395: the plugin windows error data retrieve 2024-09-30 15:22:13 +08:00
muwoo
5ec18caa72 Update package.json 2024-09-29 09:55:52 +08:00
muwoo
b7d8932291 Update index.ts
ref: 调整插件市场的数据源
2024-09-29 09:55:37 +08:00
muwoo
5608a147f7 Update package.json 2024-08-06 18:16:14 +08:00
muwoo
132fb94289 Update main.ts 2024-08-06 18:15:49 +08:00
muwoo
bb1a74b3b9 Update main.yml 2024-07-19 13:49:22 +08:00
layyback
bf9da854c7 release new version 2024-07-18 19:24:32 +08:00
layyback
a2c5bcc90c add new keyboard events 2024-07-18 18:58:34 +08:00
layyback
b9f4333c01 🎨 fix text display issue 2024-07-18 18:47:52 +08:00
layyback
bbeddb3fe6 support #371 2024-07-18 17:53:23 +08:00
layyback
4a2ca33e02 support #371 2024-07-18 17:52:20 +08:00
layyback
0578c7c7eb 🔨 fix #377 2024-07-18 17:41:30 +08:00
layyback
ef34452a4f 🔨 fix #377 2024-07-18 17:40:03 +08:00
layyback
286d9da8d1 🐛 fix hooks triggering issue 2024-07-18 17:25:11 +08:00
layyback
6b9d5182bf 🐛 fix hooks triggering issue 2024-07-18 16:46:33 +08:00
muwoo
2053491782 Update README.md 2024-06-14 19:49:24 +08:00
muwoo
e128d01b81 Merge pull request #184 from qidian99/master
Fix regex match error
2024-06-12 13:52:04 +08:00
木偶
c3bc0bdb9e fix: #352 2024-05-28 20:13:10 +08:00
木偶
f1f4e62177 fix: #352 2024-05-28 20:12:38 +08:00
wangwei1240
c07d4bae55 fix: 更新版本 2024-05-16 20:14:41 +08:00
wangwei1240
c78dd9c4b6 fix: 修复 #364 2024-05-16 20:13:45 +08:00
muwoo
2dd4ed10cc 💚 修复构建报错:https://github.com/electron/electron/issues/41089 2024-02-20 18:16:42 +08:00
muwoo
70ce3dd037 🐛 修复 #338, #345, #340 2024-02-20 18:07:19 +08:00
muwoo
a0644c0ccf 🐛 fix #333, fix #327 2023-12-27 11:34:55 +08:00
muwoo
583e9934fa icon 替换 2023-11-18 13:49:35 +08:00
muwoo
7e66b3f3e9 linux 构建包修复 2023-11-16 15:54:58 +08:00
muwoo
342f0f36a5 linux 构建包修复 2023-11-16 15:38:06 +08:00
muwoo
2a75e440ad linux 构建包修复 2023-11-16 15:25:33 +08:00
muwoo
11f53d1e07 linux 构建包修复 2023-11-16 15:19:37 +08:00
muwoo
beb8134539 linux 构建包修复 2023-11-16 15:03:50 +08:00
muwoo
d916525934 支持 asar gz 包发布 2023-11-15 11:07:20 +08:00
muwoo
7d4ccb83a2 尝试单独构建 asar 包 2023-11-14 18:17:47 +08:00
muwoo
36c2a714b5 尝试单独构建 asar 包 2023-11-14 18:11:15 +08:00
muwoo
696c24657b 尝试单独构建 asar 包 #300 2023-11-14 18:08:59 +08:00
muwoo
f59069b2ec 尝试单独构建 asar 包 #300 2023-11-14 18:07:22 +08:00
muwoo
0c16139313 尝试单独构建 asar 包 #300 2023-11-14 17:33:14 +08:00
muwoo
c99ec18151 尝试单独构建 asar 包 #300 2023-11-14 17:13:15 +08:00
muwoo
dcea66e848 尝试单独构建 asar 包 #300 2023-11-14 16:52:08 +08:00
muwoo
75e3111587 📝 Writing docs. 2023-11-14 11:41:36 +08:00
muwoo
bd1757e068 📝 Writing docs. 2023-11-14 11:37:53 +08:00
muwoo
2055bf61b1 🐛 修复插件市场插件详情页点击下载无反应的bug 2023-11-13 14:15:04 +08:00
muwoo
6c096fcd99 ♻️ 优化搜索内容排序,修复setSubInput 无法触发 inputChange bug 2023-11-13 11:40:35 +08:00
muwoo
1656418c10 🐛 fix #289,#291,#290 2023-11-10 15:00:26 +08:00
muwoo
f671b83b6a 🐛 fix #289,#291,#290 2023-11-10 14:35:37 +08:00
muwoo
dfb8446cfd 🐛 windows 启动bug 2023-11-03 13:59:29 +08:00
muwoo
4e59294b16 🐛 修复超级面板设置bug 2023-11-03 11:28:38 +08:00
muwoo
562a13fdff 支持网页快开插件 2023-11-02 16:00:50 +08:00
muwoo
9663232864 🐛 修复销毁 BrowserView 的bug 2023-11-01 15:30:08 +08:00
muwoo
3f7285b177 🐛 fix #278, #277 2023-10-31 12:20:24 +08:00
muwoo
e8c8f40bae 🐛 fix #278, #277 2023-10-31 12:19:35 +08:00
muwoo
6ae15b8f37 🐛 修复插件新老npm插件安装不兼容的问题 2023-10-27 10:17:21 +08:00
muwoo
a3a7dfde98 内置npm,替代本地npm
♻️ 优化分离插件窗口交互
2023-10-26 11:04:16 +08:00
muwoo
289165de82 内置npm,替代本地npm
♻️ 优化分离插件窗口交互
2023-10-26 11:04:06 +08:00
muwoo
6da9e2fe9c 插件适配窗口缩放;修复窗口尺寸调整的bug;新增 createBrowserWindow、getCursorScreenPoint、getDisplayNearestPoint、outPlugin API 2023-10-23 15:30:15 +08:00
木偶
c00963fabb Update package.json 2023-10-22 15:12:32 +08:00
木偶
4b8f0e4657 Merge pull request #271 from lumozx/detach
fix: 解决win相互覆盖的问题
2023-10-22 13:22:24 +08:00
lumozx
28e7d2aa46 fix: 解决win相互覆盖的问题 2023-10-22 10:58:33 +08:00
木偶
404cb4fcb5 Merge pull request #267 from lumozx/master
fix: 多端数据同步下,列表适配暗黑模式
2023-10-20 15:50:43 +08:00
muwoo
5553170c5a 🐛 修复分离窗口后主程序失去响应的bug 2023-10-20 15:33:41 +08:00
lumozx
d8fabc6b4c fix: 暗黑模式下,点击刷新插件,插件名称输入框暗黑模式失效的问题 2023-10-20 12:12:10 +08:00
lumozx
88e4e325f3 fix: 选择器和输入框适配暗黑模式 2023-10-20 12:09:46 +08:00
muwoo
c0aaae08ee 🐛 修复 linux CI 2023-10-20 11:45:46 +08:00
muwoo
35598159a6 🐛 修复 linux CI 2023-10-20 11:45:36 +08:00
muwoo
2a1a332fbb ♻️ 修改 onPluginEnter 执行时机. 2023-10-20 11:23:57 +08:00
lumozx
6d105e0f56 fix: drawer与model暗黑适配 2023-10-20 11:01:21 +08:00
lumozx
d2acdeaad6 fix: 列表页暗黑适配 2023-10-20 10:27:56 +08:00
lumozx
54ad4ef7b2 Merge branch 'rubickCenter:master' into master 2023-10-19 21:33:15 +08:00
muwoo
7fb299d270 🐛 修复 #268 2023-10-19 15:24:13 +08:00
lumozx
606cb8bb22 fix: 多端数据同步下,列表适配暗黑模式 2023-10-18 12:44:49 +08:00
muwoo
142387d684 🐛 修复CI 2023-10-18 11:25:58 +08:00
muwoo
77127b55b0 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	src/main/index.ts
2023-10-18 11:03:10 +08:00
muwoo
bde5377282 🐛 修复 #264
 支持 db.postAttachment 和 db.getAttachment
♻️ 重构版本更新机制
2023-10-18 11:02:14 +08:00
木偶
d48f8638ed Merge pull request #262 from lumozx/master
优化引导页UI,修复部分文案错误
2023-10-16 21:49:08 +08:00
lumozx
9c92e0f5fa fix: 引导样式
1、margin-left太宽导致出现滚动条
2、aligin-items -> align-items
3、按钮优化鼠标手势
2023-10-16 16:30:10 +08:00
lumozx
af11f46518 fix: LICENSE非md文件 2023-10-16 16:26:51 +08:00
lumozx
d4a4a168cd fix: registerySystemPlugin -> registerSystemPlugin 2023-10-16 16:26:18 +08:00
muwoo
a7a85a7c62 💄 修复新人引导样式问题 2023-10-13 11:22:16 +08:00
muwoo
8fd9f342b8 🐛 #255 2023-10-13 10:40:14 +08:00
木偶
7db7b9e391 Merge pull request #260 from 1129921824/master
拼写优化及窗口高度设置
2023-10-13 10:09:13 +08:00
muwoo
9eb59a9158 减少项目打包体积,去除不必要的sourcemap 2023-10-13 10:04:17 +08:00
sunyuqiang
3a2f44a448 窗体宽高使用变量,设置最小高度 2023-10-13 09:58:39 +08:00
sunyuqiang
437419aca3 Merge branch 'feat/v3.0.0'
# Conflicts:
#	src/main/browsers/main.ts
2023-10-13 09:50:40 +08:00
sunyuqiang
e8d947f18a Merge branch 'master' of https://github.com/rubickCenter/rubick 2023-10-12 16:37:14 +08:00
木偶
0233bda981 Merge pull request #258 from rubickCenter/feat/v4.x
💚 fix ci
2023-10-12 16:02:08 +08:00
muwoo
90b57d8f02 💚 fix ci 2023-10-12 16:01:26 +08:00
木偶
87ef15ffd2 Merge pull request #257 from rubickCenter/feat/v4.x
📝 update readme
2023-10-12 15:45:06 +08:00
muwoo
96bc02905a 📝 update readme 2023-10-12 15:43:56 +08:00
木偶
9445cf098f Merge pull request #256 from rubickCenter/feat/v4.x
Feat/v4.x
2023-10-12 14:55:59 +08:00
muwoo
c5ddeef8bc 🔖 release v4 2023-10-12 14:54:40 +08:00
muwoo
3cf0d3471f 💄 UI 升级 2023-10-12 14:04:10 +08:00
muwoo
0d0f745fc1 🐛 尝试修复 mac M1 构建问题 2023-09-27 16:52:52 +08:00
muwoo
1ab00151e3 🐛 尝试修复 mac M1 构建问题 2023-09-27 15:02:18 +08:00
muwoo
4c2dcc1d3e 🐛 尝试修复 mac M1 构建问题 2023-09-27 15:01:36 +08:00
muwoo
645a94b5f2 Merge branch 'feat/v3.0.0' 2023-09-27 10:58:37 +08:00
muwoo
68f4e01942 🔖 release beta 2023-09-27 10:57:57 +08:00
木偶
ad3138244b Merge pull request #249 from rubickCenter/feat/v3.0.0
🐛 尝试修复 arm build 问题
2023-09-27 10:52:41 +08:00
muwoo
effd00f10f 🐛 尝试修复 arm build 问题 2023-09-27 10:49:15 +08:00
木偶
0cbbe3525e Merge pull request #244 from rubickCenter/feat/v3.0.0
Feat/v3.0.0
2023-09-22 17:46:28 +08:00
muwoo
d1ce6a307d 🔖 release v3.2.3 2023-09-22 17:44:56 +08:00
muwoo
a26a03e948 🐛 fix macos 右击菜单打开rubick问题 2023-09-22 17:44:28 +08:00
sunyuqiang
9412d3bc59 🐛 windows搜索优化 2023-09-20 15:53:18 +08:00
sunyuqiang
ef77ca30b9 Merge branch 'feat/v3.0.0' of https://github.com/rubickCenter/rubick into feat/v3.0.0 2023-09-20 15:37:19 +08:00
sunyuqiang
dcd18fe8a1 🐛 windows搜索结果合并 2023-09-20 15:37:06 +08:00
sunyuqiang
9fed8c4c7b 禁用electron的拼写检查 & 设置窗体最小高度为60 2023-09-19 19:50:40 +08:00
sunyuqiang
60ba2bb6ad Merge remote-tracking branch 'origin/master'
# Conflicts:
#	feature/src/languages/i18n.ts
2023-09-18 09:41:25 +08:00
sunyuqiang
78ea2ac576 Merge branch 'master' of https://github.com/rubickCenter/rubick 2023-08-21 12:53:59 +08:00
sunyuqiang
a8883cd74d 删除多余console 2023-08-11 16:13:52 +08:00
Dian Qi
472879f9b2 Fix format regex error that will match all inputs 2023-06-04 20:30:06 +08:00
195 changed files with 4963 additions and 44742 deletions

View File

@@ -23,10 +23,14 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [macos-latest, windows-2019, ubuntu-latest]
os: [macos-latest, windows-2022, ubuntu-latest]
# create steps
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.10'
# step1: check out repository
- name: Check out git repository
uses: actions/checkout@v2
@@ -42,6 +46,7 @@ jobs:
run: |
sudo apt-get install libxtst-dev libpng++-dev
sudo apt-get install --no-install-recommends -y icnsutils graphicsmagick xz-utils
sudo snap install snapcraft --classic
# step3: yarn
- name: Yarn install
run: |

3
.gitignore vendored
View File

@@ -1,6 +1,7 @@
.DS_Store
node_modules
/build
build/*
!build/icons
# local env files

2
.npmrc
View File

@@ -1 +1 @@
electron_mirror=https://npm.taobao.org/mirrors/electron/
electron_mirror=https://npmmirror.com/mirrors/electron/

126
README.md
View File

@@ -1,76 +1,62 @@
English | [简体中文](./README.zh-CN.md)
<div align= "center">
<img align="center" width=200 src="https://user-images.githubusercontent.com/21073039/128333805-73e086f0-5523-46a3-a096-cba80b904c46.png" />
<img align="center" width=200 src="./public/logo.png" />
</div>
<div align= "center">
<h1>Rubick</h1>
<img alt="release" src="https://img.shields.io/github/downloads/rubickCenter/rubick/total" />
<a href="https://github.com/rubickCenter/rubick/releases">
<img alt="release" src="https://img.shields.io/github/package-json/v/rubickCenter/rubick" />
</a>
<a href="https://github.com/rubickCenter/rubick/actions">
<img alt=building src=https://img.shields.io/github/actions/workflow/status/rubickCenter/rubick/main.yml>
</a>
<a href="https://github.com/rubickCenter/rubick/blob/master/LICENSE">
<img alt="npm" src="https://img.shields.io/github/license/rubickCenter/rubick" />
</a>
<a href="https://github.com/rubickCenter/rubick/stargazers">
<img alt="star" src="https://img.shields.io/github/stars/rubickCenter/rubick?style=social">
</a>
<a href="https://gitee.com/monkeyWang/rubick">
<img alt="码云" src="https://img.shields.io/badge/Gitee--yellow.svg?style=social&logo=data:image/svg+xml;base64,PHN2ZyB0PSIxNTc0ODM3MTM4ODM3IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjE3NzAiICAgICB3aWR0aD0iMTYiIGhlaWdodD0iMTYiPiAgICA8cGF0aCBkPSJNODkxIDQyOC44SDQ2NS44Yy0yMC40IDAtMzcgMTYuNS0zNyAzN3Y5Mi40YzAgMjAuNCAxNi41IDM3IDM3IDM3aDI1OC45YzIwLjQgMCAzNyAxNi42IDM3IDM3djE4LjRjMCA2MS4zLTQ5LjcgMTEwLjktMTEwLjkgMTEwLjlIMjk5LjRjLTIwLjQgMC0zNy0xNi42LTM3LTM3VjM3My4yYzAtNjEuMyA0OS43LTExMC45IDExMC45LTExMC45aDUxNy42YzIwLjQgMCAzNy0xNi41IDM3LTM3bDAuMS05Mi4zYzAtMjAuNC0xNi41LTM3LTM3LTM3SDM3My4zQzIyMC4yIDk2IDk2IDIyMC4yIDk2IDM3My4zVjg5MWMwIDIwLjQgMTYuNiAzNyAzNyAzN2g1NDUuNEM4MTYuMiA5MjggOTI4IDgxNi4zIDkyOCA2NzguNFY0NjUuOGMwLTIwLjQtMTYuNi0zNy0zNy0zN3oiICAgICAgICAgIGZpbGw9IiNkODFlMDYiIHAtaWQ9IjE3NzEiPjwvcGF0aD48L3N2Zz4="/>
</a>
<div align="center">
<h1>Rubick</h1>
<img alt="downloads" src="https://img.shields.io/github/downloads/rubickCenter/rubick/total" />
<a href="https://github.com/rubickCenter/rubick/releases"><img alt="latest release" src="https://img.shields.io/github/package-json/v/rubickCenter/rubick" /></a>
<a href="https://github.com/rubickCenter/rubick/actions"><img alt="github action building" src="https://img.shields.io/github/actions/workflow/status/rubickCenter/rubick/main.yml" /></a>
<a href="https://github.com/rubickCenter/rubick/blob/master/LICENSE"><img alt="license" src="https://img.shields.io/github/license/rubickCenter/rubick" /></a>
<a href="https://github.com/rubickCenter/rubick/stargazers"><img alt="github stars" src="https://img.shields.io/github/stars/rubickCenter/rubick?style=social" /></a>
<a href="https://gitee.com/monkeyWang/rubick"><img alt="gitee mirror" src="https://img.shields.io/badge/Gitee--yellow.svg?style=social&logo=data:image/svg+xml;base64,PHN2ZyB0PSIxNTc0ODM3MTM4ODM3IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjE3NzAiICAgICB3aWR0aD0iMTYiIGhlaWdodD0iMTYiPiAgICA8cGF0aCBkPSJNODkxIDQyOC44SDQ2NS44Yy0yMC40IDAtMzcgMTYuNS0zNyAzN3Y5Mi40YzAgMjAuNCAxNi41IDM3IDM3IDM3aDI1OC45YzIwLjQgMCAzNyAxNi42IDM3IDM3djE4LjRjMCA2MS4zLTQ5LjcgMTEwLjktMTEwLjkgMTEwLjlIMjk5LjRjLTIwLjQgMC0zNy0xNi42LTM3LTM3VjM3My4yYzAtNjEuMyA0OS43LTExMC45IDExMC45LTExMC45aDUxNy42YzIwLjQgMCAzNy0xNi41IDM3LTM3bDAuMS05Mi4zYzAtMjAuNC0xNi41LTM3LTM3LTM3SDM3My4zQzIyMC4yIDk2IDk2IDIyMC4yIDk2IDM3My4zVjg5MWMwIDIwLjQgMTYuNiAzNyAzNyAzN2g1NDUuNEM4MTYuMiA5MjggOTI4IDgxNi4zIDkyOCA2NzguNFY0NjUuOGMwLTIwLjQtMTYuNi0zNy0zNy0zN3oiICAgICAgICAgIGZpbGw9IiNkODFlMDYiIHAtaWQ9IjE3NzEiPjwvcGF0aD48L3N2Zz4=" /></a>
</div>
Based on electron open source toolbox, free integration of rich plug-ins, to create the ultimate desktop efficiency tool。Rubick is one of the heroes of Dota The core skill is the ability to use other heroes as plug-insFinished the walk 。Very consistent with the design concept of this toolSo named Rubick。
<div align= "center">
<img align="center" src="https://picx.zhimg.com/80/v2-f8fe09ef125dac5fdcbef3fe00f92b21_720w.png" />
</div>
Open-source plugin-based desktop efficiency toolbox. The plugins are installed and uninstalled based on npm, which is very lightweight. The plugin data supports webdav multi-terminal synchronization, which is very secure. It supports internal network deployment and can be customized for further development, which is very flexible.
## Sponsor
我们通过有偿的方式积累高质量的常见问题、最佳实践文档,加入星球后可以和作者进行互动和答疑。我们提供技术支持、答疑解惑、定制化插件开发、二次定制化开发 rubick 等等官方服务。
权益明细可以参考文档:[权益明细](https://rubickcenter.github.io/rubick/super/)
<img width=400 src=https://picx.zhimg.com/80/v2-6deabf65175d18080439ef813102d18c_720w.png />
## Installation package
## Get Rubick
Download the latest release:
* [Rubick Mac OS](https://github.com/rubickCenter/rubick/releases)
* [Rubick Windows](https://github.com/rubickCenter/rubick/releases)
* [Rubick Linux](https://github.com/rubickCenter/rubick/releases)
## Feature list
- [x] Plug-in management based on npm package mode, installing plugins is as easy as installing npm packages.
- [x] Support system plug-ins, as long as rubick is running, plug-ins can be used at any time.
- [x] Support global shortcut key settings
- [x] Support clipboard file search
- [x] Support searching for locally installed apps or preferences
- [x] Support MacOS
- [x] Support Windows
- [x] Support Linux
## Docs
[Rubick website](https://rubick.vip)
[Rubick Docs](https://rubickCenter.github.io/rubick/)
[Rubick Docs](https://rubickCenter.github.io/docs/)
## How To Use Rubick
After installing rubick, you can quickly launch the main program by pressing the shortcut keys Alt/Option+R. Entering keywords in the main program input box can search for corresponding apps, plugins, files...
Select the ones you want and use them.
## Core function
If you don't want the function, you can click the logo on the left to enter the plugin market and find the ones you want to install.
## Feature list
- [x] Plugin management based on the npm package pattern, installing plugins is as simple as installing npm packages.
- [x] Supports WebDAV for multi-device data synchronization, ensuring true data security synchronization.
- [x] A unique system plugin mode that allows plugins to become an integral part of Rubick.
- [x] Supports the quick launch of local apps, files, and folders.
- [x] Supports enterprise-level intranet deployment.
- [x] Supports multiple languages.
## Core functionality showcase.
### 1. Search system application
Support pinyin and abbreviations to search system applications
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ba363e8f60f540e6a5c365c4317c4413~tplv-k3u1fbpfcp-watermark.image)
![](https://pic1.zhimg.com/80/v2-70c105ff7fb1e955fc67ffa5a5564092_720w.gif)
### 2. UI plug-in installation
Click the `rubick` icon on the right side of the search box to enter the plug-in market, select the desired plug-in, and click the download button to download. After the download is complete, you can find the installed plug-in under the Installed tab
After the installation is complete, enter the plug-in call up command to use the corresponding plug-in
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7ae45c7ede1f4e3bb7d35ae845e60b64~tplv-k3u1fbpfcp-watermark.image)
![](https://pic1.zhimg.com/80/v2-5906bba20fe0a67f9e7a5a8c11341305_720w.gif)
### 3. System plug-in installation
The system plug-in installation method is the same as that of the UI category. In the plug-in market, select the `system category` and find the system plug-in that suits you to install it.
@@ -78,22 +64,48 @@ The system plug-in installation method is the same as that of the UI category. I
After the system plug-in is installed successfully, rubick needs to be restarted to take effect
```
### 4. The input box focus automatically matches the plug-in according to the clipboard content
Search for `Preferences` in `rubick`, and then turn on the `Auto Paste` function to match the clipboard content and automatically match the plug-in for use.
### 4. Multi-device data synchronization based on WebDAV.
In "Rubick," search for "Preferences," go to "Account and Settings," and then select "Multi-Device Data Synchronization." You can export and import data for the use of Rubick plugins.
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/01ef50fbfa064ba9a88bebe1531eacd4~tplv-k3u1fbpfcp-watermark.image)
![](https://pic1.zhimg.com/80/v2-ff85793741e4dff82a729d3eb3d41551_720w.png)
### More features
If you need more features, please come here to give us suggestions[issues](https://github.com/rubickCenter/rubick/issues) 。
We will add valuable ideas to the later development. At the same time, welcome to join and build together。
## Related Repositories
## 贡献
This project exists thanks to all the people who contribute. [[Contribute](https://github.com/rubickCenter/rubick/graphs/contributors)]. <a href="https://github.com/rubickCenter/rubick/graphs/contributors"><img src="https://opencollective.com/rubick/contributors.svg?width=890&button=false" /></a>
[Rubick Plugins Repositories](https://gitee.com/rubick-center)
## 反馈
对本项目有兴趣或者想要交流学习的同学可以扫码加下面的微信,备注 rubick帮助我们更好的成长
[Rubick Plugins Database](https://gitcode.net/rubickcenter/rubick-database)
[Rubick Plugin CLI](https://github.com/rubickCenter/rubick-plugin-cli)
## Sponsor
### 1. Join the Knowledge Planet
We have accumulated a lot of knowledge and common issues about rubick on the Knowledge Planet. You can pay to join our knowledge community to discuss with us. We will answer at any time!
<img width=400 src=https://picx.zhimg.com/80/v2-6deabf65175d18080439ef813102d18c_720w.png />
### 2. Buy me a cup of coffee
If the project is helpful to you, you can buy me a cup of coffee as a reward!
<div align= "left">
<img width="180" src="https://picx.zhimg.com/80/v2-911d249dc454f3460451a4e1ecceeb14_720w.png">
<img width="180" src="https://picx.zhimg.com/80/v2-3160247d6099053405e6cd2cb6afb5e5_720w.png">
</div>
## 友情链接
<a href="https://pro.kuaitu.cc/" target="_blank">
<img width="100" src="https://github.com/user-attachments/assets/6127488e-466b-4e71-98ab-00fb3c76553e" />
</a>
## Feedback
Those who are interested in this project or want to exchange and learn can scan the QR code and add the following WeChat, with the comment rubick, to help us grow better.
![image](https://user-images.githubusercontent.com/21073039/127327603-9796f246-ee4b-4950-a69d-ce3205ec9569.png)
<a href="https://hellogithub.com/repository/0a3e2484b44e481e9dcf1850e45193cd" target="_blank"><img src="https://api.hellogithub.com/v1/widgets/recommend.svg?rid=0a3e2484b44e481e9dcf1850e45193cd&claim_uid=vXGwjpmYNsBex0C" alt="FeaturedHelloGitHub" style="width: 250px; height: 54px;" width="250" height="54" /></a>
## Contribute
This project exists thanks to all the people who contribute. [[Contribute](https://github.com/rubickCenter/rubick/graphs/contributors)]. <a href="https://github.com/rubickCenter/rubick/graphs/contributors"><img src="https://opencollective.com/rubick/contributors.svg?width=890&button=false" /></a>
## License
This project is licensed under the MIT License - see the [LICENSE.md](https://github.com/rubickCenter/rubick/blob/master/LICENSE) file for details.
This project is licensed under the MIT License - see the [LICENSE](https://github.com/rubickCenter/rubick/blob/master/LICENSE) file for details.

View File

@@ -2,74 +2,62 @@
<div align= "center">
<img align="center" width=200 src="https://user-images.githubusercontent.com/21073039/128333805-73e086f0-5523-46a3-a096-cba80b904c46.png" />
<img align="center" width=200 src="./public/logo.png" />
</div>
<div align="center">
<h1>Rubick</h1>
<img alt="累计下载数" src="https://img.shields.io/github/downloads/rubickCenter/rubick/total" />
<a href="https://github.com/rubickCenter/rubick/releases"><img alt="最新发布版本" src="https://img.shields.io/github/package-json/v/rubickCenter/rubick" /></a>
<a href="https://github.com/rubickCenter/rubick/actions"><img alt="github action 构建" src="https://img.shields.io/github/actions/workflow/status/rubickCenter/rubick/main.yml" /></a>
<a href="https://github.com/rubickCenter/rubick/blob/master/LICENSE"><img alt="许可证" src="https://img.shields.io/github/license/rubickCenter/rubick" /></a>
<a href="https://github.com/rubickCenter/rubick/stargazers"><img alt="github 收藏数" src="https://img.shields.io/github/stars/rubickCenter/rubick?style=social" /></a>
<a href="https://gitee.com/monkeyWang/rubick"><img alt="gitee 镜像源" src="https://img.shields.io/badge/Gitee--yellow.svg?style=social&logo=data:image/svg+xml;base64,PHN2ZyB0PSIxNTc0ODM3MTM4ODM3IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjE3NzAiICAgICB3aWR0aD0iMTYiIGhlaWdodD0iMTYiPiAgICA8cGF0aCBkPSJNODkxIDQyOC44SDQ2NS44Yy0yMC40IDAtMzcgMTYuNS0zNyAzN3Y5Mi40YzAgMjAuNCAxNi41IDM3IDM3IDM3aDI1OC45YzIwLjQgMCAzNyAxNi42IDM3IDM3djE4LjRjMCA2MS4zLTQ5LjcgMTEwLjktMTEwLjkgMTEwLjlIMjk5LjRjLTIwLjQgMC0zNy0xNi42LTM3LTM3VjM3My4yYzAtNjEuMyA0OS43LTExMC45IDExMC45LTExMC45aDUxNy42YzIwLjQgMCAzNy0xNi41IDM3LTM3bDAuMS05Mi4zYzAtMjAuNC0xNi41LTM3LTM3LTM3SDM3My4zQzIyMC4yIDk2IDk2IDIyMC4yIDk2IDM3My4zVjg5MWMwIDIwLjQgMTYuNiAzNyAzNyAzN2g1NDUuNEM4MTYuMiA5MjggOTI4IDgxNi4zIDkyOCA2NzguNFY0NjUuOGMwLTIwLjQtMTYuNi0zNy0zNy0zN3oiICAgICAgICAgIGZpbGw9IiNkODFlMDYiIHAtaWQ9IjE3NzEiPjwvcGF0aD48L3N2Zz4=" /></a>
</div>
<div align= "center">
<h1>Rubick</h1>
<img alt="release" src="https://img.shields.io/github/downloads/rubickCenter/rubick/total" />
<a href="https://github.com/rubickCenter/rubick/releases">
<img alt="release" src="https://img.shields.io/github/package-json/v/rubickCenter/rubick" />
</a>
<a href="https://github.com/rubickCenter/rubick/actions">
<img alt=building src=https://img.shields.io/github/workflow/status/rubickCenter/rubick/Build>
</a>
<a href="https://github.com/rubickCenter/rubick/blob/master/LICENSE">
<img alt="npm" src="https://img.shields.io/github/license/rubickCenter/rubick" />
</a>
<a href="https://github.com/rubickCenter/rubick/stargazers">
<img alt="star" src="https://img.shields.io/github/stars/rubickCenter/rubick?style=social">
</a>
<a href="https://gitee.com/monkeyWang/rubick">
<img alt="码云" src="https://img.shields.io/badge/Gitee--yellow.svg?style=social&logo=data:image/svg+xml;base64,PHN2ZyB0PSIxNTc0ODM3MTM4ODM3IiBjbGFzcz0iaWNvbiIgdmlld0JveD0iMCAwIDEwMjQgMTAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHAtaWQ9IjE3NzAiICAgICB3aWR0aD0iMTYiIGhlaWdodD0iMTYiPiAgICA8cGF0aCBkPSJNODkxIDQyOC44SDQ2NS44Yy0yMC40IDAtMzcgMTYuNS0zNyAzN3Y5Mi40YzAgMjAuNCAxNi41IDM3IDM3IDM3aDI1OC45YzIwLjQgMCAzNyAxNi42IDM3IDM3djE4LjRjMCA2MS4zLTQ5LjcgMTEwLjktMTEwLjkgMTEwLjlIMjk5LjRjLTIwLjQgMC0zNy0xNi42LTM3LTM3VjM3My4yYzAtNjEuMyA0OS43LTExMC45IDExMC45LTExMC45aDUxNy42YzIwLjQgMCAzNy0xNi41IDM3LTM3bDAuMS05Mi4zYzAtMjAuNC0xNi41LTM3LTM3LTM3SDM3My4zQzIyMC4yIDk2IDk2IDIyMC4yIDk2IDM3My4zVjg5MWMwIDIwLjQgMTYuNiAzNyAzNyAzN2g1NDUuNEM4MTYuMiA5MjggOTI4IDgxNi4zIDkyOCA2NzguNFY0NjUuOGMwLTIwLjQtMTYuNi0zNy0zNy0zN3oiICAgICAgICAgIGZpbGw9IiNkODFlMDYiIHAtaWQ9IjE3NzEiPjwvcGF0aD48L3N2Zz4="/>
</a>
<img align="center" src="https://picx.zhimg.com/80/v2-f8fe09ef125dac5fdcbef3fe00f92b21_720w.png" />
</div>
开源的插件化桌面端效率工具箱。插件是基于 npm 进行安装和卸载,非常轻便。插件数据支持 webdav 多端同步,非常安全。支持内网部署,可二次定制化开发,非常灵活。
基于 electron 的开源工具箱自由集成丰富插件打造极致的桌面端效能工具。Rubick(拉比克) 是 dota 里面的英雄之一,其核心技能是插件化使用其他英雄的技能,用完即走。非常符合本工具的设计理念,所以取名 Rubick
## 获取 rubick
下载最新的安装包:
## 赞助和服务
我们通过有偿的方式积累高质量的常见问题、最佳实践文档,加入星球后可以和作者进行互动和答疑。我们提供技术支持、答疑解惑、定制化插件开发、二次定制化开发 rubick 等等官方服务。
权益明细可以参考文档:[权益明细](https://rubickcenter.github.io/rubick/super/)
<img width=400 src=https://picx.zhimg.com/80/v2-6deabf65175d18080439ef813102d18c_720w.png />
## 安装包
* [Rubick Mac OS](https://github.com/rubickCenter/rubick/releases)
* [Rubick Windows](https://github.com/rubickCenter/rubick/releases)
* [Rubick Linux](https://github.com/rubickCenter/rubick/releases)
## 支持能力
- [x] 基于 npm 包模式的插件管理,安装插件和安装 npm 包一样简单
- [x] 支持系统插件,只要在 rubick 运行时,插件可以随时使用
- [x] 支持全局快捷键设置
- [x] 支持剪贴板文件搜索
- [x] 支持搜索本地已安装 app 或 偏好设置
- [x] 支持 MacOS
- [x] 支持 Windows
- [x] 支持 Linux
## 使用文档
[Rubick 官网](https://rubick.vip)
[Rubick Docs](https://rubickCenter.github.io/rubick/)
## 如何使用 rubick
## 目前支持能力
安装完成 rubick 后,可以通过快捷键 Alt/Option+R 可以快速呼起主程序。主程序输入框内输入关键词可以搜索出对应的 App、插件、文件... 选择即可使用。如果没有想要的功能,可以点击左侧的 logo 进入插件市场寻找自己想要的插件进行安装。
## 支持能力
- [x] 基于 npm 包模式的插件管理,安装插件和安装 npm 包一样简单
- [x] 支持 webdav 多端数据同步,真正的数据安全同步
- [x] 独一无二的系统插件模式,让插件成为 rubick 的一部分
- [x] 支持快速启动本地 app、文件、文件夹
- [x] 支持企业化内网部署
- [x] 支持多语言
## 核心功能展示
### 1. 搜索系统应用
支持拼音和缩写来搜索系统安装应用:
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ba363e8f60f540e6a5c365c4317c4413~tplv-k3u1fbpfcp-watermark.image)
![](https://pic1.zhimg.com/80/v2-70c105ff7fb1e955fc67ffa5a5564092_720w.gif)
### 2. UI类插件安装
点击搜索框右侧 `rubick` 图标,进入插件市场,选择所需插件,点击下载按钮即可下载,下载完成后在已安装 tab 下可以找到安装插件。
安装完成后,输入插件呼起命令即可使用对应插件:
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7ae45c7ede1f4e3bb7d35ae845e60b64~tplv-k3u1fbpfcp-watermark.image)
![](https://pic1.zhimg.com/80/v2-5906bba20fe0a67f9e7a5a8c11341305_720w.gif)
### 3. 系统类插件安装
系统插件安装方式和UI类一样在插件市场选择`系统分类`,寻找适合自己的系统插件安装即可。
@@ -78,23 +66,41 @@
系统插件安装成功后,需要重启 rubick 才能生效
```
### 4. 输入框聚焦自动根据剪切板内容匹配插件
`rubick` 内搜索`偏好设置`,然后开启`自动粘贴` 功能,即可匹配剪切板内容自动匹配适合插件进行使用
### 4. 基于 webdav 的多端数据同步
`rubick` 内搜索`偏好设置` 进入 `账户和设置` -> `多端数据同步`;即可对 `rubick` 插件使用数据进行 `导出``导入`
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/01ef50fbfa064ba9a88bebe1531eacd4~tplv-k3u1fbpfcp-watermark.image)
![](https://pic1.zhimg.com/80/v2-ff85793741e4dff82a729d3eb3d41551_720w.png)
### 更多功能
如果您还需要更多功能,欢迎来这里给我们提建议:[issues](https://github.com/rubickCenter/rubick/issues) 。
有价值的想法我们会加入到后期的开发当中。同时也欢迎一起加入共建。
## 关联仓库
## 贡献
This project exists thanks to all the people who contribute. [[Contribute](https://github.com/rubickCenter/rubick/graphs/contributors)]. <a href="https://github.com/rubickCenter/rubick/graphs/contributors"><img src="https://opencollective.com/rubick/contributors.svg?width=890&button=false" /></a>
[Rubick 插件仓库](https://gitee.com/rubick-center)
[Rubick 插件数据库](https://gitcode.net/rubickcenter/rubick-database)
[Rubick Plugin CLI](https://github.com/rubickCenter/rubick-plugin-cli)
## 赞助
### 1. 加入知识星球
我们在知识星球积累了大量的关于 rubick 的知识和常见问题,您可以付费加入我们的知识星球来一起讨论。我们将随时解答!
<img width=400 src=https://picx.zhimg.com/80/v2-6deabf65175d18080439ef813102d18c_720w.png />
### 2. 打赏喝杯咖啡
如果项目对你有帮助,可以请我喝杯咖啡赞赏!
<div align= "left">
<img width="180" src="https://picx.zhimg.com/80/v2-911d249dc454f3460451a4e1ecceeb14_720w.png">
<img width="180" src="https://picx.zhimg.com/80/v2-3160247d6099053405e6cd2cb6afb5e5_720w.png">
</div>
## 反馈
对本项目有兴趣或者想要交流学习的同学可以扫码加下面的微信,备注 rubick帮助我们更好的成长
![image](https://user-images.githubusercontent.com/21073039/127327603-9796f246-ee4b-4950-a69d-ce3205ec9569.png)
## License
This project is licensed under the MIT License - see the [LICENSE.md](https://github.com/rubickCenter/rubick/blob/master/LICENSE) file for details.
## 贡献
This project exists thanks to all the people who contribute. [[Contribute](https://github.com/rubickCenter/rubick/graphs/contributors)]. <a href="https://github.com/rubickCenter/rubick/graphs/contributors"><img src="https://opencollective.com/rubick/contributors.svg?width=890&button=false" /></a>
## License
This project is licensed under the MIT License - see the [LICENSE](https://github.com/rubickCenter/rubick/blob/master/LICENSE) file for details.

View File

@@ -1,9 +1,23 @@
module.exports = {
presets: ["@vue/cli-plugin-babel/preset"],
presets: ['@vue/cli-plugin-babel/preset'],
plugins: [
[
"import",
{ libraryName: "ant-design-vue", libraryDirectory: "es", style: "css" },
], // `style: true` 会加载 less 文件
'import',
{
libraryName: 'ant-design-vue',
libraryDirectory: 'es',
style: 'css', // or 'css'
},
'ant-design-vue',
],
[
'import',
{
libraryName: '@ant-design/icons-vue',
libraryDirectory: 'lib/icons',
camel2DashComponentName: false,
},
'@ant-design/icons-vue',
],
],
};

View File

@@ -1,24 +0,0 @@
#!/usr/bin/env sh
# 确保脚本抛出遇到的错误
set -e
# 生成静态文件
cd docs && npm run docs:build
# 进入生成的文件夹
cd docs/.vuepress/dist
# 如果是发布到自定义域名
# echo 'www.example.com' > CNAME
git init
git add -A
git commit -m 'deploy'
# 如果发布到 https://<USERNAME>.github.io
# git push -f git@github.com:<USERNAME>/<USERNAME>.github.io.git master
# 如果发布到 https://<USERNAME>.github.io/<REPO>
git push -f git@github.com:rubickCenter/rubick.git master:gh-pages
cd -

View File

@@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
<title></title>
</head>
<body>
<noscript>

View File

@@ -1,5 +1,5 @@
<template>
<div :class="[platform, 'detach']">
<div :class="[process.platform, 'detach']">
<div class="info">
<img :src="plugInfo.logo"/>
<input
@@ -15,7 +15,7 @@
<div class="handle">
<div class="devtool" @click="openDevTool" title="开发者工具"></div>
</div>
<div class="window-handle" v-if="platform !== 'darwin'">
<div class="window-handle" v-if="process.platform !== 'darwin'">
<div class="minimize" @click="minimize"></div>
<div class="maximize" @click="maximize"></div>
<div class="close" @click="close"></div>
@@ -30,7 +30,7 @@ import { ref } from 'vue';
const { ipcRenderer } = window.require('electron');
const platform = ref(window.process.platform);
const process = window.require('process');
const showInput = ref(false);
const storeInfo = localStorage.getItem('rubick-system-detach') || '{}';
@@ -86,6 +86,47 @@ Object.assign(window, {
plugInfo.value.subInput = null;
},
});
window.enterFullScreenTrigger = () => {
document.querySelector('.detach').classList.remove('darwin');
};
window.leaveFullScreenTrigger = () => {
const titleDom = document.querySelector('.detach');
if (!titleDom.classList.contains('darwin')) {
titleDom.classList.add('darwin');
}
};
window.maximizeTrigger = () => {
const btnMaximize = document.querySelector('.maximize')
if (!btnMaximize || btnMaximize.classList.contains('unmaximize')) return;
btnMaximize.classList.add('unmaximize');
};
window.unmaximizeTrigger = () => {
const btnMaximize = document.querySelector('.maximize');
if (!btnMaximize) return;
btnMaximize.classList.remove('unmaximize');
};
if (process.platform === 'darwin') {
window.onkeydown = (e) => {
if (e.code === 'Escape') {
ipcRenderer.send('detach:service', { type: 'endFullScreen' });
return;
}
if (e.metaKey && (e.code === 'KeyW' || e.code === 'KeyQ')) {
window.handle.close()
}
}
} else {
window.onkeydown = (e) => {
if (e.ctrlKey && e.code === 'KeyW') {
window.handle.close()
return
}
}
}
</script>
<style>

View File

@@ -1,13 +1,17 @@
const path = require("path");
const path = require('path');
module.exports = {
css: { // 配置css模块
loaderOptions: { // 向预处理器 Loader 传递配置选项
less: { // 配置less其他样式解析用法一致
css: {
// 配置css模块
loaderOptions: {
// 向预处理器 Loader 传递配置选项
less: {
// 配置less其他样式解析用法一致
javascriptEnabled: true, // 设置为true
},
},
},
outputDir: path.join(__dirname, "../public/detach"),
publicPath: process.env.NODE_ENV === "production" ? "" : "/",
productionSourceMap: false,
outputDir: path.join(__dirname, '../public/detach'),
publicPath: process.env.NODE_ENV === 'production' ? '' : '/',
};

View File

@@ -5864,7 +5864,7 @@ lodash.memoize@^4.1.2:
lodash.throttle@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
resolved "https://registry.npmmirror.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==
lodash.transform@^4.6.0:

View File

@@ -1,50 +0,0 @@
module.exports = {
title: 'Rubick',
description: '你的开源桌面插件应用',
base: '/rubick/',
themeConfig: {
themeColor: {
blue: "#2196f3",
red: "#2196f3",
green: "#2196f3",
orange: "#2196f3",
},
logo: '/images/logo.png',
nav: [
{ text: '使用文档', link: '/guide/' },
{ text: '开发者', link: '/dev/' },
],
sidebar: [
{
title: '使用文档', // 必要的
path: '/guide/', // 可选的, 标题的跳转链接,应为绝对路径且必须存在
sidebarDepth: 1, // 可选的, 默认值是 1
},
{
title: '插件开发',
path: '/dev/',
},
{
title: '特殊服务',
path: '/super/',
},
{
title: 'API',
path: '/api/',
},
{
title: '贡献 rubick',
path: '/run/',
}
],
// 假定是 GitHub. 同时也可以是一个完整的 GitLab URL
repo: 'https://github.com/rubickCenter/rubick',
// 自定义仓库链接文字。默认从 `themeConfig.repo` 中自动推断为
// "GitHub"/"GitLab"/"Bitbucket" 其中之一,或是 "Source"。
repoLabel: 'Github',
// 默认是 false, 设置为 true 来启用
editLinks: true,
// 默认为 "Edit this page"
editLinkText: '帮助我们改善此页面!'
}
}

Submodule docs/docs/.vuepress/dist deleted from 7b52f0fb4a

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -1,7 +0,0 @@
$accentColor = #ff4ea4//
$codeBgColor = #282c34//
//f12class
.sidebar-group.is-sub-group > .sidebar-heading:not(.clickable){
opacity :1
}

View File

@@ -1,16 +0,0 @@
---
home: true
heroImage: /images/logo.png
heroText: Rubick
tagline: 基于 Electron 开源的插件化工具箱
actionText: 快速上手 →
actionLink: /guide/
features:
- title: 极其轻量
details: rubick 仅仅包含插件运行所需要的API本身不内置任何插件可以看成是 electron 的二次封装框架。
- title: 更强大的插件能力
details: 不仅仅支持ui插件需要搜索呼起使用还支持系统插件不需要搜索只要rubick在运行系统插件即可用
- title: 更便捷的插件管理
details: rubick 插件全部托管在 npm 仓库rubick 插件的安装、使用、删除就是 npm 包的安装、使用、删除
footer: MIT Licensed | Copyright (c) 2021 muwoo
---

View File

@@ -1,261 +0,0 @@
## 事件
### onPluginReady(callback)、onPluginEnter(callback)
* `callback` Function
`callback` 内会返回一个 `object` 对象,来描述进入当前插件的环境信息:
* `code` String
> plugin.json 配置的 feature.code
* `type` String
> plugin.json 配置的 feature.cmd.type可以为 "text"、"img"、 "files"、 "regex"、 "over"、"window"
* payload String | Object | Array
> feature.cmd.type 对应匹配的数据
当插件装载成功rubick 将会主动调用这个方法, 所有的 `api` 都应该在 `onPluginReady` 之后进行调用。
#### 示例
```js
rubick.onPluginReady(({ code, type, payload }) => {
console.log('插件装配完成,已准备好')
})
/*
type 为 "files" 时, payload 值示例
[
{
"isFile": true,
"isDirectory": false,
"name": "demo.js",
"path": "C:\\demo.js"
}
]
type 为 "img" 时, payload 值示例
data:image/png;base64,...
type 为 "text"、"regex"、 "over" 时, payload 值为进入插件时的主输入框文本
*/
```
### onPluginOut(callback)
* `callback` Function
每当插件从前台进入到后台时rubick 将会主动调用这个方法。
## 窗口交互
### hideMainWindow()
隐藏主窗口
### showMainWindow()
显示主窗口
### setExpendHeight(height)
执行该方法将会修改插件窗口的高度。
* `height` Integer
* 返回 `Boolean`
#### 示例
```js
rubick.setExpendHeight(100)
```
### setSubInput(onChange, placeholder)
设置插件输入框监听,当进入插件后,用户搜索会触发`onChange` 函数
* `onChange` Function
* `Object`
* `text` String
> 子输入框文本修改时触发
* `placeholder` String (可选)
> 子输入框占位符
* `isFocus` Boolean (可选)
> 子输入框是否获得焦点,默认 true
`返回 Boolean`
#### 示例
```js
rubick.setSubInput(({ text }) => {
console.log(text)
}, '搜索')
```
### setSubInputValue(value)
直接对子输入框的值进行设置。
* `value` String
* `返回` Boolean
#### 示例
```js
rubick.setSubInputValue('rubick')
```
## 系统
### showNotification(body)
显示系统通知
* `body` String
```js
rubick.showNotification('Hi, rubick')
```
### shellOpenPath(fullPath)
打开给定路径的文件
* `fullPath` String
```js
rubick.shellOpenPath('/path/file')
```
### shellOpenExternal(url)
浏览器打开URL
* `url` String
```js
rubick.shellOpenExternal('https://www.baidu.com')
```
### getPath(name)
electron 内置 getPath 能力,详见 [electron API](https://www.electronjs.org/docs/latest/api/app#appgetpathname)
```js
console.log(rubick.getPath('cache'));
```
## 本地数据库
`rubick db` 是基于开源的 [pouchdb](https://github.com/pouchdb/pouchdb) 封装的
### rubick.db.put(doc)
* `doc` Object
* `返回` Object
#### 示例
```js
// 创建请求
rubick.db.put({
_id: "demo",
data: "demo"
})
// 返回 {id: "demo", ok: true, rev: "1-05c9b92e6f24287dc1f4ec79d9a34fa8"}
// 更新请求
rubick.db.put({
_id: "demo",
data: "demo",
_rev: "1-05c9b92e6f24287dc1f4ec79d9a34fa8"
})
```
_id 代表这个文档在数据库中唯一值,如果值不存在,则会创建一个新的文档,如果值已经存在,则会进行更新。你可能已经注意到,返回对象中包含一个 rev
属性,这是代表此文档的版本,每次对文档进行更新时,都要带上最新的版本号,否则更新将失败,版本化的意义在于解决同步时数据冲突。
另外需要注意,每次更新时都要传入完整的文档数据,无法对单个字段进行更新。
### rubick.db.get(id)
执行该方法将会根据文档 ID 获取数据
* `id` String
* `返回` Object
```js
rubick.db.get("demo")
// 返回 {_id: "demo", _rev: "3-9836c5c68af5aef618e17d615882942a", data: "demo"}
```
### rubick.db.remove(doc)
* `doc` String | Object
* `返回` Object 执行该方法将会删除数据库文档,可以传入文档对象或文档 id 进行操作。
```js
rubick.db.remove("demo")
// 返回 {id: "demo", ok: true, rev: "2-effe5dbc23dffc180d8411b23f3108fb"}
```
### rubick.db.bulkDocs(docs)
* `docs` Array
* `返回` Array 执行该方法将会批量更新数据库文档,传入需要更改的文档对象合并成数组进行批量更新。
```js
rubick.db.bulkDocs([{
_id: "demo1",
data: "demo",
_rev: "1-c8817a74e292eda4cba1a45924853af6"
}, {
_id: "demo2",
data: "demo",
_rev: "1-f0399b42cc6123a9cc8503632ba7b3a7"
}])
/* 返回
[{
id: "demo1", ok: true, rev: "2-7857b2801bc0303d2cc0bb82e8afd796"
}, {
id: "demo2", ok: true, rev: "2-7857b2801bc0303d2cc0bb82e8afd796"
}]
*/
```
### rubick.db.allDocs(key)
* `key` String | Array
* `返回` Array 执行该方法将会获取所有数据库文档,如果传入字符串,则会返回以字符串开头的文档,也可以传入指定 ID 的数组,不传入则为获取所有文档。
```js
// 获取所有文档
rubick.db.allDocs()
// 传入字符串则返回id以 demo 开头的文档
rubick.db.allDocs("demo")
/* 返回
[{
_id: "demo/123", _rev: "2-7857b2801bc0303d2cc0bb82e8afd796", data: "demo"
}, {
_id: "demo/124", _rev: "1-f0399b42cc6123a9cc8503632ba7b3a7", data: "demo"
}, {
_id: "demo/125", _rev: "1-f0399b42cc6123a9cc8503632ba7b3a7", data: "demo"
}]
*/
// 根据id数组请求
rubick.db.allDocs([
"demo1",
"demo2"
])
/* 返回
[{
_id: "demo1", _rev: "2-7857b2801bc0303d2cc0bb82e8afd796", data: "demo"
}, {
_id: "demo2", _rev: "1-f0399b42cc6123a9cc8503632ba7b3a7", data: "demo"
}]
*/
```

View File

@@ -1,176 +0,0 @@
## 插件说明
`rubick` 插件分为 `UI插件``系统插件` 2类。下面分别介绍这 2 类插件的区别和作用。
1. UI 插件 <Badge type="tip" text="最常用" />:都会有 UI 界面,用于和用户交互,且需要通过关键词搜索选择进行使用,比如 `斗图` 插件,有界面展示,且需要再搜索框内搜索关键词选择后进行呼起才能使用。
2. 系统插件:可能不会有 UI 界面,在 `rubick` 启动的时候,会注册执行系统插件。比如`超级面板` 插件,安装完成后,即可在 `rubick` 运行时随时使用,不需要任何关键词和匹配。
## 开发 UI 插件
一个最基础插件的目录是这样的:
```
rubick-plugin-demo
|-- index.html
|-- package.json
|-- preload.js
```
### 文件说明
#### package.json
用于指定插件最基础的配置,一个最基础的配置信息如下:
```json
{
"name": "rubick-ui-plugin-demo",
"pluginName": "插件demo",
"description": "rubick ui 插件demo",
"author": "muwoo",
"main": "index.html",
"logo": "https://www.img/demo.png",
"version": "0.0.1",
"preload":"preload.js",
"homePage": "https://gitee.com/rubick-center/rubick-ui-plugin-demo/raw/master/README.md",
"pluginType": "ui",
"features": [
{
"code": "index",
"explain": "测试插件",
"cmds":[
"demo",
"测试"
]
}
]
}
```
核心字段说明:
* name 插件 `npm` 包名称,<Badge type="tip" text="必填" />
* pluginName 插件显示名称,用于展示给使用者 <Badge type="tip" text="必填" />
* description 插件描述,描述这个插件的作用 <Badge type="tip" text="必填" />
* author 插件作者
* main 入口文件,一般为 `index.html`
* logo 尺寸建议 200 * 200, 插件的 logo, 需要是 http/https 在线地址不支持本地logo <Badge type="tip" text="必填" />
* version 插件的版本 <Badge type="tip" text="必填" />
* preload 预加载脚本
* homePage: 插件 readme raw 地址
* pluginType: 插件类型枚举ui, system. 当前选 ui <Badge type="tip" text="必填" />
* features 插件核心功能列表 <Badge type="tip" text="必填" />
* features.code 插件某个功能的识别码,可用于区分不同的功能 <Badge type="tip" text="必填" />
* features.explain 插件某个功能的解释 <Badge type="tip" text="必填" />
* features.cmds 输入框内搜索该 cmd 进入插件 <Badge type="tip" text="必填" />
#### index.html
插件的入口文件,用于展示插件的样式,一个最基础的 `html` 结构可以是这样:
```html
<!DOCTYPE html>
<html>
<body>
hello Rubick
<button id="showNotification">通知</button>
</body>
<script>
document.getElementById('showNotification').addEventListener('click', () => {
window.showNotification();
})
</script>
</html>
```
#### preload.js
细心的同学可能已经注意到上面的 `index.html` 使用了一个全局函数 `showNotification` 那么这个函数是在哪里定义的呢?
答案就是在 `preload.js` 里面。`preload.js` 可以为页面提供全局函数
```js
window.showNotification = function () {
rubick.showNotification('HI, rubick')
}
```
rubick 更多支持 API 能力参考:[rubick 全局API](https://github.com/rubickCenter/rubick/blob/master/public/preload.js)
### 测试写好的插件
由于 `rubick` 插件是基于 `npm` 的管理方式,所以开发者调试插件,也是基于 `npm` 的软连接的方式进行调试。
首先需要再插件 `package.json` 目录下执行:
```shell
$ npm link
```
然后将插件通过插件市场的 `开发者` 菜单进行安装,填写插件的 `name` 即可,如果插件需要调试,可以通过右上角 ... 来打开开发者工具进行调试,页面变更直接刷新即可:
![](https://pica.zhimg.com/80/v2-d7d6d5cba1151527aeff8e2c9b8cefb4_720w.gif)
本小节所有代码:[rubick-ui-plugin-demo](https://gitee.com/rubick-center/rubick-ui-plugin-demo)
## 开发系统插件
一个最基础插件的目录是这样的:
```
rubick-system-plugin-demo
|-- package.json
|-- index.js
```
### 文件说明
#### package.json
用于指定插件最基础的配置,一个最基础的配置信息如下:
```json
{
"name": "rubick-system-plugin-demo",
"pluginName": "rubick 系统插件demo",
"version": "0.0.0",
"description": "rubick 系统插件demo",
"entry": "index.js",
"logo": "https://xxxx/upload/202112/08/5bac90649c5343cabb63930b131cf8e6.png",
"pluginType": "system",
"author": "muwoo",
"homepage": ""
}
```
核心字段说明:
* name 插件 `npm` 包名称,<Badge type="tip" text="必填" />
* pluginName 插件显示名称,用于展示给使用者 <Badge type="tip" text="必填" />
* description 插件描述,描述这个插件的作用 <Badge type="tip" text="必填" />
* author 插件作者
* entry 入口文件,一般为 `index.js`
* logo 尺寸建议 200 * 200, 插件的 logo, 需要是 http/https 在线地址不支持本地logo <Badge type="tip" text="必填" />
* version 插件的版本 <Badge type="tip" text="必填" />
* homePage: 插件 readme raw 地址
* pluginType: 插件类型枚举ui, system. 当前选 system <Badge type="tip" text="必填" />
#### index.js
插件的入口文件,用于 rubick 主进程进行加载执行:
```js
module.exports = () => {
return {
onReady(ctx) {
const { Notification } = ctx;
new Notification({
title: "测试系统插件",
body: "这是一个系统插件在rubick运行时立即被加载"
}).show()
}
}
}
```
`index.js` 需要返回一个包含 `onReady` 生命周期的函数,该函数接受 `ctx` 对象作为参数,我们可以通过 `ctx` 使用 `electron` 主进程所有能力。
同时也为 `ctx` 上扩展挂在了 `mainWindow` 对象。
#### 调试插件
由于 `rubick` 插件是基于 `npm` 的管理方式,所以开发者调试插件,也是基于 `npm` 的软连接的方式进行调试。
首先需要再插件 `package.json` 目录下执行:
```shell
$ npm link
```
然后将插件通过插件市场的 `开发者` 菜单进行安装,填写插件的 `name` 即可。由于插件依赖于主进程启动执行,所以安装完成后需要重启 rubick 后才能生效。
![](https://pic3.zhimg.com/80/v2-e218500a0686a8735d80f417aa53b7aa_720w.gif)
::: danger
系统插件目前无法直接通过 `devtools` 进行调试,后面会进行优化
:::
## 发布插件
这里介绍完了如何开发插件,最后非常欢迎为 `rubick` 贡献开源插件,发布插件也非常简单,首先需要把自己的插件发布到 `npm` 仓库:
```shell
$ npm publish
```
然后再给 [rubick-database/plugins/total-plugins.json](https://gitcode.net/rubickcenter/rubick-database/-/blob/master/plugins/total-plugins.json) 仓库提个 `pull request`, 把你的 `package.json` 信息加入 `json` 文件内,等我们 merge 了您的提交,插件将会自动上架。

View File

@@ -1,74 +0,0 @@
## 赞助
`rubick` 是非盈利项目,开源不容易,如果该项目对你有用的话,可以打赏我们喝杯 coffee ☕️.
<img width=200 src=https://pic1.zhimg.com/80/v2-688385687a37e962fe32daf136139feb_720w.png />
<img width=200 src=https://pica.zhimg.com/80/v2-1ba296fd2cece45ee1094ee7c259035c_720w.png />
## 前言
rubick 之前的插件管理,依托于云服务器存储,我们需要为服务器存储支付一笔不小的开销。
由于项目完全开源,所以几乎无任何收入,所以为了让 rubick 先生存下去,我们再三抉择把插件包管理方式托管到了`npm` 上。
由于 rubick 的插件管理体系是基于 npm 的包管理体系,所以当您需要使用插件的时候,需要手动保证当前电脑已经安装好了`node`环境。
如果当前电脑已经安装过 `node`,那么您可以直接下载 `rubick` 进行使用啦!
[macos 下安装 nodejs 方法](https://juejin.cn/post/6844903886541553672)
[windows 下安装 nodejs 方法](https://juejin.cn/post/6892790243687137287)
## 下载 rubick
[rubick 下载安装地址](https://github.com/rubickCenter/rubick/releases)
macos 选择 `pkg` 文件windows 选择 `exe` 文件Debian/Ubuntu选择`deb`
安装完成后打开 rubick 即可看到主搜索界面:
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/26f0fbe2c69246b6a3ed139b0df1ca0b~tplv-k3u1fbpfcp-watermark.image)
## 功能说明
接下来详细介绍 rubick 所包含和支持的功能
### 1. 搜索系统应用
支持拼音和缩写来搜索系统安装应用:
![](https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ba363e8f60f540e6a5c365c4317c4413~tplv-k3u1fbpfcp-watermark.image)
### 2. UI类插件安装
点击搜索框右侧 `rubick` 图标,进入插件市场,选择所需插件,点击下载按钮即可下载,下载完成后在已安装 tab 下可以找到安装插件。
安装完成后,输入插件呼起命令即可使用对应插件:
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7ae45c7ede1f4e3bb7d35ae845e60b64~tplv-k3u1fbpfcp-watermark.image)
### 3. 系统类插件安装
系统插件安装方式和UI类一样在插件市场选择`系统分类`,寻找适合自己的系统插件安装即可。
::: danger
系统插件安装成功后,需要重启 `rubick` 才能生效
:::
### 4. 输入框聚焦自动根据剪切板内容匹配插件
`rubick` 内搜索`偏好设置`,然后开启`自动粘贴` 功能,即可匹配剪切板内容自动匹配适合插件进行使用。
![](https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/01ef50fbfa064ba9a88bebe1531eacd4~tplv-k3u1fbpfcp-watermark.image)
### 内网部署
::: tip
如果把插件发布到公网 `npm` 如果不符合您的公司安全要求,`rubick` 支持内网私有源和私有插件库,如果您需要内网部署使用,可以自行配置以下规则。
:::
`rubick` 依赖 `npm` 仓库做插件管理,依赖 `gitcode` 做插件数据存储所以如果要进行内网部署主要需要替换这2个设置。详细设置
`插件市场 -> 设置 -> 内网部署设置`
![image.png](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1319b177fb544017ae10b4a703e8efa6~tplv-k3u1fbpfcp-watermark.image?)
#### 1. 替换 npm 源
插件发布到私有 `npm` 源即可。
#### 2. 替换 `gitcode` 源为内网 `gitlab`: database url
* clone 下载 rubick 插件库:[https://gitcode.net/rubickcenter/rubick-database](https://gitcode.net/rubickcenter/rubick-database)
* 提交仓库到私有 `gitlab` 库。
替换格式:`https://gitlab.xxx.com/api/v4/projects/{projectId}/repository/files/` 。因为接口为 `gitlab openAPI`,所以需要填写仓库 `access_token`
### 更多功能
如果您还需要更多功能,欢迎来这里给我们提建议:[issues](https://github.com/rubickCenter/rubick/issues) 。
有价值的想法我们会加入到后期的开发当中。同时也欢迎一起加入共建。

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

View File

@@ -1,103 +0,0 @@
## 赞助
`rubick` 是非盈利项目,开源不容易,如果该项目对你有用的话,可以打赏我们喝杯 coffee ☕️.
<img width=200 src=https://pic1.zhimg.com/80/v2-688385687a37e962fe32daf136139feb_720w.png />
<img width=200 src=https://pica.zhimg.com/80/v2-1ba296fd2cece45ee1094ee7c259035c_720w.png />
## 贡献代码
### rubick 目录介绍
```shell
.
├── docs # 文档存方目录
│   ├── docs
│   ├── package-lock.json
│   ├── package.json
│   └── pnpm-lock.yaml
├── feature # 插件市场插件
│   ├── README.md
│   ├── babel.config.js
│   ├── package-lock.json
│   ├── package.json
│   ├── public
│   ├── src
│   ├── tsconfig.json
│   └── vue.config.js
├── public # rubick __static 目录
│   ├── favicon.ico
│   ├── feature
│   ├── icons
│   ├── index.html
│   ├── preload.js
│   └── tpl
├── src # rubick 核心源码
│   ├── common # 一些通用的函数
│   ├── core # 一些核心的能力,比如 app search
│   ├── main # 主进程
│   └── renderer # 渲染进程
├── tpl # rubick 模板插件
│   ├── README.md
│   ├── babel.config.js
│   ├── package-lock.json
│   ├── package.json
│   ├── public
│   ├── src
│   ├── tsconfig.json
│   └── vue.config.js
├── LICENSE # MIT 协议
├── README.md # 英文文档
├── README.zh-CN.md # 中文文档
├── babel.config.js
├── deploy-doc.sh # rubick doc 发布脚本
├── tsconfig.json
├── package-lock.json
├── package.json
└── vue.config.js
```
### 启动
#### 1. 安装依赖
`rubick` 启动主要涉及到3个目录
1. 根目录:`rubick` 核心进程
2. feature`rubick` 内置的插件市场插件
3. tpl: `rubick` 内置的模板插件
```shell
$ npm i
$ cd feature && npm i
$ cd tpl && npm i
```
#### 2. 启动核心进程
```shell
$ npm run electron:serve
```
#### 3. 启动插件中心 <Badge type="warning" text="非必须" vertical="top" />
```shell
$ cd feature && npm run serve
```
#### 4. 启动模板插件 <Badge type="warning" text="非必须" vertical="top" />
```shell
$ cd tpl && npm run serve
```
### 编译
```shell
$ cd feature && npm run build
$ cd tpl && npm run build
$ npm run electron:build
```
### PR
1. Create an issue about the features, such as new components.
2. Fork the repo to your own account.
3. Clone your fork.
4. Create a new branch base on dev, if you want to add new component, the branch name should be formatted as component-[Component Name]. (e.g. component-steps) And the commit info should be formatted as [Component Name]: Info about commit.
5. Make sure that running npm run prepublish outputs the correct files.
6. Rebase before creating a PR to keep commit history clear. (Merge request to branch dev)
7. Provide some description about your PR.

View File

@@ -1,19 +0,0 @@
# 特殊服务
## 说明
`rubick` 一直坚持开源免费,现在不会变,以后也不会变。但是纯开源 `MIT` 模式下,是一种 0 收入用爱发电的,完全依靠
作者自己的爱好和激情。但这种用爱发电的模式很难持续维持,为了更好的持续迭代和发展壮大 `rubick`, 我们需要一定的现金持续激励 `rubick` 的核心开发者们,让更多的人成为 `rubick`
的核心开发者。所以 `rubick` 开启了一个新的模式尝试,那是服务付费:`rubick` 用户可以购买我们提供技术支持、答疑解惑、定制化插件开发、二次定制化开发 `rubick` 等等官方服务...
## 可以提供哪些服务?
我们收集了大量用户的问题,目前约定可以支持到的服务有:
1. 二次定制化开发 `rubick`
2. 轻量级插件开发
3. `rubick` 实现原理手把手介绍
4. `rubick` 使用答疑
5. `rubick` 内网部署一条龙服务
6. 前端圈各种技术支持(作者分别是前蚂蚁集团和字节跳动的前端技术专家)
7. 未来能提供的一切...
## 如何加入特殊服务?
扫描下方的二维码,加入知识星球即可:
<img width=400 src=https://picx.zhimg.com/80/v2-6deabf65175d18080439ef813102d18c_720w.png />

View File

@@ -1,15 +0,0 @@
{
"name": "rubick-docs",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"docs:dev": "vuepress dev docs",
"docs:build": "vuepress build docs"
},
"author": "muwoo",
"license": "ISC",
"devDependencies": {
"vuepress": "^1.8.2"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,3 +1,22 @@
module.exports = {
presets: ["@vue/cli-plugin-babel/preset"],
presets: ['@vue/cli-plugin-babel/preset'],
plugins: [
[
'import',
{
libraryName: 'ant-design-vue',
style: 'css', // or 'css'
},
'ant-design-vue',
],
[
'import',
{
libraryName: '@ant-design/icons-vue',
libraryDirectory: 'lib/icons',
camel2DashComponentName: false,
},
'@ant-design/icons-vue',
],
],
};

13020
feature/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -12,15 +12,19 @@
"@vue/cli-service": "~4.5.0",
"ant-design-vue": "3.2.14",
"axios": "^0.24.0",
"babel-plugin-import": "^1.13.8",
"core-js": "^3.6.5",
"lodash.debounce": "^4.0.8",
"lodash.throttle": "^4.1.1",
"markdown-it": "^12.2.0",
"nanoid": "^4.0.2",
"vue": "3.2.45",
"vue-i18n": "^9.2.2",
"vue-i18n": "9.2.2",
"vue-router": "^4.0.0-0",
"vuex": "^4.0.0-0"
"vue3-carousel": "^0.3.1",
"vue3-lottie": "^3.1.0",
"vuex": "^4.0.0-0",
"webpack-bundle-analyzer": "^4.9.1"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^4.18.0",

View File

@@ -3,13 +3,13 @@
"pluginName": "系统菜单",
"description": "系统菜单",
"main": "index.html",
"logo": "https://pic1.zhimg.com/80/v2-c09780808301668a82e6646cb42f0806_720w.png",
"logo": "https://pic1.zhimg.com/80/v2-29152fe716010751db835adf591421f8_720w.png",
"version": "0.0.0",
"preload":"preload.js",
"pluginType": "ui",
"features": [
{
"code": "market",
"code": "finder",
"explain": "插件市场",
"cmds":[
"插件市场"
@@ -18,7 +18,7 @@
"code": "installed",
"explain": "已安装插件",
"cmds":[
"已安装插件"
"已安装插件", "installed"
]
},{
"code": "settings",

View File

@@ -1,91 +1,256 @@
<template>
<div class="main-container">
<div class="slider-bar">
<div class="left-menu">
<a-menu
v-model:selectedKeys="active"
mode="horizontal"
@select="({ key }) => changeMenu(key)"
:selectedKeys="active"
mode="vertical"
>
<a-menu-item key="market">
<a-menu-item key="finder">
<template #icon>
<AppstoreOutlined />
<StarOutlined style="font-size: 16px" />
</template>
{{ $t('feature.market.title') }}
{{ $t('feature.market.explore') }}
</a-menu-item>
<a-menu-item key="installed">
<a-menu-item key="worker">
<template #icon>
<HeartOutlined />
<SendOutlined style="transform: rotate(-45deg); font-size: 16px" />
</template>
{{ $t('feature.installed.title') }}
{{ $t('feature.market.efficiency') }}
</a-menu-item>
<a-menu-item key="settings">
<a-menu-item key="tools">
<template #icon>
<SettingOutlined />
<SearchOutlined style="font-size: 16px" />
</template>
{{ $t('feature.settings.title') }}
{{ $t('feature.market.searchTool') }}
</a-menu-item>
<a-menu-item key="dev">
<a-menu-item key="image">
<template #icon>
<BugOutlined />
<FileImageOutlined style="font-size: 16px" />
</template>
{{ $t('feature.dev.title') }}
{{ $t('feature.market.imageTool') }}
</a-menu-item>
<a-menu-item key="devPlugin">
<template #icon>
<CodeOutlined style="font-size: 16px" />
</template>
{{ $t('feature.market.developTool') }}
</a-menu-item>
<a-menu-item key="system">
<template #icon>
<DatabaseOutlined style="font-size: 16px" />
</template>
{{ $t('feature.market.systemTool') }}
</a-menu-item>
<a-sub-menu class="user-info">
<template #icon>
<a-avatar :size="32">
<template #icon>
<img :src="perf.custom.logo" />
</template>
</a-avatar>
</template>
<template #title>{{ perf.custom.username }}</template>
<a-menu-item key="settings">
<template #icon>
<SettingOutlined />
</template>
{{ $t('feature.settings.title') }}
</a-menu-item>
<a-menu-item key="installed">
<template #icon>
<HeartOutlined />
</template>
{{ $t('feature.installed.title') }}
</a-menu-item>
<a-menu-item key="dev">
<template #icon>
<BugOutlined />
</template>
{{ $t('feature.dev.title') }}
</a-menu-item>
</a-sub-menu>
</a-menu>
</div>
<router-view />
<div
:class="
[
'finder',
'result',
'devPlugin',
'image',
'tools',
'worker',
'system',
].includes(active[0])
? 'container'
: 'more'
"
>
<keep-alive>
<router-view />
</keep-alive>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { computed } from 'vue';
import { useRouter } from 'vue-router';
import {
HeartOutlined,
AppstoreOutlined,
StarOutlined,
SendOutlined,
SearchOutlined,
FileImageOutlined,
DatabaseOutlined,
CodeOutlined,
SettingOutlined,
HeartOutlined,
BugOutlined,
} from '@ant-design/icons-vue';
import { useStore } from 'vuex';
import localConfig from '@/confOp';
const store = useStore();
const router = useRouter();
const active = ref(['market']);
const active = computed(() => store.state.active);
const { perf } = localConfig.getConfig();
const changeMenu = (key: any) => {
store.commit('commonUpdate', { active: [key] });
router.push(key);
};
window.rubick.onPluginEnter(({ code }: { code: string }) => {
code = code === '已安装插件' ? 'installed' : code;
changeMenu(code);
active.value = [code];
store.commit('commonUpdate', { active: [code] });
});
const store = useStore();
window.rubick.setSubInput((e: any) => {
if (
[
'finder',
'result',
'devPlugin',
'image',
'tools',
'worker',
'system',
].includes(active.value[0])
) {
if (e.text) {
store.commit('setSearchValue', e.text);
router.push('result');
} else {
store.commit('commonUpdate', { active: ['finder'] });
router.push('finder');
}
}
}, '搜索插件');
const init = () => store.dispatch('init');
init();
</script>
<style lang="less" scoped>
* {
margin: 0;
padding: 0;
}
.main-container {
-webkit-app-region: no-drag;
display: flex;
align-items: flex-start;
background: var(--color-body-bg);
flex-direction: column;
.slider-bar {
width: 100%;
.ant-menu {
background: var(--color-body-bg);
border-color: var(--color-border-light);
:deep(.ant-menu-item) {
&:not(.ant-menu-item-selected) {
color: var(--color-text-primary);
}
<style lang="less">
.ant-menu-submenu-popup {
.ant-menu {
background: var(--color-body-bg2) !important;
height: 100%;
border-right: none;
.ant-menu-item,
.ant-menu-submenu,
.ant-menu-submenu-arrow {
color: var(--color-text-content);
&:active {
background: none;
}
}
.ant-menu-item-selected,
.ant-menu-submenu-selected {
background-color: var(--color-list-hover);
color: var(--ant-primary-color);
.ant-menu-submenu-arrow {
color: var(--ant-primary-color);
}
&:after {
display: none;
}
}
}
}
</style>
<style lang="less" scoped>
@import '~@/assets/common.less';
* {
margin: 0;
padding: 0;
}
.main-container {
-webkit-app-region: no-drag;
display: flex;
background: var(--color-body-bg);
border-top: 1px solid var(--color-border-light);
height: 100vh;
box-sizing: border-box;
align-items: flex-start;
width: 100%;
overflow: hidden;
background: var(--color-menu-bg);
.search {
:deep(.ant-btn),
:deep(.ant-input),
:deep(.ant-input-group-addon) {
color: var(--ant-primary-color) !important;
background: var(--color-input-hover);
border-color: var(--color-border-light);
}
}
.container,
.more {
background: var(--color-body-bg);
width: calc(~'100% - 183px');
height: 100%;
box-sizing: border-box;
padding: 16px;
position: relative;
overflow: auto;
}
.more {
background: var(--color-body-bg2);
}
.left-menu {
padding: 16px;
position: relative;
height: 100vh;
:deep(.ant-menu) {
width: 100%;
}
:deep(.ant-menu-item) {
padding-left: 12px !important;
display: flex;
align-items: center;
}
:deep(.ant-menu-item-selected),
:deep(.ant-menu-submenu-selected) {
background-color: var(--color-list-hover);
border-radius: 6px;
color: var(--ant-primary-color);
}
:deep(.user-info) {
position: absolute;
bottom: 16px;
width: calc(100% - 32px);
.ant-menu-submenu-title {
padding: 0 32px 0 8px;
.ant-menu-title-content {
margin-left: 8px;
}
}
}
:deep(.ant-avatar) {
background: transparent;
}
}
}
</style>

View File

@@ -1,19 +1,17 @@
@import "~ant-design-vue/dist/antd.less"; // 引入官方提供的 less 样式入口文件
@primary-color: #ff4ea4; // 全局主色
@error-color: #ff4ea4; // 错误色
:root {
--color-text-primary: rgba(0, 0, 0, 0.85);
--color-text-content: #141414;
--color-text-desc: rgba(0, 0, 0, 0.45);
// 背景色
--color-body-bg2: #eee;
--color-body-bg: #fff;
--color-menu-bg: #f3efef;
--color-list-hover: #e2e2e2;
--color-menu-bg: rgba(248, 248, 248, 1);
--color-list-hover: rgba(233, 233, 233, 1);
--color-input-hover: #fff;
// 边框
--color-border-light: #f0f0f0;
// 输入框附带icon
--color-action-color: rgba(0, 0, 0, 0.25);;
}
.dark {
@@ -22,9 +20,12 @@
--color-text-desc: #8f8fa6;
// 背景色
--color-body-bg: #1c1c28;
--color-body-bg2: #2c2f3b;
--color-menu-bg: #1c1c28;
--color-list-hover: #33333d;
--color-input-hover: #33333d;
--color-list-hover: #2c2f3b;
--color-input-hover: #444d;
// 边框
--color-border-light: #33333d;
--color-border-light: #444d;
// 输入框附带icon
--color-action-color: #ffffff4d;
}

View File

@@ -1,5 +1,5 @@
.left-menu {
width: 200px;
width: 183px;
// height: 100vh;
border-right: 1px solid var(--color-border-light);
.search-container {
@@ -20,15 +20,18 @@
background: var(--color-menu-bg);
height: 100%;
border-right: none;
.ant-menu-item {
.ant-menu-item, .ant-menu-submenu, .ant-menu-submenu-arrow {
color: var(--color-text-content);
&:active {
background: none;
}
}
.ant-menu-item-selected {
.ant-menu-item-selected, .ant-menu-submenu-selected {
background-color: var(--color-list-hover);
color: var(--color-text-primary);
color: var(--ant-primary-color);
.ant-menu-submenu-arrow {
color: var(--ant-primary-color);
}
&:after {
display: none;
}

View File

@@ -0,0 +1,35 @@
export const SPRING = {
theme: 'SPRING',
primaryColor: '#ff4ea4',
errorColor: '#ed6d46',
warningColor: '#e5a84b',
successColor: '#c0d695',
infoColor: '#aa8eeB',
};
export const SUMMER = {
theme: 'SUMMER',
primaryColor: '#6078ea',
errorColor: '#ed6d46',
warningColor: '#e5a84b',
successColor: '#c0d695',
infoColor: '#aa8eeB',
};
export const AUTUMN = {
theme: 'AUTUMN',
primaryColor: '#f55555',
errorColor: '#ed6d46',
warningColor: '#e5a84b',
successColor: '#c0d695',
infoColor: '#aa8eeB',
};
export const WINTER = {
theme: 'WINTER',
primaryColor: '#00b294',
errorColor: '#e94829',
warningColor: '#ed6d3d',
successColor: '#c3d94e',
infoColor: '#bfa782',
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 845 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 17 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
import axios from 'axios';
let baseURL = 'https://gitcode.net/rubickcenter/rubick-database/-/raw/master';
let baseURL = 'https://gitee.com/monkeyWang/rubickdatabase/raw/master';
let access_token = '';
try {
@@ -12,8 +12,9 @@ try {
}
const instance = axios.create({
timeout: 4000,
baseURL:
baseURL || 'https://gitcode.net/rubickcenter/rubick-database/-/raw/master',
baseURL || 'https://gitee.com/monkeyWang/rubickdatabase/raw/master',
});
export default {
@@ -22,9 +23,10 @@ export default {
if (access_token) {
targetPath = `${encodeURIComponent(
targetPath
)}/raw?access_token=${access_token}&ref=master`;
)}?access_token=${access_token}&ref=master`;
}
const res = await instance.get(targetPath);
console.log('total plugsin', res);
return res.data;
},
@@ -33,7 +35,7 @@ export default {
if (access_token) {
targetPath = `${encodeURIComponent(
targetPath
)}/raw?access_token=${access_token}&ref=master`;
)}?access_token=${access_token}&ref=master`;
}
const res = await instance.get(targetPath);
return res.data;
@@ -44,7 +46,7 @@ export default {
if (access_token) {
targetPath = `${encodeURIComponent(
targetPath
)}/raw?access_token=${access_token}&ref=master`;
)}?access_token=${access_token}&ref=master`;
}
const res = await instance.get(targetPath);
return res.data;
@@ -54,14 +56,14 @@ export default {
if (access_token) {
targetPath = `${encodeURIComponent(
targetPath
)}/raw?access_token=${access_token}&ref=master`;
)}?access_token=${access_token}&ref=master`;
}
const res = await instance.get(targetPath);
return res.data;
},
async getPluginDetail(url: string) {
const res = await axios.get(url);
const res = await instance.get(url);
return res.data;
},
@@ -70,7 +72,7 @@ export default {
if (access_token) {
targetPath = `${encodeURIComponent(
targetPath
)}/raw?access_token=${access_token}&ref=master`;
)}?access_token=${access_token}&ref=master`;
}
const res = await instance.get(targetPath);
return res.data;
@@ -80,7 +82,7 @@ export default {
if (access_token) {
targetPath = `${encodeURIComponent(
targetPath
)}/raw?access_token=${access_token}&ref=master`;
)}?access_token=${access_token}&ref=master`;
}
const res = await instance.get(targetPath);
return res.data;
@@ -90,7 +92,7 @@ export default {
if (access_token) {
targetPath = `${encodeURIComponent(
targetPath
)}/raw?access_token=${access_token}&ref=master`;
)}?access_token=${access_token}&ref=master`;
}
const res = await instance.get(targetPath);
return res.data;

View File

@@ -12,8 +12,9 @@ export default {
developTool: 'Develop Tools',
systemTool: 'System Tools',
finder: {
must: 'Necessary',
recommended: 'Recommended',
lastUpdated: 'Last Updated',
lastUpdated: 'Total',
},
install: 'Install',
},
@@ -37,17 +38,17 @@ export default {
tips1: 'rubick',
tips2:
'After the software preferences are set, please restart the software. Please go to the mini program set avatar and nickname.',
themeColor: 'Theme Color',
primaryColor: 'Primary Color',
errorColor: 'Error Color',
warningColor: 'Warning Color',
successColor: 'Success Color',
infoColor: 'Info Color',
themeColor: 'Theme Setting',
spring: 'Spring',
summer: 'Summer',
autumn: 'Autumn',
winter: 'Winter',
personalized: 'Personalized',
greeting: 'Search Box Greeting',
logo: 'Logo',
logo: 'Avatar',
replace: 'Repalce Logo',
reset: 'Reset Default',
name: 'User Name',
},
basic: {
title: 'Basic',
@@ -66,6 +67,7 @@ export default {
changeLang: 'Change Language',
cn: '简体中文',
en: 'English',
history: 'keywords search history',
},
global: {
title: 'Global Shortcut Key',

View File

@@ -12,8 +12,9 @@ export default {
developTool: '开发者',
systemTool: '系统',
finder: {
must: '必备',
recommended: '推荐',
lastUpdated: '最近更新',
lastUpdated: '全部',
},
install: '安装',
},
@@ -35,17 +36,17 @@ export default {
accountInfo: '账户信息',
tips1: 'rubick 用户',
tips2: '软件偏好设置完成后需重启软件,头像和昵称请前往小程序设置',
themeColor: '主题设置',
primaryColor: '主色调',
errorColor: '错误色',
warningColor: '警告色',
successColor: '成功色',
infoColor: '提醒色',
personalized: '用户个性化设置',
greeting: '主搜索框欢迎语',
logo: '界面 logo',
replace: '点我替换',
themeColor: '主题设置',
spring: '立春',
summer: '立夏',
autumn: '立秋',
winter: '立冬',
personalized: '用户设置',
greeting: '搜索框欢迎语',
logo: '头像',
replace: '替换',
reset: '恢复默认设置',
name: '用户名',
},
basic: {
title: '基本设置',
@@ -64,6 +65,7 @@ export default {
changeLang: '切换语言',
cn: '简体中文',
en: 'English',
history: '关键词搜索记录',
},
global: {
title: '全局快捷键',

View File

@@ -1,5 +1,28 @@
import { createApp } from 'vue';
import Antd, { ConfigProvider } from 'ant-design-vue';
import Vue3Lottie from 'vue3-lottie';
import {
ConfigProvider,
Button,
Divider,
Row,
Col,
Dropdown,
Menu,
Form,
Input,
Radio,
Select,
Switch,
Avatar,
Collapse,
List,
Tooltip,
Alert,
Drawer,
Modal,
Result,
Spin,
} from 'ant-design-vue';
import App from './App.vue';
import router from './router';
import store from './store';
@@ -10,8 +33,46 @@ import localConfig from './confOp';
const config: any = localConfig.getConfig();
// 暗夜模式
if (config.perf.common.darkMode) {
document.body.classList.add('dark');
window.rubick.theme = 'dark';
}
ConfigProvider.config({
theme: config.perf.custom || {},
});
createApp(App).use(registerI18n).use(store).use(Antd).use(router).mount('#app');
window.rubick.changeTheme = () => {
const config: any = localConfig.getConfig();
ConfigProvider.config({
theme: config.perf.custom || {},
});
};
createApp(App)
.use(registerI18n)
.use(store)
.use(Button)
.use(Divider)
.use(Row)
.use(Col)
.use(Dropdown)
.use(Menu)
.use(Form)
.use(Input)
.use(Radio)
.use(Select)
.use(Switch)
.use(Avatar)
.use(Collapse)
.use(List)
.use(Tooltip)
.use(Alert)
.use(Drawer)
.use(Modal)
.use(Result)
.use(Spin)
.use(router)
.use(Vue3Lottie)
.mount('#app');

View File

@@ -1,40 +1,65 @@
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/user.vue';
import Dev from '../views/dev/index.vue';
const routes: Array<RouteRecordRaw> = [
{
path: '/market',
name: 'market',
component: Market,
path: '/result',
name: 'result',
component: () => import('../views/market/components/result.vue'),
},
{
path: '/devPlugin',
name: 'devPlugin',
component: () => import('../views/market/components/devlopment.vue'),
},
{
path: '/image',
name: 'image',
component: () => import('../views/market/components/image.vue'),
},
{
path: '/tools',
name: 'tools',
component: () => import('../views/market/components/tools.vue'),
},
{
path: '/worker',
name: 'worker',
component: () => import('../views/market/components/worker.vue'),
},
{
path: '/system',
name: 'system',
component: () => import('../views/market/components/system.vue'),
},
{
path: '/finder',
name: 'finder',
component: () => import('../views/market/components/finder.vue'),
},
{
path: '/installed',
name: 'installed',
component: Installed,
component: () => import('../views/installed/index.vue'),
},
{
path: '/account',
name: 'account',
component: Account,
component: () => import('../views/account/index.vue'),
},
{
path: '/settings',
name: 'settings',
component: Settings,
component: () => import('../views/settings/user.vue'),
},
{
path: '/dev',
name: 'dev',
component: Dev,
component: () => import('../views/dev/index.vue'),
},
{
path: '/:catchAll(.*)',
name: 'market',
component: Market,
name: 'finder',
component: () => import('../views/market/components/finder.vue'),
},
];

View File

@@ -17,6 +17,7 @@ export default createStore({
totalPlugins: [],
localPlugins: [],
searchValue: '',
active: ['finder'],
},
mutations: {
commonUpdate(state: any, payload) {

View File

@@ -1,30 +1,33 @@
<template>
<div class="dev">
<a-alert
style="margin-bottom: 40px"
:message="$t('feature.dev.tips')"
type="warning"
/>
<a-form
ref="formRef"
:model="formState"
:rules="rules"
:label-col="labelCol"
:wrapper-col="wrapperCol"
>
<a-form-item :label="$t('feature.dev.pluginName')" name="name">
<a-input v-model:value="formState.name" />
</a-form-item>
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
<a-button :loading="loading" type="primary" @click="onSubmit">
{{ $t('feature.dev.install') }}
</a-button>
<a-button @click="refresh" style="margin-left: 10px">
{{ $t('feature.dev.refreshPlugins') }}
</a-button>
</a-form-item>
</a-form>
<div class="view-title">{{ $t('feature.dev.title') }}</div>
<div class="view-container">
<a-alert
style="margin-bottom: 40px"
:message="$t('feature.dev.tips')"
type="warning"
/>
<a-form
ref="formRef"
:model="formState"
:rules="rules"
:label-col="labelCol"
:wrapper-col="wrapperCol"
>
<a-form-item :label="$t('feature.dev.pluginName')" name="name">
<a-input v-model:value="formState.name" />
</a-form-item>
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
<a-button :loading="loading" type="primary" @click="onSubmit">
{{ $t('feature.dev.install') }}
</a-button>
<a-button @click="refresh" style="margin-left: 10px">
{{ $t('feature.dev.refreshPlugins') }}
</a-button>
</a-form-item>
</a-form>
</div>
</div>
</template>
@@ -81,14 +84,26 @@ const wrapperCol = { span: 14 };
box-sizing: border-box;
width: 100%;
overflow-x: hidden;
background: var(--color-body-bg);
height: calc(~'100vh - 46px');
padding: 20px;
height: calc(~'100vh - 34px');
.view-title {
font-size: 16px;
font-weight: 500;
margin-bottom: 16px;
color: var(--color-text-primary);
}
.view-container {
padding: 10px;
box-sizing: border-box;
border-radius: 8px;
background: var(--color-body-bg);
overflow: auto;
height: calc(~'100vh - 84px');
}
:deep(label) {
color: var(--color-text-content);
}
:deep(.ant-input) {
background: var(--color-input-hover);
background: var(--color-input-hover) !important;
color: var(--color-text-content);
}
}

View File

@@ -1,111 +1,106 @@
<template>
<div class="installed">
<div v-if="!localPlugins.length">
<a-result
status="404"
:title="$t('feature.installed.tips1')"
:sub-title="$t('feature.installed.tips2')"
/>
</div>
<div class="container" v-else>
<div class="installed-list">
<div
:class="currentSelect[0] === index ? 'item active' : 'item'"
:key="index"
@click="currentSelect = [index]"
v-for="(plugin, index) in localPlugins"
<div class="view-title">{{ $t('feature.installed.title') }}</div>
<div class="view-container">
<div v-if="!localPlugins.length">
<a-result
class="error-content"
sub-title="哎呀暂时还没有安装任何插件"
>
<img :src="plugin.logo" />
<div class="info">
<div class="title">
{{ plugin.pluginName }}
<span class="desc">v{{ plugin.version }}</span>
</div>
<div class="desc">{{ plugin.description }}</div>
</div>
</div>
<template #icon>
<Vue3Lottie :animationData="emptyJson" :height="240" :width="240" />
</template>
<template #extra>
<a-button @click="gotoFinder" key="console" type="primary">去插件市场看看吧</a-button>
</template>
</a-result>
</div>
<div class="plugin-detail">
<div class="plugin-top">
<div class="left">
<div class="title">
{{ pluginDetail.pluginName }}
<a-tag>{{ pluginDetail.version }}</a-tag>
<div class="container" v-else>
<div class="installed-list">
<div
:class="currentSelect[0] === plugin.name ? 'item active' : 'item'"
:key="index"
@click="currentSelect = [plugin.name]"
v-for="(plugin, index) in localPlugins"
>
<img :src="plugin.logo" />
<div class="info">
<div class="title">
{{ plugin.pluginName }}
</div>
<div class="desc">{{ plugin.description }}</div>
</div>
<div class="desc">
{{ $t('feature.installed.developer') }}{{
`${pluginDetail.author || $t('feature.installed.unknown')}`
}}
</div>
<div class="desc">
{{ pluginDetail.description }}
</div>
</div>
<div class="right">
<a-button
type="danger"
size="small"
shape="round"
:loading="pluginDetail.isloading"
@click="deletePlugin(pluginDetail)"
>
{{ $t('feature.installed.remove') }}
</a-button>
</div>
</div>
<a-tabs default-active-key="1">
<a-tab-pane key="1" :tab="$t('feature.installed.functionKey')">
<div class="feature-container">
<div
class="desc-item"
:key="index"
v-for="(item, index) in pluginDetail.features"
>
<div>{{ item.explain }}</div>
<a-tag
:key="cmd"
v-for="cmd in item.cmds"
:class="{ executable: !cmd.label }"
>
<span
@click="
!cmd.label &&
openPlugin({
code: item.code,
cmd,
})
"
>
{{ cmd.label || cmd }}
</span>
<template v-if="!cmd.label" #icon>
<a-tooltip
v-if="!hasAdded(cmd)"
placement="topLeft"
:title="$t('feature.installed.addToPanel')"
>
<PlusCircleOutlined
@click="addCmdToSuperPanel({ code: item.code, cmd })"
/>
</a-tooltip>
<a-tooltip
v-else
placement="topLeft"
:title="$t('feature.installed.removeFromPanel')"
>
<MinusCircleOutlined
@click="removePluginToSuperPanel({ cmd })"
/>
</a-tooltip>
</template>
</a-tag>
<div class="plugin-detail">
<div class="plugin-top">
<div class="left">
<div class="title">
{{ pluginDetail.pluginName }}
<a-tag>{{ pluginDetail.version }}</a-tag>
</div>
<div class="desc">
{{ $t('feature.installed.developer') }}{{
`${pluginDetail.author || $t('feature.installed.unknown')}`
}}
</div>
<div class="desc">
{{ pluginDetail.description }}
</div>
</div>
</a-tab-pane>
<a-tab-pane key="2" :tab="$t('feature.installed.detailInfo')">
<div class="detail-container" v-html="readme"></div>
</a-tab-pane>
</a-tabs>
<div class="right">
<a-button
type="primary"
size="small"
shape="round"
:loading="pluginDetail.isloading"
@click="deletePlugin(pluginDetail)"
>
{{ $t('feature.installed.remove') }}
</a-button>
</div>
</div>
<div class="feature-container">
<template
:key="index"
v-for="(item, index) in pluginDetail.features"
>
<div
class="desc-item"
v-if="item.cmds.filter(cmd => !cmd.label).length > 0"
>
<div>{{ item.explain }}</div>
<template :key="cmd" v-for="cmd in item.cmds">
<a-dropdown
v-if="!cmd.label"
:class="{ executable: !cmd.label }"
>
<template #overlay>
<a-menu @click="({key}) => handleMenuClick(key, item, cmd)">
<a-menu-item key="open">
<CaretRightOutlined />
运行
</a-menu-item>
<a-menu-item v-if="!hasAdded(cmd)" key="add">
<PushpinOutlined />
固定到超级面板
</a-menu-item>
<a-menu-item v-else key="remove">
<PushpinFilled />
从超级面板中取消固定
</a-menu-item>
</a-menu>
</template>
<a-button size="small" class="keyword-tag">
{{ cmd.label || cmd }}
<DownOutlined />
</a-button>
</a-dropdown>
</template>
</div>
</template>
</div>
</div>
</div>
</div>
</div>
@@ -113,22 +108,31 @@
<script setup>
import { useStore } from 'vuex';
import { computed, ref, toRaw } from 'vue';
import { computed, ref, toRaw, watch } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import path from 'path';
import MarkdownIt from 'markdown-it';
import { PlusCircleOutlined, MinusCircleOutlined } from '@ant-design/icons-vue';
import {
PushpinOutlined,
PushpinFilled,
CaretRightOutlined,
DownOutlined,
} from '@ant-design/icons-vue';
import { message } from 'ant-design-vue';
import emptyJson from '@/assets/lottie/empty.json';
const { ipcRenderer } = window.require('electron');
const remote = window.require('@electron/remote');
const fs = window.require('fs');
const md = new MarkdownIt();
const appPath = remote.app.getPath('userData');
const baseDir = path.join(appPath, './rubick-plugins');
const store = useStore();
const route = useRoute();
const router = useRouter();
const localPlugins = computed(() =>
store.state.localPlugins.filter(
(plugin) => plugin.name !== 'rubick-system-feature'
@@ -138,10 +142,16 @@ const updateLocalPlugin = () => store.dispatch('updateLocalPlugin');
const startUnDownload = (name) => store.dispatch('startUnDownload', name);
const errorUnDownload = (name) => store.dispatch('errorUnDownload', name);
const currentSelect = ref([0]);
const currentSelect = ref([route.query.plugin || localPlugins?.value[0]?.name]);
watch(localPlugins, () => {
currentSelect.value = [localPlugins?.value[0]?.name];
});
const pluginDetail = computed(() => {
return localPlugins.value[currentSelect.value] || {};
return (
localPlugins.value.find((v) => v.name === currentSelect.value[0]) || {}
);
});
const superPanelPlugins = ref(
@@ -151,6 +161,19 @@ const superPanelPlugins = ref(
}
);
const handleMenuClick = (key, item, cmd) => {
if(key === 'open') {
openPlugin({
code: item.code,
cmd,
});
} else if (key === 'add') {
addCmdToSuperPanel({cmd, code: item.code});
} else {
removePluginToSuperPanel({cmd, name: item.name})
}
};
const addCmdToSuperPanel = ({ cmd, code }) => {
const plugin = {
...toRaw(pluginDetail.value),
@@ -162,7 +185,8 @@ const addCmdToSuperPanel = ({ cmd, code }) => {
},
};
superPanelPlugins.value.data.push(plugin);
window.rubick.db.put(toRaw(superPanelPlugins.value));
const { rev } = window.rubick.db.put(JSON.parse(JSON.stringify(superPanelPlugins.value)));
superPanelPlugins.value._rev = rev;
};
const removePluginToSuperPanel = ({ cmd, name }) => {
@@ -172,7 +196,8 @@ const removePluginToSuperPanel = ({ cmd, name }) => {
return item.cmd !== cmd;
}
);
window.rubick.db.put(toRaw(superPanelPlugins.value));
const { rev } = window.rubick.db.put(toRaw(superPanelPlugins.value));
superPanelPlugins.value._rev = rev;
};
const hasAdded = (cmd) => {
@@ -203,21 +228,6 @@ const openPlugin = ({ cmd, code }) => {
);
};
const readme = computed(() => {
if (!pluginDetail.value.name) return '';
const readmePath = path.resolve(
baseDir,
'node_modules',
pluginDetail.value.name,
'README.md'
);
if (fs.existsSync(readmePath)) {
const str = fs.readFileSync(readmePath, 'utf-8');
return md.render(str);
}
return '';
});
const deletePlugin = async (plugin) => {
startUnDownload(plugin.name);
const timer = setTimeout(() => {
@@ -230,7 +240,10 @@ const deletePlugin = async (plugin) => {
clearTimeout(timer);
};
const gotoFinder = () => {
router.push('/finder');
store.commit('commonUpdate', { active: ['finder'] });
};
</script>
<style lang="less" scoped>
@@ -238,14 +251,29 @@ const deletePlugin = async (plugin) => {
box-sizing: border-box;
width: 100%;
overflow: hidden;
background: var(--color-body-bg);
height: calc(~'100vh - 46px');
height: calc(~'100vh - 34px');
.view-title {
font-size: 16px;
font-weight: 500;
margin-bottom: 16px;
color: var(--color-text-primary);
}
.view-container {
border-radius: 8px;
background: var(--color-body-bg);
overflow: auto;
height: calc(~'100vh - 84px');
}
:deep(.ant-result-title) {
color: var(--color-text-primary);
}
:deep(.ant-result-subtitle) {
color: var(--color-text-desc);
}
.keyword-tag {
font-size: 13px;
margin: 4px;
}
.container {
box-sizing: border-box;
@@ -257,7 +285,7 @@ const deletePlugin = async (plugin) => {
}
.installed-list {
width: 40%;
width: 38%;
background: var(--color-body-bg);
height: 100%;
padding: 10px 0;
@@ -269,17 +297,29 @@ const deletePlugin = async (plugin) => {
display: flex;
align-items: center;
color: var(--color-text-content);
border-bottom: 1px dashed var(--color-border-light);
cursor: pointer;
&:last-child {
border-bottom: none;
}
img {
width: 40px;
height: 40px;
margin-right: 20px;
width: 34px;
height: 34px;
margin-right: 12px;
}
.desc {
font-size: 12px;
color: var(--color-text-desc);
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
-webkit-line-clamp: 2;
text-overflow: ellipsis;
}
&.active {
color: var(--ant-primary-color);
background: var(--color-list-hover);
}
}
@@ -288,16 +328,18 @@ const deletePlugin = async (plugin) => {
.plugin-detail {
padding: 20px 20px 0 20px;
box-sizing: border-box;
width: 60%;
width: 62%;
height: 100%;
background: var(--color-body-bg);
.plugin-top {
display: flex;
align-items: flex-start;
justify-content: space-between;
border-bottom: 1px solid #eee;
padding-bottom: 12px;
margin-bottom: 12px;
.title {
font-size: 20px;
font-size: 16px;
display: flex;
align-items: center;
color: var(--color-text-primary);
@@ -314,12 +356,6 @@ const deletePlugin = async (plugin) => {
color: var(--color-text-desc);
}
}
.ant-tabs {
:deep(.ant-tabs-bar) {
color: var(--color-text-content);
border-bottom: 1px solid var(--color-border-light);
}
}
.detail-container,
.feature-container {
@@ -332,7 +368,6 @@ const deletePlugin = async (plugin) => {
}
.desc-item {
border-bottom: 1px solid var(--color-border-light);
padding: 10px 0;
color: var(--color-text-content);
.ant-tag {

View File

@@ -42,7 +42,6 @@ const dev = computed(() => {
<style lang="less">
.system {
width: 100%;
height: 100vh;
overflow-x: hidden;
box-sizing: border-box;
}

View File

@@ -1,20 +1,17 @@
<template>
<div class="finder">
<a-carousel arrows>
<template #prevArrow>
<div class="custom-slick-arrow" style="left: 10px; z-index: 1">
<left-circle-outlined />
</div>
</template>
<template #nextArrow>
<div class="custom-slick-arrow" style="right: 10px">
<right-circle-outlined />
</div>
</template>
<div :key="index" v-for="(banner, index) in data.banners || []">
<img @click="jumpTo(banner.link)" width="100%" :src="banner.src" />
</div>
</a-carousel>
<Carousel :itemsToShow="2" :transition="500">
<Slide :key="index" v-for="(banner, index) in data.banners || []">
<img class="carousel__item" @click="jumpTo(banner.link)" :src="banner.src" />
</Slide>
</Carousel>
<a-divider />
<PluginList
v-if="must && !!must.length"
@downloadSuccess="downloadSuccess"
:title="$t('feature.market.finder.must')"
:list="must"
/>
<PluginList
v-if="recommend && !!recommend.length"
@downloadSuccess="downloadSuccess"
@@ -30,8 +27,9 @@
</template>
<script setup>
import { LeftCircleOutlined, RightCircleOutlined } from '@ant-design/icons-vue';
import { ref, computed, onBeforeMount } from 'vue';
import 'vue3-carousel/dist/carousel.css';
import { Carousel, Slide } from 'vue3-carousel';
import request from '../../../assets/request/index';
import PluginList from './plugin-list.vue';
@@ -45,6 +43,24 @@ onBeforeMount(async () => {
data.value = await request.getFinderDetail();
});
const must = computed(() => {
const defaultData = data.value.must || [];
if (!defaultData.length) return [];
return defaultData.map((plugin) => {
let searchInfo = null;
totalPlugins.value.forEach((t) => {
if (t.name === plugin) {
searchInfo = t;
}
});
return searchInfo;
});
});
const jumpTo = (url) => {
window.rubick.shellOpenExternal(url);
};
const recommend = computed(() => {
const defaultData = data.value.recommend || [];
if (!defaultData.length) return [];
@@ -76,47 +92,46 @@ const newList = computed(() => {
<style lang="less">
.finder {
position: relative;
width: 100%;
height: 100%;
overflow-x: hidden;
box-sizing: border-box;
&::-webkit-scrollbar {
width: 0;
}
.ant-carousel .slick-slide {
text-align: center;
height: 235px;
line-height: 160px;
overflow: hidden;
border-radius: 4px;
img {
width: 100%;
height: 235px;
}
}
.ant-carousel .custom-slick-arrow {
width: 25px;
height: 25px;
font-size: 25px;
color: #fff;
background-color: rgba(31, 45, 61, 0.11);
opacity: 0.3;
}
.ant-carousel .custom-slick-arrow.slick-next:focus {
color: #fff;
}
.ant-carousel .custom-slick-arrow:before {
display: none;
}
.ant-carousel .custom-slick-arrow:hover {
opacity: 0.5;
}
.ant-carousel .slick-slide h3 {
color: #fff;
.ant-divider-horizontal {
margin: 17px 0;
}
}
.carousel__item {
cursor: pointer;
min-height: 180px;
width: 100%;
background-color: var(--vc-clr-primary);
color: var(--vc-clr-white);
font-size: 20px;
border-radius: 8px;
display: flex;
justify-content: center;
align-items: center;
}
.carousel__track {
margin-bottom: 0;
}
.carousel__slide {
padding-right: 6px;
&:last-child {
padding-left: 6px;
}
}
.carousel__prev,
.carousel__next {
box-sizing: content-box;
border: 5px solid white;
}
</style>

View File

@@ -42,7 +42,6 @@ const system = computed(() => {
<style lang="less">
.system {
width: 100%;
height: 100vh;
overflow-x: hidden;
box-sizing: border-box;
}

View File

@@ -7,7 +7,7 @@
:data-source="list.filter((item) => !!item)"
>
<template #renderItem="{ item, index }">
<a-list-item v-if="item" @click="showDetail(item)">
<a-list-item v-if="item" @click="showDetail(index)">
<template #actions>
<a-button
class="download-plugin-btn"
@@ -15,10 +15,15 @@
:loading="item.isloading"
>
<CloudDownloadOutlined
v-show="!item.isloading && !item.isdownload"
v-if="!item.isloading && !item.isdownload"
@click.stop="downloadPlugin(item, index)"
style="font-size: 20px; cursor: pointer"
/>
<SelectOutlined
v-if="!item.isloading && item.isdownload"
@click.stop="openPlugin(item)"
style="font-size: 18px; cursor: pointer"
/>
</a-button>
</template>
<a-list-item-meta>
@@ -36,73 +41,87 @@
</template>
</a-list>
</div>
</div>
<a-drawer
width="100%"
placement="right"
:closable="false"
:visible="visible"
:get-container="false"
class="plugin-info"
:style="{ position: 'absolute' }"
@close="visible = false"
>
<template #title>
<div class="plugin-title-info">
<div class="back-icon" @click="visible = false">
<ArrowLeftOutlined />
</div>
<div class="info">
<img :src="detail.logo" class="plugin-icon" />
<div class="plugin-desc">
<div class="title">
{{ detail.pluginName }}
<a-drawer
width="77%"
v-if="visible"
placement="right"
:closable="false"
:visible="visible"
class="plugin-info"
:style="{ position: 'absolute' }"
@close="visible = false"
>
<template #title>
<div class="plugin-title-info">
<div class="info">
<img :src="detail.logo" class="plugin-icon" />
<div class="plugin-desc">
<div>
<div class="title">
{{ detail.pluginName }}
</div>
<div class="desc">
{{ detail.description }}
</div>
</div>
<a-button
v-if="!detail.isdownload"
@click.stop="downloadPlugin(detail)"
shape="round"
type="primary"
:loading="detail.isloading"
>
<template #icon>
<CloudDownloadOutlined
v-show="!detail.isloading && !detail.isdownload"
/>
</template>
{{ $t('feature.market.install') }}
</a-button>
</div>
<div class="desc">
{{ detail.description }}
</div>
<a-button
v-if="!detail.isdownload"
@click.stop="downloadPlugin(detail)"
shape="round"
type="primary"
:loading="detail.isloading"
>
<template #icon>
<CloudDownloadOutlined
v-show="!detail.isloading && !detail.isdownload"
/>
</template>
{{ $t('feature.market.install') }}
</a-button>
</div>
</div>
</div>
</template>
<div v-html="content" class="home-page-container"></div>
</a-drawer>
</template>
<a-spin :spinning="!content" tip="内容加载中...">
<div v-if="content !== 'error'" v-html="content" class="home-page-container"></div>
<a-result
class="error-content"
v-else
sub-title="插件主页内容走丢啦"
>
<template #icon>
<Vue3Lottie :animationData="notFountJson" :height="240" :width="240" />
</template>
</a-result>
</a-spin>
</a-drawer>
</div>
</template>
<script setup>
import {
CloudDownloadOutlined,
ArrowLeftOutlined,
SelectOutlined
} from '@ant-design/icons-vue';
import { defineProps, ref } from 'vue';
import { defineProps, ref, computed } from 'vue';
import { useStore } from 'vuex';
import { message } from 'ant-design-vue';
import MarkdownIt from 'markdown-it';
import request from '../../../assets/request/index';
import { useRouter } from 'vue-router';
import request from '@/assets/request/index';
import notFountJson from '@/assets/lottie/404.json';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const store = useStore();
const router = useRouter();
const startDownload = (name) => store.dispatch('startDownload', name);
const successDownload = (name) => store.dispatch('successDownload', name);
defineProps({
const props = defineProps({
list: {
type: [Array],
default: () => [],
@@ -113,23 +132,39 @@ defineProps({
const downloadPlugin = async (plugin) => {
startDownload(plugin.name);
await window.market.downloadPlugin(plugin);
message.success(t('feature.dev.installSuccess', { pluginName: plugin.name }));
message.success(t('feature.dev.installSuccess', { pluginName: plugin.pluginName }));
successDownload(plugin.name);
};
const visible = ref(false);
const detail = ref({});
const showIndex = ref(0);
const markdown = new MarkdownIt();
const content = ref('');
const showDetail = async (item) => {
const showDetail = async (index) => {
const item = props.list[index];
visible.value = true;
detail.value = item;
showIndex.value = index;
content.value = '';
let mdContent = '暂无内容';
if (item.homePage) {
mdContent = await request.getPluginDetail(item.homePage);
try {
if (item.homePage) {
mdContent = await request.getPluginDetail(item.homePage);
}
content.value = markdown.render(mdContent);
} catch (e) {
content.value = 'error';
}
content.value = markdown.render(mdContent);
};
const detail = computed(() => props.list[showIndex.value]);
const openPlugin = (item) => {
store.commit('commonUpdate', {active: ['installed']})
router.push({
path: '/installed',
query: {plugin: item.name}
});
};
</script>
@@ -138,7 +173,7 @@ const showDetail = async (item) => {
width: 0;
}
.panel-item {
margin: 20px 0;
margin-bottom: 17px;
.download-plugin-btn {
color: var(--ant-primary-color);
}
@@ -170,7 +205,9 @@ const showDetail = async (item) => {
}
&:last-child {
border-bottom: none;
&:after {
border-bottom: none;
}
}
}
.plugin-info {
@@ -199,23 +236,23 @@ const showDetail = async (item) => {
.plugin-title-info {
display: flex;
align-items: flex-start;
.back-icon {
font-size: 16px;
margin-right: 40px;
}
width: 100%;
.info {
width: 100%;
display: flex;
align-items: center;
align-items: flex-start;
.plugin-icon {
width: 100px;
height: 100px;
width: 40px;
height: 40px;
margin-right: 20px;
}
.plugin-desc {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
.title {
font-size: 18px;
font-weight: bold;
@@ -225,14 +262,18 @@ const showDetail = async (item) => {
.desc {
font-size: 12px;
font-weight: normal;
margin-top: 5px;
margin-bottom: 20px;
color: var(--color-text-desc);
}
}
}
}
.error-content {
&.ant-result {
padding: 0;
}
}
.home-page-container {
min-height: 200px;
* {
color: var(--color-text-content);
}

View File

@@ -6,11 +6,21 @@
:title="$t('feature.market.searchResult')"
:list="result"
/>
<a-result
class="error-content"
v-else
sub-title="哎呀暂时还没有这个插件哟"
>
<template #icon>
<Vue3Lottie :animationData="emptyJson" :height="240" :width="240" />
</template>
</a-result>
</div>
</template>
<script setup>
import { computed } from 'vue';
import emptyJson from '@/assets/lottie/empty.json';
import PluginList from './plugin-list.vue';
import { useStore } from 'vuex';
@@ -21,9 +31,9 @@ const searchValue = computed(() => store.state.searchValue);
const result = computed(() => {
if (searchValue.value.trim().length > 0) {
const pattern = new RegExp(searchValue.value);
const pattern = new RegExp(searchValue.value.toLowerCase());
return totalPlugins.value.filter((plugin) => {
if (plugin.pluginName.match(pattern)) {
if (plugin.pluginName.toLowerCase().match(pattern)) {
return true;
} else {
return false;
@@ -38,8 +48,10 @@ const result = computed(() => {
<style lang="less">
.result {
width: 100%;
height: 100vh;
overflow-x: hidden;
box-sizing: border-box;
.error-content {
padding-top: 40px;
}
}
</style>

View File

@@ -42,7 +42,6 @@ const system = computed(() => {
<style lang="less">
.system {
width: 100%;
height: 100vh;
overflow-x: hidden;
box-sizing: border-box;
}

View File

@@ -42,7 +42,6 @@ const tools = computed(() => {
<style lang="less">
.worker {
width: 100%;
height: 100vh;
overflow-x: hidden;
box-sizing: border-box;
}

View File

@@ -42,7 +42,6 @@ const system = computed(() => {
<style lang="less">
.worker {
width: 100%;
height: 100vh;
overflow-x: hidden;
box-sizing: border-box;
}

View File

@@ -1,133 +0,0 @@
<template>
<div class="market">
<div class="left-menu">
<div class="search-container">
<a-input-search
v-model:value="searchValue"
:placeholder="$t('feature.market.search')"
style="width: 100%"
class="search"
@search="onSearch"
/>
</div>
<a-menu v-model:selectedKeys="current" mode="inline">
<a-menu-item key="finder">
<template #icon>
<StarOutlined />
</template>
{{ $t('feature.market.explore') }}
</a-menu-item>
<a-menu-item key="worker">
<template #icon>
<SendOutlined style="transform: rotate(-45deg)" />
</template>
{{ $t('feature.market.efficiency') }}
</a-menu-item>
<a-menu-item key="tools">
<template #icon>
<SearchOutlined />
</template>
{{ $t('feature.market.searchTool') }}
</a-menu-item>
<a-menu-item key="image">
<template #icon>
<FileImageOutlined />
</template>
{{ $t('feature.market.imageTool') }}
</a-menu-item>
<a-menu-item key="dev">
<template #icon>
<CodeOutlined />
</template>
{{ $t('feature.market.developTool') }}
</a-menu-item>
<a-menu-item key="system">
<template #icon>
<DatabaseOutlined />
</template>
{{ $t('feature.market.systemTool') }}
</a-menu-item>
</a-menu>
</div>
<div class="container">
<component :totalPlugins="totalPlugins" :is="Components[current[0]]" />
</div>
</div>
</template>
<script lang="ts" setup>
import {
StarOutlined,
SendOutlined,
SearchOutlined,
FileImageOutlined,
DatabaseOutlined,
CodeOutlined,
} from '@ant-design/icons-vue';
import { reactive, toRefs, computed } from 'vue';
import { useStore } from 'vuex';
import Finder from './components/finder.vue';
import System from './components/system.vue';
import Worker from './components/worker.vue';
import Tools from './components/tools.vue';
import Dev from './components/devlopment.vue';
import Image from './components/image.vue';
import Result from './components/result.vue';
const Components = {
finder: Finder,
system: System,
worker: Worker,
image: Image,
tools: Tools,
dev: Dev,
result: Result,
};
const state = reactive({
searchValue: '',
current: ['finder'],
});
const store = useStore();
const totalPlugins = computed(() => store.state.totalPlugins);
const { searchValue, current } = toRefs(state);
const onSearch = (searchValue: string) => {
state.current = ['result'];
store.commit('setSearchValue', searchValue);
};
</script>
<style lang="less" scoped>
@import '~@/assets/common.less';
.market {
display: flex;
box-sizing: border-box;
align-items: flex-start;
width: 100%;
overflow: hidden;
background: var(--color-menu-bg);
height: calc(~'100vh - 46px');
.search {
:deep(.ant-btn),
:deep(.ant-input),
:deep(.ant-input-group-addon) {
color: var(--ant-primary-color) !important;
background: var(--color-input-hover);
border-color: var(--color-border-light);
}
}
.container {
background: var(--color-body-bg);
width: calc(~'100% - 200px');
height: 100%;
box-sizing: border-box;
padding: 10px 20px;
position: relative;
}
}
</style>

View File

@@ -6,7 +6,7 @@
<ExportOutlined />
</template>
</a-button>
<a-button @click="importData" danger size="small" style="margin-right: 10px;">
<a-button @click="importData" danger size="small" style="margin-right: 10px; background-color: var(--color-input-hover)">
导入数据
<template #icon>
<ImportOutlined />
@@ -22,25 +22,30 @@
<template #renderItem="{ item }">
<a-list-item>
<template #actions>
<a v-if="!item.plugin.isdownload && !item.plugin.isloading" key="list-loadmore-edit"
<a v-if="!item.plugin?.isdownload && !item.plugin?.isloading" key="list-loadmore-edit"
@click="() => downloadPlugin(item.plugin)">
<CloudDownloadOutlined style="font-size: 18px;"/>
</a>
<a v-if="item.plugin.isloading" key="list-loadmore-edit">
<a v-if="item.plugin?.isloading" key="list-loadmore-edit">
<LoadingOutlined style="font-size: 18px;"/>
</a>
<a key="list-loadmore-edit" @click="() => showKeys(item)">
<DatabaseOutlined style="font-size: 18px;"/>
</a>
</template>
<a-list-item-meta :description="`${item.keys.length} 份文档`">
<a-list-item-meta>
<template #title>
<div>
<span>{{ item.plugin.pluginName }}</span>
<div style="color: var(--color-text-content)">
<span>{{ item.plugin?.pluginName }}</span>
</div>
</template>
<template #avatar>
<a-avatar shape="square" :src="item.plugin.logo"/>
<a-avatar shape="square" :src="item.plugin?.logo"/>
</template>
<template #description>
<div style="color: var(--color-text-desc)">
<span>{{ item.keys.length }} 份文档</span>
</div>
</template>
</a-list-item-meta>
</a-list-item>
@@ -52,6 +57,7 @@
:closable="false"
:title="currentSelect.plugin.pluginName"
placement="right"
class="exportDrawer"
>
<p
class="key-item"
@@ -64,7 +70,12 @@
</a-drawer>
<a-modal
centered
bodyStyle="max-height: 500px; overflow: auto"
:bodyStyle="{
maxHeight: '500px',
overflow: 'auto',
backgroundColor: 'var(--color-body-bg)',
color: 'var(--color-text-primary)'
}"
:footer="null"
:closable="false"
v-model:visible="show"
@@ -75,6 +86,7 @@
v-model:visible="showSetting"
title="webdav 账户配置"
:footer="null"
class="webdavModel"
>
<a-alert v-if="formState.suport === 'jianguo'" style="margin-bottom: 20px;" type="info" show-icon>
<template #message>
@@ -255,7 +267,7 @@ const downloadPlugin = async (plugin) => {
.export-header {
width: 100%;
height: 40px;
border-bottom: 1px solid #eee;
border-bottom: 1px solid var(--color-border-light);
text-align: right;
}
.key-item {
@@ -265,4 +277,44 @@ const downloadPlugin = async (plugin) => {
color: var(--ant-primary-color);
}
}
.exportDrawer{
.ant-drawer-header{
background-color: var(--color-body-bg);
border-bottom: 1px solid var(--color-border-light);
.ant-drawer-title{
color: var(--color-text-primary);
}
}
.ant-drawer-body{
background-color: var(--color-body-bg);
color: var(--color-text-content)
}
}
.webdavModel{
.ant-modal-close-x{
color: var(--color-text-content);
}
.ant-modal-header{
background-color: var(--color-body-bg);
border-bottom: 1px solid var(--color-border-light);
.ant-modal-title{
color: var(--color-text-primary);
}
}
.ant-form-item-label>label {
color: var(--color-text-content);
}
.ant-modal-body {
background-color: var(--color-body-bg);
.ant-input,
.ant-input-password,
.ant-select-selector {
background: var(--color-input-hover) !important;
color: var(--color-text-content);
}
.ant-input-password-icon, .ant-select-arrow {
color: var(--color-action-color);
}
}
}
</style>

View File

@@ -1,239 +1,231 @@
<template>
<div class="settings">
<div class="left-menu">
<a-menu v-model:selectedKeys="currentSelect" mode="inline">
<div class="view-title"> {{ $t('feature.settings.title') }}</div>
<div class="view-container">
<a-menu v-model:selectedKeys="currentSelect" mode="horizontal">
<a-menu-item key="userInfo">
<template #icon>
<UserOutlined />
</template>
{{ $t('feature.settings.account.accountInfo') }}
</a-menu-item>
<a-menu-item key="normal">
<template #icon>
<ToolOutlined />
</template>
{{ $t('feature.settings.basic.title') }}
</a-menu-item>
<a-menu-item key="localstart">
<template #icon>
<FolderOpenOutlined />
</template>
{{ $t('feature.settings.localstart.title') }}
</a-menu-item>
<a-menu-item key="global">
<template #icon>
<LaptopOutlined />
</template>
{{ $t('feature.settings.global.title') }}
</a-menu-item>
<!-- <a-menu-item key="superpanel">-->
<!-- <template #icon>-->
<!-- <FileAddOutlined />-->
<!-- </template>-->
<!-- {{ $t('feature.settings.superPanel.title') }}-->
<!-- </a-menu-item>-->
<!-- <a-menu-item key="superpanel">-->
<!-- <template #icon>-->
<!-- <FileAddOutlined />-->
<!-- </template>-->
<!-- {{ $t('feature.settings.superPanel.title') }}-->
<!-- </a-menu-item>-->
<a-menu-item key="database">
<template #icon>
<DatabaseOutlined />
</template>
{{ $t('feature.settings.database.title') }}
</a-menu-item>
<a-menu-item key="localhost">
<template #icon>
<SafetyOutlined />
</template>
{{ $t('feature.settings.intranet.title') }}
</a-menu-item>
</a-menu>
</div>
<div class="settings-detail">
<UserInfo v-if="currentSelect[0] === 'userInfo'" />
<div v-if="currentSelect[0] === 'normal'">
<div class="setting-item">
<div class="title">
{{ $t('feature.settings.basic.shortcutKey') }}
</div>
<div class="settings-item-li">
<div class="label">
{{ $t('feature.settings.basic.showOrHiddle') }}
<div class="settings-detail">
<UserInfo v-if="currentSelect[0] === 'userInfo'" />
<div v-if="currentSelect[0] === 'normal'">
<div class="setting-item">
<div class="title">
{{ $t('feature.settings.basic.shortcutKey') }}
</div>
<a-tooltip placement="top" trigger="click">
<template #title>
<span>{{ tipText }}</span>
<template v-if="isWindows">
<br />
<span
style="cursor: pointer; text-decoration: underline"
@click="resetDefault('Alt')"
>
<div class="settings-item-li">
<div class="label">
{{ $t('feature.settings.basic.showOrHiddle') }}
</div>
<a-tooltip placement="top" trigger="click">
<template #title>
<span>{{ tipText }}</span>
<template v-if="isWindows">
<br />
<span
style="cursor: pointer; text-decoration: underline"
@click="resetDefault('Alt')"
>
Alt+Space
</span>
<span
style="
<span
style="
cursor: pointer;
margin-left: 8px;
text-decoration: underline;
"
@click="resetDefault('Ctrl')"
>
@click="resetDefault('Ctrl')"
>
Ctrl+Space
</span>
</template>
</template>
</template>
<div
class="value"
tabIndex="-1"
@keyup="(e) => changeShortCut(e, 'showAndHidden')"
>
{{ shortCut.showAndHidden }}
<div
class="value"
tabIndex="-1"
@keyup="(e) => changeShortCut(e, 'showAndHidden')"
>
{{ shortCut.showAndHidden }}
</div>
</a-tooltip>
</div>
<div class="settings-item-li">
<div class="label">
{{ $t('feature.settings.basic.screenCapture') }}
</div>
</a-tooltip>
</div>
<div class="settings-item-li">
<div class="label">
{{ $t('feature.settings.basic.screenCapture') }}
</div>
<a-tooltip placement="top" trigger="click">
<template #title>
<span>{{ tipText }}</span>
</template>
<div
class="value"
tabIndex="-1"
@keyup="(e) => changeShortCut(e, 'capture')"
>
{{ shortCut.capture }}
</div>
</a-tooltip>
</div>
</div>
<div class="setting-item">
<div class="title">{{ $t('feature.settings.basic.common') }}</div>
<div class="settings-item-li">
<div class="label">
{{ $t('feature.settings.basic.autoPaste') }}
</div>
<a-switch
v-model:checked="common.autoPast"
:checked-children="$t('feature.settings.basic.on')"
:un-checked-children="$t('feature.settings.basic.off')"
></a-switch>
</div>
<div class="settings-item-li">
<div class="label">{{ $t('feature.settings.basic.autoBoot') }}</div>
<a-switch
v-model:checked="common.start"
:checked-children="$t('feature.settings.basic.on')"
:un-checked-children="$t('feature.settings.basic.off')"
></a-switch>
</div>
<div class="settings-item-li">
<div class="label">
{{ $t('feature.settings.basic.spaceExec') }}
</div>
<a-switch
v-model:checked="common.space"
:checked-children="$t('feature.settings.basic.on')"
:un-checked-children="$t('feature.settings.basic.off')"
></a-switch>
</div>
</div>
<div class="setting-item">
<div class="title">{{ $t('feature.settings.basic.theme') }}</div>
<div class="settings-item-li">
<div class="label">{{ $t('feature.settings.basic.darkMode') }}</div>
<a-switch
v-model:checked="common.darkMode"
:checked-children="$t('feature.settings.basic.on')"
:un-checked-children="$t('feature.settings.basic.off')"
></a-switch>
</div>
</div>
<div class="setting-item">
<div class="title">{{ $t('feature.settings.basic.language') }}</div>
<div class="settings-item-li">
<div class="label">
{{ $t('feature.settings.basic.changeLang') }}
</div>
<a-select
v-model:value="state.common.lang"
label-in-value
style="width: 240px"
:options="options"
@change="changeLanguage"
></a-select>
</div>
</div>
</div>
<div v-if="currentSelect[0] === 'global'">
<a-collapse>
<a-collapse-panel
key="1"
:header="$t('feature.settings.global.instructions')"
>
<div>
{{ $t('feature.settings.global.tips') }}
</div>
<h3 style="margin-top: 10px">
{{ $t('feature.settings.global.example') }}
</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>{{ $t('feature.settings.global.shortcutKey') }}</div>
<template :key="index" v-for="(item, index) in global">
<a-tooltip placement="top" trigger="click">
<template #title>
<span>{{ tipText }}</span>
</template>
<div
class="value"
tabIndex="2"
@keyup="(e) => changeGlobalKey(e, index)"
tabIndex="-1"
@keyup="(e) => changeShortCut(e, 'capture')"
>
{{ item.key }}
<MinusCircleOutlined
@click.stop="deleteGlobalKey(e, index)"
/>
{{ shortCut.capture }}
</div>
</a-tooltip>
</template>
</div>
</div>
<div class="short-cut item">
<div>{{ $t('feature.settings.global.funtionKey') }}</div>
<template v-for="(item, index) in global" :key="index">
<a-input
:value="item.value"
class="value"
allowClear
:disabled="!item.key"
@change="(e) => changeGlobalValue(index, e.target.value)"
/>
</template>
<div class="setting-item">
<div class="title">{{ $t('feature.settings.basic.common') }}</div>
<div class="settings-item-li">
<div class="label">
{{ $t('feature.settings.basic.autoPaste') }}
</div>
<a-switch
v-model:checked="common.autoPast"
:checked-children="$t('feature.settings.basic.on')"
:un-checked-children="$t('feature.settings.basic.off')"
></a-switch>
</div>
<div class="settings-item-li">
<div class="label">{{ $t('feature.settings.basic.autoBoot') }}</div>
<a-switch
v-model:checked="common.start"
:checked-children="$t('feature.settings.basic.on')"
:un-checked-children="$t('feature.settings.basic.off')"
></a-switch>
</div>
<div class="settings-item-li">
<div class="label">
{{ $t('feature.settings.basic.spaceExec') }}
</div>
<a-switch
v-model:checked="common.space"
:checked-children="$t('feature.settings.basic.on')"
:un-checked-children="$t('feature.settings.basic.off')"
></a-switch>
</div>
<div class="settings-item-li">
<div class="label">
{{ $t('feature.settings.basic.history') }}
</div>
<a-switch
v-model:checked="common.history"
:checked-children="$t('feature.settings.basic.on')"
:un-checked-children="$t('feature.settings.basic.off')"
></a-switch>
</div>
</div>
<div class="setting-item">
<div class="title">{{ $t('feature.settings.basic.theme') }}</div>
<div class="settings-item-li">
<div class="label">{{ $t('feature.settings.basic.darkMode') }}</div>
<a-switch
v-model:checked="common.darkMode"
:checked-children="$t('feature.settings.basic.on')"
:un-checked-children="$t('feature.settings.basic.off')"
></a-switch>
</div>
</div>
<div class="setting-item">
<div class="title">{{ $t('feature.settings.basic.language') }}</div>
<div class="settings-item-li">
<div class="label">
{{ $t('feature.settings.basic.changeLang') }}
</div>
<a-select
v-model:value="state.common.lang"
label-in-value
style="width: 240px"
:options="options"
@change="changeLanguage"
></a-select>
</div>
</div>
</div>
<div @click="addConfig" class="add-global">
<PlusCircleOutlined />
{{ $t('feature.settings.global.addShortcutKey') }}
<div v-if="currentSelect[0] === 'global'">
<a-collapse>
<a-collapse-panel
key="1"
:header="$t('feature.settings.global.instructions')"
>
<div>
{{ $t('feature.settings.global.tips') }}
</div>
<h3 style="margin-top: 10px">
{{ $t('feature.settings.global.example') }}
</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>{{ $t('feature.settings.global.shortcutKey') }}</div>
<template :key="index" v-for="(item, index) in global">
<a-tooltip placement="top" trigger="click">
<template #title>
<span>{{ tipText }}</span>
</template>
<div
class="value"
tabIndex="2"
@keyup="(e) => changeGlobalKey(e, index)"
>
{{ item.key }}
<MinusCircleOutlined
@click.stop="deleteGlobalKey(e, index)"
/>
</div>
</a-tooltip>
</template>
</div>
<div class="short-cut item">
<div>{{ $t('feature.settings.global.funtionKey') }}</div>
<template v-for="(item, index) in global" :key="index">
<a-input
:value="item.value"
class="value"
allowClear
:disabled="!item.key"
@change="(e) => changeGlobalValue(index, e.target.value)"
/>
</template>
</div>
</div>
<div @click="addConfig" class="add-global">
<PlusCircleOutlined />
{{ $t('feature.settings.global.addShortcutKey') }}
</div>
</div>
<Localhost v-if="currentSelect[0] === 'localhost'" />
<LocalStart v-if="currentSelect[0] === 'localstart'" />
<DataBase v-if="currentSelect[0] === 'database'" />
</div>
<SuperPanel v-if="currentSelect[0] === 'superpanel'" />
<Localhost v-if="currentSelect[0] === 'localhost'" />
<LocalStart v-if="currentSelect[0] === 'localstart'" />
<DataBase v-if="currentSelect[0] === 'database'" />
</div>
</div>
</template>
@@ -253,7 +245,6 @@ import debounce from 'lodash.debounce';
import { ref, reactive, watch, toRefs, computed } from 'vue';
import keycodes from './keycode';
import Localhost from './localhost.vue';
import SuperPanel from './super-panel.vue';
import UserInfo from './user-info';
import LocalStart from './local-start';
import DataBase from './database';
@@ -283,12 +274,16 @@ const state = reactive({
custom: {},
});
// 添加lastKeyPressTime变量来跟踪按键时间
const lastKeyPressTime = ref(0);
const DOUBLE_CLICK_THRESHOLD = 300; // 双击时间阈值(毫秒)
const isWindows = window?.rubick?.isWindows();
const tipText = computed(() => {
const optionKeyName = isWindows ? 'Alt' : 'Option、Command';
return t('feature.settings.global.addShortcutKeyTips', {
optionKeyName: optionKeyName,
});
}) + `此外你也可以双击修饰键如Ctrl+Ctrl`;
});
const currentSelect = ref(['userInfo']);
@@ -302,14 +297,15 @@ state.local = perf.local;
state.global = defaultGlobal;
const setConfig = debounce(() => {
const { perf } = localConfig.getConfig();
localConfig.setConfig(
JSON.parse(
JSON.stringify({
perf: {
...perf,
shortCut: state.shortCut,
common: state.common,
local: state.local,
custom: state.custom,
},
global: state.global,
})
@@ -322,33 +318,60 @@ watch(state, setConfig);
const changeShortCut = (e, key) => {
let compose = '';
// 添加是否包含功能键的判断
let incluFuncKeys = false;
const currentTime = Date.now();
const isDoubleClick = currentTime - lastKeyPressTime.value < DOUBLE_CLICK_THRESHOLD;
lastKeyPressTime.value = currentTime;
// 处理 F1-F12 功能键
if (e.keyCode >= 112 && e.keyCode <= 123) {
state.shortCut[key] = keycodes[e.keyCode].toUpperCase();
return;
}
// 处理双击功能键的情况
if (isDoubleClick) {
if (e.keyCode === 17) { // Ctrl
state.shortCut[key] = 'Ctrl+Ctrl';
return;
}
if (e.keyCode === 18) { // Alt
state.shortCut[key] = 'Option+Option';
return;
}
if (e.keyCode === 16) { // Shift
state.shortCut[key] = 'Shift+Shift';
return;
}
if (e.keyCode === 93) { // Command
state.shortCut[key] = 'Command+Command';
return;
}
}
// 处理功能键+普通键的组合
let hasModifierKey = false;
if (e.ctrlKey && e.keyCode !== 17) {
compose += '+Ctrl';
incluFuncKeys = true;
hasModifierKey = true;
}
if (e.shiftKey && e.keyCode !== 16) {
compose += '+Shift';
incluFuncKeys = true;
hasModifierKey = true;
}
if (e.altKey && e.keyCode !== 18) {
compose += '+Option';
incluFuncKeys = true;
hasModifierKey = true;
}
if (e.metaKey && e.keyCode !== 93) {
compose += '+Command';
incluFuncKeys = true;
hasModifierKey = true;
}
compose += '+' + keycodes[e.keyCode].toUpperCase();
compose = compose.substring(1);
if (
incluFuncKeys &&
e.keyCode !== 16 &&
e.keyCode !== 17 &&
e.keyCode !== 18 &&
e.keyCode !== 93
) {
// 只有当有修饰键时才添加普通键
if (hasModifierKey) {
compose += '+' + keycodes[e.keyCode].toUpperCase();
compose = compose.substring(1);
state.shortCut[key] = compose;
} else {
// 不做处理
@@ -453,10 +476,23 @@ const changeLanguage = (value) => {
box-sizing: border-box;
width: 100%;
overflow-x: hidden;
background: var(--color-body-bg);
height: calc(~'100vh - 46px');
display: flex;
background: var(--color-body-bg2);
height: calc(~'100vh - 34px');
.ant-menu-horizontal {
border-bottom: 1px solid var(--color-border-light);
}
.view-title {
font-size: 16px;
font-weight: 500;
margin-bottom: 16px;
color: var(--color-text-primary);
}
.view-container {
border-radius: 8px;
background: var(--color-body-bg);
overflow: auto;
height: calc(~'100vh - 84px');
}
.ant-menu {
background: var(--color-body-bg) !important;
color: var(--color-text-content) !important;
@@ -467,7 +503,6 @@ const changeLanguage = (value) => {
box-sizing: border-box;
flex: 1;
overflow: auto;
height: 100%;
background: var(--color-body-bg);
.setting-item {
@@ -479,7 +514,7 @@ const changeLanguage = (value) => {
.title {
color: var(--ant-primary-color);
font-size: 15px;
font-size: 14px;
margin-bottom: 10px;
}
@@ -519,6 +554,13 @@ const changeLanguage = (value) => {
background: var(--color-list-hover);
}
}
.ant-select-selector {
background: var(--color-input-hover) !important;
color: var(--color-text-content);
}
.ant-input-password-icon, .ant-select-arrow {
color: var(--color-action-color);
}
}
}
}
@@ -592,7 +634,6 @@ const changeLanguage = (value) => {
.ant-collapse {
background: var(--color-input-hover);
.ant-collapse-content {
background: var(--color-input-hover);
color: var(--color-text-content);

View File

@@ -98,7 +98,7 @@ const checkDrop = (e) => {
width: 100%;
overflow-x: hidden;
background: var(--color-body-bg);
height: calc(~'100vh - 106px');
height: calc(~'100vh - 180px');
.del-title {
text-decoration-line: line-through;
text-decoration-color: var(--ant-error-color);

View File

@@ -17,7 +17,7 @@
name="register"
>
<a-input
placeholder="https://registry.npm.taobao.org"
placeholder="https://registry.npmmirror.com"
v-model:value="formState.register"
/>
</a-form-item>
@@ -27,7 +27,7 @@
name="database"
>
<a-input
placeholder="https://gitcode.net/rubickcenter/rubick-database/-/raw/master"
placeholder="https://gitee.com/monkeyWang/rubickdatabase/raw/master"
v-model:value="formState.database"
/>
</a-form-item>
@@ -54,8 +54,8 @@ import { message } from 'ant-design-vue';
let _rev: any;
let defaultConfig = {
register: 'https://registry.npm.taobao.org',
database: 'https://gitcode.net/rubickcenter/rubick-database/-/raw/master',
register: 'https://registry.npmmirror.com',
database: 'https://gitee.com/monkeyWang/rubickdatabase/raw/master',
access_token: '',
};
@@ -81,7 +81,7 @@ const layout = {
const resetForm = () => {
formState.value = {
register: 'https://registry.npmmirror.com',
database: 'https://gitcode.net/rubickcenter/rubick-database/-/raw/master',
database: 'https://gitee.com/monkeyWang/rubickdatabase/raw/master',
access_token: '',
};
};

View File

@@ -1,103 +1,17 @@
<template>
<div class="user-info">
<!-- <div class="info-container">-->
<!-- <a-result-->
<!-- class="user-info-result"-->
<!-- :title="userInfo.name || $t('feature.settings.account.tips1')"-->
<!-- :sub-title="$t('feature.settings.account.tips2')"-->
<!-- >-->
<!-- <template #icon>-->
<!-- <a-avatar :size="64" v-if="!userInfo.avatar">-->
<!-- <template #icon><UserOutlined /></template>-->
<!-- </a-avatar>-->
<!-- <a-avatar :src="userInfo.avatar" :size="64" v-else />-->
<!-- </template>-->
<!-- </a-result>-->
<!-- </div>-->
<div class="settings-container">
<div class="setting-item">
<div class="title">
{{ $t('feature.settings.account.themeColor') }}
</div>
<div class="settings-item-li">
<div class="label">
{{ $t('feature.settings.account.primaryColor') }}
</div>
<a-input v-model:value="custom.primaryColor" class="value">
<template #prefix>
<div
:style="{
background: custom.primaryColor,
width: '10px',
height: '10px',
}"
></div>
</template>
</a-input>
</div>
<div class="settings-item-li">
<div class="label">
{{ $t('feature.settings.account.errorColor') }}
</div>
<a-input v-model:value="custom.errorColor" class="value">
<template #prefix>
<div
:style="{
background: custom.errorColor,
width: '10px',
height: '10px',
}"
></div>
</template>
</a-input>
</div>
<div class="settings-item-li">
<div class="label">
{{ $t('feature.settings.account.warningColor') }}
</div>
<a-input v-model:value="custom.warningColor" class="value">
<template #prefix>
<div
:style="{
background: custom.warningColor,
width: '10px',
height: '10px',
}"
></div>
</template>
</a-input>
</div>
<div class="settings-item-li">
<div class="label">
{{ $t('feature.settings.account.successColor') }}
</div>
<a-input v-model:value="custom.successColor" class="value">
<template #prefix>
<div
:style="{
background: custom.successColor,
width: '10px',
height: '10px',
}"
></div>
</template>
</a-input>
</div>
<div class="settings-item-li">
<div class="label">
{{ $t('feature.settings.account.infoColor') }}
</div>
<a-input v-model:value="custom.infoColor" class="value">
<template #prefix>
<div
:style="{
background: custom.infoColor,
width: '10px',
height: '10px',
}"
></div>
</template>
</a-input>
<a-radio-group @change="changeTheme" v-model:value="theme" button-style="solid">
<a-radio-button value="SPRING">{{ $t('feature.settings.account.spring') }}</a-radio-button>
<a-radio-button value="SUMMER">{{ $t('feature.settings.account.summer') }}</a-radio-button>
<a-radio-button value="AUTUMN">{{ $t('feature.settings.account.autumn') }}</a-radio-button>
<a-radio-button value="WINTER">{{ $t('feature.settings.account.winter') }}</a-radio-button>
</a-radio-group>
</div>
</div>
<div class="setting-item">
@@ -110,34 +24,33 @@
</div>
<a-input v-model:value="custom.placeholder" class="value"></a-input>
</div>
<div class="settings-item-li">
<div class="label">
{{ $t('feature.settings.account.name') }}
</div>
<a-input v-model:value="custom.username" class="value"></a-input>
</div>
<div class="settings-item-li">
<div class="label">
{{ $t('feature.settings.account.logo') }}
</div>
<div class="img-container">
<img class="custom-img" :src="custom.logo" />
<a-button @click="changeLogo" size="small" type="link">
<a-button class="btn" @click="changeLogo" shape="round" size="small" type="primary">
{{ $t('feature.settings.account.replace') }}
</a-button>
</div>
</div>
</div>
<!-- <div class="footer-btn">-->
<!-- <a-button @click="reset" type="danger">-->
<!-- {{ $t('feature.settings.account.reset') }}-->
<!-- </a-button>-->
<!-- </div>-->
</div>
</div>
</template>
<script setup>
import { reactive, ref, toRefs, watch } from 'vue';
import { reactive, toRefs, watch, ref } from 'vue';
import debounce from 'lodash.debounce';
import localConfig from '@/confOp';
import service from '../../assets/service';
import * as Themes from '@/assets/constans';
const { ipcRenderer } = window.require('electron');
const state = reactive({
@@ -146,15 +59,13 @@ const state = reactive({
const { perf } = localConfig.getConfig();
const theme = ref(perf.custom.theme);
state.custom = perf.custom || {};
const userInfo = ref(window.rubick.dbStorage.getItem('rubick-user-info'));
// service.getUserInfo({ openId: userInfo.value.openId }).then((res) => {
// userInfo.value = res;
// });
const setConfig = debounce(() => {
const { perf } = localConfig.getConfig();
localConfig.setConfig(
JSON.parse(
JSON.stringify({
@@ -180,6 +91,13 @@ const changeLogo = () => {
state.custom.logo = `file://${logoPath}`;
};
const changeTheme = () => {
state.custom = {
...state.custom,
...Themes[theme.value],
};
};
// const reset = () => {
// Modal.warning({
// title: '确定恢复默认设置吗?',
@@ -194,11 +112,17 @@ const changeLogo = () => {
</script>
<style lang="less">
.settings-container {
margin-top: 18px;
.ant-radio-button-wrapper {
background: var(--color-body-bg);
color: var(--color-text-content);
}
.user-info-result {
padding: 0;
.theme-preview {
width: 20px;
height: 20px;
border-radius: 100%;
}
&.ant-result {
padding: 24px;
}
@@ -214,6 +138,10 @@ const changeLogo = () => {
}
.img-container {
width: 300px;
.btn {
margin-left: 10px;
font-size: 12px;
}
}
.custom-img {
width: 60px;

View File

@@ -77,7 +77,6 @@ watch([visible], () => {
width: 100%;
overflow-x: hidden;
background: var(--color-body-bg);
height: calc(~'100vh - 46px');
:deep(.ant-result-title) {
color: var(--color-text-primary);
}

View File

@@ -1,13 +1,23 @@
const path = require("path");
const path = require('path');
module.exports = {
css: { // 配置css模块
loaderOptions: { // 向预处理器 Loader 传递配置选项
less: { // 配置less其他样式解析用法一致
javascriptEnabled: true // 设置为true
}
}
css: {
// 配置css模块
loaderOptions: {
// 向预处理器 Loader 传递配置选项
less: {
// 配置less其他样式解析用法一致
javascriptEnabled: true, // 设置为true
},
},
},
outputDir: path.join(__dirname, "../public/feature"),
publicPath: process.env.NODE_ENV === "production" ? "" : "/",
productionSourceMap: false,
outputDir: path.join(__dirname, '../public/feature'),
publicPath: process.env.NODE_ENV === 'production' ? '' : '/',
// chainWebpack: (config) => {
// // 查看打包文件体积大小
// config
// .plugin('webpack-bundle-analyzer')
// .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin);
// },
};

View File

@@ -968,6 +968,11 @@
resolved "https://registry.yarnpkg.com/@ctrl/tinycolor/-/tinycolor-3.4.1.tgz#75b4c27948c81e88ccd3a8902047bcd797f38d32"
integrity sha512-ej5oVy6lykXsvieQtqZxCOaLT+xD4+QNarq78cIYISHmZXshCvROLudpQN3lfL8G0NL7plMSSK+zlyvCaIJ4Iw==
"@discoveryjs/json-ext@0.5.7":
version "0.5.7"
resolved "https://registry.npmmirror.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
"@hapi/address@2.x.x":
version "2.1.4"
resolved "https://registry.yarnpkg.com/@hapi/address/-/address-2.1.4.tgz#5d67ed43f3fd41a69d4b9ff7b56e7c0d1d0a81e5"
@@ -1009,6 +1014,44 @@
cssnano-preset-default "^4.0.0"
postcss "^7.0.0"
"@intlify/core-base@9.2.2":
version "9.2.2"
resolved "https://registry.npmmirror.com/@intlify/core-base/-/core-base-9.2.2.tgz#5353369b05cc9fe35cab95fe20afeb8a4481f939"
integrity sha512-JjUpQtNfn+joMbrXvpR4hTF8iJQ2sEFzzK3KIESOx+f+uwIjgw20igOyaIdhfsVVBCds8ZM64MoeNSx+PHQMkA==
dependencies:
"@intlify/devtools-if" "9.2.2"
"@intlify/message-compiler" "9.2.2"
"@intlify/shared" "9.2.2"
"@intlify/vue-devtools" "9.2.2"
"@intlify/devtools-if@9.2.2":
version "9.2.2"
resolved "https://registry.npmmirror.com/@intlify/devtools-if/-/devtools-if-9.2.2.tgz#b13d9ac4b4e2fe6d2e7daa556517a8061fe8bd39"
integrity sha512-4ttr/FNO29w+kBbU7HZ/U0Lzuh2cRDhP8UlWOtV9ERcjHzuyXVZmjyleESK6eVP60tGC9QtQW9yZE+JeRhDHkg==
dependencies:
"@intlify/shared" "9.2.2"
"@intlify/message-compiler@9.2.2":
version "9.2.2"
resolved "https://registry.npmmirror.com/@intlify/message-compiler/-/message-compiler-9.2.2.tgz#e42ab6939b8ae5b3d21faf6a44045667a18bba1c"
integrity sha512-IUrQW7byAKN2fMBe8z6sK6riG1pue95e5jfokn8hA5Q3Bqy4MBJ5lJAofUsawQJYHeoPJ7svMDyBaVJ4d0GTtA==
dependencies:
"@intlify/shared" "9.2.2"
source-map "0.6.1"
"@intlify/shared@9.2.2":
version "9.2.2"
resolved "https://registry.npmmirror.com/@intlify/shared/-/shared-9.2.2.tgz#5011be9ca2b4ab86f8660739286e2707f9abb4a5"
integrity sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==
"@intlify/vue-devtools@9.2.2":
version "9.2.2"
resolved "https://registry.npmmirror.com/@intlify/vue-devtools/-/vue-devtools-9.2.2.tgz#b95701556daf7ebb3a2d45aa3ae9e6415aed8317"
integrity sha512-+dUyqyCHWHb/UcvY1MlIpO87munedm3Gn6E9WWYdWrMuYLcoIoOEVDWSS8xSwtlPU+kA+MEQTP6Q1iI/ocusJg==
dependencies:
"@intlify/core-base" "9.2.2"
"@intlify/shared" "9.2.2"
"@jridgewell/gen-mapping@^0.1.0":
version "0.1.1"
resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996"
@@ -1090,6 +1133,11 @@
"@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
"@polka/url@^1.0.0-next.20":
version "1.0.0-next.23"
resolved "https://registry.npmmirror.com/@polka/url/-/url-1.0.0-next.23.tgz#498e41218ab3b6a1419c735e5c6ae2c5ed609b6c"
integrity sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==
"@simonwep/pickr@~1.8.0":
version "1.8.2"
resolved "https://registry.yarnpkg.com/@simonwep/pickr/-/pickr-1.8.2.tgz#96dc86675940d7cad63d69c22083dd1cbb9797cb"
@@ -1720,6 +1768,11 @@
resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.1.4.tgz#b4aec2f4b4599e11ba774a50c67fa378c9824e53"
integrity sha512-IiA0SvDrJEgXvVxjNkHPFfDx6SXw0b/TUkqMcDZWNg9fnCAHbTpoo59YfJ9QLFkwa3raau5vSlRVzMSLDnfdtQ==
"@vue/devtools-api@^6.2.1":
version "6.5.0"
resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.5.0.tgz#98b99425edee70b4c992692628fa1ea2c1e57d07"
integrity sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==
"@vue/eslint-config-prettier@^6.0.0":
version "6.0.0"
resolved "https://registry.yarnpkg.com/@vue/eslint-config-prettier/-/eslint-config-prettier-6.0.0.tgz#ad5912b308f4ae468458e02a2b05db0b9d246700"
@@ -1981,6 +2034,11 @@ acorn-walk@^7.1.1:
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc"
integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==
acorn-walk@^8.0.0:
version "8.2.0"
resolved "https://registry.npmmirror.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
acorn@^6.4.1:
version "6.4.2"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6"
@@ -1991,6 +2049,11 @@ acorn@^7.1.1, acorn@^7.4.0:
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
acorn@^8.0.4:
version "8.10.0"
resolved "https://registry.npmmirror.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5"
integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==
address@^1.1.2:
version "1.2.0"
resolved "https://registry.yarnpkg.com/address/-/address-1.2.0.tgz#d352a62c92fee90f89a693eccd2a8b2139ab02d9"
@@ -2334,6 +2397,13 @@ babel-plugin-dynamic-import-node@^2.3.3:
dependencies:
object.assign "^4.1.0"
babel-plugin-import@^1.13.8:
version "1.13.8"
resolved "https://registry.npmmirror.com/babel-plugin-import/-/babel-plugin-import-1.13.8.tgz#782c517f6bbf2de3b1f75aaafd6d20a491c4878c"
integrity sha512-36babpjra5m3gca44V6tSTomeBlPA7cHUynrE2WiQIm3rEGD9xy28MKsx5IdO45EbnpJY7Jrgd00C6Dwt/l/2Q==
dependencies:
"@babel/helper-module-imports" "^7.0.0"
babel-plugin-polyfill-corejs2@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5"
@@ -3046,6 +3116,11 @@ commander@^2.12.1, commander@^2.18.0, commander@^2.20.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
commander@^7.2.0:
version "7.2.0"
resolved "https://registry.npmmirror.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
commander@~2.19.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
@@ -3802,7 +3877,7 @@ dotenv@^8.2.0:
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b"
integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==
duplexer@^0.1.1:
duplexer@^0.1.1, duplexer@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6"
integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==
@@ -3988,6 +4063,11 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
escape-string-regexp@^4.0.0:
version "4.0.0"
resolved "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
eslint-config-prettier@^6.0.0:
version "6.15.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz#7f93f6cb7d45a92f1537a70ecc06366e1ac6fed9"
@@ -4861,6 +4941,13 @@ gzip-size@^5.0.0:
duplexer "^0.1.1"
pify "^4.0.1"
gzip-size@^6.0.0:
version "6.0.0"
resolved "https://registry.npmmirror.com/gzip-size/-/gzip-size-6.0.0.tgz#065367fd50c239c0671cbcbad5be3e2eeb10e462"
integrity sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==
dependencies:
duplexer "^0.1.2"
handle-thing@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e"
@@ -5615,6 +5702,11 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4:
dependencies:
isobject "^3.0.1"
is-plain-object@^5.0.0:
version "5.0.0"
resolved "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344"
integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==
is-regex@^1.0.4, is-regex@^1.1.4:
version "1.1.4"
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
@@ -5982,7 +6074,7 @@ locate-path@^5.0.0:
dependencies:
p-locate "^4.1.0"
lodash-es@^4.17.15:
lodash-es@^4.17.15, lodash-es@^4.17.21:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
@@ -5997,6 +6089,21 @@ lodash.defaultsdeep@^4.6.1:
resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6"
integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==
lodash.escape@^4.0.1:
version "4.0.1"
resolved "https://registry.npmmirror.com/lodash.escape/-/lodash.escape-4.0.1.tgz#c9044690c21e04294beaa517712fded1fa88de98"
integrity sha512-nXEOnb/jK9g0DYMr1/Xvq6l5xMD7GDG55+GSYIYmS0G4tBk/hURD4JR9WCavs04t33WmJx9kCyp9vJ+mr4BOUw==
lodash.flatten@^4.4.0:
version "4.4.0"
resolved "https://registry.npmmirror.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
integrity sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==
lodash.invokemap@^4.6.0:
version "4.6.0"
resolved "https://registry.npmmirror.com/lodash.invokemap/-/lodash.invokemap-4.6.0.tgz#1748cda5d8b0ef8369c4eb3ec54c21feba1f2d62"
integrity sha512-CfkycNtMqgUlfjfdh2BhKO/ZXrP8ePOX5lEU/g0R3ItJcnuxWDwokMGKx1hWcfOikmyOVx6X9IwWnDGlgKl61w==
lodash.kebabcase@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36"
@@ -6012,6 +6119,11 @@ lodash.memoize@^4.1.2:
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe"
integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=
lodash.pullall@^4.2.0:
version "4.2.0"
resolved "https://registry.npmmirror.com/lodash.pullall/-/lodash.pullall-4.2.0.tgz#9d98b8518b7c965b0fae4099bd9fb7df8bbf38ba"
integrity sha512-VhqxBKH0ZxPpLhiu68YD1KnHmbhQJQctcipvmFnqIBDYzcIHzf3Zpu0tpeOKtR4x76p9yohc506eGdOjTmyIBg==
lodash.throttle@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
@@ -6027,6 +6139,11 @@ lodash.uniq@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
lodash.uniqby@^4.7.0:
version "4.7.0"
resolved "https://registry.npmmirror.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302"
integrity sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==
lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.3:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
@@ -6051,6 +6168,11 @@ loose-envify@^1.0.0:
dependencies:
js-tokens "^3.0.0 || ^4.0.0"
lottie-web@5.12.2:
version "5.12.2"
resolved "https://registry.npmmirror.com/lottie-web/-/lottie-web-5.12.2.tgz#579ca9fe6d3fd9e352571edd3c0be162492f68e5"
integrity sha512-uvhvYPC8kGPjXT3MyKMrL3JitEAmDMp30lVkuq/590Mw9ok6pWcFCwXJveo0t5uqYw1UREQHofD+jVpdjBv8wg==
lower-case@^1.1.1:
version "1.1.4"
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
@@ -6356,6 +6478,11 @@ move-concurrently@^1.0.1:
rimraf "^2.5.4"
run-queue "^1.0.3"
mrmime@^1.0.0:
version "1.0.1"
resolved "https://registry.npmmirror.com/mrmime/-/mrmime-1.0.1.tgz#5f90c825fad4bdd41dc914eff5d1a8cfdaf24f27"
integrity sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
@@ -6720,7 +6847,7 @@ open@^6.3.0:
dependencies:
is-wsl "^1.1.0"
opener@^1.5.1:
opener@^1.5.1, opener@^1.5.2:
version "1.5.2"
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598"
integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==
@@ -8170,6 +8297,15 @@ simple-swizzle@^0.2.2:
dependencies:
is-arrayish "^0.3.1"
sirv@^2.0.3:
version "2.0.3"
resolved "https://registry.npmmirror.com/sirv/-/sirv-2.0.3.tgz#ca5868b87205a74bef62a469ed0296abceccd446"
integrity sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==
dependencies:
"@polka/url" "^1.0.0-next.20"
mrmime "^1.0.0"
totalist "^3.0.0"
slash@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
@@ -8285,16 +8421,16 @@ source-map-url@^0.4.0:
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56"
integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==
source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
source-map@^0.5.6:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
source-map@^0.7.3:
version "0.7.3"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
@@ -8771,6 +8907,11 @@ toposort@^1.0.0:
resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029"
integrity sha1-LmhELZ9k7HILjMieZEOsbKqVACk=
totalist@^3.0.0:
version "3.0.1"
resolved "https://registry.npmmirror.com/totalist/-/totalist-3.0.1.tgz#ba3a3d600c915b1a97872348f79c127475f6acf8"
integrity sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==
tough-cookie@~2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
@@ -9117,11 +9258,6 @@ uuid@^8.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
uuid@^9.0.0:
version "9.0.0"
resolved "https://registry.npmmirror.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5"
integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==
v8-compile-cache@^2.0.3:
version "2.3.0"
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
@@ -9177,6 +9313,16 @@ vue-hot-reload-api@^2.3.0:
resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz#532955cc1eb208a3d990b3a9f9a70574657e08f2"
integrity sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==
vue-i18n@9.2.2:
version "9.2.2"
resolved "https://registry.npmmirror.com/vue-i18n/-/vue-i18n-9.2.2.tgz#aeb49d9424923c77e0d6441e3f21dafcecd0e666"
integrity sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ==
dependencies:
"@intlify/core-base" "9.2.2"
"@intlify/shared" "9.2.2"
"@intlify/vue-devtools" "9.2.2"
"@vue/devtools-api" "^6.2.1"
"vue-loader-v16@npm:vue-loader@^16.1.0":
version "16.8.3"
resolved "https://registry.yarnpkg.com/vue-loader/-/vue-loader-16.8.3.tgz#d43e675def5ba9345d6c7f05914c13d861997087"
@@ -9224,6 +9370,19 @@ vue-types@^3.0.0:
dependencies:
is-plain-object "3.0.1"
vue3-carousel@^0.3.1:
version "0.3.1"
resolved "https://registry.npmmirror.com/vue3-carousel/-/vue3-carousel-0.3.1.tgz#d001be7dea416dc2f4e66afc4d56af66696dc117"
integrity sha512-86vUkNPBzL2PVuR9w6hUsI90ccFjLp+K8cSFpRTISf+SjUQY3fMHc5CFF5MUL62v1xYYm27zEBmQupO9VQx9Kw==
vue3-lottie@^3.1.0:
version "3.1.0"
resolved "https://registry.npmmirror.com/vue3-lottie/-/vue3-lottie-3.1.0.tgz#39e2a595a83a7401f3308dfc923b28b0bb91a214"
integrity sha512-dS6/cjEuAoN/CWYqthPjGVVaeW5jRVB1yGEcFQbBcbDfCeMlVhC7pzn0Qatdz7gasOUIvZcJCmhfUe681GwhSg==
dependencies:
lodash-es "^4.17.21"
lottie-web "5.12.2"
vue@3.2.45:
version "3.2.45"
resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.45.tgz#94a116784447eb7dbd892167784619fef379b3c8"
@@ -9300,6 +9459,29 @@ webpack-bundle-analyzer@^3.8.0:
opener "^1.5.1"
ws "^6.0.0"
webpack-bundle-analyzer@^4.9.1:
version "4.9.1"
resolved "https://registry.npmmirror.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.9.1.tgz#d00bbf3f17500c10985084f22f1a2bf45cb2f09d"
integrity sha512-jnd6EoYrf9yMxCyYDPj8eutJvtjQNp8PHmni/e/ulydHBWhT5J3menXt3HEkScsu9YqMAcG4CfFjs3rj5pVU1w==
dependencies:
"@discoveryjs/json-ext" "0.5.7"
acorn "^8.0.4"
acorn-walk "^8.0.0"
commander "^7.2.0"
escape-string-regexp "^4.0.0"
gzip-size "^6.0.0"
is-plain-object "^5.0.0"
lodash.debounce "^4.0.8"
lodash.escape "^4.0.1"
lodash.flatten "^4.4.0"
lodash.invokemap "^4.6.0"
lodash.pullall "^4.2.0"
lodash.uniqby "^4.7.0"
opener "^1.5.2"
picocolors "^1.0.0"
sirv "^2.0.3"
ws "^7.3.1"
webpack-chain@^6.4.0:
version "6.5.1"
resolved "https://registry.yarnpkg.com/webpack-chain/-/webpack-chain-6.5.1.tgz#4f27284cbbb637e3c8fbdef43eef588d4d861206"
@@ -9519,6 +9701,11 @@ ws@^6.0.0, ws@^6.2.1:
dependencies:
async-limiter "~1.0.0"
ws@^7.3.1:
version "7.5.9"
resolved "https://registry.npmmirror.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591"
integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==
xtend@^4.0.0, xtend@~4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"

View File

@@ -102,15 +102,15 @@ const netStep = () => {
}
.info {
padding-top: 42px;
margin-right: 178px;
margin-left: 84px;
box-sizing: border-box;
width: 100%;
text-align: right;
text-align: left;
position: relative;
align-self: flex-start;
color: @text-color;
.top-icon {
position: absolute;
right: 0;
left: 0;
top: 0;
user-select: none;
width: 1em;
@@ -147,9 +147,11 @@ const netStep = () => {
background: @primary-color;
color: #fff;
display: flex;
aligin-items: center;
align-items: center;
justify-content: center;
border-radius: 4px;
cursor: pointer;
user-select: none;
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 KiB

After

Width:  |  Height:  |  Size: 238 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 110 KiB

After

Width:  |  Height:  |  Size: 89 KiB

View File

@@ -11,6 +11,7 @@ module.exports = {
},
},
},
productionSourceMap: false,
outputDir: path.join(__dirname, '../public/guide'),
publicPath: process.env.NODE_ENV === 'production' ? '' : '/',
};

20388
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "rubick",
"version": "3.2.2",
"version": "4.3.4",
"author": "muwoo <2424880409@qq.com>",
"private": true,
"scripts": {
@@ -14,7 +14,7 @@
"postinstall": "electron-builder install-app-deps",
"postuninstall": "electron-builder install-app-deps"
},
"main": "background.js",
"main": "index.js",
"optionalDependencies": {
"electron-clipboard-ex": "^1.3.3"
},
@@ -30,14 +30,16 @@
"fix-path": "^3.0.0",
"get-mac-apps": "^1.0.2",
"got": "^11.8.3",
"lodash.throttle": "^4.1.1",
"lodash.debounce": "^4.0.8",
"memorystream": "^0.3.1",
"node-key-sender": "^1.0.11",
"npm": "6.14.7",
"pinyin-match": "^1.2.4",
"pouchdb": "^7.2.2",
"pouchdb-load": "^1.4.6",
"pouchdb-replication-stream": "^1.2.9",
"simple-plist": "0.2.1",
"uiohook-napi": "^1.5.4",
"vue": "^3.0.0",
"vue-router": "^4.0.0-0",
"vuex": "^4.0.0-0",
@@ -45,6 +47,7 @@
"worker-loader": "^3.0.8"
},
"devDependencies": {
"@electron/asar": "^3.2.8",
"@ts-type/package-dts": "^1.0.53",
"@types/electron-devtools-installer": "^2.2.0",
"@typescript-eslint/eslint-plugin": "^4.18.0",
@@ -59,6 +62,7 @@
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^7.0.0",
"babel-plugin-import": "^1.13.3",
"compressing": "^1.10.0",
"electron": "26.0.0",
"electron-builder": "22.13.1",
"electron-devtools-installer": "^3.1.0",
@@ -69,10 +73,11 @@
"less-loader": "^5.0.0",
"prettier": "^2.8.4",
"typescript": "~4.1.5",
"vue-cli-plugin-electron-builder": "~2.1.1",
"vue-cli-plugin-electron-builder": "3.0.0-alpha.4",
"worker-plugin": "^5.0.1"
},
"resolutions": {
"vue-cli-plugin-electron-builder/electron-builder": "^23.0.3"
"vue-cli-plugin-electron-builder/electron-builder": "^23.0.3",
"leveldown": "6.0.3"
}
}

View File

@@ -1 +1 @@
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>detach</title><link href="css/app.65d55ce4.css" rel="preload" as="style"><link href="js/app.7471434d.js" rel="preload" as="script"><link href="js/chunk-vendors.29c10bf6.js" rel="preload" as="script"><link href="css/app.65d55ce4.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but detach doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.29c10bf6.js"></script><script src="js/app.7471434d.js"></script></body></html>
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title></title><link href="css/app.65d55ce4.css" rel="preload" as="style"><link href="js/app.f4fdc34a.js" rel="preload" as="script"><link href="js/chunk-vendors.b36194a6.js" rel="preload" as="script"><link href="css/app.65d55ce4.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but detach doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.b36194a6.js"></script><script src="js/app.f4fdc34a.js"></script></body></html>

View File

@@ -1,2 +0,0 @@
(function(e){function t(t){for(var c,o,l=t[0],a=t[1],i=t[2],p=0,d=[];p<l.length;p++)o=l[p],Object.prototype.hasOwnProperty.call(r,o)&&r[o]&&d.push(r[o][0]),r[o]=0;for(c in a)Object.prototype.hasOwnProperty.call(a,c)&&(e[c]=a[c]);s&&s(t);while(d.length)d.shift()();return u.push.apply(u,i||[]),n()}function n(){for(var e,t=0;t<u.length;t++){for(var n=u[t],c=!0,l=1;l<n.length;l++){var a=n[l];0!==r[a]&&(c=!1)}c&&(u.splice(t--,1),e=o(o.s=n[0]))}return e}var c={},r={app:0},u=[];function o(t){if(c[t])return c[t].exports;var n=c[t]={i:t,l:!1,exports:{}};return e[t].call(n.exports,n,n.exports,o),n.l=!0,n.exports}o.m=e,o.c=c,o.d=function(e,t,n){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},o.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(e,t){if(1&t&&(e=o(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var c in e)o.d(n,c,function(t){return e[t]}.bind(null,c));return n},o.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="";var l=window["webpackJsonp"]=window["webpackJsonp"]||[],a=l.push.bind(l);l.push=t,l=l.slice();for(var i=0;i<l.length;i++)t(l[i]);var s=a;u.push([0,"chunk-vendors"]),n()})({0:function(e,t,n){e.exports=n("cd49")},"0980":function(e,t,n){},4011:function(e,t,n){},cd49:function(e,t,n){"use strict";n.r(t);var c=n("79c4"),r=n("c965"),u=n.n(r);const o={class:"info"},l=["src"],a=["value","placeholder"],i={key:1};var s={__name:"App",setup(e){const{ipcRenderer:t}=window.require("electron"),n=Object(c["f"])(window.process.platform),r=Object(c["f"])(!1),s=localStorage.getItem("rubick-system-detach")||"{}",p=Object(c["f"])({});window.initDetach=e=>{p.value=e,r.value=e.subInput&&(!!e.subInput.value||!!e.subInput.placeholder),localStorage.setItem("rubick-system-detach",JSON.stringify(e))};try{window.initDetach(JSON.parse(s))}catch(O){}const d=u()(e=>{t.send("msg-trigger",{type:"detachInputChange",data:{text:e.target.value}})},500),b=()=>{t.send("msg-trigger",{type:"openPluginDevTools"})},v=()=>{t.send("detach:service",{type:"minimize"})},f=()=>{t.send("detach:service",{type:"maximize"})},h=()=>{t.send("detach:service",{type:"close"})};return Object.assign(window,{setSubInputValue:({value:e})=>{p.value.subInput.value=e},setSubInput:e=>{p.value.subInput.placeholder=e},removeSubInput:()=>{p.value.subInput=null}}),(e,t)=>{var u,s;return Object(c["e"])(),Object(c["b"])("div",{class:Object(c["d"])([n.value,"detach"])},[Object(c["c"])("div",o,[Object(c["c"])("img",{src:p.value.logo},null,8,l),r.value?(Object(c["e"])(),Object(c["b"])("input",{key:0,autofocus:"",onInput:t[0]||(t[0]=(...e)=>Object(c["h"])(d)&&Object(c["h"])(d)(...e)),value:null===(u=p.value.subInput)||void 0===u?void 0:u.value,placeholder:null===(s=p.value.subInput)||void 0===s?void 0:s.placeholder},null,40,a)):(Object(c["e"])(),Object(c["b"])("span",i,Object(c["g"])(p.value.pluginName),1))]),Object(c["c"])("div",{class:"handle-container"},[Object(c["c"])("div",{class:"handle"},[Object(c["c"])("div",{class:"devtool",onClick:b,title:"开发者工具"})]),Object(c["c"])("div",{class:"window-handle"},[Object(c["c"])("div",{class:"minimize",onClick:v}),Object(c["c"])("div",{class:"maximize",onClick:f}),Object(c["c"])("div",{class:"close",onClick:h})])])],2)}}};n("d648");const p=s;var d=p;n("4011");Object(c["a"])(d).mount("#app")},d648:function(e,t,n){"use strict";n("0980")}});
//# sourceMappingURL=app.7471434d.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
(function(e){function t(t){for(var c,o,a=t[0],l=t[1],u=t[2],d=0,p=[];d<a.length;d++)o=a[d],Object.prototype.hasOwnProperty.call(r,o)&&r[o]&&p.push(r[o][0]),r[o]=0;for(c in l)Object.prototype.hasOwnProperty.call(l,c)&&(e[c]=l[c]);s&&s(t);while(p.length)p.shift()();return i.push.apply(i,u||[]),n()}function n(){for(var e,t=0;t<i.length;t++){for(var n=i[t],c=!0,a=1;a<n.length;a++){var l=n[a];0!==r[l]&&(c=!1)}c&&(i.splice(t--,1),e=o(o.s=n[0]))}return e}var c={},r={app:0},i=[];function o(t){if(c[t])return c[t].exports;var n=c[t]={i:t,l:!1,exports:{}};return e[t].call(n.exports,n,n.exports,o),n.l=!0,n.exports}o.m=e,o.c=c,o.d=function(e,t,n){o.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},o.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.t=function(e,t){if(1&t&&(e=o(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(o.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var c in e)o.d(n,c,function(t){return e[t]}.bind(null,c));return n},o.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return o.d(t,"a",t),t},o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},o.p="";var a=window["webpackJsonp"]=window["webpackJsonp"]||[],l=a.push.bind(a);a.push=t,a=a.slice();for(var u=0;u<a.length;u++)t(a[u]);var s=l;i.push([0,"chunk-vendors"]),n()})({0:function(e,t,n){e.exports=n("cd49")},3480:function(e,t,n){"use strict";n("a1ff")},4011:function(e,t,n){},a1ff:function(e,t,n){},cd49:function(e,t,n){"use strict";n.r(t);var c=n("79c4"),r=n("c965"),i=n.n(r);const o={class:"info"},a=["src"],l=["value","placeholder"],u={key:1},s={class:"handle-container"},d={key:0,class:"window-handle"};var p={__name:"App",setup(e){const{ipcRenderer:t}=window.require("electron"),n=window.require("process"),r=Object(c["g"])(!1),p=localStorage.getItem("rubick-system-detach")||"{}",v=Object(c["g"])({});window.initDetach=e=>{v.value=e,r.value=e.subInput&&(!!e.subInput.value||!!e.subInput.placeholder),localStorage.setItem("rubick-system-detach",JSON.stringify(e))};try{window.initDetach(JSON.parse(p))}catch(y){}const b=i()(e=>{t.send("msg-trigger",{type:"detachInputChange",data:{text:e.target.value}})},500),f=()=>{t.send("msg-trigger",{type:"openPluginDevTools"})},m=()=>{t.send("detach:service",{type:"minimize"})},w=()=>{t.send("detach:service",{type:"maximize"})},h=()=>{t.send("detach:service",{type:"close"})};return Object.assign(window,{setSubInputValue:({value:e})=>{v.value.subInput.value=e},setSubInput:e=>{v.value.subInput.placeholder=e},removeSubInput:()=>{v.value.subInput=null}}),window.enterFullScreenTrigger=()=>{document.querySelector(".detach").classList.remove("darwin")},window.leaveFullScreenTrigger=()=>{const e=document.querySelector(".detach");e.classList.contains("darwin")||e.classList.add("darwin")},window.maximizeTrigger=()=>{const e=document.querySelector(".maximize");e&&!e.classList.contains("unmaximize")&&e.classList.add("unmaximize")},window.unmaximizeTrigger=()=>{const e=document.querySelector(".maximize");e&&e.classList.remove("unmaximize")},"darwin"===n.platform?window.onkeydown=e=>{"Escape"!==e.code?!e.metaKey||"KeyW"!==e.code&&"KeyQ"!==e.code||window.handle.close():t.send("detach:service",{type:"endFullScreen"})}:window.onkeydown=e=>{e.ctrlKey&&"KeyW"===e.code&&window.handle.close()},(e,t)=>{var i,p;return Object(c["f"])(),Object(c["c"])("div",{class:Object(c["e"])([Object(c["i"])(n).platform,"detach"])},[Object(c["d"])("div",o,[Object(c["d"])("img",{src:v.value.logo},null,8,a),r.value?(Object(c["f"])(),Object(c["c"])("input",{key:0,autofocus:"",onInput:t[0]||(t[0]=(...e)=>Object(c["i"])(b)&&Object(c["i"])(b)(...e)),value:null===(i=v.value.subInput)||void 0===i?void 0:i.value,placeholder:null===(p=v.value.subInput)||void 0===p?void 0:p.placeholder},null,40,l)):(Object(c["f"])(),Object(c["c"])("span",u,Object(c["h"])(v.value.pluginName),1))]),Object(c["d"])("div",s,[Object(c["d"])("div",{class:"handle"},[Object(c["d"])("div",{class:"devtool",onClick:f,title:"开发者工具"})]),"darwin"!==Object(c["i"])(n).platform?(Object(c["f"])(),Object(c["c"])("div",d,[Object(c["d"])("div",{class:"minimize",onClick:m}),Object(c["d"])("div",{class:"maximize",onClick:w}),Object(c["d"])("div",{class:"close",onClick:h})])):Object(c["b"])("",!0)])],2)}}};n("3480");const v=p;var b=v;n("4011");Object(c["a"])(b).mount("#app")}});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
.ant-menu-submenu-popup .ant-menu{background:var(--color-body-bg2)!important;height:100%;border-right:none}.ant-menu-submenu-popup .ant-menu .ant-menu-item,.ant-menu-submenu-popup .ant-menu .ant-menu-submenu,.ant-menu-submenu-popup .ant-menu .ant-menu-submenu-arrow{color:var(--color-text-content)}.ant-menu-submenu-popup .ant-menu .ant-menu-item:active,.ant-menu-submenu-popup .ant-menu .ant-menu-submenu-arrow:active,.ant-menu-submenu-popup .ant-menu .ant-menu-submenu:active{background:none}.ant-menu-submenu-popup .ant-menu .ant-menu-item-selected,.ant-menu-submenu-popup .ant-menu .ant-menu-submenu-selected{background-color:var(--color-list-hover);color:var(--ant-primary-color)}.ant-menu-submenu-popup .ant-menu .ant-menu-item-selected .ant-menu-submenu-arrow,.ant-menu-submenu-popup .ant-menu .ant-menu-submenu-selected .ant-menu-submenu-arrow{color:var(--ant-primary-color)}.ant-menu-submenu-popup .ant-menu .ant-menu-item-selected:after,.ant-menu-submenu-popup .ant-menu .ant-menu-submenu-selected:after{display:none}.left-menu[data-v-435a1273]{width:183px;border-right:1px solid var(--color-border-light)}.left-menu .search-container[data-v-435a1273]{padding:10px}.left-menu .ant-input-affix-wrapper[data-v-435a1273]{border:none;background:var(--color-input-hover)}.left-menu .ant-input-affix-wrapper[data-v-435a1273] input{background:none;color:var(--color-text-desc)}.left-menu .ant-input-affix-wrapper[data-v-435a1273] .anticon{color:var(--color-text-desc)}.left-menu[data-v-435a1273] .ant-menu{background:var(--color-menu-bg);height:100%;border-right:none}.left-menu[data-v-435a1273] .ant-menu .ant-menu-item,.left-menu[data-v-435a1273] .ant-menu .ant-menu-submenu,.left-menu[data-v-435a1273] .ant-menu .ant-menu-submenu-arrow{color:var(--color-text-content)}.left-menu[data-v-435a1273] .ant-menu .ant-menu-item:active,.left-menu[data-v-435a1273] .ant-menu .ant-menu-submenu-arrow:active,.left-menu[data-v-435a1273] .ant-menu .ant-menu-submenu:active{background:none}.left-menu[data-v-435a1273] .ant-menu .ant-menu-item-selected,.left-menu[data-v-435a1273] .ant-menu .ant-menu-submenu-selected{background-color:var(--color-list-hover);color:var(--ant-primary-color)}.left-menu[data-v-435a1273] .ant-menu .ant-menu-item-selected .ant-menu-submenu-arrow,.left-menu[data-v-435a1273] .ant-menu .ant-menu-submenu-selected .ant-menu-submenu-arrow{color:var(--ant-primary-color)}.left-menu[data-v-435a1273] .ant-menu .ant-menu-item-selected:after,.left-menu[data-v-435a1273] .ant-menu .ant-menu-submenu-selected:after{display:none}[data-v-435a1273]{margin:0;padding:0}.main-container[data-v-435a1273]{-webkit-app-region:no-drag;display:flex;background:var(--color-body-bg);border-top:1px solid var(--color-border-light);height:100vh;box-sizing:border-box;align-items:flex-start;width:100%;overflow:hidden;background:var(--color-menu-bg)}.main-container .search[data-v-435a1273] .ant-btn,.main-container .search[data-v-435a1273] .ant-input,.main-container .search[data-v-435a1273] .ant-input-group-addon{color:var(--ant-primary-color)!important;background:var(--color-input-hover);border-color:var(--color-border-light)}.main-container .container[data-v-435a1273],.main-container .more[data-v-435a1273]{background:var(--color-body-bg);width:calc(100% - 183px);height:100%;box-sizing:border-box;padding:16px;position:relative;overflow:auto}.main-container .more[data-v-435a1273]{background:var(--color-body-bg2)}.main-container .left-menu[data-v-435a1273]{padding:24px 16px;position:relative;height:100vh}.main-container .left-menu[data-v-435a1273] .ant-menu-item{padding-left:12px!important;display:flex;align-items:center}.main-container .left-menu[data-v-435a1273] .ant-menu-item-selected,.main-container .left-menu[data-v-435a1273] .ant-menu-submenu-selected{background-color:var(--color-list-hover);border-radius:6px;color:var(--ant-primary-color)}.main-container .left-menu[data-v-435a1273] .user-info{position:absolute;bottom:32px}.main-container .left-menu[data-v-435a1273] .ant-avatar{background:transparent}:root{--color-text-primary:rgba(0,0,0,0.85);--color-text-content:#141414;--color-text-desc:rgba(0,0,0,0.45);--color-body-bg2:#eee;--color-body-bg:#fff;--color-menu-bg:#f8f8f8;--color-list-hover:#e9e9e9;--color-input-hover:#fff;--color-border-light:#f0f0f0;--color-action-color:rgba(0,0,0,0.25)}.dark{--color-text-primary:#e8e8f0;--color-text-content:#ccccd8;--color-text-desc:#8f8fa6;--color-body-bg:#1c1c28;--color-body-bg2:#2c2f3b;--color-menu-bg:#1c1c28;--color-list-hover:#2c2f3b;--color-input-hover:rgba(68,68,68,0.8666666666666667);--color-border-light:rgba(68,68,68,0.8666666666666667);--color-action-color:hsla(0,0%,100%,0.30196078431372547)}

View File

@@ -0,0 +1 @@
.result{width:100%;overflow-x:hidden;box-sizing:border-box}.result .error-content{padding-top:40px}

View File

@@ -0,0 +1 @@
.worker{width:100%;overflow-x:hidden;box-sizing:border-box}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
.worker{width:100%;overflow-x:hidden;box-sizing:border-box}

View File

@@ -0,0 +1 @@
.ant-message{box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,.85);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:"tnum";position:fixed;top:8px;left:0;z-index:1010;width:100%;pointer-events:none}.ant-message-notice{padding:8px;text-align:center}.ant-message-notice-content{display:inline-block;padding:10px 16px;background:#fff;border-radius:2px;box-shadow:0 3px 6px -4px rgba(0,0,0,.12),0 6px 16px 0 rgba(0,0,0,.08),0 9px 28px 8px rgba(0,0,0,.05);pointer-events:all}.ant-message-success .anticon{color:#52c41a}.ant-message-error .anticon{color:#ff4d4f}.ant-message-warning .anticon{color:#faad14}.ant-message-info .anticon,.ant-message-loading .anticon{color:#1890ff}.ant-message .anticon{position:relative;top:1px;margin-right:8px;font-size:16px}.ant-message-notice.ant-move-up-leave.ant-move-up-leave-active{-webkit-animation-name:MessageMoveOut;animation-name:MessageMoveOut;-webkit-animation-duration:.3s;animation-duration:.3s}@-webkit-keyframes MessageMoveOut{0%{max-height:150px;padding:8px;opacity:1}to{max-height:0;padding:0;opacity:0}}@keyframes MessageMoveOut{0%{max-height:150px;padding:8px;opacity:1}to{max-height:0;padding:0;opacity:0}}.ant-message-rtl,.ant-message-rtl span{direction:rtl}.ant-message-rtl .anticon{margin-right:0;margin-left:8px}::-webkit-scrollbar{width:0}.panel-item{margin-bottom:17px}.panel-item .download-plugin-btn{color:var(--ant-primary-color)}.panel-item .title{margin-bottom:30px;color:var(--color-text-primary)}.panel-item .ellipse{display:inline-block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:100%;color:var(--color-text-content)}.panel-item .ellipse.desc{color:var(--color-text-desc)}.panel-item:after{content:" ";display:block;width:100%;height:1px;border-bottom:1px solid var(--color-border-light);transform:scaleY(.5)}.panel-item .ant-list-item{display:flex!important}.panel-item:last-child:after{border-bottom:none}.plugin-info{width:100%}.plugin-info .ant-drawer-content-wrapper{box-shadow:none!important}.plugin-info .ant-drawer-content-wrapper .ant-drawer-content{background:var(--color-body-bg)}.plugin-info .ant-drawer-content-wrapper .ant-drawer-header{background:var(--color-body-bg);border-bottom:1px solid var(--color-border-light)}.dark .plugin-title-info .back-icon{filter:invert(1) brightness(200%)}.plugin-title-info,.plugin-title-info .info{display:flex;align-items:flex-start;width:100%}.plugin-title-info .info .plugin-icon{width:40px;height:40px;margin-right:20px}.plugin-title-info .info .plugin-desc{flex:1;display:flex;align-items:center;justify-content:space-between}.plugin-title-info .info .plugin-desc .title{font-size:18px;font-weight:700;color:var(--color-text-primary)}.plugin-title-info .info .plugin-desc .desc{font-size:12px;font-weight:400;color:var(--color-text-desc)}.error-content.ant-result{padding:0}.home-page-container{min-height:200px}.home-page-container *{color:var(--color-text-content)}.home-page-container img{width:100%}

View File

@@ -0,0 +1 @@
.ant-message{box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,.85);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:"tnum";position:fixed;top:8px;left:0;z-index:1010;width:100%;pointer-events:none}.ant-message-notice{padding:8px;text-align:center}.ant-message-notice-content{display:inline-block;padding:10px 16px;background:#fff;border-radius:2px;box-shadow:0 3px 6px -4px rgba(0,0,0,.12),0 6px 16px 0 rgba(0,0,0,.08),0 9px 28px 8px rgba(0,0,0,.05);pointer-events:all}.ant-message-success .anticon{color:#52c41a}.ant-message-error .anticon{color:#ff4d4f}.ant-message-warning .anticon{color:#faad14}.ant-message-info .anticon,.ant-message-loading .anticon{color:#1890ff}.ant-message .anticon{position:relative;top:1px;margin-right:8px;font-size:16px}.ant-message-notice.ant-move-up-leave.ant-move-up-leave-active{-webkit-animation-name:MessageMoveOut;animation-name:MessageMoveOut;-webkit-animation-duration:.3s;animation-duration:.3s}@-webkit-keyframes MessageMoveOut{0%{max-height:150px;padding:8px;opacity:1}to{max-height:0;padding:0;opacity:0}}@keyframes MessageMoveOut{0%{max-height:150px;padding:8px;opacity:1}to{max-height:0;padding:0;opacity:0}}.ant-message-rtl,.ant-message-rtl span{direction:rtl}.ant-message-rtl .anticon{margin-right:0;margin-left:8px}.dev[data-v-2d26bea2]{box-sizing:border-box;width:100%;overflow-x:hidden;height:calc(100vh - 34px)}.dev .view-title[data-v-2d26bea2]{font-size:16px;font-weight:500;margin-bottom:16px;color:var(--color-text-primary)}.dev .view-container[data-v-2d26bea2]{padding:10px;box-sizing:border-box;border-radius:8px;background:var(--color-body-bg);overflow:auto;height:calc(100vh - 84px)}.dev[data-v-2d26bea2] label{color:var(--color-text-content)}.dev[data-v-2d26bea2] .ant-input{background:var(--color-input-hover)!important;color:var(--color-text-content)}

View File

@@ -0,0 +1 @@
.system{width:100%;overflow-x:hidden;box-sizing:border-box}

View File

@@ -0,0 +1 @@
.ant-message{box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,.85);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:"tnum";position:fixed;top:8px;left:0;z-index:1010;width:100%;pointer-events:none}.ant-message-notice{padding:8px;text-align:center}.ant-message-notice-content{display:inline-block;padding:10px 16px;background:#fff;border-radius:2px;box-shadow:0 3px 6px -4px rgba(0,0,0,.12),0 6px 16px 0 rgba(0,0,0,.08),0 9px 28px 8px rgba(0,0,0,.05);pointer-events:all}.ant-message-success .anticon{color:#52c41a}.ant-message-error .anticon{color:#ff4d4f}.ant-message-warning .anticon{color:#faad14}.ant-message-info .anticon,.ant-message-loading .anticon{color:#1890ff}.ant-message .anticon{position:relative;top:1px;margin-right:8px;font-size:16px}.ant-message-notice.ant-move-up-leave.ant-move-up-leave-active{-webkit-animation-name:MessageMoveOut;animation-name:MessageMoveOut;-webkit-animation-duration:.3s;animation-duration:.3s}@-webkit-keyframes MessageMoveOut{0%{max-height:150px;padding:8px;opacity:1}to{max-height:0;padding:0;opacity:0}}@keyframes MessageMoveOut{0%{max-height:150px;padding:8px;opacity:1}to{max-height:0;padding:0;opacity:0}}.ant-message-rtl,.ant-message-rtl span{direction:rtl}.ant-message-rtl .anticon{margin-right:0;margin-left:8px}.account[data-v-2bc021e6]{box-sizing:border-box;width:100%;overflow-x:hidden;background:var(--color-body-bg);height:calc(100vh - 46px)}.account[data-v-2bc021e6] .ant-result-title{color:var(--color-text-primary)}.account[data-v-2bc021e6] .ant-result-subtitle{color:var(--color-text-desc)}

View File

@@ -0,0 +1 @@
.ant-message{box-sizing:border-box;margin:0;padding:0;color:rgba(0,0,0,.85);font-size:14px;font-variant:tabular-nums;line-height:1.5715;list-style:none;font-feature-settings:"tnum";position:fixed;top:8px;left:0;z-index:1010;width:100%;pointer-events:none}.ant-message-notice{padding:8px;text-align:center}.ant-message-notice-content{display:inline-block;padding:10px 16px;background:#fff;border-radius:2px;box-shadow:0 3px 6px -4px rgba(0,0,0,.12),0 6px 16px 0 rgba(0,0,0,.08),0 9px 28px 8px rgba(0,0,0,.05);pointer-events:all}.ant-message-success .anticon{color:#52c41a}.ant-message-error .anticon{color:#ff4d4f}.ant-message-warning .anticon{color:#faad14}.ant-message-info .anticon,.ant-message-loading .anticon{color:#1890ff}.ant-message .anticon{position:relative;top:1px;margin-right:8px;font-size:16px}.ant-message-notice.ant-move-up-leave.ant-move-up-leave-active{-webkit-animation-name:MessageMoveOut;animation-name:MessageMoveOut;-webkit-animation-duration:.3s;animation-duration:.3s}@-webkit-keyframes MessageMoveOut{0%{max-height:150px;padding:8px;opacity:1}to{max-height:0;padding:0;opacity:0}}@keyframes MessageMoveOut{0%{max-height:150px;padding:8px;opacity:1}to{max-height:0;padding:0;opacity:0}}.ant-message-rtl,.ant-message-rtl span{direction:rtl}.ant-message-rtl .anticon{margin-right:0;margin-left:8px}.installed[data-v-1ed304de]{box-sizing:border-box;width:100%;overflow:hidden;height:calc(100vh - 34px)}.installed .view-title[data-v-1ed304de]{font-size:16px;font-weight:500;margin-bottom:16px;color:var(--color-text-primary)}.installed .view-container[data-v-1ed304de]{border-radius:8px;background:var(--color-body-bg);overflow:auto;height:calc(100vh - 84px)}.installed[data-v-1ed304de] .ant-result-title{color:var(--color-text-primary)}.installed[data-v-1ed304de] .ant-result-subtitle{color:var(--color-text-desc)}.installed .keyword-tag[data-v-1ed304de]{font-size:13px;margin:4px}.installed .container[data-v-1ed304de]{box-sizing:border-box;width:100%;overflow:hidden;background:#f3efef;height:100%;display:flex}.installed .installed-list[data-v-1ed304de]{width:38%;background:var(--color-body-bg);height:100%;padding:10px 0;border-right:1px solid var(--color-border-light);overflow:auto}.installed .installed-list .item[data-v-1ed304de]{padding:10px 20px;display:flex;align-items:center;color:var(--color-text-content);border-bottom:1px dashed var(--color-border-light);cursor:pointer}.installed .installed-list .item[data-v-1ed304de]:last-child{border-bottom:none}.installed .installed-list .item img[data-v-1ed304de]{width:34px;height:34px;margin-right:12px}.installed .installed-list .item .desc[data-v-1ed304de]{font-size:12px;color:var(--color-text-desc);display:-webkit-box;-webkit-box-orient:vertical;overflow:hidden;-webkit-line-clamp:2;text-overflow:ellipsis}.installed .installed-list .item.active[data-v-1ed304de]{color:var(--ant-primary-color);background:var(--color-list-hover)}.installed .plugin-detail[data-v-1ed304de]{padding:20px 20px 0 20px;box-sizing:border-box;width:62%;height:100%;background:var(--color-body-bg)}.installed .plugin-detail .plugin-top[data-v-1ed304de]{display:flex;align-items:flex-start;justify-content:space-between;border-bottom:1px solid #eee;padding-bottom:12px;margin-bottom:12px}.installed .plugin-detail .plugin-top .title[data-v-1ed304de]{font-size:16px;display:flex;align-items:center;color:var(--color-text-primary)}.installed .plugin-detail .plugin-top .title .ant-tag[data-v-1ed304de]{background:var(--color-input-hover);border:1px solid var(--color-border-light);color:var(--color-text-content);margin-left:8px}.installed .plugin-detail .plugin-top .desc[data-v-1ed304de]{font-size:13px;color:var(--color-text-desc)}.installed .plugin-detail .detail-container[data-v-1ed304de],.installed .plugin-detail .feature-container[data-v-1ed304de]{height:380px;overflow:auto;color:var(--color-text-content)}.installed .plugin-detail .detail-container img[data-v-1ed304de],.installed .plugin-detail .feature-container img[data-v-1ed304de]{width:100%}.installed .plugin-detail .desc-item[data-v-1ed304de]{padding:10px 0;color:var(--color-text-content)}.installed .plugin-detail .desc-item .ant-tag[data-v-1ed304de]{margin-top:6px}.installed .plugin-detail .desc-item .ant-tag.executable[data-v-1ed304de]{cursor:pointer;color:var(--ant-info-color)}.installed .plugin-detail .desc-item .ant-tag.executable[data-v-1ed304de]:hover{transform:translateY(-2px)}.installed .plugin-detail .desc-item .desc-title[data-v-1ed304de]{display:flex;align-items:center;justify-content:space-between}.installed .plugin-detail .desc-item .desc-info[data-v-1ed304de]{color:var(--color-text-desc)}

View File

@@ -0,0 +1 @@
:root{--vc-clr-primary:#000;--vc-clr-secondary:rgba(9,15,32,0.4980392156862745);--vc-clr-white:#fff;--vc-icn-width:1.2em;--vc-nav-width:30px;--vc-nav-height:30px;--vc-nav-border-radius:0;--vc-nav-color:var(--vc-clr-primary);--vc-nav-color-hover:var(--vc-clr-secondary);--vc-nav-background:transparent;--vc-pgn-width:12px;--vc-pgn-height:4px;--vc-pgn-margin:4px;--vc-pgn-border-radius:0;--vc-pgn-background-color:var(--vc-clr-secondary);--vc-pgn-active-color:var(--vc-clr-primary)}.carousel__next,.carousel__prev{background:var(--vc-nav-background);border-radius:var(--vc-nav-border-radius);width:var(--vc-nav-width);height:var(--vc-nav-height);text-align:center;font-size:var(--vc-nav-height);padding:0;color:var(--vc-nav-color);display:flex;justify-content:center;align-items:center;position:absolute;border:0;cursor:pointer;margin:0 10px;top:50%;transform:translateY(-50%)}.carousel__next:hover,.carousel__prev:hover{color:var(--vc-nav-color-hover)}.carousel__next--disabled,.carousel__prev--disabled{cursor:not-allowed;opacity:.5}.carousel__prev{left:0}.carousel__next{right:0}.carousel--rtl .carousel__prev{left:auto;right:0}.carousel--rtl .carousel__next{right:auto;left:0}.carousel{position:relative;text-align:center;box-sizing:border-box;touch-action:pan-y;-ms-scroll-chaining:none;overscroll-behavior:none}.carousel.is-dragging{touch-action:none}.carousel *{box-sizing:border-box}.carousel__track{display:flex;padding:0!important;position:relative}.carousel__viewport{overflow:hidden}.carousel__sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.carousel__icon{width:var(--vc-icn-width);height:var(--vc-icn-width);fill:currentColor}.carousel__pagination{display:flex;justify-content:center;list-style:none;line-height:0;margin:10px 0 0}.carousel__pagination-button{display:block;border:0;margin:0;cursor:pointer;padding:var(--vc-pgn-margin);background:transparent}.carousel__pagination-button:after{display:block;content:"";width:var(--vc-pgn-width);height:var(--vc-pgn-height);border-radius:var(--vc-pgn-border-radius);background-color:var(--vc-pgn-background-color)}.carousel__pagination-button--active:after,.carousel__pagination-button:hover:after{background-color:var(--vc-pgn-active-color)}.carousel__slide{scroll-snap-stop:auto;flex-shrink:0;margin:0;position:relative;display:flex;justify-content:center;align-items:center;transform:translateZ(0)}.finder{position:relative;width:100%;overflow-x:hidden;box-sizing:border-box}.finder::-webkit-scrollbar{width:0}.finder .ant-divider-horizontal{margin:17px 0}.carousel__item{cursor:pointer;min-height:180px;width:100%;background-color:var(--vc-clr-primary);color:var(--vc-clr-white);font-size:20px;border-radius:8px;display:flex;justify-content:center;align-items:center}.carousel__track{margin-bottom:0}.carousel__slide{padding-right:6px}.carousel__slide:last-child{padding-left:6px}.carousel__next,.carousel__prev{box-sizing:content-box;border:5px solid #fff}

View File

@@ -0,0 +1 @@
.system{width:100%;overflow-x:hidden;box-sizing:border-box}

View File

@@ -0,0 +1 @@
.system{width:100%;overflow-x:hidden;box-sizing:border-box}

View File

@@ -1 +1 @@
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>feature</title><link href="css/app.4e3502cb.css" rel="preload" as="style"><link href="css/chunk-vendors.7f9dcb72.css" rel="preload" as="style"><link href="js/app.5fe607e9.js" rel="preload" as="script"><link href="js/chunk-vendors.73a23bae.js" rel="preload" as="script"><link href="css/chunk-vendors.7f9dcb72.css" rel="stylesheet"><link href="css/app.4e3502cb.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but feature doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.73a23bae.js"></script><script src="js/app.5fe607e9.js"></script></body></html>
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>feature</title><link href="css/chunk-0add5e88.2f22e37d.css" rel="prefetch"><link href="css/chunk-111de227.2450c00b.css" rel="prefetch"><link href="css/chunk-197bc330.29812a6a.css" rel="prefetch"><link href="css/chunk-1af68a6e.2450c00b.css" rel="prefetch"><link href="css/chunk-3fb623ce.2b9b7de2.css" rel="prefetch"><link href="css/chunk-46496dac.da060b5a.css" rel="prefetch"><link href="css/chunk-596c6184.9be2495c.css" rel="prefetch"><link href="css/chunk-88e69aa8.69c3b24d.css" rel="prefetch"><link href="css/chunk-93f94cf8.0f63dd4a.css" rel="prefetch"><link href="css/chunk-a2b32e48.67429700.css" rel="prefetch"><link href="css/chunk-cf61e458.9be2495c.css" rel="prefetch"><link href="css/chunk-f69c766e.9be2495c.css" rel="prefetch"><link href="js/chunk-0add5e88.26781f59.js" rel="prefetch"><link href="js/chunk-111de227.86b2c5e3.js" rel="prefetch"><link href="js/chunk-197bc330.95c96fee.js" rel="prefetch"><link href="js/chunk-1af68a6e.2022b1a8.js" rel="prefetch"><link href="js/chunk-2d0c49e7.20196ed0.js" rel="prefetch"><link href="js/chunk-3fb623ce.ee432c33.js" rel="prefetch"><link href="js/chunk-46496dac.719cab20.js" rel="prefetch"><link href="js/chunk-596c6184.a1398c77.js" rel="prefetch"><link href="js/chunk-88e69aa8.55955c4d.js" rel="prefetch"><link href="js/chunk-93f94cf8.7dd5e910.js" rel="prefetch"><link href="js/chunk-a2b32e48.20d42be1.js" rel="prefetch"><link href="js/chunk-cf61e458.20835e3d.js" rel="prefetch"><link href="js/chunk-f69c766e.230d2fbd.js" rel="prefetch"><link href="css/app.bb291762.css" rel="preload" as="style"><link href="css/chunk-vendors.a52bdfa2.css" rel="preload" as="style"><link href="js/app.55a0112a.js" rel="preload" as="script"><link href="js/chunk-vendors.c7dcd677.js" rel="preload" as="script"><link href="css/chunk-vendors.a52bdfa2.css" rel="stylesheet"><link href="css/app.bb291762.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but feature doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.c7dcd677.js"></script><script src="js/app.55a0112a.js"></script></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-111de227"],{3271:function(e,t,n){},be50:function(e,t,n){"use strict";n.r(t);var c=n("c7eb"),o=n("1da1"),a=(n("d81d"),n("d3b7"),n("159b"),n("b0c0"),n("7a23")),r=n("0eaf"),u=n("be89"),s=n("5502"),l={class:"tools"},i={__name:"tools",setup:function(e){var t=Object(s["b"])(),n=Object(a["computed"])((function(){return t.state.totalPlugins})),i=Object(a["ref"])([]);Object(a["onBeforeMount"])(Object(o["a"])(Object(c["a"])().mark((function e(){return Object(c["a"])().wrap((function(e){while(1)switch(e.prev=e.next){case 0:return e.next=2,r["a"].getSearchDetail();case 2:i.value=e.sent;case 3:case"end":return e.stop()}}),e)}))));var b=Object(a["computed"])((function(){var e=i.value||[];return e.length?e.map((function(e){var t=null;return n.value.forEach((function(n){n.name===e&&(t=n)})),t})):[]}));return function(e,t){return Object(a["openBlock"])(),Object(a["createElementBlock"])("div",l,[Object(a["unref"])(b)&&Object(a["unref"])(b).length?(Object(a["openBlock"])(),Object(a["createBlock"])(u["a"],{key:0,onDownloadSuccess:e.downloadSuccess,title:e.$t("feature.market.searchTool"),list:Object(a["unref"])(b)},null,8,["onDownloadSuccess","title","list"])):Object(a["createCommentVNode"])("",!0)])}}};n("f1e9");const b=i;t["default"]=b},d81d:function(e,t,n){"use strict";var c=n("23e7"),o=n("b727").map,a=n("1dde"),r=a("map");c({target:"Array",proto:!0,forced:!r},{map:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}})},f1e9:function(e,t,n){"use strict";n("3271")}}]);

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-1af68a6e"],{5458:function(e,t,n){"use strict";n.r(t);var c=n("c7eb"),r=n("1da1"),a=(n("d81d"),n("d3b7"),n("159b"),n("b0c0"),n("7a23")),o=n("0eaf"),u=n("be89"),i=n("5502"),s={class:"worker"},b={__name:"worker",setup:function(e){var t=Object(i["b"])(),n=Object(a["computed"])((function(){return t.state.totalPlugins})),b=Object(a["ref"])([]);Object(a["onBeforeMount"])(Object(r["a"])(Object(c["a"])().mark((function e(){return Object(c["a"])().wrap((function(e){while(1)switch(e.prev=e.next){case 0:return e.next=2,o["a"].getWorkerDetail();case 2:b.value=e.sent;case 3:case"end":return e.stop()}}),e)}))));var f=Object(a["computed"])((function(){var e=b.value||[];return e.length?e.map((function(e){var t=null;return n.value.forEach((function(n){n.name===e&&(t=n)})),t})):[]}));return function(e,t){return Object(a["openBlock"])(),Object(a["createElementBlock"])("div",s,[Object(a["unref"])(f)&&Object(a["unref"])(f).length?(Object(a["openBlock"])(),Object(a["createBlock"])(u["a"],{key:0,onDownloadSuccess:e.downloadSuccess,title:e.$t("feature.market.efficiency"),list:Object(a["unref"])(f)},null,8,["onDownloadSuccess","title","list"])):Object(a["createCommentVNode"])("",!0)])}}};n("b63b");const f=b;t["default"]=f},"6a1f":function(e,t,n){},b63b:function(e,t,n){"use strict";n("6a1f")},d81d:function(e,t,n){"use strict";var c=n("23e7"),r=n("b727").map,a=n("1dde"),o=a("map");c({target:"Array",proto:!0,forced:!o},{map:function(e){return r(this,e,arguments.length>1?arguments[1]:void 0)}})}}]);

Some files were not shown because too many files have changed in this diff Show More