From 798d68b4c800476d588d8d3f162c876d1c53a067 Mon Sep 17 00:00:00 2001 From: Zero Date: Mon, 14 Aug 2017 19:42:00 +0200 Subject: [PATCH 01/41] Include magnet scheme in sanitize HTML params Update HtmlUtils sanitze-html params to include the magnet scheme --- src/HtmlUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 87e714083b..f1ce6a6a12 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -152,7 +152,7 @@ const sanitizeHtmlParams = { // Lots of these won't come up by default because we don't allow them selfClosing: ['img', 'br', 'hr', 'area', 'base', 'basefont', 'input', 'link', 'meta'], // URL schemes we permit - allowedSchemes: ['http', 'https', 'ftp', 'mailto'], + allowedSchemes: ['http', 'https', 'ftp', 'mailto', 'magnet'], allowProtocolRelative: false, From d1af424b3fad847b725270f519e932275808a06e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 6 Sep 2017 10:56:08 +0100 Subject: [PATCH 02/41] allow hiding of notification body for privacy reasons Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/Notifier.js | 22 ++++++++++++++++++---- src/UserSettingsStore.js | 11 +++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/Notifier.js b/src/Notifier.js index 155564dcdf..93ef192fe0 100644 --- a/src/Notifier.js +++ b/src/Notifier.js @@ -80,10 +80,11 @@ const Notifier = { if (ev.getContent().body) msg = ev.getContent().body; } - const avatarUrl = ev.sender ? Avatar.avatarUrlForMember( - ev.sender, 40, 40, 'crop' - ) : null; + if (!this.isBodyEnabled()) { + msg = ''; + } + const avatarUrl = ev.sender ? Avatar.avatarUrlForMember(ev.sender, 40, 40, 'crop') : null; const notif = plaf.displayNotification(title, msg, avatarUrl, room); // if displayNotification returns non-null, the platform supports @@ -195,6 +196,19 @@ const Notifier = { return enabled === 'true'; }, + setBodyEnabled: function(enable) { + if (!global.localStorage) return; + global.localStorage.setItem('notifications_body_enabled', enable ? 'true' : 'false'); + }, + + isBodyEnabled: function() { + if (!global.localStorage) return true; + const enabled = global.localStorage.getItem('notifications_body_enabled'); + // default to true if the popups are enabled + if (enabled === null) return this.isEnabled(); + return enabled === 'true'; + }, + setAudioEnabled: function(enable) { if (!global.localStorage) return; global.localStorage.setItem('audio_notifications_enabled', @@ -303,7 +317,7 @@ const Notifier = { this._playAudioNotification(ev, room); } } - } + }, }; if (!global.mxNotifier) { diff --git a/src/UserSettingsStore.js b/src/UserSettingsStore.js index 68a1ba229f..ec95c99e6b 100644 --- a/src/UserSettingsStore.js +++ b/src/UserSettingsStore.js @@ -73,6 +73,17 @@ export default { Notifier.setEnabled(enable); }, + getEnableNotificationBody: function() { + return Notifier.isBodyEnabled(); + }, + + setEnableNotificationBody: function(enable) { + if (!Notifier.supportsDesktopNotifications()) { + return; + } + Notifier.setBodyEnabled(enable); + }, + getEnableAudioNotifications: function() { return Notifier.isAudioEnabled(); }, From 3a58e1c0665c3f0b12ec2d26723f0ceb61105268 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 28 Sep 2017 11:03:13 -0600 Subject: [PATCH 03/41] Show pinned message changes in the timeline Signed-off-by: Travis Ralston --- src/TextForEvent.js | 6 ++++++ src/components/views/rooms/EventTile.js | 1 + src/i18n/strings/en_EN.json | 1 + src/i18n/strings/en_US.json | 1 + 4 files changed, 9 insertions(+) diff --git a/src/TextForEvent.js b/src/TextForEvent.js index a21eb5c251..06b847c19a 100644 --- a/src/TextForEvent.js +++ b/src/TextForEvent.js @@ -259,6 +259,11 @@ function textForPowerEvent(event) { }); } +function textForPinnedEvent(event) { + const senderName = event.getSender(); + return _t("%(senderName)s changed the pinned messages for the room.", {senderName}); +} + function textForWidgetEvent(event) { const senderName = event.getSender(); const {name: prevName, type: prevType, url: prevUrl} = event.getPrevContent(); @@ -301,6 +306,7 @@ const handlers = { 'm.room.history_visibility': textForHistoryVisibilityEvent, 'm.room.encryption': textForEncryptionEvent, 'm.room.power_levels': textForPowerEvent, + 'm.room.pinned_events': textForPinnedEvent, 'im.vector.modular.widgets': textForWidgetEvent, }; diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 7328cfe0b6..9bdee42cc1 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -44,6 +44,7 @@ var eventTileTypes = { 'm.room.history_visibility' : 'messages.TextualEvent', 'm.room.encryption' : 'messages.TextualEvent', 'm.room.power_levels' : 'messages.TextualEvent', + 'm.room.pinned_events' : 'messages.TextualEvent', 'im.vector.modular.widgets': 'messages.TextualEvent', }; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 87fd6d4364..0cd70c91c3 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -875,6 +875,7 @@ "Add rooms to the group summary": "Add rooms to the group summary", "Which rooms would you like to add to this summary?": "Which rooms would you like to add to this summary?", "Room name or alias": "Room name or alias", + "%(senderName)s changed the pinned messages for the room.": "%(senderName)s changed the pinned messages for the room.", "You are an administrator of this group": "You are an administrator of this group", "Failed to add the following rooms to the summary of %(groupId)s:": "Failed to add the following rooms to the summary of %(groupId)s:", "Failed to remove the room from the summary of %(groupId)s": "Failed to remove the room from the summary of %(groupId)s", diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index 928f1a9d0f..1ec7bbce83 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -852,6 +852,7 @@ "%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s", "Robot check is currently unavailable on desktop - please use a web browser": "Robot check is currently unavailable on desktop - please use a web browser", "Verifies a user, device, and pubkey tuple": "Verifies a user, device, and pubkey tuple", + "%(senderName)s changed the pinned messages for the room.": "%(senderName)s changed the pinned messages for the room.", "It is currently only possible to create groups on your own home server: use a group ID ending with %(domain)s": "It is currently only possible to create groups on your own home server: use a group ID ending with %(domain)s", "To join an existing group you'll have to know its group identifier; this will look something like +example:matrix.org.": "To join an existing group you'll have to know its group identifier; this will look something like +example:matrix.org." } From 874d383a8fdfaffbb6dd605e45209d663e2120db Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 28 Sep 2017 15:32:51 -0600 Subject: [PATCH 04/41] Add dock for pinned messages at the top of the room Signed-off-by: Travis Ralston --- src/components/structures/RoomView.js | 14 ++++++++++++-- src/components/views/rooms/RoomHeader.js | 10 ++++++++++ src/i18n/strings/en_EN.json | 1 + src/i18n/strings/en_US.json | 1 + 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index e0332b1b19..5b07459299 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -1128,6 +1128,10 @@ module.exports = React.createClass({ return ret; }, + onPinnedClick: function() { + this.setState({showingPinned: !this.state.showingPinned, searching: false}); + }, + onSettingsClick: function() { this.showSettings(true); }, @@ -1248,7 +1252,7 @@ module.exports = React.createClass({ }, onSearchClick: function() { - this.setState({ searching: true }); + this.setState({ searching: true, showingPinned: false }); }, onCancelSearchClick: function() { @@ -1447,6 +1451,7 @@ module.exports = React.createClass({ const RoomSettings = sdk.getComponent("rooms.RoomSettings"); const AuxPanel = sdk.getComponent("rooms.AuxPanel"); const SearchBar = sdk.getComponent("rooms.SearchBar"); + const PinnedEventsPanel = sdk.getComponent("rooms.PinnedEventsPanel"); const ScrollPanel = sdk.getComponent("structures.ScrollPanel"); const TintableSvg = sdk.getComponent("elements.TintableSvg"); const RoomPreviewBar = sdk.getComponent("rooms.RoomPreviewBar"); @@ -1587,7 +1592,11 @@ module.exports = React.createClass({ aux = ; } else if (this.state.searching) { hideCancel = true; // has own cancel - aux = ; + aux = ; + } else if (this.state.showingPinned) { + hideCancel = true; // has own cancel + aux = ; } else if (!myMember || myMember.membership !== "join") { // We do have a room object for this room, but we're not currently in it. // We may have a 3rd party invite to it. @@ -1761,6 +1770,7 @@ module.exports = React.createClass({ collapsedRhs={ this.props.collapsedRhs } onSearchClick={this.onSearchClick} onSettingsClick={this.onSettingsClick} + onPinnedClick={this.onPinnedClick} onSaveClick={this.onSettingsSaveClick} onCancelClick={(aux && !hideCancel) ? this.onCancelClick : null} onForgetClick={(myMember && myMember.membership === "leave") ? this.onForgetClick : null} diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js index 42cbb90cd9..3e02db5793 100644 --- a/src/components/views/rooms/RoomHeader.js +++ b/src/components/views/rooms/RoomHeader.js @@ -45,6 +45,7 @@ module.exports = React.createClass({ inRoom: React.PropTypes.bool, collapsedRhs: React.PropTypes.bool, onSettingsClick: React.PropTypes.func, + onPinnedClick: React.PropTypes.func, onSaveClick: React.PropTypes.func, onSearchClick: React.PropTypes.func, onLeaveClick: React.PropTypes.func, @@ -172,6 +173,7 @@ module.exports = React.createClass({ let spinner = null; let saveButton = null; let settingsButton = null; + let pinnedEventsButton = null; let canSetRoomName; let canSetRoomAvatar; @@ -290,6 +292,13 @@ module.exports = React.createClass({ ; } + if (this.props.onPinnedClick) { + pinnedEventsButton = + + + ; + } + // var leave_button; // if (this.props.onLeaveClick) { // leave_button = @@ -334,6 +343,7 @@ module.exports = React.createClass({ rightRow =
{ settingsButton } + { pinnedEventsButton } { manageIntegsButton } { forgetButton } { searchButton } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 0cd70c91c3..7adcb02f64 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -875,6 +875,7 @@ "Add rooms to the group summary": "Add rooms to the group summary", "Which rooms would you like to add to this summary?": "Which rooms would you like to add to this summary?", "Room name or alias": "Room name or alias", + "Pinned Messages": "Pinned Messages", "%(senderName)s changed the pinned messages for the room.": "%(senderName)s changed the pinned messages for the room.", "You are an administrator of this group": "You are an administrator of this group", "Failed to add the following rooms to the summary of %(groupId)s:": "Failed to add the following rooms to the summary of %(groupId)s:", diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index 1ec7bbce83..98796ff32e 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -837,6 +837,7 @@ "+example:%(domain)s": "+example:%(domain)s", "Group IDs must be of the form +localpart:%(domain)s": "Group IDs must be of the form +localpart:%(domain)s", "Room creation failed": "Room creation failed", + "Pinned Messages": "Pinned Messages", "You are a member of these groups:": "You are a member of these groups:", "Create a group to represent your community! Define a set of rooms and your own custom homepage to mark out your space in the Matrix universe.": "Create a group to represent your community! Define a set of rooms and your own custom homepage to mark out your space in the Matrix universe.", "Join an existing group": "Join an existing group", From f71e07670d193e127836f769be9f70ddab5c9390 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 28 Sep 2017 17:00:26 -0600 Subject: [PATCH 05/41] Send toggle handler for the cancel button in the pinned events pane Signed-off-by: Travis Ralston --- src/components/structures/RoomView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 5b07459299..23e5833468 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -1596,7 +1596,7 @@ module.exports = React.createClass({ onCancelClick={this.onCancelSearchClick} onSearch={this.onSearch}/>; } else if (this.state.showingPinned) { hideCancel = true; // has own cancel - aux = ; + aux = ; } else if (!myMember || myMember.membership !== "join") { // We do have a room object for this room, but we're not currently in it. // We may have a 3rd party invite to it. From 0f2fd9f69882b6fed86615d9b04e3b4c1a5d2cbd Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 29 Sep 2017 13:14:56 -0600 Subject: [PATCH 06/41] Move the PinnedEventsPanel to the react-sdk Signed-off-by: Travis Ralston --- src/components/views/rooms/PinnedEventTile.js | 86 +++++++++++++++ .../views/rooms/PinnedEventsPanel.js | 101 ++++++++++++++++++ 2 files changed, 187 insertions(+) create mode 100644 src/components/views/rooms/PinnedEventTile.js create mode 100644 src/components/views/rooms/PinnedEventsPanel.js diff --git a/src/components/views/rooms/PinnedEventTile.js b/src/components/views/rooms/PinnedEventTile.js new file mode 100644 index 0000000000..555718709b --- /dev/null +++ b/src/components/views/rooms/PinnedEventTile.js @@ -0,0 +1,86 @@ +/* +Copyright 2017 Travis Ralston + +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. +*/ + +import React from "react"; +import MatrixClientPeg from "../../../MatrixClientPeg"; +import dis from "../../../dispatcher"; +import AccessibleButton from "../elements/AccessibleButton"; +import MessageEvent from "../messages/MessageEvent"; +import MemberAvatar from "../avatars/MemberAvatar"; +import { _t } from '../../../languageHandler'; + +module.exports = React.createClass({ + displayName: 'PinnedEventTile', + propTypes: { + mxRoom: React.PropTypes.object.isRequired, + mxEvent: React.PropTypes.object.isRequired, + onUnpinned: React.PropTypes.func, + }, + onTileClicked: function() { + dis.dispatch({ + action: 'view_room', + event_id: this.props.mxEvent.getId(), + highlighted: true, + room_id: this.props.mxEvent.getRoomId(), + }); + }, + onUnpinClicked: function() { + const pinnedEvents = this.props.mxRoom.currentState.getStateEvents("m.room.pinned_events", ""); + if (!pinnedEvents || !pinnedEvents.getContent().pinned) { + // Nothing to do: already unpinned + if (this.props.onUnpinned) this.props.onUnpinned(); + } else { + const pinned = pinnedEvents.getContent().pinned; + const index = pinned.indexOf(this.props.mxEvent.getId()); + if (index !== -1) { + pinned.splice(index, 1); + MatrixClientPeg.get().sendStateEvent(this.props.mxRoom.roomId, 'm.room.pinned_events', {pinned}, '').then(() => { + if (this.props.onUnpinned) this.props.onUnpinned(); + }); + } else if (this.props.onUnpinned) this.props.onUnpinned(); + } + }, + _canUnpin: function() { + return this.props.mxRoom.currentState.mayClientSendStateEvent('m.room.pinned_events', MatrixClientPeg.get()); + }, + render: function() { + const sender = this.props.mxRoom.getMember(this.props.mxEvent.getSender()); + const avatarSize = 40; + + let unpinButton = null; + if (this._canUnpin()) { + unpinButton = {_t('Unpin; + } + + return ( +
+
+ + { _t("Jump to message") } + + { unpinButton } +
+ + + + {sender.name} + + +
+ ); + } +}); diff --git a/src/components/views/rooms/PinnedEventsPanel.js b/src/components/views/rooms/PinnedEventsPanel.js new file mode 100644 index 0000000000..02df29fc72 --- /dev/null +++ b/src/components/views/rooms/PinnedEventsPanel.js @@ -0,0 +1,101 @@ +/* +Copyright 2017 Travis Ralston + +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. +*/ + +import React from "react"; +import MatrixClientPeg from "../../../MatrixClientPeg"; +import AccessibleButton from "../elements/AccessibleButton"; +import PinnedEventTile from "./PinnedEventTile"; +import { _t } from '../../../languageHandler'; + +module.exports = React.createClass({ + displayName: 'PinnedEventsPanel', + propTypes: { + // The Room from the js-sdk we're going to show pinned events for + room: React.PropTypes.object.isRequired, + + onCancelClick: React.PropTypes.func, + }, + + getInitialState: function() { + return { + loading: true, + }; + }, + + componentDidMount: function() { + this._updatePinnedMessages(); + }, + + _updatePinnedMessages: function() { + const pinnedEvents = this.props.room.currentState.getStateEvents("m.room.pinned_events", ""); + if (!pinnedEvents || !pinnedEvents.getContent().pinned) { + this.setState({ loading: false, pinned: [] }); + } else { + const promises = []; + const cli = MatrixClientPeg.get(); + + pinnedEvents.getContent().pinned.map(eventId => { + promises.push(cli.getEventTimeline(this.props.room.getUnfilteredTimelineSet(), eventId, 0).then(timeline => { + const event = timeline.getEvents().find(e => e.getId() === eventId); + return {eventId, timeline, event}; + }).catch(err => { + console.error("Error looking up pinned event " + eventId + " in room " + this.props.room.roomId); + console.error(err); + return null; // return lack of context to avoid unhandled errors + })); + }); + + Promise.all(promises).then(contexts => { + // Filter out the messages before we try to render them + const pinned = contexts.filter(context => { + if (!context) return false; // no context == not applicable for the room + if (context.event.getType() !== "m.room.message") return false; + if (context.event.isRedacted()) return false; + return true; + }); + + this.setState({ loading: false, pinned }); + }); + } + }, + + _getPinnedTiles: function() { + if (this.state.pinned.length == 0) { + return (
{ _t("No pinned messages.") }
); + } + + return this.state.pinned.map(context => { + return (); + }); + }, + + render: function() { + let tiles =
{ _t("Loading...") }
; + if (this.state && !this.state.loading) { + tiles = this._getPinnedTiles(); + } + + return ( +
+
+ +

{_t("Pinned Messages")}

+ { tiles } +
+
+ ); + } +}); From a01387f7a63757fc64eac730165a7d288c801ebd Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 29 Sep 2017 13:32:25 -0600 Subject: [PATCH 07/41] Use an AccessibleButton for unpinning from the pane. Signed-off-by: Travis Ralston --- src/components/views/rooms/PinnedEventTile.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/PinnedEventTile.js b/src/components/views/rooms/PinnedEventTile.js index 555718709b..e4b5b1ff96 100644 --- a/src/components/views/rooms/PinnedEventTile.js +++ b/src/components/views/rooms/PinnedEventTile.js @@ -62,8 +62,11 @@ module.exports = React.createClass({ let unpinButton = null; if (this._canUnpin()) { - unpinButton = {_t('Unpin; + unpinButton = ( + + {_t('Unpin + + ); } return ( From 0e2a1c90d55a5b6bedd9c7332bff18bd2ba4ed47 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 29 Sep 2017 16:08:50 -0600 Subject: [PATCH 08/41] Don't suggest grey as a color scheme for a room Fixes https://github.com/vector-im/riot-web/issues/5045 Signed-off-by: Travis Ralston --- src/components/views/room_settings/ColorSettings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/room_settings/ColorSettings.js b/src/components/views/room_settings/ColorSettings.js index b37802d304..ea19fb6a89 100644 --- a/src/components/views/room_settings/ColorSettings.js +++ b/src/components/views/room_settings/ColorSettings.js @@ -34,7 +34,7 @@ var ROOM_COLORS = [ ["#dad658", "#f5f4ea"], ["#80c553", "#eef5ea"], ["#bb814e", "#eee8e3"], - ["#595959", "#ececec"], + //["#595959", "#ececec"], // Grey makes everything appear disabled, so remove it for now ]; module.exports = React.createClass({ From d54cea54298041379738367ae2996de8643c3368 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 7 Oct 2017 19:25:13 +0100 Subject: [PATCH 09/41] Add a way to jump to a user's Read Receipt from MemberInfo Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/MemberInfo.js | 35 +++++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index f705cf97d2..83f4f7e4c6 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -628,23 +628,50 @@ module.exports = withMatrixClient(React.createClass({ }, _renderUserOptions: function() { - // Only allow the user to ignore the user if its not ourselves + const cli = this.props.matrixClient; + const member = this.props.member; + let ignoreButton = null; - if (this.props.member.userId !== this.props.matrixClient.getUserId()) { + let readReceiptButton = null; + + // Only allow the user to ignore the user if its not ourselves + // same goes for jumping to read receipt + if (member.userId !== cli.getUserId()) { ignoreButton = ( {this.state.isIgnoring ? _t("Unignore") : _t("Ignore")} ); + + if (member.roomId) { + const room = cli.getRoom(member.roomId); + const eventId = room.getEventReadUpTo(member.userId); + + const onReadReceiptButton = function() { + dis.dispatch({ + action: 'view_room', + highlighted: true, + event_id: eventId, + room_id: member.roomId, + }); + }; + + readReceiptButton = ( + + Jump to read receipt + + ); + } } - if (!ignoreButton) return null; + if (!ignoreButton && !readReceiptButton) return null; return (

{ _t("User Options") }

- {ignoreButton} + { readReceiptButton } + { ignoreButton }
); From dbb6f5a44d2cdc4b0531c245fcd0b5fa1575d11a Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 7 Oct 2017 19:27:49 +0100 Subject: [PATCH 10/41] i18n the Jump to Read Receipt in MemberInfo Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/MemberInfo.js | 4 ++-- src/i18n/strings/en_EN.json | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 83f4f7e4c6..5dfdeb303b 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -639,7 +639,7 @@ module.exports = withMatrixClient(React.createClass({ if (member.userId !== cli.getUserId()) { ignoreButton = ( - {this.state.isIgnoring ? _t("Unignore") : _t("Ignore")} + { this.state.isIgnoring ? _t("Unignore") : _t("Ignore") } ); @@ -658,7 +658,7 @@ module.exports = withMatrixClient(React.createClass({ readReceiptButton = ( - Jump to read receipt + { _t('Jump to read receipt') } ); } diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6acaba9fae..5ebf6116ee 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -249,6 +249,7 @@ "%(targetName)s joined the room.": "%(targetName)s joined the room.", "Joins room with given alias": "Joins room with given alias", "Jump to first unread message.": "Jump to first unread message.", + "Jump to read receipt": "Jump to read receipt", "%(senderName)s kicked %(targetName)s.": "%(senderName)s kicked %(targetName)s.", "Kick": "Kick", "Kicks user with given id": "Kicks user with given id", From 52f3e1295bd37b197aef724f3787ae4f54858f89 Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Wed, 11 Oct 2017 09:14:11 +0200 Subject: [PATCH 11/41] Don't use string interpolation in _tJsx as it uses regexes for that Signed-off-by: Stefan Parviainen --- src/languageHandler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languageHandler.js b/src/languageHandler.js index 12242a2e15..b846980dc1 100644 --- a/src/languageHandler.js +++ b/src/languageHandler.js @@ -109,7 +109,7 @@ export function _tJsx(jsxText, patterns, subs) { } // The translation returns text so there's no XSS vector here (no unsafe HTML, no code execution) - const tJsxText = _t(jsxText); + const tJsxText = _t(jsxText, {interpolate: false}); let output = [tJsxText]; for (let i = 0; i < patterns.length; i++) { // convert the last element in 'output' into 3 elements (pre-text, sub function, post-text). From 581abcb4b78f07a7f3c0a5ac347416f108fa0c39 Mon Sep 17 00:00:00 2001 From: Stefan Parviainen Date: Wed, 11 Oct 2017 09:15:15 +0200 Subject: [PATCH 12/41] Consistent subsitution variable in translations Signed-off-by: Stefan Parviainen --- src/components/views/messages/RoomAvatarEvent.js | 4 ++-- src/i18n/strings/de_DE.json | 2 +- src/i18n/strings/el.json | 2 +- src/i18n/strings/en_EN.json | 2 +- src/i18n/strings/en_US.json | 2 +- src/i18n/strings/eu.json | 2 +- src/i18n/strings/fr.json | 2 +- src/i18n/strings/hu.json | 2 +- src/i18n/strings/ko.json | 2 +- src/i18n/strings/lv.json | 2 +- src/i18n/strings/nl.json | 2 +- src/i18n/strings/pl.json | 2 +- src/i18n/strings/pt.json | 2 +- src/i18n/strings/pt_BR.json | 2 +- src/i18n/strings/ru.json | 2 +- src/i18n/strings/tr.json | 2 +- src/i18n/strings/zh_Hant.json | 2 +- 17 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/components/views/messages/RoomAvatarEvent.js b/src/components/views/messages/RoomAvatarEvent.js index ed790953dc..c7625b0165 100644 --- a/src/components/views/messages/RoomAvatarEvent.js +++ b/src/components/views/messages/RoomAvatarEvent.js @@ -70,9 +70,9 @@ module.exports = React.createClass({ // it sucks that _tJsx doesn't support normal _t substitutions :(( return (
- { _tJsx('$senderDisplayName changed the room avatar to ', + { _tJsx('%(senderDisplayName)s changed the room avatar to ', [ - /\$senderDisplayName/, + /%\(senderDisplayName\)s/, //, ], [ diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json index aa114e241d..3fd7a4858f 100644 --- a/src/i18n/strings/de_DE.json +++ b/src/i18n/strings/de_DE.json @@ -734,7 +734,7 @@ "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and device %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "WARNUNG: SCHLÜSSEL-VERIFIZIERUNG FEHLGESCHLAGEN! Der Signatur-Schlüssel für %(userId)s und das Gerät %(deviceId)s ist \"%(fprint)s\", welcher nicht mit dem bereitgestellten Schlüssel \"%(fingerprint)s\" übereinstimmt. Dies kann bedeuten, dass deine Kommunikation abgehört wird!", "You have disabled URL previews by default.": "Du hast die URL-Vorschau standardmäßig deaktiviert.", "You have enabled URL previews by default.": "Du hast die URL-Vorschau standardmäßig aktiviert.", - "$senderDisplayName changed the room avatar to ": "$senderDisplayName hat das Raum-Bild geändert zu ", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s hat das Raum-Bild geändert zu ", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s hat das Raum-Bild für %(roomName)s geändert", "Hide removed messages": "Gelöschte Nachrichten verbergen", "Start new chat": "Neuen Chat starten", diff --git a/src/i18n/strings/el.json b/src/i18n/strings/el.json index bc45e6da9e..474ae70160 100644 --- a/src/i18n/strings/el.json +++ b/src/i18n/strings/el.json @@ -647,7 +647,7 @@ "Disable URL previews by default for participants in this room": "Απενεργοποίηση της προεπισκόπησης συνδέσμων για όλους τους συμμετέχοντες στο δωμάτιο", "Disable URL previews for this room (affects only you)": "Απενεργοποίηση της προεπισκόπησης συνδέσμων για αυτό το δωμάτιο (επηρεάζει μόνο εσάς)", " (unsupported)": " (μη υποστηριζόμενο)", - "$senderDisplayName changed the room avatar to ": "Ο $senderDisplayName άλλαξε την εικόνα του δωματίου σε ", + "%(senderDisplayName)s changed the room avatar to ": "Ο %(senderDisplayName)s άλλαξε την εικόνα του δωματίου σε ", "Missing Media Permissions, click here to request.": "Λείπουν τα δικαιώματα πολύμεσων, κάντε κλικ για να ζητήσετε.", "You may need to manually permit Riot to access your microphone/webcam": "Μπορεί να χρειαστεί να ορίσετε χειροκίνητα την πρόσβαση του Riot στο μικρόφωνο/κάμερα", "Can't connect to homeserver - please check your connectivity, ensure your homeserver's SSL certificate is trusted, and that a browser extension is not blocking requests.": "Δεν είναι δυνατή η σύνδεση στον διακομιστή - παρακαλούμε ελέγξτε την συνδεσιμότητα, βεβαιωθείτε ότι το πιστοποιητικό SSL του διακομιστή είναι έμπιστο και ότι κάποιο πρόσθετο περιηγητή δεν αποτρέπει τα αιτήματα.", diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 6acaba9fae..36d50679e2 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -790,7 +790,7 @@ "Start chatting": "Start chatting", "Start Chatting": "Start Chatting", "Click on the button below to start chatting!": "Click on the button below to start chatting!", - "$senderDisplayName changed the room avatar to ": "$senderDisplayName changed the room avatar to ", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s changed the room avatar to ", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s removed the room avatar.", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s changed the avatar for %(roomName)s", "Username available": "Username available", diff --git a/src/i18n/strings/en_US.json b/src/i18n/strings/en_US.json index 928f1a9d0f..d4f210bc08 100644 --- a/src/i18n/strings/en_US.json +++ b/src/i18n/strings/en_US.json @@ -698,7 +698,7 @@ "Idle": "Idle", "Offline": "Offline", "Disable URL previews for this room (affects only you)": "Disable URL previews for this room (affects only you)", - "$senderDisplayName changed the room avatar to ": "$senderDisplayName changed the room avatar to ", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s changed the room avatar to ", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s removed the room avatar.", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s changed the avatar for %(roomName)s", "Active call (%(roomName)s)": "Active call (%(roomName)s)", diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json index 9f3d06ec52..9aa8112382 100644 --- a/src/i18n/strings/eu.json +++ b/src/i18n/strings/eu.json @@ -744,7 +744,7 @@ "Start chatting": "Hasi txateatzen", "Start Chatting": "Hasi txateatzen", "Click on the button below to start chatting!": "Egin klik beheko botoian txateatzen hasteko!", - "$senderDisplayName changed the room avatar to ": "$senderDisplayName erabiltzaileak gelaren abatarra aldatu du beste honetara: ", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s erabiltzaileak gelaren abatarra aldatu du beste honetara: ", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s erabiltzaileak gelaren abatarra ezabatu du.", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s erabiltzaileak %(roomName)s gelaren abatarra aldatu du", "Username available": "Erabiltzaile-izena eskuragarri dago", diff --git a/src/i18n/strings/fr.json b/src/i18n/strings/fr.json index 585e47f5a3..22e901ba5e 100644 --- a/src/i18n/strings/fr.json +++ b/src/i18n/strings/fr.json @@ -635,7 +635,7 @@ "for %(amount)sm": "depuis %(amount)sm", "for %(amount)sh": "depuis %(amount)sh", "for %(amount)sd": "depuis %(amount)sj", - "$senderDisplayName changed the room avatar to ": "$senderDisplayName a changé l’image de profil du salon en ", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s a changé l’image de profil du salon en ", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s a supprimé l’image de profil du salon.", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s a changé l’image de profil de %(roomName)s", "Device already verified!": "Appareil déjà vérifié !", diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json index 2c34e05b1a..0801ecbc7b 100644 --- a/src/i18n/strings/hu.json +++ b/src/i18n/strings/hu.json @@ -730,7 +730,7 @@ "Start chatting": "Csevegés indítása", "Start Chatting": "Csevegés indítása", "Click on the button below to start chatting!": "Csevegés indításához kattints a gombra alább!", - "$senderDisplayName changed the room avatar to ": "$senderDisplayName megváltoztatta a szoba avatar képét: ", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s megváltoztatta a szoba avatar képét: ", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s törölte a szoba avatar képét.", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s megváltoztatta %(roomName)s szoba avatar képét", "Username available": "Szabad felhasználói név", diff --git a/src/i18n/strings/ko.json b/src/i18n/strings/ko.json index 8b6e233437..ac182570df 100644 --- a/src/i18n/strings/ko.json +++ b/src/i18n/strings/ko.json @@ -751,7 +751,7 @@ "Start chatting": "이야기하기", "Start Chatting": "이야기하기", "Click on the button below to start chatting!": "이야기하려면 아래 버튼을 누르세요!", - "$senderDisplayName changed the room avatar to ": "$senderDisplayName님이 방 아바타를 로 바꾸셨어요", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s님이 방 아바타를 로 바꾸셨어요", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s님이 방 아바타를 지우셨어요.", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s가 %(roomName)s 방의 아바타를 바꾸셨어요", "Username available": "쓸 수 있는 사용자 이름", diff --git a/src/i18n/strings/lv.json b/src/i18n/strings/lv.json index 5f58fd9515..6891f130b5 100644 --- a/src/i18n/strings/lv.json +++ b/src/i18n/strings/lv.json @@ -626,7 +626,7 @@ "Dec": "Dec.", "Set a display name:": "Iestatīt redzamo vārdu:", "This image cannot be displayed.": "Šo attēlu nav iespējams parādīt.", - "$senderDisplayName changed the room avatar to ": "$senderDisplayName nomainīja istabas attēlu uz ", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s nomainīja istabas attēlu uz ", "Upload an avatar:": "Augšuplādē profila attēlu:", "This server does not support authentication with a phone number.": "Šis serveris neatbalsta autentifikāciju pēc telefona numura.", "Missing password.": "Trūkst parole.", diff --git a/src/i18n/strings/nl.json b/src/i18n/strings/nl.json index f770e335cf..82e0731653 100644 --- a/src/i18n/strings/nl.json +++ b/src/i18n/strings/nl.json @@ -753,7 +753,7 @@ "Start chatting": "Start met praten", "Start Chatting": "Start Met Praten", "Click on the button below to start chatting!": "Klik op de knop hieronder om te starten met praten!", - "$senderDisplayName changed the room avatar to ": "$senderDisplayName heeft de ruimte avatar aangepast naar ", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s heeft de ruimte avatar aangepast naar ", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s heeft de ruimte avatar verwijderd.", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s veranderde de avatar voor %(roomName)s", "Username available": "Gebruikersnaam beschikbaar", diff --git a/src/i18n/strings/pl.json b/src/i18n/strings/pl.json index bd1e4c5c24..c78bc0f300 100644 --- a/src/i18n/strings/pl.json +++ b/src/i18n/strings/pl.json @@ -778,7 +778,7 @@ "for %(amount)sd": "%(amount)s dni", "Idle": "Bezczynny", "Check for update": "Sprawdź aktualizacje", - "$senderDisplayName changed the room avatar to ": "$senderDisplayName zmienił awatar pokoju na ", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s zmienił awatar pokoju na ", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s usunął awatar pokoju.", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s zmienił awatar %(roomName)s", "This will be your account name on the homeserver, or you can pick a different server.": "To będzie twoja nazwa konta na serwerze domowym; możesz też wybrać inny serwer.", diff --git a/src/i18n/strings/pt.json b/src/i18n/strings/pt.json index ba4968b7ad..e4aedecf3e 100644 --- a/src/i18n/strings/pt.json +++ b/src/i18n/strings/pt.json @@ -707,7 +707,7 @@ "for %(amount)sd": "por %(amount)sd", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s removeu a imagem da sala.", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s alterou a imagem da sala %(roomName)s", - "$senderDisplayName changed the room avatar to ": "$senderDisplayName alterou a imagem da sala para ", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s alterou a imagem da sala para ", "Missing Media Permissions, click here to request.": "Faltam permissões para uso de mídia no seu computador. Clique aqui para solicitá-las.", "No Microphones detected": "Não foi detectado nenhum microfone", "No Webcams detected": "Não foi detectada nenhuma Webcam", diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json index af4804bd85..f6c945c20c 100644 --- a/src/i18n/strings/pt_BR.json +++ b/src/i18n/strings/pt_BR.json @@ -704,7 +704,7 @@ "for %(amount)sd": "por %(amount)sd", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s removeu a imagem da sala.", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s alterou a imagem da sala %(roomName)s", - "$senderDisplayName changed the room avatar to ": "$senderDisplayName alterou a imagem da sala para ", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s alterou a imagem da sala para ", "Missing Media Permissions, click here to request.": "Faltam permissões para uso de mídia no seu computador. Clique aqui para solicitá-las.", "No Microphones detected": "Não foi detectado nenhum microfone", "No Webcams detected": "Não foi detectada nenhuma Webcam", diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json index cfab960e32..3a99d78420 100644 --- a/src/i18n/strings/ru.json +++ b/src/i18n/strings/ru.json @@ -712,7 +712,7 @@ "Idle": "Неактивен", "Offline": "Не в сети", "Disable URL previews for this room (affects only you)": "Отключить предпросмотр URL-адресов для этой комнаты (влияет только на вас)", - "$senderDisplayName changed the room avatar to ": "$senderDisplayName сменил аватар комнаты на ", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s сменил аватар комнаты на ", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s удалил аватар комнаты.", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s сменил аватар для %(roomName)s", "Create new room": "Создать новую комнату", diff --git a/src/i18n/strings/tr.json b/src/i18n/strings/tr.json index 23d4e284bc..7cbdeee173 100644 --- a/src/i18n/strings/tr.json +++ b/src/i18n/strings/tr.json @@ -746,7 +746,7 @@ "Start chatting": "Sohbeti başlat", "Start Chatting": "Sohbeti Başlat", "Click on the button below to start chatting!": "Sohbeti başlatmak için aşağıdaki butona tıklayın!", - "$senderDisplayName changed the room avatar to ": "$senderDisplayName odanın avatarını olarak çevirdi", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s odanın avatarını olarak çevirdi", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s odanın avatarını kaldırdı.", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s %(roomName)s için avatarı değiştirdi", "Username available": "Kullanıcı ismi uygun", diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json index 596bc55a01..5828d7a614 100644 --- a/src/i18n/strings/zh_Hant.json +++ b/src/i18n/strings/zh_Hant.json @@ -228,7 +228,7 @@ "Idle": "閒置", "Offline": "下線", "Disable URL previews for this room (affects only you)": "在這個房間禁止URL預覽(只影響你)", - "$senderDisplayName changed the room avatar to ": "$senderDisplayName 更改了聊天室的圖像為 ", + "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s 更改了聊天室的圖像為 ", "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s 移除了聊天室圖片。", "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s 更改了聊天室 %(roomName)s 圖像", "Cancel": "取消", From f3b1baa3c0f021c458b5bc3937171b1e462c505b Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Wed, 11 Oct 2017 21:15:00 -0600 Subject: [PATCH 13/41] Suggest to invite people when speaking in an empty room Adds vector-im/riot-web#1053 Signed-off-by: Travis Ralston --- src/components/structures/RoomStatusBar.js | 30 +++++++++++++++++- src/components/structures/RoomView.js | 36 ++++++++++++++++++++++ src/i18n/strings/en_EN.json | 1 + 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js index 3a2ab33db8..cad55351d1 100644 --- a/src/components/structures/RoomStatusBar.js +++ b/src/components/structures/RoomStatusBar.js @@ -43,6 +43,10 @@ module.exports = React.createClass({ // the end of the live timeline. atEndOfLiveTimeline: React.PropTypes.bool, + // This is true when the user is alone in the room, but has also sent a message. + // Used to suggest to the user to invite someone + sentMessageAndIsAlone: React.PropTypes.bool, + // true if there is an active call in this room (means we show // the 'Active Call' text in the status bar if there is nothing // more interesting) @@ -60,6 +64,14 @@ module.exports = React.createClass({ // 'unsent messages' bar onCancelAllClick: React.PropTypes.func, + // callback for when the user clicks on the 'invite others' button in the + // 'you are alone' bar + onInviteClick: React.PropTypes.func, + + // callback for when the user clicks on the 'stop warning me' button in the + // 'you are alone' bar + onStopWarningClick: React.PropTypes.func, + // callback for when the user clicks on the 'scroll to bottom' button onScrollToBottomClick: React.PropTypes.func, @@ -140,7 +152,8 @@ module.exports = React.createClass({ (this.state.usersTyping.length > 0) || this.props.numUnreadMessages || !this.props.atEndOfLiveTimeline || - this.props.hasActiveCall + this.props.hasActiveCall || + this.props.sentMessageAndIsAlone ) { return STATUS_BAR_EXPANDED; } else if (this.props.unsentMessageError) { @@ -305,6 +318,21 @@ module.exports = React.createClass({ ); } + // If you're alone in the room, and have sent a message, suggest to invite someone + if (this.props.sentMessageAndIsAlone) { + return ( +
+ { _tJsx("There's no one else here! Would you like to invite others or stop warning about the empty room?", + [/(.*?)<\/a>/, /(.*?)<\/a>/], + [ + (sub) => { sub }, + (sub) => { sub }, + ], + ) } +
+ ); + } + return null; }, diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 14273fc95f..c75b0f61b0 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -117,6 +117,7 @@ module.exports = React.createClass({ guestsCanJoin: false, canPeek: false, showApps: false, + isAlone: false, // error object, as from the matrix client/server API // If we failed to load information about the room, @@ -453,6 +454,8 @@ module.exports = React.createClass({ switch (payload.action) { case 'message_send_failed': case 'message_sent': + this._checkIfAlone(this.state.room); + // no break; to intentionally fall through case 'message_send_cancelled': this.setState({ unsentMessageError: this._getUnsentMessageError(this.state.room), @@ -732,6 +735,20 @@ module.exports = React.createClass({ } }, 500), + _checkIfAlone: function(room) { + let warnedAboutLonelyRoom = false; + if (localStorage) { + warnedAboutLonelyRoom = localStorage.getItem('mx_user_alone_warned_' + this.state.room.roomId); + } + if (warnedAboutLonelyRoom) { + if (this.state.isAlone) this.setState({isAlone: false}); + return; + } + + const joinedMembers = room.currentState.getMembers().filter(m => m.membership === "join" || m.membership === "invite"); + this.setState({isAlone: joinedMembers.length === 1}); + }, + _getUnsentMessageError: function(room) { const unsentMessages = this._getUnsentMessages(room); if (!unsentMessages.length) return ""; @@ -813,6 +830,22 @@ module.exports = React.createClass({ Resend.cancelUnsentEvents(this.state.room); }, + onInviteButtonClick: function() { + // call AddressPickerDialog + dis.dispatch({ + action: 'view_invite', + roomId: this.state.room.roomId, + }); + this.setState({isAlone: false}); // there's a good chance they'll invite someone + }, + + onStopAloneWarningClick: function() { + if (localStorage) { + localStorage.setItem('mx_user_alone_warned_' + this.state.room.roomId, true); + } + this.setState({isAlone: false}); + }, + onJoinButtonClicked: function(ev) { const cli = MatrixClientPeg.get(); @@ -1573,9 +1606,12 @@ module.exports = React.createClass({ numUnreadMessages={this.state.numUnreadMessages} unsentMessageError={this.state.unsentMessageError} atEndOfLiveTimeline={this.state.atEndOfLiveTimeline} + sentMessageAndIsAlone={this.state.isAlone} hasActiveCall={inCall} onResendAllClick={this.onResendAllClick} onCancelAllClick={this.onCancelAllClick} + onInviteClick={this.onInviteButtonClick} + onStopWarningClick={this.onStopAloneWarningClick} onScrollToBottomClick={this.jumpToLiveTimeline} onResize={this.onChildResize} onVisible={this.onStatusBarVisible} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index e542253641..7226b5fcd5 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -609,6 +609,7 @@ "Room": "Room", "Copied!": "Copied!", "Failed to copy": "Failed to copy", + "There's no one else here! Would you like to invite others or stop warning about the empty room?": "There's no one else here! Would you like to invite others or stop warning about the empty room?", "Connectivity to the server has been lost.": "Connectivity to the server has been lost.", "Sent messages will be stored until your connection has returned.": "Sent messages will be stored until your connection has returned.", "Resend all or cancel all now. You can also select individual messages to resend or cancel.": "Resend all or cancel all now. You can also select individual messages to resend or cancel.", From 289fc230feba274d96e6f390c5e5a90aef7797a0 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 13 Oct 2017 11:05:58 +0100 Subject: [PATCH 14/41] js-sdk rc.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e185a9027d..d89f29e958 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "isomorphic-fetch": "^2.2.1", "linkifyjs": "^2.1.3", "lodash": "^4.13.1", - "matrix-js-sdk": "0.8.4", + "matrix-js-sdk": "0.8.5-rc.1", "optimist": "^0.6.1", "prop-types": "^15.5.8", "react": "^15.4.0", From 5fe48e44a031a3c127d8b0f30cc3e8d22b99254b Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 13 Oct 2017 11:10:21 +0100 Subject: [PATCH 15/41] Prepare changelog for v0.10.7-rc.1 --- CHANGELOG.md | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97523e9189..0d29fbc7a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,136 @@ +Changes in [0.10.7-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.10.7-rc.1) (2017-10-13) +=============================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.10.6...v0.10.7-rc.1) + + * Add warm fuzzy dialog for inviting users to a group + [\#1459](https://github.com/matrix-org/matrix-react-sdk/pull/1459) + * enable/disable features in config.json + [\#1468](https://github.com/matrix-org/matrix-react-sdk/pull/1468) + * Update from Weblate. + [\#1469](https://github.com/matrix-org/matrix-react-sdk/pull/1469) + * Don't send RR or RM when peeking at a room + [\#1463](https://github.com/matrix-org/matrix-react-sdk/pull/1463) + * Fix bug that inserted emoji when typing + [\#1467](https://github.com/matrix-org/matrix-react-sdk/pull/1467) + * Ignore VS16 char in RTE + [\#1458](https://github.com/matrix-org/matrix-react-sdk/pull/1458) + * Show failures when sending messages + [\#1460](https://github.com/matrix-org/matrix-react-sdk/pull/1460) + * Run eslint --fix + [\#1461](https://github.com/matrix-org/matrix-react-sdk/pull/1461) + * Show who banned the user on hover + [\#1441](https://github.com/matrix-org/matrix-react-sdk/pull/1441) + * Enhancements to room power level settings + [\#1440](https://github.com/matrix-org/matrix-react-sdk/pull/1440) + * Added TextInputWithCheckbox dialog + [\#868](https://github.com/matrix-org/matrix-react-sdk/pull/868) + * Make it clearer which HS you're logging into + [\#1456](https://github.com/matrix-org/matrix-react-sdk/pull/1456) + * Remove redundant stale onKeyDown + [\#1451](https://github.com/matrix-org/matrix-react-sdk/pull/1451) + * Only allow event state event handlers on state events + [\#1453](https://github.com/matrix-org/matrix-react-sdk/pull/1453) + * Modify the group store to include group rooms + [\#1452](https://github.com/matrix-org/matrix-react-sdk/pull/1452) + * Factor-out GroupStore and create GroupStoreCache + [\#1449](https://github.com/matrix-org/matrix-react-sdk/pull/1449) + * Put related groups UI behind groups labs flag + [\#1448](https://github.com/matrix-org/matrix-react-sdk/pull/1448) + * Restrict Flair in the timeline to related groups of the room + [\#1447](https://github.com/matrix-org/matrix-react-sdk/pull/1447) + * Implement UI for editing related groups of a room + [\#1446](https://github.com/matrix-org/matrix-react-sdk/pull/1446) + * Fix a couple of bugs with EditableItemList + [\#1445](https://github.com/matrix-org/matrix-react-sdk/pull/1445) + * Factor out EditableItemList from AliasSettings + [\#1444](https://github.com/matrix-org/matrix-react-sdk/pull/1444) + * Add dummy translation function to mark translatable strings + [\#1421](https://github.com/matrix-org/matrix-react-sdk/pull/1421) + * Implement button to remove a room from a group + [\#1438](https://github.com/matrix-org/matrix-react-sdk/pull/1438) + * Fix showing 3pid invites in member list + [\#1443](https://github.com/matrix-org/matrix-react-sdk/pull/1443) + * Add button to get to MyGroups (view_my_groups or path #/groups) + [\#1435](https://github.com/matrix-org/matrix-react-sdk/pull/1435) + * Add eslint rule to disallow spaces inside of curly braces + [\#1436](https://github.com/matrix-org/matrix-react-sdk/pull/1436) + * Fix ability to invite existing mx users + [\#1437](https://github.com/matrix-org/matrix-react-sdk/pull/1437) + * Construct address picker message using provided `validAddressTypes` + [\#1434](https://github.com/matrix-org/matrix-react-sdk/pull/1434) + * Fix GroupView summary rooms displaying without avatars + [\#1433](https://github.com/matrix-org/matrix-react-sdk/pull/1433) + * Implement adding rooms to a group (or group summary) by room ID + [\#1432](https://github.com/matrix-org/matrix-react-sdk/pull/1432) + * Give flair avatars a tooltip = the group ID + [\#1431](https://github.com/matrix-org/matrix-react-sdk/pull/1431) + * Fix ability to feature self in a group summary + [\#1430](https://github.com/matrix-org/matrix-react-sdk/pull/1430) + * Implement "Add room to group" feature + [\#1429](https://github.com/matrix-org/matrix-react-sdk/pull/1429) + * Fix group membership publicity + [\#1428](https://github.com/matrix-org/matrix-react-sdk/pull/1428) + * Add support for Jitsi screensharing in electron app + [\#1355](https://github.com/matrix-org/matrix-react-sdk/pull/1355) + * Delint and DRY TextForEvent + [\#1424](https://github.com/matrix-org/matrix-react-sdk/pull/1424) + * Bust the flair caches after 30mins + [\#1427](https://github.com/matrix-org/matrix-react-sdk/pull/1427) + * Show displayname / avatar in group member info + [\#1426](https://github.com/matrix-org/matrix-react-sdk/pull/1426) + * Create GroupSummaryStore for storing group summary stuff + [\#1418](https://github.com/matrix-org/matrix-react-sdk/pull/1418) + * Add status & toggle for publicity + [\#1419](https://github.com/matrix-org/matrix-react-sdk/pull/1419) + * MemberList: show 100 more on overflow tile click + [\#1417](https://github.com/matrix-org/matrix-react-sdk/pull/1417) + * Fix NPE in MemberList + [\#1425](https://github.com/matrix-org/matrix-react-sdk/pull/1425) + * Fix incorrect variable in string + [\#1422](https://github.com/matrix-org/matrix-react-sdk/pull/1422) + * apply i18n _t to string which has already been translated + [\#1420](https://github.com/matrix-org/matrix-react-sdk/pull/1420) + * Make the invite section a truncatedlist too + [\#1416](https://github.com/matrix-org/matrix-react-sdk/pull/1416) + * Implement removal function of features users/rooms + [\#1415](https://github.com/matrix-org/matrix-react-sdk/pull/1415) + * Allow TruncatedList to get children via a callback + [\#1412](https://github.com/matrix-org/matrix-react-sdk/pull/1412) + * Experimental: Lazy load user autocomplete entries + [\#1413](https://github.com/matrix-org/matrix-react-sdk/pull/1413) + * Show displayname & avatar url in group member list + [\#1414](https://github.com/matrix-org/matrix-react-sdk/pull/1414) + * De-lint TruncatedList + [\#1411](https://github.com/matrix-org/matrix-react-sdk/pull/1411) + * Remove unneeded strings + [\#1409](https://github.com/matrix-org/matrix-react-sdk/pull/1409) + * Clean on prerelease + [\#1410](https://github.com/matrix-org/matrix-react-sdk/pull/1410) + * Redesign membership section in GroupView + [\#1408](https://github.com/matrix-org/matrix-react-sdk/pull/1408) + * Implement adding rooms to the group summary + [\#1406](https://github.com/matrix-org/matrix-react-sdk/pull/1406) + * Honour the is_privileged flag in GroupView + [\#1407](https://github.com/matrix-org/matrix-react-sdk/pull/1407) + * Update when a group arrives + [\#1405](https://github.com/matrix-org/matrix-react-sdk/pull/1405) + * Implement `view_group` dispatch when clicking flair + [\#1404](https://github.com/matrix-org/matrix-react-sdk/pull/1404) + * GroupView: Add a User + [\#1402](https://github.com/matrix-org/matrix-react-sdk/pull/1402) + * Track action button click event + [\#1403](https://github.com/matrix-org/matrix-react-sdk/pull/1403) + * Separate sender profile into elements with classes + [\#1401](https://github.com/matrix-org/matrix-react-sdk/pull/1401) + * Fix ugly integration button, use hover to show error + [\#1399](https://github.com/matrix-org/matrix-react-sdk/pull/1399) + * Fix promise error in flair + [\#1400](https://github.com/matrix-org/matrix-react-sdk/pull/1400) + * Flair! + [\#1351](https://github.com/matrix-org/matrix-react-sdk/pull/1351) + * Group Membership UI + [\#1328](https://github.com/matrix-org/matrix-react-sdk/pull/1328) + Changes in [0.10.6](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.10.6) (2017-09-21) ===================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.10.5...v0.10.6) From 9036f786e71954de72d7cd2bac8129750b38ca9a Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 13 Oct 2017 11:10:21 +0100 Subject: [PATCH 16/41] v0.10.7-rc.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d89f29e958..672fca4060 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.10.6", + "version": "0.10.7-rc.1", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 56825efc722d5ace3cc63b379a1a00365eaa53a7 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 13 Oct 2017 15:02:36 +0100 Subject: [PATCH 17/41] Prepare changelog for v0.10.7-rc.2 --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d29fbc7a7..3dceeef955 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,14 @@ +Changes in [0.10.7-rc.2](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.10.7-rc.2) (2017-10-13) +=============================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.10.7-rc.1...v0.10.7-rc.2) + + * Honour the (now legacy) enableLabs flag + [\#1473](https://github.com/matrix-org/matrix-react-sdk/pull/1473) + * Don't show labs features by default + [\#1472](https://github.com/matrix-org/matrix-react-sdk/pull/1472) + * Make features disabled by default + [\#1470](https://github.com/matrix-org/matrix-react-sdk/pull/1470) + Changes in [0.10.7-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.10.7-rc.1) (2017-10-13) =============================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.10.6...v0.10.7-rc.1) From b95c2368a683595c765b7e3906b74cb50a1a735e Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 13 Oct 2017 15:02:37 +0100 Subject: [PATCH 18/41] v0.10.7-rc.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 672fca4060..731137a5ae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.10.7-rc.1", + "version": "0.10.7-rc.2", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 8470a035303f28b2a868a9f9ce1d58df9ef7ece9 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 13 Oct 2017 16:31:34 +0100 Subject: [PATCH 19/41] Prepare changelog for v0.10.7-rc.3 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3dceeef955..75c99e299b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +Changes in [0.10.7-rc.3](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.10.7-rc.3) (2017-10-13) +=============================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.10.7-rc.2...v0.10.7-rc.3) + + * Fix the enableLabs flag, again + [\#1474](https://github.com/matrix-org/matrix-react-sdk/pull/1474) + Changes in [0.10.7-rc.2](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.10.7-rc.2) (2017-10-13) =============================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.10.7-rc.1...v0.10.7-rc.2) From 3b515cdebe397252ceb50cb1e362bf031dbf3617 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 13 Oct 2017 16:31:35 +0100 Subject: [PATCH 20/41] v0.10.7-rc.3 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 731137a5ae..e564366e61 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.10.7-rc.2", + "version": "0.10.7-rc.3", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From e5c8e3e7ad32794ad244f56cbffad9d76546f4b5 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 13 Oct 2017 20:57:15 -0600 Subject: [PATCH 21/41] Add option to unset room avatar Signed-off-by: Travis Ralston --- src/components/views/rooms/RoomHeader.js | 12 ++++++++-- src/components/views/settings/ChangeAvatar.js | 22 +++++++++++++++++++ 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js index 42cbb90cd9..3d2dee9e64 100644 --- a/src/components/views/rooms/RoomHeader.js +++ b/src/components/views/rooms/RoomHeader.js @@ -129,6 +129,10 @@ module.exports = React.createClass({ }).done(); }, + onAvatarRemoveClick: function() { + MatrixClientPeg.get().sendStateEvent(this.props.room.roomId, 'm.room.avatar', {url: null}, ''); + }, + onShowRhsClick: function(ev) { dis.dispatch({ action: 'show_right_panel' }); }, @@ -268,11 +272,15 @@ module.exports = React.createClass({
+
+ {_t("Remove +
); } else if (this.props.room || (this.props.oobData && this.props.oobData.name)) { diff --git a/src/components/views/settings/ChangeAvatar.js b/src/components/views/settings/ChangeAvatar.js index b3204ab86e..7d8b1d9534 100644 --- a/src/components/views/settings/ChangeAvatar.js +++ b/src/components/views/settings/ChangeAvatar.js @@ -53,6 +53,10 @@ module.exports = React.createClass({ }; }, + componentWillMount: function() { + MatrixClientPeg.get().on("RoomState.events", this.onRoomStateEvents); + }, + componentWillReceiveProps: function(newProps) { if (this.avatarSet) { // don't clobber what the user has just set @@ -63,6 +67,24 @@ module.exports = React.createClass({ }); }, + componentWillUnmount: function() { + if (MatrixClientPeg.get()) { + MatrixClientPeg.get().removeListener("RoomState.events", this.onRoomStateEvents); + } + }, + + onRoomStateEvents: function(ev) { + if (ev.getRoomId() !== this.props.room.roomId || ev.getType() !== 'm.room.avatar' + || ev.getSender() !== MatrixClientPeg.get().getUserId()) { + return; + } + + if (!ev.getContent().url) { + this.avatarSet = false; + this.setState({}); // force update + } + }, + setAvatarFromFile: function(file) { let newUrl = null; From 6e7f0d649b17cbd9150d2c37976b9253e6027a10 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 13 Oct 2017 21:13:32 -0600 Subject: [PATCH 22/41] Add option to unset your own avatar Signed-off-by: Travis Ralston --- src/components/structures/UserSettings.js | 11 ++++++++++- src/components/views/settings/ChangeAvatar.js | 4 ++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index d83434f5a8..d24ff5ad4c 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -423,6 +423,11 @@ module.exports = React.createClass({ }); }, + onAvatarRemoveClick: function() { + MatrixClientPeg.get().setAvatarUrl(null); + this.setState({avatarUrl: null}); // the avatar update will complete async for us + }, + onLogoutClicked: function(ev) { const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); Modal.createTrackedDialog('Logout E2E Export', '', QuestionDialog, { @@ -1318,7 +1323,11 @@ module.exports = React.createClass({
-
+
+ {_t("Remove +
+
diff --git a/src/components/views/settings/ChangeAvatar.js b/src/components/views/settings/ChangeAvatar.js index 7d8b1d9534..a363dc2c60 100644 --- a/src/components/views/settings/ChangeAvatar.js +++ b/src/components/views/settings/ChangeAvatar.js @@ -74,6 +74,10 @@ module.exports = React.createClass({ }, onRoomStateEvents: function(ev) { + if (!this.props.room) { + return; + } + if (ev.getRoomId() !== this.props.room.roomId || ev.getType() !== 'm.room.avatar' || ev.getSender() !== MatrixClientPeg.get().getUserId()) { return; From 97ebd271751b8c61778d7b040f417b416abfb9b9 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Fri, 13 Oct 2017 23:08:41 -0600 Subject: [PATCH 23/41] Add missing translation Signed-off-by: Travis Ralston --- src/i18n/strings/en_EN.json | 1 + 1 file changed, 1 insertion(+) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index ed07e503ce..abb5cf40a0 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -632,6 +632,7 @@ "quote": "quote", "bullet": "bullet", "numbullet": "numbullet", + "Remove avatar": "Remove avatar", "%(severalUsers)sjoined %(repeats)s times": "%(severalUsers)sjoined %(repeats)s times", "%(oneUser)sjoined %(repeats)s times": "%(oneUser)sjoined %(repeats)s times", "%(severalUsers)sjoined": "%(severalUsers)sjoined", From a0004399480cffcab14377534ce5f47743bf7b55 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 14 Oct 2017 17:09:30 +0100 Subject: [PATCH 24/41] pass search query to filter fn in _updateList Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/MemberList.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js index 0713a4ae8a..781126c543 100644 --- a/src/components/views/rooms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -146,8 +146,8 @@ module.exports = React.createClass({ const newState = { members: this.roomMembers(), }; - newState.filteredJoinedMembers = this._filterMembers(newState.members, 'join'); - newState.filteredInvitedMembers = this._filterMembers(newState.members, 'invite'); + newState.filteredJoinedMembers = this._filterMembers(newState.members, 'join', this.state.searchQuery); + newState.filteredInvitedMembers = this._filterMembers(newState.members, 'invite', this.state.searchQuery); this.setState(newState); }, 500), From 6ad8532bedc5ef881a39770e4ff320f3384b85e0 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 14 Oct 2017 17:09:58 +0100 Subject: [PATCH 25/41] lowerCase query so that searching for `Erik` will actually find `Erik`.. Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/MemberList.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js index 781126c543..4789dda192 100644 --- a/src/components/views/rooms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -302,6 +302,7 @@ module.exports = React.createClass({ const m = this.memberDict[userId]; if (query) { + query = query.toLowerCase(); const matchesName = m.name.toLowerCase().indexOf(query) !== -1; const matchesId = m.userId.toLowerCase().indexOf(query) !== -1; @@ -399,7 +400,7 @@ module.exports = React.createClass({
+ placeholder={ _t('Filter room members') } />
); @@ -412,9 +413,9 @@ module.exports = React.createClass({ getChildren={this._getChildrenJoined} getChildCount={this._getChildCountJoined} /> - { invitedSection } + {invitedSection}
); - }, + } }); From e79f9ef0115fcee0d078e8eb88c51d574587ed68 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 14 Oct 2017 17:10:51 +0100 Subject: [PATCH 26/41] === > == Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/MemberList.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js index 4789dda192..f4d81d19f0 100644 --- a/src/components/views/rooms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -187,7 +187,7 @@ module.exports = React.createClass({ const user_id = all_user_ids[i]; const m = all_members[user_id]; - if (m.membership == 'join' || m.membership == 'invite') { + if (m.membership === 'join' || m.membership === 'invite') { if ((ConferenceHandler && !ConferenceHandler.isConferenceUser(user_id)) || !ConferenceHandler) { to_display.push(user_id); ++count; @@ -311,7 +311,7 @@ module.exports = React.createClass({ } } - return m.membership == membership; + return m.membership === membership; }); }, From b0b7472901f8840599d86c21cb3fcb99887cc643 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 14 Oct 2017 17:14:17 +0100 Subject: [PATCH 27/41] undo bad merge Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/MemberList.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js index f4d81d19f0..04b6089559 100644 --- a/src/components/views/rooms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -400,7 +400,7 @@ module.exports = React.createClass({
+ placeholder={_t('Filter room members')} />
); @@ -413,9 +413,9 @@ module.exports = React.createClass({ getChildren={this._getChildrenJoined} getChildCount={this._getChildCountJoined} /> - {invitedSection} + { invitedSection }
); - } + }, }); From c1edc0c32e72307669291370458f343861b3173c Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 14 Oct 2017 19:40:45 +0100 Subject: [PATCH 28/41] add option to disable BigEmoji Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/HtmlUtils.js | 7 +++---- src/components/structures/UserSettings.js | 4 ++++ src/components/views/messages/TextualBody.js | 4 +++- src/i18n/strings/en_EN.json | 1 + 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/HtmlUtils.js b/src/HtmlUtils.js index 5620bc06df..b8a1c63dfb 100644 --- a/src/HtmlUtils.js +++ b/src/HtmlUtils.js @@ -385,10 +385,9 @@ class TextHighlighter extends BaseHighlighter { * highlights: optional list of words to highlight, ordered by longest word first * * opts.highlightLink: optional href to add to highlighted words + * opts.disableBigEmoji: optional argument to disable the big emoji class. */ -export function bodyToHtml(content, highlights, opts) { - opts = opts || {}; - +export function bodyToHtml(content, highlights, opts={}) { const isHtml = (content.format === "org.matrix.custom.html"); const body = isHtml ? content.formatted_body : escape(content.body); @@ -418,7 +417,7 @@ export function bodyToHtml(content, highlights, opts) { } let emojiBody = false; - if (bodyHasEmoji) { + if (!opts.disableBigEmoji && bodyHasEmoji) { EMOJI_REGEX.lastIndex = 0; const contentBodyTrimmed = content.body !== undefined ? content.body.trim() : ''; const match = EMOJI_REGEX.exec(contentBodyTrimmed); diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index d83434f5a8..25960f5182 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -114,6 +114,10 @@ const SETTINGS_LABELS = [ id: 'Pill.shouldHidePillAvatar', label: _td('Hide avatars in user and room mentions'), }, + { + id: 'TextualBody.disableBigEmoji', + label: _td('Disable big emoji in chat'), + } /* { id: 'useFixedWidthFont', diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index c0468c38c2..64b23238e5 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -354,7 +354,9 @@ module.exports = React.createClass({ const mxEvent = this.props.mxEvent; const content = mxEvent.getContent(); - let body = HtmlUtils.bodyToHtml(content, this.props.highlights, {}); + let body = HtmlUtils.bodyToHtml(content, this.props.highlights, { + disableBigEmoji: UserSettingsStore.getSyncedSetting('TextualBody.disableBigEmoji', false), + }); if (this.props.highlightLink) { body = { body }; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index ed07e503ce..6f46fd3257 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -289,6 +289,7 @@ "matrix-react-sdk version:": "matrix-react-sdk version:", "Matrix Apps": "Matrix Apps", "Members only": "Members only", + "Disable big emoji in chat": "Disable big emoji in chat", "Disable Emoji suggestions while typing": "Disable Emoji suggestions while typing", "Message not sent due to unknown devices being present": "Message not sent due to unknown devices being present", "Missing room_id in request": "Missing room_id in request", From c7c28c7ad2e7cbebf805216441d889a85f592bb6 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 14 Oct 2017 19:53:08 +0100 Subject: [PATCH 29/41] make linter happy Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/UserSettings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 25960f5182..7e8dbeff76 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -117,7 +117,7 @@ const SETTINGS_LABELS = [ { id: 'TextualBody.disableBigEmoji', label: _td('Disable big emoji in chat'), - } + }, /* { id: 'useFixedWidthFont', From 8d6f0db3e2737a165a29043dfd0b85da15459761 Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sat, 14 Oct 2017 22:13:00 +0100 Subject: [PATCH 30/41] be explicit in remove button height --- src/components/structures/UserSettings.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index d24ff5ad4c..3b147104e1 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -1324,7 +1324,7 @@ module.exports = React.createClass({
- {_t("Remove
From 8a641c7173dd39722322eac7abe4028ec639ee14 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sat, 14 Oct 2017 16:40:10 -0600 Subject: [PATCH 31/41] Hide message pinning behind a labs setting Signed-off-by: Travis Ralston --- src/UserSettingsStore.js | 4 ++++ src/components/views/rooms/RoomHeader.js | 3 ++- src/i18n/strings/en_EN.json | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/UserSettingsStore.js b/src/UserSettingsStore.js index f9d0a9cda8..b274e6a594 100644 --- a/src/UserSettingsStore.js +++ b/src/UserSettingsStore.js @@ -30,6 +30,10 @@ const FEATURES = [ id: 'feature_groups', name: _td("Groups"), }, + { + id: 'feature_pinning', + name: _td("Message Pinning"), + }, ]; export default { diff --git a/src/components/views/rooms/RoomHeader.js b/src/components/views/rooms/RoomHeader.js index 59d8937aa6..4df0ff738c 100644 --- a/src/components/views/rooms/RoomHeader.js +++ b/src/components/views/rooms/RoomHeader.js @@ -31,6 +31,7 @@ import linkifyMatrix from '../../../linkify-matrix'; import AccessibleButton from '../elements/AccessibleButton'; import ManageIntegsButton from '../elements/ManageIntegsButton'; import {CancelButton} from './SimpleRoomHeader'; +import UserSettingsStore from "../../../UserSettingsStore"; linkifyMatrix(linkify); @@ -300,7 +301,7 @@ module.exports = React.createClass({ ; } - if (this.props.onPinnedClick) { + if (this.props.onPinnedClick && UserSettingsStore.isFeatureEnabled('feature_pinning')) { pinnedEventsButton = diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 95a8fcdd58..86ad0631e2 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -618,6 +618,7 @@ "(~%(count)s results)|other": "(~%(count)s results)", "Cancel": "Cancel", "or": "or", + "Message Pinning": "Message Pinning", "Active call": "Active call", "Monday": "Monday", "Tuesday": "Tuesday", From c55ffe1be7d275182b9c2a9fe38882d7c38b4836 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Sat, 14 Oct 2017 16:41:02 -0600 Subject: [PATCH 32/41] Remove duplicate declaration that breaks the build Signed-off-by: Travis Ralston --- src/Notifier.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/Notifier.js b/src/Notifier.js index 6f4da260ec..93ef192fe0 100644 --- a/src/Notifier.js +++ b/src/Notifier.js @@ -84,10 +84,6 @@ const Notifier = { msg = ''; } - const avatarUrl = ev.sender ? Avatar.avatarUrlForMember( - ev.sender, 40, 40, 'crop', - ) : null; - const avatarUrl = ev.sender ? Avatar.avatarUrlForMember(ev.sender, 40, 40, 'crop') : null; const notif = plaf.displayNotification(title, msg, avatarUrl, room); From 247e32115f525e15c699ac0810aa40368dc1d8ef Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 15 Oct 2017 01:13:52 +0100 Subject: [PATCH 33/41] bizarrely strict linting :/ --- src/components/views/rooms/PinnedEventTile.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/PinnedEventTile.js b/src/components/views/rooms/PinnedEventTile.js index e4b5b1ff96..514a84cc86 100644 --- a/src/components/views/rooms/PinnedEventTile.js +++ b/src/components/views/rooms/PinnedEventTile.js @@ -80,10 +80,10 @@ module.exports = React.createClass({ - {sender.name} + { sender.name }
); - } + }, }); From 635996c083563fab1ee983e785df3dd395e0ca2f Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 15 Oct 2017 01:19:06 +0100 Subject: [PATCH 34/41] more bizarrely strict linting :/ --- src/components/views/rooms/PinnedEventsPanel.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/rooms/PinnedEventsPanel.js b/src/components/views/rooms/PinnedEventsPanel.js index 02df29fc72..2e3f6e8390 100644 --- a/src/components/views/rooms/PinnedEventsPanel.js +++ b/src/components/views/rooms/PinnedEventsPanel.js @@ -92,10 +92,10 @@ module.exports = React.createClass({
-

{_t("Pinned Messages")}

+

{ _t("Pinned Messages") }

{ tiles }
); - } + }, }); From 1d75d9e90dafd443558d5518efe612fea314b3ba Mon Sep 17 00:00:00 2001 From: Matthew Hodgson Date: Sun, 15 Oct 2017 01:47:11 +0100 Subject: [PATCH 35/41] yet more horrifically strict linting :/ --- src/components/views/rooms/PinnedEventTile.js | 3 ++- .../views/rooms/PinnedEventsPanel.js | 20 +++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/components/views/rooms/PinnedEventTile.js b/src/components/views/rooms/PinnedEventTile.js index 514a84cc86..65b41d946a 100644 --- a/src/components/views/rooms/PinnedEventTile.js +++ b/src/components/views/rooms/PinnedEventTile.js @@ -47,7 +47,8 @@ module.exports = React.createClass({ const index = pinned.indexOf(this.props.mxEvent.getId()); if (index !== -1) { pinned.splice(index, 1); - MatrixClientPeg.get().sendStateEvent(this.props.mxRoom.roomId, 'm.room.pinned_events', {pinned}, '').then(() => { + MatrixClientPeg.get().sendStateEvent(this.props.mxRoom.roomId, 'm.room.pinned_events', {pinned}, '') + .then(() => { if (this.props.onUnpinned) this.props.onUnpinned(); }); } else if (this.props.onUnpinned) this.props.onUnpinned(); diff --git a/src/components/views/rooms/PinnedEventsPanel.js b/src/components/views/rooms/PinnedEventsPanel.js index 2e3f6e8390..deea03f030 100644 --- a/src/components/views/rooms/PinnedEventsPanel.js +++ b/src/components/views/rooms/PinnedEventsPanel.js @@ -47,20 +47,21 @@ module.exports = React.createClass({ const promises = []; const cli = MatrixClientPeg.get(); - pinnedEvents.getContent().pinned.map(eventId => { - promises.push(cli.getEventTimeline(this.props.room.getUnfilteredTimelineSet(), eventId, 0).then(timeline => { - const event = timeline.getEvents().find(e => e.getId() === eventId); + pinnedEvents.getContent().pinned.map((eventId) => { + promises.push(cli.getEventTimeline(this.props.room.getUnfilteredTimelineSet(), eventId, 0).then( + (timeline) => { + const event = timeline.getEvents().find((e) => e.getId() === eventId); return {eventId, timeline, event}; - }).catch(err => { + }).catch((err) => { console.error("Error looking up pinned event " + eventId + " in room " + this.props.room.roomId); console.error(err); return null; // return lack of context to avoid unhandled errors })); }); - Promise.all(promises).then(contexts => { + Promise.all(promises).then((contexts) => { // Filter out the messages before we try to render them - const pinned = contexts.filter(context => { + const pinned = contexts.filter((context) => { if (!context) return false; // no context == not applicable for the room if (context.event.getType() !== "m.room.message") return false; if (context.event.isRedacted()) return false; @@ -77,8 +78,11 @@ module.exports = React.createClass({ return (
{ _t("No pinned messages.") }
); } - return this.state.pinned.map(context => { - return (); + return this.state.pinned.map((context) => { + return (); }); }, From bcb792a412e452039f08413ae624a8779b12401b Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 16 Oct 2017 14:41:23 +0100 Subject: [PATCH 36/41] Released js-sdk --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e564366e61..7b81c63777 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "isomorphic-fetch": "^2.2.1", "linkifyjs": "^2.1.3", "lodash": "^4.13.1", - "matrix-js-sdk": "0.8.5-rc.1", + "matrix-js-sdk": "0.8.5", "optimist": "^0.6.1", "prop-types": "^15.5.8", "react": "^15.4.0", From bb623ca0a7e61d894acf217abaf91585a4ee1fb4 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 16 Oct 2017 14:45:13 +0100 Subject: [PATCH 37/41] Prepare changelog for v0.10.7 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75c99e299b..2c2af18e43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +Changes in [0.10.7](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.10.7) (2017-10-16) +===================================================================================================== +[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.10.7-rc.3...v0.10.7) + + * Update to latest js-sdk + Changes in [0.10.7-rc.3](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.10.7-rc.3) (2017-10-13) =============================================================================================================== [Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.10.7-rc.2...v0.10.7-rc.3) From f58d89ef802f28bbab851fe63c3e6ff332394a5d Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 16 Oct 2017 14:45:14 +0100 Subject: [PATCH 38/41] v0.10.7 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7b81c63777..8693e33471 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-react-sdk", - "version": "0.10.7-rc.3", + "version": "0.10.7", "description": "SDK for matrix.org using React", "author": "matrix.org", "repository": { From 47ac0988ba55c087ef15f32470d8ae5ce7c0434d Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 16 Oct 2017 16:31:13 +0100 Subject: [PATCH 39/41] Refactor class names for an entity tile being hovered over --- src/components/views/rooms/EntityTile.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/EntityTile.js b/src/components/views/rooms/EntityTile.js index 64934f3cca..1df19340cd 100644 --- a/src/components/views/rooms/EntityTile.js +++ b/src/components/views/rooms/EntityTile.js @@ -116,7 +116,9 @@ module.exports = React.createClass({ nameEl = (
- { name } + + { name } + From 008e8d4f545309396ca7a4644a31b75f7012f116 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 16 Oct 2017 16:38:32 +0100 Subject: [PATCH 40/41] Show "Invited" section in the user list --- .../views/groups/GroupMemberList.js | 38 +++++++++++++++---- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/components/views/groups/GroupMemberList.js b/src/components/views/groups/GroupMemberList.js index 6a257259f9..00d84ad1fc 100644 --- a/src/components/views/groups/GroupMemberList.js +++ b/src/components/views/groups/GroupMemberList.js @@ -36,6 +36,7 @@ export default withMatrixClient(React.createClass({ return { fetching: false, members: null, + invited_members: null, truncateAt: INITIAL_LOAD_NUM_MEMBERS, }; }, @@ -58,6 +59,18 @@ export default withMatrixClient(React.createClass({ this.setState({fetching: false}); console.error("Failed to get group member list: " + e); }); + + this.props.matrixClient.getGroupInvitedUsers(this.props.groupId).then((result) => { + this.setState({ + invited_members: result.chunk.map((apiMember) => { + return groupMemberFromApiObject(apiMember); + }), + fetching: false, + }); + }).catch((e) => { + this.setState({fetching: false}); + console.error("Failed to get group invited member list: " + e); + }); }, _createOverflowTile: function(overflowCount, totalCount) { @@ -83,11 +96,9 @@ export default withMatrixClient(React.createClass({ this.setState({ searchQuery: ev.target.value }); }, - makeGroupMemberTiles: function(query) { + makeGroupMemberTiles: function(query, memberList) { const GroupMemberTile = sdk.getComponent("groups.GroupMemberTile"); query = (query || "").toLowerCase(); - - let memberList = this.state.members; if (query) { memberList = memberList.filter((m) => { const matchesName = m.displayname.toLowerCase().indexOf(query) !== -1; @@ -143,11 +154,22 @@ export default withMatrixClient(React.createClass({ return (
{ inputBox } - - - { this.makeGroupMemberTiles(this.state.searchQuery) } - + +
+ + { this.makeGroupMemberTiles(this.state.searchQuery, this.state.members) } + +
+
+

{ _t("Invited") }

+
+ + { this.makeGroupMemberTiles(this.state.searchQuery, this.state.invited_members) } + +
+
); From 9b08f4d11f55bdbc823214b75a9b51dc2f9aae48 Mon Sep 17 00:00:00 2001 From: Luke Barnard Date: Mon, 16 Oct 2017 17:21:05 +0100 Subject: [PATCH 41/41] Separate fetching indicator state --- .../views/groups/GroupMemberList.js | 52 ++++++++++--------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/src/components/views/groups/GroupMemberList.js b/src/components/views/groups/GroupMemberList.js index 00d84ad1fc..f800130a32 100644 --- a/src/components/views/groups/GroupMemberList.js +++ b/src/components/views/groups/GroupMemberList.js @@ -35,8 +35,9 @@ export default withMatrixClient(React.createClass({ getInitialState: function() { return { fetching: false, + fetchingInvitedMembers: false, members: null, - invited_members: null, + invitedMembers: null, truncateAt: INITIAL_LOAD_NUM_MEMBERS, }; }, @@ -47,7 +48,10 @@ export default withMatrixClient(React.createClass({ }, _fetchMembers: function() { - this.setState({fetching: true}); + this.setState({ + fetching: true, + fetchingInvitedMembers: true, + }); this.props.matrixClient.getGroupUsers(this.props.groupId).then((result) => { this.setState({ members: result.chunk.map((apiMember) => { @@ -62,13 +66,13 @@ export default withMatrixClient(React.createClass({ this.props.matrixClient.getGroupInvitedUsers(this.props.groupId).then((result) => { this.setState({ - invited_members: result.chunk.map((apiMember) => { + invitedMembers: result.chunk.map((apiMember) => { return groupMemberFromApiObject(apiMember); }), - fetching: false, + fetchingInvitedMembers: false, }); }).catch((e) => { - this.setState({fetching: false}); + this.setState({fetchingInvitedMembers: false}); console.error("Failed to get group invited member list: " + e); }); }, @@ -98,6 +102,7 @@ export default withMatrixClient(React.createClass({ makeGroupMemberTiles: function(query, memberList) { const GroupMemberTile = sdk.getComponent("groups.GroupMemberTile"); + const TruncatedList = sdk.getComponent("elements.TruncatedList"); query = (query || "").toLowerCase(); if (query) { memberList = memberList.filter((m) => { @@ -129,17 +134,19 @@ export default withMatrixClient(React.createClass({ } }); - return memberList; + return + { memberList } + ; }, render: function() { - if (this.state.fetching) { + if (this.state.fetching || this.state.fetchingInvitedMembers) { const Spinner = sdk.getComponent("elements.Spinner"); return (
); - } else if (this.state.members === null) { - return null; } const inputBox = ( @@ -150,26 +157,21 @@ export default withMatrixClient(React.createClass({ ); - const TruncatedList = sdk.getComponent("elements.TruncatedList"); + const joined = this.state.members ?
+ { this.makeGroupMemberTiles(this.state.searchQuery, this.state.members) } +
:
; + + const invited = this.state.invitedMembers ?
+

{ _t("Invited") }

+ { this.makeGroupMemberTiles(this.state.searchQuery, this.state.invitedMembers) } +
:
; + return (
{ inputBox } -
- - { this.makeGroupMemberTiles(this.state.searchQuery, this.state.members) } - -
-
-

{ _t("Invited") }

-
- - { this.makeGroupMemberTiles(this.state.searchQuery, this.state.invited_members) } - -
-
+ { joined } + { invited }
);