From 434660166cd59f469dc39c1ccf62e3ae124e8fdd Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Fri, 14 Jul 2017 17:04:28 +0100 Subject: [PATCH] Decorate http://matrix.to links in the composer as pills Any links in the composer that are recognised as matrix.to links will be decorated as ``s with CSS classes (one of mx_UserPill or mx_RoomPill). This implementation has the nice bonus that switching to markdown (and back) will Just Work. This will have some CSS changes coming to better match the design. --- .../views/rooms/MessageComposerInput.js | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 3c422b7c8a..d4ae55f03a 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -26,6 +26,7 @@ import Promise from 'bluebird'; import MatrixClientPeg from '../../../MatrixClientPeg'; import type {MatrixClient} from 'matrix-js-sdk/lib/matrix'; +import {RoomMember} from 'matrix-js-sdk'; import SlashCommands from '../../../SlashCommands'; import KeyCode from '../../../KeyCode'; import Modal from '../../../Modal'; @@ -43,6 +44,9 @@ import Markdown from '../../../Markdown'; import ComposerHistoryManager from '../../../ComposerHistoryManager'; import MessageComposerStore from '../../../stores/MessageComposerStore'; +import {MATRIXTO_URL_PATTERN} from '../../../linkify-matrix'; +const REGEX_MATRIXTO = new RegExp(MATRIXTO_URL_PATTERN); + import {asciiRegexp, shortnameToUnicode, emojioneList, asciiList, mapUnicodeToShort} from 'emojione'; const EMOJI_SHORTNAMES = Object.keys(emojioneList); const EMOJI_UNICODE_TO_SHORTNAME = mapUnicodeToShort(); @@ -183,7 +187,42 @@ export default class MessageComposerInput extends React.Component { decorators.push({ strategy: this.findLinkEntities.bind(this), component: (props) => { + const MemberAvatar = sdk.getComponent('avatars.MemberAvatar'); + const RoomAvatar = sdk.getComponent('avatars.RoomAvatar'); const {url} = Entity.get(props.entityKey).getData(); + const matrixToMatch = REGEX_MATRIXTO.exec(url); + const isUserPill = matrixToMatch[2] === '@'; + const isRoomPill = matrixToMatch[2] === '#' || matrixToMatch[2] === '!'; + + const classes = classNames({ + "mx_UserPill": isUserPill, + "mx_RoomPill": isRoomPill, + }); + + let avatar = null; + if (isUserPill) { + // If this user is not a member of this room, default to the empty + // member. This could be improved by doing an async profile lookup. + const member = this.props.room.getMember(matrixToMatch[1]) || + new RoomMember(null, matrixToMatch[1]); + avatar = member ? : null; + } else if (isRoomPill) { + const room = matrixToMatch[2] === '#' ? + MatrixClientPeg.get().getRooms().find((r) => { + return r.getCanonicalAlias() === matrixToMatch[1]; + }) : MatrixClientPeg.get().getRoom(matrixToMatch[1]); + avatar = room ? : null; + } + + if (isUserPill || isRoomPill) { + return ( + + {avatar} + {props.children} + + ); + } + return ( {props.children}