lambda is free of this insane bug
This commit is contained in:
Submodule
+1
Submodule go-xmpp added at bc2b7ceee4
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -1263,11 +1264,11 @@ func activate(app *gtk.Application) {
|
||||
if JidMustParse(mui.MucUserItem.JID).Bare() == JidMustParse(clientroot.Session.BindJid).Bare() {
|
||||
if mui.MucUserItem.Role == "visitor" {
|
||||
win := gtk.NewWindow()
|
||||
win.SetDefaultSize(1,1)
|
||||
win.SetDefaultSize(1, 1)
|
||||
box := gtk.NewBox(gtk.OrientationVertical, 5)
|
||||
txt := gtk.NewLabel("You are a visitor and do not have voice.\nWould you like to request voice from the moderators of this MUC?")
|
||||
btn := gtk.NewButtonWithLabel("Request voice")
|
||||
btn.ConnectClicked(func (){
|
||||
btn.ConnectClicked(func() {
|
||||
sendVoiceRequest(client, current)
|
||||
win.SetVisible(false)
|
||||
})
|
||||
@@ -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
@@ -1,3 +1,3 @@
|
||||
package main
|
||||
|
||||
var lambda_version string = "3"
|
||||
var lambda_version string = "4"
|
||||
|
||||
+1
-2
@@ -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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user