diff --git a/gtk-helpers.go b/gtk-helpers.go index 602f5f8..a14e723 100644 --- a/gtk-helpers.go +++ b/gtk-helpers.go @@ -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 }) diff --git a/gtk-message.go b/gtk-message.go index 82fc3b0..a1f9e11 100644 --- a/gtk-message.go +++ b/gtk-message.go @@ -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") diff --git a/main.go b/main.go index 444cac5..617387a 100644 --- a/main.go +++ b/main.go @@ -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 } diff --git a/types.go b/types.go index 78b2146..9a2797b 100644 --- a/types.go +++ b/types.go @@ -25,7 +25,7 @@ type mucUnit struct { } type userUnit struct { - // key: Resource + // key: Resource // value: last presence of this device Devices sync.Map } diff --git a/xmpp-hats.go b/xmpp-hats.go new file mode 100644 index 0000000..19716d4 --- /dev/null +++ b/xmpp-hats.go @@ -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{}) +} diff --git a/xmpp-mucuser.go b/xmpp-mucuser.go index ba7f432..f2b7c89 100644 --- a/xmpp-mucuser.go +++ b/xmpp-mucuser.go @@ -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() {