+9
-3
lexicons/profile.json
+9
-3
lexicons/profile.json
···
14
14
"maxGraphemes": 64,
15
15
"maxLength": 640
16
16
},
17
-
"description": {
17
+
"about": {
18
18
"type": "string",
19
-
"description": "Free-form profile description text.",
19
+
"description": "Conference attendee extended about text",
20
+
"maxGraphemes": 1024,
21
+
"maxLength": 10240
22
+
},
23
+
"shortbio": {
24
+
"type": "string",
25
+
"description": "If you are a speaker, this is displayed as your bio. Use about for extended text",
20
26
"maxGraphemes": 256,
21
27
"maxLength": 2560
22
28
},
23
29
"avatar": {
24
30
"type": "blob",
25
-
"description": "Profile picture for conference attendee",
31
+
"description": "Profile picture for conference attendee. Defaults to Bluesky profile pic on first login. If you are speaking, this is used as your speaker headshot",
26
32
"accept": ["image/png", "image/jpeg"],
27
33
"maxSize": 1000000
28
34
},
+33
-19
src/components/ProfileForm.astro
+33
-19
src/components/ProfileForm.astro
···
1
1
---
2
2
interface Props {
3
3
displayName?: string
4
-
description?: string
4
+
about?: string
5
5
avatar?: string
6
6
banner?: string
7
7
submitLabel?: string
···
10
10
11
11
const {
12
12
displayName = '',
13
-
description = '',
13
+
about = '',
14
14
avatar = '',
15
15
banner = '',
16
16
submitLabel = 'Create Profile',
···
26
26
>
27
27
<div class="form-control">
28
28
<label class="label">
29
-
<span class="label-text">Display Name</span>
29
+
<span class="label-text">Attendee Name</span>
30
30
<span class="label-text-alt">Max 64 characters</span>
31
31
</label>
32
32
<input
33
33
type="text"
34
34
name="displayName"
35
-
placeholder="Enter your display name"
35
+
placeholder="This is the display name that will be shown as your attendee name."
36
36
class="input input-bordered w-full"
37
37
value={displayName}
38
38
maxlength="64"
···
42
42
43
43
<div class="form-control">
44
44
<label class="label">
45
-
<span class="label-text">Description</span>
46
-
<span class="label-text-alt">Max 256 characters</span>
47
-
</label>
48
-
<textarea
49
-
name="description"
50
-
placeholder="Tell us about yourself"
51
-
class="textarea textarea-bordered h-24"
52
-
maxlength="256"
53
-
>{description}</textarea>
54
-
</div>
55
-
56
-
<div class="form-control">
57
-
<label class="label">
58
-
<span class="label-text">Avatar</span>
59
-
<span class="label-text-alt">PNG or JPEG, max 1MB</span>
45
+
<span class="label-text">Attendee Image</span>
46
+
<span class="label-text-alt">Your public attendee image. PNG or JPEG, max 1MB</span>
60
47
</label>
61
48
{avatar && (
62
49
<div class="avatar mb-2">
···
72
59
class="file-input file-input-bordered w-full"
73
60
/>
74
61
</div>
62
+
63
+
<div class="form-control">
64
+
<label class="label">
65
+
<span class="label-text">Bio</span>
66
+
<span class="label-text-alt">A short biography, displayed as speaker bios. Max 256 characters</span>
67
+
</label><br />
68
+
<textarea
69
+
name="shortbio"
70
+
placeholder="If you are a speaker, this is displayed as your bio. Use About for extended background"
71
+
class="textarea textarea-bordered h-24 w-full"
72
+
maxlength="256"
73
+
>{about}</textarea>
74
+
</div>
75
+
76
+
<div class="form-control">
77
+
<label class="label">
78
+
<span class="label-text">About</span>
79
+
<span class="label-text-alt">Max 1024 characters</span>
80
+
</label><br />
81
+
<textarea
82
+
name="about"
83
+
placeholder="Tell us about yourself"
84
+
class="textarea textarea-bordered h-24 w-full"
85
+
maxlength="1024"
86
+
>{about}</textarea>
87
+
</div>
88
+
75
89
76
90
<div class="form-control">
77
91
<label class="label">
+27
-46
src/lexicon/lexicons.ts
+27
-46
src/lexicon/lexicons.ts
···
1
1
/**
2
2
* GENERATED CODE - DO NOT MODIFY
3
3
*/
4
-
import {
5
-
type LexiconDoc,
6
-
Lexicons,
7
-
ValidationError,
8
-
type ValidationResult,
9
-
} from '@atproto/lexicon'
4
+
import { type LexiconDoc, Lexicons, ValidationError, type ValidationResult } from '@atproto/lexicon'
10
5
import { type $Typed, is$typed, maybe$typed } from './util.js'
11
6
12
7
export const schemaDict = {
···
16
11
defs: {
17
12
label: {
18
13
type: 'object',
19
-
description:
20
-
'Metadata tag on an atproto resource (eg, repo or record).',
14
+
description: 'Metadata tag on an atproto resource (eg, repo or record).',
21
15
required: ['src', 'uri', 'val', 'cts'],
22
16
properties: {
23
17
ver: {
···
32
26
uri: {
33
27
type: 'string',
34
28
format: 'uri',
35
-
description:
36
-
'AT URI of the record, repository (account), or other resource that this label applies to.',
29
+
description: 'AT URI of the record, repository (account), or other resource that this label applies to.',
37
30
},
38
31
cid: {
39
32
type: 'string',
40
33
format: 'cid',
41
-
description:
42
-
"Optionally, CID specifying the specific version of 'uri' resource this label applies to.",
34
+
description: "Optionally, CID specifying the specific version of 'uri' resource this label applies to.",
43
35
},
44
36
val: {
45
37
type: 'string',
46
38
maxLength: 128,
47
-
description:
48
-
'The short string name of the value or type of this label.',
39
+
description: 'The short string name of the value or type of this label.',
49
40
},
50
41
neg: {
51
42
type: 'boolean',
52
-
description:
53
-
'If true, this is a negation label, overwriting a previous label.',
43
+
description: 'If true, this is a negation label, overwriting a previous label.',
54
44
},
55
45
cts: {
56
46
type: 'string',
···
60
50
exp: {
61
51
type: 'string',
62
52
format: 'datetime',
63
-
description:
64
-
'Timestamp at which this label expires (no longer applies).',
53
+
description: 'Timestamp at which this label expires (no longer applies).',
65
54
},
66
55
sig: {
67
56
type: 'bytes',
···
71
60
},
72
61
selfLabels: {
73
62
type: 'object',
74
-
description:
75
-
'Metadata tags on an atproto record, published by the author within the record.',
63
+
description: 'Metadata tags on an atproto record, published by the author within the record.',
76
64
required: ['values'],
77
65
properties: {
78
66
values: {
···
94
82
val: {
95
83
type: 'string',
96
84
maxLength: 128,
97
-
description:
98
-
'The short string name of the value or type of this label.',
85
+
description: 'The short string name of the value or type of this label.',
99
86
},
100
87
},
101
88
},
102
89
labelValueDefinition: {
103
90
type: 'object',
104
-
description:
105
-
'Declares a label value and its expected interpretations and behaviors.',
91
+
description: 'Declares a label value and its expected interpretations and behaviors.',
106
92
required: ['identifier', 'severity', 'blurs', 'locales'],
107
93
properties: {
108
94
identifier: {
···
132
118
},
133
119
adultOnly: {
134
120
type: 'boolean',
135
-
description:
136
-
'Does the user need to have adult content enabled in order to configure this label?',
121
+
description: 'Does the user need to have adult content enabled in order to configure this label?',
137
122
},
138
123
locales: {
139
124
type: 'array',
···
146
131
},
147
132
labelValueDefinitionStrings: {
148
133
type: 'object',
149
-
description:
150
-
'Strings which describe the label in the UI, localized into a specific language.',
134
+
description: 'Strings which describe the label in the UI, localized into a specific language.',
151
135
required: ['lang', 'name', 'description'],
152
136
properties: {
153
137
lang: {
154
138
type: 'string',
155
-
description:
156
-
'The code of the language these strings are written in.',
139
+
description: 'The code of the language these strings are written in.',
157
140
format: 'language',
158
141
},
159
142
name: {
···
164
147
},
165
148
description: {
166
149
type: 'string',
167
-
description:
168
-
'A longer description of what the label means and why it might be applied.',
150
+
description: 'A longer description of what the label means and why it might be applied.',
169
151
maxGraphemes: 10000,
170
152
maxLength: 100000,
171
153
},
···
205
187
maxGraphemes: 64,
206
188
maxLength: 640,
207
189
},
208
-
description: {
190
+
about: {
191
+
type: 'string',
192
+
description: 'Conference attendee extended about text',
193
+
maxGraphemes: 512,
194
+
maxLength: 5120,
195
+
},
196
+
shortbio: {
209
197
type: 'string',
210
-
description: 'Free-form profile description text.',
198
+
description: 'If you are a speaker, this is displayed as your bio. Use about for extended text',
211
199
maxGraphemes: 256,
212
200
maxLength: 2560,
213
201
},
214
202
avatar: {
215
203
type: 'blob',
216
-
description: 'Profile picture for conference attendee',
204
+
description:
205
+
'Profile picture for conference attendee. Defaults to Bluesky profile pic on first login. If you are speaking, this is used as your speaker headshot',
217
206
accept: ['image/png', 'image/jpeg'],
218
207
maxSize: 1000000,
219
208
},
220
209
banner: {
221
210
type: 'blob',
222
-
description:
223
-
'Larger horizontal image to display behind profile view.',
211
+
description: 'Larger horizontal image to display behind profile view.',
224
212
accept: ['image/png', 'image/jpeg'],
225
213
maxSize: 1000000,
226
214
},
···
275
263
hash: string,
276
264
requiredType?: false,
277
265
): ValidationResult<T>
278
-
export function validate(
279
-
v: unknown,
280
-
id: string,
281
-
hash: string,
282
-
requiredType?: boolean,
283
-
): ValidationResult {
266
+
export function validate(v: unknown, id: string, hash: string, requiredType?: boolean): ValidationResult {
284
267
return (requiredType ? is$typed : maybe$typed)(v, id, hash)
285
268
? lexicons.validate(`${id}#${hash}`, v)
286
269
: {
287
270
success: false,
288
-
error: new ValidationError(
289
-
`Must be an object with "${hash === 'main' ? id : `${id}#${hash}`}" $type property`,
290
-
),
271
+
error: new ValidationError(`Must be an object with "${hash === 'main' ? id : `${id}#${hash}`}" $type property`),
291
272
}
292
273
}
293
274
+4
-6
src/lexicon/types/org/atmosphereconf/profile.ts
+4
-6
src/lexicon/types/org/atmosphereconf/profile.ts
···
14
14
export interface Main {
15
15
$type: 'org.atmosphereconf.profile'
16
16
displayName?: string
17
+
/** Bio for speakers */
18
+
shortbio?: string
17
19
/** Free-form profile description text. */
18
-
description?: string
20
+
about?: string
19
21
/** Profile picture for conference attendee */
20
22
avatar?: BlobRef
21
23
/** Larger horizontal image to display behind profile view. */
···
35
37
return validate<Main & V>(v, id, hashMain, true)
36
38
}
37
39
38
-
export {
39
-
type Main as Record,
40
-
isMain as isRecord,
41
-
validateMain as validateRecord,
42
-
}
40
+
export { type Main as Record, isMain as isRecord, validateMain as validateRecord }
+2
-2
src/pages/index.astro
+2
-2
src/pages/index.astro
···
34
34
const displayName = profile?.displayName || agent?.assertDid || 'User'
35
35
const handle = profile?.handle || agent?.assertDid || ''
36
36
const avatar = profile?.avatar
37
-
const description = profile?.description
37
+
const shortbio = profile?.shortbio
38
38
---
39
39
40
40
<html lang="en" data-theme="dracula">
···
64
64
)}
65
65
<p class="text-lg font-semibold">{displayName}</p>
66
66
<p class="text-sm opacity-70">{handle}</p>
67
-
{description && <p class="text-sm mt-2 opacity-80">{description}</p>}
67
+
{shortbio && <p class="text-sm mt-2 opacity-80">{shortbio}</p>}
68
68
</div>
69
69
<div class="space-y-2 w-full">
70
70
<a href={`/profile/${handle}`} class="btn btn-primary w-full">
+3
-3
src/pages/profile/[handle].astro
+3
-3
src/pages/profile/[handle].astro
···
80
80
}
81
81
82
82
const displayName = conferenceProfile?.displayName || profile?.displayName || handle
83
-
const description = conferenceProfile?.description || profile?.description || ''
83
+
const shortbio = conferenceProfile?.shortbio || profile?.description || ''
84
84
85
85
// Handle both blob refs and direct URLs
86
86
let avatar = ''
···
159
159
)}
160
160
</div>
161
161
162
-
{description && (
163
-
<p class="mt-4 text-base whitespace-pre-wrap">{description}</p>
162
+
{shortbio && (
163
+
<p class="mt-4 text-base whitespace-pre-wrap">{shortbio}</p>
164
164
)}
165
165
166
166
<div class="mt-4">
+2
-2
src/pages/profile/create.astro
+2
-2
src/pages/profile/create.astro
···
43
43
}
44
44
45
45
const displayName = existingProfile?.displayName || ''
46
-
const description = existingProfile?.description || ''
46
+
const about = existingProfile?.about || ''
47
47
---
48
48
49
49
<html lang="en" data-theme="dracula">
···
71
71
72
72
<ProfileForm
73
73
displayName={displayName}
74
-
description={description}
74
+
about={about}
75
75
submitLabel={existingProfile ? 'Update Profile' : 'Create Profile'}
76
76
/>
77
77