From bf5c0405153f90e24c54889d3da4fb55147a2d1e Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Thu, 20 Jul 2023 00:50:34 +0800 Subject: [PATCH] feat(desktop): add flash frame when receive message --- .github/workflows/desktop-build.yml | 2 +- .../src/main/inject/message-handler.ts | 11 +++++- client/desktop/src/main/main.ts | 11 +++++- .../com.msgbyte.env.electron/src/index.tsx | 3 ++ .../com.msgbyte.env.electron/src/utils.ts | 25 +++++++++++++ .../plugins/com.msgbyte.env.rn/src/index.tsx | 36 +------------------ .../plugins/com.msgbyte.env.rn/src/utils.ts | 35 ++++++++++++++++++ 7 files changed, 85 insertions(+), 38 deletions(-) create mode 100644 client/web/plugins/com.msgbyte.env.electron/src/utils.ts create mode 100644 client/web/plugins/com.msgbyte.env.rn/src/utils.ts diff --git a/.github/workflows/desktop-build.yml b/.github/workflows/desktop-build.yml index c811d516..000c1cc9 100644 --- a/.github/workflows/desktop-build.yml +++ b/.github/workflows/desktop-build.yml @@ -5,7 +5,7 @@ on: branches: - master paths: - - "client/desktop/**" + - "client/desktop/release/app/package.json" # build when version upgrade workflow_dispatch: jobs: diff --git a/client/desktop/src/main/inject/message-handler.ts b/client/desktop/src/main/inject/message-handler.ts index 50ce73bc..e26c49e0 100644 --- a/client/desktop/src/main/inject/message-handler.ts +++ b/client/desktop/src/main/inject/message-handler.ts @@ -1,11 +1,13 @@ import { generateInstallPluginScript } from '.'; import log from 'electron-log'; import { startScreenshots } from '../screenshots'; +import { BrowserWindow } from 'electron'; export function handleTailchatMessage( type: string, payload: any, - webview: Electron.WebContents + webview: Electron.WebContents, + win: BrowserWindow ) { log.info('onMessage receive:', type, payload); @@ -18,4 +20,11 @@ export function handleTailchatMessage( startScreenshots(); return; } + + if (type === 'receiveUnmutedMessage') { + if (!win.isFocused) { + win.flashFrame(true); + } + return; + } } diff --git a/client/desktop/src/main/main.ts b/client/desktop/src/main/main.ts index f539b531..ce251541 100644 --- a/client/desktop/src/main/main.ts +++ b/client/desktop/src/main/main.ts @@ -182,11 +182,20 @@ const createMainWindow = async (url: string) => { if (channel === 'webview-message') { const obj = JSON.parse(data); if (typeof obj === 'object' && obj._isTailchat === true && mainWindow) { - handleTailchatMessage(obj.type, obj.payload, mainWindow.webContents); + handleTailchatMessage( + obj.type, + obj.payload, + mainWindow.webContents, + mainWindow + ); } } }); + mainWindow.on('focus', () => { + mainWindow?.flashFrame(false); + }); + mainWindow.on('ready-to-show', () => { if (!mainWindow) { throw new Error('"mainWindow" is not defined'); diff --git a/client/web/plugins/com.msgbyte.env.electron/src/index.tsx b/client/web/plugins/com.msgbyte.env.electron/src/index.tsx index 9644f46a..ce3005aa 100644 --- a/client/web/plugins/com.msgbyte.env.electron/src/index.tsx +++ b/client/web/plugins/com.msgbyte.env.electron/src/index.tsx @@ -7,6 +7,7 @@ import { Icon } from '@capital/component'; import React from 'react'; import { DeviceInfoPanel } from './DeviceInfoPanel'; import { Translate } from './translate'; +import { forwardSharedEvent } from './utils'; const PLUGIN_NAME = 'Electron Support'; @@ -34,3 +35,5 @@ regChatInputButton({ ); }, }); + +forwardSharedEvent('receiveUnmutedMessage'); diff --git a/client/web/plugins/com.msgbyte.env.electron/src/utils.ts b/client/web/plugins/com.msgbyte.env.electron/src/utils.ts new file mode 100644 index 00000000..579eb0dd --- /dev/null +++ b/client/web/plugins/com.msgbyte.env.electron/src/utils.ts @@ -0,0 +1,25 @@ +import { sharedEvent, postMessageEvent } from '@capital/common'; + +/** + * 转发事件 + */ +export function forwardSharedEvent( + eventName: string, + processPayload?: (payload: any) => Promise<{ type: string; payload: any }> +) { + sharedEvent.on(eventName, async (payload: any) => { + let type = eventName; + if (processPayload) { + const res = await processPayload(payload); + if (!res) { + // Skip if res is undefined + return; + } + + payload = res.payload; + type = res.type; + } + + postMessageEvent(type, payload); + }); +} diff --git a/client/web/plugins/com.msgbyte.env.rn/src/index.tsx b/client/web/plugins/com.msgbyte.env.rn/src/index.tsx index 2a0a2c72..1a4a5502 100644 --- a/client/web/plugins/com.msgbyte.env.rn/src/index.tsx +++ b/client/web/plugins/com.msgbyte.env.rn/src/index.tsx @@ -1,6 +1,5 @@ import { getGlobalState, - sharedEvent, getCachedUserInfo, getCachedBaseGroupInfo, getMessageTextDecorators, @@ -9,6 +8,7 @@ import { } from '@capital/common'; import { DeviceInfoPanel } from './DeviceInfoPanel'; import { Translate } from './translate'; +import { forwardSharedEvent } from './utils'; const PLUGIN_NAME = 'ReactNative Support'; @@ -22,40 +22,6 @@ regCustomPanel({ render: DeviceInfoPanel, }); -/** - * 转发事件 - */ -function forwardSharedEvent( - eventName: string, - processPayload?: (payload: any) => Promise<{ type: string; payload: any }> -) { - if (!(window as any).ReactNativeWebView) { - return; - } - - sharedEvent.on(eventName, async (payload: any) => { - let type = eventName; - if (processPayload) { - const res = await processPayload(payload); - if (!res) { - // Skip if res is undefined - return; - } - - payload = res.payload; - type = res.type; - } - - (window as any).ReactNativeWebView.postMessage( - JSON.stringify({ - _isTailchat: true, - type, - payload, - }) - ); - }); -} - forwardSharedEvent('loadColorScheme'); forwardSharedEvent('loginSuccess', async (payload) => { let token = window.localStorage.getItem('jsonwebtoken'); diff --git a/client/web/plugins/com.msgbyte.env.rn/src/utils.ts b/client/web/plugins/com.msgbyte.env.rn/src/utils.ts new file mode 100644 index 00000000..da078dcc --- /dev/null +++ b/client/web/plugins/com.msgbyte.env.rn/src/utils.ts @@ -0,0 +1,35 @@ +import { sharedEvent } from '@capital/common'; + +/** + * 转发事件 + */ +export function forwardSharedEvent( + eventName: string, + processPayload?: (payload: any) => Promise<{ type: string; payload: any }> +) { + if (!(window as any).ReactNativeWebView) { + return; + } + + sharedEvent.on(eventName, async (payload: any) => { + let type = eventName; + if (processPayload) { + const res = await processPayload(payload); + if (!res) { + // Skip if res is undefined + return; + } + + payload = res.payload; + type = res.type; + } + + (window as any).ReactNativeWebView.postMessage( + JSON.stringify({ + _isTailchat: true, + type, + payload, + }) + ); + }); +}