Skip to content

Commit

Permalink
Touch Bar 好玩
Browse files Browse the repository at this point in the history
🎨 Touch Bar 功能完善
🐛 修正 mac 下 700px 宽度 chatPan 行为异常的
🐛 修正会话列表刷新工作异常的问题
  • Loading branch information
Stapxs committed Nov 26, 2024
1 parent 8c0819f commit 6dd2ad0
Show file tree
Hide file tree
Showing 16 changed files with 279 additions and 127 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-app.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# 在主分支上构建
name: build
name: build-app
on:
push: # push 触发
branches:
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/pr-check.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
# 在主分支上构建
name: lint
on:
pull_request: # PR 触发
Expand Down
2 changes: 1 addition & 1 deletion electron-builder.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# 基础配置
appId: com.stapxs.qqweb
appId: cn.stapxs.qqweb
productName: Stapxs QQ Lite
copyright: Copyright © 2022-2024 Stapx Steve [林槐]
directories:
Expand Down
11 changes: 11 additions & 0 deletions src/main/function/elements.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export interface NotifyInfo {
base_type: string,

title: string
body: string
tag: string
icon: string
image?: string
type: string
is_important: boolean
}
47 changes: 37 additions & 10 deletions src/main/function/ipc.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Store from 'electron-store'
import path from 'path'
import os from 'os'
import log4js from 'log4js'

