2017-07-21 13:41:23 +01:00
|
|
|
/*
|
2021-03-05 18:49:32 -07:00
|
|
|
Copyright 2017 - 2019, 2021 The Matrix.org Foundation C.I.C.
|
2017-07-21 13:41:23 +01:00
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
|
limitations under the License.
|
|
|
|
|
*/
|
2022-05-05 11:13:09 +02:00
|
|
|
|
2023-03-08 13:06:50 +01:00
|
|
|
import React, { useState } from "react";
|
2017-07-21 13:41:23 +01:00
|
|
|
import classNames from "classnames";
|
2021-03-18 20:50:34 -06:00
|
|
|
import { Room } from "matrix-js-sdk/src/models/room";
|
2021-10-22 17:23:32 -05:00
|
|
|
|
2021-06-29 13:11:58 +01:00
|
|
|
import { MatrixClientPeg } from "../../../MatrixClientPeg";
|
2019-12-17 17:26:12 +00:00
|
|
|
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
2023-03-08 13:06:50 +01:00
|
|
|
import Tooltip, { Alignment } from "../elements/Tooltip";
|
|
|
|
|
import { usePermalink } from "../../../hooks/usePermalink";
|
2017-07-21 13:41:23 +01:00
|
|
|
|
2022-05-05 11:13:09 +02:00
|
|
|
export enum PillType {
|
|
|
|
|
UserMention = "TYPE_USER_MENTION",
|
|
|
|
|
RoomMention = "TYPE_ROOM_MENTION",
|
|
|
|
|
AtRoomMention = "TYPE_AT_ROOM_MENTION", // '@room' mention
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-08 13:06:50 +01:00
|
|
|
export const pillRoomNotifPos = (text: string): number => {
|
|
|
|
|
return text.indexOf("@room");
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const pillRoomNotifLen = (): number => {
|
|
|
|
|
return "@room".length;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export interface PillProps {
|
2022-05-05 11:13:09 +02:00
|
|
|
// The Type of this Pill. If url is given, this is auto-detected.
|
|
|
|
|
type?: PillType;
|
|
|
|
|
// The URL to pillify (no validation is done)
|
|
|
|
|
url?: string;
|
2023-03-08 13:06:50 +01:00
|
|
|
/** Whether the pill is in a message. It will act as a link then. */
|
2022-05-05 11:13:09 +02:00
|
|
|
inMessage?: boolean;
|
|
|
|
|
// The room in which this pill is being rendered
|
|
|
|
|
room?: Room;
|
|
|
|
|
// Whether to include an avatar in the pill
|
|
|
|
|
shouldShowPillAvatar?: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-08 13:06:50 +01:00
|
|
|
export const Pill: React.FC<PillProps> = ({ type: propType, url, inMessage, room, shouldShowPillAvatar }) => {
|
|
|
|
|
const [hover, setHover] = useState(false);
|
|
|
|
|
const { avatar, onClick, resourceId, text, type } = usePermalink({
|
|
|
|
|
room,
|
|
|
|
|
type: propType,
|
|
|
|
|
url,
|
|
|
|
|
});
|
2022-05-05 11:13:09 +02:00
|
|
|
|
2023-03-08 13:06:50 +01:00
|
|
|
if (!type) {
|
|
|
|
|
return null;
|
2020-08-29 12:14:16 +01:00
|
|
|
}
|
|
|
|
|
|
2023-03-08 13:06:50 +01:00
|
|
|
const classes = classNames("mx_Pill", {
|
|
|
|
|
mx_AtRoomPill: type === PillType.AtRoomMention,
|
|
|
|
|
mx_RoomPill: type === PillType.RoomMention,
|
|
|
|
|
mx_SpacePill: type === "space",
|
|
|
|
|
mx_UserPill: type === PillType.UserMention,
|
|
|
|
|
mx_UserPill_me: resourceId === MatrixClientPeg.get().getUserId(),
|
|
|
|
|
});
|
2020-08-29 12:14:16 +01:00
|
|
|
|
2023-03-08 13:06:50 +01:00
|
|
|
const onMouseOver = (): void => {
|
|
|
|
|
setHover(true);
|
2021-02-12 08:18:27 +01:00
|
|
|
};
|
|
|
|
|
|
2023-03-08 13:06:50 +01:00
|
|
|
const onMouseLeave = (): void => {
|
|
|
|
|
setHover(false);
|
2021-02-12 08:18:27 +01:00
|
|
|
};
|
|
|
|
|
|
2023-03-08 13:06:50 +01:00
|
|
|
const tip = hover && resourceId ? <Tooltip label={resourceId} alignment={Alignment.Right} /> : null;
|
2017-07-24 17:18:29 +01:00
|
|
|
|
2023-03-08 13:06:50 +01:00
|
|
|
return (
|
|
|
|
|
<bdi>
|
|
|
|
|
<MatrixClientContext.Provider value={MatrixClientPeg.get()}>
|
|
|
|
|
{inMessage && url ? (
|
|
|
|
|
<a
|
|
|
|
|
className={classes}
|
|
|
|
|
href={url}
|
|
|
|
|
onClick={onClick}
|
|
|
|
|
onMouseOver={onMouseOver}
|
|
|
|
|
onMouseLeave={onMouseLeave}
|
|
|
|
|
>
|
|
|
|
|
{shouldShowPillAvatar && avatar}
|
|
|
|
|
<span className="mx_Pill_linkText">{text}</span>
|
|
|
|
|
{tip}
|
|
|
|
|
</a>
|
|
|
|
|
) : (
|
|
|
|
|
<span className={classes} onMouseOver={onMouseOver} onMouseLeave={onMouseLeave}>
|
|
|
|
|
{shouldShowPillAvatar && avatar}
|
|
|
|
|
<span className="mx_Pill_linkText">{text}</span>
|
|
|
|
|
{tip}
|
|
|
|
|
</span>
|
|
|
|
|
)}
|
|
|
|
|
</MatrixClientContext.Provider>
|
|
|
|
|
</bdi>
|
|
|
|
|
);
|
|
|
|
|
};
|