Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 31b9a4c

Browse files
authored
Merge pull request #5928 from matrix-org/t3chguy/hidpi
Scale all mxc thumbs using device pixel ratio for hidpi
2 parents b9cca46 + cc3571c commit 31b9a4c

File tree

8 files changed

+21
-36
lines changed

8 files changed

+21
-36
lines changed

src/Avatar.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,7 @@ export type ResizeMethod = "crop" | "scale";
2727
export function avatarUrlForMember(member: RoomMember, width: number, height: number, resizeMethod: ResizeMethod) {
2828
let url: string;
2929
if (member?.getMxcAvatarUrl()) {
30-
url = mediaFromMxc(member.getMxcAvatarUrl()).getThumbnailOfSourceHttp(
31-
Math.floor(width * window.devicePixelRatio),
32-
Math.floor(height * window.devicePixelRatio),
33-
resizeMethod,
34-
);
30+
url = mediaFromMxc(member.getMxcAvatarUrl()).getThumbnailOfSourceHttp(width, height, resizeMethod);
3531
}
3632
if (!url) {
3733
// member can be null here currently since on invites, the JS SDK
@@ -44,11 +40,7 @@ export function avatarUrlForMember(member: RoomMember, width: number, height: nu
4440

4541
export function avatarUrlForUser(user: User, width: number, height: number, resizeMethod?: ResizeMethod) {
4642
if (!user.avatarUrl) return null;
47-
return mediaFromMxc(user.avatarUrl).getThumbnailOfSourceHttp(
48-
Math.floor(width * window.devicePixelRatio),
49-
Math.floor(height * window.devicePixelRatio),
50-
resizeMethod,
51-
);
43+
return mediaFromMxc(user.avatarUrl).getThumbnailOfSourceHttp(width, height, resizeMethod);
5244
}
5345

5446
function isValidHexColor(color: string): boolean {

src/components/structures/SpaceRoomDirectory.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ const Tile: React.FC<ITileProps> = ({
136136

137137
let url: string;
138138
if (room.avatar_url) {
139-
url = mediaFromMxc(room.avatar_url).getSquareThumbnailHttp(Math.floor(20 * window.devicePixelRatio));
139+
url = mediaFromMxc(room.avatar_url).getSquareThumbnailHttp(20);
140140
}
141141

142142
let description = _t("%(count)s members", { count: room.num_joined_members });

src/components/views/avatars/MemberAvatar.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,8 @@ export default class MemberAvatar extends React.Component<IProps, IState> {
6868
let imageUrl = null;
6969
if (props.member.getMxcAvatarUrl()) {
7070
imageUrl = mediaFromMxc(props.member.getMxcAvatarUrl()).getThumbnailOfSourceHttp(
71-
Math.floor(props.width * window.devicePixelRatio),
72-
Math.floor(props.height * window.devicePixelRatio),
71+
props.width,
72+
props.height,
7373
props.resizeMethod,
7474
);
7575
}

src/components/views/avatars/RoomAvatar.tsx

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ export default class RoomAvatar extends React.Component<IProps, IState> {
9393
let oobAvatar = null;
9494
if (props.oobData.avatarUrl) {
9595
oobAvatar = mediaFromMxc(props.oobData.avatarUrl).getThumbnailOfSourceHttp(
96-
Math.floor(props.width * window.devicePixelRatio),
97-
Math.floor(props.height * window.devicePixelRatio),
96+
props.width,
97+
props.height,
9898
props.resizeMethod,
9999
);
100100
}
@@ -109,12 +109,7 @@ export default class RoomAvatar extends React.Component<IProps, IState> {
109109
private static getRoomAvatarUrl(props: IProps): string {
110110
if (!props.room) return null;
111111

112-
return Avatar.avatarUrlForRoom(
113-
props.room,
114-
Math.floor(props.width * window.devicePixelRatio),
115-
Math.floor(props.height * window.devicePixelRatio),
116-
props.resizeMethod,
117-
);
112+
return Avatar.avatarUrlForRoom(props.room, props.width, props.height, props.resizeMethod);
118113
}
119114

120115
private onRoomAvatarClick = () => {

src/components/views/dialogs/IncomingSasDialog.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ export default class IncomingSasDialog extends React.Component {
130130
const oppProfile = this.state.opponentProfile;
131131
if (oppProfile) {
132132
const url = oppProfile.avatar_url
133-
? mediaFromMxc(oppProfile.avatar_url).getSquareThumbnailHttp(Math.floor(48 * window.devicePixelRatio))
133+
? mediaFromMxc(oppProfile.avatar_url).getSquareThumbnailHttp(48)
134134
: null;
135135
profile = <div className="mx_IncomingSasDialog_opponentProfile">
136136
<BaseAvatar name={oppProfile.displayname}

src/components/views/messages/MImageBody.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,8 @@ export default class MImageBody extends React.Component {
185185
// So either we need to support custom timeline widths here, or reimpose the cap, otherwise the
186186
// thumbnail resolution will be unnecessarily reduced.
187187
// custom timeline widths seems preferable.
188-
const pixelRatio = window.devicePixelRatio;
189-
const thumbWidth = Math.round(800 * pixelRatio);
190-
const thumbHeight = Math.round(600 * pixelRatio);
188+
const thumbWidth = 800;
189+
const thumbHeight = 600;
191190

192191
const content = this.props.mxEvent.getContent();
193192
const media = mediaFromContent(content);
@@ -218,7 +217,7 @@ export default class MImageBody extends React.Component {
218217
const info = content.info;
219218
if (
220219
this._isGif() ||
221-
pixelRatio === 1.0 ||
220+
window.devicePixelRatio === 1.0 ||
222221
(!info || !info.w || !info.h || !info.size)
223222
) {
224223
return media.getThumbnailOfSourceHttp(thumbWidth, thumbHeight);

src/customisations/Media.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ export class Media {
9696
*/
9797
public getThumbnailHttp(width: number, height: number, mode: ResizeMethod = "scale"): string | null | undefined {
9898
if (!this.hasThumbnail) return null;
99+
// scale using the device pixel ratio to keep images clear
100+
width = Math.floor(width * window.devicePixelRatio);
101+
height = Math.floor(height * window.devicePixelRatio);
99102
return this.client.mxcUrlToHttp(this.thumbnailMxc, width, height, mode);
100103
}
101104

@@ -107,6 +110,9 @@ export class Media {
107110
* @returns {string} The HTTP URL which points to the thumbnail.
108111
*/
109112
public getThumbnailOfSourceHttp(width: number, height: number, mode: ResizeMethod = "scale"): string {
113+
// scale using the device pixel ratio to keep images clear
114+
width = Math.floor(width * window.devicePixelRatio);
115+
height = Math.floor(height * window.devicePixelRatio);
110116
return this.client.mxcUrlToHttp(this.srcMxc, width, height, mode);
111117
}
112118

@@ -117,6 +123,7 @@ export class Media {
117123
* @returns {string} An HTTP URL for the thumbnail.
118124
*/
119125
public getSquareThumbnailHttp(dim: number): string {
126+
dim = Math.floor(dim * window.devicePixelRatio); // scale using the device pixel ratio to keep images clear
120127
if (this.hasThumbnail) {
121128
return this.getThumbnailHttp(dim, dim, 'crop');
122129
}

src/editor/parts.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -341,11 +341,7 @@ class RoomPillPart extends PillPart {
341341

342342
setAvatar(node: HTMLElement) {
343343
let initialLetter = "";
344-
let avatarUrl = Avatar.avatarUrlForRoom(
345-
this.room,
346-
16 * window.devicePixelRatio,
347-
16 * window.devicePixelRatio,
348-
"crop");
344+
let avatarUrl = Avatar.avatarUrlForRoom(this.room, 16, 16, "crop");
349345
if (!avatarUrl) {
350346
initialLetter = Avatar.getInitialLetter(this.room ? this.room.name : this.resourceId);
351347
avatarUrl = Avatar.defaultAvatarUrlForString(this.room ? this.room.roomId : this.resourceId);
@@ -383,11 +379,7 @@ class UserPillPart extends PillPart {
383379
}
384380
const name = this.member.name || this.member.userId;
385381
const defaultAvatarUrl = Avatar.defaultAvatarUrlForString(this.member.userId);
386-
const avatarUrl = Avatar.avatarUrlForMember(
387-
this.member,
388-
16 * window.devicePixelRatio,
389-
16 * window.devicePixelRatio,
390-
"crop");
382+
const avatarUrl = Avatar.avatarUrlForMember(this.member, 16, 16, "crop");
391383
let initialLetter = "";
392384
if (avatarUrl === defaultAvatarUrl) {
393385
initialLetter = Avatar.getInitialLetter(name);

0 commit comments

Comments
 (0)