Compare commits
	
		
			5 commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | e90d8e3b05 | ||
|  | 82eb927dd4 | ||
|  | 446ab176ac | ||
|  | 7177354219 | ||
|  | 4f652dab02 | 
					 12 changed files with 39 additions and 1 deletions
				
			
		|  | @ -26,6 +26,7 @@ You should also include the user name that made the change. | |||
|   Your own theme color may be unset if it was in an invalid format. | ||||
|   Admins should check their instance settings if in doubt. | ||||
| - Perform port diagnosis at startup only when Listen fails @mei23 | ||||
| - Add pronouns to vCard and display when replying @ThatOneCalculator | ||||
| 
 | ||||
| ### Bugfixes | ||||
| - Client: fix settings page @tamaina | ||||
|  |  | |||
|  | @ -258,6 +258,7 @@ remoteUserCaution: "As this user is from a remote instance, the shown informatio | |||
| activity: "Activity" | ||||
| images: "Images" | ||||
| birthday: "Birthday" | ||||
| pronouns: "Pronouns" | ||||
| yearsOld: "{age} years old" | ||||
| registeredDate: "Joined on" | ||||
| location: "Location" | ||||
|  |  | |||
|  | @ -258,6 +258,7 @@ remoteUserCaution: "リモートユーザーのため、情報が不完全です | |||
| activity: "アクティビティ" | ||||
| images: "画像" | ||||
| birthday: "誕生日" | ||||
| pronouns: "代名詞" | ||||
| yearsOld: "{age}歳" | ||||
| registeredDate: "登録日" | ||||
| location: "場所" | ||||
|  |  | |||
|  | @ -17,6 +17,12 @@ export class UserProfile { | |||
| 	@JoinColumn() | ||||
| 	public user: User | null; | ||||
| 
 | ||||
| 	@Column('varchar', { | ||||
| 		length: 32, nullable: true, | ||||
| 		comment: 'The pronouns of the User.', | ||||
| 	}) | ||||
| 	public pronouns: string | null; | ||||
| 
 | ||||
| 	@Column('varchar', { | ||||
| 		length: 128, nullable: true, | ||||
| 		comment: 'The location of the User.', | ||||
|  |  | |||
|  | @ -30,6 +30,7 @@ const nameSchema = { type: 'string', minLength: 1, maxLength: 50 } as const; | |||
| const descriptionSchema = { type: 'string', minLength: 1, maxLength: 500 } as const; | ||||
| const locationSchema = { type: 'string', minLength: 1, maxLength: 50 } as const; | ||||
| const birthdaySchema = { type: 'string', pattern: /^([0-9]{4})-([0-9]{2})-([0-9]{2})$/.toString().slice(1, -1) } as const; | ||||
| const pronounsSchema = { type: 'string', minLength: 1, maxLength: 20 } as const; | ||||
| 
 | ||||
| function isLocalUser(user: User): user is ILocalUser; | ||||
| function isLocalUser<T extends { host: User['host'] }>(user: T): user is T & { host: null; }; | ||||
|  | @ -50,6 +51,7 @@ export const UserRepository = db.getRepository(User).extend({ | |||
| 	descriptionSchema, | ||||
| 	locationSchema, | ||||
| 	birthdaySchema, | ||||
| 	pronounsSchema, | ||||
| 
 | ||||
| 	//#region Validators
 | ||||
| 	validateLocalUsername: ajv.compile(localUsernameSchema), | ||||
|  | @ -58,6 +60,7 @@ export const UserRepository = db.getRepository(User).extend({ | |||
| 	validateDescription: ajv.compile(descriptionSchema), | ||||
| 	validateLocation: ajv.compile(locationSchema), | ||||
| 	validateBirthday: ajv.compile(birthdaySchema), | ||||
| 	validatePronouns: ajv.compile(pronounsSchema), | ||||
| 	//#endregion
 | ||||
| 
 | ||||
| 	async getRelation(me: User['id'], target: User['id']) { | ||||
|  | @ -318,6 +321,7 @@ export const UserRepository = db.getRepository(User).extend({ | |||
| 				isSilenced: user.isSilenced || falsy, | ||||
| 				isSuspended: user.isSuspended || falsy, | ||||
| 				description: profile!.description, | ||||
| 				pronouns: profile!.pronouns, | ||||
| 				location: profile!.location, | ||||
| 				birthday: profile!.birthday, | ||||
| 				lang: profile!.lang, | ||||
|  |  | |||
|  | @ -143,6 +143,11 @@ export const packedUserDetailedNotMeOnlySchema = { | |||
| 			nullable: true, optional: false, | ||||
| 			example: 'Hi masters, I am Ai!', | ||||
| 		}, | ||||
| 		pronouns: { | ||||
| 			type: 'string', | ||||
| 			nullable: true, optional: false, | ||||
| 			example: 'They/Them', | ||||
| 		}, | ||||
| 		location: { | ||||
| 			type: 'string', | ||||
| 			nullable: true, optional: false, | ||||
|  |  | |||
|  | @ -192,6 +192,7 @@ export async function createPerson(uri: string, resolver?: Resolver): Promise<Us | |||
| 				description: person.summary ? htmlToMfm(truncate(person.summary, summaryLength), person.tag) : null, | ||||
| 				url: getOneApHrefNullable(person.url), | ||||
| 				fields, | ||||
| 				pronouns: person['vcard:Nickname'] || null, | ||||
| 				birthday: bday ? bday[0] : null, | ||||
| 				location: person['vcard:Address'] || null, | ||||
| 				userHost: host, | ||||
|  | @ -368,6 +369,7 @@ export async function updatePerson(uri: string, resolver?: Resolver | null, hint | |||
| 		url: getOneApHrefNullable(person.url), | ||||
| 		fields, | ||||
| 		description: person.summary ? htmlToMfm(truncate(person.summary, summaryLength), person.tag) : null, | ||||
| 		pronouns: person['vcard:Nickname'] || null, | ||||
| 		birthday: bday ? bday[0] : null, | ||||
| 		location: person['vcard:Address'] || null, | ||||
| 	}); | ||||
|  |  | |||
|  | @ -77,6 +77,10 @@ export async function renderPerson(user: ILocalUser) { | |||
| 		attachment: attachment.length ? attachment : undefined, | ||||
| 	} as any; | ||||
| 
 | ||||
| 	if (profile?.pronouns) { | ||||
| 		person['vcard:Nickname'] = profile.pronouns; | ||||
| 	} | ||||
| 
 | ||||
| 	if (profile?.birthday) { | ||||
| 		person['vcard:bday'] = profile.birthday; | ||||
| 	} | ||||
|  |  | |||
|  | @ -164,6 +164,7 @@ export interface IActor extends IObject { | |||
| 	endpoints?: { | ||||
| 		sharedInbox?: string; | ||||
| 	}; | ||||
| 	'vcard:Nickname'?: string; | ||||
| 	'vcard:bday'?: string; | ||||
| 	'vcard:Address'?: string; | ||||
| } | ||||
|  |  | |||
|  | @ -72,6 +72,7 @@ export const paramDef = { | |||
| 	properties: { | ||||
| 		name: { ...Users.nameSchema, nullable: true }, | ||||
| 		description: { ...Users.descriptionSchema, nullable: true }, | ||||
| 		pronouns: { ...Users.pronounsSchema, nullable: true }, | ||||
| 		location: { ...Users.locationSchema, nullable: true }, | ||||
| 		birthday: { ...Users.birthdaySchema, nullable: true }, | ||||
| 		lang: { type: 'string', enum: [null, ...Object.keys(langmap)], nullable: true }, | ||||
|  | @ -132,6 +133,7 @@ export default define(meta, paramDef, async (ps, _user, token) => { | |||
| 	if (ps.name !== undefined) updates.name = ps.name; | ||||
| 	if (ps.description !== undefined) profileUpdates.description = ps.description; | ||||
| 	if (ps.lang !== undefined) profileUpdates.lang = ps.lang; | ||||
| 	if (ps.pronouns !== undefined) profileUpdates.pronouns = ps.pronouns; | ||||
| 	if (ps.location !== undefined) profileUpdates.location = ps.location; | ||||
| 	if (ps.birthday !== undefined) profileUpdates.birthday = ps.birthday; | ||||
| 	if (ps.ffVisibility !== undefined) profileUpdates.ffVisibility = ps.ffVisibility; | ||||
|  |  | |||
|  | @ -17,6 +17,11 @@ | |||
| 		<template #caption>{{ i18n.ts._profile.youCanIncludeHashtags }}</template> | ||||
| 	</FormTextarea> | ||||
| 
 | ||||
| 	<FormInput v-model="profile.pronouns" manual-save class="_formBlock"> | ||||
| 		<template #label>{{ i18n.ts.pronouns }}</template> | ||||
| 		<template #prefix><i class="fas fa-heart"></i></template> | ||||
| 	</FormInput> | ||||
| 
 | ||||
| 	<FormInput v-model="profile.location" manual-save class="_formBlock"> | ||||
| 		<template #label>{{ i18n.ts.location }}</template> | ||||
| 		<template #prefix><i class="fas fa-map-marker-alt"></i></template> | ||||
|  | @ -82,6 +87,7 @@ import { langmap } from '@/scripts/langmap'; | |||
| const profile = reactive({ | ||||
| 	name: $i.name, | ||||
| 	description: $i.description, | ||||
| 	pronouns: $i.pronouns, | ||||
| 	location: $i.location, | ||||
| 	birthday: $i.birthday, | ||||
| 	lang: $i.lang, | ||||
|  | @ -120,6 +126,7 @@ function save() { | |||
| 	os.apiWithDialog('i/update', { | ||||
| 		name: profile.name || null, | ||||
| 		description: profile.description || null, | ||||
| 		pronouns: profile.pronouns || null, | ||||
| 		location: profile.location || null, | ||||
| 		birthday: profile.birthday || null, | ||||
| 		lang: profile.lang || null, | ||||
|  |  | |||
|  | @ -47,6 +47,10 @@ | |||
| 								<p v-else class="empty">{{ $ts.noAccountDescription }}</p> | ||||
| 							</div> | ||||
| 							<div class="fields system"> | ||||
| 								<dl v-if="user.pronouns" class="field"> | ||||
| 									<dt class="name"><i class="fas fa-heart fa-fw"></i> {{ $ts.pronouns }}</dt> | ||||
| 									<dd class="value">{{ user.pronouns }}</dd> | ||||
| 								</dl> | ||||
| 								<dl v-if="user.location" class="field"> | ||||
| 									<dt class="name"><i class="fas fa-map-marker fa-fw"></i> {{ $ts.location }}</dt> | ||||
| 									<dd class="value">{{ user.location }}</dd> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue