add throughput, format code, and begin to add MUC preview window
@@ -115,6 +115,10 @@ var commentB64 string = base64.StdEncoding.EncodeToString(commentBytes)
|
||||
var informationBytes []byte
|
||||
var informationB64 string = base64.StdEncoding.EncodeToString(informationBytes)
|
||||
|
||||
//go:embed assets/car.png
|
||||
var carBytes []byte
|
||||
var carB64 string = base64.StdEncoding.EncodeToString(carBytes)
|
||||
|
||||
func init() {
|
||||
|
||||
loader := gdkpixbuf.NewPixbufLoader()
|
||||
@@ -331,4 +335,12 @@ func init() {
|
||||
loader.Close()
|
||||
|
||||
clientAssets["status_"] = gdk.NewTextureForPixbuf(loader.Pixbuf())
|
||||
|
||||
loader = gdkpixbuf.NewPixbufLoader()
|
||||
|
||||
carData, _ := base64.StdEncoding.DecodeString(carB64)
|
||||
loader.Write(carData)
|
||||
loader.Close()
|
||||
|
||||
clientAssets["car"] = gdk.NewTextureForPixbuf(loader.Pixbuf())
|
||||
}
|
||||
|
||||
|
After Width: | Height: | Size: 671 B |
|
After Width: | Height: | Size: 593 B |
|
After Width: | Height: | Size: 935 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 970 B |
|
After Width: | Height: | Size: 508 B |
|
After Width: | Height: | Size: 612 B |
|
After Width: | Height: | Size: 806 B |
|
After Width: | Height: | Size: 622 B |
|
After Width: | Height: | Size: 924 B |
|
After Width: | Height: | Size: 882 B |
|
After Width: | Height: | Size: 1.0 KiB |
|
After Width: | Height: | Size: 903 B |
@@ -55,8 +55,8 @@ func switchToTab(jid string, w *gtk.Window) {
|
||||
}
|
||||
|
||||
typed_tab := tab.(*chatTab)
|
||||
|
||||
scroller.SetChild(typed_tab.msgs)
|
||||
typingStatus.SetText("")
|
||||
if typed_tab.isMuc {
|
||||
|
||||
m, ok := mucmembers.Load(jid)
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"sort"
|
||||
"sync"
|
||||
)
|
||||
|
||||
func rangeOrdered(m *sync.Map, fn func(k, v any) bool) {
|
||||
@@ -23,4 +23,3 @@ func rangeOrdered(m *sync.Map, fn func(k, v any) bool) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,9 @@ var connectionIcon *gtk.Image
|
||||
var mStatus *gtk.Label
|
||||
var mIcon *gtk.Image
|
||||
|
||||
var sStatus *gtk.Label
|
||||
var sIcon *gtk.Image
|
||||
|
||||
var typingStatus *gtk.Label
|
||||
|
||||
var pingStatus *gtk.Label
|
||||
@@ -91,6 +94,14 @@ func init() {
|
||||
}
|
||||
|
||||
func main() {
|
||||
// Setup log
|
||||
xmlLog, err := os.CreateTemp("", "xmpp-log")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
defer os.Remove(xmlLog.Name())
|
||||
|
||||
pingTimes = append(pingTimes, []float64{})
|
||||
p, err := ensureConfig()
|
||||
if err != nil {
|
||||
@@ -120,12 +131,14 @@ func main() {
|
||||
CharsetReader: func(c string, input io.Reader) (io.Reader, error) {
|
||||
return charset.NewReaderLabel(c, input)
|
||||
},
|
||||
ConnectTimeout: 300,
|
||||
},
|
||||
Jid: loadedConfig.Username + "/" + loadedConfig.Resource,
|
||||
Credential: xmpp.Password(loadedConfig.Password),
|
||||
Insecure: loadedConfig.Insecure,
|
||||
// StreamLogger: os.Stdout,
|
||||
StreamManagementEnable: true,
|
||||
ConnectTimeout: 300,
|
||||
StreamLogger: xmlLog,
|
||||
}
|
||||
router := xmpp.NewRouter()
|
||||
|
||||
@@ -276,7 +289,9 @@ func main() {
|
||||
|
||||
if ok {
|
||||
typed_tab.msgs.Append(b)
|
||||
if current == JidMustParse(m.From).Bare() {
|
||||
scrollToBottomAfterUpdate(scroller)
|
||||
}
|
||||
} else {
|
||||
fmt.Println("Got message when the tab does not exist!")
|
||||
}
|
||||
@@ -340,7 +355,9 @@ func main() {
|
||||
|
||||
if ok {
|
||||
typed_tab.msgs.Append(b)
|
||||
if current == muc {
|
||||
scrollToBottomAfterUpdate(scroller)
|
||||
}
|
||||
} else {
|
||||
fmt.Println("Got message when the tab does not exist!")
|
||||
}
|
||||
@@ -426,9 +443,11 @@ func main() {
|
||||
|
||||
cm := xmpp.NewStreamManager(c, func(c xmpp.Sender) {
|
||||
fmt.Println("XMPP client connected")
|
||||
// Ping
|
||||
go func() {
|
||||
for {
|
||||
time.Sleep(5 * time.Second)
|
||||
go func() {
|
||||
pingStatus.AddCSSClass("pending")
|
||||
before := time.Now()
|
||||
iq := new(stanza.IQ)
|
||||
@@ -439,7 +458,7 @@ func main() {
|
||||
ctx, _ := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
mychan, err := client.SendIQ(ctx, iq)
|
||||
if err != nil {
|
||||
continue
|
||||
return
|
||||
}
|
||||
_ = <-mychan
|
||||
|
||||
@@ -447,9 +466,28 @@ func main() {
|
||||
delay := time.Since(before) / time.Millisecond
|
||||
pingStatus.SetText(fmt.Sprintf("%d ms", delay))
|
||||
pingTimes[0] = append(pingTimes[0], float64(delay))
|
||||
}()
|
||||
|
||||
}
|
||||
}()
|
||||
|
||||
// Throughput
|
||||
var oldsize int64
|
||||
var newsize int64
|
||||
go func() {
|
||||
for {
|
||||
time.Sleep(1 * time.Second)
|
||||
stat, err := xmlLog.Stat()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
newsize = stat.Size()
|
||||
diff := float64(newsize-oldsize) / 1000
|
||||
sStatus.SetText(fmt.Sprintf("%.2fKB/s", diff))
|
||||
oldsize = stat.Size()
|
||||
}
|
||||
}()
|
||||
connectionStatus.SetText(fmt.Sprintf("Connected as %s", JidMustParse(clientroot.Session.BindJid).Bare()))
|
||||
connectionStatus.SetTooltipText(fmt.Sprintf("Binded JID: %s\nUsing TLS: %t", clientroot.Session.BindJid, clientroot.Session.TlsEnabled))
|
||||
connectionIcon.SetFromPaintable(clientAssets["connect"])
|
||||
@@ -473,7 +511,32 @@ func main() {
|
||||
res, ok := result.Payload.(*stanza.PubSubGeneric)
|
||||
if ok {
|
||||
for _, item := range res.Items.List {
|
||||
go func() {
|
||||
jid := item.Id
|
||||
node := item.Any
|
||||
autojoin := false
|
||||
for _, attr := range node.Attrs {
|
||||
if attr.Name.Local == "autojoin" {
|
||||
autojoin = attr.Value == "true"
|
||||
}
|
||||
}
|
||||
|
||||
_, ok := tabs.Load(jid)
|
||||
if !ok && autojoin {
|
||||
createTab(jid, true)
|
||||
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
|
||||
@@ -490,25 +553,13 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
_, ok := tabs.Load(jid)
|
||||
if !ok && autojoin {
|
||||
if autojoin {
|
||||
err := joinMuc(client, clientroot.Session.BindJid, jid, nick)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
createTab(jid, true)
|
||||
b := gtk.NewLabel(jid)
|
||||
gesture1 := gtk.NewGestureClick()
|
||||
gesture1.SetButton(1)
|
||||
gesture1.Connect("pressed", func() {
|
||||
switchToTab(jid, &window.Window)
|
||||
})
|
||||
|
||||
b.AddController(gesture1)
|
||||
menu.Append(b)
|
||||
}
|
||||
}()
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -907,6 +958,15 @@ func activate(app *gtk.Application) {
|
||||
pBox.Append(pingStatus)
|
||||
statBar.Append(pBox)
|
||||
|
||||
sBox := gtk.NewBox(gtk.OrientationHorizontal, 0)
|
||||
sIcon = gtk.NewImageFromPaintable(clientAssets["car"])
|
||||
sIcon.AddCSSClass("icon")
|
||||
sStatus = gtk.NewLabel("-")
|
||||
sBox.Append(sIcon)
|
||||
sBox.Append(sStatus)
|
||||
sStatus.SetTooltipText("Throughput of your XMPP connection in KB/s")
|
||||
statBar.Append(sBox)
|
||||
|
||||
scrollerStatBar := gtk.NewScrolledWindow()
|
||||
scrollerStatBar.SetChild(statBar)
|
||||
box.Append(scrollerStatBar)
|
||||
|
||||
@@ -3,10 +3,10 @@ package main
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"image"
|
||||
"image/png"
|
||||
"github.com/srwiley/oksvg"
|
||||
"github.com/srwiley/rasterx"
|
||||
"image"
|
||||
"image/png"
|
||||
)
|
||||
|
||||
func SVGToPNG(svgData []byte) ([]byte, error) {
|
||||
|
||||