fix(model): enhanced message parsing and display (#223)

This commit is contained in:
Sarv
2025-08-26 01:15:13 +08:00
committed by GitHub
parent 9c221e6e0d
commit cad198d7a0
4 changed files with 401 additions and 66 deletions
+7 -6
View File
@@ -148,6 +148,7 @@ func (a *App) refresh() {
a.infoBar.UpdateBasicInfo(a.ctx.PID, a.ctx.FullVersion, a.ctx.ExePath)
a.infoBar.UpdateStatus(a.ctx.Status)
a.infoBar.UpdateDataKey(a.ctx.DataKey)
a.infoBar.UpdateImageKey(a.ctx.ImgKey)
a.infoBar.UpdatePlatform(a.ctx.Platform)
a.infoBar.UpdateDataUsageDir(a.ctx.DataUsage, a.ctx.DataDir)
a.infoBar.UpdateWorkUsageDir(a.ctx.WorkUsage, a.ctx.WorkDir)
@@ -201,14 +202,14 @@ func (a *App) inputCapture(event *tcell.EventKey) *tcell.EventKey {
func (a *App) initMenu() {
getDataKey := &menu.Item{
Index: 2,
Name: "获取数据密钥",
Description: "从进程获取数据密钥",
Name: "获取密钥",
Description: "从进程获取数据密钥 & 图片密钥",
Selected: func(i *menu.Item) {
modal := tview.NewModal()
if runtime.GOOS == "darwin" {
modal.SetText("获取数据密钥中...\n预计需要 20 秒左右的时间,期间微信会卡住,请耐心等待")
modal.SetText("获取密钥中...\n预计需要 20 秒左右的时间,期间微信会卡住,请耐心等待")
} else {
modal.SetText("获取数据密钥中...")
modal.SetText("获取密钥中...")
}
a.mainPages.AddPage("modal", modal, true, true)
a.SetFocus(modal)
@@ -220,10 +221,10 @@ func (a *App) initMenu() {
a.QueueUpdateDraw(func() {
if err != nil {
// 解密失败
modal.SetText("获取数据密钥失败: " + err.Error())
modal.SetText("获取密钥失败: " + err.Error())
} else {
// 解密成功
modal.SetText("获取数据密钥成功")
modal.SetText("获取密钥成功")
}
// 添加确认按钮
+176 -10
View File
@@ -8,10 +8,12 @@ import (
)
type MediaMsg struct {
XMLName xml.Name `xml:"msg"`
Image Image `xml:"img,omitempty"`
Video Video `xml:"videomsg,omitempty"`
App App `xml:"appmsg,omitempty"`
XMLName xml.Name `xml:"msg"`
Image Image `xml:"img,omitempty"`
Video Video `xml:"videomsg,omitempty"`
App App `xml:"appmsg,omitempty"`
Emoji Emoji `xml:"emoji,omitempty"`
Location Location `xml:"location,omitempty"`
}
type Image struct {
@@ -70,9 +72,63 @@ type App struct {
FinderFeed *FinderFeed `xml:"finderFeed,omitempty"` // type 51 视频号
ReferMsg *ReferMsg `xml:"refermsg,omitempty"` // type 57 引用
PatMsg *PatMsg `xml:"patMsg,omitempty"` // type 62 拍一拍
PatInfo *PatInfo `xml:"patinfo,omitempty"` // type 62 拍一拍 v2
FinderLive *FinderLive `xml:"finderLive,omitempty"` // type 63 视频号直播
WCPayInfo *WCPayInfo `xml:"wcpayinfo,omitempty"` // type 2000 微信转账
}
type Emoji struct {
FromUsername string `xml:"fromusername,attr"`
ToUsername string `xml:"tousername,attr"`
Type string `xml:"type,attr"`
IdBuffer string `xml:"idbuffer,attr"`
Md5 string `xml:"md5,attr"`
Len string `xml:"len,attr"`
CdnURL string `xml:"cdnurl,attr"`
AesKey string `xml:"aeskey,attr"`
Width string `xml:"width,attr"`
Height string `xml:"height,attr"`
// ProductId string `xml:"productid,attr"`
// AndroidMd5 string `xml:"androidmd5,attr"`
// AndroidLen string `xml:"androidlen,attr"`
// S60v3Md5 string `xml:"s60v3md5,attr"`
// S60v3Len string `xml:"s60v3len,attr"`
// S60v5Md5 string `xml:"s60v5md5,attr"`
// S60v5Len string `xml:"s60v5len,attr"`
// DesignerId string `xml:"designerid,attr"`
// ThumbUrl string `xml:"thumburl,attr"`
// EncryptUrl string `xml:"encrypturl,attr"`
// ExternUrl string `xml:"externurl,attr"`
// ExternMd5 string `xml:"externmd5,attr"`
// TpUrl string `xml:"tpurl,attr"`
// TpAuthKey string `xml:"tpauthkey,attr"`
// AttachedText string `xml:"attachedtext,attr"`
// AttachedTextColor string `xml:"attachedtextcolor,attr"`
// LensId string `xml:"lensid,attr"`
// EmojiAttr string `xml:"emojiattr,attr"`
// LinkId string `xml:"linkid,attr"`
// Desc string `xml:"desc,attr"`
}
type Location struct {
X string `xml:"x,attr"`
Y string `xml:"y,attr"`
Scale string `xml:"scale,attr"`
Label string `xml:"label,attr"`
MapType string `xml:"maptype,attr"`
Adcode string `xml:"adcode,attr"`
CityName string `xml:"cityname,attr"`
// PoiName string `xml:"poiname,attr"`
// PoiId string `xml:"poiid,attr"`
// BuildingId string `xml:"buildingId,attr"`
// FloorName string `xml:"floorName,attr"`
// PoiCategoryTips string `xml:"poiCategoryTips,attr"`
// PoiBusinessHour string `xml:"poiBusinessHour,attr"`
// PoiPhone string `xml:"poiPhone,attr"`
// PoiPriceTips string `xml:"poiPriceTips,attr"`
// IsFromPoiList string `xml:"isFromPoiList,attr"`
}
// ReferMsg 表示引用消息
type ReferMsg struct {
Type int64 `xml:"type"`
@@ -153,27 +209,50 @@ type DataItem struct {
MessageUUID string `xml:"messageuuid,omitempty"`
FromNewMsgID string `xml:"fromnewmsgid,omitempty"`
// 链接
Link string `xml:"link,omitempty"`
// 音乐
StreamWebURL string `xml:"streamweburl,omitempty"`
// 位置
Location DataItemLocation `xml:"location,omitempty"`
// 套娃合并转发
DataTitle string `xml:"datatitle,omitempty"`
RecordXML *RecordXML `xml:"recordxml,omitempty"`
}
type DataItemLocation struct {
Lat string `xml:"lat,attr"`
Lng string `xml:"lng,attr"`
Scale string `xml:"scale,attr"`
Label string `xml:"label,attr"`
PoiName string `xml:"poiname,attr"`
}
type RecordXML struct {
RecordInfo RecordInfo `xml:"recordinfo,omitempty"`
}
func (r *RecordInfo) String(title, host string) string {
func (r *RecordInfo) String(_type, title, host string) string {
buf := strings.Builder{}
if title == "" {
title = r.Title
}
buf.WriteString(fmt.Sprintf("[合并转发|%s]\n", title))
if title == "" {
title = strings.TrimSpace(strings.ReplaceAll(r.Desc, "\n", " "))
if len(title) > 80 {
title = title[:80] + "..."
}
}
buf.WriteString(fmt.Sprintf("[%s|%s]\n", _type, title))
for _, item := range r.DataList.DataItems {
buf.WriteString(fmt.Sprintf(" %s %s\n", item.SourceName, item.SourceTime))
// 套娃合并转发
if item.DataType == "17" && item.RecordXML != nil {
content := item.RecordXML.RecordInfo.String(item.DataTitle, host)
content := item.RecordXML.RecordInfo.String(_type, item.DataTitle, host)
if content != "" {
for _, line := range strings.Split(content, "\n") {
buf.WriteString(fmt.Sprintf(" %s\n", line))
@@ -182,14 +261,44 @@ func (r *RecordInfo) String(title, host string) string {
continue
}
switch item.DataFmt {
case "pic", "jpg":
switch item.DataType {
case "2":
// 图片
buf.WriteString(fmt.Sprintf(" ![图片](http://%s/image/%s)\n", host, item.FullMD5))
case "4":
//视频
buf.WriteString(fmt.Sprintf(" ![视频](http://%s/video/%s)\n", host, item.FullMD5))
case "8":
// 文件
// FIXME 笔记的第一条是 htm 数据,暂时跳过处理
if item.DataFmt == ".htm" {
continue
}
buf.WriteString(fmt.Sprintf(" [文件|%s](http://%s/file/%s)\n", item.DataTitle, host, item.FullMD5))
case "5":
// Link
buf.WriteString(fmt.Sprintf(" [链接|%s](%s)\n", item.DataTitle, item.Link))
case "6":
// Location
buf.WriteString(fmt.Sprintf(" [位置|%s]\n", item.Location.PoiName))
case "22":
// 视频号
buf.WriteString(fmt.Sprintf(" [视频号|%s]\n", strings.TrimSpace(strings.ReplaceAll(item.DataDesc, "\n", " "))))
case "23":
// 视频号直播
buf.WriteString(fmt.Sprintf(" [视频号直播|%s]\n", strings.TrimSpace(strings.ReplaceAll(item.DataDesc, "\n", " "))))
case "32":
// 音乐
buf.WriteString(fmt.Sprintf(" [音乐|%s](%s)\n", item.DataTitle, item.StreamWebURL))
case "37":
// 动画表情
buf.WriteString(" [动画表情]\n")
default:
for _, line := range strings.Split(item.DataDesc, "\n") {
buf.WriteString(fmt.Sprintf(" %s\n", line))
}
}
buf.WriteString("\n")
}
return buf.String()
@@ -202,6 +311,16 @@ type PatMsg struct {
Records Records `xml:"records"` // 拍一拍记录
}
// PatInfo 拍一拍 v2
type PatInfo struct {
FromUsername string `xml:"fromusername"`
ChatUsername string `xml:"chatusername"`
PattedUsername string `xml:"pattedusername"`
PatSuffix string `xml:"patsuffix"`
PatSuffixVersion int `xml:"patsuffixversion"`
Template string `xml:"template"`
}
// Records 拍一拍记录集合
type Records struct {
Record []PatRecord `xml:"record"` // 拍一拍记录列表
@@ -283,10 +402,49 @@ type FinderMegaVideo struct {
ObjectNonceID string `xml:"objectNonceId"`
}
type FinderLive struct {
FinderLiveID string `xml:"finderLiveID"`
FinderUsername string `xml:"finderUsername"`
FinderObjectID string `xml:"finderObjectID"`
FinderNonceID string `xml:"finderNonceID"`
Nickname string `xml:"nickname"`
HeadURL string `xml:"headUrl"`
Desc string `xml:"desc"`
LiveStatus int `xml:"liveStatus"`
LiveSourceTypeStr string `xml:"liveSourceTypeStr"`
ExtFlag int `xml:"extFlag"`
LiveSecondaryDeviceFlagStr string `xml:"liveSecondaryDeviceFlagStr"`
LiveFlag int `xml:"liveFlag"`
AuthIconURL string `xml:"authIconUrl"`
AuthIconTypeStr string `xml:"authIconTypeStr"`
BindType int `xml:"bindType"`
BizUsername string `xml:"bizUsername"`
BizNickname string `xml:"bizNickname"`
ChargeFlag int `xml:"chargeFlag"`
ReplayStatus int `xml:"replayStatus"`
SpamLiveExtFlagString string `xml:"spamLiveExtFlagString"`
EnterSessionID string `xml:"enterSessionId"`
LiveMode int `xml:"liveMode"`
LiveSubMode int `xml:"liveSubMode"`
Media FinderLiveMedia `xml:"media"`
ShareScene int `xml:"shareScene"`
}
type FinderLiveMedia struct {
CoverURL FinderLiveMediaCoverURL `xml:"coverUrl"`
Height int `xml:"height"`
Width int `xml:"width"`
}
type FinderLiveMediaCoverURL struct {
Text string `xml:",cdata"`
}
type SysMsg struct {
Type string `xml:"type,attr"`
DelChatRoomMember *DelChatRoomMember `xml:"delchatroommember,omitempty"`
SysMsgTemplate *SysMsgTemplate `xml:"sysmsgtemplate,omitempty"`
RevokeMsg *RevokeMsg `xml:"revokemsg,omitempty"`
}
// 第一种消息类型:删除群成员/二维码邀请
@@ -296,6 +454,11 @@ type DelChatRoomMember struct {
Link QRLink `xml:"link"`
}
type RevokeMsg struct {
Content string `xml:"content"`
RevokeTime int `xml:"revoketime"`
}
type QRLink struct {
Scene string `xml:"scene"`
Text string `xml:"text"`
@@ -345,8 +508,11 @@ type Member struct {
}
func (s *SysMsg) String() string {
if s.Type == "delchatroommember" {
switch s.Type {
case "delchatroommember":
return s.DelChatRoomMemberString()
case "revokemsg":
return s.RevokeMsg.Content
}
return s.SysMsgTemplateString()
}
+203 -47
View File
@@ -17,6 +17,94 @@ const (
WeChatDarwinV3 = "wechatdarwinv3"
)
const (
// MessageTypeText 文本
MessageTypeText = 1
// MessageTypeImage 图片
MessageTypeImage = 3
// MessageTypeVoice 语音
MessageTypeVoice = 34
// MessageTypeCard 名片
MessageTypeCard = 42
// MessageTypeVideo 视频
MessageTypeVideo = 43
// MessageTypeAnimation 动画表情
MessageTypeAnimation = 47
// MessageTypeLocation 位置
MessageTypeLocation = 48
// MessageTypeShare 分享
MessageTypeShare = 49
// MessageTypeVOIP 语音通话
MessageTypeVOIP = 50
// MessageTypeSystem 系统
MessageTypeSystem = 10000
)
const (
// MessageSubTypeText 文本
MessageSubTypeText = 1
// MessageSubTypeLink 链接分享
MessageSubTypeLink = 4
// MessageSubTypeLink2 链接分享
MessageSubTypeLink2 = 5
// MessageSubTypeFile 文件
MessageSubTypeFile = 6
// MessageSubTypeGIF 动图
MessageSubTypeGIF = 8
// MessageSubTypeMergeForward 合并转发
MessageSubTypeMergeForward = 19
// MessageSubTypeNote 笔记
MessageSubTypeNote = 24
// MessageSubTypeMiniProgram 小程序
MessageSubTypeMiniProgram = 33
// MessageSubTypeMiniProgram2 小程序
MessageSubTypeMiniProgram2 = 36
// MessageSubTypeChannel 视频号
MessageSubTypeChannel = 51
// MessageSubTypeQuote 引用
MessageSubTypeQuote = 57
// MessageSubTypePat 拍一拍
MessageSubTypePat = 62
// MessageSubTypeChannelLive 视频号直播
MessageSubTypeChannelLive = 63
// MessageSubTypeChatRoomNotice 群公告
MessageSubTypeChatRoomNotice = 87
// MessageSubTypeMusic 音乐
MessageSubTypeMusic = 92
// MessageSubTypePay 转账
MessageSubTypePay = 2000
// MessageSubTypeRedEnvelope 红包
MessageSubTypeRedEnvelope = 2001
// MessageSubTypeRedEnvelopeCover 红包封面
MessageSubTypeRedEnvelopeCover = 2003
)
type Message struct {
Version string `json:"-"` // 消息版本,内部判断
Seq int64 `json:"seq"` // 消息序号,10位时间戳 + 3位序号
@@ -46,7 +134,9 @@ func (m *Message) ParseMediaInfo(data string) error {
return nil
}
if m.Type == 10000 {
if m.Type == MessageTypeSystem {
m.Sender = "系统消息"
m.SenderName = ""
var sysMsg SysMsg
if err := xml.Unmarshal([]byte(data), &sysMsg); err != nil {
m.Content = data
@@ -55,8 +145,6 @@ func (m *Message) ParseMediaInfo(data string) error {
if Debug {
m.SysMsg = &sysMsg
}
m.Sender = "系统消息"
m.SenderName = ""
m.Content = sysMsg.String()
return nil
}
@@ -76,28 +164,36 @@ func (m *Message) ParseMediaInfo(data string) error {
}
switch m.Type {
case 3:
case MessageTypeImage:
m.Contents["md5"] = msg.Image.MD5
case 43:
case MessageTypeVideo:
if msg.Video.Md5 != "" {
m.Contents["md5"] = msg.Video.Md5
}
if msg.Video.RawMd5 != "" {
m.Contents["rawmd5"] = msg.Video.RawMd5
}
case 49:
case MessageTypeAnimation:
m.Contents["cdnurl"] = msg.Emoji.CdnURL
case MessageTypeLocation:
m.Contents["x"] = msg.Location.X
m.Contents["y"] = msg.Location.Y
m.Contents["label"] = msg.Location.Label
m.Contents["cityname"] = msg.Location.CityName
case MessageTypeShare:
m.SubType = int64(msg.App.Type)
switch m.SubType {
case 5:
case MessageSubTypeText, MessageSubTypeLink, MessageSubTypeLink2:
// 链接
m.Contents["title"] = msg.App.Title
m.Contents["desc"] = msg.App.Des
m.Contents["url"] = msg.App.URL
case 6:
case MessageSubTypeFile:
// 文件
m.Contents["title"] = msg.App.Title
m.Contents["md5"] = msg.App.MD5
case 19:
// 合并转发
case MessageSubTypeMergeForward, MessageSubTypeNote, MessageSubTypeChatRoomNotice:
// 合并转发 & 笔记
m.Contents["title"] = msg.App.Title
m.Contents["desc"] = msg.App.Des
if msg.App.RecordItem == nil {
@@ -109,20 +205,20 @@ func (m *Message) ParseMediaInfo(data string) error {
return err
}
m.Contents["recordInfo"] = recordInfo
case 33, 36:
case MessageSubTypeMiniProgram, MessageSubTypeMiniProgram2:
// 小程序
m.Contents["title"] = msg.App.SourceDisplayName
m.Contents["url"] = msg.App.URL
case 51:
case MessageSubTypeChannel:
// 视频号
if msg.App.FinderFeed == nil {
break
}
m.Contents["title"] = msg.App.FinderFeed.Desc
m.Contents["title"] = strings.TrimSpace(strings.ReplaceAll(msg.App.FinderFeed.Desc, "\n", " "))
if len(msg.App.FinderFeed.MediaList.Media) > 0 {
m.Contents["url"] = msg.App.FinderFeed.MediaList.Media[0].URL
}
case 57:
case MessageSubTypeQuote:
// 引用
m.Content = msg.App.Title
if msg.App.ReferMsg == nil {
@@ -141,17 +237,29 @@ func (m *Message) ParseMediaInfo(data string) error {
break
}
m.Contents["refer"] = subMsg
case 62:
case MessageSubTypePat:
// 拍一拍
if msg.App.PatMsg == nil {
if msg.App.PatMsg != nil {
if len(msg.App.PatMsg.Records.Record) != 0 {
m.Sender = msg.App.PatMsg.Records.Record[0].FromUser
m.Content = msg.App.PatMsg.Records.Record[0].Templete
}
}
if msg.App.PatInfo != nil {
m.Content = msg.App.Title
}
case MessageSubTypeChannelLive:
// 视频号直播
if msg.App.FinderLive == nil {
break
}
if len(msg.App.PatMsg.Records.Record) == 0 {
break
}
m.Sender = msg.App.PatMsg.Records.Record[0].FromUser
m.Content = msg.App.PatMsg.Records.Record[0].Templete
case 2000:
m.Contents["title"] = msg.App.FinderLive.Desc
case MessageSubTypeMusic:
// 音乐
m.Contents["title"] = msg.App.Title
m.Contents["desc"] = msg.App.Des
m.Contents["url"] = msg.App.URL
case MessageSubTypePay:
// 微信转账
if msg.App.WCPayInfo == nil {
break
@@ -236,9 +344,9 @@ func (m *Message) PlainText(showChatRoom bool, timeFormat string, host string) s
func (m *Message) PlainTextContent() string {
switch m.Type {
case 1:
case MessageTypeText:
return m.Content
case 3:
case MessageTypeImage:
keylist := make([]string, 0)
if m.Contents["md5"] != nil {
if md5, ok := m.Contents["md5"].(string); ok {
@@ -251,14 +359,14 @@ func (m *Message) PlainTextContent() string {
}
}
return fmt.Sprintf("![图片](http://%s/image/%s)", m.Contents["host"], strings.Join(keylist, ","))
case 34:
case MessageTypeVoice:
if voice, ok := m.Contents["voice"]; ok {
return fmt.Sprintf("[语音](http://%s/voice/%s)", m.Contents["host"], voice)
}
return "[语音]"
case 42:
case MessageTypeCard:
return "[名片]"
case 43:
case MessageTypeVideo:
keylist := make([]string, 0)
if m.Contents["md5"] != nil {
if md5, ok := m.Contents["md5"].(string); ok {
@@ -276,17 +384,34 @@ func (m *Message) PlainTextContent() string {
}
}
return fmt.Sprintf("![视频](http://%s/video/%s)", m.Contents["host"], strings.Join(keylist, ","))
case 47:
case MessageTypeAnimation:
if m.Contents["cdnurl"] != nil {
if cdnURL, ok := m.Contents["cdnurl"].(string); ok {
return fmt.Sprintf("![动画表情](%s)", cdnURL)
}
}
return "[动画表情]"
case 49:
case MessageTypeLocation:
keylist := make([]string, 0)
for _, key := range []string{"label", "cityname", "x", "y"} {
if m.Contents[key] != nil {
if value, ok := m.Contents[key].(string); ok {
keylist = append(keylist, value)
}
}
}
return fmt.Sprintf("[位置|%s]", strings.Join(keylist, "|"))
case MessageTypeShare:
switch m.SubType {
case 5:
case MessageSubTypeText:
return fmt.Sprintf("[链接|%s](%s)", m.Contents["title"], m.Contents["desc"])
case MessageSubTypeLink, MessageSubTypeLink2:
return fmt.Sprintf("[链接|%s](%s)", m.Contents["title"], m.Contents["url"])
case 6:
case MessageSubTypeFile:
return fmt.Sprintf("[文件|%s](http://%s/file/%s)", m.Contents["title"], m.Contents["host"], m.Contents["md5"])
case 8:
case MessageSubTypeGIF:
return "[GIF表情]"
case 19:
case MessageSubTypeMergeForward:
_recordInfo, ok := m.Contents["recordInfo"]
if !ok {
return "[合并转发]"
@@ -299,19 +424,33 @@ func (m *Message) PlainTextContent() string {
if m.Contents["host"] != nil {
host = m.Contents["host"].(string)
}
return recordInfo.String("", host)
case 33, 36:
return recordInfo.String("合并转发", "", host)
case MessageSubTypeNote:
_recordInfo, ok := m.Contents["recordInfo"]
if !ok {
return "[笔记]"
}
recordInfo, ok := _recordInfo.(*RecordInfo)
if !ok {
return "[笔记]"
}
host := ""
if m.Contents["host"] != nil {
host = m.Contents["host"].(string)
}
return recordInfo.String("笔记", "", host)
case MessageSubTypeMiniProgram, MessageSubTypeMiniProgram2:
if m.Contents["title"] == "" {
return "[小程序]"
}
return fmt.Sprintf("[小程序|%s](%s)", m.Contents["title"], m.Contents["url"])
case 51:
case MessageSubTypeChannel:
if m.Contents["title"] == "" {
return "[视频号]"
} else {
return fmt.Sprintf("[视频号|%s](%s)", m.Contents["title"], m.Contents["url"])
}
case 57:
case MessageSubTypeQuote:
_refer, ok := m.Contents["refer"]
if !ok {
if m.Content == "" {
@@ -342,24 +481,41 @@ func (m *Message) PlainTextContent() string {
}
buf.WriteString(m.Content)
return buf.String()
case 62:
case MessageSubTypePat:
return m.Content
case 63:
return "[视频号]"
case 87:
return "[群公告]"
case 2000:
case MessageSubTypeChannelLive:
if m.Contents["title"] != nil {
return fmt.Sprintf("[视频号直播|%s]", m.Contents["title"])
}
return "[视频号直播]"
case MessageSubTypeChatRoomNotice:
_recordInfo, ok := m.Contents["recordInfo"]
if !ok {
return "[群公告]"
}
recordInfo, ok := _recordInfo.(*RecordInfo)
if !ok {
return "[群公告]"
}
host := ""
if m.Contents["host"] != nil {
host = m.Contents["host"].(string)
}
return recordInfo.String("群公告", "", host)
case MessageSubTypeMusic:
return fmt.Sprintf("[音乐|%s](%s)", m.Contents["title"], m.Contents["url"])
case MessageSubTypePay:
return m.Content
case 2001:
case MessageSubTypeRedEnvelope:
return "[红包]"
case 2003:
case MessageSubTypeRedEnvelopeCover:
return "[红包封面]"
default:
return "[分享]"
}
case 50:
case MessageTypeVOIP:
return "[语音通话]"
case 10000:
case MessageTypeSystem:
return m.Content
default:
content := m.Content
+15 -3
View File
@@ -15,7 +15,7 @@ const (
// InfoBarViewHeight info bar height.
const (
InfoBarViewHeight = 7
InfoBarViewHeight = 8
accountRow = 0
statusRow = 1
platformRow = 2
@@ -23,6 +23,7 @@ const (
dataUsageRow = 4
workUsageRow = 5
httpServerRow = 6
autoDecryptRow = 7
// 列索引
labelCol1 = 0 // 第一列标签
@@ -145,10 +146,17 @@ func New() *InfoBar {
table.SetCell(
httpServerRow,
labelCol2,
tview.NewTableCell(fmt.Sprintf(" [%s::]%s", headerColor, "Auto Decrypt:")),
tview.NewTableCell(fmt.Sprintf(" [%s::]%s", headerColor, "Image Key:")),
)
table.SetCell(httpServerRow, valueCol2, tview.NewTableCell(""))
table.SetCell(
autoDecryptRow,
labelCol1,
tview.NewTableCell(fmt.Sprintf(" [%s::]%s", headerColor, "Auto Decrypt:")),
)
table.SetCell(autoDecryptRow, valueCol1, tview.NewTableCell(""))
// infobar
infoBar := &InfoBar{
Box: tview.NewBox(),
@@ -200,9 +208,13 @@ func (info *InfoBar) UpdateHTTPServer(server string) {
info.table.GetCell(httpServerRow, valueCol1).SetText(server)
}
func (info *InfoBar) UpdateImageKey(key string) {
info.table.GetCell(httpServerRow, valueCol2).SetText(key)
}
// UpdateAutoDecrypt updates Auto Decrypt value.
func (info *InfoBar) UpdateAutoDecrypt(text string) {
info.table.GetCell(httpServerRow, valueCol2).SetText(text)
info.table.GetCell(autoDecryptRow, valueCol1).SetText(text)
}
// Draw draws this primitive onto the screen.