Merge pull request #1486 from turt2live/travis/pinned-notice

Add a small indicator for when a new event is pinned
This commit is contained in:
Matthew Hodgson 2017-11-07 17:56:12 +00:00 committed by GitHub
commit e14e0bf200
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 102 additions and 8 deletions

View file

@ -19,6 +19,7 @@ import MatrixClientPeg from "../../../MatrixClientPeg";
import AccessibleButton from "../elements/AccessibleButton";
import PinnedEventTile from "./PinnedEventTile";
import { _t } from '../../../languageHandler';
import PinningUtils from "../../../utils/PinningUtils";
module.exports = React.createClass({
displayName: 'PinnedEventsPanel',
@ -61,20 +62,39 @@ module.exports = React.createClass({
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;
});
const pinned = contexts.filter((context) => PinningUtils.isPinnable(context.event));
this.setState({ loading: false, pinned });
});
}
this._updateReadState();
},
_updateReadState: function() {
const pinnedEvents = this.props.room.currentState.getStateEvents("m.room.pinned_events", "");
if (!pinnedEvents) return; // nothing to read
let readStateEvents = null;
const readPinsEvent = this.props.room.getAccountData("im.vector.room.read_pins");
if (readPinsEvent && readPinsEvent.getContent()) {
readStateEvents = readPinsEvent.getContent().event_ids || [];
}
if (!readStateEvents.includes(pinnedEvents.getId())) {
readStateEvents.push(pinnedEvents.getId());
// Only keep the last 10 event IDs to avoid infinite growth
readStateEvents = readStateEvents.reverse().splice(0, 10).reverse();
MatrixClientPeg.get().setRoomAccountData(this.props.room.roomId, "im.vector.room.read_pins", {
event_ids: readStateEvents,
});
}
},
_getPinnedTiles: function() {
if (this.state.pinned.length == 0) {
if (this.state.pinned.length === 0) {
return (<div>{ _t("No pinned messages.") }</div>);
}

View file

@ -65,6 +65,7 @@ module.exports = React.createClass({
componentDidMount: function() {
const cli = MatrixClientPeg.get();
cli.on("RoomState.events", this._onRoomStateEvents);
cli.on("Room.accountData", this._onRoomAccountData);
// When a room name occurs, RoomState.events is fired *before*
// room.name is updated. So we have to listen to Room.name as well as
@ -87,6 +88,7 @@ module.exports = React.createClass({
const cli = MatrixClientPeg.get();
if (cli) {
cli.removeListener("RoomState.events", this._onRoomStateEvents);
cli.removeListener("Room.accountData", this._onRoomAccountData);
}
},
@ -99,6 +101,13 @@ module.exports = React.createClass({
this._rateLimitedUpdate();
},
_onRoomAccountData: function(event, room) {
if (!this.props.room || room.roomId !== this.props.room.roomId) return;
if (event.getType() !== "im.vector.room.read_pins") return;
this._rateLimitedUpdate();
},
_rateLimitedUpdate: new RateLimitedFunc(function() {
/* eslint-disable babel/no-invalid-this */
this.forceUpdate();
@ -139,6 +148,32 @@ module.exports = React.createClass({
dis.dispatch({ action: 'show_right_panel' });
},
_hasUnreadPins: function() {
const currentPinEvent = this.props.room.currentState.getStateEvents("m.room.pinned_events", '');
if (!currentPinEvent) return false;
if (currentPinEvent.getContent().pinned && currentPinEvent.getContent().pinned.length <= 0) {
return false; // no pins == nothing to read
}
const readPinsEvent = this.props.room.getAccountData("im.vector.room.read_pins");
if (readPinsEvent && readPinsEvent.getContent()) {
const readStateEvents = readPinsEvent.getContent().event_ids || [];
if (readStateEvents) {
return !readStateEvents.includes(currentPinEvent.getId());
}
}
// There's pins, and we haven't read any of them
return true;
},
_hasPins: function() {
const currentPinEvent = this.props.room.currentState.getStateEvents("m.room.pinned_events", '');
if (!currentPinEvent) return false;
return !(currentPinEvent.getContent().pinned && currentPinEvent.getContent().pinned.length <= 0);
},
/**
* After editing the settings, get the new name for the room
*
@ -305,8 +340,17 @@ module.exports = React.createClass({
}
if (this.props.onPinnedClick && UserSettingsStore.isFeatureEnabled('feature_pinning')) {
let pinsIndicator = null;
if (this._hasUnreadPins()) {
pinsIndicator = (<div className="mx_RoomHeader_pinsIndicator mx_RoomHeader_pinsIndicatorUnread" />);
} else if (this._hasPins()) {
pinsIndicator = (<div className="mx_RoomHeader_pinsIndicator" />);
}
pinnedEventsButton =
<AccessibleButton className="mx_RoomHeader_button" onClick={this.props.onPinnedClick} title={_t("Pinned Messages")}>
<AccessibleButton className="mx_RoomHeader_button mx_RoomHeader_pinnedButton"
onClick={this.props.onPinnedClick} title={_t("Pinned Messages")}>
{ pinsIndicator }
<TintableSvg src="img/icons-pin.svg" width="16" height="16" />
</AccessibleButton>;
}