Skip to content

Commit dae136e

Browse files
authored
Implement initial MSC4440 Bios with extensible events formatting (#559)
### Description This pull request adds support for saving and reading user bios in the MSC4440 format, improving compatibility with the MSC4440 specification for Matrix user profiles. The changes ensure that bios are now stored and retrieved in both the legacy and MSC4440-compliant formats, and introduce new types to support this functionality. #### MSC4440 Bio Compatibility - User bios are now saved in the MSC4440 format (`gay.fomx.biography`) in addition to existing formats, ensuring forward compatibility with the MSC4440 spec. When saving, both HTML and plain text representations are stored. - The user profile normalization logic now reads bios from the MSC4440 field first, falling back to legacy fields if necessary. - The fields handled by the normalization function are updated to include the MSC4440 bio key. #### Type and Import Updates - New types `MSC1767Text` and `MSC4440Bio` are introduced to represent the MSC4440 bio format, and relevant imports are updated throughout the codebase. implements matrix-org/matrix-spec-proposals#4440 #### Type of change - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] This change requires a documentation update ### Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings ### AI disclosure: - [ ] Partially AI assisted (clarify which code was AI assisted and briefly explain what it does). - [ ] Fully AI generated (explain what all the generated code does in moderate detail). No AI was used in the creation of this PR
2 parents 86a3ccb + 0c62e75 commit dae136e

5 files changed

Lines changed: 39 additions & 5 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
default: note
3+
---
4+
5+
new/changed bios will now also be saved in the format MSC4440 expects

src/app/features/settings/account/BioEditor.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ type BioEditorProps = {
4444
value?: string | any;
4545
isSaving?: boolean;
4646
imagePackRooms?: any[];
47-
onSave: (htmlContent: string) => void;
47+
onSave: (htmlContent: string, plainText: string) => void;
4848
};
4949

5050
const BIO_LIMIT = 1024;
@@ -81,7 +81,7 @@ export function BioEditor({ value, isSaving, imagePackRooms, onSave }: BioEditor
8181
})
8282
);
8383

84-
onSave(customHtml || plainText);
84+
onSave(customHtml || plainText, plainText);
8585
setHasChanged(false);
8686
}, [editor, isMarkdown, onSave]);
8787

src/app/features/settings/account/Profile.tsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import { useSetAtom } from 'jotai';
2929
import { SequenceCard } from '$components/sequence-card';
3030
import { SettingTile } from '$components/setting-tile';
3131
import { useMatrixClient } from '$hooks/useMatrixClient';
32-
import { UserProfile, useUserProfile } from '$hooks/useUserProfile';
32+
import { UserProfile, useUserProfile, MSC4440Bio } from '$hooks/useUserProfile';
3333
import { getMxIdLocalPart, mxcUrlToHttp } from '$utils/matrix';
3434
import { UserAvatar } from '$components/user-avatar';
3535
import { useMediaAuthentication } from '$hooks/useMediaAuthentication';
@@ -46,6 +46,7 @@ import { useCapabilities } from '$hooks/useCapabilities';
4646
import { profilesCacheAtom } from '$state/userRoomProfile';
4747
import { SequenceCardStyle } from '$features/settings/styles.css';
4848
import { useUserPresence } from '$hooks/useUserPresence';
49+
import { MSC1767Text } from '$types/matrix/common';
4950
import { TimezoneEditor } from './TimezoneEditor';
5051
import { PronounEditor } from './PronounEditor';
5152
import { BioEditor } from './BioEditor';
@@ -576,13 +577,27 @@ function ProfileExtended({ profile, userId }: Readonly<ProfileProps>) {
576577
>
577578
<BioEditor
578579
value={
580+
(profile.extended?.['gay.fomx.biography'] satisfies MSC4440Bio)?.formatted_body ||
579581
profile.extended?.['moe.sable.app.bio'] ||
580582
profile.extended?.['chat.commet.profile_bio'] ||
581583
profile.bio
582584
}
583-
onSave={(htmlBio) => {
585+
onSave={(htmlBio, plainTextBio) => {
584586
handleSaveField('moe.sable.app.bio', htmlBio);
585587

588+
// MSC4440
589+
handleSaveField('gay.fomx.biography', {
590+
'm.text': [
591+
{
592+
body: htmlBio,
593+
mimetype: 'text/html',
594+
} satisfies MSC1767Text,
595+
{
596+
body: plainTextBio,
597+
} satisfies MSC1767Text,
598+
],
599+
} satisfies MSC4440Bio);
600+
586601
const cleanedHtml = htmlBio.replaceAll('<br/></blockquote>', '</blockquote>');
587602
handleSaveField('chat.commet.profile_bio', {
588603
format: 'org.matrix.custom.html',

src/app/hooks/useUserProfile.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@ import colorMXID from '$utils/colorMXID';
77
import { profilesCacheAtom } from '$state/userRoomProfile';
88
import { useSetting } from '$state/hooks/settings';
99
import { settingsAtom } from '$state/settings';
10+
import { MSC1767Text } from '$types/matrix/common';
1011
import { useMatrixClient } from './useMatrixClient';
1112

1213
const inFlightProfiles = new Map<string, Promise<any>>();
1314

15+
export type MSC4440Bio = {
16+
'm.text': Array<MSC1767Text>;
17+
};
18+
1419
export type UserProfile = {
1520
avatarUrl?: string;
1621
displayName?: string;
@@ -35,6 +40,7 @@ const normalizeInfo = (info: any): UserProfile => {
3540
'm.tz',
3641
'moe.sable.app.bio',
3742
'chat.commet.profile_bio',
43+
'gay.fomx.biography',
3844
'chat.commet.profile_banner',
3945
'chat.commet.profile_status',
4046
'moe.sable.app.name_color',
@@ -54,7 +60,10 @@ const normalizeInfo = (info: any): UserProfile => {
5460
displayName: info.displayname,
5561
pronouns: info['io.fsky.nyx.pronouns'],
5662
timezone: info['us.cloke.msc4175.tz'] || info['m.tz'],
57-
bio: info['moe.sable.app.bio'] || info['chat.commet.profile_bio'],
63+
bio:
64+
(info['gay.fomx.biography'] satisfies MSC4440Bio)['m.text'][0].body ||
65+
info['moe.sable.app.bio'] ||
66+
info['chat.commet.profile_bio'],
5867
status: info['chat.commet.profile_status'],
5968
bannerUrl: info['chat.commet.profile_banner'],
6069
nameColor: info['moe.sable.app.name_color'],

src/types/matrix/common.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ export type IImageInfo = {
1414
[MATRIX_BLUR_HASH_PROPERTY_NAME]?: string;
1515
};
1616

17+
export type MSC1767Text = {
18+
body: string;
19+
mimetype?: string;
20+
};
21+
1722
export type IVideoInfo = {
1823
w?: number;
1924
h?: number;

0 commit comments

Comments
 (0)