diff --git a/src/IpcMainHandler.ts b/src/IpcMainHandler.ts index 832d092..af581c3 100644 --- a/src/IpcMainHandler.ts +++ b/src/IpcMainHandler.ts @@ -2,7 +2,7 @@ import { ipcMain, screen, session } from "electron"; import http from 'http'; import https from 'https'; import { URL } from 'url'; -import { ApiResponse, MenuItem, TagResolutionConfig, EIACDesktopApi } from './EIAC_Desktop_Api'; +import { ApiResponse, MenuItem, TagResolutionConfig, EIACDesktopApi, SpecialPUrlItem } from './EIAC_Desktop_Api'; export function initialize(): void { // Get primary display(需要注意:size 是逻辑像素尺寸(logical screen size),已被 DPI 缩放影响,需要除以 DPI 缩放比例才是物理像素尺寸(physical screen size)) @@ -104,6 +104,52 @@ export function initialize(): void { // Get config cache ipcMain.handle('get-config-cache', async () => configData ?? await configDataReadyPromise); + + // Get zoom factor + ipcMain.handle('get-zoom-factor-by-url', async (event, url: string) => { + const display: Electron.Display = screen.getPrimaryDisplay(); + const physicalSize: Electron.Size = { + width: display.size.width * display.scaleFactor, + height: display.size.height * display.scaleFactor + }; + const resolution: string = `${physicalSize.width}*${physicalSize.height}`; + console.log('PhysicalResolution:', resolution); + console.log(`Resolution: ${display.size.width}*${display.size.height}`); + console.log(`ScaleFactor: ${display.scaleFactor}`); + + if (!configData) { + await configDataReadyPromise; + } + + if (configData.code != 200 || configData.status != 0) { + console.error('Get config failed:', configData.msg + ', status: ' + configData.status + ', code: ' + configData.code); + return display.scaleFactor; + } + + const configList: TagResolutionConfig[] = configData.data; + let config: TagResolutionConfig = configList.find(c => c.Resolutions.includes(resolution)); + if (!config) { + config = configList.find(c => c.Resolutions === '*'); + } + if (!config) { + config = configList[0]; + } + console.log('Match Config:', config); + + let specialPUrl: SpecialPUrlItem = config.SpecialPUrl.find(s => s.SPUrl.toLowerCase() === url.toLowerCase()); + if (!specialPUrl) { + specialPUrl = config.SpecialPUrl.find(s => url.toLowerCase().startsWith(s.SPUrl.toLowerCase())); + } + console.log('specialPUrl:', specialPUrl); + + let percentage: number = typeof config.Percentage === 'string' ? parseInt(config.Percentage) : config.Percentage; + if (specialPUrl) { + percentage = typeof specialPUrl.SPPer === 'string' ? parseInt(specialPUrl.SPPer) : specialPUrl.SPPer; + } + + console.log('Percentage:', percentage); + return percentage; + }); } let menuData: ApiResponse = null; diff --git a/src/index.ts b/src/index.ts index f8d3ac5..d26e7c4 100644 --- a/src/index.ts +++ b/src/index.ts @@ -120,14 +120,16 @@ async function addTabAsync(tabGroup: TabGroup, menuItem: MenuItem): Promise const url: string = menuItem.Url.startsWith("http") ? menuItem.Url : `http://${menuItem.Url}`; const result: { ok: boolean; status: number; message?: string } = await window.electronAPI.checkUrlAvailable(url); if (result.ok && result.status >= 200 && result.status < 400) { - console.log('✅ URL 可访问:', result.status); + console.log(`✅ URL ${url} 可访问:`, result.status); const cookies: string = window.electronAPI.getSessionStorage('cookie'); await window.electronAPI.setWebviewCookie(url, cookies); } else { - console.warn('❌ URL 不可访问:', result.message ?? `status ${result.status}`); + console.warn(`❌ URL ${url} 不可访问:`, result.message ?? `status ${result.status}`); showErrorModal(`无法访问 ${url}\r\n异常原因:${result.message ?? `status ${result.status}`}\r\n请联系10000技术支持。`); } + const zoomFactor: number = await window.electronAPI.getZoomFactorByUrl(url); + const tab: Tab = tabGroup.addTab({ active: true, closable: true, @@ -137,12 +139,25 @@ async function addTabAsync(tabGroup: TabGroup, menuItem: MenuItem): Promise webviewAttributes: { 'webpreferences': 'contextIsolation=yes, nodeIntegration=no', 'autosize': 'on', - 'allowpopups': true, + 'allowpopups': true }, ready: (tab: Tab) => { // 在webview加载完成后,获取并设置标签页的标题和图标 const webview: Electron.WebviewTag = tab.webview as Electron.WebviewTag; listenWebviewTitleChange(webview, tab); + + tab.once('webview-dom-ready', () => { + const webview: Electron.WebviewTag = tab.webview as Electron.WebviewTag; + const defaultZoomFactor: number = webview.getZoomFactor(); + console.log('Default zoom factor:', defaultZoomFactor); + + if (defaultZoomFactor != zoomFactor) { + webview.setZoomFactor(zoomFactor); + console.log('Modify zoom factor:', zoomFactor); + } else { + console.log('Default zoom factor is the same as the zoom factor:', zoomFactor); + } + }); } }); @@ -303,7 +318,6 @@ document.addEventListener('DOMContentLoaded', initialize); // 监听新标签页打开事件 window.electronAPI.onOpenTab((webContentId: number, url: string) => { - console.log(new URL(url)); const defaultFaviconUrl = new URL(url).origin + '/favicon.ico'; addTabAsync(tabGroup, { Url: url, diff --git a/src/main.ts b/src/main.ts index 845ba5b..fc47b9e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,7 +1,7 @@ import { app, BrowserWindow, globalShortcut, Menu, Tray } from 'electron'; import path from 'node:path'; import started from 'electron-squirrel-startup'; -import { initialize, preloadData } from './IpcMainHandler'; +import { initialize as initializeIpcMainHandler, preloadData } from './IpcMainHandler'; const isDevelopment: boolean = process.env.NODE_ENV === 'development'; @@ -28,9 +28,11 @@ if (started) { app.exit(0); // 使用 exit 而不是 quit,确保立即退出 } +initializeIpcMainHandler(); + const createWindow = () => { // Create the browser window. - const win = new BrowserWindow({ + const win: BrowserWindow = new BrowserWindow({ minWidth: 1024, minHeight: 768, autoHideMenuBar: true, @@ -124,12 +126,12 @@ const createWindow = () => { } // Create tray icon - const contextMenu = Menu.buildFromTemplate([ + const contextMenu: Electron.Menu = Menu.buildFromTemplate([ { label: '显示窗口', click: () => win.show() }, { label: '退出程序', click: () => app.exit() } ]); - const iconPath = isDevelopment ? path.join(__dirname, '../../assets/tray.png') : path.join(process.resourcesPath, 'assets', 'tray.png'); - const tray = new Tray(iconPath); + const iconPath: string = isDevelopment ? path.join(__dirname, '../../assets/tray.png') : path.join(process.resourcesPath, 'assets', 'tray.png'); + const tray: Tray = new Tray(iconPath); tray.setToolTip('中国电信-工作台'); tray.setContextMenu(contextMenu); @@ -164,6 +166,4 @@ app.whenReady().then(() => { createWindow(); } }); -}); - -initialize(); +}); \ No newline at end of file diff --git a/src/preload.ts b/src/preload.ts index 6be66da..fac0ec5 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -17,6 +17,13 @@ contextBridge.exposeInMainWorld('electronAPI', { */ getConfigCacheAsync: () => ipcRenderer.invoke('get-config-cache') as Promise>, + /** + * 获取指定URL的缩放比例 + * @param url 要获取缩放比例的URL + * @returns 缩放比例 + */ + getZoomFactorByUrl: (url: string) => ipcRenderer.invoke('get-zoom-factor-by-url', url) as Promise, + /** * 在新标签页打开URL * @param callback 回调函数,参数为webContentId和url。其中webContentId是请求打开URL的webview的id。 diff --git a/src/types/electron.d.ts b/src/types/electron.d.ts index 685b48c..b184290 100644 --- a/src/types/electron.d.ts +++ b/src/types/electron.d.ts @@ -11,6 +11,12 @@ export interface ElectronAPI { * @returns 配置缓存 */ getConfigCacheAsync: () => Promise>; + /** + * 获取指定URL的缩放比例 + * @param url 要获取缩放比例的URL + * @returns 缩放比例 + */ + getZoomFactorByUrl: (url: string) => Promise; /** * 在新标签页打开URL * @param callback 回调函数,参数为webContentId和url。其中webContentId是请求打开URL的webview的id。