From 77301f1aa41f6e6fdd0f184abcb542ca19cd3c83 Mon Sep 17 00:00:00 2001 From: Shalabh Agarwal Date: Tue, 21 Oct 2025 17:05:48 +0530 Subject: [PATCH] appview: add personal pronouns to profile Change-Id: ptmwklvzzmyvzqplxlxoypqyvyooxpsz Signed-off-by: Shalabh Agarwal fixes: https://tangled.org/@tangled.org/core/issues/224 --- api/tangled/actorprofile.go | 1 + appview/db/db.go | 7 +++++++ appview/db/profile.go | 20 +++++++++++++------ appview/ingester.go | 6 ++++++ appview/models/profile.go | 1 + .../templates/user/fragments/editBio.html | 11 ++++++++++ .../templates/user/fragments/profileCard.html | 5 +++++ appview/state/profile.go | 2 ++ lexicons/actor/profile.json | 5 +++++ 9 files changed, 52 insertions(+), 6 deletions(-) diff --git a/api/tangled/actorprofile.go b/api/tangled/actorprofile.go index 1279952e..c9a130a8 100644 --- a/api/tangled/actorprofile.go +++ b/api/tangled/actorprofile.go @@ -28,4 +28,5 @@ type ActorProfile struct { // 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 index 21f2c20c..f61490c7 100644 --- a/appview/db/db.go +++ b/appview/db/db.go @@ -1106,6 +1106,13 @@ func Make(ctx context.Context, dbPath string) (*DB, error) { 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 index 7eb5ba83..4a0ce04f 100644 --- a/appview/db/profile.go +++ b/appview/db/profile.go @@ -129,13 +129,15 @@ func UpsertProfile(tx *sql.Tx, profile *models.Profile) error { 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 @@ func GetProfiles(e Execer, filters ...filter) (map[string]*models.Profile, error did, description, include_bluesky, - location + location, + pronouns from profile %s`, @@ -232,7 +235,7 @@ func GetProfiles(e Execer, filters ...filter) (map[string]*models.Profile, error var profile models.Profile var includeBluesky int - err = rows.Scan(&profile.ID, &profile.Did, &profile.Description, &includeBluesky, &profile.Location) + err = rows.Scan(&profile.ID, &profile.Did, &profile.Description, &includeBluesky, &profile.Location, &profile.Pronouns) if err != nil { return nil, err } @@ -306,9 +309,9 @@ func GetProfile(e Execer, did string) (*models.Profile, error) { 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, &profile.Pronouns) if err == sql.ErrNoRows { profile := models.Profile{} profile.Did = did @@ -414,6 +417,11 @@ func ValidateProfile(e Execer, profile *models.Profile) error { 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 err := validateLinks(profile) if err != nil { diff --git a/appview/ingester.go b/appview/ingester.go index 547233fe..1c5d6d0a 100644 --- a/appview/ingester.go +++ b/appview/ingester.go @@ -291,6 +291,11 @@ func (i *Ingester) ingestProfile(e *jmodels.Event) error { includeBluesky := record.Bluesky + pronouns := "" + if record.Pronouns != nil { + pronouns = *record.Pronouns + } + location := "" if record.Location != nil { location = *record.Location @@ -325,6 +330,7 @@ func (i *Ingester) ingestProfile(e *jmodels.Event) error { Links: links, Stats: stats, PinnedRepos: pinned, + Pronouns: pronouns, } ddb, ok := i.Db.Execer.(*db.DB) diff --git a/appview/models/profile.go b/appview/models/profile.go index 0890a766..70fb646b 100644 --- a/appview/models/profile.go +++ b/appview/models/profile.go @@ -19,6 +19,7 @@ type Profile struct { Links [5]string Stats [2]VanityStat PinnedRepos [6]syntax.ATURI + Pronouns string } func (p Profile) IsLinksEmpty() bool { diff --git a/appview/pages/templates/user/fragments/editBio.html b/appview/pages/templates/user/fragments/editBio.html index 7c2730c6..7615da91 100644 --- a/appview/pages/templates/user/fragments/editBio.html +++ b/appview/pages/templates/user/fragments/editBio.html @@ -19,6 +19,17 @@ placeholder="write a bio">{{ $description }} +
+ +
+ {{ $pronouns := "" }} + {{ if and .Profile .Profile.Pronouns }} + {{ $pronouns = .Profile.Pronouns }} + {{ end }} + +
+
+
diff --git a/appview/pages/templates/user/fragments/profileCard.html b/appview/pages/templates/user/fragments/profileCard.html index 0b5f3f60..83a62417 100644 --- 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" }}
diff --git a/appview/state/profile.go b/appview/state/profile.go index 8d9e82fd..2c47add2 100644 --- a/appview/state/profile.go +++ b/appview/state/profile.go @@ -538,6 +538,7 @@ func (s *State) UpdateProfileBio(w http.ResponseWriter, r *http.Request) { 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 @@ func (s *State) updateProfile(profile *models.Profile, w http.ResponseWriter, r Location: &profile.Location, PinnedRepositories: pinnedRepoStrings, Stats: vanityStats[:], + Pronouns: &profile.Pronouns, }}, SwapRecord: cid, }) diff --git a/lexicons/actor/profile.json b/lexicons/actor/profile.json index 1115595e..fdd43674 100644 --- 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 } } } -- 2.43.0