2021-12-23 15:28:10 +08:00

144 lines
3.9 KiB
TypeScript

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import getMacApps from "./get-mac-app";
import fs from "fs";
import path from "path";
import translate from "./translate";
import os from "os";
const icondir = path.join(os.tmpdir(), "ProcessIcon");
const exists = fs.existsSync(icondir);
if (!exists) {
fs.mkdirSync(icondir);
}
const isZhRegex = /[\u4e00-\u9fa5]/;
async function getAppIcon(
appPath: string,
nativeImage: {
createThumbnailFromPath: (
iconPath: string,
size: { width: number; height: number }
) => { toDataURL: () => string };
},
name: string
) {
try {
const iconpath = path.join(icondir, `${name}.png`);
const iconnone = path.join(icondir, `${name}.none`);
const exists = fs.existsSync(iconpath);
const existsnone = fs.existsSync(iconnone);
if (exists) return true;
if (existsnone) return false;
const appName: string = appPath.split("/").pop() || "";
const extname: string = path.extname(appName);
const appSubStr: string = appName.split(extname)[0];
const path1 = path.join(appPath, `/Contents/Resources/App.icns`);
const path2 = path.join(appPath, `/Contents/Resources/AppIcon.icns`);
const path3 = path.join(appPath, `/Contents/Resources/${appSubStr}.icns`);
const path4 = path.join(
appPath,
`/Contents/Resources/${appSubStr.replace(" ", "")}.icns`
);
let iconPath: string = 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(appPath, `/Contents/Resources`)
);
const iconName = resourceList.filter(
(file) => path.extname(file) === ".icns"
)[0];
if (!iconName) {
fs.writeFileSync(iconnone, "")
return false;
}
iconPath = path.join(appPath, `/Contents/Resources/${iconName}`);
}
const img = await nativeImage.createThumbnailFromPath(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;
} catch (e) {
return false;
}
}
export default async (nativeImage: any) => {
let apps: any = await getMacApps.getApps();
apps = apps.filter((app: any) => {
const extname = path.extname(app.path);
return extname === ".app" || extname === ".prefPane";
});
for (const app of apps) {
if (await getAppIcon(app.path, nativeImage, app._name)) {
app.icon =
"image://" +
path.join(
os.tmpdir(),
"ProcessIcon",
`${encodeURIComponent(app._name)}.png`
);
}
// todo getApp size
}
apps = apps.filter((app: any) => !!app.icon);
apps = apps.map((app: any) => {
const appName: any = app.path.split("/").pop();
const extname = path.extname(appName);
const appSubStr = appName.split(extname)[0];
let fileOptions = {
...app,
value: "plugin",
desc: app.path,
pluginType: "app",
action: `open ${app.path.replace(/ /g, "\\ ") as string}`,
keyWords: [appSubStr],
};
if (app._name && isZhRegex.test(app._name)) {
const py = translate(app._name);
const pinyinArr = py.split(",");
const firstLatter = pinyinArr.map((py) => py[0]);
// 拼音
fileOptions.keyWords.push(pinyinArr.join(""));
// 缩写
fileOptions.keyWords.push(firstLatter.join(""));
// 中文
fileOptions.keyWords.push(app._name);
}
fileOptions = {
...fileOptions,
name: app._name,
names: JSON.parse(JSON.stringify(fileOptions.keyWords)),
};
return fileOptions;
});
return apps;
};