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

Commit 8a799f8

Browse files
committed
Implement event permalink pills
1 parent b373ef8 commit 8a799f8

File tree

15 files changed

+685
-233
lines changed

15 files changed

+685
-233
lines changed

res/css/views/elements/_Pill.pcss

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,17 @@ limitations under the License.
5555
min-width: $font-16px; /* ensure the avatar is not compressed */
5656
}
5757

58-
.mx_Pill_linkText {
59-
white-space: nowrap; /* enforce the pill text to be a single line */
60-
overflow: hidden;
61-
text-overflow: ellipsis;
58+
&.mx_EventPill .mx_BaseAvatar {
59+
/* Event pill avatars are inside the text. */
60+
margin-inline-start: 0.2em;
61+
margin-inline-end: 0.2em;
62+
}
6263

64+
.mx_Pill_content {
65+
overflow: hidden;
6366
pointer-events: none; /* ensure clicks on the pills go through the anchor */
67+
text-overflow: ellipsis;
68+
white-space: nowrap;
6469
}
6570

6671
a& {
@@ -69,4 +74,20 @@ limitations under the License.
6974
overflow: hidden;
7075
text-decoration: none !important; /* To override .markdown-body */
7176
}
77+
78+
.mx_Pill_LinkIcon {
79+
background-color: $link-external;
80+
box-sizing: border-box;
81+
color: $background;
82+
height: 16px;
83+
padding: 1px;
84+
width: 16px;
85+
}
86+
87+
.mx_Pill_UserIcon {
88+
box-sizing: border-box;
89+
color: $secondary-content;
90+
height: 16px;
91+
width: 16px;
92+
}
7293
}

res/img/compound/user.svg

Lines changed: 7 additions & 0 deletions
Loading

res/themes/legacy-dark/css/_legacy-dark.pcss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ $room-icon-unread-color: #fff;
9090
$accent: #0dbd8b;
9191
$alert: #ff5b55;
9292
$links: #0086e6;
93+
$link-external: #0467dd;
9394
$primary-content: $primary-fg-color;
9495
$secondary-content: $secondary-fg-color;
9596
$tertiary-content: $tertiary-fg-color;

res/themes/legacy-light/css/_legacy-light.pcss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ $presence-busy: #ff5b55;
149149
$accent: #0dbd8b;
150150
$alert: #ff5b55;
151151
$links: #0086e6;
152+
$link-external: #0467dd;
152153
$primary-content: $primary-fg-color;
153154
$secondary-content: $secondary-fg-color;
154155
$tertiary-content: $tertiary-fg-color;

res/themes/light/css/_light.pcss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ $space-nav: rgba($tertiary-content, 0.15);
4141
$accent: #0dbd8b;
4242
$alert: #ff5b55;
4343
$links: #0086e6;
44+
$link-external: #0467dd;
4445

4546
$username-variant1-color: #368bd6;
4647
$username-variant2-color: #ac3ba8;

src/components/views/elements/Pill.tsx

Lines changed: 74 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,24 @@ limitations under the License.
1717
import React, { ReactElement, useState } from "react";
1818
import classNames from "classnames";
1919
import { Room } from "matrix-js-sdk/src/models/room";
20+
import { RoomMember } from "matrix-js-sdk/src/matrix";
2021

2122
import { MatrixClientPeg } from "../../../MatrixClientPeg";
2223
import MatrixClientContext from "../../../contexts/MatrixClientContext";
2324
import Tooltip, { Alignment } from "../elements/Tooltip";
2425
import { usePermalink } from "../../../hooks/usePermalink";
2526
import RoomAvatar from "../avatars/RoomAvatar";
2627
import MemberAvatar from "../avatars/MemberAvatar";
28+
import { _t } from "../../../languageHandler";
29+
import { Icon as LinkIcon } from "../../../../res/img/element-icons/room/composer/link.svg";
30+
import { Icon as UserIcon } from "../../../../res/img/compound/user.svg";
2731

2832
export enum PillType {
2933
UserMention = "TYPE_USER_MENTION",
3034
RoomMention = "TYPE_ROOM_MENTION",
3135
AtRoomMention = "TYPE_AT_ROOM_MENTION", // '@room' mention
36+
EventInSameRoom = "TYPE_EVENT_IN_SAME_ROOM",
37+
EventInOtherRoom = "TYPE_EVENT_IN_OTHER_ROOM",
3238
}
3339

