mirror of
https://github.com/rubickCenter/rubick
synced 2025-07-19 06:09:41 +08:00
✨ 支持本地启动,修改mac 下获取 APP icon 的方式
This commit is contained in:
parent
61b4e37fe0
commit
c21c08c370
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "rubick-system-feature",
|
"name": "rubick-system-feature",
|
||||||
"pluginName": "rubick 系统菜单",
|
"pluginName": "系统菜单",
|
||||||
"description": "rubick 系统菜单",
|
"description": "系统菜单",
|
||||||
"main": "index.html",
|
"main": "index.html",
|
||||||
"logo": "https://pic1.zhimg.com/80/v2-c09780808301668a82e6646cb42f0806_720w.png",
|
"logo": "https://pic1.zhimg.com/80/v2-c09780808301668a82e6646cb42f0806_720w.png",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
@ -10,19 +10,19 @@
|
|||||||
"features": [
|
"features": [
|
||||||
{
|
{
|
||||||
"code": "market",
|
"code": "market",
|
||||||
"explain": "rubick 插件市场",
|
"explain": "插件市场",
|
||||||
"cmds":[
|
"cmds":[
|
||||||
"插件市场"
|
"插件市场"
|
||||||
]
|
]
|
||||||
},{
|
},{
|
||||||
"code": "installed",
|
"code": "installed",
|
||||||
"explain": "rubick 已安装插件",
|
"explain": "已安装插件",
|
||||||
"cmds":[
|
"cmds":[
|
||||||
"已安装插件"
|
"已安装插件"
|
||||||
]
|
]
|
||||||
},{
|
},{
|
||||||
"code": "settings",
|
"code": "settings",
|
||||||
"explain": "rubick 偏好设置",
|
"explain": "偏好设置",
|
||||||
"cmds":[
|
"cmds":[
|
||||||
"偏好设置"
|
"偏好设置"
|
||||||
]
|
]
|
||||||
|
@ -1,4 +1,21 @@
|
|||||||
const remote = require('@electron/remote');
|
const remote = require('@electron/remote');
|
||||||
|
const { ipcRenderer } = require('electron');
|
||||||
|
|
||||||
|
const ipcSendSync = (type, data) => {
|
||||||
|
const returnValue = ipcRenderer.sendSync('msg-trigger', {
|
||||||
|
type,
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
if (returnValue instanceof Error) throw returnValue;
|
||||||
|
return returnValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ipcSend = (type, data) => {
|
||||||
|
ipcRenderer.send('msg-trigger', {
|
||||||
|
type,
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
window.market = {
|
window.market = {
|
||||||
getLocalPlugins() {
|
getLocalPlugins() {
|
||||||
@ -13,4 +30,10 @@ window.market = {
|
|||||||
refreshPlugin(plugin) {
|
refreshPlugin(plugin) {
|
||||||
return remote.getGlobal('LOCAL_PLUGINS').refreshPlugin(plugin);
|
return remote.getGlobal('LOCAL_PLUGINS').refreshPlugin(plugin);
|
||||||
},
|
},
|
||||||
|
addLocalStartPlugin(plugin) {
|
||||||
|
ipcSend('addLocalStartPlugin', { plugin });
|
||||||
|
},
|
||||||
|
removeLocalStartPlugin(plugin) {
|
||||||
|
ipcSend('removeLocalStartPlugin', { plugin });
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
@ -96,6 +96,9 @@ export default {
|
|||||||
accessToken: 'access token',
|
accessToken: 'access token',
|
||||||
placeholder: 'required for private network gitlab warehouse',
|
placeholder: 'required for private network gitlab warehouse',
|
||||||
},
|
},
|
||||||
|
localstart: {
|
||||||
|
title: 'Local Start',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
dev: {
|
dev: {
|
||||||
title: 'Developer',
|
title: 'Developer',
|
||||||
|
@ -94,6 +94,9 @@ export default {
|
|||||||
accessToken: 'access token',
|
accessToken: 'access token',
|
||||||
placeholder: '内网gitlab仓库必填',
|
placeholder: '内网gitlab仓库必填',
|
||||||
},
|
},
|
||||||
|
localstart: {
|
||||||
|
title: '本地启动',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
dev: {
|
dev: {
|
||||||
title: '开发者',
|
title: '开发者',
|
||||||
|
@ -14,6 +14,12 @@
|
|||||||
</template>
|
</template>
|
||||||
{{ $t('feature.settings.basic.title') }}
|
{{ $t('feature.settings.basic.title') }}
|
||||||
</a-menu-item>
|
</a-menu-item>
|
||||||
|
<a-menu-item key="localstart">
|
||||||
|
<template #icon>
|
||||||
|
<FolderOpenOutlined />
|
||||||
|
</template>
|
||||||
|
{{ $t('feature.settings.localstart.title') }}
|
||||||
|
</a-menu-item>
|
||||||
<a-menu-item key="global">
|
<a-menu-item key="global">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<LaptopOutlined />
|
<LaptopOutlined />
|
||||||
@ -220,6 +226,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<SuperPanel v-if="currentSelect[0] === 'superpanel'" />
|
<SuperPanel v-if="currentSelect[0] === 'superpanel'" />
|
||||||
<Localhost v-if="currentSelect[0] === 'localhost'" />
|
<Localhost v-if="currentSelect[0] === 'localhost'" />
|
||||||
|
<LocalStart v-if="currentSelect[0] === 'localstart'" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -232,6 +239,7 @@ import {
|
|||||||
MinusCircleOutlined,
|
MinusCircleOutlined,
|
||||||
PlusCircleOutlined,
|
PlusCircleOutlined,
|
||||||
UserOutlined,
|
UserOutlined,
|
||||||
|
FolderOpenOutlined,
|
||||||
} from '@ant-design/icons-vue';
|
} from '@ant-design/icons-vue';
|
||||||
import debounce from 'lodash.debounce';
|
import debounce from 'lodash.debounce';
|
||||||
import { ref, reactive, watch, toRefs, computed } from 'vue';
|
import { ref, reactive, watch, toRefs, computed } from 'vue';
|
||||||
@ -239,6 +247,7 @@ import keycodes from './keycode';
|
|||||||
import Localhost from './localhost.vue';
|
import Localhost from './localhost.vue';
|
||||||
import SuperPanel from './super-panel.vue';
|
import SuperPanel from './super-panel.vue';
|
||||||
import UserInfo from './user-info';
|
import UserInfo from './user-info';
|
||||||
|
import LocalStart from './local-start';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import localConfig from '@/confOp';
|
import localConfig from '@/confOp';
|
||||||
|
|
||||||
|
71
feature/src/views/settings/local-start.vue
Normal file
71
feature/src/views/settings/local-start.vue
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
<template>
|
||||||
|
<div class="file-container" @drop.prevent="dropFile" @dragenter="checkDrop" @dragover="checkDrop">
|
||||||
|
<a-alert message="可拖放文件夹到这里加入启动" type="info" show-icon />
|
||||||
|
<a-list item-layout="horizontal" :data-source="localStartList">
|
||||||
|
<template #renderItem="{ item }">
|
||||||
|
<a-list-item>
|
||||||
|
<template #actions>
|
||||||
|
<a key="list-loadmore-edit" @click="() => remove(item)">移除</a>
|
||||||
|
</template>
|
||||||
|
<a-list-item-meta :description="item.desc">
|
||||||
|
<template #title>
|
||||||
|
<div>{{item.name}}</div>
|
||||||
|
</template>
|
||||||
|
<template #avatar>
|
||||||
|
<a-avatar shape="square" :src="item.icon" />
|
||||||
|
</template>
|
||||||
|
</a-list-item-meta>
|
||||||
|
</a-list-item>
|
||||||
|
</template>
|
||||||
|
</a-list>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
const dbId = 'rubick-local-start-app';
|
||||||
|
|
||||||
|
const localStartList = ref(window.rubick.dbStorage.getItem(dbId) || []);
|
||||||
|
|
||||||
|
const dropFile = (e) => {
|
||||||
|
const files = Array.from(e.dataTransfer.files).map((file) => {
|
||||||
|
const plugin = {
|
||||||
|
icon: window.rubick.getFileIcon(file.path),
|
||||||
|
value: 'plugin',
|
||||||
|
desc: file.path,
|
||||||
|
pluginType: 'app',
|
||||||
|
name: file.name,
|
||||||
|
action: `open ${file.path.replace(/ /g, '\\ ')}`,
|
||||||
|
keyWords: [file.name],
|
||||||
|
names: [file.name],
|
||||||
|
};
|
||||||
|
window.market.addLocalStartPlugin(plugin);
|
||||||
|
return plugin;
|
||||||
|
});
|
||||||
|
localStartList.value = [
|
||||||
|
...localStartList.value,
|
||||||
|
...files,
|
||||||
|
];
|
||||||
|
window.rubick.dbStorage.setItem(dbId, JSON.parse(JSON.stringify(localStartList.value)));
|
||||||
|
};
|
||||||
|
|
||||||
|
const remove = (item) => {
|
||||||
|
localStartList.value = localStartList.value.filter(app => app.desc !== item.desc);
|
||||||
|
window.rubick.dbStorage.setItem(dbId, JSON.parse(JSON.stringify(localStartList.value)));
|
||||||
|
window.market.removeLocalStartPlugin(JSON.parse(JSON.stringify(item)));
|
||||||
|
};
|
||||||
|
|
||||||
|
const checkDrop = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
.file-container {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
overflow-x: hidden;
|
||||||
|
background: var(--color-body-bg);
|
||||||
|
height: calc(~'100vh - 106px');
|
||||||
|
}
|
||||||
|
</style>
|
@ -33,6 +33,7 @@
|
|||||||
"lodash.throttle": "^4.1.1",
|
"lodash.throttle": "^4.1.1",
|
||||||
"node-key-sender": "^1.0.11",
|
"node-key-sender": "^1.0.11",
|
||||||
"pouchdb": "^7.2.2",
|
"pouchdb": "^7.2.2",
|
||||||
|
"simple-plist": "0.2.1",
|
||||||
"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",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "rubick-system-feature",
|
"name": "rubick-system-feature",
|
||||||
"pluginName": "rubick 系统菜单",
|
"pluginName": "系统菜单",
|
||||||
"description": "rubick 系统菜单",
|
"description": "系统菜单",
|
||||||
"main": "index.html",
|
"main": "index.html",
|
||||||
"logo": "https://pic1.zhimg.com/80/v2-c09780808301668a82e6646cb42f0806_720w.png",
|
"logo": "https://pic1.zhimg.com/80/v2-c09780808301668a82e6646cb42f0806_720w.png",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
@ -10,19 +10,19 @@
|
|||||||
"features": [
|
"features": [
|
||||||
{
|
{
|
||||||
"code": "market",
|
"code": "market",
|
||||||
"explain": "rubick 插件市场",
|
"explain": "插件市场",
|
||||||
"cmds":[
|
"cmds":[
|
||||||
"插件市场"
|
"插件市场"
|
||||||
]
|
]
|
||||||
},{
|
},{
|
||||||
"code": "installed",
|
"code": "installed",
|
||||||
"explain": "rubick 已安装插件",
|
"explain": "已安装插件",
|
||||||
"cmds":[
|
"cmds":[
|
||||||
"已安装插件"
|
"已安装插件"
|
||||||
]
|
]
|
||||||
},{
|
},{
|
||||||
"code": "settings",
|
"code": "settings",
|
||||||
"explain": "rubick 偏好设置",
|
"explain": "偏好设置",
|
||||||
"cmds":[
|
"cmds":[
|
||||||
"偏好设置"
|
"偏好设置"
|
||||||
]
|
]
|
||||||
|
@ -1,4 +1,21 @@
|
|||||||
const remote = require('@electron/remote');
|
const remote = require('@electron/remote');
|
||||||
|
const { ipcRenderer } = require('electron');
|
||||||
|
|
||||||
|
const ipcSendSync = (type, data) => {
|
||||||
|
const returnValue = ipcRenderer.sendSync('msg-trigger', {
|
||||||
|
type,
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
if (returnValue instanceof Error) throw returnValue;
|
||||||
|
return returnValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ipcSend = (type, data) => {
|
||||||
|
ipcRenderer.send('msg-trigger', {
|
||||||
|
type,
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
window.market = {
|
window.market = {
|
||||||
getLocalPlugins() {
|
getLocalPlugins() {
|
||||||
@ -13,4 +30,10 @@ window.market = {
|
|||||||
refreshPlugin(plugin) {
|
refreshPlugin(plugin) {
|
||||||
return remote.getGlobal('LOCAL_PLUGINS').refreshPlugin(plugin);
|
return remote.getGlobal('LOCAL_PLUGINS').refreshPlugin(plugin);
|
||||||
},
|
},
|
||||||
|
addLocalStartPlugin(plugin) {
|
||||||
|
ipcSend('addLocalStartPlugin', { plugin });
|
||||||
|
},
|
||||||
|
removeLocalStartPlugin(plugin) {
|
||||||
|
ipcSend('removeLocalStartPlugin', { plugin });
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
const WINDOW_MAX_HEIGHT = 600;
|
const WINDOW_MAX_HEIGHT = 600;
|
||||||
const WINDOW_MIN_HEIGHT = 60;
|
const WINDOW_MIN_HEIGHT = 60;
|
||||||
const PRE_ITEM_HEIGHT = 60;
|
const PRE_ITEM_HEIGHT = 60;
|
||||||
|
const HISTORY_HEIGHT = 80;
|
||||||
|
|
||||||
export default (searchList: Array<any>): number => {
|
export default (searchList: Array<any>, historyList): number => {
|
||||||
if (!searchList) return WINDOW_MAX_HEIGHT;
|
const defaultHeight = historyList.length ? HISTORY_HEIGHT : 0;
|
||||||
if (!searchList.length) return WINDOW_MIN_HEIGHT;
|
if (!searchList) return WINDOW_MAX_HEIGHT + defaultHeight;
|
||||||
return searchList.length * PRE_ITEM_HEIGHT + WINDOW_MIN_HEIGHT + 5 >
|
if (!searchList.length) return WINDOW_MIN_HEIGHT + defaultHeight;
|
||||||
|
return searchList.length * PRE_ITEM_HEIGHT + WINDOW_MIN_HEIGHT >
|
||||||
WINDOW_MAX_HEIGHT
|
WINDOW_MAX_HEIGHT
|
||||||
? WINDOW_MAX_HEIGHT
|
? WINDOW_MAX_HEIGHT
|
||||||
: searchList.length * PRE_ITEM_HEIGHT + WINDOW_MIN_HEIGHT + 5;
|
: searchList.length * PRE_ITEM_HEIGHT + WINDOW_MIN_HEIGHT;
|
||||||
};
|
};
|
||||||
|
@ -16,16 +16,7 @@ if (!exists) {
|
|||||||
|
|
||||||
const isZhRegex = /[\u4e00-\u9fa5]/;
|
const isZhRegex = /[\u4e00-\u9fa5]/;
|
||||||
|
|
||||||
async function getAppIcon(
|
async function getAppIcon(appPath: string, nativeImage: any, name: string) {
|
||||||
appPath: string,
|
|
||||||
nativeImage: {
|
|
||||||
createThumbnailFromPath: (
|
|
||||||
iconPath: string,
|
|
||||||
size: { width: number; height: number }
|
|
||||||
) => { toDataURL: () => string };
|
|
||||||
},
|
|
||||||
name: string
|
|
||||||
) {
|
|
||||||
try {
|
try {
|
||||||
const iconpath = path.join(icondir, `${name}.png`);
|
const iconpath = path.join(icondir, `${name}.png`);
|
||||||
const iconnone = path.join(icondir, `${name}.none`);
|
const iconnone = path.join(icondir, `${name}.none`);
|
||||||
@ -33,52 +24,40 @@ async function getAppIcon(
|
|||||||
const existsnone = fs.existsSync(iconnone);
|
const existsnone = fs.existsSync(iconnone);
|
||||||
if (exists) return true;
|
if (exists) return true;
|
||||||
if (existsnone) return false;
|
if (existsnone) return false;
|
||||||
const appName: string = appPath.split('/').pop() || '';
|
// const appName: string = appPath.split('/').pop() || '';
|
||||||
const extname: string = path.extname(appName);
|
// const extname: string = path.extname(appName);
|
||||||
const appSubStr: string = appName.split(extname)[0];
|
// const appSubStr: string = appName.split(extname)[0];
|
||||||
const path1 = path.join(appPath, `/Contents/Resources/App.icns`);
|
// const path1 = path.join(appPath, `/Contents/Resources/App.icns`);
|
||||||
const path2 = path.join(appPath, `/Contents/Resources/AppIcon.icns`);
|
// const path2 = path.join(appPath, `/Contents/Resources/AppIcon.icns`);
|
||||||
const path3 = path.join(appPath, `/Contents/Resources/${appSubStr}.icns`);
|
// const path3 = path.join(appPath, `/Contents/Resources/${appSubStr}.icns`);
|
||||||
const path4 = path.join(
|
// const path4 = path.join(
|
||||||
appPath,
|
// appPath,
|
||||||
`/Contents/Resources/${appSubStr.replace(' ', '')}.icns`
|
// `/Contents/Resources/${appSubStr.replace(' ', '')}.icns`
|
||||||
);
|
// );
|
||||||
let iconPath: string = path1;
|
// let iconPath: string = path1;
|
||||||
if (fs.existsSync(path1)) {
|
// if (fs.existsSync(path1)) {
|
||||||
iconPath = path1;
|
// iconPath = path1;
|
||||||
} else if (fs.existsSync(path2)) {
|
// } else if (fs.existsSync(path2)) {
|
||||||
iconPath = path2;
|
// iconPath = path2;
|
||||||
} else if (fs.existsSync(path3)) {
|
// } else if (fs.existsSync(path3)) {
|
||||||
iconPath = path3;
|
// iconPath = path3;
|
||||||
} else if (fs.existsSync(path4)) {
|
// } else if (fs.existsSync(path4)) {
|
||||||
iconPath = path4;
|
// iconPath = path4;
|
||||||
} else {
|
// } else {
|
||||||
// 性能最低的方式
|
// // 性能最低的方式
|
||||||
const resourceList = fs.readdirSync(
|
// const resourceList = fs.readdirSync(
|
||||||
path.join(appPath, `/Contents/Resources`)
|
// path.join(appPath, `/Contents/Resources`)
|
||||||
);
|
// );
|
||||||
const iconName = resourceList.filter(
|
// const iconName = resourceList.filter(
|
||||||
(file) => path.extname(file) === '.icns'
|
// (file) => path.extname(file) === '.icns'
|
||||||
)[0];
|
// )[0];
|
||||||
if (!iconName) {
|
// if (!iconName) {
|
||||||
fs.writeFileSync(iconnone, '');
|
// fs.writeFileSync(iconnone, '');
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
iconPath = path.join(appPath, `/Contents/Resources/${iconName}`);
|
// iconPath = path.join(appPath, `/Contents/Resources/${iconName}`);
|
||||||
}
|
// }
|
||||||
const img = await nativeImage.createThumbnailFromPath(iconPath, {
|
await getMacApps.app2png(appPath, iconpath);
|
||||||
width: 64,
|
|
||||||
height: 64,
|
|
||||||
});
|
|
||||||
|
|
||||||
const base64Data = img.toDataURL().replace(/^data:.+;base64,/, '"');
|
|
||||||
|
|
||||||
const result = Buffer.from(base64Data, 'base64');
|
|
||||||
|
|
||||||
fs.writeFile(iconpath, result, 'base64', () => {
|
|
||||||
// todo
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return false;
|
return false;
|
||||||
|
109
src/core/app-search/get-mac-app/app2png.ts
Normal file
109
src/core/app-search/get-mac-app/app2png.ts
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
import path from 'path';
|
||||||
|
import fs from 'fs';
|
||||||
|
import { exec } from 'child_process';
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
|
const plist = require('simple-plist');
|
||||||
|
|
||||||
|
const getIconFile = (appFileInput) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const plistPath = path.join(appFileInput, 'Contents', 'Info.plist');
|
||||||
|
plist.readFile(plistPath, (err, data) => {
|
||||||
|
if (err || !data.CFBundleIconFile) {
|
||||||
|
return resolve(
|
||||||
|
'/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/GenericApplicationIcon.icns'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
const iconFile = path.join(
|
||||||
|
appFileInput,
|
||||||
|
'Contents',
|
||||||
|
'Resources',
|
||||||
|
data.CFBundleIconFile
|
||||||
|
);
|
||||||
|
const iconFiles = [iconFile, iconFile + '.icns', iconFile + '.tiff'];
|
||||||
|
const existedIcon = iconFiles.find((iconFile) => {
|
||||||
|
return fs.existsSync(iconFile);
|
||||||
|
});
|
||||||
|
resolve(
|
||||||
|
existedIcon ||
|
||||||
|
'/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/GenericApplicationIcon.icns'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 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(
|
||||||
|
`sips -s format png '${iconFile}' --out '${pngFileOutput}' --resampleHeightWidth 64 64`,
|
||||||
|
(error) => {
|
||||||
|
error ? reject(error) : resolve(null);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const app2png = (appFileInput, pngFileOutput) => {
|
||||||
|
return getIconFile(appFileInput).then((iconFile) => {
|
||||||
|
return tiffToPng(iconFile, pngFileOutput);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export default app2png;
|
@ -1,4 +1,5 @@
|
|||||||
import getApps from "./getApps";
|
import getApps from './getApps';
|
||||||
|
import app2png from './app2png';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getApps: () => {
|
getApps: () => {
|
||||||
@ -7,4 +8,5 @@ export default {
|
|||||||
isInstalled: (appName) => {
|
isInstalled: (appName) => {
|
||||||
return new Promise((resolve, reject) => getApps(resolve, reject, appName));
|
return new Promise((resolve, reject) => getApps(resolve, reject, appName));
|
||||||
},
|
},
|
||||||
|
app2png,
|
||||||
};
|
};
|
||||||
|
@ -319,6 +319,22 @@ class API extends DBInstance {
|
|||||||
ks.sendKeys(keys);
|
ks.sendKeys(keys);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public addLocalStartPlugin({ data: { plugin } }, window) {
|
||||||
|
window.webContents.executeJavaScript(
|
||||||
|
`window.addLocalStartPlugin(${JSON.stringify({
|
||||||
|
plugin,
|
||||||
|
})})`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeLocalStartPlugin({ data: { plugin } }, window) {
|
||||||
|
window.webContents.executeJavaScript(
|
||||||
|
`window.removeLocalStartPlugin(${JSON.stringify({
|
||||||
|
plugin,
|
||||||
|
})})`
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new API();
|
export default new API();
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
:searchValue="searchValue"
|
:searchValue="searchValue"
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
:pluginLoading="pluginLoading"
|
:pluginLoading="pluginLoading"
|
||||||
|
:pluginHistory="pluginHistory"
|
||||||
:clipboardFile="clipboardFile || []"
|
:clipboardFile="clipboardFile || []"
|
||||||
@choosePlugin="choosePlugin"
|
@choosePlugin="choosePlugin"
|
||||||
@focus="searchFocus"
|
@focus="searchFocus"
|
||||||
@ -20,6 +21,7 @@
|
|||||||
@readClipboardContent="readClipboardContent"
|
@readClipboardContent="readClipboardContent"
|
||||||
/>
|
/>
|
||||||
<Result
|
<Result
|
||||||
|
:pluginHistory="pluginHistory"
|
||||||
:currentPlugin="currentPlugin"
|
:currentPlugin="currentPlugin"
|
||||||
:searchValue="searchValue"
|
:searchValue="searchValue"
|
||||||
:currentSelect="currentSelect"
|
:currentSelect="currentSelect"
|
||||||
@ -37,7 +39,6 @@ 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';
|
||||||
import useDrag from '../common/utils/dragWindow';
|
import useDrag from '../common/utils/dragWindow';
|
||||||
import commonConst from '@/common/utils/commonConst';
|
|
||||||
|
|
||||||
const { onMouseDown } = useDrag();
|
const { onMouseDown } = useDrag();
|
||||||
const remote = window.require('@electron/remote');
|
const remote = window.require('@electron/remote');
|
||||||
@ -58,6 +59,7 @@ const {
|
|||||||
setSearchValue,
|
setSearchValue,
|
||||||
clearClipboardFile,
|
clearClipboardFile,
|
||||||
readClipboardContent,
|
readClipboardContent,
|
||||||
|
pluginHistory,
|
||||||
} = createPluginManager();
|
} = createPluginManager();
|
||||||
|
|
||||||
initPlugins();
|
initPlugins();
|
||||||
@ -74,24 +76,37 @@ getPluginInfo({
|
|||||||
remote.getGlobal('LOCAL_PLUGINS').addPlugin(res);
|
remote.getGlobal('LOCAL_PLUGINS').addPlugin(res);
|
||||||
});
|
});
|
||||||
|
|
||||||
watch([options], () => {
|
watch([options, pluginHistory], () => {
|
||||||
currentSelect.value = 0;
|
currentSelect.value = 0;
|
||||||
if (currentPlugin.value.name) return;
|
if (currentPlugin.value.name) return;
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
ipcRenderer.sendSync('msg-trigger', {
|
ipcRenderer.sendSync('msg-trigger', {
|
||||||
type: 'setExpendHeight',
|
type: 'setExpendHeight',
|
||||||
data: getWindowHeight(options.value),
|
data: getWindowHeight(options.value, pluginHistory.value),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const changeIndex = (index) => {
|
const changeIndex = (index) => {
|
||||||
if (!options.value.length) return;
|
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 (
|
if (
|
||||||
currentSelect.value + index > options.value.length - 1 ||
|
currentSelect.value + index > options.value.length - 1 ||
|
||||||
currentSelect.value + index < 0
|
currentSelect.value + index < 0
|
||||||
)
|
) {
|
||||||
|
currentSelect.value = 0;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
currentSelect.value = currentSelect.value + index;
|
currentSelect.value = currentSelect.value + index;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -101,14 +116,20 @@ const openMenu = (ext) => {
|
|||||||
feature: menuPluginInfo.value.features[0],
|
feature: menuPluginInfo.value.features[0],
|
||||||
cmd: '插件市场',
|
cmd: '插件市场',
|
||||||
ext,
|
ext,
|
||||||
|
click: () => openMenu(ext),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
window.rubick.openMenu = openMenu;
|
window.rubick.openMenu = openMenu;
|
||||||
|
|
||||||
const choosePlugin = () => {
|
const choosePlugin = () => {
|
||||||
|
if (options.value.length) {
|
||||||
const currentChoose = options.value[currentSelect.value];
|
const currentChoose = options.value[currentSelect.value];
|
||||||
currentChoose.click();
|
currentChoose.click();
|
||||||
|
} else {
|
||||||
|
const currentChoose = pluginHistory.value[currentSelect.value];
|
||||||
|
currentChoose.click();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const clearSearchValue = () => {
|
const clearSearchValue = () => {
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
// 背景色
|
// 背景色
|
||||||
--color-body-bg: #fff;
|
--color-body-bg: #fff;
|
||||||
--color-menu-bg: #f3efef;
|
--color-menu-bg: #f3efef;
|
||||||
--color-list-hover: #e2e2e2;
|
--color-list-hover: #ebeee8;
|
||||||
--color-input-hover: #fff;
|
--color-input-hover: #fff;
|
||||||
// 边框
|
// 边框
|
||||||
--color-border-light: #f0f0f0;
|
--color-border-light: #f0f0f0;
|
||||||
|
@ -1,14 +1,24 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
v-show="
|
v-show="!currentPlugin.name"
|
||||||
!!options.length &&
|
|
||||||
(searchValue || !!clipboardFile.length) &&
|
|
||||||
!currentPlugin.name
|
|
||||||
"
|
|
||||||
class="options"
|
class="options"
|
||||||
ref="scrollDom"
|
ref="scrollDom"
|
||||||
>
|
>
|
||||||
<a-list item-layout="horizontal" :dataSource="sort(options)">
|
<div class="history-plugins" v-if="!options.length || !(searchValue || !!clipboardFile.length)">
|
||||||
|
<a-row>
|
||||||
|
<a-col
|
||||||
|
@click="() => item.click()"
|
||||||
|
:class="currentSelect === index ? 'active history-item' : 'history-item'"
|
||||||
|
:span="3"
|
||||||
|
v-for="(item, index) in pluginHistory"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<a-avatar style="border-radius: 0" :src="item.icon" />
|
||||||
|
<div class="name ellpise">{{item.pluginName || item._name || item.name}}</div>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</div>
|
||||||
|
<a-list v-else item-layout="horizontal" :dataSource="sort(options)">
|
||||||
<template #renderItem="{ item, index }">
|
<template #renderItem="{ item, index }">
|
||||||
<a-list-item
|
<a-list-item
|
||||||
@click="() => item.click()"
|
@click="() => item.click()"
|
||||||
@ -52,6 +62,7 @@ const props = defineProps({
|
|||||||
default: 0,
|
default: 0,
|
||||||
},
|
},
|
||||||
currentPlugin: {},
|
currentPlugin: {},
|
||||||
|
pluginHistory: (() => [])(),
|
||||||
clipboardFile: (() => [])(),
|
clipboardFile: (() => [])(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -91,15 +102,45 @@ const sort = (options) => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
|
.ellpise {
|
||||||
|
overflow:hidden;
|
||||||
|
text-overflow:ellipsis;
|
||||||
|
display:-webkit-box;
|
||||||
|
-webkit-line-clamp:1;
|
||||||
|
-webkit-box-orient:vertical;
|
||||||
|
}
|
||||||
|
|
||||||
.options {
|
.options {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 62px;
|
top: 60px;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 99;
|
z-index: 99;
|
||||||
max-height: calc(~'100vh - 64px');
|
max-height: calc(~'100vh - 60px');
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
background: var(--color-body-bg);
|
background: var(--color-body-bg);
|
||||||
|
.history-plugins {
|
||||||
|
width: 100%;
|
||||||
|
border-top: 1px dashed #ddd;
|
||||||
|
box-sizing: border-box;
|
||||||
|
.history-item {
|
||||||
|
box-sizing: border-box;
|
||||||
|
height: 79px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
border-right: 1px dashed #ddd;
|
||||||
|
&.active {
|
||||||
|
background: var(--color-list-hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.name {
|
||||||
|
margin-top: 4px;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
.op-item {
|
.op-item {
|
||||||
padding: 0 10px;
|
padding: 0 10px;
|
||||||
height: 60px;
|
height: 60px;
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
class="main-input"
|
class="main-input"
|
||||||
@input="e => changeValue(e)"
|
@input="e => changeValue(e)"
|
||||||
@keydown.down="e => keydownEvent(e, 'down')"
|
@keydown.down="e => keydownEvent(e, 'down')"
|
||||||
|
@keydown.tab="e => keydownEvent(e, 'down')"
|
||||||
@keydown.up="e => keydownEvent(e, 'up')"
|
@keydown.up="e => keydownEvent(e, 'up')"
|
||||||
@keydown="e => checkNeedInit(e)"
|
@keydown="e => checkNeedInit(e)"
|
||||||
:value="searchValue"
|
:value="searchValue"
|
||||||
@ -71,6 +72,7 @@ const props: any = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
pluginHistory: (() => [])(),
|
||||||
currentPlugin: {},
|
currentPlugin: {},
|
||||||
pluginLoading: Boolean,
|
pluginLoading: Boolean,
|
||||||
clipboardFile: (() => [])(),
|
clipboardFile: (() => [])(),
|
||||||
@ -107,7 +109,7 @@ const keydownEvent = (e, key: string) => {
|
|||||||
modifiers,
|
modifiers,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
const runPluginDisable = e.target.value === '' || props.currentPlugin.name;
|
const runPluginDisable = ((e.target.value === '' && !props.pluginHistory.length) || props.currentPlugin.name) ;
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'up':
|
case 'up':
|
||||||
emit('changeCurrent', -1);
|
emit('changeCurrent', -1);
|
||||||
|
@ -7,6 +7,8 @@ import {
|
|||||||
Avatar,
|
Avatar,
|
||||||
Tag,
|
Tag,
|
||||||
ConfigProvider,
|
ConfigProvider,
|
||||||
|
Row,
|
||||||
|
Col,
|
||||||
} from 'ant-design-vue';
|
} from 'ant-design-vue';
|
||||||
import App from './App.vue';
|
import App from './App.vue';
|
||||||
import localConfig from './confOp';
|
import localConfig from './confOp';
|
||||||
@ -26,4 +28,6 @@ createApp(App)
|
|||||||
.use(Input)
|
.use(Input)
|
||||||
.use(Avatar)
|
.use(Avatar)
|
||||||
.use(Tag)
|
.use(Tag)
|
||||||
|
.use(Row)
|
||||||
|
.use(Col)
|
||||||
.mount('#app');
|
.mount('#app');
|
||||||
|
@ -56,7 +56,7 @@ export default ({ currentPlugin, optionsRef, openPlugin, setOptionsRef }) => {
|
|||||||
regImg.test(ext) &&
|
regImg.test(ext) &&
|
||||||
fileList.length === 1
|
fileList.length === 1
|
||||||
) {
|
) {
|
||||||
options.push({
|
const option = {
|
||||||
name: cmd.label,
|
name: cmd.label,
|
||||||
value: 'plugin',
|
value: 'plugin',
|
||||||
icon: plugin.logo,
|
icon: plugin.logo,
|
||||||
@ -75,17 +75,19 @@ export default ({ currentPlugin, optionsRef, openPlugin, setOptionsRef }) => {
|
|||||||
.toDataURL(),
|
.toDataURL(),
|
||||||
},
|
},
|
||||||
openPlugin,
|
openPlugin,
|
||||||
|
option,
|
||||||
});
|
});
|
||||||
clearClipboardFile();
|
clearClipboardFile();
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
|
options.push(option);
|
||||||
}
|
}
|
||||||
// 如果是文件,且符合文件正则类型
|
// 如果是文件,且符合文件正则类型
|
||||||
if (
|
if (
|
||||||
fileList.length > 1 ||
|
fileList.length > 1 ||
|
||||||
(cmd.type === 'file' && new RegExp(cmd.match).test(ext))
|
(cmd.type === 'file' && new RegExp(cmd.match).test(ext))
|
||||||
) {
|
) {
|
||||||
options.push({
|
const option = {
|
||||||
name: cmd,
|
name: cmd,
|
||||||
value: 'plugin',
|
value: 'plugin',
|
||||||
icon: plugin.logo,
|
icon: plugin.logo,
|
||||||
@ -96,6 +98,7 @@ export default ({ currentPlugin, optionsRef, openPlugin, setOptionsRef }) => {
|
|||||||
plugin,
|
plugin,
|
||||||
fe,
|
fe,
|
||||||
cmd,
|
cmd,
|
||||||
|
option,
|
||||||
ext: {
|
ext: {
|
||||||
code: fe.code,
|
code: fe.code,
|
||||||
type: cmd.type || 'text',
|
type: cmd.type || 'text',
|
||||||
@ -105,7 +108,8 @@ export default ({ currentPlugin, optionsRef, openPlugin, setOptionsRef }) => {
|
|||||||
});
|
});
|
||||||
clearClipboardFile();
|
clearClipboardFile();
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
|
options.push(option);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -155,7 +159,7 @@ export default ({ currentPlugin, optionsRef, openPlugin, setOptionsRef }) => {
|
|||||||
feature.forEach((fe) => {
|
feature.forEach((fe) => {
|
||||||
fe.cmds.forEach((cmd) => {
|
fe.cmds.forEach((cmd) => {
|
||||||
if (cmd.type === 'img') {
|
if (cmd.type === 'img') {
|
||||||
options.push({
|
const option = {
|
||||||
name: cmd.label,
|
name: cmd.label,
|
||||||
value: 'plugin',
|
value: 'plugin',
|
||||||
icon: plugin.logo,
|
icon: plugin.logo,
|
||||||
@ -172,10 +176,12 @@ export default ({ currentPlugin, optionsRef, openPlugin, setOptionsRef }) => {
|
|||||||
payload: dataUrl,
|
payload: dataUrl,
|
||||||
},
|
},
|
||||||
openPlugin,
|
openPlugin,
|
||||||
|
option,
|
||||||
});
|
});
|
||||||
clearClipboardFile();
|
clearClipboardFile();
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
|
options.push(option);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -21,12 +21,35 @@ const createPluginManager = (): any => {
|
|||||||
localPlugins: [],
|
localPlugins: [],
|
||||||
currentPlugin: {},
|
currentPlugin: {},
|
||||||
pluginLoading: false,
|
pluginLoading: false,
|
||||||
|
pluginHistory: [],
|
||||||
});
|
});
|
||||||
|
|
||||||
const appList = ref([]);
|
const appList: any = ref([]);
|
||||||
|
|
||||||
const initPlugins = async () => {
|
const initPlugins = async () => {
|
||||||
appList.value = await appSearch(nativeImage);
|
appList.value = await appSearch(nativeImage);
|
||||||
|
initLocalStartPlugin();
|
||||||
|
};
|
||||||
|
|
||||||
|
const initLocalStartPlugin = () => {
|
||||||
|
const result = ipcRenderer.sendSync('msg-trigger', {
|
||||||
|
type: 'dbGet',
|
||||||
|
data: {
|
||||||
|
id: 'rubick-local-start-app',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (result && result.value) {
|
||||||
|
appList.value = [...appList.value, ...result.value];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.removeLocalStartPlugin = ({ plugin }) => {
|
||||||
|
appList.value = appList.value.filter((app) => app.desc !== plugin.desc);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addLocalStartPlugin = ({ plugin }) => {
|
||||||
|
window.removeLocalStartPlugin({ plugin });
|
||||||
|
appList.value.push(plugin);
|
||||||
};
|
};
|
||||||
|
|
||||||
const loadPlugin = async (plugin) => {
|
const loadPlugin = async (plugin) => {
|
||||||
@ -43,7 +66,7 @@ const createPluginManager = (): any => {
|
|||||||
state.pluginLoading = false;
|
state.pluginLoading = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const openPlugin = async (plugin) => {
|
const openPlugin = async (plugin, option) => {
|
||||||
if (plugin.pluginType === 'ui' || plugin.pluginType === 'system') {
|
if (plugin.pluginType === 'ui' || plugin.pluginType === 'system') {
|
||||||
if (state.currentPlugin && state.currentPlugin.name === plugin.name) {
|
if (state.currentPlugin && state.currentPlugin.name === plugin.name) {
|
||||||
return;
|
return;
|
||||||
@ -66,6 +89,23 @@ const createPluginManager = (): any => {
|
|||||||
if (plugin.pluginType === 'app') {
|
if (plugin.pluginType === 'app') {
|
||||||
execSync(plugin.action);
|
execSync(plugin.action);
|
||||||
}
|
}
|
||||||
|
window.initRubick();
|
||||||
|
changePluginHistory({
|
||||||
|
...plugin,
|
||||||
|
...option,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const changePluginHistory = (plugin) => {
|
||||||
|
if (state.pluginHistory.length >= 8) {
|
||||||
|
state.pluginHistory.pop();
|
||||||
|
}
|
||||||
|
state.pluginHistory.forEach((p, index) => {
|
||||||
|
if (p.name === plugin.name) {
|
||||||
|
state.pluginHistory.splice(index, 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
state.pluginHistory.unshift(plugin);
|
||||||
};
|
};
|
||||||
|
|
||||||
const { searchValue, onSearch, setSearchValue, placeholder } =
|
const { searchValue, onSearch, setSearchValue, placeholder } =
|
||||||
|
@ -52,7 +52,8 @@ const optionsManager = ({
|
|||||||
const cmds = searchKeyValues(fe.cmds, value, strict);
|
const cmds = searchKeyValues(fe.cmds, value, strict);
|
||||||
options = [
|
options = [
|
||||||
...options,
|
...options,
|
||||||
...cmds.map((cmd) => ({
|
...cmds.map((cmd) => {
|
||||||
|
const option = {
|
||||||
name: cmd.label || cmd,
|
name: cmd.label || cmd,
|
||||||
value: 'plugin',
|
value: 'plugin',
|
||||||
icon: plugin.logo,
|
icon: plugin.logo,
|
||||||
@ -72,9 +73,12 @@ const optionsManager = ({
|
|||||||
}
|
}
|
||||||
: null,
|
: null,
|
||||||
openPlugin,
|
openPlugin,
|
||||||
|
option,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
})),
|
};
|
||||||
|
return option;
|
||||||
|
}),
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -106,13 +110,14 @@ const optionsManager = ({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map((plugin) => {
|
.map((plugin) => {
|
||||||
return {
|
const option = {
|
||||||
...plugin,
|
...plugin,
|
||||||
zIndex: 1,
|
zIndex: 1,
|
||||||
click: () => {
|
click: () => {
|
||||||
openPlugin(plugin);
|
openPlugin(plugin, option);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
return option;
|
||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
return options;
|
return options;
|
||||||
|
@ -3,7 +3,14 @@ import path from 'path';
|
|||||||
import { toRaw } from 'vue';
|
import { toRaw } from 'vue';
|
||||||
import commonConst from '@/common/utils/commonConst';
|
import commonConst from '@/common/utils/commonConst';
|
||||||
|
|
||||||
export default function pluginClickEvent({ plugin, fe, cmd, ext, openPlugin }) {
|
export default function pluginClickEvent({
|
||||||
|
plugin,
|
||||||
|
fe,
|
||||||
|
cmd,
|
||||||
|
ext,
|
||||||
|
openPlugin,
|
||||||
|
option,
|
||||||
|
}) {
|
||||||
const pluginPath = path.resolve(baseDir, 'node_modules', plugin.name);
|
const pluginPath = path.resolve(baseDir, 'node_modules', plugin.name);
|
||||||
const pluginDist = {
|
const pluginDist = {
|
||||||
...toRaw(plugin),
|
...toRaw(plugin),
|
||||||
@ -24,5 +31,5 @@ export default function pluginClickEvent({ plugin, fe, cmd, ext, openPlugin }) {
|
|||||||
? 'http://localhost:8081/#/'
|
? 'http://localhost:8081/#/'
|
||||||
: `file://${__static}/feature/index.html`;
|
: `file://${__static}/feature/index.html`;
|
||||||
}
|
}
|
||||||
openPlugin(pluginDist);
|
openPlugin(pluginDist, option);
|
||||||
}
|
}
|
||||||
|
2
src/renderer/shims-vue.d.ts
vendored
2
src/renderer/shims-vue.d.ts
vendored
@ -21,6 +21,8 @@ interface Window {
|
|||||||
loadPlugin: (plugin: any) => void;
|
loadPlugin: (plugin: any) => void;
|
||||||
updatePlugin: (plugin: any) => void;
|
updatePlugin: (plugin: any) => void;
|
||||||
initRubick: () => void;
|
initRubick: () => void;
|
||||||
|
addLocalStartPlugin: (plugin: any) => void;
|
||||||
|
removeLocalStartPlugin: (plugin: any) => void;
|
||||||
setCurrentPlugin: (plugin: any) => void;
|
setCurrentPlugin: (plugin: any) => void;
|
||||||
pluginLoaded: () => void;
|
pluginLoaded: () => void;
|
||||||
getMainInputInfo: () => any;
|
getMainInputInfo: () => any;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user