fix avatars

This commit is contained in:
2026-05-02 06:56:08 +01:00
parent 5bcf0eda0b
commit 58c7165ce5
3 changed files with 48 additions and 31 deletions
+35 -25
View File
@@ -13,10 +13,12 @@ import (
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
"sync"
) )
// 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)
var textureCache sync.Map
// Invalid images, if an image/avatar cannot be loaded on the system (e.g: incompatible format) it's put here // 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) var invalidImages = make(map[string]bool)
@@ -31,49 +33,57 @@ func ensureCache() (string, error) {
return cachePath, nil return cachePath, nil
} }
func getTexture(path string) gdk.Paintabler { func getTexture(path string) (gdk.Paintabler, error) {
if tex, exists := textureCache[path]; exists { tex, exists := textureCache.Load(path)
return tex if exists {
return tex.(gdk.Paintabler), nil
} }
tex, err := gdk.NewTextureFromFilename(path) // load once tex, err := gdk.NewTextureFromFilename(path) // load once
if err != nil { if err != nil {
panic(err) return nil, err
} }
textureCache[path] = tex textureCache.Store(path, tex)
return tex return tex.(gdk.Paintabler), nil
} }
func newPictureFromPath(path string) *gtk.Picture { func newPictureFromPath(path string) (*gtk.Picture, error) {
tex := getTexture(path) tex, err := getTexture(path)
if err != nil {
return nil, err
}
img := gtk.NewPictureForPaintable(tex) img := gtk.NewPictureForPaintable(tex)
return img return img, nil
} }
func newImageFromPath(path string) *gtk.Image { func newImageFromPath(path string) (*gtk.Image, error) {
tex := getTexture(path) tex, err := getTexture(path)
if err != nil {
return nil, err
}
img := gtk.NewImageFromPaintable(tex) img := gtk.NewImageFromPaintable(tex)
return img return img, nil
} }
func newPictureFromWeb(url string) *gtk.Picture { func newPictureFromWeb(url string) (*gtk.Picture, error) {
pa, _ := ensureCache() pa, _ := ensureCache()
// step 1: get a sha256 sum of the URL // step 1: get a sha256 sum of the URL
sum := fmt.Sprintf("%x", sha256.Sum256([]byte(url))) sum := fmt.Sprintf("%x", sha256.Sum256([]byte(url)))
p, ok := textureCache[sum] p, ok := textureCache.Load(sum)
if ok { if ok {
return gtk.NewPictureForPaintable(p) return gtk.NewPictureForPaintable(p.(gdk.Paintabler)), nil
} }
// step 2: download it // step 2: download it
resp, err := http.Get(url) resp, err := http.Get(url)
if err != nil { if err != nil {
return nil return nil, err
} }
b, err := io.ReadAll(resp.Body) b, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil return nil, err
} }
fullpath := filepath.Join(pa, sum) fullpath := filepath.Join(pa, sum)
@@ -81,31 +91,31 @@ func newPictureFromWeb(url string) *gtk.Picture {
// step 3: save it // step 3: save it
err = os.WriteFile(fullpath, b, 0644) err = os.WriteFile(fullpath, b, 0644)
if err != nil { if err != nil {
return nil return nil, err
} }
return newPictureFromPath(fullpath) return newPictureFromPath(fullpath)
} }
func newImageFromWeb(url string) *gtk.Image { func newImageFromWeb(url string) (*gtk.Image, error) {
pa, _ := ensureCache() pa, _ := ensureCache()
// step 1: get a sha256 sum of the URL // step 1: get a sha256 sum of the URL
sum := fmt.Sprintf("%x", sha256.Sum256([]byte(url))) sum := fmt.Sprintf("%x", sha256.Sum256([]byte(url)))
p, ok := textureCache[sum] p, ok := textureCache.Load(sum)
if ok { if ok {
return gtk.NewImageFromPaintable(p) return gtk.NewImageFromPaintable(p.(gdk.Paintabler)), nil
} }
// step 2: download it // step 2: download it
resp, err := http.Get(url) resp, err := http.Get(url)
if err != nil { if err != nil {
return nil return nil, err
} }
b, err := io.ReadAll(resp.Body) b, err := io.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil return nil, err
} }
fullpath := filepath.Join(pa, sum) fullpath := filepath.Join(pa, sum)
@@ -113,7 +123,7 @@ func newImageFromWeb(url string) *gtk.Image {
// step 3: save it // step 3: save it
err = os.WriteFile(fullpath, b, 0644) err = os.WriteFile(fullpath, b, 0644)
if err != nil { if err != nil {
return nil return nil, err
} }
return newImageFromPath(fullpath) return newImageFromPath(fullpath)
+12 -5
View File
@@ -10,7 +10,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/google/uuid" "github.com/google/uuid"
"github.com/jacoblockett/sanitizefilename"
"github.com/jasonlovesdoggo/gopen" "github.com/jasonlovesdoggo/gopen"
"gosrc.io/xmpp/stanza" "gosrc.io/xmpp/stanza"
"mellium.im/xmpp/jid" "mellium.im/xmpp/jid"
@@ -305,11 +304,15 @@ func getAvatar(j, hash string) *gtk.Image { // TODO: This function probably shou
return createIdenticon(j) return createIdenticon(j)
} }
hash = filepath.Join(p, sanitizefilename.Sanitize(hash)) hash = filepath.Join(p, hash)
_, err = os.ReadFile(hash) _, err = os.ReadFile(hash)
if err == nil { if err == nil {
i := newImageFromPath(hash) i, err := newImageFromPath(hash)
if err != nil {
invalidImages[oghash] = true
return createIdenticon(j)
}
i.AddCSSClass(loadedConfig.CVD.String() + "_CVD") i.AddCSSClass(loadedConfig.CVD.String() + "_CVD")
return i return i
} }
@@ -318,7 +321,7 @@ func getAvatar(j, hash string) *gtk.Image { // TODO: This function probably shou
Type: "get", Type: "get",
From: clientroot.Session.BindJid, From: clientroot.Session.BindJid,
To: j, To: j,
Id: "vc2", Id: uuid.New().String(),
Lang: "en", Lang: "en",
}) })
@@ -356,7 +359,11 @@ func getAvatar(j, hash string) *gtk.Image { // TODO: This function probably shou
panic(err) panic(err)
} }
i := newImageFromPath(hash) i, err := newImageFromPath(hash)
if err != nil {
invalidImages[oghash] = true
return createIdenticon(j)
}
i.AddCSSClass(loadedConfig.CVD.String() + "_CVD") i.AddCSSClass(loadedConfig.CVD.String() + "_CVD")
return i return i
} }
+1 -1
View File
@@ -272,7 +272,7 @@ func main() {
composing := stanza.StateComposing{} composing := stanza.StateComposing{}
ok = m.Get(&composing) ok = m.Get(&composing)
if ok && current == JidMustParse(m.From).Bare() { if ok && current == JidMustParse(m.From).Bare() {
typingStatus.SetText(fmt.Sprintf("%s %s", m.From, loadedLocale["isTyping"])) typingStatus.SetText(fmt.Sprintf("%s%s", m.From, loadedLocale["isTyping"]))
return return
} }