Add hat icon, change some CSS and remove all reply support

This commit is contained in:
2026-02-08 09:44:45 +00:00
parent 589101c292
commit 713cb24508
7 changed files with 118 additions and 74 deletions

View File

@@ -3,3 +3,5 @@
an XMPP client an XMPP client
icons are from Psi+ ([https://github.com/psi-im](https://github.com/psi-im)) icons are from Psi+ ([https://github.com/psi-im](https://github.com/psi-im))
additional icons are by Mark James's Silk Icon Set [https://peacocksoftware.com/sites/peacocksoftware/silk_icons/comment.png](https://peacocksoftware.com/sites/peacocksoftware/silk_icons/comment.png)

BIN
assets/tag.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 666 B

View File

@@ -2,6 +2,8 @@ package main
import ( import (
"context" "context"
"crypto/sha1"
"encoding/hex"
"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"
@@ -105,11 +107,28 @@ func switchToTab(jid string, w *gtk.Window) {
userbox.Append(nick_label) userbox.Append(nick_label)
// userbox.Append(affil_label) // userbox.Append(affil_label)
var hats Hats
ok := u.Get(&hats)
if ok {
for _, hat := range hats.Hats {
tag := gtk.NewImageFromPaintable(clientAssets["tag"])
tag.SetTooltipText(hat.Title)
// tag.SetHAlign(gtk.AlignEnd)
// tag.SetHExpand(true)
userbox.Prepend(tag)
}
}
medal := gtk.NewImageFromPaintable(clientAssets[mu.MucUserItem.Affiliation]) medal := gtk.NewImageFromPaintable(clientAssets[mu.MucUserItem.Affiliation])
medal.SetTooltipText(mu.MucUserItem.Affiliation)
medal.SetHAlign(gtk.AlignEnd) medal.SetHAlign(gtk.AlignEnd)
medal.SetHExpand(true) medal.SetHExpand(true)
userbox.Append(medal) userbox.Append(medal)
gesture := gtk.NewGestureClick() gesture := gtk.NewGestureClick()
gesture.SetButton(3) // Right click gesture.SetButton(3) // Right click
@@ -143,7 +162,9 @@ func switchToTab(jid string, w *gtk.Window) {
ok := u.Get(&hats) ok := u.Get(&hats)
if ok { if ok {
for _, hat := range hats.Hats { for _, hat := range hats.Hats {
profile_box.Append(gtk.NewLabel(hat.Title)) l := gtk.NewLabel(hat.Title)
l.AddCSSClass("hat")
profile_box.Append(l)
} }
} }
@@ -157,6 +178,43 @@ func switchToTab(jid string, w *gtk.Window) {
profile_box.Append(gtk.NewLabel("Affiliated as " + mu.MucUserItem.Affiliation)) profile_box.Append(gtk.NewLabel("Affiliated as " + mu.MucUserItem.Affiliation))
} }
go func() {
fmt.Println("Attempting to get Disco info")
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("Identity %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))
profile_box.Append(gtk.NewLabel(fmt.Sprintf("The hash of this user's Disco features is:\n%s\nUse the disco feature to view them", sha1_hash)))
}
}
}()
go func() { go func() {
ctx := context.TODO() ctx := context.TODO()
mychan, err := client.SendIQ(ctx, iqResp) mychan, err := client.SendIQ(ctx, iqResp)
@@ -169,9 +227,7 @@ func switchToTab(jid string, w *gtk.Window) {
version := ver.Version version := ver.Version
os := ver.OS os := ver.OS
profile_box.Append(gtk.NewLabel(name)) profile_box.Append(gtk.NewLabel(fmt.Sprintf("%s %s %s", name, version, os)))
profile_box.Append(gtk.NewLabel(version))
profile_box.Append(gtk.NewLabel(os))
} }
} }
}() }()

View File

@@ -6,8 +6,8 @@ import (
"context" "context"
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"github.com/diamondburned/gotk4/pkg/gtk/v4"
"github.com/diamondburned/gotk4/pkg/gdk/v4" "github.com/diamondburned/gotk4/pkg/gdk/v4"
"github.com/diamondburned/gotk4/pkg/gtk/v4"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/jacoblockett/sanitizefilename" "github.com/jacoblockett/sanitizefilename"
"github.com/jasonlovesdoggo/gopen" "github.com/jasonlovesdoggo/gopen"
@@ -54,9 +54,9 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
return b return b
} }
indicator := stanza.StateComposing{} composing := stanza.StateComposing{}
ok = m.Get(&indicator) ok = m.Get(&composing)
if ok { // TODO: Display typing indicator in a stat bar or something similar if ok {
b := gtk.NewBox(gtk.OrientationHorizontal, 0) b := gtk.NewBox(gtk.OrientationHorizontal, 0)
b.Append(gtk.NewLabel(fmt.Sprintf("%s is typing...", JidMustParse(m.From).Resource))) b.Append(gtk.NewLabel(fmt.Sprintf("%s is typing...", JidMustParse(m.From).Resource)))
return b return b
@@ -72,7 +72,6 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
return error_box return error_box
} }
sid := StanzaID{} sid := StanzaID{}
m.Get(&sid) m.Get(&sid)
@@ -80,7 +79,6 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
gesture := gtk.NewGestureClick() gesture := gtk.NewGestureClick()
gesture.SetButton(3) // Right click gesture.SetButton(3) // Right click
popover := gtk.NewPopover() popover := gtk.NewPopover()
popover.SetParent(mainBox) popover.SetParent(mainBox)
popover.SetHasArrow(false) popover.SetHasArrow(false)
@@ -123,7 +121,6 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
rc_box.Append(moderate) rc_box.Append(moderate)
} }
popover.SetChild(rc_box) popover.SetChild(rc_box)
gesture.Connect("pressed", func(n_press, x, y int) { gesture.Connect("pressed", func(n_press, x, y int) {
@@ -134,14 +131,6 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
mainBox.AddController(gesture) mainBox.AddController(gesture)
reply := Reply{}
ok = m.Get(&reply)
if ok {
replyBox := gtk.NewBox(gtk.OrientationHorizontal, 0)
replyBox.Append(gtk.NewLabel("↱ " + jid.MustParse(reply.To).Resourcepart()))
mainBox.Append(replyBox)
}
ocu := OccupantID{} ocu := OccupantID{}
m.Get(&ocu) m.Get(&ocu)
@@ -190,7 +179,6 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
al.SetText(al.Text() + " whispers") al.SetText(al.Text() + " whispers")
} }
authorBox.Append(al) authorBox.Append(al)
mlabel := gtk.NewLabel(m.Body) mlabel := gtk.NewLabel(m.Body)
mlabel.SetWrap(true) mlabel.SetWrap(true)

24
main.go
View File

@@ -7,10 +7,10 @@ import (
"context" "context"
"fmt" "fmt"
"github.com/diamondburned/gotk4/pkg/gdk/v4" "github.com/diamondburned/gotk4/pkg/gdk/v4"
"github.com/diamondburned/gotk4/pkg/gdkpixbuf/v2"
"github.com/diamondburned/gotk4/pkg/gio/v2" "github.com/diamondburned/gotk4/pkg/gio/v2"
"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"
"path/filepath" "path/filepath"
"github.com/BurntSushi/toml" "github.com/BurntSushi/toml"
@@ -20,10 +20,11 @@ import (
"time" "time"
_ "embed" _ "embed"
"encoding/base64"
"encoding/xml" "encoding/xml"
"math/rand/v2" "math/rand/v2"
"runtime" "runtime"
"encoding/base64" "github.com/kr/pretty"
) )
var loadedConfig lambdaConfig var loadedConfig lambdaConfig
@@ -84,6 +85,10 @@ var outcastMedalB64 string = base64.StdEncoding.EncodeToString(outcastMedalBytes
var cancelBytes []byte var cancelBytes []byte
var cancelB64 string = base64.StdEncoding.EncodeToString(cancelBytes) var cancelB64 string = base64.StdEncoding.EncodeToString(cancelBytes)
//go:embed assets/tag.png
var tagBytes []byte
var tagB64 string = base64.StdEncoding.EncodeToString(tagBytes)
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) var lockedJIDs map[string]bool = make(map[string]bool)
@@ -105,7 +110,6 @@ func init() {
loader.Close() loader.Close()
clientAssets["DefaultAvatar"] = gdk.NewTextureForPixbuf(loader.Pixbuf()) clientAssets["DefaultAvatar"] = gdk.NewTextureForPixbuf(loader.Pixbuf())
loader = gdkpixbuf.NewPixbufLoader() loader = gdkpixbuf.NewPixbufLoader()
ownerMedalData, _ := base64.StdEncoding.DecodeString(ownerMedalB64) ownerMedalData, _ := base64.StdEncoding.DecodeString(ownerMedalB64)
@@ -124,6 +128,14 @@ func init() {
loader = gdkpixbuf.NewPixbufLoader() loader = gdkpixbuf.NewPixbufLoader()
tagData, _ := base64.StdEncoding.DecodeString(tagB64)
loader.Write(tagData)
loader.Close()
clientAssets["tag"] = 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()
@@ -219,7 +231,6 @@ func main() {
{Var: "jabber:iq:version"}, {Var: "jabber:iq:version"},
{Var: "urn:xmpp:delegation:1"}, {Var: "urn:xmpp:delegation:1"},
{Var: "http://jabber.org/protocol/muc"}, {Var: "http://jabber.org/protocol/muc"},
{Var: "urn:xmpp:reply:0"},
{Var: "λ"}, {Var: "λ"},
}, },
} }
@@ -252,6 +263,8 @@ func main() {
return return
} }
pretty.Println(m)
e := stanza.PubSubEvent{} e := stanza.PubSubEvent{}
ok = m.Get(&e) ok = m.Get(&e)
if ok { if ok {
@@ -354,7 +367,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 && !lockedJIDs[user]{ if ok && !lockedJIDs[user] {
userdevices.Store(user, userUnit{}) userdevices.Store(user, userUnit{})
b := gtk.NewButtonWithLabel(user) b := gtk.NewButtonWithLabel(user)
@@ -510,7 +523,6 @@ func activate(app *gtk.Application) {
the_menu.AppendSubmenu("File", fileMenu) the_menu.AppendSubmenu("File", fileMenu)
the_menu.AppendSubmenu("Help", helpMenu) the_menu.AppendSubmenu("Help", helpMenu)
the_menuBar := gtk.NewPopoverMenuBarFromModel(the_menu) the_menuBar := gtk.NewPopoverMenuBarFromModel(the_menu)
app.SetMenubar(gio.NewMenu()) app.SetMenubar(gio.NewMenu())

View File

@@ -33,3 +33,9 @@
.visitor { .visitor {
color: grey; color: grey;
} }
.hat {
background-color: orange;
color: black;
font-family: monospace;
}

View File

@@ -1,20 +0,0 @@
package main
// Implementation of XEP-0461
// https://xmpp.org/extensions/xep-0461.html#business-id
import (
"encoding/xml"
"gosrc.io/xmpp/stanza"
)
type Reply struct {
stanza.MsgExtension
XMLName xml.Name `xml:"urn:xmpp:reply:0 reply"`
To string `xml:"to,attr"`
ID string `xml:"id,attr"`
}
func init() {
stanza.TypeRegistry.MapExtension(stanza.PKTMessage, xml.Name{Space: "urn:xmpp:reply:0", Local: "reply"}, Reply{})
}