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

View file

@ -872,19 +872,23 @@ func (c *Client) MUCHasResource(chatID int64, resource string) bool {
return ok
}
func (c *Client) getMUCJoinedJIDs(chatId int64) (bool, []string) {
c.locks.mucCacheLock.Lock()
defer c.locks.mucCacheLock.Unlock()
func (c *Client) getMUCJoinedJIDs(chatId int64, mucState *MUCState, lock bool) (bool, []string) {
if lock {
c.locks.mucCacheLock.Lock()
defer c.locks.mucCacheLock.Unlock()
}
groupChatTos := []string{}
mucState, ok := c.mucCache[chatId]
if !ok || mucState == nil {
if mucState == nil {
mucState, _ = c.mucCache[chatId]
}
if mucState == 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
@ -1099,7 +1103,7 @@ func (c *Client) getMessageReply(message *client.Message, preview bool, noConten
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
if message == nil {
message, err = c.client.GetMessage(&client.GetMessageRequest{
@ -1115,16 +1119,18 @@ func (c *Client) formatMessage(chatID int64, messageID int64, preview bool, mess
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
// add messageid and sender
if message.MessageId != 0 {
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
if !preview {
str.WriteString(
@ -1354,7 +1360,7 @@ func (c *Client) messageContentToText(content client.MessageContent, chatId int6
return "kicked " + c.FormatContact(deleteMember.UserId)
case client.TypeMessagePinMessage:
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:
changeTitle, _ := content.(*client.MessageChatChangeTitle)
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)
}
replyLine := "reply: " + c.formatMessageContent(preview, tgReply)
replyLine := "reply: " + c.formatMessageContent(preview, tgReply, true)
prefix = append(prefix, 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)
var ok bool
ok, groupChatTos = c.getMUCJoinedJIDs(chatId)
ok, groupChatTos = c.getMUCJoinedJIDs(chatId, nil, true)
if !ok {
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) {
sChatId := gateway.CHATNODE(chatID)
var mucJid string
if toJid != "" {
mucJid = gateway.MUCJID(chatID)
mucJid := gateway.MUCJID(chatID)
var plainTos []string
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-- {
@ -2614,23 +2631,37 @@ func (c *Client) sendMessagesReverse(chatID int64, messages []*client.Message, p
if plain {
reply, _ := c.getMessageReply(message, false, true)
sId := strconv.FormatInt(message.Id, 10)
gateway.SendMessage(
c.jid,
sChatId,
c.formatMessage(0, 0, false, message),
sId,
c.xmpp,
reply,
0,
"",
false,
false,
false,
"",
"",
)
var originalFrom string
var from string
if isMUC {
senderId := c.getMessageSenderId(message)
if senderId != 0 {
originalFrom = gateway.CHATJID(senderId, true)
}
from = mucJid + "/" + c.GetMUCNickname(senderId)
} else {
from = sChatId
}
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 {
msgId, _ := gateway.IdsDB.GetByTgIds(c.Session.Login, c.jid, chatID, message.Id)
c.SendMessageToGateway(
@ -2764,6 +2795,7 @@ func (c *Client) leaveChat(chatID int64) error {
return c.unsubscribe(chatID)
}
// achtung: assuming a locked mucState context
func (c *Client) kickMeFromMUC(chatID int64, statusCodes []uint16, destroy bool, mucState *MUCState) error {
var myJid string
if c.me != nil {
@ -2778,12 +2810,7 @@ func (c *Client) kickMeFromMUC(chatID int64, statusCodes []uint16, destroy bool,
gateway.SPMUCStatusCodes(statusCodes),
}
if destroy {
var toResources []string
if mucState != nil {
for resource := range mucState.Resources {
toResources = append(toResources, resource)
}
}
_, toResources := c.getMUCJoinedJIDs(chatID, mucState, false)
args = append(
args,
gateway.SPMUCDestroy(""),