diff --git a/src/TextForEvent.js b/src/TextForEvent.js index c8d0a0a0f7..d39ebd6c0a 100644 --- a/src/TextForEvent.js +++ b/src/TextForEvent.js @@ -149,19 +149,32 @@ function textForRoomAliasesEvent(ev) { if (addedAliases.length && !removedAliases.length) { return _t('%(senderName)s added %(addedAddresses)s as addresses for this room.', { senderName: senderName, + count: addedAliases.length, addedAddresses: addedAliases.join(', '), }); } else if (!addedAliases.length && removedAliases.length) { - return _t('%(senderName)s removed %(addresses)s as addresses for this room.', { + return _t('%(senderName)s removed %(removedAddresses)s as addresses for this room.', { senderName: senderName, + count: removedAliases.length, removedAddresses: removedAliases.join(', '), }); } else { - return _t('%(senderName)s added %(addedAddresses)s and removed %(removedAddresses)s as addresses for this room.', { + const args = { senderName: senderName, addedAddresses: addedAliases.join(', '), removedAddresses: removedAliases.join(', '), - }); + }; + /* eslint-disable max-len */ + if (addedAliases.length === 1 && removedAliases.length === 1) { + return _t('%(senderName)s added %(addedAddresses)s and removed %(removedAddresses)s as addresses for this room.|one,one', args); + } else if (addedAliases.length !== 1 && removedAliases.length === 1) { + return _t('%(senderName)s added %(addedAddresses)s and removed %(removedAddresses)s as addresses for this room.|other,one', args); + } else if (addedAliases.length === 1 && removedAliases.length !== 1) { + return _t('%(senderName)s added %(addedAddresses)s and removed %(removedAddresses)s as addresses for this room.|one,other', args); + } else { + return _t('%(senderName)s added %(addedAddresses)s and removed %(removedAddresses)s as addresses for this room.|other,other', args); + } + /* eslint-enable max-len */ } } diff --git a/src/components/views/messages/RoomAliasesEvent.js b/src/components/views/messages/RoomAliasesEvent.js new file mode 100644 index 0000000000..7d9b2e6795 --- /dev/null +++ b/src/components/views/messages/RoomAliasesEvent.js @@ -0,0 +1,161 @@ +/* +Michael Telatynski <7t3chguy@gmail.com> + +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. +*/ + +'use strict'; + +import React from 'react'; +import PropTypes from 'prop-types'; +import { _t } from '../../../languageHandler'; + +export class GenericEventListSummary extends React.Component { + static propTypes = { + // An summary to display when collapsed + summary: PropTypes.string.isRequired, + // whether to show summary whilst children are expanded + alwaysShowSummary: PropTypes.bool, + // An array of EventTiles to render when expanded + children: PropTypes.array.isRequired, + // Called when the GELS expansion is toggled + onToggle: PropTypes.func, + // how many children should cause GELS to act + threshold: PropTypes.number.isRequired, + }; + + static defaultProps = { + threshold: 1, + }; + + constructor(props, context) { + super(props, context); + this._toggleSummary = this._toggleSummary.bind(this); + } + + state = { + expanded: false, + }; + + _toggleSummary() { + this.setState({expanded: !this.state.expanded}); + this.props.onToggle(); + } + + render() { + const fewEvents = this.props.children.length < this.props.threshold; + const expanded = this.state.expanded || fewEvents; + const showSummary = !expanded || this.props.alwaysShowSummary; + + let expandedEvents = null; + if (expanded) { + expandedEvents = this.props.children; + } + + if (fewEvents) { + return <div className="mx_MemberEventListSummary">{ expandedEvents }</div>; + } + + let summaryContainer = null; + if (showSummary) { + summaryContainer = ( + <div className="mx_EventTile_line"> + <div className="mx_EventTile_info"> + {this.props.summary} + </div> + </div> + ); + } + let toggleButton = null; + if (!fewEvents) { + toggleButton = <div className={"mx_MemberEventListSummary_toggle"} onClick={this._toggleSummary}> + {expanded ? 'collapse' : 'expand'} + </div>; + } + + return ( + <div className="mx_MemberEventListSummary"> + {toggleButton} + {summaryContainer} + {/*{showSummary ? <div className="mx_MemberEventListSummary_line"> </div> : null}*/} + {expandedEvents} + </div> + ); + } +} + +export default class RoomAliasesEvent extends React.Component { + static PropTypes = { + /* the MatrixEvent to show */ + mxEvent: PropTypes.object.isRequired, + + /* the shsape of the tile, used */ + tileShape: PropTypes.string, + }; + + getEventTileOps() { + return this.refs.body && this.refs.body.getEventTileOps ? this.refs.body.getEventTileOps() : null; + } + + render() { + const senderName = this.props.mxEvent.sender ? this.props.mxEvent.sender.name : this.props.mxEvent.getSender(); + const oldAliases = this.props.mxEvent.getPrevContent().aliases || []; + const newAliases = this.props.mxEvent.getContent().aliases || []; + + const addedAliases = newAliases.filter((x) => !oldAliases.includes(x)); + const removedAliases = oldAliases.filter((x) => !newAliases.includes(x)); + + if (!addedAliases.length && !removedAliases.length) { + return ''; + } + + if (addedAliases.length && !removedAliases.length) { + return <div>{_t('%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.', { + senderName: senderName, + count: addedAliases.length, + addedAddresses: addedAliases.join(', '), + })}</div>; + } else if (!addedAliases.length && removedAliases.length) { + return <div>{_t('%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.', { + senderName: senderName, + count: removedAliases.length, + removedAddresses: removedAliases.join(', '), + })}</div>; + } else { + // const args = { + // senderName: senderName, + // addedAddresses: addedAliases.join(', '), + // removedAddresses: removedAliases.join(', '), + // }; + + const changes = []; + addedAliases.forEach((alias) => { + changes.push(<div key={'+' + alias}>Added {alias}</div>); + }); + removedAliases.forEach((alias) => { + changes.push(<div key={'-' + alias}>Removed {alias}</div>); + }); + + const summary = _t('%(senderName)s changed the addresses of this room.', {senderName}); + return <GenericEventListSummary alwaysShowSummary={true} summary={summary}> + {changes} + </GenericEventListSummary>; + } + + // return <BodyType ref="body" mxEvent={this.props.mxEvent} highlights={this.props.highlights} + // highlightLink={this.props.highlightLink} + // showUrlPreview={this.props.showUrlPreview} + // tileShape={this.props.tileShape} + // onWidgetLoad={this.props.onWidgetLoad} />; + } +} diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 647b8a0f5d..10f0b85936 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -33,7 +33,7 @@ var ObjectUtils = require('../../../ObjectUtils'); var eventTileTypes = { 'm.room.message': 'messages.MessageEvent', - 'm.room.aliases': 'messages.TextualEvent', + 'm.room.aliases': 'messages.RoomAliasesEvent', 'm.room.member' : 'messages.TextualEvent', 'm.call.invite' : 'messages.TextualEvent', 'm.call.answer' : 'messages.TextualEvent', diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index de0b8e9ebb..5ee29b6314 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -853,5 +853,10 @@ "%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s", "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s", "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget modified by %(senderName)s", - "Robot check is currently unavailable on desktop - please use a <a>web browser</a>": "Robot check is currently unavailable on desktop - please use a <a>web browser</a>" + "Robot check is currently unavailable on desktop - please use a <a>web browser</a>": "Robot check is currently unavailable on desktop - please use a <a>web browser</a>", + "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|one": "%(senderName)s added %(addedAddresses)s as an address for this room.", + "%(senderName)s added %(count)s %(addedAddresses)s as addresses for this room.|other": "%(senderName)s added %(addedAddresses)s as addresses for this room.", + "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|one": "%(senderName)s removed %(removedAddresses)s as an address for this room.", + "%(senderName)s removed %(count)s %(removedAddresses)s as addresses for this room.|other": "%(senderName)s removed %(removedAddresses)s as addresses for this room.", + "%(senderName)s changed the addresses of this room.": "%(senderName)s changed the addresses of this room." }