add some icons and only store members by resource

This commit is contained in:
2026-03-12 16:09:22 +00:00
parent 7a201808e3
commit 654ab8b618
9 changed files with 52 additions and 15 deletions

View File

@@ -11,6 +11,10 @@ import (
var defaultAvatarBytes []byte var defaultAvatarBytes []byte
var defaultAvatarB64 string = base64.StdEncoding.EncodeToString(defaultAvatarBytes) var defaultAvatarB64 string = base64.StdEncoding.EncodeToString(defaultAvatarBytes)
//go:embed failed_load.png
var failedBytes []byte
var failedB64 string = base64.StdEncoding.EncodeToString(failedBytes)
//go:embed assets/owner.png //go:embed assets/owner.png
var ownerMedalBytes []byte var ownerMedalBytes []byte
var ownerMedalB64 string = base64.StdEncoding.EncodeToString(ownerMedalBytes) var ownerMedalB64 string = base64.StdEncoding.EncodeToString(ownerMedalBytes)
@@ -100,6 +104,15 @@ func init() {
loader.Close() loader.Close()
clientAssets["DefaultAvatar"] = gdk.NewTextureForPixbuf(loader.Pixbuf()) clientAssets["DefaultAvatar"] = gdk.NewTextureForPixbuf(loader.Pixbuf())
loader = gdkpixbuf.NewPixbufLoader()
failedData, _ := base64.StdEncoding.DecodeString(failedB64)
loader.Write(failedData)
loader.Close()
clientAssets["FailedAvatar"] = gdk.NewTextureForPixbuf(loader.Pixbuf())
loader = gdkpixbuf.NewPixbufLoader() loader = gdkpixbuf.NewPixbufLoader()
ownerMedalData, _ := base64.StdEncoding.DecodeString(ownerMedalB64) ownerMedalData, _ := base64.StdEncoding.DecodeString(ownerMedalB64)

View File

@@ -0,0 +1 @@
All client assets are owned by their respective owners

View File

@@ -18,6 +18,9 @@ import (
// global or app-level map/cache // global or app-level map/cache
var textureCache = make(map[string]gdk.Paintabler) var textureCache = make(map[string]gdk.Paintabler)
// Invalid images, if an image/avatar cannot be loaded on the system (e.g: incompatible format) it's put here
var invalidImages = make(map[string]bool)
func ensureCache() (string, error) { func ensureCache() (string, error) {
cachePath := configdir.LocalCache("lambda-im") cachePath := configdir.LocalCache("lambda-im")
err := configdir.MakePath(cachePath) // Ensure it exists. err := configdir.MakePath(cachePath) // Ensure it exists.

BIN
failed_load.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

View File

@@ -70,10 +70,10 @@ func switchToTab(jid string, w *gtk.Window) {
var ocu OccupantID var ocu OccupantID
u.Get(&mu) u.Get(&mu)
u.Get(&ocu) u.Get(&ocu)
id := ocu.ID //id := ocu.ID
if id == "" { //if id == "" {
id = JidMustParse(u.From).Resource id := JidMustParse(u.From).Resource
} //}
nick_label := gtk.NewLabel(JidMustParse(u.From).Resource) nick_label := gtk.NewLabel(JidMustParse(u.From).Resource)
nick_label.SetEllipsize(pango.EllipsizeEnd) nick_label.SetEllipsize(pango.EllipsizeEnd)

View File

@@ -151,10 +151,10 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
ocu := OccupantID{} ocu := OccupantID{}
m.Get(&ocu) m.Get(&ocu)
id := ocu.ID //id := ocu.ID
if id == "" { // if id == "" {
id = JidMustParse(m.From).Resource id := JidMustParse(m.From).Resource
} // }
authorBox := gtk.NewBox(gtk.OrientationHorizontal, 10) authorBox := gtk.NewBox(gtk.OrientationHorizontal, 10)
@@ -265,9 +265,10 @@ func getVAdjustment(scrolledWindow *gtk.ScrolledWindow) *gtk.Adjustment {
} }
func getAvatar(j, hash string) *gtk.Image { // TODO: This function probably shouldn't be here, and should probably be in xmpp-helpers or somewhere similar. func getAvatar(j, hash string) *gtk.Image { // TODO: This function probably shouldn't be here, and should probably be in xmpp-helpers or somewhere similar.
oghash := hash
p, err := ensureCache() p, err := ensureCache()
if err != nil { if err != nil {
return gtk.NewImageFromPaintable(clientAssets["DefaultAvatar"]) return gtk.NewImageFromPaintable(clientAssets["FailedAvatar"])
} }
if hash == "" { if hash == "" {
@@ -275,6 +276,12 @@ func getAvatar(j, hash string) *gtk.Image { // TODO: This function probably shou
return gtk.NewImageFromPaintable(clientAssets["DefaultAvatar"]) return gtk.NewImageFromPaintable(clientAssets["DefaultAvatar"])
} }
_, ok := invalidImages[hash]
if ok {
fmt.Println("Image is invalid")
return gtk.NewImageFromPaintable(clientAssets["FailedAvatar"])
}
hash = filepath.Join(p, sanitizefilename.Sanitize(hash)) hash = filepath.Join(p, sanitizefilename.Sanitize(hash))
_, err = os.ReadFile(hash) _, err = os.ReadFile(hash)
@@ -309,7 +316,9 @@ func getAvatar(j, hash string) *gtk.Image { // TODO: This function probably shou
base64_data := card.Photo.Binval base64_data := card.Photo.Binval
if card.Photo.Binval == "" || ((card.Photo.Type == "image/svg+xml" || card.Photo.Type == "image/webp") && (runtime.GOOS == "windows" || runtime.GOOS == "netbsd")) { if card.Photo.Binval == "" || ((card.Photo.Type == "image/svg+xml" || card.Photo.Type == "image/webp") && (runtime.GOOS == "windows" || runtime.GOOS == "netbsd")) {
return gtk.NewImageFromPaintable(clientAssets["DefaultAvatar"]) fmt.Println("Blocking image")
invalidImages[oghash] = true
return gtk.NewImageFromPaintable(clientAssets["FailedAvatar"])
} }
data, err := base64.StdEncoding.DecodeString(base64_data) data, err := base64.StdEncoding.DecodeString(base64_data)

20
main.go
View File

@@ -1,6 +1,7 @@
package main package main
import ( import (
"strings"
"os" "os"
"sync" "sync"
@@ -121,7 +122,7 @@ func main() {
Jid: loadedConfig.Username + "/" + loadedConfig.Resource, Jid: loadedConfig.Username + "/" + loadedConfig.Resource,
Credential: xmpp.Password(loadedConfig.Password), Credential: xmpp.Password(loadedConfig.Password),
Insecure: loadedConfig.Insecure, Insecure: loadedConfig.Insecure,
// StreamLogger: os.Stdout, StreamLogger: os.Stdout,
StreamManagementEnable: true, StreamManagementEnable: true,
} }
router := xmpp.NewRouter() router := xmpp.NewRouter()
@@ -282,10 +283,10 @@ func main() {
if ok { // This is a presence stanza from a user in a MUC if ok { // This is a presence stanza from a user in a MUC
presence.Get(&ocu) presence.Get(&ocu)
id := ocu.ID // id := ocu.ID
if id == "" { // if id == "" {
id = JidMustParse(presence.From).Resource id := JidMustParse(presence.From).Resource
} // }
from, _ := stanza.NewJid(presence.From) from, _ := stanza.NewJid(presence.From)
muc := from.Bare() muc := from.Bare()
_, ok = mucmembers.Load(muc) _, ok = mucmembers.Load(muc)
@@ -868,6 +869,15 @@ func activate(app *gtk.Application) {
exts = append(exts, new_oob) exts = append(exts, new_oob)
} }
if strings.Contains(t, "@everyone") {
new_mention := new(Mention)
new_mention.Mentions = "urn:xmpp:mentions:0#channel"
exts = append(exts, new_mention)
} else if strings.Contains(t, "@here") {
new_attention := new(Attention)
exts = append(exts, new_attention)
}
err := sendMessage(client, current, message_type, t, "", "", exts) err := sendMessage(client, current, message_type, t, "", "", exts)
if err != nil { if err != nil {
panic(err) // TODO: Show error message via GTK panic(err) // TODO: Show error message via GTK

BIN
please_wait.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

@@ -16,6 +16,7 @@ type Mention struct {
Begin int `xml:"begin,attr,omitempty"` Begin int `xml:"begin,attr,omitempty"`
End int `xml:"end,attr,omitempty"` End int `xml:"end,attr,omitempty"`
OccupantID string `xml:"occupantid,attr,omitempty"` OccupantID string `xml:"occupantid,attr,omitempty"`
JID string `xml:"ji,attr,omitempty"`
} }
func init() { func init() {