From df2a0d826285617dfa4a5c651138dab11b4b24bc Mon Sep 17 00:00:00 2001 From: Shalabh Agarwal Date: Tue, 21 Oct 2025 11:35:48 +0000 Subject: [PATCH] appview: add personal pronouns to profile Signed-off-by: Shalabh Agarwal fixes: https://tangled.org/@tangled.org/core/issues/224 --- appview/ingester.go | 6 ++++++ api/tangled/actorprofile.go | 1 + appview/db/db.go | 7 +++++++ appview/db/profile.go | 32 ++++++++++++++++++++++++++------ appview/models/profile.go | 1 + appview/state/profile.go | 2 ++ lexicons/actor/profile.json | 5 +++++ appview/pages/templates/user/fragments/editBio.html | 11 +++++++++++ appview/pages/templates/user/fragments/profileCard.html | 5 +++++ 9 file(s) changed, 64 insertion(s)(+), 6 deletion(s)(-) diff --git a/appview/ingester.go b/appview/ingester.go --- a/appview/ingester.go +++ b/appview/ingester.go @@ -291,6 +291,11 @@ includeBluesky := record.Bluesky + pronouns := "" + if record.Pronouns != nil { + pronouns = *record.Pronouns + } + location := "" if record.Location != nil { location = *record.Location @@ -325,6 +330,7 @@ Links: links, Stats: stats, PinnedRepos: pinned, + Pronouns: pronouns, } ddb, ok := i.Db.Execer.(*db.DB) diff --git a/api/tangled/actorprofile.go b/api/tangled/actorprofile.go --- a/api/tangled/actorprofile.go +++ b/api/tangled/actorprofile.go @@ -28,4 +28,5 @@ // pinnedRepositories: Any ATURI, it is up to appviews to validate these fields. PinnedRepositories []string `json:"pinnedRepositories,omitempty" cborgen:"pinnedRepositories,omitempty"` Stats []string `json:"stats,omitempty" cborgen:"stats,omitempty"` + Pronouns *string `json:"pronouns,omitempty" cborgen:"pronouns,omitempty"` } diff --git a/appview/db/db.go b/appview/db/db.go --- a/appview/db/db.go +++ b/appview/db/db.go @@ -1106,6 +1106,13 @@ return err }) + runMigration(conn, logger, "add-pronouns-profile", func(tx *sql.Tx) error { + _, err := tx.Exec(` + alter table profile add column pronouns text; + `) + return err + }) + return &DB{ db, logger, diff --git a/appview/db/profile.go b/appview/db/profile.go --- a/appview/db/profile.go +++ b/appview/db/profile.go @@ -129,13 +129,15 @@ did, description, include_bluesky, - location + location, + pronouns ) - values (?, ?, ?, ?)`, + values (?, ?, ?, ?, ?)`, profile.Did, profile.Description, includeBskyValue, profile.Location, + profile.Pronouns, ) if err != nil { @@ -216,7 +218,8 @@ did, description, include_bluesky, - location + location, + pronouns from profile %s`, @@ -231,14 +234,19 @@ for rows.Next() { var profile models.Profile var includeBluesky int + var pronouns sql.Null[string] - err = rows.Scan(&profile.ID, &profile.Did, &profile.Description, &includeBluesky, &profile.Location) + err = rows.Scan(&profile.ID, &profile.Did, &profile.Description, &includeBluesky, &profile.Location, &pronouns) if err != nil { return nil, err } if includeBluesky != 0 { profile.IncludeBluesky = true + } + + if pronouns.Valid { + profile.Pronouns = pronouns.V } profileMap[profile.Did] = &profile @@ -302,13 +310,16 @@ func GetProfile(e Execer, did string) (*models.Profile, error) { var profile models.Profile + var pronouns sql.Null[string] + profile.Did = did includeBluesky := 0 + err := e.QueryRow( - `select description, include_bluesky, location from profile where did = ?`, + `select description, include_bluesky, location, pronouns from profile where did = ?`, did, - ).Scan(&profile.Description, &includeBluesky, &profile.Location) + ).Scan(&profile.Description, &includeBluesky, &profile.Location, &pronouns) if err == sql.ErrNoRows { profile := models.Profile{} profile.Did = did @@ -321,6 +332,10 @@ if includeBluesky != 0 { profile.IncludeBluesky = true + } + + if pronouns.Valid { + profile.Pronouns = pronouns.V } rows, err := e.Query(`select link from profile_links where did = ?`, did) @@ -412,6 +427,11 @@ // ensure description is not too long if len(profile.Location) > 40 { return fmt.Errorf("Entered location is too long.") + } + + // ensure pronouns are not too long + if len(profile.Pronouns) > 40 { + return fmt.Errorf("Entered pronouns are too long.") } // ensure links are in order diff --git a/appview/models/profile.go b/appview/models/profile.go --- a/appview/models/profile.go +++ b/appview/models/profile.go @@ -19,6 +19,7 @@ Links [5]string Stats [2]VanityStat PinnedRepos [6]syntax.ATURI + Pronouns string } func (p Profile) IsLinksEmpty() bool { diff --git a/appview/state/profile.go b/appview/state/profile.go --- a/appview/state/profile.go +++ b/appview/state/profile.go @@ -538,6 +538,7 @@ profile.Description = r.FormValue("description") profile.IncludeBluesky = r.FormValue("includeBluesky") == "on" profile.Location = r.FormValue("location") + profile.Pronouns = r.FormValue("pronouns") var links [5]string for i := range 5 { @@ -652,6 +653,7 @@ Location: &profile.Location, PinnedRepositories: pinnedRepoStrings, Stats: vanityStats[:], + Pronouns: &profile.Pronouns, }}, SwapRecord: cid, }) diff --git a/lexicons/actor/profile.json b/lexicons/actor/profile.json --- a/lexicons/actor/profile.json +++ b/lexicons/actor/profile.json @@ -64,6 +64,11 @@ "type": "string", "format": "at-uri" } + }, + "pronouns": { + "type": "string", + "description": "Preferred gender pronouns.", + "maxLength": 40 } } } diff --git a/appview/pages/templates/user/fragments/editBio.html b/appview/pages/templates/user/fragments/editBio.html --- a/appview/pages/templates/user/fragments/editBio.html +++ b/appview/pages/templates/user/fragments/editBio.html @@ -20,6 +20,17 @@
+ +
+ {{ $pronouns := "" }} + {{ if and .Profile .Profile.Pronouns }} + {{ $pronouns = .Profile.Pronouns }} + {{ end }} + +
+
+ +
{{ $location := "" }} diff --git a/appview/pages/templates/user/fragments/profileCard.html b/appview/pages/templates/user/fragments/profileCard.html --- a/appview/pages/templates/user/fragments/profileCard.html +++ b/appview/pages/templates/user/fragments/profileCard.html @@ -12,6 +12,11 @@ class="text-lg font-bold dark:text-white overflow-hidden text-ellipsis whitespace-nowrap"> {{ $userIdent }}

+ {{ with .Profile }} + {{ if .Pronouns }} +

{{ .Pronouns }}

+ {{ end }} + {{ end }} {{ i "rss" "size-4" }}
-- tangled.sh