diff --git a/package-lock.json b/package-lock.json index 9701a8c..6e7b9b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "core-js": "^3.6.5", "monaco-editor": "^0.33.0", "monaco-editor-webpack-plugin": "^7.0.1", + "picture-compressor": "^1.1.0", "pinyin-match": "^1.2.2", "quasar": "^2.6.0", "raw-loader": "^4.0.2", @@ -8132,6 +8133,11 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, + "node_modules/picture-compressor": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/picture-compressor/-/picture-compressor-1.1.0.tgz", + "integrity": "sha512-yJNpdb97h1KXGxGh1JPav1wYXDEPtuCVryt2VIb74i7WGZu4RyU+gr8u2nmLf24MjwgT4oo3US+yxUCGeadRgg==" + }, "node_modules/pinyin-match": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/pinyin-match/-/pinyin-match-1.2.2.tgz", @@ -17505,6 +17511,11 @@ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, + "picture-compressor": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/picture-compressor/-/picture-compressor-1.1.0.tgz", + "integrity": "sha512-yJNpdb97h1KXGxGh1JPav1wYXDEPtuCVryt2VIb74i7WGZu4RyU+gr8u2nmLf24MjwgT4oo3US+yxUCGeadRgg==" + }, "pinyin-match": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/pinyin-match/-/pinyin-match-1.2.2.tgz", diff --git a/package.json b/package.json index 1f1d58d..85c5381 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "core-js": "^3.6.5", "monaco-editor": "^0.33.0", "monaco-editor-webpack-plugin": "^7.0.1", + "picture-compressor": "^1.1.0", "pinyin-match": "^1.2.2", "quasar": "^2.6.0", "raw-loader": "^4.0.2", diff --git a/plugin/lib/picture-compressor.js b/plugin/lib/picture-compressor.js deleted file mode 100644 index 217597a..0000000 --- a/plugin/lib/picture-compressor.js +++ /dev/null @@ -1,132 +0,0 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global = global || self, global.pictureCompress = factory()); -}(this, function () { 'use strict'; - - /** - * 将图片压缩为对应尺寸 - * @param {Object} options - * @param {String} options.img 图片的url或者base64数据 - * @param {Number} options.width 目标图片的宽度 - * @param {Number} options.height 目标图片的高度 - * @param {Number} options.quality 生成目标图片质量 - * @param {String} options.fit 图片压缩填充模式默认 scale:按比例缩放,可选 fill:按使用目标尺寸 - * @param {String} options.type 图片压缩类型默认 jpg,可选 png - * @param {Number} options.rotate 图片旋转,由于手机拍照的角度和我们使用的头像不一致,需要旋转 默认0 仅支持 90 180 -90 - * @returns {Promise} then {width,height,img} - */ - function pictureCompress(options) { - return new Promise(function (resolve, reject) { - if (!options.img) { - reject(new Error('need img')); - return; - } - - var imgSrc = options.img, - width = options.width || 640, - height = options.height || 640, - type = options.type || 'jpg', - quality = options.quality || 0.92, - fit = options.fit || 'scale', - rotate = options.rotate || 0; - - if (width <= 0 || height <= 0) { - reject(new Error('dist width or height need > 0')); - return; - } - - if (!/jpg|png|jpeg/.test(type)) { - reject(new Error('type need jpg or png!')); - return; - } - - if (rotate !== 90 && rotate !== -90 && rotate !== 0 && rotate !== 180) { - reject(new Error('rotate mast be 0 90 -90 180!')); - return; - } - - var changeWidthAndHeight = rotate === 90 || rotate === -90; - var image = new Image(); - image.src = imgSrc; - - image.onload = function () { - var distSize = getDistSize({ - width: changeWidthAndHeight ? this.naturalHeight : this.naturalWidth, - height: changeWidthAndHeight ? this.naturalWidth : this.naturalHeight - }, { - width: changeWidthAndHeight ? height : width, - height: changeWidthAndHeight ? width : height - }, fit); - var imgData = compress(this, distSize.width, distSize.height, type, quality, rotate); - resolve({ - width: distSize.width, - height: distSize.height, - img: imgData - }); - }; - - image.onerror = function (err) { - reject(err); - }; - }); - } - /** - * 将图片转换为固定尺寸的 - * @param {Image} img 图片数据 - * @param {Number} width 转换之后的图片宽度 - * @param {Number} height 转换之后的图片高度 - * @param {String} type base64的图片类型 jpg png - * @param {Number} quality 转换之后的图片质量 - */ - - - function compress(img, width, height, type, quality, rotate) { - var canvas = document.createElement('canvas'); - var ctx = canvas.getContext('2d'); - var types = { - 'jpg': 'image/jpeg', - 'jpeg': 'image/jpeg', - 'png': 'image/png' - }; - canvas.width = width; - canvas.height = height; - - if (rotate === 90) { - ctx.translate(width, 0); - ctx.rotate(90 * Math.PI / 180); - ctx.drawImage(img, 0, 0, height, width); - } else if (rotate === -90) { - ctx.translate(0, height); - ctx.rotate(-90 * Math.PI / 180); - ctx.drawImage(img, 0, 0, height, width); - } else if (rotate === 180) { - ctx.translate(width, height); - ctx.rotate(180 * Math.PI / 180); - ctx.drawImage(img, 0, 0, width, height); - } else { - ctx.drawImage(img, 0, 0, width, height); - } - - return canvas.toDataURL(types[type], quality); - } - /** - * 选择源尺寸与目标尺寸比例中较小的那个,保证图片可以完全显示 - * 最大值不超过1,如果图片源尺寸小于目标尺寸,则不做处理,返回图片原尺寸 - * @param {Object} source 源图片的宽高 - * @param {Object} dist 目标图片的宽高 - */ - - - function getDistSize(source, dist, fit) { - if (fit === 'fill') return dist; - var scale = Math.min(dist.width / source.width, dist.height / source.height, 1); - return { - width: Math.round(source.width * scale), - height: Math.round(source.height * scale) - }; - } - - return pictureCompress; - -})); diff --git a/plugin/preload.js b/plugin/preload.js index ed01913..4cf9ae8 100644 --- a/plugin/preload.js +++ b/plugin/preload.js @@ -9,7 +9,6 @@ const { } = require('./lib/vm2') const path = require("path") const axios = require('axios'); -const pictureCompress = require("./lib/picture-compressor") window._ = require("lodash") window.yuQueClient = axios.create({ @@ -220,22 +219,22 @@ if (process.platform !== 'linux') quickcommand.runInTerminal = function(cmdline, } let getCommandToLaunchTerminal = (cmdline, dir) => { - let cd = '' - if (utools.isWindows()) { - let appPath = path.join(utools.getPath('home'), '/AppData/Local/Microsoft/WindowsApps/') - // 直接 existsSync wt.exe 无效 - if (fs.existsSync(appPath) && fs.readdirSync(appPath).includes('wt.exe')) { - cmdline = cmdline.replace(/"/g, `\\"`) - if (dir) cd = `-d "${dir.replace(/\\/g, '/')}"` - command = `${appPath}wt.exe ${cd} cmd /k "${cmdline}"` + let cd = '' + if (utools.isWindows()) { + let appPath = path.join(utools.getPath('home'), '/AppData/Local/Microsoft/WindowsApps/') + // 直接 existsSync wt.exe 无效 + if (fs.existsSync(appPath) && fs.readdirSync(appPath).includes('wt.exe')) { + cmdline = cmdline.replace(/"/g, `\\"`) + if (dir) cd = `-d "${dir.replace(/\\/g, '/')}"` + command = `${appPath}wt.exe ${cd} cmd /k "${cmdline}"` + } else { + cmdline = cmdline.replace(/"/g, `^"`) + if (dir) cd = `cd /d "${dir.replace(/\\/g, '/')}" &&` + command = `${cd} start "" cmd /k "${cmdline}"` + } } else { - cmdline = cmdline.replace(/"/g, `^"`) - if (dir) cd = `cd /d "${dir.replace(/\\/g, '/')}" &&` - command = `${cd} start "" cmd /k "${cmdline}"` - } - } else { - cmdline = cmdline.replace(/"/g, `\\"`) - if (dir) cd = `cd ${dir.replace(/ /g, `\\\\ `)} &&` + cmdline = cmdline.replace(/"/g, `\\"`) + if (dir) cd = `cd ${dir.replace(/ /g, `\\\\ `)} &&` if (fs.existsSync('/Applications/iTerm.app')) { command = `osascript -e 'tell application "iTerm" create window with default profile @@ -427,11 +426,44 @@ window.base64Decode = text => Buffer.from(text, 'base64').toString('utf8') window.processPlatform = process.platform window.joinPath = path.join +window.getUtoolsPlugins = () => { + let root = utools.isMacOs() ? + path.join(os.homedir(), 'Library/Application Support/uTools/plugins/') : + (utools.isWindows() ? + path.join(os.homedir(), 'AppData/Roaming/uTools/plugins') : + path.join(os.homedir(), '.config/uTools/plugins')) + let plugins = {}; + let files = fs.readdirSync(root); + let deleted = path.join(root, "deleted"); + let deletedList = fs.existsSync(deleted) ? + fs.readFileSync(path.join(root, "deleted"), "utf8").split("|") : []; + files.forEach((file) => { + if (/[a-zA-Z0-9\-]+\.asar$/.test(file) && !deletedList.includes(file)) { + let pluginInfo = JSON.parse( + fs.readFileSync(path.join(root, file, "plugin.json")) + ); + pluginInfo.logoPath = path.join(root, file, pluginInfo.logo); + let keyWordFeatures = []; + pluginInfo.features.forEach((f) => { + f.cmds.some((c) => { + c.length && (keyWordFeatures.push(c)); + return true; + }); + }); + if (!_.isEmpty(keyWordFeatures)) { + pluginInfo["keyWordFeatures"] = keyWordFeatures + plugins[pluginInfo.pluginName] = pluginInfo + } + } + }); + return plugins; +} + window.getQuickcommandTempFile = ext => { return path.join(os.tmpdir(), `quickcommandTempFile.${ext}`) } -window.getBase64Ico = async (filepath, compressed = true) => { +window.getBase64Ico = filepath => { let sourceImage, ext = path.extname(filepath).slice(1) if (['png', 'jpg', 'jpeg', 'bmp', 'ico', 'gif', 'svg'].includes(ext)) { if (ext == 'svg') ext = 'svg+xml' @@ -441,20 +473,7 @@ window.getBase64Ico = async (filepath, compressed = true) => { sourceImage = utools.getFileIcon(filepath) return sourceImage } - if (!compressed) return sourceImage - let compressedImage = await getCompressedIco(sourceImage) - return compressedImage -} - -let getCompressedIco = async (img, width = 80) => { - let compressedImage = await pictureCompress({ - img: img, - width: width, - height: width, - type: 'png', - quality: 1 - }) - return compressedImage.img + return sourceImage } window.getFileInfo = options => { @@ -586,4 +605,4 @@ window.runCodeFile = (cmd, option, terminal, callback) => { // let stderr = err_chunks.join(""); // callback(stdout, stderr) // }) -} +} \ No newline at end of file diff --git a/src/components/IconPicker.vue b/src/components/IconPicker.vue index 0e808e0..7d2b2a4 100644 --- a/src/components/IconPicker.vue +++ b/src/components/IconPicker.vue @@ -90,6 +90,7 @@