mirror of
https://github.com/rubickCenter/rubick
synced 2025-07-18 22:05:05 +08:00
✨ 修改插件runner为browserview
This commit is contained in:
parent
0132a11d7e
commit
cd41f0561c
42
feature/package-lock.json
generated
42
feature/package-lock.json
generated
@ -7918,6 +7918,14 @@
|
|||||||
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
|
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"linkify-it": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==",
|
||||||
|
"requires": {
|
||||||
|
"uc.micro": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"loader-fs-cache": {
|
"loader-fs-cache": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/loader-fs-cache/-/loader-fs-cache-1.0.3.tgz",
|
||||||
@ -8128,6 +8136,30 @@
|
|||||||
"object-visit": "^1.0.0"
|
"object-visit": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"markdown-it": {
|
||||||
|
"version": "12.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.2.0.tgz",
|
||||||
|
"integrity": "sha512-Wjws+uCrVQRqOoJvze4HCqkKl1AsSh95iFAeQDwnyfxM09divCBSXlDR1uTvyUP3Grzpn4Ru8GeCxYPM8vkCQg==",
|
||||||
|
"requires": {
|
||||||
|
"argparse": "^2.0.1",
|
||||||
|
"entities": "~2.1.0",
|
||||||
|
"linkify-it": "^3.0.1",
|
||||||
|
"mdurl": "^1.0.1",
|
||||||
|
"uc.micro": "^1.0.5"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"argparse": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||||
|
},
|
||||||
|
"entities": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"md5.js": {
|
"md5.js": {
|
||||||
"version": "1.3.5",
|
"version": "1.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
|
||||||
@ -8145,6 +8177,11 @@
|
|||||||
"integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==",
|
"integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"mdurl": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
|
||||||
|
},
|
||||||
"media-typer": {
|
"media-typer": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
@ -11898,6 +11935,11 @@
|
|||||||
"integrity": "sha512-pxnwLxeb/Z5SP80JDRzVjh58KsM6jZHRAOtTpS7sXLS4ogXNKC9ANxHHZqLLeVHZN35jCtI4JdmLLbLiC1kBow==",
|
"integrity": "sha512-pxnwLxeb/Z5SP80JDRzVjh58KsM6jZHRAOtTpS7sXLS4ogXNKC9ANxHHZqLLeVHZN35jCtI4JdmLLbLiC1kBow==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"uc.micro": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
|
||||||
|
},
|
||||||
"uglify-js": {
|
"uglify-js": {
|
||||||
"version": "3.4.10",
|
"version": "3.4.10",
|
||||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz",
|
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz",
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
"ant-design-vue": "^2.2.8",
|
"ant-design-vue": "^2.2.8",
|
||||||
"axios": "^0.24.0",
|
"axios": "^0.24.0",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
|
"markdown-it": "^12.2.0",
|
||||||
"vue": "^3.0.0",
|
"vue": "^3.0.0",
|
||||||
"vue-router": "^4.0.0-0",
|
"vue-router": "^4.0.0-0",
|
||||||
"vuex": "^4.0.0-0"
|
"vuex": "^4.0.0-0"
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
"logo": "logo.jpg",
|
"logo": "logo.jpg",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"preload":"preload.js",
|
"preload":"preload.js",
|
||||||
|
"pluginType": "ui",
|
||||||
"features": [
|
"features": [
|
||||||
{
|
{
|
||||||
"code": "market",
|
"code": "market",
|
||||||
|
@ -0,0 +1 @@
|
|||||||
|
console.log("hello");
|
@ -1,28 +1,32 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="main-container">
|
<div class="main-container">
|
||||||
<div class="slider-bar">
|
<div class="slider-bar">
|
||||||
<div class="top">
|
<a-menu v-model:selectedKeys="active" mode="horizontal" @select="({key}) => changeMenu(key)">
|
||||||
<div class="menu-item avatar">
|
<a-menu-item key="market">
|
||||||
<a-avatar shape="square" :size="30">
|
<template #icon>
|
||||||
<template #icon><UserOutlined /></template>
|
<AppstoreOutlined />
|
||||||
</a-avatar>
|
</template>
|
||||||
</div>
|
插件市场
|
||||||
<div class="menu-item" @click="changeMenu('market')">
|
</a-menu-item>
|
||||||
<AppstoreOutlined :class="active === 'market' && 'active'" style="font-size: 24px;" />
|
<a-menu-item key="installed">
|
||||||
</div>
|
<template #icon>
|
||||||
<div class="menu-item" @click="changeMenu('installed')">
|
<HeartOutlined />
|
||||||
<HeartOutlined :class="active === 'installed' && 'active'" style="font-size: 24px;" />
|
</template>
|
||||||
</div>
|
已安装
|
||||||
<div class="menu-item" @click="changeMenu('settings')">
|
</a-menu-item>
|
||||||
<SettingOutlined :class="active === 'installed' && 'active'" style="font-size: 24px;" />
|
<a-menu-item key="settings">
|
||||||
</div>
|
<template #icon>
|
||||||
<div class="menu-item" @click="changeMenu('dev')">
|
<SettingOutlined />
|
||||||
<BugOutlined :class="active === 'installed' && 'active'" style="font-size: 24px;" />
|
</template>
|
||||||
</div>
|
设置
|
||||||
</div>
|
</a-menu-item>
|
||||||
<div class="menu-item bottom" @click="changeMenu('more')">
|
<a-menu-item key="user">
|
||||||
<MenuOutlined style="font-size: 24px;" />
|
<template #icon>
|
||||||
</div>
|
<UserOutlined />
|
||||||
|
</template>
|
||||||
|
账户
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
</div>
|
</div>
|
||||||
<router-view />
|
<router-view />
|
||||||
</div>
|
</div>
|
||||||
@ -30,10 +34,23 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { HeartOutlined, UserOutlined, SearchOutlined, MenuOutlined, AppstoreOutlined, SettingOutlined, BugOutlined } from "@ant-design/icons-vue";
|
import { useRouter } from "vue-router";
|
||||||
|
import {
|
||||||
const active = ref("market");
|
HeartOutlined,
|
||||||
|
UserOutlined,
|
||||||
|
AppstoreOutlined,
|
||||||
|
SettingOutlined,
|
||||||
|
} from "@ant-design/icons-vue";
|
||||||
|
import { useStore } from "vuex";
|
||||||
|
const router = useRouter();
|
||||||
|
const active = ref(["market"]);
|
||||||
|
const changeMenu = (key: any) => {
|
||||||
|
router.push(key);
|
||||||
|
};
|
||||||
|
|
||||||
|
const store = useStore();
|
||||||
|
const init = () => store.dispatch("init");
|
||||||
|
init();
|
||||||
</script>
|
</script>
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
* {
|
* {
|
||||||
@ -45,43 +62,10 @@ const active = ref("market");
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
background: #F2EFEF;
|
background: #F2EFEF;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
.slider-bar {
|
.slider-bar {
|
||||||
-webkit-app-region: drag;
|
width: 100%;
|
||||||
width: 60px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column;
|
|
||||||
padding-top: 15px;
|
|
||||||
height: 100vh;
|
|
||||||
background-image: linear-gradient(to top right, rgba(255, 159, 180, 0.3), rgba(255, 159, 180, 0.2));
|
|
||||||
color: #7D7170;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
.top {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-item {
|
|
||||||
cursor: pointer;
|
|
||||||
margin-bottom: 40px;
|
|
||||||
-webkit-app-region: no-drag;
|
|
||||||
|
|
||||||
.active {
|
|
||||||
color: #ff4ea4;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.avatar {
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.bottom {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,12 +1,23 @@
|
|||||||
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
|
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
|
||||||
import Market from "../views/market/index.vue";
|
import Market from "../views/market/index.vue";
|
||||||
|
import Installed from "../views/installed/index.vue";
|
||||||
|
|
||||||
const routes: Array<RouteRecordRaw> = [
|
const routes: Array<RouteRecordRaw> = [
|
||||||
{
|
{
|
||||||
path: "/",
|
path: "/market",
|
||||||
name: "Market",
|
name: "market",
|
||||||
component: Market,
|
component: Market,
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
path: "/installed",
|
||||||
|
name: "installed",
|
||||||
|
component: Installed,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/:catchAll(.*)",
|
||||||
|
name: "market",
|
||||||
|
component: Market,
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
|
@ -35,7 +35,6 @@ export default createStore({
|
|||||||
origin.isloading = false;
|
origin.isloading = false;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
commit("commonUpdate", {
|
commit("commonUpdate", {
|
||||||
localPlugins,
|
localPlugins,
|
||||||
totalPlugins,
|
totalPlugins,
|
||||||
@ -64,8 +63,17 @@ export default createStore({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
const localPlugins = (window as any).rubick.getLocalPlugins();
|
||||||
|
|
||||||
commit("commonUpdate", {
|
commit("commonUpdate", {
|
||||||
totalPlugins,
|
totalPlugins,
|
||||||
|
localPlugins,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateLocalPlugin({ commit }) {
|
||||||
|
const localPlugins = (window as any).rubick.getLocalPlugins();
|
||||||
|
commit("commonUpdate", {
|
||||||
|
localPlugins,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
163
feature/src/views/installed/index.vue
Normal file
163
feature/src/views/installed/index.vue
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
<template>
|
||||||
|
<div class="installed">
|
||||||
|
<div class="installed-list">
|
||||||
|
<div :class="currentSelect === index ? 'item active' : 'item'" :key="index" v-for="(plugin, index) in localPlugins">
|
||||||
|
<img :src="plugin.logo" />
|
||||||
|
<div class="info">
|
||||||
|
<div class="title">{{ plugin.pluginName }} <span class="desc">v{{ plugin.version }}</span></div>
|
||||||
|
<div class="desc">{{ plugin.description }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="plugin-detail">
|
||||||
|
<div class="plugin-top">
|
||||||
|
<div class="left">
|
||||||
|
<div class="title">
|
||||||
|
{{ pluginDetail.pluginName }}
|
||||||
|
<a-tag>{{ pluginDetail.version }}</a-tag>
|
||||||
|
</div>
|
||||||
|
<div class="desc">
|
||||||
|
开发者:{{`${pluginDetail.author || '未知'}`}}
|
||||||
|
</div>
|
||||||
|
<div class="desc">
|
||||||
|
{{pluginDetail.description}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<a-button type="danger" size="small" shape="round" @click="deletePlugin(pluginDetail)">移除</a-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a-tabs default-active-key="1">
|
||||||
|
<a-tab-pane key="1" tab="功能关键字">
|
||||||
|
<div class="feature-container">
|
||||||
|
<div class="desc-item" :key="index" v-for="(item, index) in pluginDetail.features">
|
||||||
|
<div>{{item.explain}}</div>
|
||||||
|
<a-tag
|
||||||
|
:key="cmd"
|
||||||
|
@click="openPlugin({cmd, plugin: pluginDetail, feature: item, router: $router})"
|
||||||
|
v-for="cmd in item.cmds"
|
||||||
|
>
|
||||||
|
{{cmd}}
|
||||||
|
</a-tag>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-tab-pane>
|
||||||
|
<a-tab-pane key="2" tab="详情介绍">
|
||||||
|
<div class="detail-container" v-html="readme"></div>
|
||||||
|
</a-tab-pane>
|
||||||
|
</a-tabs>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { useStore } from "vuex";
|
||||||
|
import { computed, ref } from "vue";
|
||||||
|
import path from "path";
|
||||||
|
import MarkdownIt from "markdown-it";
|
||||||
|
|
||||||
|
const { remote } = window.require("electron");
|
||||||
|
const fs = window.require("fs");
|
||||||
|
const md = new MarkdownIt();
|
||||||
|
|
||||||
|
const appPath = remote.app.getPath("cache");
|
||||||
|
const baseDir = path.join(appPath, "./rubick-plugins");
|
||||||
|
|
||||||
|
const store = useStore();
|
||||||
|
const localPlugins = computed(() => store.state.localPlugins);
|
||||||
|
const updateLocalPlugin = () => store.dispatch("updateLocalPlugin");
|
||||||
|
|
||||||
|
const currentSelect = ref(0);
|
||||||
|
|
||||||
|
const pluginDetail = computed(() => {
|
||||||
|
return localPlugins.value[currentSelect.value] || {};
|
||||||
|
});
|
||||||
|
|
||||||
|
const readme = computed(() => {
|
||||||
|
if(!pluginDetail.value.name) return "";
|
||||||
|
const str = fs.readFileSync(
|
||||||
|
path.resolve(baseDir, "node_modules", pluginDetail.value.name, "readme.md"),
|
||||||
|
"utf-8"
|
||||||
|
);
|
||||||
|
return md.render(str);
|
||||||
|
});
|
||||||
|
|
||||||
|
const deletePlugin = async (plugin) => {
|
||||||
|
await window.rubick.deletePlugin(plugin);
|
||||||
|
updateLocalPlugin();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
.installed {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
background: #F3EFEF;
|
||||||
|
height: calc(~"100vh - 46px");
|
||||||
|
display: flex;
|
||||||
|
.installed-list {
|
||||||
|
width: 40%;
|
||||||
|
background: #fff;
|
||||||
|
height: 100%;
|
||||||
|
padding: 10px 0;
|
||||||
|
border-right: 1px solid #eee;
|
||||||
|
.item {
|
||||||
|
padding: 10px 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
img {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
.desc {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
&.active {
|
||||||
|
background: #eee;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.plugin-detail {
|
||||||
|
padding: 20px 20px 0 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 60%;
|
||||||
|
height: 100%;
|
||||||
|
background: #fff;
|
||||||
|
.plugin-top {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
.title {
|
||||||
|
font-size: 20px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.desc {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.detail-container, .feature-container {
|
||||||
|
height: 380px;
|
||||||
|
overflow: auto;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.desc-item {
|
||||||
|
border-bottom: 1px solid #ddd;
|
||||||
|
padding: 10px 0;
|
||||||
|
.desc-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.desc-info {
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -78,8 +78,7 @@ const state = reactive({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
const init = () => store.dispatch("init");
|
|
||||||
init();
|
|
||||||
const totalPlugins = computed(() => store.state.totalPlugins);
|
const totalPlugins = computed(() => store.state.totalPlugins);
|
||||||
|
|
||||||
const { searchValue, current } = toRefs(state);
|
const { searchValue, current } = toRefs(state);
|
||||||
@ -93,6 +92,7 @@ const { searchValue, current } = toRefs(state);
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
background: #F3EFEF;
|
background: #F3EFEF;
|
||||||
|
height: calc(~"100vh - 46px");
|
||||||
.left-menu {
|
.left-menu {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
height: 100vh;
|
height: 100vh;
|
||||||
@ -116,7 +116,7 @@ const { searchValue, current } = toRefs(state);
|
|||||||
.container {
|
.container {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
width: calc(~'100% - 200px');
|
width: calc(~'100% - 200px');
|
||||||
height: 100vh;
|
height: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
padding: 10px 20px;
|
padding: 10px 20px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -7,4 +7,7 @@ window.rubick = {
|
|||||||
downloadPlugin(plugin) {
|
downloadPlugin(plugin) {
|
||||||
return remote.getGlobal("LOCAL_PLUGINS").downloadPlugin(plugin);
|
return remote.getGlobal("LOCAL_PLUGINS").downloadPlugin(plugin);
|
||||||
},
|
},
|
||||||
|
deletePlugin(plugin) {
|
||||||
|
return remote.getGlobal("LOCAL_PLUGINS").deletePlugin(plugin);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
@ -43,4 +43,10 @@ global.LOCAL_PLUGINS = {
|
|||||||
fs.writeFileSync(configPath, JSON.stringify(global.LOCAL_PLUGINS.PLUGINS));
|
fs.writeFileSync(configPath, JSON.stringify(global.LOCAL_PLUGINS.PLUGINS));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
async deletePlugin(plugin) {
|
||||||
|
await pluginInstance.uninstall([plugin.name]);
|
||||||
|
global.LOCAL_PLUGINS.PLUGINS = global.LOCAL_PLUGINS.PLUGINS.filter((p) => plugin.name !== p.name);
|
||||||
|
fs.writeFileSync(configPath, JSON.stringify(global.LOCAL_PLUGINS.PLUGINS));
|
||||||
|
return global.LOCAL_PLUGINS.PLUGINS;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
@ -112,7 +112,7 @@ export default async (nativeImage: any) => {
|
|||||||
...app,
|
...app,
|
||||||
value: "plugin",
|
value: "plugin",
|
||||||
desc: app.path,
|
desc: app.path,
|
||||||
type: "app",
|
pluginType: "app",
|
||||||
action: `open ${app.path.replace(" ", "\\ ") as string}`,
|
action: `open ${app.path.replace(" ", "\\ ") as string}`,
|
||||||
keyWords: [appSubStr],
|
keyWords: [appSubStr],
|
||||||
};
|
};
|
||||||
|
@ -34,7 +34,6 @@ class AdapterHandler {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.baseDir = options.baseDir;
|
this.baseDir = options.baseDir;
|
||||||
console.log(this.baseDir);
|
|
||||||
this.registry = options.registry || "https://registry.npm.taobao.org";
|
this.registry = options.registry || "https://registry.npm.taobao.org";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,22 +1,25 @@
|
|||||||
import { app, BrowserWindow } from "electron";
|
import { BrowserView, BrowserWindow, session } from "electron";
|
||||||
|
import path from "path";
|
||||||
|
import commonConst from "../../common/utils/commonConst";
|
||||||
|
|
||||||
export default () => {
|
export default () => {
|
||||||
let win;
|
let view;
|
||||||
|
|
||||||
const init = (plugin) => {
|
const init = (plugin, window: BrowserWindow) => {
|
||||||
if (win === null || win === undefined) {
|
if (view === null || view === undefined) {
|
||||||
createWindow(plugin);
|
createView(plugin, window);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const createWindow = (plugin) => {
|
const createView = (plugin, window: BrowserWindow) => {
|
||||||
win = new BrowserWindow({
|
const preload = commonConst.dev()
|
||||||
autoHideMenuBar: true,
|
? `http://localhost:8080/preload.js`
|
||||||
width: 850,
|
: path.resolve(plugin.indexPath, `../`, plugin.preload);
|
||||||
height: 700,
|
|
||||||
alwaysOnTop: true,
|
const ses = session.fromPartition("<" + plugin.name + ">");
|
||||||
focusable: true,
|
ses.setPreloads([`${__static}/preload.js`]);
|
||||||
show: false,
|
|
||||||
|
view = new BrowserView({
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
enableRemoteModule: true,
|
enableRemoteModule: true,
|
||||||
webSecurity: false,
|
webSecurity: false,
|
||||||
@ -24,24 +27,32 @@ export default () => {
|
|||||||
contextIsolation: false,
|
contextIsolation: false,
|
||||||
devTools: true,
|
devTools: true,
|
||||||
webviewTag: true,
|
webviewTag: true,
|
||||||
preload: `${__static}/preload.js`,
|
preload,
|
||||||
|
session: ses,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
win.loadURL(plugin.indexPath);
|
window.setBrowserView(view);
|
||||||
|
view.webContents.loadURL(plugin.indexPath);
|
||||||
win.once("ready-to-show", () => {
|
window.once("ready-to-show", () => {
|
||||||
win.show();
|
view.setBounds({ x: 0, y: 60, width: 800, height: 600 });
|
||||||
});
|
view.setAutoResize({ width: true });
|
||||||
|
window.setSize(800, 660);
|
||||||
win.on("closed", () => {
|
view.webContents.openDevTools();
|
||||||
win = undefined;
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const getWindow = () => win;
|
const removeView = (window: BrowserWindow) => {
|
||||||
|
if (!view) return;
|
||||||
|
window.removeBrowserView(view);
|
||||||
|
window.setSize(800, 60);
|
||||||
|
view = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getView = () => view;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
init,
|
init,
|
||||||
getWindow,
|
getView,
|
||||||
|
removeView,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -7,8 +7,12 @@ const API: any = {
|
|||||||
setExpendHeight({ height }: { height: number }, win: BrowserWindow): void {
|
setExpendHeight({ height }: { height: number }, win: BrowserWindow): void {
|
||||||
win.setSize(800, height || 60);
|
win.setSize(800, height || 60);
|
||||||
},
|
},
|
||||||
openPlugin({plugin}) {
|
openPlugin({ plugin }, window) {
|
||||||
runnerInstance.init(plugin);
|
runnerInstance.removeView(window);
|
||||||
|
runnerInstance.init(plugin, window);
|
||||||
|
},
|
||||||
|
removePlugin(e, window) {
|
||||||
|
runnerInstance.removeView(window);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,21 +1,36 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="components-layout">
|
<div id="components-layout">
|
||||||
<div class="rubick-select">
|
<div class="rubick-select">
|
||||||
<Search @changeCurrent="changeIndex" :menuPluginInfo="menuPluginInfo" @onSearch="onSearch" />
|
<Search
|
||||||
|
:currentPlugin="currentPlugin"
|
||||||
|
@changeCurrent="changeIndex"
|
||||||
|
@onSearch="onSearch"
|
||||||
|
@openMenu="openMenu"
|
||||||
|
@changeSelect="changeSelect"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Result :searchValue="searchValue" :currentSelect="currentSelect" :options="options" />
|
<Result :searchValue="searchValue" :currentSelect="currentSelect" :options="options" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { watch, ref, nextTick } from "vue";
|
import { watch, ref, nextTick, toRaw } from "vue";
|
||||||
import { ipcRenderer } from "electron";
|
import { ipcRenderer } from "electron";
|
||||||
import Result from "./components/result.vue";
|
import Result from "./components/result.vue";
|
||||||
import Search from "./components/search.vue";
|
import Search from "./components/search.vue";
|
||||||
import getWindowHeight from "../common/utils/getWindowHeight";
|
import getWindowHeight from "../common/utils/getWindowHeight";
|
||||||
import createPluginManager from "./plugins-manager";
|
import createPluginManager from "./plugins-manager";
|
||||||
|
|
||||||
const { initPlugins, getPluginInfo, options, onSearch, searchValue } = createPluginManager();
|
const {
|
||||||
|
initPlugins,
|
||||||
|
getPluginInfo,
|
||||||
|
options,
|
||||||
|
onSearch,
|
||||||
|
searchValue,
|
||||||
|
changeSelect,
|
||||||
|
openPlugin,
|
||||||
|
currentPlugin,
|
||||||
|
} = createPluginManager();
|
||||||
|
|
||||||
initPlugins();
|
initPlugins();
|
||||||
|
|
||||||
@ -49,6 +64,13 @@ const changeIndex = (index) => {
|
|||||||
return;
|
return;
|
||||||
currentSelect.value = currentSelect.value + index;
|
currentSelect.value = currentSelect.value + index;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const openMenu = () => {
|
||||||
|
openPlugin({
|
||||||
|
...toRaw(menuPluginInfo.value),
|
||||||
|
cmd: "插件市场",
|
||||||
|
});
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="rubick-select">
|
<div class="rubick-select">
|
||||||
|
<div class="select-tag" v-show="currentPlugin.cmd">{{ currentPlugin.cmd }}</div>
|
||||||
<a-input
|
<a-input
|
||||||
class="main-input"
|
class="main-input"
|
||||||
placeholder="Hi, Rubick2"
|
placeholder="Hi, Rubick2"
|
||||||
@change="(e) => emit('onSearch', e)"
|
@change="(e) => changeValue(e)"
|
||||||
@keydown.down="() => emit('changeCurrent', 1)"
|
@keydown.down="() => emit('changeCurrent', 1)"
|
||||||
@keydown.up="() => emit('changeCurrent', -1)"
|
@keydown.up="() => emit('changeCurrent', -1)"
|
||||||
|
@keydown="checkNeedInit"
|
||||||
>
|
>
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<div @click="openMenu" class="suffix-tool" >
|
<div @click="() => emit('openMenu')" class="suffix-tool" >
|
||||||
<div class="rubick-logo">
|
<div class="rubick-logo">
|
||||||
<img src="../assets/logo.png" />
|
<img src="../assets/logo.png" />
|
||||||
</div>
|
</div>
|
||||||
@ -19,19 +21,33 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineProps, defineEmits, toRaw } from "vue";
|
import { defineProps, defineEmits, ref } from "vue";
|
||||||
import { ipcRenderer } from "electron";
|
import { ipcRenderer } from "electron";
|
||||||
|
|
||||||
const props = defineProps({
|
defineProps({
|
||||||
menuPluginInfo: {},
|
currentPlugin: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(["onSearch", "changeCurrent"]);
|
const searchValue = ref("");
|
||||||
|
|
||||||
const openMenu = async () => {
|
const changeValue = (e) => {
|
||||||
ipcRenderer.sendSync("msg-trigger", {
|
emit("onSearch", e);
|
||||||
type: "openPlugin",
|
searchValue.value = e.target.value;
|
||||||
plugin: toRaw(props.menuPluginInfo),
|
};
|
||||||
|
|
||||||
|
const emit = defineEmits(["onSearch", "changeCurrent", "openMenu", "changeSelect"]);
|
||||||
|
|
||||||
|
const checkNeedInit = (e) => {
|
||||||
|
console.log(e.keyCode);
|
||||||
|
if (searchValue.value === "" && e.keyCode === 8) {
|
||||||
|
closeTag();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeTag = () => {
|
||||||
|
emit("changeSelect", {});
|
||||||
|
ipcRenderer.send("msg-trigger", {
|
||||||
|
type: "removePlugin",
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@ -45,6 +61,21 @@ const openMenu = async () => {
|
|||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
.select-tag {
|
||||||
|
white-space: pre;
|
||||||
|
user-select: none;
|
||||||
|
font-size: 18px;
|
||||||
|
border-radius: 16px;
|
||||||
|
height: 32px;
|
||||||
|
position: relative;
|
||||||
|
color: #fff;
|
||||||
|
background-color: rgba(255, 78, 164, 0.8);
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 1px;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
.main-input {
|
.main-input {
|
||||||
height: 60px !important;
|
height: 60px !important;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
@ -28,6 +28,7 @@ const createPluginManager = (): any => {
|
|||||||
options: [],
|
options: [],
|
||||||
searchValue: "",
|
searchValue: "",
|
||||||
localPlugins: [],
|
localPlugins: [],
|
||||||
|
currentPlugin: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
const initPlugins = async () => {
|
const initPlugins = async () => {
|
||||||
@ -67,16 +68,15 @@ const createPluginManager = (): any => {
|
|||||||
"node_modules",
|
"node_modules",
|
||||||
plugin.name
|
plugin.name
|
||||||
);
|
);
|
||||||
ipcRenderer.sendSync("msg-trigger", {
|
openPlugin({
|
||||||
type: "openPlugin",
|
|
||||||
plugin: {
|
|
||||||
...toRaw(plugin),
|
...toRaw(plugin),
|
||||||
indexPath: `file://${path.join(
|
indexPath: `file://${path.join(
|
||||||
pluginPath,
|
pluginPath,
|
||||||
"./",
|
"./",
|
||||||
plugin.main
|
plugin.main
|
||||||
)}`,
|
)}`,
|
||||||
},
|
cmd,
|
||||||
|
feature: fe,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
})),
|
})),
|
||||||
@ -111,7 +111,7 @@ const createPluginManager = (): any => {
|
|||||||
})
|
})
|
||||||
.map((plugin) => {
|
.map((plugin) => {
|
||||||
plugin.click = () => {
|
plugin.click = () => {
|
||||||
_openPlugin({ plugin });
|
openPlugin(plugin);
|
||||||
};
|
};
|
||||||
return plugin;
|
return plugin;
|
||||||
}),
|
}),
|
||||||
@ -129,8 +129,18 @@ const createPluginManager = (): any => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const _openPlugin = ({ plugin }) => {
|
const openPlugin = (plugin) => {
|
||||||
//
|
if (plugin.pluginType === "ui") {
|
||||||
|
state.currentPlugin = plugin;
|
||||||
|
ipcRenderer.sendSync("msg-trigger", {
|
||||||
|
type: "openPlugin",
|
||||||
|
plugin: JSON.parse(JSON.stringify(plugin)),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const changeSelect = (select) => {
|
||||||
|
state.currentPlugin = select;
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -140,6 +150,8 @@ const createPluginManager = (): any => {
|
|||||||
removePlugin,
|
removePlugin,
|
||||||
onSearch,
|
onSearch,
|
||||||
getPluginInfo,
|
getPluginInfo,
|
||||||
|
openPlugin,
|
||||||
|
changeSelect,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user