Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/fix-inline-images-behaviors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
default: patch
---

Added a couple new settings for max incoming inline image height and default height for unspecified.
5 changes: 5 additions & 0 deletions .changeset/fix-markdown-link-preview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
default: patch
---

Fixed links with suppressed previews not having the arrow brackets readded when editing a message.
5 changes: 5 additions & 0 deletions .changeset/fix-read-reciept-size.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
default: patch
---

Fix the inconsistent sizing for the read receipt dialog boxes.
5 changes: 5 additions & 0 deletions .changeset/fix-room-avatar-settings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
default: patch
---

Fixed room avatars set in the settings cosmetics menu not applying.
30 changes: 30 additions & 0 deletions src/app/components/editor/output.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { describe, expect, it } from 'vitest';
import { toMatrixCustomHTML, trimCustomHtml } from '$components/editor/output';
import { BlockType } from '$components/editor/types';

describe('toMatrixCustomHTML emoticons', () => {
it('always serializes custom emoji images with height=32', () => {
const html = trimCustomHtml(
toMatrixCustomHTML(
[
{
type: BlockType.Paragraph,
children: [
{
type: BlockType.Emoticon,
key: 'mxc://example.org/emote',
shortcode: 'blobcat',
children: [{ text: '' }],
} as never,
],
} as never,
],
{}
)
);

expect(html).toContain('data-mx-emoticon');
expect(html).toContain('mxc://example.org/emote');
expect(html).toContain('height="32"');
});
});
3 changes: 3 additions & 0 deletions src/app/components/event-readers/EventReaders.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const EventReaders = style([
DefaultReset,
{
height: '100%',
width: '280px',
},
]);

