fix(messages): sync preserve private dialogs after clearing history

This commit is contained in:
iamxvbaba 2026-07-29 13:51:02 +08:00
parent 3926db7762
commit e22fac1c3f
19 changed files with 923 additions and 231 deletions

View file

@ -537,6 +537,11 @@ type MessageServiceActionKind string
const (
MessageServiceActionSuggestProfilePhoto MessageServiceActionKind = "suggest_profile_photo"
// MessageServiceActionHistoryClear 映射 messageActionHistoryClear。私聊
// messages.deleteHistory(just_clear) 复用清理开始时的 top box id把它
// 原位转换成 owner-local 服务消息,使 getDialogs/getHistory 在冷启动时
// 仍能从真实 top message 重建会话。
MessageServiceActionHistoryClear MessageServiceActionKind = "history_clear"
// MessageServiceActionPinMessage 映射 messageActionPinMessage
// pm_oneside 私聊置顶生成的服务消息,被置顶消息经 reply_to 指向。
MessageServiceActionPinMessage MessageServiceActionKind = "pin_message"

View file

@ -165,6 +165,37 @@ type Message struct {
SavedPeer Peer
}
// NewHistoryClearMessage 把一个 owner 视角的现有 box 原位投影为
// messageActionHistoryClear 服务消息。调用方只传递仍需保留的身份字段;
// 其余正文、媒体、reply、reaction、TTL、pin 等载荷全部按不变量清空。
func NewHistoryClearMessage(ownerUserID int64, peer Peer, boxID int, uid int64, date, pts int) Message {
self := Peer{Type: PeerTypeUser, ID: ownerUserID}
return Message{
ID: boxID,
UID: uid,
OwnerUserID: ownerUserID,
Peer: peer,
From: self,
Date: date,
Out: true,
Pts: pts,
Media: &MessageMedia{
Kind: MessageMediaKindService,
ServiceAction: &MessageServiceAction{
Kind: MessageServiceActionHistoryClear,
},
},
}
}
// IsHistoryClearServiceMessage 报告该 box 是否已经是清空历史锚点。
func IsHistoryClearServiceMessage(msg Message) bool {
return msg.Media != nil &&
msg.Media.Kind == MessageMediaKindService &&
msg.Media.ServiceAction != nil &&
msg.Media.ServiceAction.Kind == MessageServiceActionHistoryClear
}
// MessageRichMessage 是 Layer 228 富文本消息richMessage的协议中立快照一组 IV
// PageBlockBlocks+ 内嵌已解析的 Photos/Documents。
//
@ -593,7 +624,23 @@ type DeleteHistoryRequest struct {
type DeletedMessagesForUser struct {
UserID int64
MessageIDs []int
Event UpdateEvent
// Event 保留单一 delete_messages 事件,供普通 deleteMessages 路径与
// replay receipt 使用just_clear 还会在 Events 中携带 read/edit 事件。
Event UpdateEvent
Events []UpdateEvent
// Pts/PtsCount 是本次 method 对该 owner 的 affected watermark 汇总。
// 普通删除等于 Eventjust_clear 等于最后一条真实 update 的 pts 与
// delete/read/edit 三段 pts_count 之和。
Pts int
PtsCount int
}
// AffectedPts 返回 messages.Affected* 应使用的最终 PTS 与本次总增量。
func (d DeletedMessagesForUser) AffectedPts() (int, int) {
if d.Pts != 0 {
return d.Pts, d.PtsCount
}
return d.Event.Pts, d.Event.PtsCount
}
// DeleteMessagesResult 描述消息删除后的 owner 维度结果。
@ -616,7 +663,8 @@ func (r DeleteMessagesResult) Self() DeletedMessagesForUser {
// Changed 表示本次删除是否实际影响了任何 owner 视角。
func (r DeleteMessagesResult) Changed() bool {
for _, item := range r.Deleted {
if len(item.MessageIDs) > 0 {
pts, _ := item.AffectedPts()
if len(item.MessageIDs) > 0 || pts > 0 {
return true
}
}