Compare commits

...
73 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
269 changed files with 21313 additions and 735 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.
+9 -1
View File
@@ -1,3 +1,11 @@
# lambda
an XMPP client
an XMPP client
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: 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

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

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 460 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

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

+38
View File
@@ -0,0 +1,38 @@
name: Run tests
on:
pull_request:
paths:
- '**.go'
- 'go.*'
- .github/workflows/test.yaml
push:
paths:
- '**.go'
- 'go.*'
- .github/workflows/test.yaml
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.25
uses: actions/setup-go@v1
with:
go-version: 1.25
id: go
- uses: actions/checkout@v1
- name: Run tests
run: |
go test ./... -v -race -coverprofile cover.out -covermode=atomic
- name: Convert coverage to lcov
uses: jandelgado/gcov2lcov-action@v1
with:
infile: cover.out
outfile: coverage.lcov
- name: Coveralls
uses: coverallsapp/github-action@v1
with:
github-token: ${{ secrets.github_token }}
path-to-lcov: coverage.lcov
+36
View File
@@ -0,0 +1,36 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe
*.test
*.prof
coverage.out
coverage.txt
.idea/
*.iml
.DS_Store
# Do not commit codeship key
codeship.aes
codeship.env
priv/
+58
View File
@@ -0,0 +1,58 @@
# Fluux XMPP Changelog
## v0.5.0
### Changes
- Added support for XEP-0198 (Stream management)
- Added message queue : when using "SendX" methods on a client, messages are also stored in a queue. When requesting
acks from the server, sent messages will be discarded, and unsent ones will be sent again. (see https://xmpp.org/extensions/xep-0198.html#acking)
- Added support for stanza_errors (see https://xmpp.org/rfcs/rfc3920.html#def C.2. Stream error namespace and https://xmpp.org/rfcs/rfc6120.html#schemas-streamerror)
- Added separate hooks for connection and reconnection on the client. One can now specify different actions to get triggered on client connect
and reconnect, at client init time.
- Client state update is now thread safe
- Changed the Config struct to use pointer semantics
- Tests
- Refactoring, including removing some Fprintf statements in favor of Marshal + Write and using structs from the library
instead of strings
## v0.4.0
### Changes
- Added support for XEP-0060 (PubSub)
(no support for 6.5.4 Returning Some Items yet as it needs XEP-0059, Result Sets)
- Added support for XEP-0050 (Commands)
- Added support for XEP-0004 (Forms)
- Updated the client example with a TUI
- Make keepalive interval configurable #134
- Fix updating of EventManager.CurrentState #136
- Added callbacks for error management in Component and Client. Users must now provide a callback function when using NewClient/Component.
- Moved JID from xmpp package to stanza package
## v0.3.0
### Changes
- Update requirements to go1.13
- Add a websocket transport
- Add Client.SendIQ method
- Add IQ result routes to the Router
- Fix SIGSEGV in xmpp_component (#126)
- Add tests for Component and code style fixes
## v0.2.0
### Changes
- XMPP Over Websocket support
- Add support for getting IQ responses to client IQ queries (synchronously or asynchronously, passing an handler
function).
- Implement X-OAUTH2 authentication method. You can read more details here:
[Understanding ejabberd OAuth Support & Roadmap: Step 4](https://blog.process-one.net/understanding-ejabberd-oauth-support-roadmap/)
- Fix issues in the stanza builder when trying to add text inside and XMPP node.
- Fix issues with unescaped % characters in XMPP payload.
### Code migration guide
TODO

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