Merge pull request #5575 from matrix-org/jryans/no-event-pills
Remove pills from event permalinks with textpull/21833/head
commit
89b835dd20
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
Copyright 2018 New Vector Ltd
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019, 2021 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -23,23 +23,11 @@ import { Room, RoomMember } from 'matrix-js-sdk';
|
|||
import PropTypes from 'prop-types';
|
||||
import {MatrixClientPeg} from '../../../MatrixClientPeg';
|
||||
import FlairStore from "../../../stores/FlairStore";
|
||||
import {getPrimaryPermalinkEntity} from "../../../utils/permalinks/Permalinks";
|
||||
import {getPrimaryPermalinkEntity, parseAppLocalLink} from "../../../utils/permalinks/Permalinks";
|
||||
import MatrixClientContext from "../../../contexts/MatrixClientContext";
|
||||
import {Action} from "../../../dispatcher/actions";
|
||||
|
||||
// For URLs of matrix.to links in the timeline which have been reformatted by
|
||||
// HttpUtils transformTags to relative links. This excludes event URLs (with `[^\/]*`)
|
||||
const REGEX_LOCAL_PERMALINK = /^#\/(?:user|room|group)\/(([#!@+]).*?)(?=\/|\?|$)/;
|
||||
|
||||
class Pill extends React.Component {
|
||||
static isPillUrl(url) {
|
||||
return !!getPrimaryPermalinkEntity(url);
|
||||
}
|
||||
|
||||
static isMessagePillUrl(url) {
|
||||
return !!REGEX_LOCAL_PERMALINK.exec(url);
|
||||
}
|
||||
|
||||
static roomNotifPos(text) {
|
||||
return text.indexOf("@room");
|
||||
}
|
||||
|
@ -56,7 +44,7 @@ class Pill extends React.Component {
|
|||
static propTypes = {
|
||||
// The Type of this Pill. If url is given, this is auto-detected.
|
||||
type: PropTypes.string,
|
||||
// The URL to pillify (no validation is done, see isPillUrl and isMessagePillUrl)
|
||||
// The URL to pillify (no validation is done)
|
||||
url: PropTypes.string,
|
||||
// Whether the pill is in a message
|
||||
inMessage: PropTypes.bool,
|
||||
|
@ -90,12 +78,9 @@ class Pill extends React.Component {
|
|||
|
||||
if (nextProps.url) {
|
||||
if (nextProps.inMessage) {
|
||||
// Default to the empty array if no match for simplicity
|
||||
// resource and prefix will be undefined instead of throwing
|
||||
const matrixToMatch = REGEX_LOCAL_PERMALINK.exec(nextProps.url) || [];
|
||||
|
||||
resourceId = matrixToMatch[1]; // The room/user ID
|
||||
prefix = matrixToMatch[2]; // The first character of prefix
|
||||
const parts = parseAppLocalLink(nextProps.url);
|
||||
resourceId = parts.primaryEntityId; // The room/user ID
|
||||
prefix = parts.sigil; // The first character of prefix
|
||||
} else {
|
||||
resourceId = getPrimaryPermalinkEntity(nextProps.url);
|
||||
prefix = resourceId ? resourceId[0] : undefined;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019, 2021 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -76,6 +76,10 @@ export default class ElementPermalinkConstructor extends PermalinkConstructor {
|
|||
}
|
||||
|
||||
const parts = fullUrl.substring(`${this._elementUrl}/#/`.length).split("/");
|
||||
return ElementPermalinkConstructor.parseLinkParts(parts);
|
||||
}
|
||||
|
||||
static parseLinkParts(parts: string[]): PermalinkParts {
|
||||
if (parts.length < 2) { // we're expecting an entity and an ID of some kind at least
|
||||
throw new Error("URL is missing parts");
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019, 2021 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -80,4 +80,12 @@ export class PermalinkParts {
|
|||
static forEvent(roomId: string, eventId: string, viaServers: string[]): PermalinkParts {
|
||||
return new PermalinkParts(roomId, eventId, null, null, viaServers || []);
|
||||
}
|
||||
|
||||
get primaryEntityId(): string {
|
||||
return this.roomIdOrAlias || this.userId || this.groupId;
|
||||
}
|
||||
|
||||
get sigil(): string {
|
||||
return this.primaryEntityId[0];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019 New Vector Ltd
|
||||
Copyright 2019, 2021 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -405,6 +405,23 @@ export function parsePermalink(fullUrl: string): PermalinkParts {
|
|||
return null; // not a permalink we can handle
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses an app local link (`#/(user|room|group)/identifer`) to a Matrix entity
|
||||
* (room, user, group). Such links are produced by `HtmlUtils` when encountering
|
||||
* links, which calls `tryTransformPermalinkToLocalHref` in this module.
|
||||
* @param {string} localLink The app local link
|
||||
* @returns {PermalinkParts}
|
||||
*/
|
||||
export function parseAppLocalLink(localLink: string): PermalinkParts {
|
||||
try {
|
||||
const segments = localLink.replace("#/", "").split("/");
|
||||
return ElementPermalinkConstructor.parseLinkParts(segments);
|
||||
} catch (e) {
|
||||
// Ignore failures
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function getServerName(userId) {
|
||||
return userId.split(":").splice(1).join(":");
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
|
||||
Copyright 2019, 2020, 2021 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
@ -19,7 +19,8 @@ import ReactDOM from 'react-dom';
|
|||
import {MatrixClientPeg} from '../MatrixClientPeg';
|
||||
import SettingsStore from "../settings/SettingsStore";
|
||||
import {PushProcessor} from 'matrix-js-sdk/src/pushprocessor';
|
||||
import * as sdk from '../index';
|
||||
import Pill from "../components/views/elements/Pill";
|
||||
import { parseAppLocalLink } from "./permalinks/Permalinks";
|
||||
|
||||
/**
|
||||
* Recurses depth-first through a DOM tree, converting matrix.to links
|
||||
|
@ -43,10 +44,10 @@ export function pillifyLinks(nodes, mxEvent, pills) {
|
|||
|
||||
if (node.tagName === "A" && node.getAttribute("href")) {
|
||||
const href = node.getAttribute("href");
|
||||
|
||||
const parts = parseAppLocalLink(href);
|
||||
// If the link is a (localised) matrix.to link, replace it with a pill
|
||||
const Pill = sdk.getComponent('elements.Pill');
|
||||
if (Pill.isMessagePillUrl(href)) {
|
||||
// We don't want to pill event permalinks, so those are ignored.
|
||||
if (parts && !parts.eventId) {
|
||||
const pillContainer = document.createElement('span');
|
||||
|
||||
const pill = <Pill
|
||||
|
@ -72,8 +73,6 @@ export function pillifyLinks(nodes, mxEvent, pills) {
|
|||
// to clear the pills from the last run of pillifyLinks
|
||||
!node.parentElement.classList.contains("mx_AtRoomPill")
|
||||
) {
|
||||
const Pill = sdk.getComponent('elements.Pill');
|
||||
|
||||
let currentTextNode = node;
|
||||
const roomNotifTextNodes = [];
|
||||
|
||||
|
|
|
@ -213,6 +213,35 @@ describe("<TextualBody />", () => {
|
|||
'style="width: 16px; height: 16px;" title="@member:domain.bla" alt="" aria-hidden="true">Member</a>' +
|
||||
'</span></span>');
|
||||
});
|
||||
|
||||
it("pills do not appear for event permalinks", () => {
|
||||
const ev = mkEvent({
|
||||
type: "m.room.message",
|
||||
room: "room_id",
|
||||
user: "sender",
|
||||
content: {
|
||||
body:
|
||||
"An [event link](https://matrix.to/#/!ZxbRYPQXDXKGmDnJNg:example.com/" +
|
||||
"$16085560162aNpaH:example.com?via=example.com) with text",
|
||||
msgtype: "m.text",
|
||||
format: "org.matrix.custom.html",
|
||||
formatted_body:
|
||||
"An <a href=\"https://matrix.to/#/!ZxbRYPQXDXKGmDnJNg:example.com/" +
|
||||
"$16085560162aNpaH:example.com?via=example.com\">event link</a> with text",
|
||||
},
|
||||
event: true,
|
||||
});
|
||||
|
||||
const wrapper = mount(<TextualBody mxEvent={ev} />);
|
||||
expect(wrapper.text()).toBe("An event link with text");
|
||||
const content = wrapper.find(".mx_EventTile_body");
|
||||
expect(content.html()).toBe(
|
||||
'<span class="mx_EventTile_body markdown-body" dir="auto">' +
|
||||
'An <a href="#/room/!ZxbRYPQXDXKGmDnJNg:example.com/' +
|
||||
'$16085560162aNpaH:example.com?via=example.com" ' +
|
||||
'rel="noreferrer noopener">event link</a> with text</span>',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("renders url previews correctly", () => {
|
||||
|
|
Loading…
Reference in New Issue