diff --git a/src/components/views/rooms/PinnedEventsPanel.js b/src/components/views/rooms/PinnedEventsPanel.js index a5d5d2ed..53bf3db6 100644 --- a/src/components/views/rooms/PinnedEventsPanel.js +++ b/src/components/views/rooms/PinnedEventsPanel.js @@ -29,6 +29,7 @@ const PinnedEventTile = React.createClass({ propTypes: { mxRoom: React.PropTypes.object.isRequired, mxEvent: React.PropTypes.object.isRequired, + onUnpinned: React.PropTypes.func, }, onTileClicked: function() { dis.dispatch({ @@ -38,6 +39,22 @@ const PinnedEventTile = React.createClass({ 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(); + } + }, render: function() { const MessageEvent = sdk.getComponent("views.messages.MessageEvent"); const MemberAvatar = sdk.getComponent("views.avatars.MemberAvatar"); @@ -46,7 +63,15 @@ const PinnedEventTile = React.createClass({ const avatarSize = 40; return ( -
+
+
+ + Jump to message + + {_t('Unpin +
+ {sender.name} @@ -73,6 +98,10 @@ module.exports = React.createClass({ }, 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: [] }); @@ -103,7 +132,7 @@ module.exports = React.createClass({ // Don't show non-messages. Technically users can pin state/custom events, but we won't // support those events. if (event.getType() !== "m.room.message") return ''; - return (); + return (); }); }, diff --git a/src/skins/vector/css/vector-web/views/rooms/_PinnedEventsPanel.scss b/src/skins/vector/css/vector-web/views/rooms/_PinnedEventsPanel.scss index 133fa703..a2041cfe 100644 --- a/src/skins/vector/css/vector-web/views/rooms/_PinnedEventsPanel.scss +++ b/src/skins/vector/css/vector-web/views/rooms/_PinnedEventsPanel.scss @@ -32,7 +32,6 @@ limitations under the License. .mx_PinnedEventTile { min-height: 40px; margin-bottom: 5px; - cursor: pointer; width: 100%; border-radius: 5px; // for the hover } @@ -46,6 +45,7 @@ limitations under the License. font-size: 0.8em; vertical-align: top; display: block; + padding-bottom: 3px; } .mx_PinnedEventTile .mx_EventTile_content { @@ -65,3 +65,23 @@ limitations under the License. float: right; display: inline-block; } + +.mx_PinnedEventTile:hover .mx_PinnedEventTile_actions { + display: block; +} + +.mx_PinnedEventTile_actions { + float: right; + margin-right: 10px; + display: none; +} + +.mx_PinnedEventTile_unpinButton { + cursor: pointer; + margin-left: 10px; +} + +.mx_PinnedEventTile_gotoButton { + display: inline-block; + font-size: 0.8em; +}