Skip to content

Commit

Permalink
Merge pull request #5142 from turt2live/travis/pinned_messages
Browse files Browse the repository at this point in the history
Message/event pinning
  • Loading branch information
ara4n committed Oct 15, 2017
2 parents 6f81960 + 6926c96 commit f143315
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 5 deletions.
56 changes: 51 additions & 5 deletions src/components/views/context_menus/MessageContextMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,26 +43,40 @@ module.exports = React.createClass({
getInitialState: function() {
return {
canRedact: false,
canPin: false,
};
},

componentWillMount: function() {
MatrixClientPeg.get().on('RoomMember.powerLevel', this._checkCanRedact);
this._checkCanRedact();
MatrixClientPeg.get().on('RoomMember.powerLevel', this._checkPermissions);
this._checkPermissions();
},

componentWillUnmount: function() {
const cli = MatrixClientPeg.get();
if (cli) {
cli.removeListener('RoomMember.powerLevel', this._checkCanRedact);
cli.removeListener('RoomMember.powerLevel', this._checkPermissions);
}
},

_checkCanRedact: function() {
_checkPermissions: function() {
const cli = MatrixClientPeg.get();
const room = cli.getRoom(this.props.mxEvent.getRoomId());

const canRedact = room.currentState.maySendRedactionForEvent(this.props.mxEvent, cli.credentials.userId);
this.setState({canRedact});
let canPin = room.currentState.mayClientSendStateEvent('m.room.pinned_events', cli);

// HACK: Intentionally say we can't pin if the user doesn't want to use the functionality
if (!UserSettingsStore.isFeatureEnabled("feature_pinning")) canPin = false;

this.setState({canRedact, canPin});
},

_isPinned: function() {
const room = MatrixClientPeg.get().getRoom(this.props.mxEvent.getRoomId());
const pinnedEvent = room.currentState.getStateEvents('m.room.pinned_events', '');
if (!pinnedEvent) return false;
return pinnedEvent.getContent().pinned.includes(this.props.mxEvent.getId());
},

onResendClick: function() {
Expand Down Expand Up @@ -122,6 +136,28 @@ module.exports = React.createClass({
this.closeMenu();
},

onPinClick: function() {
MatrixClientPeg.get().getStateEvent(this.props.mxEvent.getRoomId(), 'm.room.pinned_events', '')
.catch(e => {
// Intercept the Event Not Found error and fall through the promise chain with no event.
if (e.errcode === "M_NOT_FOUND") return null;
throw e;
})
.then(event => {
const eventIds = (event ? event.pinned : []) || [];
if (!eventIds.includes(this.props.mxEvent.getId())) {
// Not pinned - add
eventIds.push(this.props.mxEvent.getId());
} else {
// Pinned - remove
eventIds.splice(eventIds.indexOf(this.props.mxEvent.getId()), 1);
}

MatrixClientPeg.get().sendStateEvent(this.props.mxEvent.getRoomId(), 'm.room.pinned_events', {pinned: eventIds}, '');
});
this.closeMenu();
},

closeMenu: function() {
if (this.props.onFinished) this.props.onFinished();
},
Expand All @@ -147,6 +183,7 @@ module.exports = React.createClass({
let redactButton;
let cancelButton;
let forwardButton;
let pinButton;
let viewSourceButton;
let viewClearSourceButton;
let unhidePreviewButton;
Expand Down Expand Up @@ -186,6 +223,14 @@ module.exports = React.createClass({
{ _t('Forward Message') }
</div>
);

if (this.state.canPin) {
pinButton = (
<div className="mx_MessageContextMenu_field" onClick={this.onPinClick}>
{this._isPinned() ? _t('Unpin Message') : _t('Pin Message')}
</div>
);
}
}
}

Expand Down Expand Up @@ -246,6 +291,7 @@ module.exports = React.createClass({
{redactButton}
{cancelButton}
{forwardButton}
{pinButton}
{viewSourceButton}
{viewClearSourceButton}
{unhidePreviewButton}
Expand Down
5 changes: 5 additions & 0 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,11 @@
"You have successfully set a password!": "You have successfully set a password!",
"You can now return to your account after signing out, and sign in on other devices.": "You can now return to your account after signing out, and sign in on other devices.",
"Continue": "Continue",
"Pin Message": "Pin Message",
"Unpin Message": "Unpin Message",
"Jump to message": "Jump to message",
"No pinned messages.": "No pinned messages.",
"Loading...": "Loading...",
"Please set a password!": "Please set a password!",
"This will allow you to return to your account after signing out, and sign in on other devices.": "This will allow you to return to your account after signing out, and sign in on other devices.",
"You have successfully set a password and an email address!": "You have successfully set a password and an email address!",
Expand Down
5 changes: 5 additions & 0 deletions src/i18n/strings/en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,11 @@
"You have successfully set a password and an email address!": "You have successfully set a password and an email address!",
"Remember, you can always set an email address in user settings if you change your mind.": "Remember, you can always set an email address in user settings if you change your mind.",
"Warning": "Warning",
"Pin Message": "Pin Message",
"Unpin Message": "Unpin Message",
"Jump to message": "Jump to message",
"No pinned messages.": "No pinned messages.",
"Loading...": "Loading...",
"Checking for an update...": "Checking for an update...",
"Error encountered (%(errorDetail)s).": "Error encountered (%(errorDetail)s).",
"No update available.": "No update available.",
Expand Down
2 changes: 2 additions & 0 deletions src/skins/vector/css/_components.scss
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@
@import "./matrix-react-sdk/views/voip/_CallView.scss";
@import "./matrix-react-sdk/views/voip/_IncomingCallbox.scss";
@import "./matrix-react-sdk/views/voip/_VideoView.scss";
@import "./matrix-react-sdk/views/rooms/_PinnedEventsPanel.scss";
@import "./matrix-react-sdk/views/rooms/_PinnedEventTile.scss";
@import "./vector-web/_fonts.scss";
@import "./vector-web/structures/_CompatibilityPage.scss";
@import "./vector-web/structures/_HomePage.scss";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
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.
*/

.mx_PinnedEventTile {
min-height: 40px;
margin-bottom: 5px;
width: 100%;
border-radius: 5px; // for the hover
}

.mx_PinnedEventTile:hover {
background-color: $event-selected-color;
}

.mx_PinnedEventTile .mx_PinnedEventTile_sender {
color: #868686;
font-size: 0.8em;
vertical-align: top;
display: block;
padding-bottom: 3px;
}

.mx_PinnedEventTile .mx_EventTile_content {
margin-left: 50px;
position: relative;
top: 0;
left: 0;
}

.mx_PinnedEventTile .mx_BaseAvatar {
float: left;
margin-right: 10px;
}

.mx_PinnedEventTile:hover .mx_PinnedEventTile_actions {
display: block;
}

.mx_PinnedEventTile_actions {
float: right;
margin-right: 10px;
display: none;
}

.mx_PinnedEventTile_unpinButton {
display: inline-block;
cursor: pointer;
margin-left: 10px;
}

.mx_PinnedEventTile_gotoButton {
display: inline-block;
font-size: 0.8em;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
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.
*/

.mx_PinnedEventsPanel {
border-top: 1px solid $primary-hairline-color;
}

.mx_PinnedEventsPanel_body {
max-height: 300px;
overflow-y: auto;
padding-bottom: 15px;
}

.mx_PinnedEventsPanel_header {
margin: 0;
padding-top: 8px;
padding-bottom: 15px;
}

.mx_PinnedEventsPanel_cancel {
margin: 12px;
float: right;
display: inline-block;
}
7 changes: 7 additions & 0 deletions src/skins/vector/img/icons-pin.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit f143315

Please sign in to comment.