diff --git a/assets.go b/assets.go index 87c25c2..a737c0f 100644 --- a/assets.go +++ b/assets.go @@ -11,6 +11,10 @@ import ( var defaultAvatarBytes []byte 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 var ownerMedalBytes []byte var ownerMedalB64 string = base64.StdEncoding.EncodeToString(ownerMedalBytes) @@ -100,6 +104,15 @@ func init() { loader.Close() 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() ownerMedalData, _ := base64.StdEncoding.DecodeString(ownerMedalB64) diff --git a/assets/client_icons/README b/assets/client_icons/README new file mode 100644 index 0000000..f92ca0a --- /dev/null +++ b/assets/client_icons/README @@ -0,0 +1 @@ +All client assets are owned by their respective owners diff --git a/cache.go b/cache.go index 337171a..267ca68 100644 --- a/cache.go +++ b/cache.go @@ -18,6 +18,9 @@ import ( // global or app-level map/cache 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) { cachePath := configdir.LocalCache("lambda-im") err := configdir.MakePath(cachePath) // Ensure it exists. diff --git a/failed_load.png b/failed_load.png new file mode 100644 index 0000000..291626c Binary files /dev/null and b/failed_load.png differ diff --git a/gtk-helpers.go b/gtk-helpers.go index dfb055e..f6b5e11 100644 --- a/gtk-helpers.go +++ b/gtk-helpers.go @@ -70,10 +70,10 @@ func switchToTab(jid string, w *gtk.Window) { var ocu OccupantID u.Get(&mu) u.Get(&ocu) - id := ocu.ID - if id == "" { - id = JidMustParse(u.From).Resource - } + //id := ocu.ID + //if id == "" { + id := JidMustParse(u.From).Resource + //} nick_label := gtk.NewLabel(JidMustParse(u.From).Resource) nick_label.SetEllipsize(pango.EllipsizeEnd) diff --git a/gtk-message.go b/gtk-message.go index a21a73c..e7b3d0d 100644 --- a/gtk-message.go +++ b/gtk-message.go @@ -151,10 +151,10 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter { ocu := OccupantID{} m.Get(&ocu) - id := ocu.ID - if id == "" { - id = JidMustParse(m.From).Resource - } + //id := ocu.ID + // if id == "" { + id := JidMustParse(m.From).Resource + // } 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. + oghash := hash p, err := ensureCache() if err != nil { - return gtk.NewImageFromPaintable(clientAssets["DefaultAvatar"]) + return gtk.NewImageFromPaintable(clientAssets["FailedAvatar"]) } if hash == "" { @@ -275,6 +276,12 @@ func getAvatar(j, hash string) *gtk.Image { // TODO: This function probably shou 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)) _, 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 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) diff --git a/main.go b/main.go index 2e5e83b..2dc6d14 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "strings" "os" "sync" @@ -121,7 +122,7 @@ func main() { Jid: loadedConfig.Username + "/" + loadedConfig.Resource, Credential: xmpp.Password(loadedConfig.Password), Insecure: loadedConfig.Insecure, - // StreamLogger: os.Stdout, + StreamLogger: os.Stdout, StreamManagementEnable: true, } router := xmpp.NewRouter() @@ -282,10 +283,10 @@ func main() { if ok { // This is a presence stanza from a user in a MUC presence.Get(&ocu) - id := ocu.ID - if id == "" { - id = JidMustParse(presence.From).Resource - } + // id := ocu.ID + // if id == "" { + id := JidMustParse(presence.From).Resource + // } from, _ := stanza.NewJid(presence.From) muc := from.Bare() _, ok = mucmembers.Load(muc) @@ -868,6 +869,15 @@ func activate(app *gtk.Application) { 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) if err != nil { panic(err) // TODO: Show error message via GTK diff --git a/please_wait.png b/please_wait.png new file mode 100644 index 0000000..0918883 Binary files /dev/null and b/please_wait.png differ diff --git a/xmpp-mentions.go b/xmpp-mentions.go index 11b4b6e..7344a18 100644 --- a/xmpp-mentions.go +++ b/xmpp-mentions.go @@ -16,6 +16,7 @@ type Mention struct { Begin int `xml:"begin,attr,omitempty"` End int `xml:"end,attr,omitempty"` OccupantID string `xml:"occupantid,attr,omitempty"` + JID string `xml:"ji,attr,omitempty"` } func init() {