Add experimental hats support

This commit is contained in:
2026-01-31 15:08:54 +00:00
parent 3962f1f17d
commit 2ef3cf3a06
6 changed files with 135 additions and 2 deletions

View File

@@ -1,6 +1,7 @@
package main
import (
"context"
"fmt"
"github.com/diamondburned/gotk4/pkg/glib/v2"
"github.com/diamondburned/gotk4/pkg/gtk/v4"
@@ -60,6 +61,94 @@ func switchToTab(jid string) {
userbox.Append(nick_label)
gesture := gtk.NewGestureClick()
gesture.SetButton(3) // Right click
gesture.Connect("pressed", func(n_press, x, y int) {
win := gtk.NewWindow()
win.SetDefaultSize(400, 400)
profile_box := gtk.NewBox(gtk.OrientationVertical, 0)
nick := gtk.NewLabel(Jid.MustParse(u.From).Resourcepart())
nick.AddCSSClass("author")
profile_box.Append(nick)
profile_box.Append(gtk.NewLabel(u.From))
iqResp, err := stanza.NewIQ(stanza.Attrs{
Type: "get",
From: clientroot.Session.BindJid,
To: u.From,
Id: "vc2",
Lang: "en",
})
if err != nil {
panic(err)
}
iqResp.Payload = &stanza.Version{}
loading_version_text := gtk.NewLabel("...")
var hats Hats
ok := u.Get(&hats)
if ok {
for _, hat := range hats.Hats {
profile_box.Append(gtk.NewLabel(hat.Title))
}
}
go func() {
ctx := context.TODO()
mychan, err := client.SendIQ(ctx, iqResp)
if err == nil {
result := <-mychan
ver, ok := result.Payload.(*stanza.Version)
if ok {
loading_version_text.SetVisible(false)
name := ver.Name
version := ver.Version
os := ver.OS
profile_box.Append(gtk.NewLabel(name))
profile_box.Append(gtk.NewLabel(version))
profile_box.Append(gtk.NewLabel(os))
}
}
}()
go func() {
mo, _ := mucmembers.Load(Jid.MustParse(u.From).Bare().String())
mm := mo.(mucUnit)
mmm := mm.Members
mmmm, ok := mmm.Load(ocu.ID)
if ok {
pres := mmmm.(stanza.Presence)
var vu VCardUpdate
pres.Get(&vu)
if vu.Photo != "" {
im := getAvatar(u.From, vu.Photo)
im.SetPixelSize(80)
im.AddCSSClass("author_img")
profile_box.Append(im)
} else {
im := newImageFromPath("debug.png")
im.SetPixelSize(80)
im.AddCSSClass("author_img")
profile_box.Append(im)
}
} else {
im := newImageFromPath("debug.png")
im.SetPixelSize(80)
im.AddCSSClass("author_img")
profile_box.Append(im)
}
}()
win.SetChild(profile_box)
win.Present()
})
userbox.AddController(gesture)
gen.Append(userbox)
return true
})

View File

@@ -24,6 +24,14 @@ func generatePresenceWidget(p stanza.Packet) gtk.Widgetter {
}
if presence.Type == stanza.PresenceTypeUnavailable {
var mu MucUser
ok := presence.Get(&mu)
if ok {
if mu.MucUserItem.Affiliation == "outcast" {
return gtk.NewLabel(jid.MustParse(presence.From).Resourcepart() + " has been banned!")
}
}
return gtk.NewLabel(jid.MustParse(presence.From).Resourcepart() + " left the room")
} else {
return gtk.NewLabel(jid.MustParse(presence.From).Resourcepart() + " joined the room")

View File

@@ -10,6 +10,7 @@ import (
"github.com/diamondburned/gotk4/pkg/gio/v2"
"github.com/diamondburned/gotk4/pkg/glib/v2"
"github.com/diamondburned/gotk4/pkg/gtk/v4"
"github.com/kr/pretty"
"github.com/BurntSushi/toml"
"gosrc.io/xmpp"
@@ -79,7 +80,7 @@ func main() {
Jid: loadedConfig.Username,
Credential: xmpp.Password(loadedConfig.Password),
Insecure: loadedConfig.Insecure,
StreamLogger: os.Stdout,
// StreamLogger: os.Stdout,
}
router := xmpp.NewRouter()
@@ -112,6 +113,7 @@ func main() {
{Var: "urn:xmpp:delegation:1"},
{Var: "http://jabber.org/protocol/muc"},
{Var: "urn:xmpp:reply:0"},
{Var: "λ"},
},
}
iqResp.Payload = &payload
@@ -176,6 +178,8 @@ func main() {
return
}
pretty.Println(presence)
if presence.Error != *new(stanza.Err) {
return
}

31
xmpp-hats.go Normal file
View File

@@ -0,0 +1,31 @@
package main
import (
"encoding/xml"
"gosrc.io/xmpp/stanza"
)
// Implementation of XEP-0317: Hats
// https://xmpp.org/extensions/xep-0317.html
type Hats struct {
XMLName xml.Name `xml:"urn:xmpp:hats:0 hats"`
Hats []Hat `xml:"hat"`
}
type Hat struct {
Title string `xml:"title,attr"`
URI string `xml:"uri,attr"`
Hue string `xml:"hue,attr"`
Lang string `xml:"xml:lang,attr"`
Badge Badge `xml:"badge"`
}
type Badge struct {
XMLName xml.Name `xml:"urn:example:badges badge"`
Level int `xml:"level,attr"`
}
func init() {
stanza.TypeRegistry.MapExtension(stanza.PKTPresence, xml.Name{Space: "urn:xmpp:hats:0", Local: "hats"}, Hats{})
}

View File

@@ -19,6 +19,7 @@ type MucUserItem struct {
Affiliation string `xml:"affiliation,attr,omitempty"` // TODO: Use enum
Role string `xml:"role,attr,omitempty"` // TODO: Use enum
JID string `xml:"jid,attr,omitempty"`
Reason string `xml:"reason,omitempty"`
}
func init() {