import {
ipcMain,
Expand All @@ -14,9 +15,11 @@ import {
import { runCommand } from './util.ts'
import { win, touchBarInstance } from '../index.ts'
import { Connector } from './connector.ts'
import { logLevel } from '../index.ts'

let connector = undefined as Connector | undefined
const store = new Store()
const logger = log4js.getLogger('ipc')
let template = [] as any[]

// 消息缓存,key 为 tag
Expand Down Expand Up @@ -186,6 +189,13 @@ export function regIpcListener() {
})
// 发送通知
ipcMain.on('sys:sendNotice', async (_, data) => {
logger.level = logLevel
logger.info('创建通知:' + data.tag + ' - ' + data.body)
// MacOS: 刷新 TouchBar
if(touchBarInstance && data.base_type === 'msg') {
touchBarInstance.newMessage(data)
}

const userId = data.tag.split('/')[0]
const msgId = data.tag.split('/')[1]

Expand Down Expand Up @@ -260,21 +270,38 @@ export function regIpcListener() {
})
// 关闭通知
ipcMain.on('sys:closeNotice', (_, tag) => {
if (noticeList[tag]) {
if(noticeList[tag]) {
logger.level = logLevel
logger.info('关闭通知:' + tag)
noticeList[tag].close()
delete noticeList[tag]
// macOS: 刷新 TouchBar
if(touchBarInstance) {
touchBarInstance.removeMessage(tag)
}
}
})
// 清空通知
ipcMain.on('sys:clearNotice', () => {
Object.keys(noticeList).forEach((key) => {
logger.level = logLevel
logger.info('清空通知')
noticeList[key].close()
delete noticeList[key]
})
})
// 关闭指定 ID 的所有通知
ipcMain.on('sys:closeAllNotice', (_, id) => {
Object.keys(noticeList).forEach((key) => {
if (key.startsWith(id)) {
if(key.startsWith(id)) {
logger.level = logLevel
logger.info('关闭所有通知:' + id)
noticeList[key].close()
delete noticeList[key]
// macOS: 刷新 TouchBar
if(touchBarInstance) {
touchBarInstance.removeMessage(key)
}
}
})
})
Expand Down Expand Up @@ -484,23 +511,23 @@ export function regIpcListener() {
})
function sendMenuClick(name: string, value = undefined as any) {
if (win) {
win.focus()
if (value) {
win.webContents.send(name, value)
} else {
win.webContents.send(name)
}
}
}
// MacOS:刷新 touchBar 消息列表
ipcMain.on('sys:flushTouchBar', (_, list) => {
if (touchBarInstance) {
touchBarInstance.flush(list)
// MacOS:touchBar 相关功能
ipcMain.on('sys:flushOnMessage', (_, list) => {
if(touchBarInstance) {
touchBarInstance.flushOnMessage(list)
}
})
// MacOS:新消息,刷新 touchBar
ipcMain.on('sys:newMessage', (_, data) => {
if (touchBarInstance) {
touchBarInstance.newMessage(data)
ipcMain.on('sys:flushFriendSearch', (_, list) => {
if(touchBarInstance) {
touchBarInstance.flushFriendSearch(list)
}
})
}
225 changes: 161 additions & 64 deletions src/main/function/touchbar.ts
Original file line number Diff line number Diff line change
@@ -1,97 +1,194 @@
import axios from 'axios'

import { BrowserWindow, TouchBar, ScrubberItem, nativeImage } from 'electron'
import { BrowserWindow, NativeImage, TouchBar, nativeImage } from 'electron'
import { NotifyInfo } from './elements.ts'
const {
TouchBarButton,
TouchBarScrubber,
TouchBarPopover,
TouchBarSpacer,
TouchBarLabel,
TouchBarLabel
} = TouchBar

export class touchBar {
win: BrowserWindow
private win: BrowserWindow

private nowView: 'Home' | 'FriendSearch' = 'Home'
private itemList: { id: number, name: string, image: string }[] = []
private msgList = {} as {[key: string]: { tag: string, title: string,
image: NativeImage | undefined, body: string }}

touchBarScrubber = new TouchBarScrubber({
overlayStyle: 'outline',
showArrowButtons: true,
continuous: false,
showArrowButtons: false,
continuous: true,
mode: 'free',
items: [],
select: (index) => {
const id = Object.keys(this.itemList)[index]
const id = this.itemList[index].id
this.win.webContents.send('app:jumpChat', {
userId: id,
messageId: 0,
messageId: 0
})
},
}
})
search = new TouchBarButton({
icon: nativeImage.createFromDataURL(
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAEDSURBVHgBtZKBEYIwDEWDE7CB3UBGwA3cQDbQDWAD3AA3QSdQJygbwAY19cIRa0OLp//un7lLfElKABwZYxS6Rmsz6YZu0DksEYFCsmAlMRIGa/CnYLkL+oEe0Bv0juU69DZJkg6EyUpnPeWpsU9xZnWtBFOsSKNTmBHmT6y+8BU0rEBBQLYhuhenpBXlFfzQig3xttEKnVF8hXjdWaxc4DcaWPwxYUfxGuKVCfDXe4yn0Ie+MPtPO16FL5mzB64jYAdWX4U6WpWRMC2eGR23doqPNH1OMW86ag8z3V2opD4aSuDCTMfuguxBp1QTDyVwylZWQuNl0Iimf4f28AsRVKObJwdbHWO7DC5FAAAAAElFTkSuQmCC',
),
icon: nativeImage.createFromNamedImage('NSImageNameTouchBarSearchTemplate', [-1, 0, 1]).resize({ width: 20, height: 20 }),
click: () => {
this.win.focus()
this.win.webContents.send('app:changeTab', 'Friends')
},
}
})
itemList: { [key: number]: ScrubberItem } = {}

baseView = [
this.search,
new TouchBarPopover({
icon: nativeImage.createFromNamedImage('NSImageNameListViewTemplate', [-1, 0, 1]).resize({ width: 20, height: 20 }),
items: new TouchBar({ items: [ this.touchBarScrubber ]
}), showCloseButton: true}),
new TouchBarSpacer({ size: 'flexible' })
]

// ====================================

constructor(win: BrowserWindow) {
this.win = win
this.win.setTouchBar(
new TouchBar({ items: [this.search, this.touchBarScrubber] }),
)
}
flush(
messageList: {
id: number
name: string
image: string
}[],
) {
this.itemList = {}
this.win.setTouchBar(
new TouchBar({ items: [this.search, this.touchBarScrubber] }),
)
// 创建 item
messageList.forEach(async (message) => {
this.itemList[message.id] = { label: message.name }

/**
* 刷新消息列表
* @param messageList 消息列表
*/
flushOnMessage(messageList: { id: number, name: string, image: string }[]) {
this.itemList = messageList
this.touchBarScrubber.items = messageList.map((item) => {
return {
label: item.name
}
})
this.touchBarScrubber.items = Object.values(this.itemList)

// 如果在主页就主动刷新,其他情况退出到主页时会刷新
if(this.nowView == 'Home') this.loadHome()
}
async newMessage(data: {
id: number
image: string
name: string
msg: string
}) {
const response = await axios.get(data.image, {
responseType: 'arraybuffer',
})
let image = nativeImage.createFromBuffer(response.data)
image = image.resize({ width: 25, height: 25 })
// 创建 poper
const popover = new TouchBarPopover({
label: '新消息',
items: new TouchBar({
items: [
new TouchBarButton({
icon: image,
iconPosition: 'right',
enabled: false,
backgroundColor: '#000',

/**
* 刷新好友搜索
* @param nameList 好友列表
*/
flushFriendSearch(nameList: { id: number, name: string}[]) {
if(nameList.length > 0) {
this.nowView = 'FriendSearch'

this.win.setTouchBar(new TouchBar({ items: [
new TouchBarButton({
icon: nativeImage.createFromNamedImage('NSImageNameGoLeftTemplate', [-1, 0, 1]).resize({ width: 10, height: 15 }),
click: () => {
this.loadHome()
this.win.webContents.send('app:changeTab', 'Messages')
}
}),
new TouchBarButton({ label: '搜索联系人' }),
new TouchBarScrubber({
overlayStyle: 'outline',
showArrowButtons: false,
continuous: false,
mode: 'free',
items: nameList.map((item) => {
return {
label: item.name
}
}),
new TouchBarButton({ label: data.name ?? '' }),
new TouchBarSpacer({ size: 'small' }),
new TouchBarLabel({ label: data.msg ?? '' }),
],
}),
showCloseButton: true,
})
this.win.setTouchBar(
new TouchBar({
items: [this.search, this.touchBarScrubber, popover],
}),
)
select: (index) => {
const id = nameList[index].id
this.win.webContents.send('app:jumpChat', {
userId: id,
messageId: 0
})
this.loadHome()
}
}),
new TouchBarSpacer({ size: 'flexible' })
]}))
} else {
this.loadHome()
}
}

/**
* 保存新消息
* @param data 新消息
*/
async newMessage(data: NotifyInfo) {
let image
if(data.icon) {
const response = await axios.get(data.icon, {
responseType: 'arraybuffer'
})
image = nativeImage.createFromBuffer(response.data)
image = image.resize({ width: 25, height: 25 })
}
this.msgList[data.tag] = {
tag: data.tag,
title: data.title,
image: image,
body: data.body
}

// 如果在主页就主动刷新,其他情况退出到主页时会刷新
if(this.nowView == 'Home') this.loadHome()
}

/**
* 删除消息
* @param tag 消息标签
*/
removeMessage(tag: string) {
delete this.msgList[tag]

// 如果在主页就主动刷新,其他情况退出到主页时会刷新
if(this.nowView == 'Home') this.loadHome()
}

// ====================================

/**
* 刷新主页面
*/
private loadHome() {
this.nowView = 'Home'

const count = Object.keys(this.msgList).length
if(count > 0) {
const data = Object.values(this.msgList)[0]
const id = data.tag.split('/')[0]

// 创建 poper
const popover = new TouchBarPopover({
icon: nativeImage.createFromNamedImage('NSImageNameTouchBarNewMessageTemplate', [-1, 0, 1]).resize({ width: 20, height: 20 }),
label: count.toString(),
items: new TouchBar({
items: [
new TouchBarButton({ icon: data.image, iconPosition: 'right', enabled: false, backgroundColor: '#000'}),
new TouchBarButton({ label: data.title, click: () => {
this.win.webContents.focus()
this.win.webContents.send('app:jumpChat', {
userId: id,
messageId: 0
})
this.win.setTouchBar(
new TouchBar({ items: this.baseView }))
}}),
new TouchBarSpacer({ size: 'small' }),
new TouchBarLabel({ label: data.body }),
new TouchBarSpacer({ size: 'flexible' })
]
}),
showCloseButton: true
})
this.win.setTouchBar(
new TouchBar({ items: this.baseView.concat(popover)}))
} else {
this.win.setTouchBar(new TouchBar({ items: this.baseView }))
}
}
}
Loading

0 comments on commit 6dd2ad0

Please sign in to comment.