perf: 优化本地资源

This commit is contained in:
kuaifan 2024-11-18 11:35:38 +08:00
parent 5b9b6ed966
commit d0b54ab27c
7 changed files with 56 additions and 33 deletions

View File

@ -54,15 +54,15 @@ const electronMenu = {
async saveImageAs(url, params) { async saveImageAs(url, params) {
let extension = ''; let extension = '';
if (utils.isProtocolResource(url)) { if (utils.isLocalAssetPath(url)) {
extension = utils.protocolResourcePath(url).split('.').pop().toLowerCase(); extension = utils.localAssetRestoreRealPath(url).split('.').pop().toLowerCase();
} else { } else {
const urlExtension = url.split('.').pop().split(/[#?]/)[0].toLowerCase(); const urlExtension = url.split('.').pop().split(/[#?]/)[0].toLowerCase();
if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(urlExtension)) { if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp'].includes(urlExtension)) {
extension = urlExtension; extension = urlExtension;
} }
} }
if (!extension) { if (!extension) {
extension = 'png'; extension = 'png';
} }
@ -84,8 +84,8 @@ const electronMenu = {
try { try {
if (electronMenu.isBlobOrDataUrl(url)) { if (electronMenu.isBlobOrDataUrl(url)) {
await electronMenu.writeNativeImage(filePath, nativeImage.createFromDataURL(url)); await electronMenu.writeNativeImage(filePath, nativeImage.createFromDataURL(url));
} else if (utils.isProtocolResource(url)) { } else if (utils.isLocalAssetPath(url)) {
await fs.promises.copyFile(utils.protocolResourcePath(url), filePath); await fs.promises.copyFile(utils.localAssetRestoreRealPath(url), filePath);
} else { } else {
const writeStream = fs.createWriteStream(filePath) const writeStream = fs.createWriteStream(filePath)
const readStream = request(url) const readStream = request(url)
@ -122,7 +122,7 @@ const electronMenu = {
const url = params.linkURL || params.srcURL; const url = params.linkURL || params.srcURL;
const popupMenu = new Menu(); const popupMenu = new Menu();
if (!electronMenu.isBlobOrDataUrl(url) && !utils.isProtocolResource(url)) { if (!electronMenu.isBlobOrDataUrl(url) && !utils.isLocalAssetPath(url)) {
popupMenu.append( popupMenu.append(
new MenuItem({ new MenuItem({
label: electronMenu.language.openInBrowser, label: electronMenu.language.openInBrowser,
@ -168,7 +168,7 @@ const electronMenu = {
}, },
}), }),
); );
} else if (!utils.isProtocolResource(url)) { } else if (!utils.isLocalAssetPath(url)) {
popupMenu.append( popupMenu.append(
new MenuItem({ new MenuItem({
label: params.hasImageContents ? electronMenu.language.copyImageAddress : electronMenu.language.copyLinkAddress, label: params.hasImageContents ? electronMenu.language.copyImageAddress : electronMenu.language.copyLinkAddress,

22
electron/electron.js vendored
View File

@ -1,7 +1,21 @@
const fs = require('fs') const fs = require('fs')
const os = require("os"); const os = require("os");
const path = require('path') const path = require('path')
const {app, BrowserWindow, ipcMain, dialog, clipboard, nativeImage, shell, Tray, Menu, globalShortcut, Notification, BrowserView, nativeTheme, protocol} = require('electron') const {
app,
ipcMain,
dialog,
clipboard,
nativeImage,
shell,
globalShortcut,
nativeTheme,
protocol,
Tray,
Menu,
BrowserView,
BrowserWindow
} = require('electron')
const {autoUpdater} = require("electron-updater") const {autoUpdater} = require("electron-updater")
const loger = require("electron-log"); const loger = require("electron-log");
const electronConf = require('electron-config') const electronConf = require('electron-config')
@ -61,7 +75,7 @@ if (!fs.existsSync(cacheDir)) {
// 在最开始就注册协议为特权协议 // 在最开始就注册协议为特权协议
protocol.registerSchemesAsPrivileged([ protocol.registerSchemesAsPrivileged([
{ {
scheme: 'dootask-resources', scheme: 'local-asset',
privileges: { privileges: {
standard: true, standard: true,
secure: true, secure: true,
@ -75,8 +89,8 @@ protocol.registerSchemesAsPrivileged([
* 创建协议 * 创建协议
*/ */
function createProtocol() { function createProtocol() {
protocol.handle('dootask-resources', async (request) => { protocol.handle('local-asset', async (request) => {
const url = utils.protocolResourcePath(request.url) const url = utils.localAssetRestoreRealPath(request.url)
if (url.includes('..')) { if (url.includes('..')) {
return new Response('Access Denied', { status: 403 }) return new Response('Access Denied', { status: 403 })

20
electron/utils.js vendored
View File

@ -608,30 +608,30 @@ const utils = {
}, },
/** /**
* 是否协议资源 * 是否本地资源路径
* @param {string} url * @param {string} url
* @returns {boolean} * @returns {boolean}
*/ */
isProtocolResource(url) { isLocalAssetPath(url) {
return url.startsWith('dootask-resources://') return url.startsWith('local-asset://')
}, },
/** /**
* 协议资源路径 * 本地资源路径还原
* @param {string} url * @param {string} url
* @returns {string} * @returns {string}
*/ */
protocolResourcePath(url) { localAssetRestoreRealPath(url) {
if (!utils.isProtocolResource(url)) { if (!utils.isLocalAssetPath(url)) {
return url return url
} }
let p0 = url.replace(/^dootask-resources:\/\//, '') let p0 = url.replace(/^local-asset:\/\//, '')
const p1 = path.join(__dirname, '.', p0) const p1 = path.join(__dirname, '.', p0)
if (fs.existsSync(p1)) { if (fs.existsSync(p1)) {
return p1 return p1
} }
const p2 = path.join(__dirname, '..', p0) const p2 = path.join(__dirname, '..', p0)
if (fs.existsSync(p2)) { if (fs.existsSync(p2)) {

View File

@ -3,7 +3,7 @@
</template> </template>
<script> <script>
import {publicImageResources} from "./utils"; import {convertLocalResourcePath} from "./utils";
export default { export default {
props: { props: {
@ -18,7 +18,7 @@ export default {
}, },
computed: { computed: {
processedSrc({src}) { processedSrc({src}) {
return publicImageResources(src) return convertLocalResourcePath(src)
} }
}, },
} }

View File

@ -1,4 +1,8 @@
const publicImageResources = (() => { /**
* 将服务器资源路径转换为本地资源路径
* @type {(function(*): (*))|*}
*/
const convertLocalResourcePath = (() => {
let initialized = false let initialized = false
let appPreUrl = null let appPreUrl = null
let serverPreUrl = null let serverPreUrl = null
@ -20,7 +24,7 @@ const publicImageResources = (() => {
appPreUrl = appPreUrl.replace(/^file:\/\/assets\//, 'file:///android_asset/') appPreUrl = appPreUrl.replace(/^file:\/\/assets\//, 'file:///android_asset/')
} }
} else if ($A.Electron) { } else if ($A.Electron) {
appPreUrl = "dootask-resources://public/" appPreUrl = "local-asset://public/"
} }
// 如果没有特殊前缀,提前返回 // 如果没有特殊前缀,提前返回
@ -62,11 +66,16 @@ const publicImageResources = (() => {
} }
})() })()
const isPublicResources = (url) => { /**
* 是否是本地资源路径
* @param url
* @returns {*}
*/
const isLocalResourcePath = (url) => {
return url && ( return url && (
url.startsWith('file://') || url.startsWith('file://') ||
url.startsWith('dootask-resources://') url.startsWith('local-asset://')
) )
} }
export {publicImageResources, isPublicResources} export {convertLocalResourcePath, isLocalResourcePath}

View File

@ -1,5 +1,5 @@
import {MarkdownPreview} from "../store/markdown"; import {MarkdownPreview} from "../store/markdown";
import {publicImageResources} from "../components/Replace/utils"; import {convertLocalResourcePath} from "../components/Replace/utils";
/** /**
* 页面专用 * 页面专用
@ -350,7 +350,7 @@ import {publicImageResources} from "../components/Replace/utils";
const value = item.original const value = item.original
.replace(/\s+width=/, ` original-width=`) .replace(/\s+width=/, ` original-width=`)
.replace(/\s+height=/, ` original-height=`) .replace(/\s+height=/, ` original-height=`)
.replace(/\s+src=(["'])([^'"]*)\1/i, ` style="width:${data.width}px;height:${data.height}px" src="${publicImageResources(data.src)}"`) .replace(/\s+src=(["'])([^'"]*)\1/i, ` style="width:${data.width}px;height:${data.height}px" src="${convertLocalResourcePath(data.src)}"`)
text = text.replace(item.original, value) text = text.replace(item.original, value)
} else { } else {
text = text.replace(item.original, `<div class="no-size-image-box">${item.original}</div>`); text = text.replace(item.original, `<div class="no-size-image-box">${item.original}</div>`);

View File

@ -673,7 +673,7 @@ import DialogGroupVote from "./DialogGroupVote";
import DialogComplaint from "./DialogComplaint"; import DialogComplaint from "./DialogComplaint";
import touchclick from "../../../directives/touchclick"; import touchclick from "../../../directives/touchclick";
import {languageList} from "../../../language"; import {languageList} from "../../../language";
import {isPublicResources} from "../../../components/Replace/utils"; import {isLocalResourcePath} from "../../../components/Replace/utils";
export default { export default {
name: "DialogWrapper", name: "DialogWrapper",
@ -2880,7 +2880,7 @@ export default {
}) })
} }
if (msgData.type === 'text') { if (msgData.type === 'text') {
if (event.target.nodeName === 'IMG' && !isPublicResources(event.target.currentSrc)) { if (event.target.nodeName === 'IMG' && !isLocalResourcePath(event.target.currentSrc)) {
this.operateCopys.push({ this.operateCopys.push({
type: 'imagedown', type: 'imagedown',
icon: '&#xe7a8;', icon: '&#xe7a8;',