Compare commits

..
85 Commits
Author SHA1 Message Date
Sunglocto 7a875f84a5 you can run from your demons until you are exhausted, one day you will have to stop and find out what they wanted; keep on running to those angels until you are exhausted 2026-08-25 20:21:43 +01:00
Sunglocto a6e74ec808 Rest in peace Dolly Patron 2026-08-25 20:17:23 +01:00
Sunglocto 2717137270 can we pretend that airplanes in the night sky are like shooting stars 2026-08-20 11:01:25 +01:00
Sunglocto 58ae55e061 rotund 2026-08-16 20:07:53 +01:00
Sunglocto eebb6906c6 6-7 2026-08-08 13:54:20 +01:00
Sunglocto 0179d614b9 you need a man, with, sen-si-ti-vi-ty. a man like me 2026-08-07 12:50:35 +01:00
Sunglocto 2794adaa21 Decrement version 2026-08-06 13:35:41 +01:00
Sunglocto 37266ab8d4 homer drops his donut, doh, homer spills his soda, doh, homer hits the doorway, doh, homer ruins his whole day, doh! 2026-08-06 13:33:55 +01:00
Sunglocto 74f5761e06 peanits... hehe 2026-08-06 07:53:46 +01:00
Sunglocto 546234eacf sorry guys... lambda is now a snapchat client..... 2026-08-03 19:39:57 +01:00
Sunglocto 7a822e8eaf Add blocking, add note to self to tabs and add snit's default avatar img 2026-07-30 01:39:31 +01:00
Sunglocto b07f92853d NOBODYSETISGONELETSGO 2026-07-17 18:38:35 +01:00
Sunglocto 3bb74eb672 i farted2 2026-07-17 17:20:18 +01:00
Sunglocto 8cf0f84ddc uhh whats a submodule i have never heard of that bro 2026-07-17 17:18:21 +01:00
Sunglocto 006b43a590 lambda is free of this insane bug 2026-07-17 17:15:41 +01:00
Sunglocto 120b0c2647 Fix insecure TLS and bump version to 3 2026-07-16 17:08:43 +01:00
Sunglocto a3702a900c AV hash custom nicks 2026-07-16 09:05:03 +01:00
Sunglocto ede81d551c this commit was sponsored by mizkif 2026-07-14 16:25:18 +01:00
Sunglocto 7c19abb6ae Add update check, upgrade dependencies and format code and change ver 2026-07-14 07:51:46 +01:00
Sunglocto 8f93dde120 status msg in userbox 2026-07-10 09:52:18 +01:00
Sunglocto ca7b82dab5 compact mode changes 2026-06-03 06:38:31 +01:00
Sunglocto fce8df9e84 fixed member window 2026-06-01 10:37:22 +01:00
Sunglocto 1597f99eef format code + make showing avatars in member lists optional 2026-05-31 16:44:04 +01:00
Sunglocto 9ad48ff310 a 2026-05-23 06:45:18 +01:00
Sunglocto af0ec78eae format code 2026-05-19 14:07:21 +01:00
Sunglocto 5f95df147f h 2026-05-18 06:27:55 +01:00
Sunglocto 98cd855349 some qol stuff 2026-05-10 14:46:19 +01:00
Sunglocto 1aa14f9fd5 compact mode 2026-05-09 09:00:44 +01:00
Sunglocto 39cdd5e6c1 format + allow closing 2026-05-09 07:33:47 +01:00
Sunglocto 9bbefbcea8 t 2026-05-08 06:56:51 +01:00
Sunglocto 9593e7c041 some lag fixes and begin work on jingle 2026-05-07 09:16:38 +01:00
Sunglocto 82aa2abfbd t 2026-05-03 11:10:15 +01:00
Sunglocto 58c7165ce5 fix avatars 2026-05-02 06:56:08 +01:00
Sunglocto 5bcf0eda0b t 2026-05-01 21:05:14 +01:00
Sunglocto 0bfb140dc7 Fix lag issues 2026-04-30 14:55:17 +01:00
Sunglocto 7b63799f0b Add extra fields to vCard and format code 2026-04-28 13:08:16 +01:00
Sunglocto a97c42323c Do not let ebassi see this code 2026-04-28 12:58:00 +01:00
Sunglocto fc0ed5ac2c somehow sunglocto returned 2026-04-26 10:40:13 +01:00
Sunglocto 69994d9856 remove base64 encoding/decoding which was not needed for embedding assets 2026-04-18 11:09:59 +01:00
Sunglocto 843687ff2b add throughput, format code, and begin to add MUC preview window 2026-04-18 10:29:07 +01:00
Sunglocto 7416aa37e0 Merge branch 'master' of https://forge.sunglocto.net/sunglocto/lambda 2026-04-06 11:05:49 +01:00
Sunglocto ce83000e0c i forgor to commit sorry 2026-04-06 11:04:53 +01:00
Sunglocto 359e8ed63e 'I like small icons, the big ones weird me out' 2026-03-17 19:04:43 +00:00
Sunglocto 3b9df94cf6 add CONTRIBUTING.md 2026-03-17 19:02:52 +00:00
Sunglocto 634f451595 Merge branch 'master' of https://forge.sunglocto.net/sunglocto/lambda 2026-03-17 18:56:02 +00:00
Sunglocto 00d7945f70 add kick png (not initialised yet) 2026-03-17 18:53:08 +00:00
Sunglocto 60d6a287e5 oops 2026-03-15 16:14:27 +00:00
Sunglocto d5981b7475 icl i forgot i had this file 2026-03-15 09:58:27 +00:00
Sunglocto 523722bae6 Format code 2026-03-15 09:57:08 +00:00
Sunglocto 71e6a58fbd ban, kick and change role&affil menu, status icons in muc, blocking avatars that are invalid so we dont fetch them over and over again 2026-03-15 09:55:26 +00:00
Sunglocto a7e90e4ae5 fix avatars in rc menu 2026-03-12 16:17:29 +00:00
Sunglocto 654ab8b618 add some icons and only store members by resource 2026-03-12 16:09:22 +00:00
Sunglocto 7a201808e3 format code & add additional assets 2026-03-10 16:48:10 +00:00
Sunglocto 77e4e444d4 Attention and experimental mentions impl 2026-03-10 16:35:56 +00:00
Sunglocto bf1685a382 MODS 2026-02-28 16:24:37 +00:00
Sunglocto 0ac43946b1 this commit was sponsored by RAID SHADOW LEGENDS 2026-02-22 08:16:14 +00:00
Sunglocto 15ff7a20db prevent loading svg and webp if on netbsd (thanks gtk) 2026-02-20 09:01:40 +00:00
Sunglocto 1dd3f09fed ping graph 2026-02-20 06:28:31 +00:00
Sunglocto 87bdbc440a i'll do as much, for my true love, as any young girl may 2026-02-19 14:30:37 +00:00
Sunglocto 62b5a9db72 cold blows the wind over my true love, cold blows the drops of rain 2026-02-19 14:30:04 +00:00
Sunglocto 39156af48a format code, add confirmation to destroy muc, implement some disconnect logic 2026-02-19 11:28:18 +00:00
Sunglocto 3f40d3da29 stat bar 2026-02-17 09:27:46 +00:00
Sunglocto a7a49f7441 format code 2026-02-16 09:54:37 +00:00
Sunglocto e026e777f6 BOOKMARKS! BOOKMARKS! WE GOT BOOKMARKS PEOPLE 2026-02-16 09:52:25 +00:00
Sunglocto 09a809c102 add Destroy room button, show error notification on presence error and show disabled lambda icon when not focused on any chat 2026-02-15 13:08:52 +00:00
Sunglocto 29ef37e237 Format code, remove use of Mellium JID parser, and add indicator for messages originating from WebXDC apps 2026-02-14 22:38:32 +00:00
Sunglocto 713cb24508 Add hat icon, change some CSS and remove all reply support 2026-02-08 09:44:45 +00:00
Sunglocto 589101c292 add info to readme 2026-02-04 19:29:56 +00:00
Sunglocto f807565cb2 Add nickname fallback for rooms that don't have XEP-0421 2026-02-04 17:57:24 +00:00
Sunglocto 6626d35920 fix some crashes and debug smtn 2026-02-04 10:12:49 +00:00
Sunglocto 5c76729a6b Attempt to fix duplicated user tabs 2026-02-03 10:38:41 +00:00
Sunglocto c260b8b231 add more support for other message types 2026-02-03 10:07:33 +00:00
Sunglocto 971147dcb8 add icon 2026-02-02 18:57:11 +00:00
Sunglocto 777df725b6 Add affiliation medals 2026-02-02 13:23:08 +00:00
Sunglocto 6cb8771994 Sensible room joining flow 2026-02-01 19:22:43 +00:00
Sunglocto ac013e7969 right-click menus alongside other changes 2026-02-01 18:16:55 +00:00
Sunglocto 067a74e157 add forgotten file 2026-02-01 14:03:31 +00:00
Sunglocto 1dcd55d5ff remove some occurences of mellium jid lib and try to add experimental affiliation displays 2026-02-01 13:49:30 +00:00
Sunglocto e87369912d sensible size defaults 2026-02-01 09:17:57 +00:00
Sunglocto 63bb323ac3 Merge branch 'master' of https://forge.sunglocto.net/sunglocto/lambda 2026-02-01 09:05:30 +00:00
Sunglocto e7054741a0 seperate signin logic into its own file and have error handling 2026-02-01 09:05:20 +00:00
Sunglocto 70d51aef47 Update README.md -> manually creating configuration is no longer rquired 2026-02-01 09:03:50 +00:00
Sunglocto 519e7bcf25 Merge branch 'master' of https://forge.sunglocto.net/sunglocto/lambda 2026-01-31 23:32:52 +00:00
Sunglocto 4d69d95c88 custom resource 2026-01-31 23:32:26 +00:00
Sunglocto c0e330ea22 Merge pull request 'One character patch to allow building with Go 1.25.5' (#1) from Hydrogen/lambda:master into master
Reviewed-on: sunglocto/lambda#1
2026-01-31 23:32:04 +00:00
275 changed files with 21557 additions and 719 deletions
+1
View File
@@ -0,0 +1 @@
im gonna make my own xmpp client with blackjack and hookers
+1
View File
@@ -0,0 +1 @@
i farted
+15
View File
@@ -0,0 +1,15 @@
# Contributing
As you might have gathered, this Gitea instance does not allow registrations. If you want to have an account on this instance in order to contribute to this project, you must contact me for an account. I am available on:
- XMPP: `x@sunglocto.net`
- Matrix: `@x:sunglocto.net`
- E-Mail: sunglocto <img width=16px height=16px src="https://sunglocto.net/icons/email.gif"/> protonmail.com
For actually submitting your patches, you can just fork this repo and submit a pull request. I currently have no contribution policy that you have to follow however if you just use common sense you should be good.
## AI contributions
Obviously vibe-coded or fully AI-generated contributions will be immediately rejected. This is in order to ensure the stability of the project and decrease the chance of significant bugs or vulnerabilities.
AI contributions that you have reviewed, edited and **ensured that they compile, run and work successfully** are acceptable. AI is a tool, and like any other tools, can be used for good if used in moderation.
+8 -9
View File
@@ -1,12 +1,11 @@
# lambda
In order to run this program you must have a file named `lambda.toml` that specifies your config.
Here is an example:
an XMPP client
```toml
Server = "example.com:5222"
Username = "user@example.com"
Password = "123456789"
Insecure = false
Nick = "User"
```
Experimental XMPP client written in Go, with the GTK4 UI toolkit and the Fluux IO XMPP libraries.
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://github.com/markjames/famfamfam-silk-icons](https://github.com/markjames/famfamfam-silk-icons) and the [Haiku project](https://www.haiku-os.org/)
pepper & carrot default avatar is from [Pepper&Carrot](https://peppercarrot.com) - created by David Revoy, licensed under Creative Commons Attribution 4.0. Change made: cropped and made black & white
+1 -4
View File
@@ -1,7 +1,4 @@
# TODO
- XEP-0393: Message Styling 0%
- XEP-0402: PEP Native Bookmarks 0%
- XEP-0066: Out of Band Data partial
- XEP-0461: Message Replies partial
- XEP-0461: Message Replies 0%
- XEP-0444: Message Reactions partial
+306
View File
@@ -0,0 +1,306 @@
package main
import (
_ "embed"
"github.com/diamondburned/gotk4/pkg/gdk/v4"
"github.com/diamondburned/gotk4/pkg/gdkpixbuf/v2"
"sync"
)
// If you want to change the default profile picture used when Identicons are disabled, you can change the below line to an image in the repository and recompile Lambda.
//go:embed debug_psi.png
var defaultAvatarBytes []byte
//go:embed failed_load.png
var failedBytes []byte
//go:embed assets/owner.png
var ownerMedalBytes []byte
//go:embed assets/admin.png
var adminMedalBytes []byte
//go:embed assets/member.png
var memberMedalBytes []byte
//go:embed assets/noaffiliation.png
var noneMedalBytes []byte
//go:embed assets/outcast.png
var outcastMedalBytes []byte
//go:embed assets/cancel.png
var cancelBytes []byte
//go:embed assets/status_away.png
var sABytes []byte
//go:embed assets/status_busy.png
var sBBytes []byte
//go:embed assets/status_chatty.png
var sCBytes []byte
//go:embed assets/status_online.png
var sOBytes []byte
//go:embed assets/status_xa.png
var xaBytes []byte
//go:embed assets/tag.png
var tagBytes []byte
//go:embed assets/lambda-disabled.png
var logoDisabledBytes []byte
//go:embed assets/icon.png
var logoBytes []byte
//go:embed assets/group.png
var groupBytes []byte
//go:embed assets/door_in.png
var doorInBytes []byte
//go:embed assets/door_out.png
var doorOutBytes []byte
//go:embed assets/large_group.png
var largeGroupBytes []byte
//go:embed assets/world.png
var worldBytes []byte
//go:embed assets/disconnect.png
var disconnectBytes []byte
//go:embed assets/chart_bar.png
var barBytes []byte
//go:embed assets/chart_bar_laggy.png
var barLaggyBytes []byte
//go:embed assets/ok.png
var okBytes []byte
//go:embed assets/hourglass.png
var hourglassBytes []byte
//go:embed assets/connect_tls.png
var connectBytes []byte
//go:embed assets/comment.png
var commentBytes []byte
//go:embed assets/information.png
var informationBytes []byte
//go:embed assets/car.png
var carBytes []byte
//go:embed assets/car_high.png
var carHighBytes []byte
// muc icons
//go:embed assets/muc_open.png
var mucOpenBytes []byte
//go:embed assets/muc_membersonly.png
var mucMembersOnlyBytes []byte
//go:embed assets/muc_passwordprotected.png
var mucPasswordProtectedBytes []byte
//go:embed assets/muc_unsecured.png
var mucUnsecuredBytes []byte
//go:embed assets/muc_hidden.png
var mucHiddenBytes []byte
//go:embed assets/muc_public.png
var mucPublicBytes []byte
//go:embed assets/muc_unmoderated.png
var mucUnmoderatedBytes []byte
//go:embed assets/muc_moderated.png
var mucModeratedBytes []byte
//go:embed assets/muc_nonanonymous.png
var mucNonAnonymousBytes []byte
//go:embed assets/muc_semianonymous.png
var mucSemiAnonymousBytes []byte
//go:embed assets/muc_persistent.png
var mucPersistentBytes []byte
//go:embed assets/muc_temporary.png
var mucTemporaryBytes []byte
//go:embed assets/moderate.png
var moderateBytes []byte
//go:embed assets/jabber.png
var jabberBytes []byte
//go:embed assets/fail.png
var failBytes []byte
//go:embed assets/please_wait.gif
var pleaseWaitBytes []byte
//go:embed assets/update.png
var updateBytes []byte
//go:embed assets/solar.png
var solarBytes []byte
//go:embed assets/timeline_marker.png
var timelineMarkerBytes []byte
//go:embed assets/cap.png
var capIconBytes []byte
// client icons
//go:embed assets/client_icons/monocles.png
var monoclesCapBytes []byte
//go:embed assets/client_icons/gajim.png
var gajimCapBytes []byte
//go:embed assets/client_icons/conversations.png
var conversationsCapBytes []byte
//go:embed assets/client_icons/dino.png
var dinoCapBytes []byte
//go:embed assets/client_icons/blabber.png
var blabberCapBytes []byte
//go:embed assets/client_icons/profanity.png
var profanityCapBytes []byte
//go:embed assets/client_icons/poezio.png
var poezioCapBytes []byte
//go:embed assets/client_icons/mcabber.png
var mcabberCapBytes []byte
//go:embed assets/client_icons/converse.png
var converseJSCapBytes []byte
//go:embed assets/client_icons/pidgin.png
var pidginCapBytes []byte
//go:embed assets/client_icons/anotherim.png
var anotherImCapBytes []byte
//go:embed assets/client_icons/movim.png
var movimCapBytes []byte
//go:embed assets/client_icons/yaxim.png
var yaximCapBytes []byte
//go:embed assets/client_icons/psi.png
var psiCapBytes []byte
var clientAssets sync.Map
func loadAsset(key string, data []byte) {
loader := gdkpixbuf.NewPixbufLoader()
loader.Write(data)
loader.Close()
clientAssets.Store(key, gdk.NewTextureForPixbuf(loader.Pixbuf()))
}
func clientAssetsLoad(key string) gdk.Paintabler {
dat, ok := clientAssets.Load(key)
if !ok {
return nil
}
paintable, ok := dat.(gdk.Paintabler)
if !ok {
return nil
}
return paintable
}
func init() {
for key, data := range map[string][]byte{
"logo": logoBytes,
"DefaultAvatar": defaultAvatarBytes,
"FailedAvatar": failedBytes,
"owner": ownerMedalBytes,
"admin": adminMedalBytes,
"member": memberMedalBytes,
"none": noneMedalBytes,
"outcast": outcastMedalBytes,
"cancel": cancelBytes,
"tag": tagBytes,
"disabled_logo": logoDisabledBytes,
"group": groupBytes,
"door_in": doorInBytes,
"door_out": doorOutBytes,
"large_group": largeGroupBytes,
"world": worldBytes,
"disconnect": disconnectBytes,
"chart_bar": barBytes,
"chart_bar_laggy": barLaggyBytes,
"ok": okBytes,
"hourglass": hourglassBytes,
"connect": connectBytes,
"comment": commentBytes,
"information": informationBytes,
"status_away": sABytes,
"status_dnd": sBBytes,
"status_chat": sCBytes,
"status_xa": xaBytes,
"status_": sOBytes,
"car": carBytes,
"car_high": carHighBytes,
"muc_open": mucOpenBytes,
"muc_membersonly": mucMembersOnlyBytes,
"muc_passwordprotected": mucPasswordProtectedBytes,
"muc_unsecured": mucUnsecuredBytes,
"muc_hidden": mucHiddenBytes,
"muc_public": mucPublicBytes,
"muc_unmoderated": mucUnmoderatedBytes,
"muc_moderated": mucModeratedBytes,
"muc_nonanonymous": mucNonAnonymousBytes,
"muc_semianonymous": mucSemiAnonymousBytes,
"muc_persistent": mucPersistentBytes,
"muc_temporary": mucTemporaryBytes,
"moderate": moderateBytes,
"jabber": jabberBytes,
"fail": failBytes,
"please_wait": pleaseWaitBytes,
"update": updateBytes,
"solar": solarBytes,
"timeline_marker": timelineMarkerBytes,
"cap": capIconBytes,
"https://monocles.eu": monoclesCapBytes,
"https://gajim.org": gajimCapBytes,
"http://conversations.im": conversationsCapBytes,
"https://dino.im": dinoCapBytes,
"http://blabber.im": blabberCapBytes,
"http://profanity-im.github.io": profanityCapBytes,
"https://poez.io": poezioCapBytes,
"http://mcabber.com/caps": mcabberCapBytes,
"https://conversejs.org": converseJSCapBytes,
"http://pidgin.im/": pidginCapBytes,
"https://dev.narayana.im/narayana/Conversations-Classic": anotherImCapBytes,
"https://movim.eu/": movimCapBytes,
"https://yaxim.org/": yaximCapBytes,
"https://psi-im.org": psiCapBytes,
} {
loadAsset(key, data)
}
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 600 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 762 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 226 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 607 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 287 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 671 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 641 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 434 B

+1
View File
@@ -0,0 +1 @@
All client assets are owned by their respective owners
Binary file not shown.

After

Width:  |  Height:  |  Size: 783 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 588 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 796 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 693 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 643 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 753 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 744 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 264 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 778 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 730 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 793 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 593 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 935 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 970 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 508 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 612 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 806 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 622 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 924 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 882 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 903 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 591 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 460 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 538 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 584 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 543 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 794 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 722 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 910 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 327 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 923 B

+55 -26
View File
@@ -5,6 +5,7 @@ package main
import (
"crypto/sha256"
"errors"
"fmt"
"github.com/diamondburned/gotk4/pkg/gdk/v4"
"github.com/diamondburned/gotk4/pkg/gtk/v4"
@@ -13,10 +14,17 @@ import (
"net/http"
"os"
"path/filepath"
"sync"
)
// 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
// var invalidImages = make(map[string]bool)
var invalidImages sync.Map
func ensureCache() (string, error) {
cachePath := configdir.LocalCache("lambda-im")
@@ -28,49 +36,70 @@ func ensureCache() (string, error) {
return cachePath, nil
}
func getTexture(path string) gdk.Paintabler {
if tex, exists := textureCache[path]; exists {
return tex
func getTexture(path string) (gdk.Paintabler, error) {
tex, exists := textureCache.Load(path)
if exists {
return tex.(gdk.Paintabler), nil
}
tex, err := gdk.NewTextureFromFilename(path) // load once
if err != nil {
panic(err)
return nil, err
}
textureCache[path] = tex
return tex
textureCache.Store(path, tex)
t, ok := tex.(gdk.Paintabler)
if !ok {
return nil, errors.New("invalid type")
}
return t, nil
}
func newPictureFromPath(path string) *gtk.Picture {
tex := getTexture(path)
func newPictureFromPath(path string) (*gtk.Picture, error) {
tex, err := getTexture(path)
if err != nil {
return nil, err
}
img := gtk.NewPictureForPaintable(tex)
return img
return img, nil
}
func newImageFromPath(path string) *gtk.Image {
tex := getTexture(path)
img := gtk.NewImageFromPaintable(tex)
return img
func newImageFromPath(path string) (*gtk.Image, error) {
tex, err := getTexture(path)
if err != nil {
return nil, err
}
return gtk.NewImageFromPaintable(tex), nil
}
func newPictureFromWeb(url string) *gtk.Picture {
func setImageFromPath(path string, i *gtk.Image) error {
tex, err := getTexture(path)
if err != nil {
return err
}
i.SetFromPaintable(tex)
return nil
}
func newPictureFromWeb(url string) (*gtk.Picture, error) {
pa, _ := ensureCache()
// step 1: get a sha256 sum of the URL
sum := fmt.Sprintf("%x", sha256.Sum256([]byte(url)))
p, ok := textureCache[sum]
p, ok := textureCache.Load(sum)
if ok {
return gtk.NewPictureForPaintable(p)
return gtk.NewPictureForPaintable(p.(gdk.Paintabler)), nil
}
// step 2: download it
resp, err := http.Get(url)
if err != nil {
return nil
return nil, err
}
b, err := io.ReadAll(resp.Body)
if err != nil {
return nil
return nil, err
}
fullpath := filepath.Join(pa, sum)
@@ -78,31 +107,31 @@ func newPictureFromWeb(url string) *gtk.Picture {
// step 3: save it
err = os.WriteFile(fullpath, b, 0644)
if err != nil {
return nil
return nil, err
}
return newPictureFromPath(fullpath)
}
func newImageFromWeb(url string) *gtk.Image {
func newImageFromWeb(url string) (*gtk.Image, error) {
pa, _ := ensureCache()
// step 1: get a sha256 sum of the URL
sum := fmt.Sprintf("%x", sha256.Sum256([]byte(url)))
p, ok := textureCache[sum]
p, ok := textureCache.Load(sum)
if ok {
return gtk.NewImageFromPaintable(p)
return gtk.NewImageFromPaintable(p.(gdk.Paintabler)), nil
}
// step 2: download it
resp, err := http.Get(url)
if err != nil {
return nil
return nil, err
}
b, err := io.ReadAll(resp.Body)
if err != nil {
return nil
return nil, err
}
fullpath := filepath.Join(pa, sum)
@@ -110,7 +139,7 @@ func newImageFromWeb(url string) *gtk.Image {
// step 3: save it
err = os.WriteFile(fullpath, b, 0644)
if err != nil {
return nil
return nil, err
}
return newImageFromPath(fullpath)
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Some files were not shown because too many files have changed in this diff Show More