3440
export const pillRoomNotifPos = (text: string): number => {
@@ -39,6 +45,34 @@ export const pillRoomNotifLen = (): number => {
3945
return "@room".length;
4046
};
4147

48+
const PillRoomAvatar: React.FC<{
49+
shouldShowPillAvatar: boolean;
50+
room: Room | null;
51+
}> = ({ shouldShowPillAvatar, room }) => {
52+
if (!shouldShowPillAvatar) {
53+
return null;
54+
}
55+
56+
if (room) {
57+
return <RoomAvatar room={room} width={16} height={16} aria-hidden="true" />;
58+
}
59+
return <LinkIcon className="mx_Pill_LinkIcon mx_BaseAvatar mx_BaseAvatar_image" />;
60+
};
61+
62+
const PillMemberAvatar: React.FC<{
63+
shouldShowPillAvatar: boolean;
64+
member: RoomMember | null;
65+
}> = ({ shouldShowPillAvatar, member }) => {
66+
if (!shouldShowPillAvatar) {
67+
return null;
68+
}
69+
70+
if (member) {
71+
return <MemberAvatar member={member} width={16} height={16} aria-hidden="true" hideTitle />;
72+
}
73+
return <UserIcon className="mx_Pill_UserIcon mx_BaseAvatar mx_BaseAvatar_image" />;
74+
};
75+
4276
export interface PillProps {
4377
// The Type of this Pill. If url is given, this is auto-detected.
4478
type?: PillType;
@@ -70,6 +104,7 @@ export const Pill: React.FC<PillProps> = ({ type: propType, url, inMessage, room
70104
mx_SpacePill: type === "space",
71105
mx_UserPill: type === PillType.UserMention,
72106
mx_UserPill_me: resourceId === MatrixClientPeg.get().getUserId(),
107+
mx_EventPill: type === PillType.EventInOtherRoom || type === PillType.EventInSameRoom,
73108
});
74109

75110
const onMouseOver = (): void => {
@@ -81,28 +116,55 @@ export const Pill: React.FC<PillProps> = ({ type: propType, url, inMessage, room
81116
};
82117

83118
const tip = hover && resourceId ? <Tooltip label={resourceId} alignment={Alignment.Right} /> : null;
84-
let avatar: ReactElement | null = null;
119+
let content: ReactElement | null = null;
85120

86121
switch (type) {
122+
case PillType.EventInOtherRoom:
123+
{
124+
const avatar = <PillRoomAvatar shouldShowPillAvatar={shouldShowPillAvatar} room={targetRoom} />;
125+
content = (
126+
<>
127+
{_t("Message in")}
128+
{avatar || " "}
129+
{text}
130+
</>
131+
);
132+
}
133+
break;
134+
case PillType.EventInSameRoom:
135+
{
136+
const avatar = <PillMemberAvatar shouldShowPillAvatar={shouldShowPillAvatar} member={member} />;
137+
content = (
138+
<>
139+
{_t("Message from")}
140+
{avatar || " "}
141+
{text}
142+
</>
143+
);
144+
}
145+
break;
87146
case PillType.AtRoomMention:
88147
case PillType.RoomMention:
89148
case "space":
90-
avatar = targetRoom ? <RoomAvatar room={targetRoom} width={16} height={16} aria-hidden="true" /> : null;
149+
content = (
150+
<>
151+
<PillRoomAvatar shouldShowPillAvatar={shouldShowPillAvatar} room={targetRoom} />
152+
{text}
153+
</>
154+
);
91155
break;
92156
case PillType.UserMention:
93-
avatar = <MemberAvatar member={member} width={16} height={16} aria-hidden="true" hideTitle />;
157+
content = (
158+
<>
159+
<PillMemberAvatar shouldShowPillAvatar={shouldShowPillAvatar} member={member} />
160+
{text}
161+
</>
162+
);
94163
break;
95164
default:
96165
return null;
97166
}
98167

99-
const content = (
100-
<>
101-
{shouldShowPillAvatar && avatar}
102-
<span className="mx_Pill_linkText">{text}</span>
103-
</>
104-
);
105-
106168
return (
107169
<bdi>
108170
<MatrixClientContext.Provider value={MatrixClientPeg.get()}>
@@ -114,12 +176,12 @@ export const Pill: React.FC<PillProps> = ({ type: propType, url, inMessage, room
114176
onMouseOver={onMouseOver}
115177
onMouseLeave={onMouseLeave}
116178
>
117-
{content}
179+
<span className="mx_Pill_content">{content}</span>
118180
{tip}
119181
</a>
120182
) : (
121183
<span className={classes} onMouseOver={onMouseOver} onMouseLeave={onMouseLeave}>
122-
{content}
184+
<span className="mx_Pill_content">{content}</span>
123185
{tip}
124186
</span>
125187
)}

0 commit comments

Comments
 (0)