Add action bar to pinned event tiles; support unpinning from the panel

Signed-off-by: Travis Ralston <travpc@gmail.com>
This commit is contained in:
Travis Ralston 2017-09-29 10:41:23 -06:00
parent fa5a23e0df
commit 9b11f576fe
2 changed files with 52 additions and 3 deletions

View File

@ -29,6 +29,7 @@ const PinnedEventTile = React.createClass({
propTypes: { propTypes: {
mxRoom: React.PropTypes.object.isRequired, mxRoom: React.PropTypes.object.isRequired,
mxEvent: React.PropTypes.object.isRequired, mxEvent: React.PropTypes.object.isRequired,
onUnpinned: React.PropTypes.func,
}, },
onTileClicked: function() { onTileClicked: function() {
dis.dispatch({ dis.dispatch({
@ -38,6 +39,22 @@ const PinnedEventTile = React.createClass({
room_id: this.props.mxEvent.getRoomId(), 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() { render: function() {
const MessageEvent = sdk.getComponent("views.messages.MessageEvent"); const MessageEvent = sdk.getComponent("views.messages.MessageEvent");
const MemberAvatar = sdk.getComponent("views.avatars.MemberAvatar"); const MemberAvatar = sdk.getComponent("views.avatars.MemberAvatar");
@ -46,7 +63,15 @@ const PinnedEventTile = React.createClass({
const avatarSize = 40; const avatarSize = 40;
return ( return (
<div className="mx_PinnedEventTile" onClick={this.onTileClicked}> <div className="mx_PinnedEventTile">
<div className="mx_PinnedEventTile_actions">
<AccessibleButton className="mx_PinnedEventTile_gotoButton mx_textButton" onClick={this.onTileClicked}>
Jump to message
</AccessibleButton>
<img src="img/cancel-red.svg" className="mx_PinnedEventTile_unpinButton" width="8" height="8"
onClick={this.onUnpinClicked} alt={_t('Unpin Message')} title={_t('Unpin Message')} />
</div>
<MemberAvatar member={sender} width={avatarSize} height={avatarSize} /> <MemberAvatar member={sender} width={avatarSize} height={avatarSize} />
<span className="mx_PinnedEventTile_sender"> <span className="mx_PinnedEventTile_sender">
{sender.name} {sender.name}
@ -73,6 +98,10 @@ module.exports = React.createClass({
}, },
componentDidMount: function() { componentDidMount: function() {
this._updatePinnedMessages();
},
_updatePinnedMessages: function() {
const pinnedEvents = this.props.room.currentState.getStateEvents("m.room.pinned_events", ""); const pinnedEvents = this.props.room.currentState.getStateEvents("m.room.pinned_events", "");
if (!pinnedEvents || !pinnedEvents.getContent().pinned) { if (!pinnedEvents || !pinnedEvents.getContent().pinned) {
this.setState({ loading: false, 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 // Don't show non-messages. Technically users can pin state/custom events, but we won't
// support those events. // support those events.
if (event.getType() !== "m.room.message") return ''; if (event.getType() !== "m.room.message") return '';
return (<PinnedEventTile key={event.getId()} mxRoom={this.props.room} mxEvent={event} />); return (<PinnedEventTile key={event.getId()} mxRoom={this.props.room} mxEvent={event} onUnpinned={this._updatePinnedMessages} />);
}); });
}, },

View File

@ -32,7 +32,6 @@ limitations under the License.
.mx_PinnedEventTile { .mx_PinnedEventTile {
min-height: 40px; min-height: 40px;
margin-bottom: 5px; margin-bottom: 5px;
cursor: pointer;
width: 100%; width: 100%;
border-radius: 5px; // for the hover border-radius: 5px; // for the hover
} }
@ -46,6 +45,7 @@ limitations under the License.
font-size: 0.8em; font-size: 0.8em;
vertical-align: top; vertical-align: top;
display: block; display: block;
padding-bottom: 3px;
} }
.mx_PinnedEventTile .mx_EventTile_content { .mx_PinnedEventTile .mx_EventTile_content {
@ -65,3 +65,23 @@ limitations under the License.
float: right; float: right;
display: inline-block; 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;
}