+1
api/tangled/actorprofile.go
+1
api/tangled/actorprofile.go
···
28
28
// pinnedRepositories: Any ATURI, it is up to appviews to validate these fields.
29
29
PinnedRepositories []string `json:"pinnedRepositories,omitempty" cborgen:"pinnedRepositories,omitempty"`
30
30
Stats []string `json:"stats,omitempty" cborgen:"stats,omitempty"`
31
+
Pronouns *string `json:"pronouns,omitempty" cborgen:"pronouns,omitempty"`
31
32
}
+7
appview/db/db.go
+7
appview/db/db.go
···
1106
1106
return err
1107
1107
})
1108
1108
1109
+
runMigration(conn, logger, "add-pronouns-profile", func(tx *sql.Tx) error {
1110
+
_, err := tx.Exec(`
1111
+
alter table profile add column pronouns text;
1112
+
`)
1113
+
return err
1114
+
})
1115
+
1109
1116
return &DB{
1110
1117
db,
1111
1118
logger,
+26
-6
appview/db/profile.go
+26
-6
appview/db/profile.go
···
129
129
did,
130
130
description,
131
131
include_bluesky,
132
-
location
132
+
location,
133
+
pronouns
133
134
)
134
-
values (?, ?, ?, ?)`,
135
+
values (?, ?, ?, ?, ?)`,
135
136
profile.Did,
136
137
profile.Description,
137
138
includeBskyValue,
138
139
profile.Location,
140
+
profile.Pronouns,
139
141
)
140
142
141
143
if err != nil {
···
216
218
did,
217
219
description,
218
220
include_bluesky,
219
-
location
221
+
location,
222
+
pronouns
220
223
from
221
224
profile
222
225
%s`,
···
231
234
for rows.Next() {
232
235
var profile models.Profile
233
236
var includeBluesky int
237
+
var pronouns sql.Null[string]
234
238
235
-
err = rows.Scan(&profile.ID, &profile.Did, &profile.Description, &includeBluesky, &profile.Location)
239
+
err = rows.Scan(&profile.ID, &profile.Did, &profile.Description, &includeBluesky, &profile.Location, &pronouns)
236
240
if err != nil {
237
241
return nil, err
238
242
}
239
243
240
244
if includeBluesky != 0 {
241
245
profile.IncludeBluesky = true
246
+
}
247
+
248
+
if pronouns.Valid {
249
+
profile.Pronouns = pronouns.V
242
250
}
243
251
244
252
profileMap[profile.Did] = &profile
···
302
310
303
311
func GetProfile(e Execer, did string) (*models.Profile, error) {
304
312
var profile models.Profile
313
+
var pronouns sql.Null[string]
314
+
305
315
profile.Did = did
306
316
307
317
includeBluesky := 0
318
+
308
319
err := e.QueryRow(
309
-
`select description, include_bluesky, location from profile where did = ?`,
320
+
`select description, include_bluesky, location, pronouns from profile where did = ?`,
310
321
did,
311
-
).Scan(&profile.Description, &includeBluesky, &profile.Location)
322
+
).Scan(&profile.Description, &includeBluesky, &profile.Location, &pronouns)
312
323
if err == sql.ErrNoRows {
313
324
profile := models.Profile{}
314
325
profile.Did = did
···
321
332
322
333
if includeBluesky != 0 {
323
334
profile.IncludeBluesky = true
335
+
}
336
+
337
+
if pronouns.Valid {
338
+
profile.Pronouns = pronouns.V
324
339
}
325
340
326
341
rows, err := e.Query(`select link from profile_links where did = ?`, did)
···
412
427
// ensure description is not too long
413
428
if len(profile.Location) > 40 {
414
429
return fmt.Errorf("Entered location is too long.")
430
+
}
431
+
432
+
// ensure pronouns are not too long
433
+
if len(profile.Pronouns) > 40 {
434
+
return fmt.Errorf("Entered pronouns are too long.")
415
435
}
416
436
417
437
// ensure links are in order
+6
appview/ingester.go
+6
appview/ingester.go
···
291
291
292
292
includeBluesky := record.Bluesky
293
293
294
+
pronouns := ""
295
+
if record.Pronouns != nil {
296
+
pronouns = *record.Pronouns
297
+
}
298
+
294
299
location := ""
295
300
if record.Location != nil {
296
301
location = *record.Location
···
325
330
Links: links,
326
331
Stats: stats,
327
332
PinnedRepos: pinned,
333
+
Pronouns: pronouns,
328
334
}
329
335
330
336
ddb, ok := i.Db.Execer.(*db.DB)
+1
appview/models/profile.go
+1
appview/models/profile.go
+11
appview/pages/templates/user/fragments/editBio.html
+11
appview/pages/templates/user/fragments/editBio.html
···
20
20
</div>
21
21
22
22
<div class="flex flex-col gap-1">
23
+
<label class="m-0 p-0" for="pronouns">pronouns</label>
24
+
<div class="flex items-center gap-2 w-full">
25
+
{{ $pronouns := "" }}
26
+
{{ if and .Profile .Profile.Pronouns }}
27
+
{{ $pronouns = .Profile.Pronouns }}
28
+
{{ end }}
29
+
<input type="text" class="py-1 px-1 w-full" name="pronouns" value="{{ $pronouns }}">
30
+
</div>
31
+
</div>
32
+
33
+
<div class="flex flex-col gap-1">
23
34
<label class="m-0 p-0" for="location">location</label>
24
35
<div class="flex items-center gap-2 w-full">
25
36
{{ $location := "" }}
+5
appview/pages/templates/user/fragments/profileCard.html
+5
appview/pages/templates/user/fragments/profileCard.html
···
12
12
class="text-lg font-bold dark:text-white overflow-hidden text-ellipsis whitespace-nowrap">
13
13
{{ $userIdent }}
14
14
</p>
15
+
{{ with .Profile }}
16
+
{{ if .Pronouns }}
17
+
<p class="text-gray-500 dark:text-gray-400">{{ .Pronouns }}</p>
18
+
{{ end }}
19
+
{{ end }}
15
20
<a href="/{{ $userIdent }}/feed.atom">{{ i "rss" "size-4" }}</a>
16
21
</div>
17
22
+2
appview/state/profile.go
+2
appview/state/profile.go
···
538
538
profile.Description = r.FormValue("description")
539
539
profile.IncludeBluesky = r.FormValue("includeBluesky") == "on"
540
540
profile.Location = r.FormValue("location")
541
+
profile.Pronouns = r.FormValue("pronouns")
541
542
542
543
var links [5]string
543
544
for i := range 5 {
···
652
653
Location: &profile.Location,
653
654
PinnedRepositories: pinnedRepoStrings,
654
655
Stats: vanityStats[:],
656
+
Pronouns: &profile.Pronouns,
655
657
}},
656
658
SwapRecord: cid,
657
659
})