diff --git a/assets.go b/assets.go
index bcb8214..918bee5 100644
--- a/assets.go
+++ b/assets.go
@@ -226,7 +226,7 @@ func init() {
"fail": failBytes,
"please_wait": pleaseWaitBytes,
"update": updateBytes,
- "solar": solarBytes,
+ "solar": solarBytes,
} {
loadAsset(key, data)
}
diff --git a/go-xmpp b/go-xmpp
new file mode 160000
index 0000000..bc2b7ce
--- /dev/null
+++ b/go-xmpp
@@ -0,0 +1 @@
+Subproject commit bc2b7ceee4b4d4c9ba5ec2451afdd43462f0b188
diff --git a/go.mod b/go.mod
index 822a4a0..150f5fb 100644
--- a/go.mod
+++ b/go.mod
@@ -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/
diff --git a/gtk-helpers.go b/gtk-helpers.go
index 3518b96..f663fe2 100644
--- a/gtk-helpers.go
+++ b/gtk-helpers.go
@@ -23,6 +23,201 @@ import (
func init() {
}
+func showUserWindow(u stanza.Presence, custom_nick string) {
+ var ocu OccupantID
+ u.Get(&ocu)
+
+ var id string
+ id = JidMustParse(u.From).Resource
+
+ 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)
+ }
+
+ ver_text := gtk.NewLabel(loadedLocale["gettingVersion"])
+ ver_text.AddCSSClass("visitor")
+
+ win.SetTitle(JidMustParse(u.From).Resource)
+ nick.AddCSSClass("author")
+ nick.SetSelectable(true)
+ profile_box.Append(nick)
+ if u.Status != "" {
+ status_message := gtk.NewLabel(u.Status)
+ status_message.AddCSSClass("status")
+ profile_box.Append(status_message)
+ }
+ profile_box.Append(ver_text)
+ fr := gtk.NewLabel(u.From)
+ fr.AddCSSClass("jid")
+ fr.SetSelectable(true)
+ profile_box.Append(fr)
+ profile_box.Append(ver_text)
+
+ 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 {
+ l := gtk.NewLabel(hat.Title)
+ l.AddCSSClass("hat")
+ profile_box.Append(l)
+ }
+ }
+
+ var mu MucUser
+ ok = u.Get(&mu)
+ if ok {
+ if mu.MucUserItem.JID != "" {
+ ji := (gtk.NewLabel(mu.MucUserItem.JID))
+ ji.AddCSSClass("jid")
+ ji.SetSelectable(true)
+ profile_box.Append(ji)
+ }
+ profile_box.Append(gtk.NewLabel(loadedLocale["connectedWithRole"] + mu.MucUserItem.Role))
+ var affil string
+ if mu.MucUserItem.Affiliation == "none" {
+ affil = loadedLocale["unaffiliated"]
+ } else {
+ affil = loadedLocale["affiliatedAs"] + mu.MucUserItem.Affiliation
+ }
+ profile_box.Append(gtk.NewLabel(affil))
+ }
+
+ if ocu.ID != "" {
+ ocu_label := gtk.NewLabel(ocu.ID)
+ ocu_label.AddCSSClass("jid")
+ ocu_label.SetSelectable(true)
+ profile_box.Append(ocu_label)
+ }
+
+ go func() {
+
+ myIQ, err := stanza.NewIQ(stanza.Attrs{
+ Type: "get",
+ From: clientroot.Session.BindJid,
+ To: u.From,
+ Id: "dicks",
+ Lang: "en",
+ })
+
+ if err != nil {
+ panic(err)
+ }
+
+ myIQ.Payload = &stanza.DiscoInfo{}
+
+ ctx := context.TODO()
+ mychan, err := client.SendIQ(ctx, myIQ)
+ if err == nil {
+ result := <-mychan
+ res, ok := result.Payload.(*stanza.DiscoInfo)
+ if ok {
+ idents := res.Identity
+ for i, ident := range idents {
+ profile_box.Append(gtk.NewLabel(fmt.Sprintf("%d: Name: %s, Category: %s, Type: %s", i+1, ident.Name, ident.Category, ident.Type)))
+ }
+
+ /*
+ s := fmt.Sprintf("%v", res.Features)
+ h := sha1.New()
+ h.Write([]byte(s))
+ sha1_hash := hex.EncodeToString(h.Sum(nil))
+ */
+
+ sw := gtk.NewScrolledWindow()
+ s := ""
+ for _, feature := range res.Features {
+ s = s + feature.Var + "\n"
+ }
+ sw.SetChild(gtk.NewLabel(s))
+
+ profile_box.Append(sw)
+ }
+ }
+ }()
+
+ 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
+
+ vr := fmt.Sprintf("%s %s %s", name, version, os)
+ if name == "" && version == "" && os == "" {
+ ver_text.SetText(loadedLocale["versionQueryEmpty"])
+ } else {
+ ver_text.SetText(vr)
+ ver_text.RemoveCSSClass("visitor")
+ }
+ } else if result.Error != nil && result.Error.Type != "" {
+ ver_text.SetText(loadedLocale["versionQueryError"])
+ ver_text.SetTooltipText(result.Error.Reason + ": " + result.Error.Text)
+ ver_text.RemoveCSSClass("visitor")
+ ver_text.AddCSSClass("error")
+ }
+ }
+ }()
+
+ go func() {
+ mo, _ := mucmembers.Load(JidMustParse(u.From).Bare())
+ mm := mo.(mucUnit)
+ mmm := mm.Members
+ mmmm, ok := mmm.Load(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.Prepend(im)
+ } else {
+ im := createIdenticon(u.From, false)
+ im.SetPixelSize(80)
+ im.AddCSSClass("author_img")
+ profile_box.Prepend(im)
+ }
+ } else {
+ im := createIdenticon(u.From, false)
+ im.SetPixelSize(80)
+ im.AddCSSClass("author_img")
+ profile_box.Prepend(im)
+ }
+ }()
+
+ win.SetChild(profile_box)
+ win.SetTransientFor(win)
+ win.Present()
+}
+
func scrollToBottomAfterUpdate(scrolledWindow *gtk.ScrolledWindow) {
glib.IdleAdd(func() bool {
vAdj := scrolledWindow.VAdjustment()
@@ -147,10 +342,9 @@ func switchToTab(jid string, w *gtk.Window) {
//id := ocu.ID
//if id == "" {
- id := JidMustParse(u.From).Resource
+ // id := JidMustParse(u.From).Resource
//}
-
nick_label := gtk.NewLabel(JidMustParse(u.From).Resource)
var custom_nick string
@@ -166,15 +360,13 @@ func switchToTab(jid string, w *gtk.Window) {
ocu_nick, ok := loadedConfig.CustomNicks[ocu.ID]
if ok {
- custom_nick = ocu_nick
+ 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" {
@@ -332,7 +524,7 @@ func switchToTab(jid string, w *gtk.Window) {
`, clientroot.Session.BindJid, jid, the_entry.Text(), JidMustParse(mu.MucUserItem.JID).Bare()))
- win.SetVisible(false)
+ win.Destroy()
})
box.Append(the_entry)
@@ -399,191 +591,7 @@ func switchToTab(jid string, w *gtk.Window) {
})
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)
- }
-
- ver_text := gtk.NewLabel(loadedLocale["gettingVersion"])
- ver_text.AddCSSClass("visitor")
-
- win.SetTitle(JidMustParse(u.From).Resource)
- nick.AddCSSClass("author")
- nick.SetSelectable(true)
- profile_box.Append(nick)
- if u.Status != "" {
- status_message := gtk.NewLabel(u.Status)
- status_message.AddCSSClass("status")
- profile_box.Append(status_message)
- }
- profile_box.Append(ver_text)
- fr := gtk.NewLabel(u.From)
- fr.AddCSSClass("jid")
- fr.SetSelectable(true)
- profile_box.Append(fr)
- profile_box.Append(ver_text)
-
- 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 {
- l := gtk.NewLabel(hat.Title)
- l.AddCSSClass("hat")
- profile_box.Append(l)
- }
- }
-
- var mu MucUser
- ok = u.Get(&mu)
- if ok {
- if mu.MucUserItem.JID != "" {
- ji := (gtk.NewLabel(mu.MucUserItem.JID))
- ji.AddCSSClass("jid")
- ji.SetSelectable(true)
- profile_box.Append(ji)
- }
- profile_box.Append(gtk.NewLabel(loadedLocale["connectedWithRole"] + mu.MucUserItem.Role))
- var affil string
- if mu.MucUserItem.Affiliation == "none" {
- affil = loadedLocale["unaffiliated"]
- } else {
- affil = loadedLocale["affiliatedAs"] + mu.MucUserItem.Affiliation
- }
- profile_box.Append(gtk.NewLabel(affil))
- }
-
- if ocu.ID != "" {
- ocu_label := gtk.NewLabel(ocu.ID)
- ocu_label.AddCSSClass("jid")
- ocu_label.SetSelectable(true)
- profile_box.Append(ocu_label)
- }
-
- go func() {
-
- myIQ, err := stanza.NewIQ(stanza.Attrs{
- Type: "get",
- From: clientroot.Session.BindJid,
- To: u.From,
- Id: "dicks",
- Lang: "en",
- })
-
- if err != nil {
- panic(err)
- }
-
- myIQ.Payload = &stanza.DiscoInfo{}
-
- ctx := context.TODO()
- mychan, err := client.SendIQ(ctx, myIQ)
- if err == nil {
- result := <-mychan
- res, ok := result.Payload.(*stanza.DiscoInfo)
- if ok {
- idents := res.Identity
- for i, ident := range idents {
- profile_box.Append(gtk.NewLabel(fmt.Sprintf("%d: Name: %s, Category: %s, Type: %s", i+1, ident.Name, ident.Category, ident.Type)))
- }
-
- /*
- s := fmt.Sprintf("%v", res.Features)
- h := sha1.New()
- h.Write([]byte(s))
- sha1_hash := hex.EncodeToString(h.Sum(nil))
- */
-
- sw := gtk.NewScrolledWindow()
- s := ""
- for _, feature := range res.Features {
- s = s + feature.Var + "\n"
- }
- sw.SetChild(gtk.NewLabel(s))
-
- profile_box.Append(sw)
- }
- }
- }()
-
- 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
-
- vr := fmt.Sprintf("%s %s %s", name, version, os)
- if name == "" && version == "" && os == "" {
- ver_text.SetText(loadedLocale["versionQueryEmpty"])
- } else {
- ver_text.SetText(vr)
- ver_text.RemoveCSSClass("visitor")
- }
- } else if result.Error != nil && result.Error.Type != "" {
- ver_text.SetText(loadedLocale["versionQueryError"])
- ver_text.SetTooltipText(result.Error.Reason + ": " + result.Error.Text)
- ver_text.RemoveCSSClass("visitor")
- ver_text.AddCSSClass("error")
- }
- }
- }()
-
- go func() {
- mo, _ := mucmembers.Load(JidMustParse(u.From).Bare())
- mm := mo.(mucUnit)
- mmm := mm.Members
- mmmm, ok := mmm.Load(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.Prepend(im)
- } else {
- im := createIdenticon(u.From, false)
- im.SetPixelSize(80)
- im.AddCSSClass("author_img")
- profile_box.Prepend(im)
- }
- } else {
- im := createIdenticon(u.From, false)
- im.SetPixelSize(80)
- im.AddCSSClass("author_img")
- profile_box.Prepend(im)
- }
- }()
-
- win.SetChild(profile_box)
- win.SetTransientFor(win)
- win.Present()
+ 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)
diff --git a/gtk-message.go b/gtk-message.go
index 9e82b85..ca51807 100644
--- a/gtk-message.go
+++ b/gtk-message.go
@@ -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("%s", hexcolor, id))
+ al.SetMarkup(fmt.Sprintf("%s", hexcolor, name))
al.SetSelectable(true)
al.SetVAlign(gtk.AlignStart)
mainBox.Append(al)
diff --git a/main.go b/main.go
index 49d1f6e..5a4a530 100644
--- a/main.go
+++ b/main.go
@@ -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"
@@ -139,7 +139,7 @@ func main() {
return charset.NewReaderLabel(c, input)
},
ConnectTimeout: 300,
- TLSConfig: &tls.Config{InsecureSkipVerify: loadedConfig.Insecure},
+ TLSConfig: &tls.Config{InsecureSkipVerify: loadedConfig.Insecure},
},
Jid: loadedConfig.Username + "/" + loadedConfig.Resource,
Credential: xmpp.Password(loadedConfig.Password),
@@ -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)
diff --git a/types.go b/types.go
index 22049de..135f18d 100644
--- a/types.go
+++ b/types.go
@@ -30,7 +30,7 @@ type lambdaConfig struct {
CompactMode bool
ShowAvatarsInMemberList bool
CustomNicks map[string]string // Anyone with a specific Occupant ID will have this nick
- CustomNicksAV map[string]string // Anyone with a specific avatar hash will have this nick
+ CustomNicksAV map[string]string // Anyone with a specific avatar hash will have this nick
CheckUpdate string
}
diff --git a/version.go b/version.go
index c2226d9..ffb439b 100644
--- a/version.go
+++ b/version.go
@@ -1,3 +1,3 @@
package main
-var lambda_version string = "3"
+var lambda_version string = "4"
diff --git a/xmpp-helpers.go b/xmpp-helpers.go
index a6db8c6..375a267 100644
--- a/xmpp-helpers.go
+++ b/xmpp-helpers.go
@@ -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
}
-