Merge pull request #1676 from turt2live/travis/remove-presence
Remove presence managementpull/21833/head
commit
d0827586e6
|
@ -98,7 +98,6 @@ class MatrixClientPeg {
|
||||||
const opts = utils.deepCopy(this.opts);
|
const opts = utils.deepCopy(this.opts);
|
||||||
// the react sdk doesn't work without this, so don't allow
|
// the react sdk doesn't work without this, so don't allow
|
||||||
opts.pendingEventOrdering = "detached";
|
opts.pendingEventOrdering = "detached";
|
||||||
opts.disablePresence = true; // we do this manually
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const promise = this.matrixClient.store.startup();
|
const promise = this.matrixClient.store.startup();
|
||||||
|
|
|
@ -57,27 +57,13 @@ class Presence {
|
||||||
return this.state;
|
return this.state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current status message.
|
|
||||||
* @returns {String} the status message, may be null
|
|
||||||
*/
|
|
||||||
getStatusMessage() {
|
|
||||||
return this.statusMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the presence state.
|
* Set the presence state.
|
||||||
* If the state has changed, the Home Server will be notified.
|
* If the state has changed, the Home Server will be notified.
|
||||||
* @param {string} newState the new presence state (see PRESENCE enum)
|
* @param {string} newState the new presence state (see PRESENCE enum)
|
||||||
* @param {String} statusMessage an optional status message for the presence
|
|
||||||
* @param {boolean} maintain true to have this status maintained by this tracker
|
|
||||||
*/
|
*/
|
||||||
setState(newState, statusMessage=null, maintain=false) {
|
setState(newState) {
|
||||||
if (this.maintain) {
|
if (newState === this.state) {
|
||||||
// Don't update presence if we're maintaining a particular status
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (newState === this.state && statusMessage === this.statusMessage) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (PRESENCE_STATES.indexOf(newState) === -1) {
|
if (PRESENCE_STATES.indexOf(newState) === -1) {
|
||||||
|
@ -87,37 +73,21 @@ class Presence {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const old_state = this.state;
|
const old_state = this.state;
|
||||||
const old_message = this.statusMessage;
|
|
||||||
this.state = newState;
|
this.state = newState;
|
||||||
this.statusMessage = statusMessage;
|
|
||||||
this.maintain = maintain;
|
|
||||||
|
|
||||||
if (MatrixClientPeg.get().isGuest()) {
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
return; // don't try to set presence when a guest; it won't work.
|
return; // don't try to set presence when a guest; it won't work.
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateContent = {
|
|
||||||
presence: this.state,
|
|
||||||
status_msg: this.statusMessage ? this.statusMessage : '',
|
|
||||||
};
|
|
||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
MatrixClientPeg.get().setPresence(updateContent).done(function() {
|
MatrixClientPeg.get().setPresence(this.state).done(function() {
|
||||||
console.log("Presence: %s", newState);
|
console.log("Presence: %s", newState);
|
||||||
|
|
||||||
// We have to dispatch because the js-sdk is unreliable at telling us about our own presence
|
|
||||||
dis.dispatch({action: "self_presence_updated", statusInfo: updateContent});
|
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
console.error("Failed to set presence: %s", err);
|
console.error("Failed to set presence: %s", err);
|
||||||
self.state = old_state;
|
self.state = old_state;
|
||||||
self.statusMessage = old_message;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
stopMaintainingStatus() {
|
|
||||||
this.maintain = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback called when the user made no action on the page for UNAVAILABLE_TIME ms.
|
* Callback called when the user made no action on the page for UNAVAILABLE_TIME ms.
|
||||||
* @private
|
* @private
|
||||||
|
|
|
@ -1,169 +0,0 @@
|
||||||
/*
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import React from "react";
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import * as sdk from "../../../index";
|
|
||||||
import MatrixClientPeg from "../../../MatrixClientPeg";
|
|
||||||
import AccessibleButton from '../elements/AccessibleButton';
|
|
||||||
import Presence from "../../../Presence";
|
|
||||||
import dispatcher from "../../../dispatcher";
|
|
||||||
import * as ContextualMenu from "../../structures/ContextualMenu";
|
|
||||||
import SettingsStore from "../../../settings/SettingsStore";
|
|
||||||
|
|
||||||
// This is an avatar with presence information and controls on it.
|
|
||||||
module.exports = React.createClass({
|
|
||||||
displayName: 'MemberPresenceAvatar',
|
|
||||||
|
|
||||||
propTypes: {
|
|
||||||
member: PropTypes.object.isRequired,
|
|
||||||
width: PropTypes.number,
|
|
||||||
height: PropTypes.number,
|
|
||||||
resizeMethod: PropTypes.string,
|
|
||||||
},
|
|
||||||
|
|
||||||
getDefaultProps: function() {
|
|
||||||
return {
|
|
||||||
width: 40,
|
|
||||||
height: 40,
|
|
||||||
resizeMethod: 'crop',
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
getInitialState: function() {
|
|
||||||
let presenceState = null;
|
|
||||||
let presenceMessage = null;
|
|
||||||
|
|
||||||
// RoomMembers do not necessarily have a user.
|
|
||||||
if (this.props.member.user) {
|
|
||||||
presenceState = this.props.member.user.presence;
|
|
||||||
presenceMessage = this.props.member.user.presenceStatusMsg;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
status: presenceState,
|
|
||||||
message: presenceMessage,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
componentWillMount: function() {
|
|
||||||
MatrixClientPeg.get().on("User.presence", this.onUserPresence);
|
|
||||||
this.dispatcherRef = dispatcher.register(this.onAction);
|
|
||||||
},
|
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
|
||||||
if (MatrixClientPeg.get()) {
|
|
||||||
MatrixClientPeg.get().removeListener("User.presence", this.onUserPresence);
|
|
||||||
}
|
|
||||||
dispatcher.unregister(this.dispatcherRef);
|
|
||||||
},
|
|
||||||
|
|
||||||
onAction: function(payload) {
|
|
||||||
if (payload.action !== "self_presence_updated") return;
|
|
||||||
if (this.props.member.userId !== MatrixClientPeg.get().getUserId()) return;
|
|
||||||
this.setState({
|
|
||||||
status: payload.statusInfo.presence,
|
|
||||||
message: payload.statusInfo.status_msg,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onUserPresence: function(event, user) {
|
|
||||||
if (user.userId !== MatrixClientPeg.get().getUserId()) return;
|
|
||||||
this.setState({
|
|
||||||
status: user.presence,
|
|
||||||
message: user.presenceStatusMsg,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onStatusChange: function(newStatus) {
|
|
||||||
Presence.stopMaintainingStatus();
|
|
||||||
if (newStatus === "online") {
|
|
||||||
Presence.setState(newStatus);
|
|
||||||
} else Presence.setState(newStatus, null, true);
|
|
||||||
},
|
|
||||||
|
|
||||||
onClick: function(e) {
|
|
||||||
const PresenceContextMenu = sdk.getComponent('context_menus.PresenceContextMenu');
|
|
||||||
const elementRect = e.target.getBoundingClientRect();
|
|
||||||
|
|
||||||
// The window X and Y offsets are to adjust position when zoomed in to page
|
|
||||||
const x = (elementRect.left + window.pageXOffset) - (elementRect.width / 2) + 3;
|
|
||||||
const chevronOffset = 12;
|
|
||||||
let y = elementRect.top + (elementRect.height / 2) + window.pageYOffset;
|
|
||||||
y = y - (chevronOffset + 4); // where 4 is 1/4 the height of the chevron
|
|
||||||
|
|
||||||
ContextualMenu.createMenu(PresenceContextMenu, {
|
|
||||||
chevronOffset: chevronOffset,
|
|
||||||
chevronFace: 'bottom',
|
|
||||||
left: x,
|
|
||||||
top: y,
|
|
||||||
menuWidth: 125,
|
|
||||||
currentStatus: this.state.status,
|
|
||||||
onChange: this.onStatusChange,
|
|
||||||
});
|
|
||||||
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
// XXX NB the following assumes that user is non-null, which is not valid
|
|
||||||
// const presenceState = this.props.member.user.presence;
|
|
||||||
// const presenceLastActiveAgo = this.props.member.user.lastActiveAgo;
|
|
||||||
// const presenceLastTs = this.props.member.user.lastPresenceTs;
|
|
||||||
// const presenceCurrentlyActive = this.props.member.user.currentlyActive;
|
|
||||||
// const presenceMessage = this.props.member.user.presenceStatusMsg;
|
|
||||||
},
|
|
||||||
|
|
||||||
render: function() {
|
|
||||||
const MemberAvatar = sdk.getComponent("avatars.MemberAvatar");
|
|
||||||
|
|
||||||
let onClickFn = null;
|
|
||||||
if (this.props.member.userId === MatrixClientPeg.get().getUserId()) {
|
|
||||||
onClickFn = this.onClick;
|
|
||||||
}
|
|
||||||
|
|
||||||
const avatarNode = (
|
|
||||||
<MemberAvatar member={this.props.member} width={this.props.width} height={this.props.height}
|
|
||||||
resizeMethod={this.props.resizeMethod} />
|
|
||||||
);
|
|
||||||
let statusNode = (
|
|
||||||
<span className={"mx_MemberPresenceAvatar_status mx_MemberPresenceAvatar_status_" + this.state.status} />
|
|
||||||
);
|
|
||||||
|
|
||||||
// LABS: Disable presence management functions for now
|
|
||||||
// Also disable the presence information if there's no status information
|
|
||||||
if (!SettingsStore.isFeatureEnabled("feature_presence_management") || !this.state.status) {
|
|
||||||
statusNode = null;
|
|
||||||
onClickFn = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let avatar = (
|
|
||||||
<div className="mx_MemberPresenceAvatar">
|
|
||||||
{ avatarNode }
|
|
||||||
{ statusNode }
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
if (onClickFn) {
|
|
||||||
avatar = (
|
|
||||||
<AccessibleButton onClick={onClickFn} className="mx_MemberPresenceAvatar" element="div">
|
|
||||||
{ avatarNode }
|
|
||||||
{ statusNode }
|
|
||||||
</AccessibleButton>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return avatar;
|
|
||||||
},
|
|
||||||
});
|
|
|
@ -235,7 +235,7 @@ export default class MessageComposer extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const me = this.props.room.getMember(MatrixClientPeg.get().credentials.userId);
|
const me = this.props.room.getMember(MatrixClientPeg.get().credentials.userId);
|
||||||
const uploadInputStyle = {display: 'none'};
|
const uploadInputStyle = {display: 'none'};
|
||||||
const MemberPresenceAvatar = sdk.getComponent('avatars.MemberPresenceAvatar');
|
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
|
||||||
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
const TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||||
const MessageComposerInput = sdk.getComponent("rooms.MessageComposerInput");
|
const MessageComposerInput = sdk.getComponent("rooms.MessageComposerInput");
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ export default class MessageComposer extends React.Component {
|
||||||
|
|
||||||
controls.push(
|
controls.push(
|
||||||
<div key="controls_avatar" className="mx_MessageComposer_avatar">
|
<div key="controls_avatar" className="mx_MessageComposer_avatar">
|
||||||
<MemberPresenceAvatar member={me} width={24} height={24} />
|
<MemberAvatar member={me} width={24} height={24} />
|
||||||
</div>,
|
</div>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -170,6 +170,7 @@
|
||||||
"%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget modified by %(senderName)s",
|
"%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s widget modified by %(senderName)s",
|
||||||
"%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s",
|
"%(widgetName)s widget added by %(senderName)s": "%(widgetName)s widget added by %(senderName)s",
|
||||||
"%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s",
|
"%(widgetName)s widget removed by %(senderName)s": "%(widgetName)s widget removed by %(senderName)s",
|
||||||
|
"Message Pinning": "Message Pinning",
|
||||||
"%(displayName)s is typing": "%(displayName)s is typing",
|
"%(displayName)s is typing": "%(displayName)s is typing",
|
||||||
"%(names)s and %(count)s others are typing|other": "%(names)s and %(count)s others are typing",
|
"%(names)s and %(count)s others are typing|other": "%(names)s and %(count)s others are typing",
|
||||||
"%(names)s and %(count)s others are typing|one": "%(names)s and one other is typing",
|
"%(names)s and %(count)s others are typing|one": "%(names)s and one other is typing",
|
||||||
|
|
|
@ -88,12 +88,6 @@ export const SETTINGS = {
|
||||||
supportedLevels: LEVELS_FEATURE,
|
supportedLevels: LEVELS_FEATURE,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
"feature_presence_management": {
|
|
||||||
isFeature: true,
|
|
||||||
displayName: _td("Presence Management"),
|
|
||||||
supportedLevels: LEVELS_FEATURE,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
"feature_tag_panel": {
|
"feature_tag_panel": {
|
||||||
isFeature: true,
|
isFeature: true,
|
||||||
displayName: _td("Tag Panel"),
|
displayName: _td("Tag Panel"),
|
||||||
|
|
Loading…
Reference in New Issue