forked from matrix/element-web
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:
parent
fa5a23e0df
commit
9b11f576fe
|
@ -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} />);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue