feat: 增加系统app搜索功能

This commit is contained in:
muwoo 2021-06-28 20:08:54 +08:00
parent 56bf86286c
commit 74f7f3ebdf
4 changed files with 122 additions and 6 deletions

View File

@ -16,7 +16,7 @@
id="search"
:placeholder="subPlaceHolder && selected && selected.key === 'plugin-container' ? subPlaceHolder : 'Hi, Rubick'"
class="main-input"
@change="e => onSearch({value: e.target.value})"
@change="e => search({value: e.target.value})"
:value="searchValue"
:maxLength="selected && selected.key !== 'plugin-container' ? 0 : 1000"
>
@ -33,7 +33,7 @@
<a-list-item-meta
:description="item.desc"
>
<span slot="title" >{{ item.name }}</span>
<span slot="title" v-html="renderTitle(item.name)" ></span>
<a-avatar
slot="avatar"
:src="item.icon"
@ -67,7 +67,7 @@
<script>
import {mapActions, mapMutations, mapState} from "vuex";
import {ipcRenderer, remote} from "electron";
import {getWindowHeight} from "./assets/common/utils";
import {getWindowHeight, debounce} from "./assets/common/utils";
const {Menu, MenuItem} = remote;
@ -75,7 +75,8 @@ export default {
data() {
return {
searchType: this.$route.query.searchType ? 'subWindow' : '',
query: this.$route.query
query: this.$route.query,
searchFn: null,
}
},
mounted() {
@ -89,6 +90,16 @@ export default {
methods: {
...mapActions('main', ['onSearch', 'showMainUI']),
...mapMutations('main', ['commonUpdate']),
search(v) {
if (!this.searchFn) {
this.searchFn = debounce(this.onSearch, 200);
}
this.searchFn(v);
},
renderTitle(title) {
const result = title.split(this.searchValue);
return `<div>${result[0]}<span style="color: red">${this.searchValue}</span>${result[1]}</div>`
},
checkNeedInit(e) {
// tag
if (this.searchValue === '' && e.keyCode === 8) {
@ -178,6 +189,9 @@ export default {
padding-top: 60px;
height: 100vh;
overflow: auto;
::-webkit-scrollbar {
width: 0;
}
}
.rubick-select, .rubick-select-subMenu {
display: flex;
@ -211,6 +225,8 @@ export default {
left: 0;
width: 100%;
z-index: 99;
max-height: calc(~'100vh - 60px');
overflow: auto;
.op-item {
padding: 0 10px;
height: 60px;

View File

@ -39,11 +39,18 @@ const SYSTEM_PLUGINS = [
],
"tag": 'rubick-screen-short-cut',
}
]
];
const APP_FINDER_PATH = [
'/System/Applications',
'/Applications',
'/System/Library/PreferencePanes',
];
export {
WINDOW_MAX_HEIGHT,
WINDOW_MIN_HEIGHT,
PRE_ITEM_HEIGHT,
SYSTEM_PLUGINS,
APP_FINDER_PATH,
}

View File

@ -5,6 +5,8 @@ import fs from 'fs';
import process from 'child_process';
import Store from 'electron-store';
import downloadFile from 'download';
import {nativeImage} from 'electron';
import {APP_FINDER_PATH} from './constans';
const store = new Store();
@ -148,6 +150,70 @@ function find(p, target = 'plugin.json') {
console.log(e);
}
}
const fileLists = [];
// 默认搜索目录
APP_FINDER_PATH.forEach((searchPath) => {
fs.readdir(searchPath, (err, files) => {
try {
for (let i = 0; i < files.length; i++) {
const appName = files[i];
const extname = path.extname(appName);
const appSubStr = appName.split(extname)[0];
if ((extname === '.app' || extname === '.prefPane') >= 0 ) {
try {
const path1 = path.join(searchPath, `${appName}/Contents/Resources/App.icns`);
const path2 = path.join(searchPath, `${appName}/Contents/Resources/AppIcon.icns`);
const path3 = path.join(searchPath, `${appName}/Contents/Resources/${appSubStr}.icns`);
const path4 = path.join(searchPath, `${appName}/Contents/Resources/${appSubStr.replace(' ', '')}.icns`);
let iconPath = path1;
if (fs.existsSync(path1)) {
iconPath = path1;
} else if (fs.existsSync(path2)) {
iconPath = path2;
} else if (fs.existsSync(path3)) {
iconPath = path3;
} else if (fs.existsSync(path4)) {
iconPath = path4;
} else {
// 性能最低的方式
const resourceList = fs.readdirSync(path.join(searchPath, `${appName}/Contents/Resources`));
const iconName = resourceList.filter(file => path.extname(file) === '.icns')[0];
iconPath = path.join(searchPath, `${appName}/Contents/Resources/${iconName}`);
}
nativeImage.createThumbnailFromPath(iconPath, {width: 64, height: 64}).then(img => {
fileLists.push({
name: appSubStr,
value: 'plugin',
icon: img.toDataURL(),
desc: path.join(searchPath, appName),
type: 'app',
action: `open ${path.join(searchPath, appName).replace(' ', '\\ ')}`
})
})
} catch (e) {
}
}
}
} catch (e) {
console.log(e);
}
});
});
function debounce(fn, delay) {
let timer
return function () {
const context = this
const args = arguments
clearTimeout(timer)
timer = setTimeout(function () {
fn.apply(context, args)
}, delay)
}
}
export {
getWindowHeight,
@ -157,4 +223,6 @@ export {
mergePlugins,
find,
downloadZip,
fileLists,
debounce,
}

View File

@ -8,10 +8,12 @@ import {
mergePlugins,
find,
downloadZip,
fileLists,
} from '../../assets/common/utils';
import systemMethod from '../../assets/common/system';
import fs from "fs";
import path from 'path';
import {execSync} from 'child_process';
const state = {
selected: null,
@ -89,7 +91,7 @@ const actions = {
})
})
},
onSearch ({ commit }, paylpad) {
async onSearch ({ commit }, paylpad) {
if (state.selected && state.selected.key !== 'plugin-container') {
commit('commonUpdate', {searchValue: ''});
return;
@ -199,6 +201,16 @@ const actions = {
]
})
});
options = [
...options,
...(fileLists.filter(plugin => plugin.name.indexOf(value) >= 0)).map(plugin => {
plugin.click = () => {
console.log(plugin)
actions.openPlugin({commit}, {plugin});
}
return plugin
}),
]
}
commit('commonUpdate', {
@ -224,6 +236,19 @@ const actions = {
});
},
openPlugin({commit}, {cmd, plugin, feature, router}) {
if (plugin.type === 'app') {
execSync(plugin.action);
commit('commonUpdate', {
selected: null,
showMain: false,
options: [],
searchValue: '',
});
ipcRenderer.send('changeWindowSize-rubick', {
height: getWindowHeight([]),
});
return;
}
commit('commonUpdate', {
selected: {
key: 'plugin-container',