Compare commits
88 Commits
v4.1.0-bet
...
master
Author | SHA1 | Date | |
---|---|---|---|
|
a546bc0d59 | ||
|
c732e448c3 | ||
|
fbc7da0606 | ||
|
6315ec12ae | ||
|
3ba8250d7c | ||
|
706aa84374 | ||
|
f70bf3983e | ||
|
47359308fc | ||
|
3f03e5578e | ||
|
7cabbe26f5 | ||
|
5c048c6341 | ||
|
e90a30c8a4 | ||
|
599538db76 | ||
|
e9c41b6bdb | ||
|
1e7a8209b7 | ||
|
481cd44ab3 | ||
|
d41caa742b | ||
|
69218a728b | ||
|
73cef1512c | ||
|
986ad42ed7 | ||
|
42aec3403a | ||
|
8c15dba68d | ||
|
37647de7a8 | ||
|
1b2c9b3577 | ||
|
7cb832829d | ||
|
02da06c450 | ||
|
e613fc19d4 | ||
|
c7807aeb3f | ||
|
9813573679 | ||
|
61ec18f0dc | ||
|
5ca1ba1271 | ||
|
8c3186afef | ||
|
de0e9ed8f2 | ||
|
ef85084730 | ||
|
b4b7c81b60 | ||
|
4b79cce2f4 | ||
|
ae10dac5f7 | ||
|
1e0babe22d | ||
|
5ec18caa72 | ||
|
b7d8932291 | ||
|
5608a147f7 | ||
|
132fb94289 | ||
|
bb1a74b3b9 | ||
|
bf9da854c7 | ||
|
a2c5bcc90c | ||
|
b9f4333c01 | ||
|
bbeddb3fe6 | ||
|
4a2ca33e02 | ||
|
0578c7c7eb | ||
|
ef34452a4f | ||
|
286d9da8d1 | ||
|
6b9d5182bf | ||
|
2053491782 | ||
|
e128d01b81 | ||
|
c3bc0bdb9e | ||
|
f1f4e62177 | ||
|
c07d4bae55 | ||
|
c78dd9c4b6 | ||
|
2dd4ed10cc | ||
|
70ce3dd037 | ||
|
a0644c0ccf | ||
|
583e9934fa | ||
|
7e66b3f3e9 | ||
|
342f0f36a5 | ||
|
2a75e440ad | ||
|
11f53d1e07 | ||
|
beb8134539 | ||
|
d916525934 | ||
|
7d4ccb83a2 | ||
|
36c2a714b5 | ||
|
696c24657b | ||
|
f59069b2ec | ||
|
0c16139313 | ||
|
c99ec18151 | ||
|
dcea66e848 | ||
|
75e3111587 | ||
|
bd1757e068 | ||
|
2055bf61b1 | ||
|
6c096fcd99 | ||
|
1656418c10 | ||
|
f671b83b6a | ||
|
dfb8446cfd | ||
|
4e59294b16 | ||
|
562a13fdff | ||
|
9663232864 | ||
|
3f7285b177 | ||
|
e8c8f40bae | ||
|
472879f9b2 |
7
.github/workflows/main.yml
vendored
@ -23,10 +23,14 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [macos-11, 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
@ -1,6 +1,7 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/build
|
||||
build/*
|
||||
!build/icons
|
||||
|
||||
|
||||
# local env files
|
||||
|
2
.npmrc
@ -1 +1 @@
|
||||
electron_mirror=https://npm.taobao.org/mirrors/electron/
|
||||
electron_mirror=https://npmmirror.com/mirrors/electron/
|
||||
|
104
README.md
@ -1,46 +1,41 @@
|
||||
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>
|
||||
|
||||
An open-source toolbox based on Electron, freely integrating rich plugins to create the ultimate desktop productivity tool. Rubick is one of the heroes in Dota, whose core skill is the ability to use the skills of other heroes through plugins, and then move on. This aligns perfectly with the design philosophy of this tool, which is why it is 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)
|
||||
|
||||
## Docs
|
||||
|
||||
[Rubick website](https://rubick.vip)
|
||||
|
||||
[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.
|
||||
|
||||
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.
|
||||
@ -50,13 +45,6 @@ An open-source toolbox based on Electron, freely integrating rich plugins to cre
|
||||
- [x] Supports enterprise-level intranet deployment.
|
||||
- [x] Supports multiple languages.
|
||||
|
||||
## Docs
|
||||
|
||||
[Rubick website](https://rubick.vip)
|
||||
|
||||
[Rubick Docs](https://rubickCenter.github.io/rubick/)
|
||||
|
||||
|
||||
## Core functionality showcase.
|
||||
### 1. Search system application
|
||||
Support pinyin and abbreviations to search system applications:
|
||||
@ -81,17 +69,43 @@ In "Rubick," search for "Preferences," go to "Account and Settings," and then se
|
||||
|
||||

|
||||
|
||||
### 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.
|
||||
|
||||

|
||||
|
||||
<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="Featured|HelloGitHub" 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](https://github.com/rubickCenter/rubick/blob/master/LICENSE) file for details.
|
||||
|
@ -2,46 +2,42 @@
|
||||
|
||||
|
||||
<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)
|
||||
|
||||
## 使用文档
|
||||
|
||||
[Rubick 官网](https://rubick.vip)
|
||||
|
||||
[Rubick Docs](https://rubickCenter.github.io/rubick/)
|
||||
|
||||
## 如何使用 rubick
|
||||
|
||||
安装完成 rubick 后,可以通过快捷键 Alt/Option+R 可以快速呼起主程序。主程序输入框内输入关键词可以搜索出对应的 App、插件、文件... 选择即可使用。如果没有想要的功能,可以点击左侧的 logo 进入插件市场寻找自己想要的插件进行安装。
|
||||
|
||||
## 支持能力
|
||||
- [x] 基于 npm 包模式的插件管理,安装插件和安装 npm 包一样简单
|
||||
- [x] 支持 webdav 多端数据同步,真正的数据安全同步
|
||||
@ -50,12 +46,6 @@
|
||||
- [x] 支持企业化内网部署
|
||||
- [x] 支持多语言
|
||||
|
||||
## 使用文档
|
||||
|
||||
[Rubick 官网](https://rubick.vip)
|
||||
|
||||
[Rubick Docs](https://rubickCenter.github.io/rubick/)
|
||||
|
||||
|
||||
## 核心功能展示
|
||||
### 1. 搜索系统应用
|
||||
@ -81,18 +71,36 @@
|
||||
|
||||

|
||||
|
||||
### 更多功能
|
||||
如果您还需要更多功能,欢迎来这里给我们提建议:[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,帮助我们更好的成长:
|
||||
|
||||

|
||||
|
||||
## 贡献
|
||||
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.
|
||||
|
||||
|
@ -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 -
|
@ -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:
|
||||
|
@ -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: '帮助我们改善此页面!'
|
||||
}
|
||||
}
|
@ -1 +0,0 @@
|
||||
Subproject commit 7b52f0fb4a06d8036a35e125368cf2ddd67dbaa8
|
Before Width: | Height: | Size: 47 KiB |
@ -1,7 +0,0 @@
|
||||
$accentColor = #ff4ea4//默认主题颜色
|
||||
$codeBgColor = #282c34//默认背景颜色
|
||||
|
||||
//示例修改相关样式f12找到需要修改的地方找到对应class类拿过来直接用就行了
|
||||
.sidebar-group.is-sub-group > .sidebar-heading:not(.clickable){
|
||||
opacity :1
|
||||
}
|
@ -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
|
||||
---
|
@ -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"
|
||||
}]
|
||||
*/
|
||||
```
|
@ -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` 即可,如果插件需要调试,可以通过右上角 ... 来打开开发者工具进行调试,页面变更直接刷新即可:
|
||||
|
||||

|
||||
|
||||
|
||||
本小节所有代码:[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 后才能生效。
|
||||
|
||||

|
||||
|
||||
::: 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 了您的提交,插件将会自动上架。
|
||||
|
||||
|
@ -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 即可看到主搜索界面:
|
||||
|
||||

|
||||
|
||||
## 功能说明
|
||||
接下来详细介绍 rubick 所包含和支持的功能
|
||||
|
||||
### 1. 搜索系统应用
|
||||
支持拼音和缩写来搜索系统安装应用:
|
||||
|
||||

|
||||
|
||||
### 2. UI类插件安装
|
||||
点击搜索框右侧 `rubick` 图标,进入插件市场,选择所需插件,点击下载按钮即可下载,下载完成后在已安装 tab 下可以找到安装插件。
|
||||
安装完成后,输入插件呼起命令即可使用对应插件:
|
||||
|
||||

|
||||
|
||||
### 3. 系统类插件安装
|
||||
系统插件安装方式和UI类一样,在插件市场选择`系统分类`,寻找适合自己的系统插件安装即可。
|
||||
::: danger
|
||||
系统插件安装成功后,需要重启 `rubick` 才能生效
|
||||
:::
|
||||
|
||||
### 4. 输入框聚焦自动根据剪切板内容匹配插件
|
||||
在 `rubick` 内搜索`偏好设置`,然后开启`自动粘贴` 功能,即可匹配剪切板内容自动匹配适合插件进行使用。
|
||||
|
||||

|
||||
|
||||
### 内网部署
|
||||
::: tip
|
||||
如果把插件发布到公网 `npm` 如果不符合您的公司安全要求,`rubick` 支持内网私有源和私有插件库,如果您需要内网部署使用,可以自行配置以下规则。
|
||||
:::
|
||||
`rubick` 依赖 `npm` 仓库做插件管理,依赖 `gitcode` 做插件数据存储,所以如果要进行内网部署,主要需要替换这2个设置。详细设置:
|
||||
`插件市场 -> 设置 -> 内网部署设置`
|
||||
|
||||

|
||||
|
||||
#### 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) 。
|
||||
有价值的想法我们会加入到后期的开发当中。同时也欢迎一起加入共建。
|
||||
|
Before Width: | Height: | Size: 92 KiB |
@ -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.
|
@ -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 />
|
@ -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"
|
||||
}
|
||||
}
|
8688
docs/yarn.lock
@ -3,7 +3,7 @@
|
||||
"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",
|
||||
@ -18,7 +18,7 @@
|
||||
"code": "installed",
|
||||
"explain": "已安装插件",
|
||||
"cmds":[
|
||||
"已安装插件"
|
||||
"已安装插件", "installed"
|
||||
]
|
||||
},{
|
||||
"code": "settings",
|
||||
|
@ -8,37 +8,37 @@
|
||||
>
|
||||
<a-menu-item key="finder">
|
||||
<template #icon>
|
||||
<StarOutlined style="font-size: 18px;" />
|
||||
<StarOutlined style="font-size: 16px" />
|
||||
</template>
|
||||
{{ $t('feature.market.explore') }}
|
||||
</a-menu-item>
|
||||
<a-menu-item key="worker">
|
||||
<template #icon>
|
||||
<SendOutlined style="transform: rotate(-45deg); font-size: 18px;" />
|
||||
<SendOutlined style="transform: rotate(-45deg); font-size: 16px" />
|
||||
</template>
|
||||
{{ $t('feature.market.efficiency') }}
|
||||
</a-menu-item>
|
||||
<a-menu-item key="tools">
|
||||
<template #icon>
|
||||
<SearchOutlined style="font-size: 18px;" />
|
||||
<SearchOutlined style="font-size: 16px" />
|
||||
</template>
|
||||
{{ $t('feature.market.searchTool') }}
|
||||
</a-menu-item>
|
||||
<a-menu-item key="image">
|
||||
<template #icon>
|
||||
<FileImageOutlined style="font-size: 18px;" />
|
||||
<FileImageOutlined style="font-size: 16px" />
|
||||
</template>
|
||||
{{ $t('feature.market.imageTool') }}
|
||||
</a-menu-item>
|
||||
<a-menu-item key="devPlugin">
|
||||
<template #icon>
|
||||
<CodeOutlined style="font-size: 18px;" />
|
||||
<CodeOutlined style="font-size: 16px" />
|
||||
</template>
|
||||
{{ $t('feature.market.developTool') }}
|
||||
</a-menu-item>
|
||||
<a-menu-item key="system">
|
||||
<template #icon>
|
||||
<DatabaseOutlined style="font-size: 18px;" />
|
||||
<DatabaseOutlined style="font-size: 16px" />
|
||||
</template>
|
||||
{{ $t('feature.market.systemTool') }}
|
||||
</a-menu-item>
|
||||
@ -72,7 +72,21 @@
|
||||
</a-sub-menu>
|
||||
</a-menu>
|
||||
</div>
|
||||
<div :class="['finder', 'result', 'devPlugin', 'image', 'tools', 'worker', 'system'].includes(active[0]) ? 'container' : 'more'">
|
||||
<div
|
||||
:class="
|
||||
[
|
||||
'finder',
|
||||
'result',
|
||||
'devPlugin',
|
||||
'image',
|
||||
'tools',
|
||||
'worker',
|
||||
'system',
|
||||
].includes(active[0])
|
||||
? 'container'
|
||||
: 'more'
|
||||
"
|
||||
>
|
||||
<keep-alive>
|
||||
<router-view />
|
||||
</keep-alive>
|
||||
@ -103,13 +117,14 @@ const active = computed(() => store.state.active);
|
||||
const { perf } = localConfig.getConfig();
|
||||
|
||||
const changeMenu = (key: any) => {
|
||||
store.commit('commonUpdate', {active: [key]})
|
||||
store.commit('commonUpdate', { active: [key] });
|
||||
router.push(key);
|
||||
};
|
||||
|
||||
window.rubick.onPluginEnter(({ code }: { code: string }) => {
|
||||
code = code === '已安装插件' ? 'installed' : code;
|
||||
changeMenu(code);
|
||||
store.commit('commonUpdate', {active: [code]})
|
||||
store.commit('commonUpdate', { active: [code] });
|
||||
});
|
||||
|
||||
window.rubick.setSubInput((e: any) => {
|
||||
@ -128,7 +143,7 @@ window.rubick.setSubInput((e: any) => {
|
||||
store.commit('setSearchValue', e.text);
|
||||
router.push('result');
|
||||
} else {
|
||||
store.commit('commonUpdate', {active: ['finder']})
|
||||
store.commit('commonUpdate', { active: ['finder'] });
|
||||
router.push('finder');
|
||||
}
|
||||
}
|
||||
@ -143,13 +158,16 @@ init();
|
||||
background: var(--color-body-bg2) !important;
|
||||
height: 100%;
|
||||
border-right: none;
|
||||
.ant-menu-item, .ant-menu-submenu, .ant-menu-submenu-arrow {
|
||||
.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 {
|
||||
.ant-menu-item-selected,
|
||||
.ant-menu-submenu-selected {
|
||||
background-color: var(--color-list-hover);
|
||||
color: var(--ant-primary-color);
|
||||
.ant-menu-submenu-arrow {
|
||||
@ -202,9 +220,12 @@ init();
|
||||
background: var(--color-body-bg2);
|
||||
}
|
||||
.left-menu {
|
||||
padding: 24px 16px;
|
||||
padding: 16px;
|
||||
position: relative;
|
||||
height: 100vh;
|
||||
:deep(.ant-menu) {
|
||||
width: 100%;
|
||||
}
|
||||
:deep(.ant-menu-item) {
|
||||
padding-left: 12px !important;
|
||||
display: flex;
|
||||
@ -218,7 +239,14 @@ init();
|
||||
}
|
||||
:deep(.user-info) {
|
||||
position: absolute;
|
||||
bottom: 32px;
|
||||
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;
|
||||
|
@ -1,8 +1,3 @@
|
||||
@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;
|
||||
|
BIN
feature/src/assets/delete.png
Normal file
After Width: | Height: | Size: 845 B |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 17 KiB |
@ -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 {
|
||||
@ -14,7 +14,7 @@ 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 {
|
||||
@ -23,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;
|
||||
},
|
||||
|
||||
@ -34,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;
|
||||
@ -45,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;
|
||||
@ -55,7 +56,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;
|
||||
@ -71,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;
|
||||
@ -81,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;
|
||||
@ -91,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;
|
||||
|
@ -67,6 +67,7 @@ export default {
|
||||
changeLang: 'Change Language',
|
||||
cn: '简体中文',
|
||||
en: 'English',
|
||||
history: 'keywords search history',
|
||||
},
|
||||
global: {
|
||||
title: 'Global Shortcut Key',
|
||||
|
@ -65,6 +65,7 @@ export default {
|
||||
changeLang: '切换语言',
|
||||
cn: '简体中文',
|
||||
en: 'English',
|
||||
history: '关键词搜索记录',
|
||||
},
|
||||
global: {
|
||||
title: '全局快捷键',
|
||||
|
@ -33,6 +33,12 @@ 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 || {},
|
||||
});
|
||||
|
@ -185,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 }) => {
|
||||
@ -195,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) => {
|
||||
|
@ -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"
|
||||
@ -105,7 +105,7 @@ import {
|
||||
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';
|
||||
@ -121,7 +121,7 @@ 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: () => [],
|
||||
@ -137,13 +137,14 @@ const downloadPlugin = async (plugin) => {
|
||||
};
|
||||
|
||||
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 = '暂无内容';
|
||||
try {
|
||||
@ -156,6 +157,8 @@ const showDetail = async (item) => {
|
||||
}
|
||||
};
|
||||
|
||||
const detail = computed(() => props.list[showIndex.value]);
|
||||
|
||||
const openPlugin = (item) => {
|
||||
store.commit('commonUpdate', {active: ['installed']})
|
||||
router.push({
|
||||
|
@ -31,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;
|
||||
|
@ -119,6 +119,16 @@
|
||||
: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>
|
||||
@ -264,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']);
|
||||
@ -283,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,
|
||||
})
|
||||
@ -303,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 {
|
||||
// 不做处理
|
||||
|
@ -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: '',
|
||||
};
|
||||
};
|
||||
|
@ -64,6 +64,8 @@ const theme = ref(perf.custom.theme);
|
||||
state.custom = perf.custom || {};
|
||||
|
||||
const setConfig = debounce(() => {
|
||||
const { perf } = localConfig.getConfig();
|
||||
|
||||
localConfig.setConfig(
|
||||
JSON.parse(
|
||||
JSON.stringify({
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "rubick",
|
||||
"version": "4.1.0-beta.2",
|
||||
"version": "4.3.5",
|
||||
"author": "muwoo <2424880409@qq.com>",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
@ -30,7 +30,7 @@
|
||||
"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",
|
||||
@ -39,6 +39,7 @@
|
||||
"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",
|
||||
@ -46,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",
|
||||
@ -60,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",
|
||||
|
1
public/feature/css/app.bb291762.css
Normal 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)}
|
1
public/feature/css/chunk-197bc330.29812a6a.css
Normal file
@ -1 +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-6fb0031c]{box-sizing:border-box;width:100%;overflow-x:hidden;height:calc(100vh - 34px)}.dev .view-title[data-v-6fb0031c]{font-size:16px;font-weight:500;margin-bottom:16px;color:var(--color-text-primary)}.dev .view-container[data-v-6fb0031c]{padding:10px;box-sizing:border-box;border-radius:8px;background:var(--color-body-bg);overflow:auto;height:calc(100vh - 84px)}.dev[data-v-6fb0031c] label{color:var(--color-text-content)}.dev[data-v-6fb0031c] .ant-input{background:var(--color-input-hover);color:var(--color-text-content)}
|
||||
.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)}
|
@ -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/chunk-0add5e88.2f22e37d.css" rel="prefetch"><link href="css/chunk-111de227.2450c00b.css" rel="prefetch"><link href="css/chunk-1af68a6e.2450c00b.css" rel="prefetch"><link href="css/chunk-1e4a75e5.ba6f3d8b.css" rel="prefetch"><link href="css/chunk-3fb623ce.2b9b7de2.css" rel="prefetch"><link href="css/chunk-596c6184.9be2495c.css" rel="prefetch"><link href="css/chunk-5cf3b9db.e273616c.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-1af68a6e.2022b1a8.js" rel="prefetch"><link href="js/chunk-1e4a75e5.e9c5b1d4.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-596c6184.a1398c77.js" rel="prefetch"><link href="js/chunk-5cf3b9db.d5ee71ed.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.4abdfe3a.css" rel="preload" as="style"><link href="css/chunk-vendors.a52bdfa2.css" rel="preload" as="style"><link href="js/app.313735e9.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.4abdfe3a.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.313735e9.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>
|
1
public/feature/js/app.55a0112a.js
Normal file
1
public/feature/js/chunk-197bc330.95c96fee.js
Normal file
1
public/feature/js/chunk-46496dac.719cab20.js
Normal file
@ -0,0 +1 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-46496dac"],{"2b1c":function(e,t,n){"use strict";n("dc36")},"44e73":function(e,t,n){"use strict";n.r(t);var a=n("c7eb"),c=(n("c346"),n("e63d")),r=n.n(c),o=n("1da1"),u=(n("b0c0"),n("7a23")),i=n("47e2"),l={class:"dev"},s={class:"view-title"},d={class:"view-container"},f={__name:"index",setup:function(e){var t=Object(i["b"])(),n=t.t,c=Object(u["ref"])(),f=Object(u["reactive"])({name:void 0}),b={name:{required:!0,message:"Please input name"}},m=function(){c.value.validate().then((function(){v(f.name)}))},p=Object(u["ref"])(!1),v=function(){var e=Object(o["a"])(Object(a["a"])().mark((function e(t){return Object(a["a"])().wrap((function(e){while(1)switch(e.prev=e.next){case 0:return p.value=!0,e.next=3,window.market.downloadPlugin({name:t,isDev:!0});case 3:r.a.success(n("feature.dev.installSuccess",{pluginName:t})),p.value=!1;case 5:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),j=function(){c.value.validate().then((function(){window.market.refreshPlugin({name:f.name}),r.a.success(n("feature.dev.refreshSuccess",{pluginName:f.name}))}))},O={span:4},w={span:14};return function(e,t){var n=Object(u["resolveComponent"])("a-alert"),a=Object(u["resolveComponent"])("a-input"),r=Object(u["resolveComponent"])("a-form-item"),o=Object(u["resolveComponent"])("a-button"),i=Object(u["resolveComponent"])("a-form");return Object(u["openBlock"])(),Object(u["createElementBlock"])("div",l,[Object(u["createElementVNode"])("div",s,Object(u["toDisplayString"])(e.$t("feature.dev.title")),1),Object(u["createElementVNode"])("div",d,[Object(u["createVNode"])(n,{style:{"margin-bottom":"40px"},message:e.$t("feature.dev.tips"),type:"warning"},null,8,["message"]),Object(u["createVNode"])(i,{ref_key:"formRef",ref:c,model:f,rules:b,"label-col":O,"wrapper-col":w},{default:Object(u["withCtx"])((function(){return[Object(u["createVNode"])(r,{label:e.$t("feature.dev.pluginName"),name:"name"},{default:Object(u["withCtx"])((function(){return[Object(u["createVNode"])(a,{value:f.name,"onUpdate:value":t[0]||(t[0]=function(e){return f.name=e})},null,8,["value"])]})),_:1},8,["label"]),Object(u["createVNode"])(r,{"wrapper-col":{span:14,offset:4}},{default:Object(u["withCtx"])((function(){return[Object(u["createVNode"])(o,{loading:p.value,type:"primary",onClick:m},{default:Object(u["withCtx"])((function(){return[Object(u["createTextVNode"])(Object(u["toDisplayString"])(e.$t("feature.dev.install")),1)]})),_:1},8,["loading"]),Object(u["createVNode"])(o,{onClick:j,style:{"margin-left":"10px"}},{default:Object(u["withCtx"])((function(){return[Object(u["createTextVNode"])(Object(u["toDisplayString"])(e.$t("feature.dev.refreshPlugins")),1)]})),_:1})]})),_:1})]})),_:1},8,["model"])])])}}},b=(n("2b1c"),n("6b0d")),m=n.n(b);const p=m()(f,[["__scopeId","data-v-2d26bea2"]]);t["default"]=p},a479:function(e,t,n){},c346:function(e,t,n){"use strict";n("fe5b"),n("a479")},dc36:function(e,t,n){}}]);
|
@ -1 +0,0 @@
|
||||
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["chunk-5cf3b9db"],{"44e73":function(e,t,n){"use strict";n.r(t);var a=n("c7eb"),c=(n("c346"),n("e63d")),r=n.n(c),o=n("1da1"),u=(n("b0c0"),n("7a23")),i=n("47e2"),l={class:"dev"},s={class:"view-title"},f={class:"view-container"},d={__name:"index",setup:function(e){var t=Object(i["b"])(),n=t.t,c=Object(u["ref"])(),d=Object(u["reactive"])({name:void 0}),b={name:{required:!0,message:"Please input name"}},m=function(){c.value.validate().then((function(){v(d.name)}))},p=Object(u["ref"])(!1),v=function(){var e=Object(o["a"])(Object(a["a"])().mark((function e(t){return Object(a["a"])().wrap((function(e){while(1)switch(e.prev=e.next){case 0:return p.value=!0,e.next=3,window.market.downloadPlugin({name:t,isDev:!0});case 3:r.a.success(n("feature.dev.installSuccess",{pluginName:t})),p.value=!1;case 5:case"end":return e.stop()}}),e)})));return function(t){return e.apply(this,arguments)}}(),j=function(){c.value.validate().then((function(){window.market.refreshPlugin({name:d.name}),r.a.success(n("feature.dev.refreshSuccess",{pluginName:d.name}))}))},O={span:4},w={span:14};return function(e,t){var n=Object(u["resolveComponent"])("a-alert"),a=Object(u["resolveComponent"])("a-input"),r=Object(u["resolveComponent"])("a-form-item"),o=Object(u["resolveComponent"])("a-button"),i=Object(u["resolveComponent"])("a-form");return Object(u["openBlock"])(),Object(u["createElementBlock"])("div",l,[Object(u["createElementVNode"])("div",s,Object(u["toDisplayString"])(e.$t("feature.dev.title")),1),Object(u["createElementVNode"])("div",f,[Object(u["createVNode"])(n,{style:{"margin-bottom":"40px"},message:e.$t("feature.dev.tips"),type:"warning"},null,8,["message"]),Object(u["createVNode"])(i,{ref_key:"formRef",ref:c,model:d,rules:b,"label-col":O,"wrapper-col":w},{default:Object(u["withCtx"])((function(){return[Object(u["createVNode"])(r,{label:e.$t("feature.dev.pluginName"),name:"name"},{default:Object(u["withCtx"])((function(){return[Object(u["createVNode"])(a,{value:d.name,"onUpdate:value":t[0]||(t[0]=function(e){return d.name=e})},null,8,["value"])]})),_:1},8,["label"]),Object(u["createVNode"])(r,{"wrapper-col":{span:14,offset:4}},{default:Object(u["withCtx"])((function(){return[Object(u["createVNode"])(o,{loading:p.value,type:"primary",onClick:m},{default:Object(u["withCtx"])((function(){return[Object(u["createTextVNode"])(Object(u["toDisplayString"])(e.$t("feature.dev.install")),1)]})),_:1},8,["loading"]),Object(u["createVNode"])(o,{onClick:j,style:{"margin-left":"10px"}},{default:Object(u["withCtx"])((function(){return[Object(u["createTextVNode"])(Object(u["toDisplayString"])(e.$t("feature.dev.refreshPlugins")),1)]})),_:1})]})),_:1})]})),_:1},8,["model"])])])}}},b=(n("ef18"),n("6b0d")),m=n.n(b);const p=m()(d,[["__scopeId","data-v-6fb0031c"]]);t["default"]=p},a479:function(e,t,n){},c346:function(e,t,n){"use strict";n("fe5b"),n("a479")},ef18:function(e,t,n){"use strict";n("f44a")},f44a:function(e,t,n){}}]);
|
@ -3,7 +3,7 @@
|
||||
"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",
|
||||
@ -18,7 +18,7 @@
|
||||
"code": "installed",
|
||||
"explain": "已安装插件",
|
||||
"cmds":[
|
||||
"已安装插件"
|
||||
"已安装插件", "installed"
|
||||
]
|
||||
},{
|
||||
"code": "settings",
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 131 KiB |
BIN
public/icons/delete@2x.png
Normal file
After Width: | Height: | Size: 845 B |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 3.2 KiB |
BIN
public/icons/iconTemplate@2x.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
public/icons/pin@2x.png
Normal file
After Width: | Height: | Size: 830 B |
BIN
public/icons/shield@2x.png
Normal file
After Width: | Height: | Size: 828 B |
BIN
public/icons/unpin@2x.png
Normal file
After Width: | Height: | Size: 747 B |
BIN
public/logo.png
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 131 KiB |
@ -5,7 +5,7 @@ const path = require('path');
|
||||
|
||||
const appPath = app.getPath('userData');
|
||||
|
||||
const baseDir = path.join(appPath, './rubick-plugins');
|
||||
const baseDir = path.join(appPath, './rubick-plugins-new');
|
||||
|
||||
const ipcSendSync = (type, data) => {
|
||||
const returnValue = ipcRenderer.sendSync('msg-trigger', {
|
||||
@ -49,6 +49,10 @@ window.rubick = {
|
||||
showOpenDialog(options) {
|
||||
return ipcSendSync('showOpenDialog', options);
|
||||
},
|
||||
showSaveDialog(options) {
|
||||
return ipcSendSync('showSaveDialog', options);
|
||||
},
|
||||
|
||||
setExpendHeight(height) {
|
||||
ipcSendSync('setExpendHeight', height);
|
||||
},
|
||||
|
9
release.js
Normal file
@ -0,0 +1,9 @@
|
||||
exports.default = async function () {
|
||||
const fs = require('fs');
|
||||
const compressing = require('compressing');
|
||||
|
||||
const src = './build/mac/rubick.app/Contents/Resources/app.asar';
|
||||
if (fs.existsSync(src)) {
|
||||
await compressing.gzip.compressFile(src, 'build/app.asar.gz');
|
||||
}
|
||||
};
|
@ -1,5 +1,6 @@
|
||||
export const WINDOW_WIDTH = 688;
|
||||
export const WINDOW_WIDTH = 800;
|
||||
export const WINDOW_HEIGHT = 60;
|
||||
export const WINDOW_PLUGIN_HEIGHT = 600;
|
||||
|
||||
export const GUIDE_WIDTH = 800;
|
||||
export const GUIDE_HEIGHT = 600;
|
||||
|
@ -1,5 +1,5 @@
|
||||
export default {
|
||||
version: 4,
|
||||
version: 7,
|
||||
perf: {
|
||||
custom: {
|
||||
theme: 'SPRING',
|
||||
@ -25,6 +25,7 @@ export default {
|
||||
autoPast: false,
|
||||
darkMode: false,
|
||||
guide: false,
|
||||
history: true,
|
||||
lang: 'zh-CN',
|
||||
},
|
||||
local: {
|
||||
|
@ -4,5 +4,6 @@ import path from 'path';
|
||||
const appPath = app.getPath('userData');
|
||||
|
||||
const PLUGIN_INSTALL_DIR = path.join(appPath, './rubick-plugins-new');
|
||||
const PLUGIN_HISTORY = 'rubick-plugin-history';
|
||||
|
||||
export { PLUGIN_INSTALL_DIR };
|
||||
export { PLUGIN_INSTALL_DIR, PLUGIN_HISTORY };
|
||||
|
@ -9,7 +9,8 @@ const useDrag = () => {
|
||||
let draggable = true;
|
||||
|
||||
const onMouseDown = (e) => {
|
||||
// if (commonConst.macOS()) return;
|
||||
// 右击不移动
|
||||
if (e.button === 2) return;
|
||||
draggable = true;
|
||||
mouseX = e.clientX;
|
||||
mouseY = e.clientY;
|
||||
|
@ -1,6 +1,6 @@
|
||||
const WINDOW_MAX_HEIGHT = 600;
|
||||
const WINDOW_MAX_HEIGHT = 620;
|
||||
const WINDOW_MIN_HEIGHT = 60;
|
||||
const PRE_ITEM_HEIGHT = 60;
|
||||
const PRE_ITEM_HEIGHT = 70;
|
||||
const HISTORY_HEIGHT = 70;
|
||||
|
||||
export default (searchList: Array<any>, historyList): number => {
|
||||
|
@ -32,63 +32,6 @@ const getIconFile = (appFileInput) => {
|
||||
});
|
||||
};
|
||||
|
||||
// const sortIcons = (icons) => {
|
||||
// const aWins = -1;
|
||||
// const bWins = 1;
|
||||
// const catWins = 0;
|
||||
// return icons.sort((a, b) => {
|
||||
// const aSize = parseInt(a.match(/(\d+)x\1/)[1], 10);
|
||||
// const bSize = parseInt(b.match(/(\d+)x\1/)[1], 10);
|
||||
// if (aSize === bSize) {
|
||||
// if (a.indexOf('@2x') > -1) return aWins;
|
||||
// if (b.indexOf('@2x') > -1) return bWins;
|
||||
// return catWins;
|
||||
// }
|
||||
// if (aSize > bSize) return aWins;
|
||||
// if (aSize < bSize) return bWins;
|
||||
// return catWins;
|
||||
// });
|
||||
// };
|
||||
|
||||
// const icnsToPng = (iconFile, pngFileOutput) => {
|
||||
// const outputDir = pngFileOutput.split('.')[0] + '.iconset'
|
||||
// return new Promise((resolve, reject) => {
|
||||
// exec(`iconutil --convert iconset '${iconFile}' --output '${outputDir}'`, (error) => {
|
||||
// if (error) return reject(error)
|
||||
// fs.readdir(outputDir, (error, files) => {
|
||||
// if (error) {
|
||||
// return resolve(tiffToPng(iconFile, pngFileOutput))
|
||||
// }
|
||||
// const realIcons = files.map((file) => {
|
||||
// return path.join(outputDir, file)
|
||||
// })
|
||||
// const biggestIcon = sortIcons(realIcons).find(Boolean)
|
||||
// fs.rename(biggestIcon, pngFileOutput, (error) => {
|
||||
// error ? reject(error) : resolve(realIcons.filter((file) => {
|
||||
// return file !== biggestIcon
|
||||
// }))
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// }).then((files) => {
|
||||
// // Cleanup temp icons
|
||||
// return Promise.all(files.map((file) => {
|
||||
// return new Promise((resolve, reject) => {
|
||||
// fs.unlink(file, (error) => {
|
||||
// error ? reject(error) : resolve()
|
||||
// })
|
||||
// })
|
||||
// }))
|
||||
// }).then(() => {
|
||||
// // Cleanup temp directory
|
||||
// return new Promise((resolve, reject) => {
|
||||
// fs.rmdir(outputDir, (error) => {
|
||||
// error ? reject(error) : resolve()
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// }
|
||||
|
||||
const tiffToPng = (iconFile, pngFileOutput) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(
|
||||
|
@ -1,23 +1,23 @@
|
||||
import { spawn } from "child_process";
|
||||
import plist from "plist";
|
||||
import { spawn } from 'child_process';
|
||||
import plist from 'plist';
|
||||
|
||||
export default function getApps(resolve, reject, filterByAppName = false) {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
let resultBuffer = new Buffer.from([]);
|
||||
|
||||
const profileInstalledApps = spawn("/usr/sbin/system_profiler", [
|
||||
"-xml",
|
||||
"-detailLevel",
|
||||
"mini",
|
||||
"SPApplicationsDataType",
|
||||
const profileInstalledApps = spawn('/usr/sbin/system_profiler', [
|
||||
'-xml',
|
||||
'-detailLevel',
|
||||
'mini',
|
||||
'SPApplicationsDataType',
|
||||
]);
|
||||
|
||||
profileInstalledApps.stdout.on("data", (chunckBuffer) => {
|
||||
profileInstalledApps.stdout.on('data', (chunckBuffer) => {
|
||||
resultBuffer = Buffer.concat([resultBuffer, chunckBuffer]);
|
||||
});
|
||||
|
||||
profileInstalledApps.on("exit", (exitCode) => {
|
||||
profileInstalledApps.on('exit', (exitCode) => {
|
||||
if (exitCode !== 0) {
|
||||
reject([]);
|
||||
return;
|
||||
@ -37,7 +37,7 @@ export default function getApps(resolve, reject, filterByAppName = false) {
|
||||
}
|
||||
});
|
||||
|
||||
profileInstalledApps.on("error", (err) => {
|
||||
profileInstalledApps.on('error', (err) => {
|
||||
reject(err);
|
||||
});
|
||||
}
|
||||
|
@ -1,12 +1,8 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import os from 'os';
|
||||
import translate from './translate';
|
||||
import { shell } from 'electron';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const fileIcon = require('extract-file-icon');
|
||||
|
||||
const filePath = path.resolve(
|
||||
'C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs'
|
||||
);
|
||||
@ -29,6 +25,8 @@ if (!exists) {
|
||||
|
||||
const getico = (app) => {
|
||||
try {
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const fileIcon = require('extract-file-icon');
|
||||
const buffer = fileIcon(app.desc, 32);
|
||||
const iconpath = path.join(icondir, `${app.name}.png`);
|
||||
|
||||
|
@ -7,11 +7,10 @@ import path from 'path';
|
||||
import got from 'got';
|
||||
import fixPath from 'fix-path';
|
||||
|
||||
import spawn from 'cross-spawn';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import axios from 'axios';
|
||||
|
||||
import npm from 'npm';
|
||||
|
||||
fixPath();
|
||||
|
||||
/**
|
||||
@ -42,7 +41,7 @@ class AdapterHandler {
|
||||
}
|
||||
this.baseDir = options.baseDir;
|
||||
|
||||
let register = options.registry || 'https://registry.npmmirror.com/';
|
||||
let register = options.registry || 'https://registry.npmmirror.com';
|
||||
|
||||
try {
|
||||
const dbdata = ipcRenderer.sendSync('msg-trigger', {
|
||||
@ -61,7 +60,7 @@ class AdapterHandler {
|
||||
const packageJSON = JSON.parse(
|
||||
fs.readFileSync(`${this.baseDir}/package.json`, 'utf-8')
|
||||
);
|
||||
const registryUrl = `https://registry.npm.taobao.org/${name}`;
|
||||
const registryUrl = `https://registry.npmmirror.com/${name}`;
|
||||
|
||||
// 从npm源中获取依赖包的最新版本
|
||||
try {
|
||||
@ -158,67 +157,44 @@ class AdapterHandler {
|
||||
*/
|
||||
private async execCommand(cmd: string, modules: string[]): Promise<string> {
|
||||
return new Promise((resolve: any, reject: any) => {
|
||||
const module =
|
||||
let args: string[] = [cmd].concat(
|
||||
cmd !== 'uninstall' && cmd !== 'link'
|
||||
? modules.map((m) => `${m}@latest`)
|
||||
: modules;
|
||||
const config: any = {
|
||||
prefix: this.baseDir,
|
||||
save: true,
|
||||
cache: path.join(this.baseDir, 'cache'),
|
||||
};
|
||||
: modules
|
||||
);
|
||||
if (cmd !== 'link') {
|
||||
config.registry = this.registry;
|
||||
args = args
|
||||
.concat('--color=always')
|
||||
.concat('--save')
|
||||
.concat(`--registry=${this.registry}`);
|
||||
}
|
||||
npm.load(config, function (err) {
|
||||
npm.commands[cmd](module, function (er, data) {
|
||||
if (!err) {
|
||||
console.log(data);
|
||||
resolve({ code: -1, data });
|
||||
} else {
|
||||
reject({ code: -1, data: err });
|
||||
}
|
||||
});
|
||||
|
||||
npm.on('log', function (message) {
|
||||
// log installation progress
|
||||
console.log(message);
|
||||
});
|
||||
const npm = spawn('npm', args, {
|
||||
cwd: this.baseDir,
|
||||
});
|
||||
|
||||
// if (cmd !== 'link') {
|
||||
// args = args
|
||||
// .concat('--color=always')
|
||||
// .concat('--save')
|
||||
// .concat(`--registry=${this.registry}`);
|
||||
// }
|
||||
console.log(args);
|
||||
|
||||
// const npm = spawn('npm', args, {
|
||||
// cwd: this.baseDir,
|
||||
// });
|
||||
//
|
||||
// console.log(args);
|
||||
//
|
||||
// let output = '';
|
||||
// npm.stdout
|
||||
// .on('data', (data: string) => {
|
||||
// output += data; // 获取输出日志
|
||||
// })
|
||||
// .pipe(process.stdout);
|
||||
//
|
||||
// npm.stderr
|
||||
// .on('data', (data: string) => {
|
||||
// output += data; // 获取报错日志
|
||||
// })
|
||||
// .pipe(process.stderr);
|
||||
//
|
||||
// npm.on('close', (code: number) => {
|
||||
// if (!code) {
|
||||
// resolve({ code: 0, data: output }); // 如果没有报错就输出正常日志
|
||||
// } else {
|
||||
// reject({ code: code, data: output }); // 如果报错就输出报错日志
|
||||
// }
|
||||
// });
|
||||
let output = '';
|
||||
npm.stdout
|
||||
.on('data', (data: string) => {
|
||||
output += data; // 获取输出日志
|
||||
})
|
||||
.pipe(process.stdout);
|
||||
|
||||
npm.stderr
|
||||
.on('data', (data: string) => {
|
||||
output += data; // 获取报错日志
|
||||
})
|
||||
.pipe(process.stderr);
|
||||
|
||||
npm.on('close', (code: number) => {
|
||||
if (!code) {
|
||||
resolve({ code: 0, data: output }); // 如果没有报错就输出正常日志
|
||||
} else {
|
||||
reject({ code: code, data: output }); // 如果报错就输出报错日志
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -54,6 +54,7 @@ export default () => {
|
||||
executeHooks('PluginOut', null);
|
||||
});
|
||||
createWin.on('closed', () => {
|
||||
view.webContents?.destroy();
|
||||
win = undefined;
|
||||
});
|
||||
createWin.on('focus', () => {
|
||||
@ -70,6 +71,7 @@ export default () => {
|
||||
);
|
||||
view.setAutoResize({ width: true, height: true });
|
||||
createWin.setBrowserView(view);
|
||||
view.inDetach = true;
|
||||
createWin.webContents.executeJavaScript(
|
||||
`window.initDetach(${JSON.stringify(pluginInfo)})`
|
||||
);
|
||||
|
@ -3,6 +3,11 @@ import path from 'path';
|
||||
import commonConst from '../../common/utils/commonConst';
|
||||
import { PLUGIN_INSTALL_DIR as baseDir } from '@/common/constans/main';
|
||||
import localConfig from '@/main/common/initLocalConfig';
|
||||
import {
|
||||
WINDOW_HEIGHT,
|
||||
WINDOW_PLUGIN_HEIGHT,
|
||||
WINDOW_WIDTH,
|
||||
} from '@/common/constans/common';
|
||||
|
||||
const getRelativePath = (indexPath) => {
|
||||
return commonConst.windows()
|
||||
@ -57,8 +62,13 @@ export default () => {
|
||||
const viewReadyFn = async (window, { pluginSetting, ext }) => {
|
||||
if (!view) return;
|
||||
const height = pluginSetting && pluginSetting.height;
|
||||
window.setSize(800, height || 600);
|
||||
view.setBounds({ x: 0, y: 60, width: 800, height: height || 540 });
|
||||
window.setSize(WINDOW_WIDTH, height || WINDOW_PLUGIN_HEIGHT);
|
||||
view.setBounds({
|
||||
x: 0,
|
||||
y: WINDOW_HEIGHT,
|
||||
width: WINDOW_WIDTH,
|
||||
height: height || WINDOW_PLUGIN_HEIGHT - WINDOW_HEIGHT,
|
||||
});
|
||||
view.setAutoResize({ width: true, height: true });
|
||||
executeHooks('PluginEnter', ext);
|
||||
executeHooks('PluginReady', ext);
|
||||
@ -165,26 +175,29 @@ export default () => {
|
||||
|
||||
const removeView = (window: BrowserWindow) => {
|
||||
if (!view) return;
|
||||
window.removeBrowserView(view);
|
||||
// window.setSize(800, 60);
|
||||
executeHooks('PluginOut', null);
|
||||
window.webContents?.executeJavaScript(`window.initRubick()`);
|
||||
view = undefined;
|
||||
setTimeout(() => {
|
||||
window.removeBrowserView(view);
|
||||
if (!view.inDetach) {
|
||||
window.setBrowserView(null);
|
||||
view.webContents?.destroy();
|
||||
}
|
||||
window.webContents?.executeJavaScript(`window.initRubick()`);
|
||||
view = undefined;
|
||||
}, 0);
|
||||
};
|
||||
|
||||
const getView = () => view;
|
||||
|
||||
const executeHooks = (hook, data) => {
|
||||
setTimeout(() => {
|
||||
if (!view) return;
|
||||
const evalJs = `if(window.rubick && window.rubick.hooks && typeof window.rubick.hooks.on${hook} === 'function' ) {
|
||||
if (!view) return;
|
||||
const evalJs = `if(window.rubick && window.rubick.hooks && typeof window.rubick.hooks.on${hook} === 'function' ) {
|
||||
try {
|
||||
window.rubick.hooks.on${hook}(${data ? JSON.stringify(data) : ''});
|
||||
} catch(e) {}
|
||||
}
|
||||
`;
|
||||
view.webContents?.executeJavaScript(evalJs);
|
||||
}, 300);
|
||||
view.webContents?.executeJavaScript(evalJs);
|
||||
};
|
||||
|
||||
return {
|
||||
|
@ -26,6 +26,7 @@ import { runner, detach } from '../browsers';
|
||||
import DBInstance from './db';
|
||||
import getWinPosition from './getWinPosition';
|
||||
import path from 'path';
|
||||
import commonConst from '@/common/utils/commonConst';
|
||||
|
||||
const runnerInstance = runner();
|
||||
const detachInstance = detach();
|
||||
@ -97,7 +98,12 @@ class API extends DBInstance {
|
||||
? 'http://localhost:8083/#/'
|
||||
: `file://${__static}/tpl/index.html`;
|
||||
}
|
||||
if (!plugin.indexPath) {
|
||||
if (plugin.name === 'rubick-system-feature') {
|
||||
plugin.logo = plugin.logo || `file://${__static}/logo.png`;
|
||||
plugin.indexPath = commonConst.dev()
|
||||
? 'http://localhost:8081/#/'
|
||||
: `file://${__static}/feature/index.html`;
|
||||
} else if (!plugin.indexPath) {
|
||||
const pluginPath = path.resolve(baseDir, 'node_modules', plugin.name);
|
||||
plugin.indexPath = `file://${path.join(
|
||||
pluginPath,
|
||||
@ -122,8 +128,8 @@ class API extends DBInstance {
|
||||
}
|
||||
|
||||
public removePlugin(e, window) {
|
||||
this.currentPlugin = null;
|
||||
runnerInstance.removeView(window);
|
||||
this.currentPlugin = null;
|
||||
}
|
||||
|
||||
public openPluginDevTools() {
|
||||
@ -142,11 +148,24 @@ class API extends DBInstance {
|
||||
return dialog.showOpenDialogSync(window, data);
|
||||
}
|
||||
|
||||
public showSaveDialog({ data }, window) {
|
||||
return dialog.showSaveDialogSync(window, data);
|
||||
}
|
||||
|
||||
public setExpendHeight({ data: height }, window: BrowserWindow, e) {
|
||||
const originWindow = this.getCurrentWindow(window, e);
|
||||
if (!originWindow) return;
|
||||
const targetHeight = height;
|
||||
originWindow.setSize(originWindow.getSize()[0], targetHeight);
|
||||
const screenPoint = screen.getCursorScreenPoint();
|
||||
const display = screen.getDisplayNearestPoint(screenPoint);
|
||||
const position =
|
||||
originWindow.getPosition()[1] + targetHeight > display.bounds.height
|
||||
? height - 60
|
||||
: 0;
|
||||
originWindow.webContents.executeJavaScript(
|
||||
`window.setPosition && typeof window.setPosition === "function" && window.setPosition(${position})`
|
||||
);
|
||||
}
|
||||
|
||||
public setSubInput({ data }, window, e) {
|
||||
@ -181,6 +200,7 @@ class API extends DBInstance {
|
||||
value: data.text,
|
||||
})})`
|
||||
);
|
||||
this.sendSubInputChangeEvent({ data });
|
||||
}
|
||||
|
||||
public getPath({ data }) {
|
||||
@ -191,11 +211,10 @@ class API extends DBInstance {
|
||||
if (!Notification.isSupported()) return;
|
||||
'string' != typeof body && (body = String(body));
|
||||
const plugin = this.currentPlugin;
|
||||
if (!plugin) return;
|
||||
const notify = new Notification({
|
||||
title: plugin.pluginName,
|
||||
title: plugin ? plugin.pluginName : null,
|
||||
body,
|
||||
icon: plugin.logo,
|
||||
icon: plugin ? plugin.logo : null,
|
||||
});
|
||||
notify.show();
|
||||
}
|
||||
@ -316,6 +335,7 @@ class API extends DBInstance {
|
||||
shell.showItemInFolder(data.path);
|
||||
return true;
|
||||
}
|
||||
|
||||
public async getFileIcon({ data }) {
|
||||
const nativeImage = await app.getFileIcon(data.path, { size: 'normal' });
|
||||
return nativeImage.toDataURL();
|
||||
|
@ -10,15 +10,18 @@ import {
|
||||
import screenCapture from '@/core/screen-capture';
|
||||
import localConfig from '@/main/common/initLocalConfig';
|
||||
import winPosition from './getWinPosition';
|
||||
import { uIOhook, UiohookKey } from 'uiohook-napi';
|
||||
|
||||
const registerHotKey = (mainWindow: BrowserWindow): void => {
|
||||
// 设置开机启动
|
||||
const setAutoLogin = async () => {
|
||||
const config = await localConfig.getConfig();
|
||||
app.setLoginItemSettings({
|
||||
openAtLogin: config.perf.common.start,
|
||||
openAsHidden: true,
|
||||
});
|
||||
if (app.getLoginItemSettings().openAtLogin !== config.perf.common.start) {
|
||||
app.setLoginItemSettings({
|
||||
openAtLogin: config.perf.common.start,
|
||||
openAsHidden: true,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const setTheme = async () => {
|
||||
@ -55,27 +58,43 @@ const registerHotKey = (mainWindow: BrowserWindow): void => {
|
||||
}
|
||||
};
|
||||
|
||||
// 显示主窗口
|
||||
function mainWindowPopUp() {
|
||||
const currentShow = mainWindow.isVisible() && mainWindow.isFocused();
|
||||
if (currentShow) return mainWindow.hide();
|
||||
const { x: wx, y: wy } = winPosition.getPosition();
|
||||
mainWindow.setAlwaysOnTop(false);
|
||||
mainWindow.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true });
|
||||
mainWindow.focus();
|
||||
mainWindow.setVisibleOnAllWorkspaces(false, {
|
||||
visibleOnFullScreen: true,
|
||||
});
|
||||
mainWindow.setPosition(wx, wy);
|
||||
mainWindow.show();
|
||||
}
|
||||
|
||||
const init = async () => {
|
||||
await setAutoLogin();
|
||||
await setDarkMode();
|
||||
await setTheme();
|
||||
const config = await localConfig.getConfig();
|
||||
globalShortcut.unregisterAll();
|
||||
// 注册偏好快捷键
|
||||
globalShortcut.register(config.perf.shortCut.showAndHidden, () => {
|
||||
const currentShow = mainWindow.isVisible() && mainWindow.isFocused();
|
||||
if (currentShow) return mainWindow.hide();
|
||||
const { x: wx, y: wy } = winPosition.getPosition();
|
||||
mainWindow.setAlwaysOnTop(false);
|
||||
mainWindow.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true });
|
||||
mainWindow.focus();
|
||||
mainWindow.setVisibleOnAllWorkspaces(false, {
|
||||
visibleOnFullScreen: true,
|
||||
});
|
||||
mainWindow.setPosition(wx, wy);
|
||||
mainWindow.show();
|
||||
});
|
||||
|
||||
// 注册偏好快捷键
|
||||
// 处理显示/隐藏快捷键的注册
|
||||
const doublePressShortcuts = ['Ctrl+Ctrl', 'Option+Option', 'Shift+Shift', 'Command+Command'];
|
||||
const isDoublePressShortcut = doublePressShortcuts.includes(config.perf.shortCut.showAndHidden);
|
||||
|
||||
if (isDoublePressShortcut) {
|
||||
// 双击快捷键(如 Ctrl+Ctrl)详见 uIOhookRegister 函数实现
|
||||
} else {
|
||||
// 注册普通快捷键(如 Ctrl+Space、F8 等)
|
||||
globalShortcut.register(config.perf.shortCut.showAndHidden, () => {
|
||||
mainWindowPopUp();
|
||||
});
|
||||
}
|
||||
|
||||
// 截图快捷键
|
||||
globalShortcut.register(config.perf.shortCut.capture, () => {
|
||||
screenCapture(mainWindow, (data) => {
|
||||
data &&
|
||||
@ -86,15 +105,22 @@ const registerHotKey = (mainWindow: BrowserWindow): void => {
|
||||
});
|
||||
});
|
||||
|
||||
// globalShortcut.register(config.perf.shortCut.separate, () => {
|
||||
//
|
||||
// });
|
||||
|
||||
globalShortcut.register(config.perf.shortCut.quit, () => {
|
||||
// mainWindow.webContents.send('init-rubick');
|
||||
// mainWindow.show();
|
||||
});
|
||||
|
||||
// 添加局部快捷键监听
|
||||
mainWindow.webContents.on('before-input-event', (event, input) => {
|
||||
if (input.key.toLowerCase() === 'w'
|
||||
&& (input.control || input.meta) && !input.alt && !input.shift) {
|
||||
event.preventDefault();
|
||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||
mainWindow.hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 注册自定义全局快捷键
|
||||
config.global.forEach((sc) => {
|
||||
if (!sc.key || !sc.value) return;
|
||||
@ -103,9 +129,48 @@ const registerHotKey = (mainWindow: BrowserWindow): void => {
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
uIOhookRegister(mainWindowPopUp);
|
||||
init();
|
||||
ipcMain.on('re-register', () => {
|
||||
init();
|
||||
});
|
||||
};
|
||||
export default registerHotKey;
|
||||
|
||||
function uIOhookRegister(callback: () => void) {
|
||||
let lastModifierPress = Date.now();
|
||||
uIOhook.on('keydown', async (uio_event) => {
|
||||
const config = await localConfig.getConfig(); // 此处还有优化空间
|
||||
|
||||
if (
|
||||
![
|
||||
'Ctrl+Ctrl',
|
||||
'Option+Option',
|
||||
'Shift+Shift',
|
||||
'Command+Command',
|
||||
].includes(config.perf.shortCut.showAndHidden)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 双击快捷键,如 Ctrl+Ctrl
|
||||
const modifers = config.perf.shortCut.showAndHidden.split('+');
|
||||
const showAndHiddenKeyStr = modifers.pop(); // Ctrl
|
||||
const keyStr2uioKeyCode = {
|
||||
Ctrl: UiohookKey.Ctrl,
|
||||
Shift: UiohookKey.Shift,
|
||||
Option: UiohookKey.Alt,
|
||||
Command: UiohookKey.Comma,
|
||||
};
|
||||
|
||||
if (uio_event.keycode === keyStr2uioKeyCode[showAndHiddenKeyStr]) {
|
||||
const currentTime = Date.now();
|
||||
if (currentTime - lastModifierPress < 300) {
|
||||
callback(); // 调用 mainWindowPopUp
|
||||
}
|
||||
lastModifierPress = currentTime;
|
||||
}
|
||||
});
|
||||
uIOhook.start();
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ function createTray(window: BrowserWindow): Promise<Tray> {
|
||||
return new Promise((resolve) => {
|
||||
let icon;
|
||||
if (commonConst.macOS()) {
|
||||
icon = './icons/icon@3x.png';
|
||||
icon = './icons/iconTemplate@2x.png';
|
||||
} else if (commonConst.windows()) {
|
||||
icon =
|
||||
parseInt(os.release()) < 10
|
||||
|
@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<div
|
||||
id="components-layout"
|
||||
@mousedown="onMouseDown"
|
||||
>
|
||||
<div id="components-layout" @mousedown="onMouseDown">
|
||||
<Search
|
||||
:currentPlugin="currentPlugin"
|
||||
@changeCurrent="changeIndex"
|
||||
@ -27,18 +24,24 @@
|
||||
:currentSelect="currentSelect"
|
||||
:options="options"
|
||||
:clipboardFile="clipboardFile || []"
|
||||
@setPluginHistory="setPluginHistory"
|
||||
@choosePlugin="choosePlugin"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { watch, ref, nextTick, toRaw } from 'vue';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { watch, ref, toRaw } from 'vue';
|
||||
import { exec } from 'child_process';
|
||||
import Result from './components/result.vue';
|
||||
import Search from './components/search.vue';
|
||||
import getWindowHeight from '../common/utils/getWindowHeight';
|
||||
import createPluginManager from './plugins-manager';
|
||||
import useDrag from '../common/utils/dragWindow';
|
||||
import { getGlobal } from '@electron/remote';
|
||||
import { PLUGIN_HISTORY } from '@/common/constans/renderer';
|
||||
import { message } from 'ant-design-vue';
|
||||
import localConfig from './confOp';
|
||||
|
||||
const { onMouseDown } = useDrag();
|
||||
const remote = window.require('@electron/remote');
|
||||
@ -60,6 +63,8 @@ const {
|
||||
clearClipboardFile,
|
||||
readClipboardContent,
|
||||
pluginHistory,
|
||||
setPluginHistory,
|
||||
changePluginHistory,
|
||||
} = createPluginManager();
|
||||
|
||||
initPlugins();
|
||||
@ -67,6 +72,8 @@ initPlugins();
|
||||
const currentSelect = ref(0);
|
||||
const menuPluginInfo: any = ref({});
|
||||
|
||||
const config: any = ref(localConfig.getConfig());
|
||||
|
||||
getPluginInfo({
|
||||
pluginName: 'feature',
|
||||
// eslint-disable-next-line no-undef
|
||||
@ -76,41 +83,35 @@ getPluginInfo({
|
||||
remote.getGlobal('LOCAL_PLUGINS').addPlugin(res);
|
||||
});
|
||||
|
||||
watch([options, pluginHistory, currentPlugin], () => {
|
||||
currentSelect.value = 0;
|
||||
// if (currentPlugin.value.name) return;
|
||||
nextTick(() => {
|
||||
ipcRenderer.sendSync('msg-trigger', {
|
||||
type: 'setExpendHeight',
|
||||
data: getWindowHeight(
|
||||
watch(
|
||||
[options, pluginHistory, currentPlugin],
|
||||
() => {
|
||||
currentSelect.value = 0;
|
||||
if (currentPlugin.value.name) return;
|
||||
window.rubick.setExpendHeight(
|
||||
getWindowHeight(
|
||||
options.value,
|
||||
(pluginLoading.value || currentPlugin.value.name) ? [] : pluginHistory.value
|
||||
),
|
||||
});
|
||||
});
|
||||
});
|
||||
pluginLoading.value || !config.value.perf.common.history
|
||||
? []
|
||||
: pluginHistory.value
|
||||
)
|
||||
);
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
|
||||
const changeIndex = (index) => {
|
||||
if (!options.value.length) {
|
||||
if (!pluginHistory.value.length) return;
|
||||
if (
|
||||
currentSelect.value + index > pluginHistory.value.length - 1 ||
|
||||
currentSelect.value + index < 0
|
||||
) {
|
||||
currentSelect.value = 0;
|
||||
return;
|
||||
}
|
||||
currentSelect.value = currentSelect.value + index;
|
||||
return;
|
||||
}
|
||||
if (
|
||||
currentSelect.value + index > options.value.length - 1 ||
|
||||
currentSelect.value + index < 0
|
||||
) {
|
||||
const len = options.value.length || pluginHistory.value.length;
|
||||
if (!len) return;
|
||||
if (currentSelect.value + index > len - 1) {
|
||||
currentSelect.value = 0;
|
||||
return;
|
||||
} else if (currentSelect.value + index < 0) {
|
||||
currentSelect.value = len - 1;
|
||||
} else {
|
||||
currentSelect.value = currentSelect.value + index;
|
||||
}
|
||||
currentSelect.value = currentSelect.value + index;
|
||||
};
|
||||
|
||||
const openMenu = (ext) => {
|
||||
@ -125,13 +126,48 @@ const openMenu = (ext) => {
|
||||
|
||||
window.rubick.openMenu = openMenu;
|
||||
|
||||
const choosePlugin = () => {
|
||||
const choosePlugin = (plugin) => {
|
||||
if (options.value.length) {
|
||||
const currentChoose = options.value[currentSelect.value];
|
||||
currentChoose.click();
|
||||
} else {
|
||||
const currentChoose = pluginHistory.value[currentSelect.value];
|
||||
currentChoose.click();
|
||||
const localPlugins = getGlobal('LOCAL_PLUGINS').getLocalPlugins();
|
||||
const currentChoose = plugin || pluginHistory.value[currentSelect.value];
|
||||
let hasRemove = true;
|
||||
if (currentChoose.pluginType === 'app') {
|
||||
hasRemove = false;
|
||||
changePluginHistory(currentChoose);
|
||||
exec(currentChoose.action);
|
||||
return;
|
||||
}
|
||||
localPlugins.find((plugin) => {
|
||||
if (plugin.name === currentChoose.originName) {
|
||||
hasRemove = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
if (hasRemove) {
|
||||
const result = window.rubick.db.get(PLUGIN_HISTORY) || {};
|
||||
const history = result.data.filter(
|
||||
(item) => item.originName !== currentChoose.originName
|
||||
);
|
||||
setPluginHistory(history);
|
||||
return message.warning('插件已被卸载!');
|
||||
}
|
||||
changePluginHistory(currentChoose);
|
||||
window.rubick.openPlugin(
|
||||
JSON.parse(
|
||||
JSON.stringify({
|
||||
...currentChoose,
|
||||
ext: {
|
||||
code: currentChoose.feature.code,
|
||||
type: currentChoose.cmd.type || 'text',
|
||||
payload: null,
|
||||
},
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 17 KiB |
@ -1,20 +1,30 @@
|
||||
<template>
|
||||
<div
|
||||
v-show="!currentPlugin.name"
|
||||
class="options"
|
||||
ref="scrollDom"
|
||||
>
|
||||
<div class="history-plugins" v-if="!options.length || !(searchValue || !!clipboardFile.length)">
|
||||
<div v-show="!currentPlugin.name" class="options">
|
||||
<div
|
||||
class="history-plugins"
|
||||
v-if="
|
||||
!options.length &&
|
||||
!searchValue &&
|
||||
!clipboardFile.length &&
|
||||
config.perf.common.history
|
||||
"
|
||||
>
|
||||
<a-row>
|
||||
<a-col
|
||||
@click="() => item.click()"
|
||||
:class="currentSelect === index ? 'active history-item' : 'history-item'"
|
||||
@click="() => openPlugin(item)"
|
||||
@contextmenu.prevent="openMenu($event,item)"
|
||||
:class="
|
||||
currentSelect === index ? 'active history-item' : 'history-item'
|
||||
"
|
||||
:span="3"
|
||||
v-for="(item, index) in pluginHistory"
|
||||
:key="index"
|
||||
>
|
||||
<a-avatar style="width: 28px; height: 28px;" :src="item.icon" />
|
||||
<div class="name ellpise">{{item.cmd || item.pluginName || item._name || item.name}}</div>
|
||||
<a-avatar style="width: 28px; height: 28px" :src="item.icon" />
|
||||
<div class="name ellpise">
|
||||
{{ item.cmd || item.pluginName || item._name || item.name }}
|
||||
</div>
|
||||
<div class="badge" v-if="item.pin"></div>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</div>
|
||||
@ -39,16 +49,17 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import BScroll from '@better-scroll/core';
|
||||
import { defineProps, onMounted, ref } from 'vue';
|
||||
import { defineEmits, defineProps, reactive, ref, toRaw, watch } from 'vue';
|
||||
import localConfig from '../confOp';
|
||||
|
||||
const scrollDom = ref(null);
|
||||
const path = window.require('path');
|
||||
const remote = window.require('@electron/remote');
|
||||
|
||||
onMounted(() => {
|
||||
new BScroll(scrollDom.value);
|
||||
});
|
||||
declare const __static: string;
|
||||
|
||||
const props = defineProps({
|
||||
const config: any = ref(localConfig.getConfig());
|
||||
|
||||
const props: any = defineProps({
|
||||
searchValue: {
|
||||
type: [String, Number],
|
||||
default: '',
|
||||
@ -66,14 +77,22 @@ const props = defineProps({
|
||||
clipboardFile: (() => [])(),
|
||||
});
|
||||
|
||||
const emit = defineEmits(['choosePlugin', 'setPluginHistory']);
|
||||
|
||||
const renderTitle = (title, match) => {
|
||||
if (typeof title !== 'string') return;
|
||||
if (!props.searchValue || !match) return title;
|
||||
const result = title.substring(match[0], match[1] + 1);
|
||||
return `<div>${title.substring(0, match[0])}<span style='color: var(--ant-error-color)'>${result}</span>${title.substring(match[1]+1, title.length)}</div>`;
|
||||
return `<div>${title.substring(
|
||||
0,
|
||||
match[0]
|
||||
)}<span style='color: var(--ant-error-color)'>${result}</span>${title.substring(
|
||||
match[1] + 1,
|
||||
title.length
|
||||
)}</div>`;
|
||||
};
|
||||
|
||||
const renderDesc = (desc) => {
|
||||
const renderDesc = (desc = '') => {
|
||||
if (desc.length > 80) {
|
||||
return `${desc.substr(0, 63)}...${desc.substr(
|
||||
desc.length - 14,
|
||||
@ -93,17 +112,97 @@ const sort = (options) => {
|
||||
}
|
||||
}
|
||||
}
|
||||
return options;
|
||||
return options.slice(0, 20);
|
||||
};
|
||||
|
||||
const openPlugin = (item) => {
|
||||
emit('choosePlugin', item);
|
||||
};
|
||||
|
||||
const menuState: any = reactive({
|
||||
plugin: null,
|
||||
});
|
||||
let mainMenus;
|
||||
|
||||
const openMenu = (e, item) => {
|
||||
const pinToMain = mainMenus.getMenuItemById('pinToMain');
|
||||
const unpinFromMain = mainMenus.getMenuItemById('unpinFromMain');
|
||||
pinToMain.visible = !item.pin;
|
||||
unpinFromMain.visible = item.pin;
|
||||
mainMenus.popup({
|
||||
x: e.pageX,
|
||||
y: e.pageY,
|
||||
});
|
||||
menuState.plugin = item;
|
||||
};
|
||||
|
||||
const initMainCmdMenus = () => {
|
||||
const menu = [
|
||||
{
|
||||
id: 'removeRecentCmd',
|
||||
label: '从"使用记录"中删除',
|
||||
icon: path.join(__static, 'icons', 'delete@2x.png'),
|
||||
click: () => {
|
||||
const history = props.pluginHistory.filter((item) => item.name !== menuState.plugin.name);
|
||||
emit('setPluginHistory', toRaw(history));
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'pinToMain',
|
||||
label: '固定到"搜索面板"',
|
||||
icon: path.join(__static, 'icons', 'pin@2x.png'),
|
||||
click: () => {
|
||||
const history = props.pluginHistory.map((item) => {
|
||||
if (item.name === menuState.plugin.name) {
|
||||
item.pin = true;
|
||||
}
|
||||
return item;
|
||||
});
|
||||
emit('setPluginHistory', toRaw(history));
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'unpinFromMain',
|
||||
label: '从"搜索面板"取消固定',
|
||||
icon: path.join(__static, 'icons', 'unpin@2x.png'),
|
||||
click: () => {
|
||||
const history = props.pluginHistory.map((item) => {
|
||||
if (item.name === menuState.plugin.name) {
|
||||
item.pin = false;
|
||||
}
|
||||
return item;
|
||||
});
|
||||
emit('setPluginHistory', toRaw(history));
|
||||
},
|
||||
},
|
||||
];
|
||||
mainMenus = remote.Menu.buildFromTemplate(menu);
|
||||
};
|
||||
|
||||
initMainCmdMenus();
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.ellpise {
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
display:-webkit-box;
|
||||
-webkit-line-clamp:1;
|
||||
-webkit-box-orient:vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
.contextmenu {
|
||||
margin: 0;
|
||||
background: #fff;
|
||||
z-index: 3000;
|
||||
position: absolute;
|
||||
list-style-type: none;
|
||||
padding: 5px 0;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: #333;
|
||||
box-shadow: 2px 2px 3px 0 rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.options {
|
||||
@ -120,6 +219,7 @@ const sort = (options) => {
|
||||
border-top: 1px dashed var(--color-border-light);
|
||||
box-sizing: border-box;
|
||||
.history-item {
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
height: 69px;
|
||||
display: flex;
|
||||
@ -128,6 +228,19 @@ const sort = (options) => {
|
||||
flex-direction: column;
|
||||
color: var(--color-text-content);
|
||||
border-right: 1px dashed var(--color-border-light);
|
||||
position: relative;
|
||||
.badge {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 2px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-radius: 4px;
|
||||
border-top: 6px solid var(--ant-primary-4);
|
||||
border-right: 6px solid var(--ant-primary-4);
|
||||
border-left: 6px solid transparent;
|
||||
border-bottom: 6px solid transparent;
|
||||
}
|
||||
&.active {
|
||||
background: var(--color-list-hover);
|
||||
}
|
||||
@ -141,7 +254,7 @@ const sort = (options) => {
|
||||
}
|
||||
.op-item {
|
||||
padding: 0 10px;
|
||||
height: 60px;
|
||||
height: 70px;
|
||||
line-height: 50px;
|
||||
max-height: 500px;
|
||||
overflow: auto;
|
||||
|
@ -25,6 +25,8 @@
|
||||
ref="mainInput"
|
||||
class="main-input"
|
||||
@input="(e) => changeValue(e)"
|
||||
@keydown.left="(e) => keydownEvent(e, 'left')"
|
||||
@keydown.right="(e) => keydownEvent(e, 'right')"
|
||||
@keydown.down="(e) => keydownEvent(e, 'down')"
|
||||
@keydown.tab="(e) => keydownEvent(e, 'down')"
|
||||
@keydown.up="(e) => keydownEvent(e, 'up')"
|
||||
@ -41,10 +43,7 @@
|
||||
>
|
||||
<template #suffix>
|
||||
<div class="suffix-tool">
|
||||
<MoreOutlined
|
||||
@click="showSeparate()"
|
||||
class="icon-more"
|
||||
/>
|
||||
<MoreOutlined @click="showSeparate()" class="icon-more" />
|
||||
</div>
|
||||
</template>
|
||||
</a-input>
|
||||
@ -96,6 +95,7 @@ const emit = defineEmits([
|
||||
]);
|
||||
|
||||
const keydownEvent = (e, key: string) => {
|
||||
key !== 'space' && e.preventDefault();
|
||||
const { ctrlKey, shiftKey, altKey, metaKey } = e;
|
||||
const modifiers: Array<string> = [];
|
||||
ctrlKey && modifiers.push('control');
|
||||
@ -119,12 +119,19 @@ const keydownEvent = (e, key: string) => {
|
||||
case 'down':
|
||||
emit('changeCurrent', 1);
|
||||
break;
|
||||
case 'left':
|
||||
emit('changeCurrent', -1);
|
||||
break;
|
||||
case 'right':
|
||||
emit('changeCurrent', 1);
|
||||
break;
|
||||
case 'enter':
|
||||
if (runPluginDisable) return;
|
||||
emit('choosePlugin');
|
||||
break;
|
||||
case 'space':
|
||||
if (runPluginDisable || !config.value.perf.common.space) return;
|
||||
e.preventDefault();
|
||||
emit('choosePlugin');
|
||||
break;
|
||||
default:
|
||||
|
@ -8,7 +8,10 @@ import commonConst from '@/common/utils/commonConst';
|
||||
import { exec } from 'child_process';
|
||||
import searchManager from './search';
|
||||
import optionsManager from './options';
|
||||
import { PLUGIN_INSTALL_DIR as baseDir } from '@/common/constans/renderer';
|
||||
import {
|
||||
PLUGIN_INSTALL_DIR as baseDir,
|
||||
PLUGIN_HISTORY,
|
||||
} from '@/common/constans/renderer';
|
||||
import { message } from 'ant-design-vue';
|
||||
|
||||
const createPluginManager = (): any => {
|
||||
@ -28,16 +31,22 @@ const createPluginManager = (): any => {
|
||||
const appList: any = ref([]);
|
||||
|
||||
const initPlugins = async () => {
|
||||
initPluginHistory();
|
||||
appList.value = await appSearch(nativeImage);
|
||||
initLocalStartPlugin();
|
||||
};
|
||||
|
||||
const initPluginHistory = () => {
|
||||
const result = window.rubick.db.get(PLUGIN_HISTORY) || {};
|
||||
if (result && result.data) {
|
||||
state.pluginHistory = result.data;
|
||||
}
|
||||
};
|
||||
|
||||
const initLocalStartPlugin = () => {
|
||||
const result = ipcRenderer.sendSync('msg-trigger', {
|
||||
type: 'dbGet',
|
||||
data: {
|
||||
id: 'rubick-local-start-app',
|
||||
},
|
||||
data: { id: 'rubick-local-start-app' },
|
||||
});
|
||||
if (result && result.value) {
|
||||
appList.value.push(...result.value);
|
||||
@ -68,17 +77,18 @@ const createPluginManager = (): any => {
|
||||
};
|
||||
|
||||
const openPlugin = async (plugin, option) => {
|
||||
ipcRenderer.send('msg-trigger', {
|
||||
type: 'removePlugin',
|
||||
});
|
||||
window.initRubick();
|
||||
if (plugin.pluginType === 'ui' || plugin.pluginType === 'system') {
|
||||
if (state.currentPlugin && state.currentPlugin.name === plugin.name) {
|
||||
ipcRenderer.sendSync('msg-trigger', {
|
||||
type: 'showMainWindow',
|
||||
});
|
||||
window.rubick.showMainWindow();
|
||||
return;
|
||||
}
|
||||
await loadPlugin(plugin);
|
||||
ipcRenderer.sendSync('msg-trigger', {
|
||||
type: 'openPlugin',
|
||||
data: JSON.parse(
|
||||
window.rubick.openPlugin(
|
||||
JSON.parse(
|
||||
JSON.stringify({
|
||||
...plugin,
|
||||
ext: plugin.ext || {
|
||||
@ -87,8 +97,8 @@ const createPluginManager = (): any => {
|
||||
payload: null,
|
||||
},
|
||||
})
|
||||
),
|
||||
});
|
||||
)
|
||||
);
|
||||
}
|
||||
if (plugin.pluginType === 'app') {
|
||||
try {
|
||||
@ -97,23 +107,55 @@ const createPluginManager = (): any => {
|
||||
message.error('启动应用出错,请确保启动应用存在!');
|
||||
}
|
||||
}
|
||||
window.initRubick();
|
||||
changePluginHistory({
|
||||
...plugin,
|
||||
...option,
|
||||
originName: plugin.name,
|
||||
});
|
||||
};
|
||||
|
||||
const changePluginHistory = (plugin) => {
|
||||
state.pluginHistory.forEach((p, index) => {
|
||||
if (p.name === plugin.name) {
|
||||
state.pluginHistory.splice(index, 1);
|
||||
}
|
||||
});
|
||||
state.pluginHistory.unshift(plugin);
|
||||
if (state.pluginHistory.length > 8) {
|
||||
state.pluginHistory.pop();
|
||||
const unpin = state.pluginHistory.filter((plugin) => !plugin.pin);
|
||||
const pin = state.pluginHistory.filter((plugin) => plugin.pin);
|
||||
const isPin = state.pluginHistory.find((p) => p.name === plugin.name)?.pin;
|
||||
if (isPin) {
|
||||
pin.forEach((p, index) => {
|
||||
if (p.name === plugin.name) {
|
||||
plugin = pin.splice(index, 1)[0];
|
||||
}
|
||||
});
|
||||
pin.unshift(plugin);
|
||||
} else {
|
||||
unpin.forEach((p, index) => {
|
||||
if (p.name === plugin.name) {
|
||||
unpin.splice(index, 1);
|
||||
}
|
||||
});
|
||||
unpin.unshift(plugin);
|
||||
}
|
||||
if (state.pluginHistory.length > 8) {
|
||||
unpin.pop();
|
||||
}
|
||||
state.pluginHistory = [...pin, ...unpin];
|
||||
const result = window.rubick.db.get(PLUGIN_HISTORY) || {};
|
||||
window.rubick.db.put({
|
||||
_id: PLUGIN_HISTORY,
|
||||
_rev: result._rev,
|
||||
data: JSON.parse(JSON.stringify(state.pluginHistory)),
|
||||
});
|
||||
};
|
||||
|
||||
const setPluginHistory = (plugins) => {
|
||||
state.pluginHistory = plugins;
|
||||
const unpin = state.pluginHistory.filter((plugin) => !plugin.pin);
|
||||
const pin = state.pluginHistory.filter((plugin) => plugin.pin);
|
||||
state.pluginHistory = [...pin, ...unpin];
|
||||
const result = window.rubick.db.get(PLUGIN_HISTORY) || {};
|
||||
window.rubick.db.put({
|
||||
_id: PLUGIN_HISTORY,
|
||||
_rev: result._rev,
|
||||
data: JSON.parse(JSON.stringify(state.pluginHistory)),
|
||||
});
|
||||
};
|
||||
|
||||
const { searchValue, onSearch, setSearchValue, placeholder } =
|
||||
@ -206,6 +248,8 @@ const createPluginManager = (): any => {
|
||||
clipboardFile,
|
||||
clearClipboardFile,
|
||||
readClipboardContent,
|
||||
setPluginHistory,
|
||||
changePluginHistory,
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { ref, watch } from 'vue';
|
||||
import throttle from 'lodash.throttle';
|
||||
import debounce from 'lodash.debounce';
|
||||
import { ipcRenderer } from 'electron';
|
||||
import { getGlobal } from '@electron/remote';
|
||||
import PinyinMatch from 'pinyin-match';
|
||||
@ -8,7 +8,7 @@ import useFocus from './clipboardWatch';
|
||||
|
||||
function formatReg(regStr) {
|
||||
const flags = regStr.replace(/.*\/([gimy]*)$/, '$1');
|
||||
const pattern = flags.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');
|
||||
const pattern = regStr.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1');
|
||||
return new RegExp(pattern, flags);
|
||||
}
|
||||
|
||||
@ -41,6 +41,17 @@ const optionsManager = ({
|
||||
options[0].click();
|
||||
});
|
||||
|
||||
const getIndex = (cmd, value) => {
|
||||
let index = 0;
|
||||
if (PinyinMatch.match(cmd.label || cmd, value)) {
|
||||
index += 1;
|
||||
}
|
||||
if (cmd.label) {
|
||||
index -= 1;
|
||||
}
|
||||
return index;
|
||||
};
|
||||
|
||||
const getOptionsFromSearchValue = (value, strict = false) => {
|
||||
const localPlugins = getGlobal('LOCAL_PLUGINS').getLocalPlugins();
|
||||
let options: any = [];
|
||||
@ -61,7 +72,7 @@ const optionsManager = ({
|
||||
desc: fe.explain,
|
||||
type: plugin.pluginType,
|
||||
match: PinyinMatch.match(cmd.label || cmd, value),
|
||||
zIndex: cmd.label ? 0 : 1, // 排序权重
|
||||
zIndex: getIndex(cmd, value), // 排序权重
|
||||
click: () => {
|
||||
pluginClickEvent({
|
||||
plugin,
|
||||
@ -117,7 +128,7 @@ const optionsManager = ({
|
||||
.map((plugin) => {
|
||||
const option = {
|
||||
...plugin,
|
||||
zIndex: 1,
|
||||
zIndex: 0,
|
||||
click: () => {
|
||||
openPlugin(plugin, option);
|
||||
},
|
||||
@ -130,7 +141,7 @@ const optionsManager = ({
|
||||
|
||||
watch(searchValue, () => search(searchValue.value));
|
||||
// search Input operation
|
||||
const search = throttle((value) => {
|
||||
const search = debounce((value) => {
|
||||
if (currentPlugin.value.name) return;
|
||||
if (clipboardFile.value.length) return;
|
||||
if (!value) {
|
||||
@ -138,7 +149,7 @@ const optionsManager = ({
|
||||
return;
|
||||
}
|
||||
optionsRef.value = getOptionsFromSearchValue(value);
|
||||
}, 500);
|
||||
}, 100);
|
||||
|
||||
const setOptionsRef = (options) => {
|
||||
optionsRef.value = options;
|
||||
|
@ -33,6 +33,10 @@ module.exports = {
|
||||
productName: 'rubick',
|
||||
appId: 'com.muwoo.rubick',
|
||||
compression: 'maximum',
|
||||
// afterPack: './release.js',
|
||||
// afterAllArtifactBuild: () => {
|
||||
// return ['./build/app.asar.gz'];
|
||||
// },
|
||||
directories: {
|
||||
output: 'build',
|
||||
},
|
||||
|
146
yarn.lock
@ -1007,6 +1007,23 @@
|
||||
ajv "^6.12.0"
|
||||
ajv-keywords "^3.4.1"
|
||||
|
||||
"@eggjs/yauzl@^2.11.0":
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@eggjs/yauzl/-/yauzl-2.11.0.tgz#b8e4413f50fc7c51451f770f152de4c1137aa99b"
|
||||
integrity sha512-Jq+k2fCZJ3i3HShb0nxLUiAgq5pwo8JTT1TrH22JoehZQ0Nm2dvByGIja1NYfNyuE4Tx5/Dns5nVsBN/mlC8yg==
|
||||
dependencies:
|
||||
buffer-crc32 "~0.2.3"
|
||||
fd-slicer2 "^1.2.0"
|
||||
|
||||
"@electron/asar@^3.2.8":
|
||||
version "3.2.8"
|
||||
resolved "https://registry.yarnpkg.com/@electron/asar/-/asar-3.2.8.tgz#2ea722f3452583dbd4ffdcc4b4f5dc903f1d8178"
|
||||
integrity sha512-cmskk5M06ewHMZAplSiF4AlME3IrnnZhKnWbtwKVLRkdJkKyUVjMLhDIiPIx/+6zQWVlKX/LtmK9xDme7540Sg==
|
||||
dependencies:
|
||||
commander "^5.0.0"
|
||||
glob "^7.1.6"
|
||||
minimatch "^3.0.4"
|
||||
|
||||
"@electron/get@^2.0.0":
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@electron/get/-/get-2.0.2.tgz#ae2a967b22075e9c25aaf00d5941cd79c21efd7e"
|
||||
@ -3188,6 +3205,14 @@ bindings@^1.5.0:
|
||||
dependencies:
|
||||
file-uri-to-path "1.0.0"
|
||||
|
||||
bl@^1.0.0:
|
||||
version "1.2.3"
|
||||
resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.3.tgz#1e8dd80142eac80d7158c9dccc047fb620e035e7"
|
||||
integrity sha512-pvcNpa0UU69UT341rO6AYy4FVAIkUHuZXRIWbq+zHnsVcRzDDjIAhGuuYoi0d//cwIwtt4pkpKycWEfjdV+vww==
|
||||
dependencies:
|
||||
readable-stream "^2.3.5"
|
||||
safe-buffer "^5.1.1"
|
||||
|
||||
bl@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a"
|
||||
@ -4280,6 +4305,21 @@ compressible@~2.0.16:
|
||||
dependencies:
|
||||
mime-db ">= 1.43.0 < 2"
|
||||
|
||||
compressing@^1.10.0:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/compressing/-/compressing-1.10.0.tgz#bca0f734736b5bb05c3a176fef8d60d7f5f322da"
|
||||
integrity sha512-k2vpbZLaJoHe9euyUZjYYE8vOrbR19aU3HcWIYw5EBXiUs34ygfDVnXU+ubI41JXMriHutnoiu0ZFdwCkH6jPA==
|
||||
dependencies:
|
||||
"@eggjs/yauzl" "^2.11.0"
|
||||
flushwritable "^1.0.0"
|
||||
get-ready "^1.0.0"
|
||||
iconv-lite "^0.5.0"
|
||||
mkdirp "^0.5.1"
|
||||
pump "^3.0.0"
|
||||
streamifier "^0.1.1"
|
||||
tar-stream "^1.5.2"
|
||||
yazl "^2.4.2"
|
||||
|
||||
compression@^1.7.4:
|
||||
version "1.7.4"
|
||||
resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f"
|
||||
@ -4829,7 +4869,7 @@ debug@^3.1.0, debug@^3.2.7:
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debuglog@*, debuglog@^1.0.1:
|
||||
debuglog@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmmirror.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
|
||||
integrity sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw==
|
||||
@ -6205,6 +6245,13 @@ faye-websocket@^0.11.3, faye-websocket@^0.11.4:
|
||||
dependencies:
|
||||
websocket-driver ">=0.5.1"
|
||||
|
||||
fd-slicer2@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/fd-slicer2/-/fd-slicer2-1.2.0.tgz#a2c54a540639bbcd4702480821771341277ca20e"
|
||||
integrity sha512-3lBUNUckhMZduCc4g+Pw4Ve16LD9vpX9b8qUkkKq2mgDRLYWzblszZH2luADnJqjJe+cypngjCuKRm/IW12rRw==
|
||||
dependencies:
|
||||
pend "^1.2.0"
|
||||
|
||||
fd-slicer@~1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
|
||||
@ -6387,6 +6434,11 @@ flush-write-stream@^1.0.0:
|
||||
inherits "^2.0.3"
|
||||
readable-stream "^2.3.6"
|
||||
|
||||
flushwritable@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/flushwritable/-/flushwritable-1.0.0.tgz#3e328d8fde412ad47e738e3be750b4d290043498"
|
||||
integrity sha512-3VELfuWCLVzt5d2Gblk8qcqFro6nuwvxwMzHaENVDHI7rxcBRtMCwTk/E9FXcgh+82DSpavPNDueA9+RxXJoFg==
|
||||
|
||||
follow-redirects@^1.0.0:
|
||||
version "1.15.1"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5"
|
||||
@ -6503,6 +6555,11 @@ from2@^2.1.0:
|
||||
inherits "^2.0.1"
|
||||
readable-stream "^2.0.0"
|
||||
|
||||
fs-constants@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
|
||||
integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==
|
||||
|
||||
fs-extra@^10.0.0, fs-extra@^10.1.0:
|
||||
version "10.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf"
|
||||
@ -6697,6 +6754,11 @@ get-mac-apps@^1.0.2:
|
||||
dependencies:
|
||||
plist "^3.0.1"
|
||||
|
||||
get-ready@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/get-ready/-/get-ready-1.0.0.tgz#f91817f1e9adecfea13a562adfc8de883ab34782"
|
||||
integrity sha512-mFXCZPJIlcYcth+N8267+mghfYN9h3EhsDa6JSnbA3Wrhh/XFpuowviFcsDeYZtKspQyWyJqfs4O6P8CHeTwzw==
|
||||
|
||||
get-stdin@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b"
|
||||
@ -7430,6 +7492,13 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.5:
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
|
||||
iconv-lite@^0.5.0:
|
||||
version "0.5.2"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.5.2.tgz#af6d628dccfb463b7364d97f715e4b74b8c8c2b8"
|
||||
integrity sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==
|
||||
dependencies:
|
||||
safer-buffer ">= 2.1.2 < 3"
|
||||
|
||||
iconv-lite@^0.6.2:
|
||||
version "0.6.3"
|
||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501"
|
||||
@ -7539,7 +7608,7 @@ import-local@^2.0.0:
|
||||
pkg-dir "^3.0.0"
|
||||
resolve-cwd "^2.0.0"
|
||||
|
||||
imurmurhash@*, imurmurhash@^0.1.4:
|
||||
imurmurhash@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
|
||||
integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==
|
||||
@ -8842,11 +8911,6 @@ lodash-es@^4.17.15:
|
||||
resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
|
||||
integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==
|
||||
|
||||
lodash._baseindexof@*:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.npmmirror.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c"
|
||||
integrity sha512-bSYo8Pc/f0qAkr8fPJydpJjtrHiSynYfYBjtANIgXv5xEf1WlTC63dIDlgu0s9dmTvzRu1+JJTxcIAHe+sH0FQ==
|
||||
|
||||
lodash._baseuniq@~4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.npmmirror.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8"
|
||||
@ -8855,33 +8919,11 @@ lodash._baseuniq@~4.6.0:
|
||||
lodash._createset "~4.0.0"
|
||||
lodash._root "~3.0.0"
|
||||
|
||||
lodash._bindcallback@*:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.npmmirror.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e"
|
||||
integrity sha512-2wlI0JRAGX8WEf4Gm1p/mv/SZ+jLijpj0jyaE/AXeuQphzCgD8ZQW4oSpoN8JAopujOFGU3KMuq7qfHBWlGpjQ==
|
||||
|
||||
lodash._cacheindexof@*:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.npmmirror.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92"
|
||||
integrity sha512-S8dUjWr7SUT/X6TBIQ/OYoCHo1Stu1ZRy6uMUSKqzFnZp5G5RyQizSm6kvxD2Ewyy6AVfMg4AToeZzKfF99T5w==
|
||||
|
||||
lodash._createcache@*:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.npmmirror.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093"
|
||||
integrity sha512-ev5SP+iFpZOugyab/DEUQxUeZP5qyciVTlgQ1f4Vlw7VUcCD8fVnyIqVUEIaoFH9zjAqdgi69KiofzvVmda/ZQ==
|
||||
dependencies:
|
||||
lodash._getnative "^3.0.0"
|
||||
|
||||
lodash._createset@~4.0.0:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.npmmirror.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26"
|
||||
integrity sha512-GTkC6YMprrJZCYU3zcqZj+jkXkrXzq3IPBcF/fIPpNEAB4hZEtXU8zp/RwKOvZl43NUmwDbyRk3+ZTbeRdEBXA==
|
||||
|
||||
lodash._getnative@*, lodash._getnative@^3.0.0:
|
||||
version "3.9.1"
|
||||
resolved "https://registry.npmmirror.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
|
||||
integrity sha512-RrL9VxMEPyDMHOd9uFbvMe8X55X16/cGM5IgOKgRElQZutpX89iS6vwl64duTV1/16w5JY7tuFNXqoekmh1EmA==
|
||||
|
||||
lodash._root@~3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.npmmirror.com/lodash._root/-/lodash._root-3.0.1.tgz#fba1c4524c19ee9a5f8136b4609f017cf4ded692"
|
||||
@ -8894,7 +8936,7 @@ lodash.clonedeep@^4.5.0, lodash.clonedeep@~4.5.0:
|
||||
|
||||
lodash.debounce@^4.0.8:
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
||||
resolved "https://registry.npmmirror.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
||||
integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==
|
||||
|
||||
lodash.defaultsdeep@^4.6.1:
|
||||
@ -8937,16 +8979,6 @@ lodash.pick@^4.0.0:
|
||||
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3"
|
||||
integrity sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==
|
||||
|
||||
lodash.restparam@*:
|
||||
version "3.6.1"
|
||||
resolved "https://registry.npmmirror.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805"
|
||||
integrity sha512-L4/arjjuq4noiUJpt3yS6KIKDtJwNe2fIYgMqyYYKoeIfV1iEqvPwhCx23o+R9dzouGihDAPN1dTIRWa7zk8tw==
|
||||
|
||||
lodash.throttle@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
|
||||
integrity sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==
|
||||
|
||||
lodash.transform@^4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.transform/-/lodash.transform-4.6.0.tgz#12306422f63324aed8483d3f38332b5f670547a0"
|
||||
@ -10513,7 +10545,7 @@ pbkdf2@^3.0.3:
|
||||
safe-buffer "^5.0.1"
|
||||
sha.js "^2.4.8"
|
||||
|
||||
pend@~1.2.0:
|
||||
pend@^1.2.0, pend@~1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
|
||||
integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
|
||||
@ -11542,7 +11574,7 @@ readable-stream@1.1.14, readable-stream@^1.0.27-1, readable-stream@~1.1.10:
|
||||
isarray "0.0.1"
|
||||
string_decoder "~0.10.x"
|
||||
|
||||
readable-stream@^2.0.6:
|
||||
readable-stream@^2.0.6, readable-stream@^2.3.0, readable-stream@^2.3.5:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.npmmirror.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b"
|
||||
integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==
|
||||
@ -12739,6 +12771,11 @@ stream-shift@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d"
|
||||
integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==
|
||||
|
||||
streamifier@^0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/streamifier/-/streamifier-0.1.1.tgz#97e98d8fa4d105d62a2691d1dc07e820db8dfc4f"
|
||||
integrity sha512-zDgl+muIlWzXNsXeyUfOk9dChMjlpkq0DRsxujtYPgyJ676yQ8jEm6zzaaWHFDg5BNcLuif0eD2MTyJdZqXpdg==
|
||||
|
||||
strict-uri-encode@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713"
|
||||
@ -12987,6 +13024,19 @@ tapable@^2.1.1, tapable@^2.2.0:
|
||||
resolved "https://registry.npmmirror.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
|
||||
integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
|
||||
|
||||
tar-stream@^1.5.2:
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555"
|
||||
integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==
|
||||
dependencies:
|
||||
bl "^1.0.0"
|
||||
buffer-alloc "^1.2.0"
|
||||
end-of-stream "^1.0.0"
|
||||
fs-constants "^1.0.0"
|
||||
readable-stream "^2.3.0"
|
||||
to-buffer "^1.1.1"
|
||||
xtend "^4.0.0"
|
||||
|
||||
tar@^4.4.10, tar@^4.4.12, tar@^4.4.13:
|
||||
version "4.4.19"
|
||||
resolved "https://registry.npmmirror.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3"
|
||||
@ -13182,6 +13232,11 @@ to-arraybuffer@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
|
||||
integrity sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==
|
||||
|
||||
to-buffer@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80"
|
||||
integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==
|
||||
|
||||
to-fast-properties@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
|
||||
@ -14531,6 +14586,13 @@ yauzl@^2.10.0:
|
||||
buffer-crc32 "~0.2.3"
|
||||
fd-slicer "~1.1.0"
|
||||
|
||||
yazl@^2.4.2:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.5.1.tgz#a3d65d3dd659a5b0937850e8609f22fffa2b5c35"
|
||||
integrity sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==
|
||||
dependencies:
|
||||
buffer-crc32 "~0.2.3"
|
||||
|
||||
yorkie@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/yorkie/-/yorkie-2.0.0.tgz#92411912d435214e12c51c2ae1093e54b6bb83d9"
|
||||
|