diff --git a/.changeset/fix_pmp_empty_displayname.md b/.changeset/fix_pmp_empty_displayname.md new file mode 100644 index 000000000..97e6e2d7a --- /dev/null +++ b/.changeset/fix_pmp_empty_displayname.md @@ -0,0 +1,5 @@ +--- +default: patch +--- + +fix the issue of empty displaynames of a persona, causing an empty fallback message, it will now ommit the fallback, if the name is empty or only consists of whitespace diff --git a/src/app/features/room/RoomInput.tsx b/src/app/features/room/RoomInput.tsx index ba0a5fd47..b9d2dbb65 100644 --- a/src/app/features/room/RoomInput.tsx +++ b/src/app/features/room/RoomInput.tsx @@ -768,30 +768,34 @@ export const RoomInput = forwardRef( const perMessageProfile = await getCurrentlyUsedPerMessageProfileForRoom(mx, roomId); if (perMessageProfile) { - content['com.beeper.per_message_profile'] = - convertPerMessageProfileToBeeperFormat(perMessageProfile); + content['com.beeper.per_message_profile'] = convertPerMessageProfileToBeeperFormat( + perMessageProfile, + perMessageProfile.name.trim() !== '' + ); - // if a per-message profile is used, it must per spec include a fallback - const prefix = `${perMessageProfile.name}: `; + if (perMessageProfile.name.trim() !== '') { + // if a per-message profile is used, it must per spec include a fallback + const prefix = `${perMessageProfile.name}: `; - if (!content.body.startsWith(prefix)) { - // to prevent double-prefixing when the fallback is already present - content.body = prefix + content.body; - } + if (!content.body.startsWith(prefix)) { + // to prevent double-prefixing when the fallback is already present + content.body = prefix + content.body; + } - /** - * html escaped version of the display name - */ - const escapedName = sanitizeCustomHtml(perMessageProfile.name); + /** + * html escaped version of the display name + */ + const escapedName = sanitizeCustomHtml(perMessageProfile.name); - const htmlPrefix = `${escapedName}: `; + const htmlPrefix = `${escapedName}: `; - if (content.formatted_body && !content.formatted_body.startsWith(htmlPrefix)) { - content.formatted_body = htmlPrefix + content.formatted_body; - } else { - // we don't have a formatted body, but we need one - content.format = 'org.matrix.custom.html'; - content.formatted_body = `${htmlPrefix}${plainText}`; + if (content.formatted_body && !content.formatted_body.startsWith(htmlPrefix)) { + content.formatted_body = htmlPrefix + content.formatted_body; + } else { + // we don't have a formatted body, but we need one + content.format = 'org.matrix.custom.html'; + content.formatted_body = `${htmlPrefix}${plainText}`; + } } } diff --git a/src/app/features/room/message/Message.tsx b/src/app/features/room/message/Message.tsx index 88a4349ff..c26e40692 100644 --- a/src/app/features/room/message/Message.tsx +++ b/src/app/features/room/message/Message.tsx @@ -403,8 +403,9 @@ function MessageInternal( /** * boolean to indicate wheather we should indicate to the user that it is a pmp + * We want to not show it, when the name is unset, or whitespace only */ - const showPmPInfo = pmp !== undefined; + const showPmPInfo = parsedPMPContent?.name && parsedPMPContent.name?.trim() !== ''; // Profiles and Colors const profile = useUserProfile(senderId, room); const { color: usernameColor, font: usernameFont } = useSableCosmetics(senderId, room); diff --git a/src/app/hooks/usePerMessageProfile.ts b/src/app/hooks/usePerMessageProfile.ts index 8ef2f8d44..966db2af9 100644 --- a/src/app/hooks/usePerMessageProfile.ts +++ b/src/app/hooks/usePerMessageProfile.ts @@ -40,7 +40,7 @@ export type PerMessageProfileBeeperFormat = { /** * the display name to use for messages using this profile. This is required because otherwise the profile would have no effect on the message. */ - displayname: string; + displayname?: string; /** * the avatar url to use for messages using this profile. * Beeper expects this to be a mxc url. @@ -50,7 +50,7 @@ export type PerMessageProfileBeeperFormat = { * using the unstable prefix for pronouns, under which it is also stored in profiles */ 'io.fsky.nyx.pronouns'?: PronounSet[]; - has_fallback: boolean; + has_fallback?: boolean; }; /** @@ -61,15 +61,23 @@ export type PerMessageProfileBeeperFormat = { * @return {*} {PerMessageProfileBeeperFormat} the per message profile in Beeper's format, which can be applied to a message before sending it */ export function convertPerMessageProfileToBeeperFormat( - profile: PerMessageProfile + profile: PerMessageProfile, + has_fallback: boolean ): PerMessageProfileBeeperFormat { - return { + const beeperPMP: PerMessageProfileBeeperFormat = { id: profile.id, displayname: profile.name, avatar_url: profile.avatarUrl, 'io.fsky.nyx.pronouns': profile.pronouns, - has_fallback: true, + has_fallback, }; + // delete empty fields + // to-do maybe find a better way of doing it + if (!profile.name || profile?.name.trim().length === 0) delete beeperPMP.displayname; + if (!profile.avatarUrl) delete beeperPMP.avatar_url; + if (!profile.pronouns || profile.pronouns?.length === 0) delete beeperPMP['io.fsky.nyx.pronouns']; + if (!has_fallback) delete beeperPMP.has_fallback; + return beeperPMP; } /** @@ -85,7 +93,7 @@ export function convertBeeperFormatToOurPerMessageProfile( ): PerMessageProfile { return { id: beeperProfile.id, - name: beeperProfile.displayname, + name: beeperProfile.displayname ?? '', avatarUrl: beeperProfile.avatar_url, pronouns: beeperProfile['io.fsky.nyx.pronouns'], };