Compare commits

4 Commits

Author SHA1 Message Date
6626d35920 fix some crashes and debug smtn 2026-02-04 10:12:49 +00:00
5c76729a6b Attempt to fix duplicated user tabs 2026-02-03 10:38:41 +00:00
c260b8b231 add more support for other message types 2026-02-03 10:07:33 +00:00
971147dcb8 add icon 2026-02-02 18:57:11 +00:00
7 changed files with 61 additions and 11 deletions

BIN
assets/cancel.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 607 B

BIN
assets/icon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

BIN
assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -5,6 +5,7 @@ import (
"fmt" "fmt"
"github.com/diamondburned/gotk4/pkg/glib/v2" "github.com/diamondburned/gotk4/pkg/glib/v2"
"github.com/diamondburned/gotk4/pkg/gtk/v4" "github.com/diamondburned/gotk4/pkg/gtk/v4"
"github.com/diamondburned/gotk4/pkg/pango"
"gosrc.io/xmpp/stanza" "gosrc.io/xmpp/stanza"
) )
@@ -19,7 +20,9 @@ func scrollToBottomAfterUpdate(scrolledWindow *gtk.ScrolledWindow) {
func createTab(jid string, isMuc bool) bool { func createTab(jid string, isMuc bool) bool {
fmt.Println("Creating tab", jid, "isMuc:", isMuc) fmt.Println("Creating tab", jid, "isMuc:", isMuc)
_, ok := tabs.Load(jid) _, ok := tabs.Load(jid)
if !ok { _, uok := userdevices.Load(jid)
_, mok := mucmembers.Load(jid)
if !ok && !uok && !mok {
newTab := new(chatTab) newTab := new(chatTab)
newTab.isMuc = isMuc newTab.isMuc = isMuc
newTab.msgs = gtk.NewListBox() newTab.msgs = gtk.NewListBox()
@@ -45,8 +48,14 @@ func switchToTab(jid string, w *gtk.Window) {
scroller.SetChild(typed_tab.msgs) scroller.SetChild(typed_tab.msgs)
if typed_tab.isMuc { if typed_tab.isMuc {
m, _ := mucmembers.Load(jid) m, ok := mucmembers.Load(jid)
ma := m.(mucUnit) if !ok {
return
}
ma, ok := m.(mucUnit)
if !ok {
return
}
mm := ma.Members mm := ma.Members
gen := gtk.NewBox(gtk.OrientationVertical, 0) gen := gtk.NewBox(gtk.OrientationVertical, 0)
@@ -60,6 +69,7 @@ func switchToTab(jid string, w *gtk.Window) {
u.Get(&ocu) u.Get(&ocu)
nick_label := gtk.NewLabel(JidMustParse(u.From).Resource) nick_label := gtk.NewLabel(JidMustParse(u.From).Resource)
nick_label.SetEllipsize(pango.EllipsizeEnd)
/* /*
affil_label := gtk.NewLabel("") affil_label := gtk.NewLabel("")
switch mu.MucUserItem.Affiliation { switch mu.MucUserItem.Affiliation {
@@ -196,8 +206,11 @@ func switchToTab(jid string, w *gtk.Window) {
win.Present() win.Present()
}) })
userbox.AddController(gesture) userbox.AddController(gesture)
if mu.MucUserItem.Role == "moderator" {
gen.Append(userbox) gen.Prepend(userbox)
} else {
gen.Append(userbox)
}
return true return true
}) })

View File

@@ -49,7 +49,27 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
readmarker := Marker{} readmarker := Marker{}
ok = m.Get(&readmarker) ok = m.Get(&readmarker)
if ok { if ok {
return gtk.NewLabel(fmt.Sprintf("%s has read to this point", JidMustParse(m.From).Resource)) b := gtk.NewBox(gtk.OrientationHorizontal, 0)
b.Append(gtk.NewLabel(fmt.Sprintf("%s has read to this point", JidMustParse(m.From).Resource)))
return b
}
indicator := stanza.StateComposing{}
ok = m.Get(&indicator)
if ok { // TODO: Display typing indicator in a stat bar or something similar
b := gtk.NewBox(gtk.OrientationHorizontal, 0)
b.Append(gtk.NewLabel(fmt.Sprintf("%s is typing...", JidMustParse(m.From).Resource)))
return b
}
if m.Error.Type != "" {
error_box := gtk.NewBox(gtk.OrientationHorizontal, 0)
cancel_img := gtk.NewImageFromPaintable(clientAssets["cancel"])
error_label := gtk.NewLabel(m.Error.Text)
error_box.Append(cancel_img)
error_box.Append(error_label)
return error_box
} }

27
main.go
View File

@@ -11,7 +11,6 @@ import (
"github.com/diamondburned/gotk4/pkg/glib/v2" "github.com/diamondburned/gotk4/pkg/glib/v2"
"github.com/diamondburned/gotk4/pkg/gtk/v4" "github.com/diamondburned/gotk4/pkg/gtk/v4"
"github.com/diamondburned/gotk4/pkg/gdkpixbuf/v2" "github.com/diamondburned/gotk4/pkg/gdkpixbuf/v2"
_ "github.com/kr/pretty"
"path/filepath" "path/filepath"
"github.com/BurntSushi/toml" "github.com/BurntSushi/toml"
@@ -81,8 +80,12 @@ var noneMedalB64 string = base64.StdEncoding.EncodeToString(noneMedalBytes)
var outcastMedalBytes []byte var outcastMedalBytes []byte
var outcastMedalB64 string = base64.StdEncoding.EncodeToString(outcastMedalBytes) var outcastMedalB64 string = base64.StdEncoding.EncodeToString(outcastMedalBytes)
//go:embed assets/cancel.png
var cancelBytes []byte
var cancelB64 string = base64.StdEncoding.EncodeToString(cancelBytes)
var clientAssets map[string]gdk.Paintabler = make(map[string]gdk.Paintabler) var clientAssets map[string]gdk.Paintabler = make(map[string]gdk.Paintabler)
var lockedJIDs map[string]bool = make(map[string]bool)
func init() { func init() {
go func() { go func() {
@@ -113,6 +116,14 @@ func init() {
loader = gdkpixbuf.NewPixbufLoader() loader = gdkpixbuf.NewPixbufLoader()
cancelData, _ := base64.StdEncoding.DecodeString(cancelB64)
loader.Write(cancelData)
loader.Close()
clientAssets["cancel"] = gdk.NewTextureForPixbuf(loader.Pixbuf())
loader = gdkpixbuf.NewPixbufLoader()
adminMedalData, _ := base64.StdEncoding.DecodeString(adminMedalB64) adminMedalData, _ := base64.StdEncoding.DecodeString(adminMedalB64)
loader.Write(adminMedalData) loader.Write(adminMedalData)
loader.Close() loader.Close()
@@ -176,7 +187,7 @@ func main() {
Jid: loadedConfig.Username + "/lambda." + str, Jid: loadedConfig.Username + "/lambda." + str,
Credential: xmpp.Password(loadedConfig.Password), Credential: xmpp.Password(loadedConfig.Password),
Insecure: loadedConfig.Insecure, Insecure: loadedConfig.Insecure,
StreamLogger: os.Stdout, // StreamLogger: os.Stdout,
} }
router := xmpp.NewRouter() router := xmpp.NewRouter()
@@ -241,6 +252,12 @@ func main() {
return return
} }
e := stanza.PubSubEvent{}
ok = m.Get(&e)
if ok {
fmt.Println(e)
}
/* /*
if m.Body == "" { if m.Body == "" {
return return
@@ -306,7 +323,6 @@ func main() {
} else { } else {
typed_unit.Members.Delete(ocu.ID) typed_unit.Members.Delete(ocu.ID)
glib.IdleAdd(func() { glib.IdleAdd(func() {
//uiQueue <- func() {
b := gtk.NewLabel("") b := gtk.NewLabel("")
ba, ok := generatePresenceWidget(p).(*gtk.Label) ba, ok := generatePresenceWidget(p).(*gtk.Label)
if ok { if ok {
@@ -322,7 +338,6 @@ func main() {
} else { } else {
fmt.Println("Got message when the tab does not exist!") fmt.Println("Got message when the tab does not exist!")
} }
//}
}) })
} }
@@ -335,7 +350,7 @@ func main() {
_, mok := mucmembers.Load(user) _, mok := mucmembers.Load(user)
if !ok && !mok { // FIXME: The initial muc presence gets picked up from this check if !ok && !mok { // FIXME: The initial muc presence gets picked up from this check
ok := createTab(user, false) ok := createTab(user, false)
if ok { if ok && !lockedJIDs[user]{
userdevices.Store(user, userUnit{}) userdevices.Store(user, userUnit{})
b := gtk.NewButtonWithLabel(user) b := gtk.NewButtonWithLabel(user)
@@ -363,7 +378,9 @@ func main() {
} }
userdevices.Store(user, typed_unit) userdevices.Store(user, typed_unit)
lockedJIDs[user] = true
} }
time.Sleep(1 * time.Second)
}) })
c, err := xmpp.NewClient(&config, router, func(err error) { c, err := xmpp.NewClient(&config, router, func(err error) {

BIN
rsrc_windows_amd64.syso Normal file

Binary file not shown.