package main import ( "context" "fmt" "github.com/diamondburned/gotk4/pkg/glib/v2" "github.com/diamondburned/gotk4/pkg/gtk/v4" "gosrc.io/xmpp/stanza" Jid "mellium.im/xmpp/jid" ) func scrollToBottomAfterUpdate(scrolledWindow *gtk.ScrolledWindow) { glib.IdleAdd(func() bool { vAdj := scrolledWindow.VAdjustment() vAdj.SetValue(vAdj.Upper() - vAdj.PageSize()) return false // Return false to run only once }) } func createTab(jid string, isMuc bool) { fmt.Println("Creating tab", jid, "isMuc:", isMuc) _, ok := tabs.Load(jid) if !ok { newTab := new(chatTab) newTab.isMuc = isMuc newTab.msgs = gtk.NewListBox() newTab.msgs.SetVExpand(true) newTab.msgs.SetShowSeparators(true) newTab.msgs.Append(gtk.NewButtonWithLabel("Get past messages...")) tabs.Store(jid, newTab) } } func switchToTab(jid string, w *gtk.Window) { current = jid tab, ok := tabs.Load(current) if !ok { return } typed_tab := tab.(*chatTab) scroller.SetChild(typed_tab.msgs) if typed_tab.isMuc { m, _ := mucmembers.Load(jid) ma := m.(mucUnit) mm := ma.Members gen := gtk.NewBox(gtk.OrientationVertical, 0) mm.Range(func(k, v any) bool { userbox := gtk.NewBox(gtk.OrientationHorizontal, 0) u := v.(stanza.Presence) var mu MucUser var ocu OccupantID u.Get(&mu) u.Get(&ocu) nick_label := gtk.NewLabel(Jid.MustParse(u.From).Resourcepart()) 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.SetTransientFor(win) win.Present() }) userbox.AddController(gesture) gen.Append(userbox) return true }) memberList.SetChild(gen) } else { memberList.SetChild(gtk.NewLabel(jid)) } } func showErrorDialog(err error) { fmt.Println(err.Error()) }