From 9dc4dd2ec427da6ddcea82e22b3367a8563420b0 Mon Sep 17 00:00:00 2001 From: Amy Gale Ruth Bowersox Date: Thu, 26 Feb 2026 18:19:40 -0700 Subject: [PATCH] Member Export now done --- docs/MISSINGFUNCS.md | 2 +- exports/vcard_xml.go | 260 ++++++++++++++++++++++--------------------- exports/vcif_xml.go | 24 ++-- exports/viu_xml.go | 18 +-- ui/dialog.go | 7 +- 5 files changed, 159 insertions(+), 152 deletions(-) diff --git a/docs/MISSINGFUNCS.md b/docs/MISSINGFUNCS.md index bd5f3b2..4626b7b 100644 --- a/docs/MISSINGFUNCS.md +++ b/docs/MISSINGFUNCS.md @@ -32,7 +32,7 @@ _(italicized items can be deferred)_ - ~~Community Profile: Invite~~ - _Help link atop page headers_ - _Policy page_ -- Member List: Export +- ~~Member List: Export~~ - ~~HTML reference for post boxes~~ - ~~Posts view:~~ - ~~Find~~ diff --git a/exports/vcard_xml.go b/exports/vcard_xml.go index 2e2e46f..dbb1b7d 100644 --- a/exports/vcard_xml.go +++ b/exports/vcard_xml.go @@ -23,119 +23,128 @@ import ( * https://xmpp.org/extensions/xep-0054.html. */ +// Used to indicate a field which may be present, or not. +type Presence struct{} + +// Specifies that a "present" field is "present." +var Present = &Presence{} + +// The vCard version field. +const VCARD_VERSION = "2.0" + // VCard is the top level vCard structure. type VCard struct { - XMLName xml.Name `xml:"vcard-temp vCard"` // name must be "vCard" in the "vcard-temp" namespace - Version string `xml:"VERSION"` // vCard version number - FullName string `xml:"FN"` // full name - Name VCName `xml:"N"` // broken-up name components - Nickname string `xml:"NICKNAME"` // nickname (not used in Amsterdam) - Photo *VCPhoto `xml:"PHOTO"` // user photo (not used in Amsterdam) - BDay string `xml:"BDAY"` // birthday, ISO 8601 format - Address *[]VCAddress `xml:"ADR"` // address - AddressLabel *[]VCAddressLabel `xml:"LABEL"` // address label - Email *[]VCEmail `xml:"EMAIL"` // E-mail address - Tel *[]VCTelephone `xml:"TEL"` // telephone number - JabberID string `xml:"JABBERID"` // Jabber/XMPP address (user@host) (XMPP extension) (not used in Amsterdam) - Mailer string `xml:"MAILER"` // mailer user agent (not used in Amsterdam) - TZ string `xml:"TZ"` // time zone indicator, ISO 8601 formatted UTC offset - Geolocation *VCGeolocation `xml:"GEO"` // geolocation (not used in Amsterdam) - Title string `xml:"TITLE"` // job title (not used in Amsterdam) - Role string `xml:"ROLE"` // job role (not used in Amsterdam) - Logo *VCLogo `xml:"LOGO"` // organization logo (not used in Amsterdam) - Agent *VCAgent `xml:"AGENT"` // agent for the organization (not used in Amsterdam) - Org *VCOrganization `xml:"ORG"` // organization - Categories *VCCategory `xml:"CATEGORIES"` // categories - Note string `xml:"NOTE"` // text note (not used by Amsterdam) - ProductID string `xml:"PRODID"` // product ID that generated this vCard (not used by Amsterdam) - LastUpdate string `xml:"REV"` // last update to this information, ISO 8601 format - SortString string `xml:"SORT-STRING"` // sort string - Sound *VCSound `xml:"SOUND"` // pronunciation property (not used in Amsterdam) - UID string `xml:"UID"` // unique identifier (not necessarily an Amsterdam UID!) (not used in Amsterdam) - URL string `xml:"URL"` // URL - Class *VCClass `xml:"CLASS"` // privacy classification (not used in Amsterdam) - Key *VCKey `xml:"KEY"` // authentication credential or encryption key (not used in Amsterdam) - Description string `xml:"DESC"` // description string value (XMPP extension) + XMLName xml.Name `xml:"vcard-temp vCard"` // name must be "vCard" in the "vcard-temp" namespace + Version string `xml:"VERSION"` // vCard version number + FullName string `xml:"FN"` // full name + Name VCName `xml:"N"` // broken-up name components + Nickname string `xml:"NICKNAME,omitempty"` // nickname (not used in Amsterdam) + Photo *VCPhoto `xml:"PHOTO,omitempty"` // user photo (not used in Amsterdam) + BDay string `xml:"BDAY,omitempty"` // birthday, ISO 8601 format + Address *[]VCAddress `xml:"ADR,omitempty"` // address + AddressLabel *[]VCAddressLabel `xml:"LABEL,omitempty"` // address label + Email *[]VCEmail `xml:"EMAIL,omitempty"` // E-mail address + Tel *[]VCTelephone `xml:"TEL,omitempty"` // telephone number + JabberID string `xml:"JABBERID,omitempty"` // Jabber/XMPP address (user@host) (XMPP extension) (not used in Amsterdam) + Mailer string `xml:"MAILER,omitempty"` // mailer user agent (not used in Amsterdam) + TZ string `xml:"TZ,omitempty"` // time zone indicator, ISO 8601 formatted UTC offset + Geolocation *VCGeolocation `xml:"GEO,omitempty"` // geolocation (not used in Amsterdam) + Title string `xml:"TITLE,omitempty"` // job title (not used in Amsterdam) + Role string `xml:"ROLE,omitempty"` // job role (not used in Amsterdam) + Logo *VCLogo `xml:"LOGO,omitempty"` // organization logo (not used in Amsterdam) + Agent *VCAgent `xml:"AGENT,omitempty"` // agent for the organization (not used in Amsterdam) + Org *VCOrganization `xml:"ORG,omitempty"` // organization + Categories *VCCategory `xml:"CATEGORIES,omitempty"` // categories + Note string `xml:"NOTE,omitempty"` // text note (not used by Amsterdam) + ProductID string `xml:"PRODID,omitempty"` // product ID that generated this vCard (not used by Amsterdam) + LastUpdate string `xml:"REV,omitempty"` // last update to this information, ISO 8601 format + SortString string `xml:"SORT-STRING,omitempty"` // sort string + Sound *VCSound `xml:"SOUND,omitempty"` // pronunciation property (not used in Amsterdam) + UID string `xml:"UID,omitempty"` // unique identifier (not necessarily an Amsterdam UID!) (not used in Amsterdam) + URL string `xml:"URL,omitempty"` // URL + Class *VCClass `xml:"CLASS,omitempty"` // privacy classification (not used in Amsterdam) + Key *VCKey `xml:"KEY,omitempty"` // authentication credential or encryption key (not used in Amsterdam) + Description string `xml:"DESC,omitempty"` // description string value (XMPP extension) } // VCPhoto is the "photo" attachment to the VCard. type VCPhoto struct { - XMLName xml.Name `xml:"PHOTO"` // must be a "PHOTO" tag - Type string `xml:"TYPE"` // data type for BINVAL - BinaryValue string `xml:"BINVAL"` // binary photo value (Base64 encoded) - ExternalValue string `xml:"EXTVAL"` // external value of photo (URL) + XMLName xml.Name `xml:"PHOTO"` // must be a "PHOTO" tag + Type string `xml:"TYPE,omitempty"` // data type for BINVAL + BinaryValue string `xml:"BINVAL,omitempty"` // binary photo value (Base64 encoded) + ExternalValue string `xml:"EXTVAL,omitempty"` // external value of photo (URL) } // Name is the "structured name" property of the vCard. type VCName struct { - XMLName xml.Name `xml:"N"` // must be an "N" tag - Family string `xml:"FAMILY"` // family name - Given string `xml:"GIVEN"` // given name - Middle string `xml:"MIDDLE"` // middle name/initial - Prefix string `xml:"PREFIX"` // prefix - Suffix string `xml:"SUFFIX"` // suffix + XMLName xml.Name `xml:"N"` // must be an "N" tag + Family string `xml:"FAMILY,omitempty"` // family name + Given string `xml:"GIVEN,omitempty"` // given name + Middle string `xml:"MIDDLE,omitempty"` // middle name/initial + Prefix string `xml:"PREFIX,omitempty"` // prefix + Suffix string `xml:"SUFFIX,omitempty"` // suffix } // VCAddress is the "address" property of the vCard. type VCAddress struct { - XMLName xml.Name `xml:"ADR"` // must be a "ADR" tag - Work xml.Name `xml:"WORK"` // Presence indicates work address - Home xml.Name `xml:"HOME"` // Presence indicates home address - Postal xml.Name `xml:"POSTAL"` // presence indicates postal address - Parcel xml.Name `xml:"PARCEL"` // presence indicates parcel address - Domestic xml.Name `xml:"DOM"` // presence indicates domestic address - International xml.Name `xml:"INTL"` // presence indicates international address - Preferred xml.Name `xml:"PREF"` // Presence indicates preferred address - POBox string `xml:"POBOX"` // post office box - Locality string `xml:"LOCALITY"` // locality (city) - Region string `xml:"REGION"` // region (state/province) - PCode string `xml:"PCODE"` // postal code - Country string `xml:"CTRY"` // country - Street string `xml:"STREET"` // street address (addr line 1) - ExtAddr string `xml:"EXTADR"` // extended address (addr line 2) + XMLName xml.Name `xml:"ADR"` // must be a "ADR" tag + Work *Presence `xml:"WORK,omitempty"` // Presence indicates work address + Home *Presence `xml:"HOME,omitempty"` // Presence indicates home address + Postal *Presence `xml:"POSTAL,omitempty"` // presence indicates postal address + Parcel *Presence `xml:"PARCEL,omitempty"` // presence indicates parcel address + Domestic *Presence `xml:"DOM,omitempty"` // presence indicates domestic address + International *Presence `xml:"INTL,omitempty"` // presence indicates international address + Preferred *Presence `xml:"PREF,omitempty"` // Presence indicates preferred address + POBox string `xml:"POBOX,omitempty"` // post office box + Locality string `xml:"LOCALITY,omitempty"` // locality (city) + Region string `xml:"REGION,omitempty"` // region (state/province) + PCode string `xml:"PCODE,omitempty"` // postal code + Country string `xml:"CTRY,omitempty"` // country + Street string `xml:"STREET,omitempty"` // street address (addr line 1) + ExtAddr string `xml:"EXTADR,omitempty"` // extended address (addr line 2) } // VCAddressLabel is the "address label" property of the vCard. type VCAddressLabel struct { - XMLName xml.Name `xml:"LABEL"` // must be a "LABEL" tag - Work xml.Name `xml:"WORK"` // Presence indicates work address - Home xml.Name `xml:"HOME"` // Presence indicates home address - Postal xml.Name `xml:"POSTAL"` // presence indicates postal address - Parcel xml.Name `xml:"PARCEL"` // presence indicates parcel address - Domestic xml.Name `xml:"DOM"` // presence indicates domestic address - International xml.Name `xml:"INTL"` // presence indicates international address - Preferred xml.Name `xml:"PREF"` // Presence indicates preferred address - Lines []string `xml:"LINE"` // lines of text on the address label + XMLName xml.Name `xml:"LABEL"` // must be a "LABEL" tag + Work *Presence `xml:"WORK,omitempty"` // Presence indicates work address + Home *Presence `xml:"HOME,omitempty"` // Presence indicates home address + Postal *Presence `xml:"POSTAL,omitempty"` // presence indicates postal address + Parcel *Presence `xml:"PARCEL,omitempty"` // presence indicates parcel address + Domestic *Presence `xml:"DOM,omitempty"` // presence indicates domestic address + International *Presence `xml:"INTL,omitempty"` // presence indicates international address + Preferred *Presence `xml:"PREF,omitempty"` // Presence indicates preferred address + Lines []string `xml:"LINE"` // lines of text on the address label } // VCEmail is the "E-mail address" property of the vCard. type VCEmail struct { - XMLName xml.Name `xml:"EMAIL"` // must be an "EMAIL" tag - Work xml.Name `xml:"WORK"` // presence indicates work address - Home xml.Name `xml:"HOME"` // presence indicates home address - Internet xml.Name `xml:"INTERNET"` // presence indicates Internet address - Preferred xml.Name `xml:"PREF"` // Presence indicates preferred address - X400 xml.Name `xml:"X400"` // Presence indicates X.400 address - UserID string `xml:"USERID"` // user ID (address) + XMLName xml.Name `xml:"EMAIL"` // must be an "EMAIL" tag + Work *Presence `xml:"WORK,omitempty"` // presence indicates work address + Home *Presence `xml:"HOME,omitempty"` // presence indicates home address + Internet *Presence `xml:"INTERNET,omitempty"` // presence indicates Internet address + Preferred *Presence `xml:"PREF,omitempty"` // Presence indicates preferred address + X400 *Presence `xml:"X400,omitempty"` // Presence indicates X.400 address + UserID string `xml:"USERID"` // user ID (address) } // VCTelephone is the "telephone number" property of the vCard. type VCTelephone struct { - XMLName xml.Name `xml:"TEL"` // must be a "TEL" tag - Work xml.Name `xml:"WORK"` // presence indicates work number - Home xml.Name `xml:"HOME"` // presence indicates home number - Voice xml.Name `xml:"VOICE"` // presence indicates voice number - Fax xml.Name `xml:"FAX"` // presence indicates fax number - Pager xml.Name `xml:"PAGER"` // presence indicates pager number - Message xml.Name `xml:"MSG"` // presence indicates message number - Cell xml.Name `xml:"CELL"` // presence indicates cellphone number - Video xml.Name `xml:"VIDEO"` // presence indicates videophone number - BBS xml.Name `xml:"BBS"` // presence indicates BBS number - Modem xml.Name `xml:"MODEM"` // presence indicates modem number - ISDN xml.Name `xml:"ISDN"` // presence indicates ISDN number - PCS xml.Name `xml:"PCS"` // presence indicates PCS number - Preferred xml.Name `xml:"PREF"` // presence indicates preferred number - Number string `xml:"NUMBER"` // the number + XMLName xml.Name `xml:"TEL"` // must be a "TEL" tag + Work *Presence `xml:"WORK,omitempty"` // presence indicates work number + Home *Presence `xml:"HOME,omitempty"` // presence indicates home number + Voice *Presence `xml:"VOICE,omitempty"` // presence indicates voice number + Fax *Presence `xml:"FAX,omitempty"` // presence indicates fax number + Pager *Presence `xml:"PAGER,omitempty"` // presence indicates pager number + Message *Presence `xml:"MSG,omitempty"` // presence indicates message number + Cell *Presence `xml:"CELL,omitempty"` // presence indicates cellphone number + Video *Presence `xml:"VIDEO,omitempty"` // presence indicates videophone number + BBS *Presence `xml:"BBS,omitempty"` // presence indicates BBS number + Modem *Presence `xml:"MODEM,omitempty"` // presence indicates modem number + ISDN *Presence `xml:"ISDN,omitempty"` // presence indicates ISDN number + PCS *Presence `xml:"PCS,omitempty"` // presence indicates PCS number + Preferred *Presence `xml:"PREF,omitempty"` // presence indicates preferred number + Number string `xml:"NUMBER"` // the number } // VCGeolocation is the "geolocation" property of the vCard. @@ -147,24 +156,24 @@ type VCGeolocation struct { // VCLogo is the "logo" property of the vCard. type VCLogo struct { - XMLName xml.Name `xml:"LOGO"` // must be a "LOGO" tag - Type string `xml:"TYPE"` // data type for BINVAL - BinaryValue string `xml:"BINVAL"` // binary photo value (Base64 encoded) - ExternalValue string `xml:"EXTVAL"` // external value of photo (URL) + XMLName xml.Name `xml:"LOGO"` // must be a "LOGO" tag + Type string `xml:"TYPE,omitempty"` // data type for BINVAL + BinaryValue string `xml:"BINVAL,omitempty"` // binary photo value (Base64 encoded) + ExternalValue string `xml:"EXTVAL,omitempty"` // external value of photo (URL) } // VCAgent is the "agent" property of the vCard. type VCAgent struct { - XMLName xml.Name `xml:"AGENT"` // must be an "AGENT" tag - VCard *VCard `xml:"vcard-temp vCard"` // vCard with agent contact info - ExternalValue string `xml:"EXTVAL"` // external value, such as URL to contact info + XMLName xml.Name `xml:"AGENT"` // must be an "AGENT" tag + VCard *VCard `xml:"vcard-temp vCard,omitempty"` // vCard with agent contact info + ExternalValue string `xml:"EXTVAL,omitempty"` // external value, such as URL to contact info } // VCOrganization is the "organization" property of the vCard. type VCOrganization struct { - XMLName xml.Name `xml:"ORG"` // must be an "ORG" tag - OrgName string `xml:"ORGNAME"` // organization name - OrgUnit *[]string `xml:"ORGUNIT"` // organization unit(s) + XMLName xml.Name `xml:"ORG"` // must be an "ORG" tag + OrgName string `xml:"ORGNAME"` // organization name + OrgUnit *[]string `xml:"ORGUNIT,omitempty"` // organization unit(s) } // VCCategory is the "category" property of the vCard. @@ -175,29 +184,30 @@ type VCCategory struct { // VCSound is the "pronunciation guide" property of the vCard. type VCSound struct { - XMLName xml.Name `xml:"SOUND"` // must be a "SOUND" tag - Phonetic string `xml:"PHONETIC"` // phonetic pronunciation - BinaryValue string `xml:"BINVAL"` // binary audio value (Base64 encoded) - ExternalValue string `xml:"EXTVAL"` // external value of audio (URL) + XMLName xml.Name `xml:"SOUND"` // must be a "SOUND" tag + Phonetic string `xml:"PHONETIC,omitempty"` // phonetic pronunciation + BinaryValue string `xml:"BINVAL,omitempty"` // binary audio value (Base64 encoded) + ExternalValue string `xml:"EXTVAL,omitempty"` // external value of audio (URL) } // VCClass is the "privacy classification" property of the vCard. type VCClass struct { - XMLName xml.Name `xml:"CLASS"` // must be a "CLASS" tag - Public xml.Name `xml:"PUBLIC"` // presence indicates public information - Private xml.Name `xml:"PRIVATE"` // presence indicates private information - Confidential xml.Name `xml:"CONFIDENTIAL"` // presence indicates confidential information + XMLName xml.Name `xml:"CLASS"` // must be a "CLASS" tag + Public *Presence `xml:"PUBLIC,omitempty"` // presence indicates public information + Private *Presence `xml:"PRIVATE,omitempty"` // presence indicates private information + Confidential *Presence `xml:"CONFIDENTIAL,omitempty"` // presence indicates confidential information } // VCKey is the "authentication or encryption key" property of the vCard. type VCKey struct { - XMLName xml.Name `xml:"KEY"` // must be a "KEY" tag - Type string `xml:"TYPE"` // type indicator - Credential string `xml:"CRED"` // credential value + XMLName xml.Name `xml:"KEY"` // must be a "KEY" tag + Type string `xml:"TYPE,omitempty"` // type indicator + Credential string `xml:"CRED"` // credential value } +// VCardFromContactInfo fills in a VCard structure from a ContactInfo object. func VCardFromContactInfo(ctx context.Context, target *VCard, ci *database.ContactInfo) error { - target.Version = "2.0" + target.Version = VCARD_VERSION target.FullName = ci.FullName(false) target.Name.Family = util.SRef(ci.FamilyName) target.Name.Given = util.SRef(ci.GivenName) @@ -210,9 +220,9 @@ func VCardFromContactInfo(ctx context.Context, target *VCard, ci *database.Conta } addr := make([]VCAddress, 1) - addr[0].Home.Local = "HOME" - addr[0].Postal.Local = "POSTAL" - addr[0].Preferred.Local = "PREF" + addr[0].Home = Present + addr[0].Postal = Present + addr[0].Preferred = Present addr[0].Street = util.SRef(ci.Addr1) addr[0].ExtAddr = util.SRef(ci.Addr2) addr[0].Locality = util.SRef(ci.Locality) @@ -226,24 +236,24 @@ func VCardFromContactInfo(ctx context.Context, target *VCard, ci *database.Conta phone := make([]VCTelephone, phcount) i := 0 if ci.Phone != nil { - phone[i].Home.Local = "HOME" - phone[i].Voice.Local = "VOICE" - phone[i].Preferred.Local = "PREF" + phone[i].Home = Present + phone[i].Voice = Present + phone[i].Preferred = Present phone[i].Number = *ci.Phone i++ } if ci.Fax != nil { - phone[i].Home.Local = "HOME" - phone[i].Fax.Local = "FAX" - phone[i].Preferred.Local = "PREF" + phone[i].Home = Present + phone[i].Fax = Present + phone[i].Preferred = Present phone[i].Number = *ci.Fax i++ } if ci.Mobile != nil { - phone[i].Home.Local = "HOME" - phone[i].Cell.Local = "CELL" - phone[i].Voice.Local = "VOICE" - phone[i].Preferred.Local = "PREF" + phone[i].Home = Present + phone[i].Cell = Present + phone[i].Voice = Present + phone[i].Preferred = Present phone[i].Number = *ci.Mobile i++ } @@ -256,9 +266,9 @@ func VCardFromContactInfo(ctx context.Context, target *VCard, ci *database.Conta if ci.Email != nil { email := make([]VCEmail, 1) - email[0].Home.Local = "HOME" - email[0].Internet.Local = "INTERNET" - email[0].Preferred.Local = "PREF" + email[0].Home = Present + email[0].Internet = Present + email[0].Preferred = Present email[0].UserID = *ci.Email target.Email = &email } diff --git a/exports/vcif_xml.go b/exports/vcif_xml.go index 9545a2b..7d1f5cf 100644 --- a/exports/vcif_xml.go +++ b/exports/vcif_xml.go @@ -49,18 +49,18 @@ type VCIFTopic struct { // VCIFPost is the VCIF element representing a post in a topic. type VCIFPost struct { - XMLName xml.Name `xml:"post"` // I am the element - ID int64 `xml:"id,attr"` // post ID (PostId) - Parent int64 `xml:"parent,attr"` // parent PostId (usually 0) - Index int `xml:"index,attr"` // post index (number) - Lines int `xml:"lines,attr"` // line count - Author string `xml:"author,attr"` // author username - DateISO8601 string `xml:"date,attr"` // post date, ISO 8601 format - Hidden bool `xml:"hidden,attr"` // is post hidden? - Scribbled *VCIFScribble `xml:"scribbled"` // is post scribbled? - Pseud string `xml:"pseud"` // post pseud - Text string `xml:"text"` // post text - Attachment *VCIFPostAttachment `xml:"attachment"` // attachment data + XMLName xml.Name `xml:"post"` // I am the element + ID int64 `xml:"id,attr"` // post ID (PostId) + Parent int64 `xml:"parent,attr"` // parent PostId (usually 0) + Index int `xml:"index,attr"` // post index (number) + Lines int `xml:"lines,attr"` // line count + Author string `xml:"author,attr"` // author username + DateISO8601 string `xml:"date,attr"` // post date, ISO 8601 format + Hidden bool `xml:"hidden,attr"` // is post hidden? + Scribbled *VCIFScribble `xml:"scribbled,omitempty"` // is post scribbled? + Pseud string `xml:"pseud"` // post pseud + Text string `xml:"text"` // post text + Attachment *VCIFPostAttachment `xml:"attachment,omitempty"` // attachment data } // VCIFScribble is the VCIF element representing that a post has been scribbled. diff --git a/exports/viu_xml.go b/exports/viu_xml.go index 5f1a7ab..5558aba 100644 --- a/exports/viu_xml.go +++ b/exports/viu_xml.go @@ -33,15 +33,15 @@ type VIUBase struct { // VIUUser is the structure representing a single user. type VIUUser struct { - XMLName xml.Name `xml:"venice-user"` // must be a tag - ID int `xml:"id,attr"` // the UID for the user - Username string `xml:"username"` // user name - Password VIUPassword `xml:"password"` // password information - PasswordReminder string `xml:"password-reminder"` // password reminder string - Description string `xml:"description"` // description string - Options VIUOptions `xml:"options"` // user options - VCard VCard `xml:"vcard-temp vCard"` // user contact info in vCard XML format - Joins []VIUCommunityJoin `xml:"join"` // joined communities + XMLName xml.Name `xml:"venice-user"` // must be a tag + ID int `xml:"id,attr"` // the UID for the user + Username string `xml:"username"` // user name + Password VIUPassword `xml:"password,omitempty"` // password information + PasswordReminder string `xml:"password-reminder,omitempty"` // password reminder string + Description string `xml:"description,omitempty"` // description string + Options VIUOptions `xml:"options"` // user options + VCard VCard `xml:"vcard-temp vCard"` // user contact info in vCard XML format + Joins []VIUCommunityJoin `xml:"join,omitempty"` // joined communities } // VIUPassword represents the user password information. diff --git a/ui/dialog.go b/ui/dialog.go index 978bb6a..57fe11e 100644 --- a/ui/dialog.go +++ b/ui/dialog.go @@ -23,6 +23,7 @@ import ( "git.erbosoft.com/amy/amsterdam/config" "git.erbosoft.com/amy/amsterdam/database" + "git.erbosoft.com/amy/amsterdam/util" "gopkg.in/yaml.v3" ) @@ -212,11 +213,7 @@ func (fld *DialogItem) ValPtr() *string { // SetVal sets the value of a field from a string pointer. func (fld *DialogItem) SetVal(p *string) { - if p == nil { - fld.Value = "" - } else { - fld.Value = *p - } + fld.Value = util.SRef(p) } // SetInt sets the value of a field to an integer.