package main import ( "context" "fmt" "github.com/diamondburned/gotk4/pkg/glib/v2" "github.com/diamondburned/gotk4/pkg/gtk/v4" "gosrc.io/xmpp/stanza" ) 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) 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) return true } return false } 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(JidMustParse(u.From).Resource) /* affil_label := gtk.NewLabel("") switch mu.MucUserItem.Affiliation { case "owner": affil_label.SetText("O") case "admin": affil_label.SetText("A") case "member": affil_label.SetText("M") case "none": affil_label.SetText("-") } */ nick_label.AddCSSClass(mu.MucUserItem.Role) if mu.MucUserItem.Role == "visitor" { nick_label.SetOpacity(0.5) } /* affil_label.SetHAlign(gtk.AlignEnd) affil_label.SetHExpand(true) affil_label.AddCSSClass(mu.MucUserItem.Affiliation) */ userbox.SetTooltipText(fmt.Sprintf("%s\n%s\n%s\nRight-click for more information", u.From, mu.MucUserItem.Role, mu.MucUserItem.Affiliation)) userbox.Append(nick_label) // userbox.Append(affil_label) medal := gtk.NewImageFromPaintable(clientAssets[mu.MucUserItem.Affiliation]) medal.SetHAlign(gtk.AlignEnd) medal.SetHExpand(true) userbox.Append(medal) 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(JidMustParse(u.From).Resource) win.SetTitle(JidMustParse(u.From).Resource) 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)) } } var mu MucUser ok = u.Get(&mu) if ok { if mu.MucUserItem.JID != "" { profile_box.Append(gtk.NewLabel(mu.MucUserItem.JID)) } profile_box.Append(gtk.NewLabel("Connected with role " + mu.MucUserItem.Role)) profile_box.Append(gtk.NewLabel("Affiliated as " + mu.MucUserItem.Affiliation)) } 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(JidMustParse(u.From).Bare()) 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) if mu.MucUserItem.Role == "moderator" { gen.Prepend(userbox) } else { gen.Append(userbox) } return true }) memberList.SetChild(gen) } else { memberList.SetChild(gtk.NewLabel(jid)) } } func showErrorDialog(err error) { fmt.Println(err.Error()) }