Add extra fields to vCard and format code

This commit is contained in:
2026-04-28 13:08:16 +01:00
parent a97c42323c
commit 7b63799f0b
4 changed files with 211 additions and 200 deletions
+52 -53
View File
@@ -138,59 +138,58 @@ var mucTemporaryBytes []byte
var moderateBytes []byte var moderateBytes []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)
loader.Close() loader.Close()
clientAssets[key] = gdk.NewTextureForPixbuf(loader.Pixbuf()) clientAssets[key] = gdk.NewTextureForPixbuf(loader.Pixbuf())
} }
func init() { func init() {
for key, data := range map[string][]byte{ for key, data := range map[string][]byte{
"DefaultAvatar": defaultAvatarBytes, "DefaultAvatar": defaultAvatarBytes,
"FailedAvatar": failedBytes, "FailedAvatar": failedBytes,
"owner": ownerMedalBytes, "owner": ownerMedalBytes,
"admin": adminMedalBytes, "admin": adminMedalBytes,
"member": memberMedalBytes, "member": memberMedalBytes,
"none": noneMedalBytes, "none": noneMedalBytes,
"outcast": outcastMedalBytes, "outcast": outcastMedalBytes,
"cancel": cancelBytes, "cancel": cancelBytes,
"tag": tagBytes, "tag": tagBytes,
"disabled_logo": logoDisabledBytes, "disabled_logo": logoDisabledBytes,
"group": groupBytes, "group": groupBytes,
"door_in": doorInBytes, "door_in": doorInBytes,
"door_out": doorOutBytes, "door_out": doorOutBytes,
"large_group": largeGroupBytes, "large_group": largeGroupBytes,
"world": worldBytes, "world": worldBytes,
"disconnect": disconnectBytes, "disconnect": disconnectBytes,
"chart_bar": barBytes, "chart_bar": barBytes,
"chart_bar_laggy": barLaggyBytes, "chart_bar_laggy": barLaggyBytes,
"ok": okBytes, "ok": okBytes,
"hourglass": hourglassBytes, "hourglass": hourglassBytes,
"connect": connectBytes, "connect": connectBytes,
"comment": commentBytes, "comment": commentBytes,
"information": informationBytes, "information": informationBytes,
"status_away": sABytes, "status_away": sABytes,
"status_dnd": sBBytes, "status_dnd": sBBytes,
"status_chat": sCBytes, "status_chat": sCBytes,
"status_xa": xaBytes, "status_xa": xaBytes,
"status_": sOBytes, "status_": sOBytes,
"car": carBytes, "car": carBytes,
"car_high": carHighBytes, "car_high": carHighBytes,
"muc_open": mucOpenBytes, "muc_open": mucOpenBytes,
"muc_membersonly": mucMembersOnlyBytes, "muc_membersonly": mucMembersOnlyBytes,
"muc_passwordprotected": mucPasswordProtectedBytes, "muc_passwordprotected": mucPasswordProtectedBytes,
"muc_unsecured": mucUnsecuredBytes, "muc_unsecured": mucUnsecuredBytes,
"muc_hidden": mucHiddenBytes, "muc_hidden": mucHiddenBytes,
"muc_public": mucPublicBytes, "muc_public": mucPublicBytes,
"muc_unmoderated": mucUnmoderatedBytes, "muc_unmoderated": mucUnmoderatedBytes,
"muc_moderated": mucModeratedBytes, "muc_moderated": mucModeratedBytes,
"muc_nonanonymous": mucNonAnonymousBytes, "muc_nonanonymous": mucNonAnonymousBytes,
"muc_semianonymous": mucSemiAnonymousBytes, "muc_semianonymous": mucSemiAnonymousBytes,
"muc_persistent": mucPersistentBytes, "muc_persistent": mucPersistentBytes,
"muc_temporary": mucTemporaryBytes, "muc_temporary": mucTemporaryBytes,
"moderate": moderateBytes, "moderate": moderateBytes,
} { } {
loadAsset(key, data) loadAsset(key, data)
} }
} }
+139 -140
View File
@@ -1,140 +1,139 @@
package main package main
// Default language is en_GB // Default language is en_GB
var loadedLocale = make(map[string]string) var loadedLocale = make(map[string]string)
var enGB = map[string]string{ // British English var enGB = map[string]string{ // British English
// main.go // main.go
"appName": "Lambda", "appName": "Lambda",
"cancel": "Cancel", "cancel": "Cancel",
"submit": "Submit", "submit": "Submit",
"join": "Join", "join": "Join",
"send": "Send", "send": "Send",
"error": "Error", "error": "Error",
"close": "Close", "close": "Close",
"userRequested": "User requested", "userRequested": "User requested",
"configResourceEmptyWarning": "Config resource is empty! Generating a random one", "configResourceEmptyWarning": "Config resource is empty! Generating a random one",
"attention": "Attention", "attention": "Attention",
"disconnected": "Disconnected: ", "disconnected": "Disconnected: ",
"connecting": "Connecting...", "connecting": "Connecting...",
"milliseconds": "ms", "milliseconds": "ms",
"KBPerSecond": "KB/s", "KBPerSecond": "KB/s",
"connectedAs": "Connected as ", "connectedAs": "Connected as ",
"bindedJid": "Binded JID: ", "bindedJid": "Binded JID: ",
"usingTLS": "Using TLS: ", "usingTLS": "Using TLS: ",
"joinMUCMenu": "Join MUC", "joinMUCMenu": "Join MUC",
"joinMUCJIDEntry": "MUC JID:", "joinMUCJIDEntry": "MUC JID:",
"joinMUCNickEntry": "Nick:", "joinMUCNickEntry": "Nick:",
"joinMUCDiscoCheck": "Check MUC features before joining", "joinMUCDiscoCheck": "Check MUC features before joining",
"joinMUCDiscoCheckTooltip": "If you are creating a MUC through this window then turn this off", "joinMUCDiscoCheckTooltip": "If you are creating a MUC through this window then turn this off",
"joinPreviewTitle": "Joining ", "joinPreviewTitle": "Joining ",
"joinPasswordRequired": "Password required", "joinPasswordRequired": "Password required",
"muc_passwordprotected_description": "This MUC is password-protected", "muc_passwordprotected_description": "This MUC is password-protected",
"muc_unsecured_description": "This MUC does not require a password", "muc_unsecured_description": "This MUC does not require a password",
"muc_membersonly_description": "Only members can join this MUC", "muc_membersonly_description": "Only members can join this MUC",
"muc_open_description": "Anyone can join this MUC", "muc_open_description": "Anyone can join this MUC",
"muc_moderated_description": "Only members can speak in this MUC", "muc_moderated_description": "Only members can speak in this MUC",
"muc_unmoderated_description": "Anyone 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_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_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_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_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_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", "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:mam_description": "This MUC supports archiving via MAM",
"urn:xmpp:message-moderate_description": "This MUC supports message moderation", "urn:xmpp:message-moderate_description": "This MUC supports message moderation",
"discoFail": "Failed to get Disco info", "discoFail": "Failed to get Disco info",
"startDMMenu": "Start DM", "startDMMenu": "Start DM",
"destroyMUCMenu": "Destroy MUC", "destroyMUCMenu": "Destroy MUC",
"aboutMenu": "About", "aboutMenu": "About",
"destroyMUCWarningOne": "Are you sure? This MUC will be gone forever! (a very long time)", "destroyMUCWarningOne": "Are you sure? This MUC will be gone forever! (a very long time)",
"destroyMUCWarningTwo": "If you wish to continue, type 'I understand'", "destroyMUCWarningTwo": "If you wish to continue, type 'I understand'",
"destroyMUCPassword": "I understand", "destroyMUCPassword": "I understand",
"destroyMUCActionButton": "Destroy", "destroyMUCActionButton": "Destroy",
"destroyMUCNotOwnerWarning": "You are not an owner of this MUC and thus will most likely not be able to delete it", "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", "pingBarTooltip": "Ping between you and your XMPP server\nRight-click to see graph",
"pingGraphTitle": "Server latency", "pingGraphTitle": "Server latency",
"pingGraphYAxis": "Ping (ms)", "pingGraphYAxis": "Ping (ms)",
"throughputTooltip": "Throughput of your XMPP connection in KB/s", "throughputTooltip": "Throughput of your XMPP connection in KB/s",
"messageEntryPlaceholder": "Say something, what else are you going to do here?", "messageEntryPlaceholder": "Say something, what else are you going to do here?",
// gtk-message.go // gtk-message.go
"unsupportedMessage": "Unsupported message.", "unsupportedMessage": "Unsupported message.",
"bannedWidget": " has been banned by ", "bannedWidget": " has been banned by ",
"readWidget": " has read to this point", "readWidget": " has read to this point",
"isTyping": " is typing...", "isTyping": " is typing...",
"whispers": " whispers", "whispers": " whispers",
"noBodySet": "No body set", "noBodySet": "No body set",
"affilChange": "'s affiliation has been changed to ", "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", "linkPreviewWarning": "This link preview was generated by the client sending it and may not be accurate of the actual website content",
// gtk-helpers.go // gtk-helpers.go
"getPastMessages": "Get past messages...", "getPastMessages": "Get past messages...",
"clickForMoreInfo": "Click for more information", "clickForMoreInfo": "Click for more information",
"ban": "Ban", "ban": "Ban",
"kick": "Kick", "kick": "Kick",
"setAffil": "Set affiliation", "setAffil": "Set affiliation",
"setAffilDescPartOne": "Set ", "setAffilDescPartOne": "Set ",
"setAffilDescPartTwo": "'s affiliation", "setAffilDescPartTwo": "'s affiliation",
"setRole": "Set role", "setRole": "Set role",
"setRoleDescPartOne": "Set ", "setRoleDescPartOne": "Set ",
"setRoleDescPartTwo": "'s role", "setRoleDescPartTwo": "'s role",
"setRoleWarning": "Important: if you want this to be permanent, set their affiliation instead", "setRoleWarning": "Important: if you want this to be permanent, set their affiliation instead",
"gettingVersion": "Getting version...", "gettingVersion": "Getting version...",
"connectedWithRole": "Connected with role ", "connectedWithRole": "Connected with role ",
"affiliatedAs": "Affiliated as ", "affiliatedAs": "Affiliated as ",
"participants": "participant(s)", "participants": "participant(s)",
"versionQueryEmpty": "Client responded with empty version", "versionQueryEmpty": "Client responded with empty version",
"versionQueryError": "Got error trying to get version", "versionQueryError": "Got error trying to get version",
// gtk-signin.go // gtk-signin.go
"SIServerLabel": "Server: ", "SIServerLabel": "Server: ",
"SIUsernameLabel": "Username: ", "SIUsernameLabel": "Username: ",
"SIPasswordLabel": "Password: ", "SIPasswordLabel": "Password: ",
"SINicknameLabel": "Nickname: ", "SINicknameLabel": "Nickname: ",
"SIInsecureLabel": "Insecure: (?)", "SIInsecureLabel": "Insecure: (?)",
"SIInsecureLabelTooltip": "Tick this if you need to connect without TLS, usually for connecting to Tor XMPP servers", "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 kaGE = map[string]string{ // Georgian (Georgia)
} }
var roRo = map[string]string { // Romanian (Romania) var roRo = map[string]string{ // Romanian (Romania)
"appName": "Lambda", "appName": "Lambda",
"cancel": "Canselează", "cancel": "Canselează",
"submit": "A preda", "submit": "A preda",
"join": "Intră", "join": "Intră",
"send": "Trimite", "send": "Trimite",
"error": "Eroare", "error": "Eroare",
"close": "închide", "close": "închide",
"userRequested": "Uzator cerut", "userRequested": "Uzator cerut",
"configResourceEmptyWarning": "Resursa configurată este goala! Creiez unu aleatoriu", "configResourceEmptyWarning": "Resursa configurată este goala! Creiez unu aleatoriu",
"attention": "Atenție", "attention": "Atenție",
"disconnected": "Deconectat", "disconnected": "Deconectat",
"connecting": "Conectat", "connecting": "Conectat",
"bindedJid": "Lipit JID", "bindedJid": "Lipit JID",
"joinMUCMenu": "Intră pe MUC", "joinMUCMenu": "Intră pe MUC",
"joinMUCJIDEntry": "MUC JID:", "joinMUCJIDEntry": "MUC JID:",
"joinMUCNickEntry": "Poreclă:", "joinMUCNickEntry": "Poreclă:",
"joinMUCDiscoCheck": "Verifica detalile de MUC înainte sa intri", "joinMUCDiscoCheck": "Verifica detalile de MUC înainte sa intri",
"joinMUCDiscoCheckTooltip": "Dacă creiezi un MUC prin această oglindă închido", "joinMUCDiscoCheckTooltip": "Dacă creiezi un MUC prin această oglindă închido",
} }
var enUS = enGB // American English var enUS = enGB // American English
var locales = map[string]map[string]string{
var locales = map[string]map[string]string { "en_GB": enGB,
"en_GB": enGB, "ka_GE": kaGE,
"ka_GE": kaGE, "en_US": enUS,
"en_US": enUS, }
}
// TODO: Load locale according to user configuration
// TODO: Load locale according to user configuration func init() {
func init() { loadedLocale = locales["en_GB"]
loadedLocale = locales["en_GB"] }
}
+3 -4
View File
@@ -880,7 +880,6 @@ func activate(app *gtk.Application) {
warning_box.Append(box) warning_box.Append(box)
} }
for _, feature := range features { for _, feature := range features {
switch feature.Var { switch feature.Var {
case "muc_passwordprotected": case "muc_passwordprotected":
@@ -893,7 +892,7 @@ func activate(app *gtk.Application) {
case "muc_open": case "muc_open":
addFeature("muc_open", loadedLocale["muc_open_description"]) addFeature("muc_open", loadedLocale["muc_open_description"])
case "muc_moderated": case "muc_moderated":
addFeature("muc_moderated", loadedLocale["muc_moderated_description"]) addFeature("muc_moderated", loadedLocale["muc_moderated_description"])
case "muc_unmoderated": case "muc_unmoderated":
addFeature("muc_unmoderated", loadedLocale["muc_unmoderated_description"]) addFeature("muc_unmoderated", loadedLocale["muc_unmoderated_description"])
case "muc_nonanonymous": case "muc_nonanonymous":
@@ -913,8 +912,8 @@ func activate(app *gtk.Application) {
case "urn:xmpp:message-moderate:0": case "urn:xmpp:message-moderate:0":
addFeature("moderate", loadedLocale["urn:xmpp:message-moderate_description"]) addFeature("moderate", loadedLocale["urn:xmpp:message-moderate_description"])
/* /*
default: default:
addFeature("comment", feature.Var) addFeature("comment", feature.Var)
*/ */
} }
} }
+17 -3
View File
@@ -9,9 +9,23 @@ import (
) )
type VCard struct { type VCard struct {
XMLName xml.Name `xml:"vcard-temp vCard"` XMLName xml.Name `xml:"vcard-temp vCard"`
Photo Photo `xml:"PHOTO"` FirstName string `xml:"FN"`
ResultSet *stanza.ResultSet `xml:"set,omitempty"` 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 { type VCardUpdate struct {