From 7b63799f0b86d2d8c076776302d7bb79c0bc75fe Mon Sep 17 00:00:00 2001 From: sunglocto Date: Tue, 28 Apr 2026 13:08:16 +0100 Subject: [PATCH] Add extra fields to vCard and format code --- assets.go | 105 ++++++++++--------- l18n.go | 279 +++++++++++++++++++++++++------------------------- main.go | 7 +- xmpp-vcard.go | 20 +++- 4 files changed, 211 insertions(+), 200 deletions(-) diff --git a/assets.go b/assets.go index 8e47329..e20202a 100644 --- a/assets.go +++ b/assets.go @@ -138,59 +138,58 @@ var mucTemporaryBytes []byte var moderateBytes []byte func loadAsset(key string, data []byte) { - loader := gdkpixbuf.NewPixbufLoader() - loader.Write(data) - loader.Close() - clientAssets[key] = gdk.NewTextureForPixbuf(loader.Pixbuf()) + loader := gdkpixbuf.NewPixbufLoader() + loader.Write(data) + loader.Close() + clientAssets[key] = gdk.NewTextureForPixbuf(loader.Pixbuf()) } - func init() { - for key, data := range map[string][]byte{ - "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, - } { - loadAsset(key, data) - } -} \ No newline at end of file + for key, data := range map[string][]byte{ + "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, + } { + loadAsset(key, data) + } +} diff --git a/l18n.go b/l18n.go index defbe34..bb3a1dc 100644 --- a/l18n.go +++ b/l18n.go @@ -1,140 +1,139 @@ -package main - -// Default language is en_GB -var loadedLocale = make(map[string]string) - -var enGB = map[string]string{ // British English - // main.go - - "appName": "Lambda", - "cancel": "Cancel", - "submit": "Submit", - "join": "Join", - "send": "Send", - "error": "Error", - "close": "Close", - "userRequested": "User requested", - "configResourceEmptyWarning": "Config resource is empty! Generating a random one", - "attention": "Attention", - "disconnected": "Disconnected: ", - "connecting": "Connecting...", - "milliseconds": "ms", - "KBPerSecond": "KB/s", - "connectedAs": "Connected as ", - "bindedJid": "Binded JID: ", - "usingTLS": "Using TLS: ", - "joinMUCMenu": "Join MUC", - "joinMUCJIDEntry": "MUC JID:", - "joinMUCNickEntry": "Nick:", - "joinMUCDiscoCheck": "Check MUC features before joining", - "joinMUCDiscoCheckTooltip": "If you are creating a MUC through this window then turn this off", - "joinPreviewTitle": "Joining ", - "joinPasswordRequired": "Password required", - "muc_passwordprotected_description": "This MUC is password-protected", - "muc_unsecured_description": "This MUC does not require a password", - "muc_membersonly_description": "Only members can join this MUC", - "muc_open_description": "Anyone can join this MUC", - "muc_moderated_description": "Only members can speak in this MUC", - "muc_unmoderated_description": "Anyone can speak in this MUC", - "muc_nonanonymous_description": "This MUC is non-anonymous, your JID will be visible to other users", - "muc_semianonymous_description": "This MUC is semi-anonymous, only moderators will see your full JID", - "muc_persistent_description": "This MUC is persistent, it will not be deleted when the last user leaves", - "muc_temporary_description": "This MUC is temporary, it will be deleted when the last user leaves", - "muc_public_description": "This MUC can be found in directories and search engines", - "muc_hidden_description": "This MUC is hidden and cannot be found in directories or search engines", - "urn:xmpp:mam_description": "This MUC supports archiving via MAM", - "urn:xmpp:message-moderate_description": "This MUC supports message moderation", - "discoFail": "Failed to get Disco info", - "startDMMenu": "Start DM", - "destroyMUCMenu": "Destroy MUC", - "aboutMenu": "About", - "destroyMUCWarningOne": "Are you sure? This MUC will be gone forever! (a very long time)", - "destroyMUCWarningTwo": "If you wish to continue, type 'I understand'", - "destroyMUCPassword": "I understand", - "destroyMUCActionButton": "Destroy", - "destroyMUCNotOwnerWarning": "You are not an owner of this MUC and thus will most likely not be able to delete it", - "pingBarTooltip": "Ping between you and your XMPP server\nRight-click to see graph", - "pingGraphTitle": "Server latency", - "pingGraphYAxis": "Ping (ms)", - "throughputTooltip": "Throughput of your XMPP connection in KB/s", - "messageEntryPlaceholder": "Say something, what else are you going to do here?", - - // gtk-message.go - - "unsupportedMessage": "Unsupported message.", - "bannedWidget": " has been banned by ", - "readWidget": " has read to this point", - "isTyping": " is typing...", - "whispers": " whispers", - "noBodySet": "No body set", - "affilChange": "'s affiliation has been changed to ", - "linkPreviewWarning": "This link preview was generated by the client sending it and may not be accurate of the actual website content", - - // gtk-helpers.go - - "getPastMessages": "Get past messages...", - "clickForMoreInfo": "Click for more information", - "ban": "Ban", - "kick": "Kick", - "setAffil": "Set affiliation", - "setAffilDescPartOne": "Set ", - "setAffilDescPartTwo": "'s affiliation", - "setRole": "Set role", - "setRoleDescPartOne": "Set ", - "setRoleDescPartTwo": "'s role", - "setRoleWarning": "Important: if you want this to be permanent, set their affiliation instead", - "gettingVersion": "Getting version...", - "connectedWithRole": "Connected with role ", - "affiliatedAs": "Affiliated as ", - "participants": "participant(s)", - "versionQueryEmpty": "Client responded with empty version", - "versionQueryError": "Got error trying to get version", - - // gtk-signin.go - - "SIServerLabel": "Server: ", - "SIUsernameLabel": "Username: ", - "SIPasswordLabel": "Password: ", - "SINicknameLabel": "Nickname: ", - "SIInsecureLabel": "Insecure: (?)", - "SIInsecureLabelTooltip": "Tick this if you need to connect without TLS, usually for connecting to Tor XMPP servers", -} - -var kaGE = map[string]string { // Georgian (Georgia) - -} - -var roRo = map[string]string { // Romanian (Romania) - "appName": "Lambda", - "cancel": "Canselează", - "submit": "A preda", - "join": "Intră", - "send": "Trimite", - "error": "Eroare", - "close": "închide", - "userRequested": "Uzator cerut", - "configResourceEmptyWarning": "Resursa configurată este goala! Creiez unu aleatoriu", - "attention": "Atenție", - "disconnected": "Deconectat", - "connecting": "Conectat", - "bindedJid": "Lipit JID", - "joinMUCMenu": "Intră pe MUC", - "joinMUCJIDEntry": "MUC JID:", - "joinMUCNickEntry": "Poreclă:", - "joinMUCDiscoCheck": "Verifica detalile de MUC înainte sa intri", - "joinMUCDiscoCheckTooltip": "Dacă creiezi un MUC prin această oglindă închido", -} - -var enUS = enGB // American English - - -var locales = map[string]map[string]string { - "en_GB": enGB, - "ka_GE": kaGE, - "en_US": enUS, -} - -// TODO: Load locale according to user configuration -func init() { - loadedLocale = locales["en_GB"] -} +package main + +// Default language is en_GB +var loadedLocale = make(map[string]string) + +var enGB = map[string]string{ // British English + // main.go + + "appName": "Lambda", + "cancel": "Cancel", + "submit": "Submit", + "join": "Join", + "send": "Send", + "error": "Error", + "close": "Close", + "userRequested": "User requested", + "configResourceEmptyWarning": "Config resource is empty! Generating a random one", + "attention": "Attention", + "disconnected": "Disconnected: ", + "connecting": "Connecting...", + "milliseconds": "ms", + "KBPerSecond": "KB/s", + "connectedAs": "Connected as ", + "bindedJid": "Binded JID: ", + "usingTLS": "Using TLS: ", + "joinMUCMenu": "Join MUC", + "joinMUCJIDEntry": "MUC JID:", + "joinMUCNickEntry": "Nick:", + "joinMUCDiscoCheck": "Check MUC features before joining", + "joinMUCDiscoCheckTooltip": "If you are creating a MUC through this window then turn this off", + "joinPreviewTitle": "Joining ", + "joinPasswordRequired": "Password required", + "muc_passwordprotected_description": "This MUC is password-protected", + "muc_unsecured_description": "This MUC does not require a password", + "muc_membersonly_description": "Only members can join this MUC", + "muc_open_description": "Anyone can join this MUC", + "muc_moderated_description": "Only members can speak in this MUC", + "muc_unmoderated_description": "Anyone can speak in this MUC", + "muc_nonanonymous_description": "This MUC is non-anonymous, your JID will be visible to other users", + "muc_semianonymous_description": "This MUC is semi-anonymous, only moderators will see your full JID", + "muc_persistent_description": "This MUC is persistent, it will not be deleted when the last user leaves", + "muc_temporary_description": "This MUC is temporary, it will be deleted when the last user leaves", + "muc_public_description": "This MUC can be found in directories and search engines", + "muc_hidden_description": "This MUC is hidden and cannot be found in directories or search engines", + "urn:xmpp:mam_description": "This MUC supports archiving via MAM", + "urn:xmpp:message-moderate_description": "This MUC supports message moderation", + "discoFail": "Failed to get Disco info", + "startDMMenu": "Start DM", + "destroyMUCMenu": "Destroy MUC", + "aboutMenu": "About", + "destroyMUCWarningOne": "Are you sure? This MUC will be gone forever! (a very long time)", + "destroyMUCWarningTwo": "If you wish to continue, type 'I understand'", + "destroyMUCPassword": "I understand", + "destroyMUCActionButton": "Destroy", + "destroyMUCNotOwnerWarning": "You are not an owner of this MUC and thus will most likely not be able to delete it", + "pingBarTooltip": "Ping between you and your XMPP server\nRight-click to see graph", + "pingGraphTitle": "Server latency", + "pingGraphYAxis": "Ping (ms)", + "throughputTooltip": "Throughput of your XMPP connection in KB/s", + "messageEntryPlaceholder": "Say something, what else are you going to do here?", + + // gtk-message.go + + "unsupportedMessage": "Unsupported message.", + "bannedWidget": " has been banned by ", + "readWidget": " has read to this point", + "isTyping": " is typing...", + "whispers": " whispers", + "noBodySet": "No body set", + "affilChange": "'s affiliation has been changed to ", + "linkPreviewWarning": "This link preview was generated by the client sending it and may not be accurate of the actual website content", + + // gtk-helpers.go + + "getPastMessages": "Get past messages...", + "clickForMoreInfo": "Click for more information", + "ban": "Ban", + "kick": "Kick", + "setAffil": "Set affiliation", + "setAffilDescPartOne": "Set ", + "setAffilDescPartTwo": "'s affiliation", + "setRole": "Set role", + "setRoleDescPartOne": "Set ", + "setRoleDescPartTwo": "'s role", + "setRoleWarning": "Important: if you want this to be permanent, set their affiliation instead", + "gettingVersion": "Getting version...", + "connectedWithRole": "Connected with role ", + "affiliatedAs": "Affiliated as ", + "participants": "participant(s)", + "versionQueryEmpty": "Client responded with empty version", + "versionQueryError": "Got error trying to get version", + + // gtk-signin.go + + "SIServerLabel": "Server: ", + "SIUsernameLabel": "Username: ", + "SIPasswordLabel": "Password: ", + "SINicknameLabel": "Nickname: ", + "SIInsecureLabel": "Insecure: (?)", + "SIInsecureLabelTooltip": "Tick this if you need to connect without TLS, usually for connecting to Tor XMPP servers", +} + +var kaGE = map[string]string{ // Georgian (Georgia) + +} + +var roRo = map[string]string{ // Romanian (Romania) + "appName": "Lambda", + "cancel": "Canselează", + "submit": "A preda", + "join": "Intră", + "send": "Trimite", + "error": "Eroare", + "close": "închide", + "userRequested": "Uzator cerut", + "configResourceEmptyWarning": "Resursa configurată este goala! Creiez unu aleatoriu", + "attention": "Atenție", + "disconnected": "Deconectat", + "connecting": "Conectat", + "bindedJid": "Lipit JID", + "joinMUCMenu": "Intră pe MUC", + "joinMUCJIDEntry": "MUC JID:", + "joinMUCNickEntry": "Poreclă:", + "joinMUCDiscoCheck": "Verifica detalile de MUC înainte sa intri", + "joinMUCDiscoCheckTooltip": "Dacă creiezi un MUC prin această oglindă închido", +} + +var enUS = enGB // American English + +var locales = map[string]map[string]string{ + "en_GB": enGB, + "ka_GE": kaGE, + "en_US": enUS, +} + +// TODO: Load locale according to user configuration +func init() { + loadedLocale = locales["en_GB"] +} diff --git a/main.go b/main.go index a36ffa7..7405ab5 100644 --- a/main.go +++ b/main.go @@ -880,7 +880,6 @@ func activate(app *gtk.Application) { warning_box.Append(box) } - for _, feature := range features { switch feature.Var { case "muc_passwordprotected": @@ -893,7 +892,7 @@ func activate(app *gtk.Application) { case "muc_open": addFeature("muc_open", loadedLocale["muc_open_description"]) case "muc_moderated": - addFeature("muc_moderated", loadedLocale["muc_moderated_description"]) + addFeature("muc_moderated", loadedLocale["muc_moderated_description"]) case "muc_unmoderated": addFeature("muc_unmoderated", loadedLocale["muc_unmoderated_description"]) case "muc_nonanonymous": @@ -913,8 +912,8 @@ func activate(app *gtk.Application) { case "urn:xmpp:message-moderate:0": addFeature("moderate", loadedLocale["urn:xmpp:message-moderate_description"]) /* - default: - addFeature("comment", feature.Var) + default: + addFeature("comment", feature.Var) */ } } diff --git a/xmpp-vcard.go b/xmpp-vcard.go index d8abd38..34ae7b4 100644 --- a/xmpp-vcard.go +++ b/xmpp-vcard.go @@ -9,9 +9,23 @@ import ( ) type VCard struct { - XMLName xml.Name `xml:"vcard-temp vCard"` - Photo Photo `xml:"PHOTO"` - ResultSet *stanza.ResultSet `xml:"set,omitempty"` + XMLName xml.Name `xml:"vcard-temp vCard"` + FirstName string `xml:"FN"` + LastName string `xml:"N>FAMILY"` + GivenName string `xml:"N>GIVEN"` + MiddleName string `xml:"N>MIDDLE"` + Nickname string `xml:"NICKNAME"` + URI string `xml:"URL"` + Birthday string `xml:"BDAY"` + OrgName string `xml:"ORG>ORGNAME"` + OrgUnit string `xml:"ORG>ORGUNIT"` + Title string `xml:"TITLE"` + Role string `xml:"ROLE"` + Description string `xml:"DESC"` + Jid string `xml:"JABBERID"` + Photo Photo `xml:"PHOTO"` + Email string `xml:"EMAIL>USERID"` + ResultSet *stanza.ResultSet `xml:"set,omitempty"` } type VCardUpdate struct {