t
This commit is contained in:
@@ -140,6 +140,10 @@ var moderateBytes []byte
|
|||||||
//go:embed assets/jabber.png
|
//go:embed assets/jabber.png
|
||||||
var jabberBytes []byte
|
var jabberBytes []byte
|
||||||
|
|
||||||
|
|
||||||
|
//go:embed assets/fail.png
|
||||||
|
var failBytes []byte
|
||||||
|
|
||||||
func loadAsset(key string, data []byte) {
|
func loadAsset(key string, data []byte) {
|
||||||
loader := gdkpixbuf.NewPixbufLoader()
|
loader := gdkpixbuf.NewPixbufLoader()
|
||||||
loader.Write(data)
|
loader.Write(data)
|
||||||
@@ -193,6 +197,7 @@ func init() {
|
|||||||
"muc_temporary": mucTemporaryBytes,
|
"muc_temporary": mucTemporaryBytes,
|
||||||
"moderate": moderateBytes,
|
"moderate": moderateBytes,
|
||||||
"jabber": jabberBytes,
|
"jabber": jabberBytes,
|
||||||
|
"fail": failBytes,
|
||||||
} {
|
} {
|
||||||
loadAsset(key, data)
|
loadAsset(key, data)
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 7.8 KiB |
@@ -21,7 +21,9 @@ import (
|
|||||||
var textureCache sync.Map
|
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)
|
||||||
|
|
||||||
|
var invalidImages sync.Map
|
||||||
|
|
||||||
func ensureCache() (string, error) {
|
func ensureCache() (string, error) {
|
||||||
cachePath := configdir.LocalCache("lambda-im")
|
cachePath := configdir.LocalCache("lambda-im")
|
||||||
|
|||||||
+30
-6
@@ -16,9 +16,13 @@ import (
|
|||||||
"image"
|
"image"
|
||||||
"image/png"
|
"image/png"
|
||||||
xmpp_color "mellium.im/xmpp/color"
|
xmpp_color "mellium.im/xmpp/color"
|
||||||
|
"image/color"
|
||||||
"strconv"
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
}
|
||||||
|
|
||||||
func scrollToBottomAfterUpdate(scrolledWindow *gtk.ScrolledWindow) {
|
func scrollToBottomAfterUpdate(scrolledWindow *gtk.ScrolledWindow) {
|
||||||
glib.IdleAdd(func() bool {
|
glib.IdleAdd(func() bool {
|
||||||
vAdj := scrolledWindow.VAdjustment()
|
vAdj := scrolledWindow.VAdjustment()
|
||||||
@@ -63,10 +67,26 @@ func switchToTab(jid string, w *gtk.Window) {
|
|||||||
if typed_tab.isMuc {
|
if typed_tab.isMuc {
|
||||||
m, ok := mucmembers.Load(jid)
|
m, ok := mucmembers.Load(jid)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
box := gtk.NewBox(gtk.OrientationVertical, 10)
|
||||||
|
failed_icon := gtk.NewImageFromPaintable(clientAssets["fail"])
|
||||||
|
failed_icon.SetPixelSize(100)
|
||||||
|
box.Append(failed_icon)
|
||||||
|
label := gtk.NewLabel("There was an error loading the members of this room. Maybe the MUC does not give user presence, it does not exist, you have been banned from it, or you have to fill a CAPTCHA to access it. Try joining the room again or check if the room exists.")
|
||||||
|
label.SetWrap(true)
|
||||||
|
box.Append(label)
|
||||||
|
memberList.SetChild(box)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ma, ok := m.(mucUnit)
|
ma, ok := m.(mucUnit)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
box := gtk.NewBox(gtk.OrientationVertical, 10)
|
||||||
|
failed_icon := gtk.NewImageFromPaintable(clientAssets["fail"])
|
||||||
|
failed_icon.SetPixelSize(100)
|
||||||
|
box.Append(failed_icon)
|
||||||
|
label := gtk.NewLabel("There was an error loading the members of this room. Maybe the MUC does not give user presence, it does not exist, you have been banned from it, or you have to fill a CAPTCHA to access it. Try joining the room again or check if the room exists.")
|
||||||
|
label.SetWrap(true)
|
||||||
|
box.Append(label)
|
||||||
|
memberList.SetChild(box)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mm := ma.Members
|
mm := ma.Members
|
||||||
@@ -155,7 +175,7 @@ func switchToTab(jid string, w *gtk.Window) {
|
|||||||
medal.SetHExpand(true)
|
medal.SetHExpand(true)
|
||||||
userbox.Append(medal)
|
userbox.Append(medal)
|
||||||
|
|
||||||
default_av := createIdenticon(u.From)
|
default_av := createIdenticon(u.From, false)
|
||||||
userbox.Prepend(default_av)
|
userbox.Prepend(default_av)
|
||||||
var vcu VCardUpdate
|
var vcu VCardUpdate
|
||||||
ok = u.Get(&vcu)
|
ok = u.Get(&vcu)
|
||||||
@@ -461,13 +481,13 @@ func switchToTab(jid string, w *gtk.Window) {
|
|||||||
im.AddCSSClass("author_img")
|
im.AddCSSClass("author_img")
|
||||||
profile_box.Prepend(im)
|
profile_box.Prepend(im)
|
||||||
} else {
|
} else {
|
||||||
im := createIdenticon(u.From)
|
im := createIdenticon(u.From, false)
|
||||||
im.SetPixelSize(80)
|
im.SetPixelSize(80)
|
||||||
im.AddCSSClass("author_img")
|
im.AddCSSClass("author_img")
|
||||||
profile_box.Prepend(im)
|
profile_box.Prepend(im)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
im := createIdenticon(u.From)
|
im := createIdenticon(u.From, false)
|
||||||
im.SetPixelSize(80)
|
im.SetPixelSize(80)
|
||||||
im.AddCSSClass("author_img")
|
im.AddCSSClass("author_img")
|
||||||
profile_box.Prepend(im)
|
profile_box.Prepend(im)
|
||||||
@@ -529,14 +549,18 @@ func showErrorDialog(err error) {
|
|||||||
err_win.Present()
|
err_win.Present()
|
||||||
}
|
}
|
||||||
|
|
||||||
func createIdenticon(word string) *gtk.Image { // This function generates an identicon
|
func createIdenticon(word string, always_create bool) *gtk.Image { // This function generates an identicon
|
||||||
if !loadedConfig.Identicons {
|
if !loadedConfig.Identicons && !always_create {
|
||||||
i := gtk.NewImageFromPaintable(clientAssets["DefaultAvatar"])
|
i := gtk.NewImageFromPaintable(clientAssets["DefaultAvatar"])
|
||||||
i.AddCSSClass(loadedConfig.CVD.String() + "_CVD")
|
i.AddCSSClass(loadedConfig.CVD.String() + "_CVD")
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
gen, _ := identicon.New("github", 5, 3)
|
identicon.SetBackgroundColorFunction(func([]byte, color.Color) color.Color {
|
||||||
|
return color.Transparent
|
||||||
|
})
|
||||||
|
|
||||||
|
gen, _ := identicon.New("", 5, 3)
|
||||||
ii, _ := gen.Draw(word)
|
ii, _ := gen.Draw(word)
|
||||||
im := ii.Image(250)
|
im := ii.Image(250)
|
||||||
|
|
||||||
|
|||||||
+19
-13
@@ -171,7 +171,7 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
|
|||||||
pres := mmmm.(stanza.Presence)
|
pres := mmmm.(stanza.Presence)
|
||||||
var vu VCardUpdate
|
var vu VCardUpdate
|
||||||
pres.Get(&vu)
|
pres.Get(&vu)
|
||||||
im := createIdenticon(m.From)
|
im := createIdenticon(m.From, false)
|
||||||
im.SetPixelSize(40)
|
im.SetPixelSize(40)
|
||||||
im.AddCSSClass("author_img")
|
im.AddCSSClass("author_img")
|
||||||
authorBox.Append(im)
|
authorBox.Append(im)
|
||||||
@@ -188,7 +188,7 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
im := createIdenticon(m.From)
|
im := createIdenticon(m.From, false)
|
||||||
im.SetPixelSize(40)
|
im.SetPixelSize(40)
|
||||||
im.AddCSSClass("author_img")
|
im.AddCSSClass("author_img")
|
||||||
authorBox.Append(im)
|
authorBox.Append(im)
|
||||||
@@ -199,6 +199,12 @@ func generateMessageWidget(p stanza.Packet) gtk.Widgetter {
|
|||||||
|
|
||||||
authorBox.Append(al)
|
authorBox.Append(al)
|
||||||
|
|
||||||
|
if m.Thread != "" {
|
||||||
|
im := createIdenticon(m.Thread, true)
|
||||||
|
im.SetPixelSize(10)
|
||||||
|
authorBox.Append(im)
|
||||||
|
}
|
||||||
|
|
||||||
wxdc := XDCEl{}
|
wxdc := XDCEl{}
|
||||||
ok = m.Get(&wxdc)
|
ok = m.Get(&wxdc)
|
||||||
if ok {
|
if ok {
|
||||||
@@ -288,16 +294,16 @@ func getAvatar(j, hash string) *gtk.Image { // TODO: This function probably shou
|
|||||||
oghash := hash
|
oghash := hash
|
||||||
p, err := ensureCache()
|
p, err := ensureCache()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return createIdenticon(j)
|
return createIdenticon(j, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
if hash == "" {
|
if hash == "" {
|
||||||
return createIdenticon(j)
|
return createIdenticon(j, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, ok := invalidImages[hash]
|
_, ok := invalidImages.Load(hash)
|
||||||
if ok {
|
if ok {
|
||||||
return createIdenticon(j)
|
return createIdenticon(j, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
hash = filepath.Join(p, hash)
|
hash = filepath.Join(p, hash)
|
||||||
@@ -306,8 +312,8 @@ func getAvatar(j, hash string) *gtk.Image { // TODO: This function probably shou
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
i, err := newImageFromPath(hash)
|
i, err := newImageFromPath(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
invalidImages[oghash] = true
|
invalidImages.Store(oghash, true)
|
||||||
return createIdenticon(j)
|
return createIdenticon(j, false)
|
||||||
}
|
}
|
||||||
i.AddCSSClass(loadedConfig.CVD.String() + "_CVD")
|
i.AddCSSClass(loadedConfig.CVD.String() + "_CVD")
|
||||||
return i
|
return i
|
||||||
@@ -335,14 +341,14 @@ func getAvatar(j, hash string) *gtk.Image { // TODO: This function probably shou
|
|||||||
result := <-mychan
|
result := <-mychan
|
||||||
card, ok := result.Payload.(*VCard)
|
card, ok := result.Payload.(*VCard)
|
||||||
if !ok {
|
if !ok {
|
||||||
return createIdenticon(j)
|
return createIdenticon(j, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
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")) {
|
||||||
fmt.Println("Blocking image")
|
fmt.Println("Blocking image")
|
||||||
invalidImages[oghash] = true
|
invalidImages.Store(oghash, true)
|
||||||
return createIdenticon(j)
|
return createIdenticon(j, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := base64.StdEncoding.DecodeString(base64_data)
|
data, err := base64.StdEncoding.DecodeString(base64_data)
|
||||||
@@ -357,8 +363,8 @@ func getAvatar(j, hash string) *gtk.Image { // TODO: This function probably shou
|
|||||||
|
|
||||||
i, err := newImageFromPath(hash)
|
i, err := newImageFromPath(hash)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
invalidImages[oghash] = true
|
invalidImages.Store(oghash, true)
|
||||||
return createIdenticon(j)
|
return createIdenticon(j, false)
|
||||||
}
|
}
|
||||||
i.AddCSSClass(loadedConfig.CVD.String() + "_CVD")
|
i.AddCSSClass(loadedConfig.CVD.String() + "_CVD")
|
||||||
return i
|
return i
|
||||||
|
|||||||
@@ -346,7 +346,7 @@ func main() {
|
|||||||
|
|
||||||
if presence.Type != "unavailable" {
|
if presence.Type != "unavailable" {
|
||||||
_, ok := typed_unit.Members.Load(id)
|
_, ok := typed_unit.Members.Load(id)
|
||||||
if !ok {
|
if !ok && loadedConfig.ShowPresenceUpdates {
|
||||||
glib.IdleAdd(func() {
|
glib.IdleAdd(func() {
|
||||||
b := gtk.NewBox(gtk.OrientationVertical, 0)
|
b := gtk.NewBox(gtk.OrientationVertical, 0)
|
||||||
ba, ok := generatePresenceWidget(p).(*gtk.Box)
|
ba, ok := generatePresenceWidget(p).(*gtk.Box)
|
||||||
@@ -370,25 +370,27 @@ func main() {
|
|||||||
typed_unit.Members.Store(id, presence)
|
typed_unit.Members.Store(id, presence)
|
||||||
} else {
|
} else {
|
||||||
typed_unit.Members.Delete(id)
|
typed_unit.Members.Delete(id)
|
||||||
glib.IdleAdd(func() {
|
if loadedConfig.ShowPresenceUpdates {
|
||||||
b := gtk.NewBox(gtk.OrientationVertical, 0)
|
glib.IdleAdd(func() {
|
||||||
ba, ok := generatePresenceWidget(p).(*gtk.Box)
|
b := gtk.NewBox(gtk.OrientationVertical, 0)
|
||||||
if ok {
|
ba, ok := generatePresenceWidget(p).(*gtk.Box)
|
||||||
b = ba
|
if ok {
|
||||||
}
|
b = ba
|
||||||
|
|
||||||
tab, ok := tabs.Load(muc)
|
|
||||||
typed_tab := tab.(*chatTab)
|
|
||||||
|
|
||||||
if ok {
|
|
||||||
typed_tab.msgs.Append(b)
|
|
||||||
if current == muc {
|
|
||||||
scrollToBottomAfterUpdate(scroller)
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
fmt.Println("Got message when the tab does not exist!")
|
tab, ok := tabs.Load(muc)
|
||||||
}
|
typed_tab := tab.(*chatTab)
|
||||||
})
|
|
||||||
|
if ok {
|
||||||
|
typed_tab.msgs.Append(b)
|
||||||
|
if current == muc {
|
||||||
|
scrollToBottomAfterUpdate(scroller)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println("Got message when the tab does not exist!")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mucmembers.Store(muc, typed_unit)
|
mucmembers.Store(muc, typed_unit)
|
||||||
@@ -510,7 +512,7 @@ func main() {
|
|||||||
jid := v.Jid
|
jid := v.Jid
|
||||||
|
|
||||||
if name == "" {
|
if name == "" {
|
||||||
name = jid
|
name = jid
|
||||||
}
|
}
|
||||||
|
|
||||||
createTab(jid, false, name)
|
createTab(jid, false, name)
|
||||||
|
|||||||
Reference in New Issue
Block a user