lambda is free of this insane bug

This commit is contained in:
2026-07-17 17:15:41 +01:00
parent 120b0c2647
commit 006b43a590
9 changed files with 263 additions and 240 deletions
Submodule
+1
Submodule go-xmpp added at bc2b7ceee4
+2
View File
@@ -49,3 +49,5 @@ require (
mellium.im/xmlstream v0.15.4 // indirect
nhooyr.io/websocket v1.8.17 // indirect
)
replace gosrc.io/xmpp => ./go-xmpp/
+382 -375
View File
@@ -23,387 +23,19 @@ import (
func init() {
}
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, name string) bool {
if name == "" {
name = jid
}
_, ok := tabs.Load(jid)
_, uok := userdevices.Load(jid)
_, mok := mucmembers.Load(jid)
if !ok && !uok && !mok {
newTab := new(chatTab)
newTab.isMuc = isMuc
newTab.msgs = gtk.NewListBox()
glib.IdleAdd(func() {
newTab.msgs.SetVExpand(true)
newTab.msgs.SetShowSeparators(true)
newTab.msgs.Append(gtk.NewButtonWithLabel(loadedLocale["getPastMessages"]))
})
newTab.name = name
tabs.Store(jid, newTab)
return true
}
return false
}
func removeTab(jid string, w *gtk.Window) {
t, ok := tabs.Load(jid)
if ok {
tab := t.(*chatTab)
tab.msgs.RemoveAll()
if tab.isMuc {
client.SendRaw(fmt.Sprintf(`
<presence from='%s' to='%s' type='unavailable'>
<x xmlns='http://jabber.org/protocol/muc'/>
</presence>
`, clientroot.Session.BindJid, jid+"/"+tab.current_nick))
}
tabs.Delete(jid)
mucmembers.Delete(jid)
userdevices.Delete(jid)
if current == jid {
current = ""
scroller.SetChild(empty_dialog)
typingStatus.SetText("")
memberList.SetChild(gtk.NewLabel(""))
}
mucmembers.Delete(jid)
}
}
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)
typingStatus.SetText("")
if typed_tab.isMuc {
m, ok := mucmembers.Load(jid)
if !ok {
box := gtk.NewBox(gtk.OrientationVertical, 10)
failed_icon := gtk.NewImageFromPaintable(clientAssetsLoad("fail"))
failed_icon.SetPixelSize(100)
box.Append(failed_icon)
label := gtk.NewLabel("There was an error loading the members of this room. Maybe the MUC does not give user presence, it does not exist, you have been banned from it, or you have to fill a CAPTCHA to access it. Try joining the room again or check if the room exists.")
label.SetWrap(true)
box.Append(label)
memberList.SetChild(box)
return
}
ma, ok := m.(mucUnit)
if !ok {
box := gtk.NewBox(gtk.OrientationVertical, 10)
failed_icon := gtk.NewImageFromPaintable(clientAssetsLoad("fail"))
failed_icon.SetPixelSize(100)
box.Append(failed_icon)
label := gtk.NewLabel("There was an error loading the members of this room. Maybe the MUC does not give user presence, it does not exist, you have been banned from it, or you have to fill a CAPTCHA to access it. Try joining the room again or check if the room exists.")
label.SetWrap(true)
box.Append(label)
memberList.SetChild(box)
return
}
mm := ma.Members
gen := gtk.NewBox(gtk.OrientationVertical, 10)
i := 0
rangeOrdered(&mm, (func(k, v any) bool {
i++
u, ok := v.(stanza.Presence)
if !ok {
return true
}
userbox := gtk.NewBox(gtk.OrientationHorizontal, 2)
var mu MucUser
func showUserWindow(u stanza.Presence, custom_nick string) {
var ocu OccupantID
u.Get(&mu)
u.Get(&ocu)
if mu.MucUserItem.Role == "moderator" {
gen.Prepend(gtk.NewSeparator(gtk.OrientationHorizontal))
gen.Prepend(userbox)
} else {
gen.Append(userbox)
gen.Append(gtk.NewSeparator(gtk.OrientationHorizontal))
}
var id string
id = JidMustParse(u.From).Resource
//id := ocu.ID
//if id == "" {
id := JidMustParse(u.From).Resource
//}
nick_label := gtk.NewLabel(JidMustParse(u.From).Resource)
var custom_nick string
var vcu VCardUpdate
ok = u.Get(&vcu)
if ok {
av_nick, ok := loadedConfig.CustomNicksAV[vcu.Photo]
if ok {
custom_nick = av_nick
}
}
ocu_nick, ok := loadedConfig.CustomNicks[ocu.ID]
if ok {
custom_nick = ocu_nick
}
if custom_nick != "" {
nick_label.SetText(custom_nick)
}
nick_label.SetEllipsize(pango.EllipsizeEnd)
nick_label.AddCSSClass(mu.MucUserItem.Role)
if mu.MucUserItem.Role == "visitor" {
nick_label.SetOpacity(0.5)
}
userbox.SetTooltipText(fmt.Sprintf("%s\n%s\n%s\n%s", u.From, mu.MucUserItem.Role, mu.MucUserItem.Affiliation, loadedLocale["clickForMoreInfo"]))
userbox.Append(nick_label)
var hats Hats
ok = u.Get(&hats)
if ok {
for _, hat := range hats.Hats {
var val float64
if hat.Hue != "" {
tval, _ := strconv.Atoi(hat.Hue)
val = float64(tval)
} else {
xc := xmpp_color.String(hat.URI, 255, loadedConfig.CVD)
r, g, b, _ := xc.RGBA()
val, _, _ = colorconv.RGBToHSV(uint8(r), uint8(g), uint8(b))
}
tB := tagBytes
img, _, _ := image.Decode(bytes.NewReader(tB))
i_rgba := imaging.AdjustHue(img, val)
var buf bytes.Buffer
png.Encode(&buf, i_rgba)
tB = buf.Bytes()
loader := gdkpixbuf.NewPixbufLoader()
loader.Write(tB)
loader.Close()
tag := gtk.NewPictureForPaintable(gdk.NewTextureForPixbuf(loader.Pixbuf()))
tag.SetTooltipText(hat.Title)
userbox.Prepend(tag)
}
}
status := gtk.NewImageFromPaintable(clientAssetsLoad("status_" + string(u.Show)))
status.SetTooltipText(string(u.Show))
status.SetHAlign(gtk.AlignEnd)
// medal.SetHExpand(true)
userbox.Prepend(status)
if u.Status != "" {
status_message := gtk.NewImageFromPaintable(clientAssetsLoad("comment"))
status_message.SetTooltipText(u.Status)
status_message.SetHAlign(gtk.AlignEnd)
userbox.Append(status_message)
}
medal := gtk.NewImageFromPaintable(clientAssetsLoad(mu.MucUserItem.Affiliation))
medal.SetTooltipText(mu.MucUserItem.Affiliation)
medal.SetHAlign(gtk.AlignEnd)
medal.SetHExpand(true)
userbox.Append(medal)
if loadedConfig.ShowAvatarsInMemberList {
default_av := createIdenticon(u.From, false)
userbox.Prepend(default_av)
var vcu VCardUpdate
ok = u.Get(&vcu)
if ok {
photo := vcu.Photo
go func() {
new_im := getAvatar(u.From, photo)
glib.IdleAdd(func() {
userbox.Remove(default_av)
userbox.Prepend(new_im)
})
}()
}
}
gesture := gtk.NewGestureClick()
gesture.SetButton(1)
mod_gesture := gtk.NewGestureClick()
mod_gesture.SetButton(3)
popover := gtk.NewPopover()
popover.SetHasArrow(false)
popover.SetParent(userbox)
rc_box := gtk.NewBox(gtk.OrientationVertical, 0)
bb := gtk.NewButtonWithLabel(loadedLocale["ban"])
kb := gtk.NewButtonWithLabel(loadedLocale["kick"])
ab := gtk.NewButtonWithLabel(loadedLocale["setAffil"])
rb := gtk.NewButtonWithLabel(loadedLocale["setRole"])
kb.ConnectClicked(func() {
client.SendRaw(fmt.Sprintf(`
<iq from='%s'
id='kick1'
to='%s'
type='set'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item nick='%s' role='none'>
</item>
</query>
</iq>
`, clientroot.Session.BindJid, jid, JidMustParse(u.From).Resource))
})
bb.ConnectClicked(func() {
var mu MucUser
ok = u.Get(&mu)
if ok {
if mu.MucUserItem.JID != "" {
client.SendRaw(fmt.Sprintf(`
<iq from='%s'
id='ban1'
to='%s'
type='set'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item affiliation='outcast' jid='%s'/>
</query>
</iq>
`, clientroot.Session.BindJid, jid, JidMustParse(mu.MucUserItem.JID).Bare()))
}
}
})
ab.ConnectClicked(func() {
var mu MucUser
ok = u.Get(&mu)
if ok {
if mu.MucUserItem.JID != "" {
win := gtk.NewWindow()
win.SetDefaultSize(400, 1)
win.SetResizable(false)
box := gtk.NewBox(gtk.OrientationVertical, 0)
box.Append(gtk.NewLabel(loadedLocale["setAffilDescPartOne"] + JidMustParse(u.From).Resource + loadedLocale["setAffilDescPartTwo"]))
the_entry := gtk.NewEntry()
the_entry.SetText(mu.MucUserItem.Affiliation)
submit := gtk.NewButtonWithLabel(loadedLocale["submit"])
submit.ConnectClicked(func() {
client.SendRaw(fmt.Sprintf(`
<iq from='%s'
id='ba1'
to='%s'
type='set'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item affiliation='%s' jid='%s'/>
</query>
</iq>
`, clientroot.Session.BindJid, jid, the_entry.Text(), JidMustParse(mu.MucUserItem.JID).Bare()))
win.SetVisible(false)
})
box.Append(the_entry)
box.Append(submit)
win.SetChild(box)
win.SetVisible(true)
}
}
})
rb.ConnectClicked(func() {
var mu MucUser
ok = u.Get(&mu)
if ok {
if mu.MucUserItem.JID != "" {
win := gtk.NewWindow()
win.SetDefaultSize(400, 1)
win.SetResizable(false)
box := gtk.NewBox(gtk.OrientationVertical, 0)
box.Append(gtk.NewLabel(loadedLocale["setRoleDescPartOne"] + JidMustParse(u.From).Resource + loadedLocale["setRoleDescPartTwo"]))
box.Append(gtk.NewLabel(loadedLocale["setRoleWarning"]))
the_entry := gtk.NewEntry()
the_entry.SetText(mu.MucUserItem.Role)
submit := gtk.NewButtonWithLabel(loadedLocale["submit"])
submit.ConnectClicked(func() {
client.SendRaw(fmt.Sprintf(`
<iq from='%s'
id='kick1'
to='%s'
type='set'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item nick='%s' role='%s'>
</item>
</query>
</iq>
`, clientroot.Session.BindJid, jid, JidMustParse(u.From).Resource, the_entry.Text()))
})
box.Append(the_entry)
box.Append(submit)
win.SetChild(box)
win.SetVisible(true)
}
}
})
rc_box.Append(bb)
rc_box.Append(kb)
rc_box.Append(ab)
rc_box.Append(rb)
popover.SetChild(rc_box)
mod_gesture.Connect("pressed", func(n_press, x, y int) {
rect := gdk.NewRectangle(x, y, 1, 1)
popover.SetPointingTo(&rect)
popover.Popup()
})
gesture.Connect("pressed", func(n_press, x, y int) {
win := gtk.NewWindow()
win.SetDefaultSize(400, 400)
win.SetResizable(false)
profile_box := gtk.NewBox(gtk.OrientationVertical, 0)
nick := gtk.NewLabel(JidMustParse(u.From).Resource)
if custom_nick != "" {
nick.SetText(custom_nick)
}
@@ -584,6 +216,382 @@ func switchToTab(jid string, w *gtk.Window) {
win.SetChild(profile_box)
win.SetTransientFor(win)
win.Present()
}
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, name string) bool {
if name == "" {
name = jid
}
_, ok := tabs.Load(jid)
_, uok := userdevices.Load(jid)
_, mok := mucmembers.Load(jid)
if !ok && !uok && !mok {
newTab := new(chatTab)
newTab.isMuc = isMuc
newTab.msgs = gtk.NewListBox()
glib.IdleAdd(func() {
newTab.msgs.SetVExpand(true)
newTab.msgs.SetShowSeparators(true)
newTab.msgs.Append(gtk.NewButtonWithLabel(loadedLocale["getPastMessages"]))
})
newTab.name = name
tabs.Store(jid, newTab)
return true
}
return false
}
func removeTab(jid string, w *gtk.Window) {
t, ok := tabs.Load(jid)
if ok {
tab := t.(*chatTab)
tab.msgs.RemoveAll()
if tab.isMuc {
client.SendRaw(fmt.Sprintf(`
<presence from='%s' to='%s' type='unavailable'>
<x xmlns='http://jabber.org/protocol/muc'/>
</presence>
`, clientroot.Session.BindJid, jid+"/"+tab.current_nick))
}
tabs.Delete(jid)
mucmembers.Delete(jid)
userdevices.Delete(jid)
if current == jid {
current = ""
scroller.SetChild(empty_dialog)
typingStatus.SetText("")
memberList.SetChild(gtk.NewLabel(""))
}
mucmembers.Delete(jid)
}
}
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)
typingStatus.SetText("")
if typed_tab.isMuc {
m, ok := mucmembers.Load(jid)
if !ok {
box := gtk.NewBox(gtk.OrientationVertical, 10)
failed_icon := gtk.NewImageFromPaintable(clientAssetsLoad("fail"))
failed_icon.SetPixelSize(100)
box.Append(failed_icon)
label := gtk.NewLabel("There was an error loading the members of this room. Maybe the MUC does not give user presence, it does not exist, you have been banned from it, or you have to fill a CAPTCHA to access it. Try joining the room again or check if the room exists.")
label.SetWrap(true)
box.Append(label)
memberList.SetChild(box)
return
}
ma, ok := m.(mucUnit)
if !ok {
box := gtk.NewBox(gtk.OrientationVertical, 10)
failed_icon := gtk.NewImageFromPaintable(clientAssetsLoad("fail"))
failed_icon.SetPixelSize(100)
box.Append(failed_icon)
label := gtk.NewLabel("There was an error loading the members of this room. Maybe the MUC does not give user presence, it does not exist, you have been banned from it, or you have to fill a CAPTCHA to access it. Try joining the room again or check if the room exists.")
label.SetWrap(true)
box.Append(label)
memberList.SetChild(box)
return
}
mm := ma.Members
gen := gtk.NewBox(gtk.OrientationVertical, 10)
i := 0
rangeOrdered(&mm, (func(k, v any) bool {
i++
u, ok := v.(stanza.Presence)
if !ok {
return true
}
userbox := gtk.NewBox(gtk.OrientationHorizontal, 2)
var mu MucUser
var ocu OccupantID
u.Get(&mu)
u.Get(&ocu)
if mu.MucUserItem.Role == "moderator" {
gen.Prepend(gtk.NewSeparator(gtk.OrientationHorizontal))
gen.Prepend(userbox)
} else {
gen.Append(userbox)
gen.Append(gtk.NewSeparator(gtk.OrientationHorizontal))
}
//id := ocu.ID
//if id == "" {
// id := JidMustParse(u.From).Resource
//}
nick_label := gtk.NewLabel(JidMustParse(u.From).Resource)
var custom_nick string
var vcu VCardUpdate
ok = u.Get(&vcu)
if ok {
av_nick, ok := loadedConfig.CustomNicksAV[vcu.Photo]
if ok {
custom_nick = av_nick
}
}
ocu_nick, ok := loadedConfig.CustomNicks[ocu.ID]
if ok {
custom_nick = ocu_nick
}
if custom_nick != "" {
nick_label.SetText(custom_nick)
}
nick_label.SetEllipsize(pango.EllipsizeEnd)
nick_label.AddCSSClass(mu.MucUserItem.Role)
if mu.MucUserItem.Role == "visitor" {
nick_label.SetOpacity(0.5)
}
userbox.SetTooltipText(fmt.Sprintf("%s\n%s\n%s\n%s", u.From, mu.MucUserItem.Role, mu.MucUserItem.Affiliation, loadedLocale["clickForMoreInfo"]))
userbox.Append(nick_label)
var hats Hats
ok = u.Get(&hats)
if ok {
for _, hat := range hats.Hats {
var val float64
if hat.Hue != "" {
tval, _ := strconv.Atoi(hat.Hue)
val = float64(tval)
} else {
xc := xmpp_color.String(hat.URI, 255, loadedConfig.CVD)
r, g, b, _ := xc.RGBA()
val, _, _ = colorconv.RGBToHSV(uint8(r), uint8(g), uint8(b))
}
tB := tagBytes
img, _, _ := image.Decode(bytes.NewReader(tB))
i_rgba := imaging.AdjustHue(img, val)
var buf bytes.Buffer
png.Encode(&buf, i_rgba)
tB = buf.Bytes()
loader := gdkpixbuf.NewPixbufLoader()
loader.Write(tB)
loader.Close()
tag := gtk.NewPictureForPaintable(gdk.NewTextureForPixbuf(loader.Pixbuf()))
tag.SetTooltipText(hat.Title)
userbox.Prepend(tag)
}
}
status := gtk.NewImageFromPaintable(clientAssetsLoad("status_" + string(u.Show)))
status.SetTooltipText(string(u.Show))
status.SetHAlign(gtk.AlignEnd)
// medal.SetHExpand(true)
userbox.Prepend(status)
if u.Status != "" {
status_message := gtk.NewImageFromPaintable(clientAssetsLoad("comment"))
status_message.SetTooltipText(u.Status)
status_message.SetHAlign(gtk.AlignEnd)
userbox.Append(status_message)
}
medal := gtk.NewImageFromPaintable(clientAssetsLoad(mu.MucUserItem.Affiliation))
medal.SetTooltipText(mu.MucUserItem.Affiliation)
medal.SetHAlign(gtk.AlignEnd)
medal.SetHExpand(true)
userbox.Append(medal)
if loadedConfig.ShowAvatarsInMemberList {
default_av := createIdenticon(u.From, false)
userbox.Prepend(default_av)
var vcu VCardUpdate
ok = u.Get(&vcu)
if ok {
photo := vcu.Photo
go func() {
new_im := getAvatar(u.From, photo)
glib.IdleAdd(func() {
userbox.Remove(default_av)
userbox.Prepend(new_im)
})
}()
}
}
gesture := gtk.NewGestureClick()
gesture.SetButton(1)
mod_gesture := gtk.NewGestureClick()
mod_gesture.SetButton(3)
popover := gtk.NewPopover()
popover.SetHasArrow(false)
popover.SetParent(userbox)
rc_box := gtk.NewBox(gtk.OrientationVertical, 0)
bb := gtk.NewButtonWithLabel(loadedLocale["ban"])
kb := gtk.NewButtonWithLabel(loadedLocale["kick"])
ab := gtk.NewButtonWithLabel(loadedLocale["setAffil"])
rb := gtk.NewButtonWithLabel(loadedLocale["setRole"])
kb.ConnectClicked(func() {
client.SendRaw(fmt.Sprintf(`
<iq from='%s'
id='kick1'
to='%s'
type='set'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item nick='%s' role='none'>
</item>
</query>
</iq>
`, clientroot.Session.BindJid, jid, JidMustParse(u.From).Resource))
})
bb.ConnectClicked(func() {
var mu MucUser
ok = u.Get(&mu)
if ok {
if mu.MucUserItem.JID != "" {
client.SendRaw(fmt.Sprintf(`
<iq from='%s'
id='ban1'
to='%s'
type='set'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item affiliation='outcast' jid='%s'/>
</query>
</iq>
`, clientroot.Session.BindJid, jid, JidMustParse(mu.MucUserItem.JID).Bare()))
}
}
})
ab.ConnectClicked(func() {
var mu MucUser
ok = u.Get(&mu)
if ok {
if mu.MucUserItem.JID != "" {
win := gtk.NewWindow()
win.SetDefaultSize(400, 1)
win.SetResizable(false)
box := gtk.NewBox(gtk.OrientationVertical, 0)
box.Append(gtk.NewLabel(loadedLocale["setAffilDescPartOne"] + JidMustParse(u.From).Resource + loadedLocale["setAffilDescPartTwo"]))
the_entry := gtk.NewEntry()
the_entry.SetText(mu.MucUserItem.Affiliation)
submit := gtk.NewButtonWithLabel(loadedLocale["submit"])
submit.ConnectClicked(func() {
client.SendRaw(fmt.Sprintf(`
<iq from='%s'
id='ba1'
to='%s'
type='set'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item affiliation='%s' jid='%s'/>
</query>
</iq>
`, clientroot.Session.BindJid, jid, the_entry.Text(), JidMustParse(mu.MucUserItem.JID).Bare()))
win.Destroy()
})
box.Append(the_entry)
box.Append(submit)
win.SetChild(box)
win.SetVisible(true)
}
}
})
rb.ConnectClicked(func() {
var mu MucUser
ok = u.Get(&mu)
if ok {
if mu.MucUserItem.JID != "" {
win := gtk.NewWindow()
win.SetDefaultSize(400, 1)
win.SetResizable(false)
box := gtk.NewBox(gtk.OrientationVertical, 0)
box.Append(gtk.NewLabel(loadedLocale["setRoleDescPartOne"] + JidMustParse(u.From).Resource + loadedLocale["setRoleDescPartTwo"]))
box.Append(gtk.NewLabel(loadedLocale["setRoleWarning"]))
the_entry := gtk.NewEntry()
the_entry.SetText(mu.MucUserItem.Role)
submit := gtk.NewButtonWithLabel(loadedLocale["submit"])
submit.ConnectClicked(func() {
client.SendRaw(fmt.Sprintf(`
<iq from='%s'
id='kick1'
to='%s'
type='set'>
<query xmlns='http://jabber.org/protocol/muc#admin'>
<item nick='%s' role='%s'>
</item>
</query>
</iq>
`, clientroot.Session.BindJid, jid, JidMustParse(u.From).Resource, the_entry.Text()))
})
box.Append(the_entry)
box.Append(submit)
win.SetChild(box)
win.SetVisible(true)
}
}
})
rc_box.Append(bb)
rc_box.Append(kb)
rc_box.Append(ab)
rc_box.Append(rb)
popover.SetChild(rc_box)
mod_gesture.Connect("pressed", func(n_press, x, y int) {
rect := gdk.NewRectangle(x, y, 1, 1)
popover.SetPointingTo(&rect)
popover.Popup()
})
gesture.Connect("pressed", func(n_press, x, y int) {
showUserWindow(u, custom_nick)
})
userbox.AddController(gesture)
@@ -625,7 +633,6 @@ func switchToTab(jid string, w *gtk.Window) {
} else {
memberList.SetChild(gtk.NewLabel(jid))
}
}
func showErrorDialog(err error, w *gtk.Window) {
@@ -641,7 +648,7 @@ func showErrorDialog(err error, w *gtk.Window) {
close_btn := gtk.NewButtonWithLabel(loadedLocale["close"])
close_btn.ConnectClicked(func() {
err_win.SetVisible(false)
err_win.Destroy()
})
box.Append(close_btn)
err_win.SetChild(box)
@@ -737,7 +744,7 @@ func jidBuilder(en *gtk.Entry) { // This function spawns a window that allows th
jid := localPart + at + domain + slash + resource
en.SetText(jid)
win.SetVisible(false)
win.Destroy()
})
box.Append(submit)
+50 -34
View File
@@ -110,6 +110,37 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
sid := StanzaID{}
m.Get(&sid)
ocu := OccupantID{}
m.Get(&ocu)
id := JidMustParse(m.From).Resource
name := id
custom_nick, ok := loadedConfig.CustomNicks[ocu.ID]
if ok {
name = custom_nick
}
// Avatar hash custom nicks. This code needs to be optimised.
mo, ok := mucmembers.Load(JidMustParse(m.From).Bare())
if ok {
mm, ok := mo.(mucUnit)
if ok {
mmm, ok := mm.Members.Load(id)
if ok {
u := mmm.(stanza.Presence)
var vcu VCardUpdate
ok = u.Get(&vcu)
if ok {
av_nick, ok := loadedConfig.CustomNicksAV[vcu.Photo]
if ok {
name = av_nick
}
}
}
}
}
padding := 10
orientation := gtk.OrientationVertical
if loadedConfig.CompactMode {
@@ -177,6 +208,23 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
})
rc_box.Append(quote)
vp := gtk.NewButtonWithLabel("View profile")
vp.ConnectClicked(func() {
mo, ok := mucmembers.Load(JidMustParse(m.From).Bare())
if ok {
mm, ok := mo.(mucUnit)
if ok {
mmm, ok := mm.Members.Load(id)
if ok {
u := mmm.(stanza.Presence)
showUserWindow(u, name)
}
}
}
})
rc_box.Append(vp)
popover.SetChild(rc_box)
rect := gdk.NewRectangle(x, y, 1, 1)
popover.SetPointingTo(&rect)
@@ -185,50 +233,18 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
mainBox.AddController(gesture)
ocu := OccupantID{}
m.Get(&ocu)
id := JidMustParse(m.From).Resource
name := id
// Avatar hash custom nicks. This code needs to be optimised.
mo, ok := mucmembers.Load(JidMustParse(m.From).Bare())
if ok {
mm, ok := mo.(mucUnit)
if ok {
mmm, ok := mm.Members.Load(id)
if ok {
u := mmm.(stanza.Presence)
var vcu VCardUpdate
ok = u.Get(&vcu)
if ok {
av_nick, ok := loadedConfig.CustomNicksAV[vcu.Photo]
if ok {
name = av_nick
}
}
}
}
}
custom_nick, ok := loadedConfig.CustomNicks[ocu.ID]
if ok {
name = custom_nick
}
if name == "" {
name = JidMustParse(m.From).Bare()
}
if loadedConfig.CompactMode {
al := gtk.NewLabel(id)
al := gtk.NewLabel(name)
ycbcr := xmpp_color.String(id, 255, loadedConfig.CVD)
r, g, b, _ := ycbcr.RGBA()
hexcolor := fmt.Sprintf("#%02x%02x%02x", r, g, b)
al.SetMarkup(fmt.Sprintf("<span foreground='%s'>%s</span>", hexcolor, id))
al.SetMarkup(fmt.Sprintf("<span foreground='%s'>%s</span>", hexcolor, name))
al.SetSelectable(true)
al.SetVAlign(gtk.AlignStart)
mainBox.Append(al)
+2 -4
View File
@@ -6,9 +6,9 @@ import (
"sync"
"context"
"crypto/tls"
"fmt"
"path/filepath"
"crypto/tls"
"github.com/diamondburned/gotk4/pkg/gdk/v4"
"github.com/diamondburned/gotk4/pkg/gdkpixbuf/v2"
@@ -588,6 +588,7 @@ func main() {
if err == nil {
res, ok := result.Payload.(*stanza.PubSubGeneric)
if ok {
fmt.Printf("%d rooms in bookmarks\n", len(res.Items.List))
for _, item := range res.Items.List {
jid := item.Id
node := item.Any
@@ -1276,7 +1277,6 @@ func activate(app *gtk.Application) {
win.SetVisible(false)
})
box.Append(txt)
box.Append(btn)
box.Append(dismiss)
@@ -1319,8 +1319,6 @@ func activate(app *gtk.Application) {
exts = append(exts, new_attention)
}
err := sendMessage(client, current, message_type, t, "", "", exts)
if err != nil {
showErrorDialog(err, &window.Window)
+1 -1
View File
@@ -1,3 +1,3 @@
package main
var lambda_version string = "3"
var lambda_version string = "4"
+1 -2
View File
@@ -1,9 +1,9 @@
package main
import (
"fmt"
"gosrc.io/xmpp"
"gosrc.io/xmpp/stanza"
"fmt"
)
// This file has small functions that can be used to do XMPP stuff without writing tons of boilerplate
@@ -140,4 +140,3 @@ func sendVoiceRequest(c xmpp.Sender, sendTo string) error {
}
return nil
}