Send the own MUC member the last with status codes 110/210 according to the spec

This commit is contained in:
Bohdan Horbeshko 2023-09-18 00:47:47 -04:00
parent 4249a8bf41
commit 6c65ef9988
3 changed files with 57 additions and 7 deletions

View file

@ -301,6 +301,17 @@ func (c *Client) SendMUCStatuses(chatID int64) {
Filter: &client.ChatMembersFilterMembers{}, Filter: &client.ChatMembersFilterMembers{},
}) })
if err == nil { if err == nil {
chatIDString := strconv.FormatInt(chatID, 10)
myNickname := "me"
if c.me != nil {
myNickname := c.me.FirstName
if c.me.LastName != "" {
myNickname = myNickname + " " + c.me.LastName
}
}
myAffiliation := "member"
for _, member := range members.Members { for _, member := range members.Members {
var senderId int64 var senderId int64
switch member.MemberId.MessageSenderType() { switch member.MemberId.MessageSenderType() {
@ -311,15 +322,35 @@ func (c *Client) SendMUCStatuses(chatID int64) {
memberChat, _ := member.MemberId.(*client.MessageSenderChat) memberChat, _ := member.MemberId.(*client.MessageSenderChat)
senderId = memberChat.ChatId senderId = memberChat.ChatId
} }
nickname := c.formatContact(senderId)
affiliation := c.memberStatusToAffiliation(member.Status)
if c.me != nil && senderId == c.me.Id {
myNickname = nickname
myAffiliation = affiliation
continue
}
gateway.SendPresence( gateway.SendPresence(
c.xmpp, c.xmpp,
c.jid, c.jid,
gateway.SPFrom(strconv.FormatInt(chatID, 10)), gateway.SPFrom(chatIDString),
gateway.SPResource(c.formatContact(senderId)), gateway.SPResource(nickname),
gateway.SPImmed(true), gateway.SPImmed(true),
gateway.SPAffiliation(c.memberStatusToAffiliation(member.Status)), gateway.SPAffiliation(affiliation),
) )
} }
// according to the spec, own member entry should be sent the last
gateway.SendPresence(
c.xmpp,
c.jid,
gateway.SPFrom(chatIDString),
gateway.SPResource(myNickname),
gateway.SPImmed(true),
gateway.SPAffiliation(myAffiliation),
gateway.SPMUCStatusCodes([]uint16{110, 210}),
)
} }
} }

View file

@ -217,6 +217,7 @@ type QueryRegisterRemove struct {
type PresenceXMucUserExtension struct { type PresenceXMucUserExtension struct {
XMLName xml.Name `xml:"http://jabber.org/protocol/muc#user x"` XMLName xml.Name `xml:"http://jabber.org/protocol/muc#user x"`
Item PresenceXMucUserItem Item PresenceXMucUserItem
Statuses []PresenceXMucUserStatus
} }
// PresenceXMucUserItem is from XEP-0045 // PresenceXMucUserItem is from XEP-0045
@ -226,6 +227,12 @@ type PresenceXMucUserItem struct {
Role string `xml:"role,attr"` Role string `xml:"role,attr"`
} }
// PresenceXMucUserStatus is from XEP-0045
type PresenceXMucUserStatus struct {
XMLName xml.Name `xml:"status"`
Code uint16 `xml:"code,attr"`
}
// Namespace is a namespace! // Namespace is a namespace!
func (c PresenceNickExtension) Namespace() string { func (c PresenceNickExtension) Namespace() string {
return c.XMLName.Space return c.XMLName.Space

View file

@ -243,6 +243,9 @@ var SPImmed = args.NewBool(args.Default(true))
// SPAffiliation is a XEP-0045 MUC affiliation // SPAffiliation is a XEP-0045 MUC affiliation
var SPAffiliation = args.NewString() var SPAffiliation = args.NewString()
// SPMUCStatusCodes is a set of XEP-0045 MUC status codes
var SPMUCStatusCodes = args.New()
func newPresence(bareJid string, to string, args ...args.V) stanza.Presence { func newPresence(bareJid string, to string, args ...args.V) stanza.Presence {
var presenceFrom string var presenceFrom string
if SPFrom.IsSet(args) { if SPFrom.IsSet(args) {
@ -301,14 +304,23 @@ func newPresence(bareJid string, to string, args ...args.V) stanza.Presence {
if SPAffiliation.IsSet(args) { if SPAffiliation.IsSet(args) {
affiliation := SPAffiliation.Get(args) affiliation := SPAffiliation.Get(args)
if affiliation != "" { if affiliation != "" {
presence.Extensions = append(presence.Extensions, extensions.PresenceXMucUserExtension{ userExt := extensions.PresenceXMucUserExtension{
Item: extensions.PresenceXMucUserItem{ Item: extensions.PresenceXMucUserItem{
Affiliation: affiliation, Affiliation: affiliation,
Role: affilationToRole(affiliation), Role: affilationToRole(affiliation),
}, },
}
if SPMUCStatusCodes.IsSet(args) {
statusCodes := SPMUCStatusCodes.Get(args).([]uint16)
for _, statusCode := range statusCodes {
userExt.Statuses = append(userExt.Statuses, extensions.PresenceXMucUserStatus{
Code: statusCode,
}) })
} }
} }
presence.Extensions = append(presence.Extensions, userExt)
}
}
return presence return presence
} }