From 39156af48a0deb2c395de2a0e71da293d54ff1ec Mon Sep 17 00:00:00 2001 From: sunglocto Date: Thu, 19 Feb 2026 11:28:18 +0000 Subject: [PATCH] format code, add confirmation to destroy muc, implement some disconnect logic --- gtk-signin.go | 1 + main.go | 178 +++++++++++++++++++++++++++++++++++--------------- style.css | 5 ++ types.go | 11 ++-- 4 files changed, 136 insertions(+), 59 deletions(-) diff --git a/gtk-signin.go b/gtk-signin.go index 4d278b8..aaa5009 100644 --- a/gtk-signin.go +++ b/gtk-signin.go @@ -80,6 +80,7 @@ func dropToSignInPage(err error) { conf.Password = password_entry.Text() conf.Nick = nickname_entry.Text() conf.Insecure = insecure_check.Active() + conf.JoinBookmarks = true var b bytes.Buffer e := toml.NewEncoder(&b) diff --git a/main.go b/main.go index 848886d..e6f5f2c 100644 --- a/main.go +++ b/main.go @@ -298,10 +298,11 @@ func main() { TransportConfiguration: xmpp.TransportConfiguration{ Address: loadedConfig.Server, }, - Jid: loadedConfig.Username + "/lambda." + str, - Credential: xmpp.Password(loadedConfig.Password), - Insecure: loadedConfig.Insecure, - StreamLogger: os.Stdout, + Jid: loadedConfig.Username + "/lambda." + str, + Credential: xmpp.Password(loadedConfig.Password), + Insecure: loadedConfig.Insecure, + StreamLogger: os.Stdout, + StreamManagementEnable: true, } router := xmpp.NewRouter() @@ -525,9 +526,9 @@ func main() { }) c, err := xmpp.NewClient(&config, router, func(err error) { - showErrorDialog(err) - panic(err) + connectionStatus.SetText(fmt.Sprintf("Disconnected: %s", err.Error())) }) + if err != nil { showErrorDialog(err) panic(err) @@ -540,66 +541,70 @@ func main() { go func() { for { time.Sleep(5 * time.Second) + pingStatus.AddCSSClass("pending") before := time.Now() iq := new(stanza.IQ) iq.From = clientroot.Session.BindJid iq.To = iq.From iq.Type = "get" - ctx, _ := context.WithTimeout(context.Background(), 30 * time.Second) + ctx, _ := context.WithTimeout(context.Background(), 30*time.Second) mychan, err := client.SendIQ(ctx, iq) if err != nil { - panic(err) + continue } - _ = <- mychan + _ = <-mychan - pingStatus.SetText(fmt.Sprintf("%d ms", time.Since(before) / time.Millisecond)) + pingStatus.RemoveCSSClass("pending") + pingStatus.SetText(fmt.Sprintf("%d ms", time.Since(before)/time.Millisecond)) } }() connectionStatus.SetText(fmt.Sprintf("Connected as %s", JidMustParse(clientroot.Session.BindJid).Bare())) // Join rooms in bookmarks - books, err := stanza.NewItemsRequest("", "urn:xmpp:bookmarks:1", 0) - if err == nil { - mychan, err := c.SendIQ(context.TODO(), books) - result := <-mychan + if loadedConfig.JoinBookmarks { + books, err := stanza.NewItemsRequest("", "urn:xmpp:bookmarks:1", 0) if err == nil { - res, ok := result.Payload.(*stanza.PubSubGeneric) - if ok { - for _, item := range res.Items.List { - go func() { - jid := item.Id - node := item.Any - autojoin := false - nick := loadedConfig.Nick - for _, attr := range node.Attrs { - if attr.Name.Local == "autojoin" { - autojoin = attr.Value == "true" - } - } - - for _, node := range node.Nodes { - if node.XMLName.Local == "nick" { - nick = node.Content - } - } - - _, ok := tabs.Load(jid) - if !ok && autojoin { - err := joinMuc(client, clientroot.Session.BindJid, jid, nick) - if err != nil { - panic(err) + mychan, err := c.SendIQ(context.TODO(), books) + result := <-mychan + if err == nil { + res, ok := result.Payload.(*stanza.PubSubGeneric) + if ok { + for _, item := range res.Items.List { + go func() { + jid := item.Id + node := item.Any + autojoin := false + nick := loadedConfig.Nick + for _, attr := range node.Attrs { + if attr.Name.Local == "autojoin" { + autojoin = attr.Value == "true" + } } - createTab(jid, true) - b := gtk.NewButtonWithLabel(jid) - b.ConnectClicked(func() { - b.AddCSSClass("accent") - switchToTab(jid, &window.Window) - }) - menu.Append(b) - } - }() + for _, node := range node.Nodes { + if node.XMLName.Local == "nick" { + nick = node.Content + } + } + + _, ok := tabs.Load(jid) + if !ok && autojoin { + err := joinMuc(client, clientroot.Session.BindJid, jid, nick) + if err != nil { + panic(err) + } + + createTab(jid, true) + b := gtk.NewButtonWithLabel(jid) + b.ConnectClicked(func() { + b.AddCSSClass("accent") + switchToTab(jid, &window.Window) + }) + menu.Append(b) + } + }() + } } } } @@ -611,8 +616,8 @@ func main() { connectionStatus.SetText("Connecting...") err = cm.Run() if err != nil { - showErrorDialog(err) - panic(err) + fmt.Println(err.Error()) + connectionStatus.SetText(fmt.Sprintf("Disconnected: %s", err.Error())) } }() @@ -654,7 +659,30 @@ func activate(app *gtk.Application) { if ok { cur := cur.(*chatTab) if cur.isMuc { - client.SendRaw(fmt.Sprintf(` + win := gtk.NewWindow() + win.SetTitle("Destroy MUC") + win.SetDefaultSize(400, 1) + win.SetResizable(false) + + box := gtk.NewBox(gtk.OrientationVertical, 0) + box.Append(gtk.NewLabel("Are you sure? This MUC will be gone forever! (a very long time)")) + box.Append(gtk.NewLabel("If you wish to continue, type 'I understand'")) + cancel := gtk.NewButtonWithLabel("Cancel") + cancel.ConnectClicked(func() { + win.SetVisible(false) + }) + en := gtk.NewEntry() + en.SetPlaceholderText("...") + + submit := gtk.NewButtonWithLabel("Destroy") + submit.ConnectClicked(func() { + fmt.Println(en.Text()) + if en.Text() == "I understand" { + cur, ok := tabs.Load(current) + if ok { + cur := cur.(*chatTab) + if cur.isMuc { + client.SendRaw(fmt.Sprintf(` `, clientroot.Session.BindJid, current, JidMustParse(clientroot.Session.BindJid).Bare())) + } + } + win.SetVisible(false) + } + }) + + box.Append(en) + box.Append(submit) + box.Append(cancel) + + mu, ok := mucmembers.Load(current) + if ok { + typed_mu := mu.(mucUnit) + typed_mu.Members.Range(func(k, v any) bool { + user, ok := v.(stanza.Presence) + if ok { + mu := MucUser{} + ok := user.Get(&mu) + if ok { + if mu.MucUserItem.JID != "" { + if JidMustParse(mu.MucUserItem.JID).Bare() == JidMustParse(clientroot.Session.BindJid).Bare() { + if mu.MucUserItem.Affiliation != "owner" { + box.Append(gtk.NewLabel("You are not an owner of this MUC and thus will most likely not be able to delete it")) + } + // return false + } + } + } else { + panic("not ok") + } + } else { + panic("not ok") + } + return true + }) + } else { + panic("not ok") + } + + win.SetChild(box) + win.SetVisible(true) } } + }) joinAction := gio.NewSimpleAction("join", nil) @@ -704,6 +774,7 @@ func activate(app *gtk.Application) { win := gtk.NewWindow() win.SetTitle("Join MUC") win.SetDefaultSize(400, 1) + win.SetResizable(false) win.SetChild(box) btn.ConnectClicked(func() { @@ -762,17 +833,16 @@ func activate(app *gtk.Application) { cBox := gtk.NewBox(gtk.OrientationHorizontal, 0) cBox.Append(gtk.NewImageFromPaintable(clientAssets["disconnect"])) - connectionStatus = gtk.NewLabel("Disconnected") + connectionStatus = gtk.NewLabel("Disconnected") cBox.Append(connectionStatus) statBar.Append(cBox) - pBox := gtk.NewBox(gtk.OrientationHorizontal, 0) pBox.SetTooltipText("Ping between you and your XMPP server") i := (gtk.NewImageFromPaintable(clientAssets["chart_bar"])) i.AddCSSClass("icon") pBox.Append(i) - pingStatus = gtk.NewLabel("...") + pingStatus = gtk.NewLabel("...") pBox.Append(pingStatus) statBar.Append(pBox) diff --git a/style.css b/style.css index ef2cdd7..4b72d84 100644 --- a/style.css +++ b/style.css @@ -34,6 +34,11 @@ color: grey; } +.pending { + color: grey; + transition-duration: 0.5s; +} + .hat { background-color: orange; color: black; diff --git a/types.go b/types.go index 9a2797b..e6fa0cd 100644 --- a/types.go +++ b/types.go @@ -11,11 +11,12 @@ type chatTab struct { } type lambdaConfig struct { - Server string - Username string - Password string - Insecure bool - Nick string + Server string + Username string + Password string + Insecure bool + Nick string + JoinBookmarks bool } type mucUnit struct {