Fix lag issues

This commit is contained in:
2026-04-30 14:55:17 +01:00
parent 7b63799f0b
commit 0bfb140dc7
5 changed files with 223 additions and 70 deletions
+4
View File
@@ -137,6 +137,9 @@ var mucTemporaryBytes []byte
//go:embed assets/moderate.png
var moderateBytes []byte
//go:embed assets/jabber.png
var jabberBytes []byte
func loadAsset(key string, data []byte) {
loader := gdkpixbuf.NewPixbufLoader()
loader.Write(data)
@@ -189,6 +192,7 @@ func init() {
"muc_persistent": mucPersistentBytes,
"muc_temporary": mucTemporaryBytes,
"moderate": moderateBytes,
"jabber": jabberBytes,
} {
loadAsset(key, data)
}
+73 -2
View File
@@ -73,9 +73,13 @@ func switchToTab(jid string, w *gtk.Window) {
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)
u := v.(stanza.Presence)
var mu MucUser
var ocu OccupantID
u.Get(&mu)
@@ -103,7 +107,7 @@ func switchToTab(jid string, w *gtk.Window) {
userbox.Append(nick_label)
var hats Hats
ok := u.Get(&hats)
ok = u.Get(&hats)
if ok {
for _, hat := range hats.Hats {
var val float64
@@ -531,3 +535,70 @@ func createIdenticon(word string) *gtk.Image { // This function generates an ide
return i
}
func jidBuilder(en *gtk.Entry) { // This function spawns a window that allows the user to interactively build a JID
// TODO: Localise this
win := gtk.NewWindow()
win.SetTitle("Build-A-JID")
win.SetDefaultSize(400, 1)
win.SetResizable(false)
box := gtk.NewBox(gtk.OrientationVertical, 2)
header := gtk.NewLabel("Build-A-JID")
header.AddCSSClass("author")
box.Append(header)
box.Append(gtk.NewLabel("All fields except for domain are optional"))
jid_builder := gtk.NewBox(gtk.OrientationHorizontal, 2)
localPartEntry := gtk.NewEntry()
localPartEntry.SetPlaceholderText("localpart")
jid_builder.Append(localPartEntry)
at_sign := gtk.NewLabel("@")
at_sign.AddCSSClass("author")
jid_builder.Append(at_sign)
domainEntry := gtk.NewEntry()
domainEntry.SetPlaceholderText("domain")
jid_builder.Append(domainEntry)
resource_sign := gtk.NewLabel("/")
resource_sign.AddCSSClass("author")
jid_builder.Append(resource_sign)
resourceEntry := gtk.NewEntry()
resourceEntry.SetPlaceholderText("resource")
jid_builder.Append(resourceEntry)
box.Append(jid_builder)
submit := gtk.NewButtonWithLabel(loadedLocale["submit"])
submit.ConnectClicked(func() {
localPart := localPartEntry.Text()
domain := domainEntry.Text()
resource := resourceEntry.Text()
at := "@"
slash := "/"
if localPart == "" {
at = ""
}
if resource == "" {
slash = ""
}
jid := localPart + at + domain + slash + resource
en.SetText(jid)
win.SetVisible(false)
})
box.Append(submit)
win.SetChild(box)
win.SetVisible(true)
}
+18 -13
View File
@@ -7,6 +7,7 @@ import (
"encoding/base64"
"fmt"
"github.com/diamondburned/gotk4/pkg/gdk/v4"
"github.com/diamondburned/gotk4/pkg/glib/v2"
"github.com/diamondburned/gotk4/pkg/gtk/v4"
"github.com/google/uuid"
"github.com/jacoblockett/sanitizefilename"
@@ -155,35 +156,39 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
// authorBox.Append(im)
n := jid.MustParse(m.From).Resourcepart()
n := JidMustParse(m.From).Resource
if n == "" {
n = jid.MustParse(m.From).String()
n = JidMustParse(m.From).Resource
}
al := gtk.NewLabel(n)
al.AddCSSClass("author")
al.SetSelectable(true)
if m.Type == stanza.MessageTypeGroupchat {
mo, _ := mucmembers.Load(jid.MustParse(m.From).Bare().String())
mo, _ := mucmembers.Load(JidMustParse(m.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)
im := createIdenticon(m.From)
im.SetPixelSize(40)
im.AddCSSClass("author_img")
authorBox.Append(im)
if vu.Photo != "" {
im := getAvatar(m.From, vu.Photo)
im.SetPixelSize(40)
im.AddCSSClass("author_img")
authorBox.Append(im)
} else {
im := createIdenticon(m.From)
im.SetPixelSize(40)
im.AddCSSClass("author_img")
authorBox.Append(im)
go func() {
new_im := getAvatar(m.From, vu.Photo)
glib.IdleAdd(func() {
new_im.SetPixelSize(40)
new_im.AddCSSClass("author_img")
authorBox.Remove(im)
authorBox.Prepend(new_im)
})
}()
}
} else {
im := createIdenticon(m.From)
im.SetPixelSize(40)
+83 -53
View File
@@ -219,7 +219,9 @@ func main() {
*/
originator := JidMustParse(m.From).Bare()
mStatus.SetText(originator)
glib.IdleAdd(func() {
mStatus.SetText(originator)
})
at := new(Attention)
ok = m.Get(at)
@@ -280,7 +282,6 @@ func main() {
}
glib.IdleAdd(func() {
//uiQueue <- func() {
b := gtk.NewBox(gtk.OrientationVertical, 0)
tab, ok := tabs.Load(originator)
@@ -303,7 +304,6 @@ func main() {
if ok {
b.Append(ba)
}
//}
})
})
@@ -464,11 +464,13 @@ func main() {
return
}
_ = <-mychan
pingStatus.RemoveCSSClass("pending")
delay := time.Since(before) / time.Millisecond
pingStatus.SetText(fmt.Sprintf("%d %s", delay, loadedLocale["milliseconds"]))
pingTimes[0] = append(pingTimes[0], float64(delay))
glib.IdleAdd(func() {
pingStatus.RemoveCSSClass("pending")
pingStatus.SetText(fmt.Sprintf("%d %s", delay, loadedLocale["milliseconds"]))
})
}()
}
@@ -480,28 +482,30 @@ func main() {
go func() {
for {
time.Sleep(1 * time.Second)
stat, err := xmlLog.Stat()
if err != nil {
panic(err)
}
glib.IdleAdd(func() {
stat, err := xmlLog.Stat()
if err != nil {
panic(err)
}
newsize = stat.Size()
diff := float64(newsize-oldsize) / 1000
newsize = stat.Size()
diff := float64(newsize-oldsize) / 1000
if diff > 100 {
sIcon.SetFromPaintable(clientAssets["car_high"])
} else {
sIcon.SetFromPaintable(clientAssets["car"])
}
sStatus.SetText(fmt.Sprintf("%.2f%s", diff, loadedLocale["KBPerSecond"]))
oldsize = stat.Size()
ic := clientAssets["car"]
if diff >= 25 {
ic = clientAssets["car_high"]
}
sStatus.SetText(fmt.Sprintf("%.2f%s", diff, loadedLocale["KBPerSecond"]))
sIcon.SetFromPaintable(ic)
})
}
}()
connectionStatus.SetText(fmt.Sprintf("%s%s", loadedLocale["connectedAs"], JidMustParse(clientroot.Session.BindJid).Bare()))
connectionStatus.SetTooltipText(fmt.Sprintf("%s%s\n%s%t", loadedLocale["bindedJid"], clientroot.Session.BindJid, loadedLocale["usingTLS"], clientroot.Session.TlsEnabled))
connectionIcon.SetFromPaintable(clientAssets["connect"])
glib.IdleAdd(func() {
connectionStatus.SetText(fmt.Sprintf("%s%s", loadedLocale["connectedAs"], JidMustParse(clientroot.Session.BindJid).Bare()))
connectionStatus.SetTooltipText(fmt.Sprintf("%s%s\n%s%t", loadedLocale["bindedJid"], clientroot.Session.BindJid, loadedLocale["usingTLS"], clientroot.Session.TlsEnabled))
connectionIcon.SetFromPaintable(clientAssets["connect"])
})
// Enable carbons
client.SendRaw(fmt.Sprintf(
`<iq xmlns='jabber:client'
@@ -526,6 +530,8 @@ func main() {
node := item.Any
autojoin := false
name := ""
password := ""
nick := loadedConfig.Nick
for _, attr := range node.Attrs {
if attr.Name.Local == "autojoin" {
autojoin = attr.Value == "true"
@@ -540,27 +546,6 @@ func main() {
}
}
_, ok := tabs.Load(jid)
if !ok && autojoin {
createTab(jid, true, name)
b := gtk.NewLabel(jid)
gesture1 := gtk.NewGestureClick()
gesture1.SetButton(1)
gesture1.Connect("pressed", func() {
switchToTab(jid, &window.Window)
})
b.AddController(gesture1)
menu.Append(b)
}
}
for _, item := range res.Items.List {
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"
@@ -575,22 +560,40 @@ func main() {
}
}
if autojoin {
err := joinMuc(client, clientroot.Session.BindJid, jid, nick, "")
if err != nil {
panic(err)
for _, node := range node.Nodes {
if node.XMLName.Local == "password" {
password = node.Content
break
}
}
_, ok := tabs.Load(jid)
if !ok && autojoin {
joinMuc(client, clientroot.Session.BindJid, jid, nick, password)
createTab(jid, true, name)
glib.IdleAdd(func() {
b := gtk.NewLabel(jid)
gesture1 := gtk.NewGestureClick()
gesture1.SetButton(1)
gesture1.Connect("pressed", func() {
switchToTab(jid, &window.Window)
})
b.AddController(gesture1)
menu.Append(b)
})
}
}
}
}
}
}
})
conc := func() {
time.Sleep(3 * time.Second)
// time.Sleep(3 * time.Second)
connectionStatus.SetText(loadedLocale["connecting"])
connectionIcon.SetFromPaintable(clientAssets["hourglass"])
@@ -604,8 +607,8 @@ func main() {
app := gtk.NewApplication("net.sunglocto.lambda", gio.ApplicationFlagsNone)
app.ConnectActivate(func() {
go conc()
activate(app)
go conc()
})
if code := app.Run(os.Args); code > 0 {
@@ -633,8 +636,26 @@ func activate(app *gtk.Application) {
aboutAction := gio.NewSimpleAction("about", nil)
aboutAction.ConnectActivate(func(p *glib.Variant) {
a := gtk.AboutDialog{}
a.SetVisible(true)
a := gtk.NewAboutDialog()
about_window := gtk.NewWindow()
about_window.SetTransientFor(&window.Window)
about_window.SetTitle(fmt.Sprintf("%s %s", "About", loadedLocale["appName"]))
a.SetProgramName("Lambda")
a.SetVersion(lambda_version)
a.SetComments("yet another XMPP client")
a.SetAuthors([]string{"Sunglocto"})
a.SetLicense("GPL3")
a.SetWebsite("https://forge.sunglocto.net/sunglocto/lambda")
a.SetWebsiteLabel("Website")
/*
a.ConnectResponse(func() {
about_window.SetVisible(false)
})
*/
about_window.SetChild(a)
about_window.SetDefaultSize(400, 300)
about_window.SetVisible(true)
})
destroymucAction := gio.NewSimpleAction("destroymuc", nil)
@@ -743,7 +764,16 @@ func activate(app *gtk.Application) {
nick_entry.SetText(loadedConfig.Nick)
create_jid := gtk.NewImageFromPaintable(clientAssets["jabber"])
gesture := gtk.NewGestureClick()
gesture.SetButton(1)
gesture.Connect("pressed", func() {
jidBuilder(jid_entry)
})
create_jid.AddController(gesture)
jid_box.Append(gtk.NewLabel(loadedLocale["joinMUCJIDEntry"]))
jid_box.Append(create_jid)
jid_box.Append(jid_entry)
nick_box.Append(gtk.NewLabel(loadedLocale["joinMUCNickEntry"]))
@@ -946,7 +976,7 @@ func activate(app *gtk.Application) {
app.AddAction(aboutAction)
app.AddAction(destroymucAction)
the_menu.AppendSubmenu("File", fileMenu)
the_menu.AppendSubmenu("MUC", fileMenu)
the_menu.AppendSubmenu("Help", helpMenu)
the_menuBar := gtk.NewPopoverMenuBarFromModel(the_menu)
+45 -2
View File
@@ -1,7 +1,6 @@
package main
import (
"fmt"
"gosrc.io/xmpp"
"gosrc.io/xmpp/stanza"
)
@@ -31,7 +30,6 @@ func sendMessage(c xmpp.Sender, sendTo string, msgType stanza.StanzaType, body s
func joinMuc(c xmpp.Sender, jid string, muc string, nick string, password string) error {
var joinPresence stanza.Presence
addr := muc + "/" + nick
fmt.Println(addr)
if password == "" {
joinPresence = stanza.Presence{
Attrs: stanza.Attrs{
@@ -63,6 +61,51 @@ func joinMuc(c xmpp.Sender, jid string, muc string, nick string, password string
return nil
}
func joinMucWithoutHistory(c xmpp.Sender, jid string, muc string, nick string, password string) error {
var joinPresence stanza.Presence
addr := muc + "/" + nick
if password == "" {
joinPresence = stanza.Presence{
Attrs: stanza.Attrs{
From: jid,
To: addr,
},
Extensions: []stanza.PresExtension{
&stanza.MucPresence{
History: stanza.History{
MaxChars: stanza.NewNullableInt(0),
MaxStanzas: stanza.NewNullableInt(0),
Seconds: stanza.NewNullableInt(0),
},
},
},
}
} else {
joinPresence = stanza.Presence{
Attrs: stanza.Attrs{
From: jid,
To: addr,
},
Extensions: []stanza.PresExtension{
&stanza.MucPresence{
Password: password,
History: stanza.History{
MaxChars: stanza.NewNullableInt(0),
MaxStanzas: stanza.NewNullableInt(0),
Seconds: stanza.NewNullableInt(0),
},
},
},
}
}
err := client.Send(joinPresence)
if err != nil {
return err
}
return nil
}
// jid MustParse but using gosrc's instead of mellium
// This function will panic if its an invalid JID