Support /history command in MUCs

This commit is contained in:
Bohdan Horbeshko 2025-07-05 12:43:38 -04:00
parent 5c4c722cdc
commit 3b01b1de70
2 changed files with 70 additions and 43 deletions

View file

@ -274,7 +274,7 @@ func (c *Client) updateMessageContent(update *client.UpdateMessageContent) {
var jids []string var jids []string
if isMUC { if isMUC {
_, jids = c.getMUCJoinedJIDs(update.ChatId) _, jids = c.getMUCJoinedJIDs(update.ChatId, nil, true)
} else { } else {
c.getCarbonFullJids(true, ignoredResource) c.getCarbonFullJids(true, ignoredResource)
} }
@ -408,7 +408,7 @@ func (c *Client) updateDeleteMessages(update *client.UpdateDeleteMessages) {
var jids []string var jids []string
if isGroupchat { if isGroupchat {
fromJid = gateway.MUCJID(update.ChatId) fromJid = gateway.MUCJID(update.ChatId)
_, jids = c.getMUCJoinedJIDs(update.ChatId) _, jids = c.getMUCJoinedJIDs(update.ChatId, nil, true)
} else { } else {
fromJid = gateway.CHATNODE(update.ChatId) fromJid = gateway.CHATNODE(update.ChatId)
c.getCarbonFullJids(true, "") c.getCarbonFullJids(true, "")

View file

@ -872,19 +872,23 @@ func (c *Client) MUCHasResource(chatID int64, resource string) bool {
return ok return ok
} }
func (c *Client) getMUCJoinedJIDs(chatId int64) (bool, []string) { func (c *Client) getMUCJoinedJIDs(chatId int64, mucState *MUCState, lock bool) (bool, []string) {
c.locks.mucCacheLock.Lock() if lock {
defer c.locks.mucCacheLock.Unlock() c.locks.mucCacheLock.Lock()
defer c.locks.mucCacheLock.Unlock()
}
groupChatTos := []string{} groupChatTos := []string{}
mucState, ok := c.mucCache[chatId] if mucState == nil {
if !ok || mucState == nil { mucState, _ = c.mucCache[chatId]
}
if mucState == nil {
return false, nil return false, nil
} else { }
for resource := range mucState.Resources {
groupChatTos = append(groupChatTos, c.jid + "/" + resource) for resource := range mucState.Resources {
} groupChatTos = append(groupChatTos, c.jid + "/" + resource)
} }
return true, groupChatTos return true, groupChatTos
@ -1099,7 +1103,7 @@ func (c *Client) getMessageReply(message *client.Message, preview bool, noConten
return return
} }
func (c *Client) formatMessage(chatID int64, messageID int64, preview bool, message *client.Message) string { func (c *Client) formatMessage(chatID int64, messageID int64, preview bool, sender bool, message *client.Message) string {
var err error var err error
if message == nil { if message == nil {
message, err = c.client.GetMessage(&client.GetMessageRequest{ message, err = c.client.GetMessage(&client.GetMessageRequest{
@ -1115,16 +1119,18 @@ func (c *Client) formatMessage(chatID int64, messageID int64, preview bool, mess
return "" return ""
} }
return c.formatMessageContent(preview, c.messageToStub(message, preview, "")) return c.formatMessageContent(preview, c.messageToStub(message, preview, ""), sender)
} }
func (c *Client) formatMessageContent(preview bool, message *messageStub) string { func (c *Client) formatMessageContent(preview bool, message *messageStub, sender bool) string {
var str strings.Builder var str strings.Builder
// add messageid and sender // add messageid and sender
if message.MessageId != 0 { if message.MessageId != 0 {
str.WriteString(fmt.Sprintf("%v | ", message.MessageId)) str.WriteString(fmt.Sprintf("%v | ", message.MessageId))
} }
str.WriteString(fmt.Sprintf("%s | ", message.Sender)) if sender {
str.WriteString(fmt.Sprintf("%s | ", message.Sender))
}
// add date // add date
if !preview { if !preview {
str.WriteString( str.WriteString(
@ -1354,7 +1360,7 @@ func (c *Client) messageContentToText(content client.MessageContent, chatId int6
return "kicked " + c.FormatContact(deleteMember.UserId) return "kicked " + c.FormatContact(deleteMember.UserId)
case client.TypeMessagePinMessage: case client.TypeMessagePinMessage:
pinMessage, _ := content.(*client.MessagePinMessage) pinMessage, _ := content.(*client.MessagePinMessage)
return "pinned message: " + c.formatMessage(chatId, pinMessage.MessageId, preview, nil) return "pinned message: " + c.formatMessage(chatId, pinMessage.MessageId, preview, true, nil)
case client.TypeMessageChatChangeTitle: case client.TypeMessageChatChangeTitle:
changeTitle, _ := content.(*client.MessageChatChangeTitle) changeTitle, _ := content.(*client.MessageChatChangeTitle)
return "chat title set to: " + changeTitle.Title return "chat title set to: " + changeTitle.Title
@ -1648,7 +1654,7 @@ func (c *Client) messageToPrefix(message *client.Message, previewString string,
replyStart = c.countCharsInLines(&prefix) + (len(prefix)-1)*len(messageHeaderSeparator) replyStart = c.countCharsInLines(&prefix) + (len(prefix)-1)*len(messageHeaderSeparator)
} }
replyLine := "reply: " + c.formatMessageContent(preview, tgReply) replyLine := "reply: " + c.formatMessageContent(preview, tgReply, true)
prefix = append(prefix, replyLine) prefix = append(prefix, replyLine)
replyEnd = replyStart + utf8.RuneCountInString(replyLine) replyEnd = replyStart + utf8.RuneCountInString(replyLine)
@ -1750,7 +1756,7 @@ func (c *Client) ProcessIncomingMessage(chatId int64, message *client.Message) {
groupChatFrom = gateway.MUCJID(chatId) + "/" + c.GetMUCNickname(senderId) groupChatFrom = gateway.MUCJID(chatId) + "/" + c.GetMUCNickname(senderId)
var ok bool var ok bool
ok, groupChatTos = c.getMUCJoinedJIDs(chatId) ok, groupChatTos = c.getMUCJoinedJIDs(chatId, nil, true)
if !ok { if !ok {
safeToSend = false safeToSend = false
} }
@ -2604,9 +2610,20 @@ func (c *Client) TgMemberToMUCOccupant(member *client.ChatMember, chat *client.C
func (c *Client) sendMessagesReverse(chatID int64, messages []*client.Message, plain bool, toJid string) { func (c *Client) sendMessagesReverse(chatID int64, messages []*client.Message, plain bool, toJid string) {
sChatId := gateway.CHATNODE(chatID) sChatId := gateway.CHATNODE(chatID)
var mucJid string mucJid := gateway.MUCJID(chatID)
if toJid != "" { var plainTos []string
mucJid = gateway.MUCJID(chatID)
var isMUC bool
if plain {
chat, err := c.GetChatByID(chatID, nil)
if err == nil {
isMUC = c.Session.MUC && c.IsGroup(chat)
}
}
if isMUC {
_, plainTos = c.getMUCJoinedJIDs(chatID, nil, true)
} else {
plainTos = []string{c.jid}
} }
for i := len(messages) - 1; i >= 0; i-- { for i := len(messages) - 1; i >= 0; i-- {
@ -2614,23 +2631,37 @@ func (c *Client) sendMessagesReverse(chatID int64, messages []*client.Message, p
if plain { if plain {
reply, _ := c.getMessageReply(message, false, true) reply, _ := c.getMessageReply(message, false, true)
sId := strconv.FormatInt(message.Id, 10) sId := strconv.FormatInt(message.Id, 10)
gateway.SendMessage(
c.jid, var originalFrom string
sChatId, var from string
c.formatMessage(0, 0, false, message), if isMUC {
sId, senderId := c.getMessageSenderId(message)
c.xmpp, if senderId != 0 {
reply, originalFrom = gateway.CHATJID(senderId, true)
0, }
"", from = mucJid + "/" + c.GetMUCNickname(senderId)
false, } else {
false, from = sChatId
false, }
"",
"", for _, to := range plainTos {
) gateway.SendMessage(
to,
from,
c.formatMessage(0, 0, false, !isMUC, message),
sId,
c.xmpp,
reply,
0,
"",
false,
isMUC,
false,
originalFrom,
"",
)
}
} else { } else {
msgId, _ := gateway.IdsDB.GetByTgIds(c.Session.Login, c.jid, chatID, message.Id) msgId, _ := gateway.IdsDB.GetByTgIds(c.Session.Login, c.jid, chatID, message.Id)
c.SendMessageToGateway( c.SendMessageToGateway(
@ -2764,6 +2795,7 @@ func (c *Client) leaveChat(chatID int64) error {
return c.unsubscribe(chatID) return c.unsubscribe(chatID)
} }
// achtung: assuming a locked mucState context
func (c *Client) kickMeFromMUC(chatID int64, statusCodes []uint16, destroy bool, mucState *MUCState) error { func (c *Client) kickMeFromMUC(chatID int64, statusCodes []uint16, destroy bool, mucState *MUCState) error {
var myJid string var myJid string
if c.me != nil { if c.me != nil {
@ -2778,12 +2810,7 @@ func (c *Client) kickMeFromMUC(chatID int64, statusCodes []uint16, destroy bool,
gateway.SPMUCStatusCodes(statusCodes), gateway.SPMUCStatusCodes(statusCodes),
} }
if destroy { if destroy {
var toResources []string _, toResources := c.getMUCJoinedJIDs(chatID, mucState, false)
if mucState != nil {
for resource := range mucState.Resources {
toResources = append(toResources, resource)
}
}
args = append( args = append(
args, args,
gateway.SPMUCDestroy(""), gateway.SPMUCDestroy(""),