Expand All @@ -18,4 +19,6 @@ export const Header = style({
export const Content = style({
paddingLeft: config.space.S200,
paddingBottom: config.space.S400,
width: '100%',
minWidth: 0,
});
13 changes: 9 additions & 4 deletions src/app/components/event-readers/EventReaders.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,14 @@ export const EventReaders = as<'div', EventReadersProps>(
<Icon src={Icons.Cross} />
</IconButton>
</Header>
<Box grow="Yes">
<Box className={css.Content} direction="Column">
<Scroll visibility="Hover" hideTrack size="300">
<Box grow="Yes" style={{ width: '100%', minWidth: 0 }}>
<Box
grow="Yes"
className={css.Content}
direction="Column"
style={{ width: '100%', minWidth: 0 }}
>
<Scroll visibility="Hover" hideTrack size="300" style={{ width: '100%' }}>
{latestEventReaders.map((readerId) => {
const name = getName(readerId);
const avatarMxcUrl = room.getMember(readerId)?.getMxcAvatarUrl();
Expand All @@ -79,7 +84,7 @@ export const EventReaders = as<'div', EventReadersProps>(
return (
<MenuItem
key={readerId}
style={{ padding: `0 ${config.space.S200}` }}
style={{ padding: `0 ${config.space.S200}`, width: '100%' }}
radii="400"
onClick={(event) => {
openProfile(
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/member-tile/MemberTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const MemberTile = as<'button', MemberTileProps>(
const name = getName(room, member, nicknames);
const presence = useUserPresence(member.userId ?? '');

const avatarMxcUrl = member.getMxcAvatarUrl();
const avatarMxcUrl = member.getMxcAvatarUrl() ?? mx.getUser(member.userId)?.avatarUrl;
const avatarUrl = avatarMxcUrl
? mx.mxcUrlToHttp(avatarMxcUrl, 100, 100, 'crop', undefined, false, useAuthentication)
: undefined;
Expand Down
12 changes: 12 additions & 0 deletions src/app/components/message/Reply.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import { useIgnoredUsers } from '$hooks/useIgnoredUsers';
import { nicknamesAtom } from '$state/nicknames';
import { useMatrixClient } from '$hooks/useMatrixClient';
import { useMemberEventParser } from '$hooks/useMemberEventParser';
import { useSetting } from '$state/hooks/settings';
import { settingsAtom } from '$state/settings';

import { useMentionClickHandler } from '$hooks/useMentionClickHandler';
import { useTranslation } from 'react-i18next';
Expand Down Expand Up @@ -139,6 +141,14 @@ export const Reply = as<'div', ReplyProps>(
const nicknames = useAtomValue(nicknamesAtom);
const useAuthentication = useMediaAuthentication();
const settingsLinkBaseUrl = useSettingsLinkBaseUrl();
const [incomingInlineImagesDefaultHeight] = useSetting(
settingsAtom,
'incomingInlineImagesDefaultHeight'
);
const [incomingInlineImagesMaxHeight] = useSetting(
settingsAtom,
'incomingInlineImagesMaxHeight'
);

const fallbackBody = isRedacted ? <MessageDeletedContent /> : <MessageFailedContent />;

Expand Down Expand Up @@ -190,6 +200,8 @@ export const Reply = as<'div', ReplyProps>(
useAuthentication,
nicknames,
handleMentionClick: mentionClickHandler,
incomingInlineImagesDefaultHeight,
incomingInlineImagesMaxHeight,
});
bodyJSX = parse(sanitizedHtml, parserOpts) as JSX.Element;
} else if (hasPlainTextReply) {
Expand Down
20 changes: 19 additions & 1 deletion src/app/components/upload-card/UploadCardRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import { roomUploadAtomFamily } from '$state/room/roomInputDrafts';
import { useObjectURL } from '$hooks/useObjectURL';
import { useMediaConfig } from '$hooks/useMediaConfig';
import { useSettingsLinkBaseUrl } from '$features/settings/useSettingsLinkBaseUrl';
import { useSetting } from '$state/hooks/settings';
import { settingsAtom } from '$state/settings';
import { UploadCard, UploadCardError, UploadCardProgress } from './UploadCard';
import * as css from './UploadCard.css';
import { DescriptionEditor } from './UploadDescriptionEditor';
Expand Down Expand Up @@ -397,15 +399,31 @@ export function UploadCardRenderer({
const spoilerClickHandler = useSpoilerClickHandler();
const useAuthentication = useMediaAuthentication();
const settingsLinkBaseUrl = useSettingsLinkBaseUrl();
const [incomingInlineImagesDefaultHeight] = useSetting(
settingsAtom,
'incomingInlineImagesDefaultHeight'
);
const [incomingInlineImagesMaxHeight] = useSetting(settingsAtom, 'incomingInlineImagesMaxHeight');
const htmlReactParserOptions = useMemo<HTMLReactParserOptions>(
() =>
getReactCustomHtmlParser(mx, roomId, {
settingsLinkBaseUrl,
linkifyOpts,
useAuthentication,
handleSpoilerClick: spoilerClickHandler,
incomingInlineImagesDefaultHeight,
incomingInlineImagesMaxHeight,
}),
[linkifyOpts, mx, roomId, settingsLinkBaseUrl, spoilerClickHandler, useAuthentication]
[
linkifyOpts,
mx,
roomId,
settingsLinkBaseUrl,
spoilerClickHandler,
useAuthentication,
incomingInlineImagesDefaultHeight,
incomingInlineImagesMaxHeight,
]
);
return (
<UploadCard
Expand Down
50 changes: 30 additions & 20 deletions src/app/features/common-settings/cosmetics/Cosmetics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import { SettingTile } from '$components/setting-tile';
import { useRoom } from '$hooks/useRoom';
import { usePowerLevels } from '$hooks/usePowerLevels';
import { useMatrixClient } from '$hooks/useMatrixClient';
import { useStateEvent } from '$hooks/useStateEvent';

import { useRoomCreators } from '$hooks/useRoomCreators';
import { useRoomPermissions } from '$hooks/useRoomPermissions';
Expand Down Expand Up @@ -70,8 +71,17 @@ export function CosmeticsAvatar({ profile, member, userId, room }: CosmeticsSett
const capabilities = useCapabilities();
const [alertRemove, setAlertRemove] = useState(false);
const disableSetAvatar = capabilities['m.set_avatar_url']?.enabled === false;

const avatarMxc = member.getMxcAvatarUrl();
const memberStateEvent = useStateEvent(room, EventType.RoomMember, userId);
const memberStateContent = memberStateEvent?.getContent<{ avatar_url?: string }>();
const globalAvatarMxc = mx.getUser(userId)?.avatarUrl ?? profile.avatarUrl;
const roomAvatarMxc = memberStateEvent
? memberStateContent?.avatar_url
: member.getMxcAvatarUrl();
const avatarMxc = roomAvatarMxc ?? globalAvatarMxc;
const hasRoomAvatarOverride =
memberStateEvent !== undefined &&
memberStateContent?.avatar_url !== undefined &&
memberStateContent.avatar_url !== globalAvatarMxc;
const avatarUrl =
avatarMxc && (mxcUrlToHttp(mx, avatarMxc, useAuthentication, 96, 96, 'crop') ?? undefined);

Expand All @@ -92,15 +102,17 @@ export function CosmeticsAvatar({ profile, member, userId, room }: CosmeticsSett
const handleUploaded = useCallback(
(upload: UploadSuccess) => {
const { mxc } = upload;
myRoomAvatar.exe(mxc);
handleRemoveUpload();
myRoomAvatar.exe(mxc).finally(() => {
handleRemoveUpload();
});
},
[myRoomAvatar, handleRemoveUpload]
);

const handleRemoveAvatar = () => {
myRoomAvatar.exe('');
setAlertRemove(false);
myRoomAvatar.exe('').finally(() => {
setAlertRemove(false);
});
};

return (
Expand Down Expand Up @@ -139,20 +151,18 @@ export function CosmeticsAvatar({ profile, member, userId, room }: CosmeticsSett
>
<Text size="B300">Upload</Text>
</Button>
{avatarUrl &&
avatarUrl !==
mxcUrlToHttp(mx, profile.avatarUrl ?? '', useAuthentication, 96, 96, 'crop') && (
<Button
size="300"
variant="Critical"
fill="None"
radii="300"
disabled={disableSetAvatar}
onClick={() => setAlertRemove(true)}
>
<Text size="B300">Remove</Text>
</Button>
)}
{hasRoomAvatarOverride && (
<Button
size="300"
variant="Critical"
fill="None"
radii="300"
disabled={disableSetAvatar}
onClick={() => setAlertRemove(true)}
>
<Text size="B300">Remove</Text>
</Button>
)}
</Box>
)}

Expand Down
11 changes: 11 additions & 0 deletions src/app/features/message-search/SearchResultGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ import {
import { useRoomCreators } from '$hooks/useRoomCreators';
import { useRoomCreatorsTag } from '$hooks/useRoomCreatorsTag';
import { useSettingsLinkBaseUrl } from '$features/settings/useSettingsLinkBaseUrl';
import { useSetting } from '$state/hooks/settings';
import { settingsAtom } from '$state/settings';
import type { ResultItem } from './useMessageSearch';

type SearchResultGroupProps = {
Expand Down Expand Up @@ -95,6 +97,11 @@ export function SearchResultGroup({
const accessibleTagColors = useAccessiblePowerTagColors(theme.kind, creatorsTag, powerLevelTags);
const nicknames = useAtomValue(nicknamesAtom);
const settingsLinkBaseUrl = useSettingsLinkBaseUrl();
const [incomingInlineImagesDefaultHeight] = useSetting(
settingsAtom,
'incomingInlineImagesDefaultHeight'
);
const [incomingInlineImagesMaxHeight] = useSetting(settingsAtom, 'incomingInlineImagesMaxHeight');

const mentionClickHandler = useMentionClickHandler(room.roomId);
const spoilerClickHandler = useSpoilerClickHandler();
Expand Down Expand Up @@ -127,6 +134,8 @@ export function SearchResultGroup({
handleSpoilerClick: spoilerClickHandler,
handleMentionClick: mentionClickHandler,
nicknames,
incomingInlineImagesDefaultHeight,
incomingInlineImagesMaxHeight,
}),
[
mx,
Expand All @@ -138,6 +147,8 @@ export function SearchResultGroup({
useAuthentication,
nicknames,
settingsLinkBaseUrl,
incomingInlineImagesDefaultHeight,
incomingInlineImagesMaxHeight,
]
);

Expand Down
9 changes: 9 additions & 0 deletions src/app/features/room/RoomTimeline.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,11 @@ export function RoomTimeline({
const [dateFormatString] = useSetting(settingsAtom, 'dateFormatString');
const [autoplayStickers] = useSetting(settingsAtom, 'autoplayStickers');
const [autoplayEmojis] = useSetting(settingsAtom, 'autoplayEmojis');
const [incomingInlineImagesDefaultHeight] = useSetting(
settingsAtom,
'incomingInlineImagesDefaultHeight'
);
const [incomingInlineImagesMaxHeight] = useSetting(settingsAtom, 'incomingInlineImagesMaxHeight');
const [hideMemberInReadOnly] = useSetting(settingsAtom, 'hideMembershipInReadOnly');

const showUrlPreview = room.hasEncryptionStateEvent() ? encUrlPreview : urlPreview;
Expand Down Expand Up @@ -567,13 +572,17 @@ export function RoomTimeline({
handleMentionClick: mentionClickHandler,
nicknames,
autoplayEmojis,
incomingInlineImagesDefaultHeight,
incomingInlineImagesMaxHeight,
replaceTextNode: buildAbbrReplaceTextNode(abbrMap, linkifyOpts),
}),
[
mx,
room.roomId,
linkifyOpts,
autoplayEmojis,
incomingInlineImagesDefaultHeight,
incomingInlineImagesMaxHeight,
mentionClickHandler,
nicknames,
mediaAuthentication,
Expand Down
Loading
Loading