@atlaskit/mention
Version:
A React component used to display user profiles in a list for 'Mention' functionality
223 lines (221 loc) • 9.05 kB
JavaScript
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _inherits from "@babel/runtime/helpers/inherits";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
import React from 'react';
import { withAnalyticsEvents } from '@atlaskit/analytics-next';
import uniqueId from '../../util/id';
import debug from '../../util/logger';
import MentionList from '../MentionList';
import { fireSliAnalyticsEvent, SLI_EVENT_TYPE } from '../../util/analytics';
function applyPresence(mentions, presences) {
var updatedMentions = [];
for (var i = 0; i < mentions.length; i++) {
// Shallow copy
var mention = _objectSpread({}, mentions[i]);
var presence = presences[mention.id];
if (presence) {
mention.presence = presence;
}
updatedMentions.push(mention);
}
return updatedMentions;
}
function extractPresences(mentions) {
var presences = {};
for (var i = 0; i < mentions.length; i++) {
var mention = mentions[i];
if (mention.presence) {
presences[mention.id] = mention.presence;
}
}
return presences;
}
export var ResourcedMentionListWithoutAnalytics = /*#__PURE__*/function (_React$PureComponent) {
function ResourcedMentionListWithoutAnalytics(props) {
var _this;
_classCallCheck(this, ResourcedMentionListWithoutAnalytics);
_this = _callSuper(this, ResourcedMentionListWithoutAnalytics, [props]);
// API
_defineProperty(_this, "selectNext", function () {
if (_this.mentionListRef) {
_this.mentionListRef.selectNext();
}
});
_defineProperty(_this, "selectPrevious", function () {
if (_this.mentionListRef) {
_this.mentionListRef.selectPrevious();
}
});
_defineProperty(_this, "selectIndex", function (index, callback) {
if (_this.mentionListRef) {
_this.mentionListRef.selectIndex(index, callback);
}
});
_defineProperty(_this, "selectId", function (id, callback) {
if (_this.mentionListRef) {
_this.mentionListRef.selectId(id, callback);
}
});
_defineProperty(_this, "chooseCurrentSelection", function () {
if (_this.mentionListRef) {
_this.mentionListRef.chooseCurrentSelection();
}
});
_defineProperty(_this, "mentionsCount", function () {
if (_this.mentionListRef) {
return _this.mentionListRef.mentionsCount();
}
return 0;
});
// internal, used for callbacks
_defineProperty(_this, "filterChange", function (mentions) {
// Retain known presence
var currentPresences = extractPresences(_this.state.mentions);
_this.setState({
resourceError: undefined,
mentions: applyPresence(mentions, currentPresences)
});
_this.refreshPresences(mentions);
});
_defineProperty(_this, "sendAnalytics", function (event, actionSubject, action) {
if (event === SLI_EVENT_TYPE) {
fireSliAnalyticsEvent(_this.props)(actionSubject, action);
}
});
_defineProperty(_this, "filterError", function (error) {
debug('ak-resourced-mentions-list._filterError', error);
_this.setState({
resourceError: error
});
});
_defineProperty(_this, "presenceUpdate", function (presences) {
_this.setState({
mentions: applyPresence(_this.state.mentions, presences)
});
});
_defineProperty(_this, "notifySelection", function (mention) {
_this.props.resourceProvider.recordMentionSelection(mention);
if (_this.props.onSelection) {
_this.props.onSelection(mention);
}
});
_defineProperty(_this, "handleMentionListRef", function (ref) {
_this.mentionListRef = ref;
});
_this.subscriberKey = uniqueId('ak-resourced-mention-list');
_this.state = {
resourceError: undefined,
mentions: []
};
_this.applyPropChanges({}, props);
return _this;
}
_inherits(ResourcedMentionListWithoutAnalytics, _React$PureComponent);
return _createClass(ResourcedMentionListWithoutAnalytics, [{
key: "componentDidMount",
value: function componentDidMount() {
this.subscribeMentionProvider(this.props.resourceProvider);
this.subscribePresenceProvider(this.props.presenceProvider);
}
}, {
key: "UNSAFE_componentWillReceiveProps",
value: function UNSAFE_componentWillReceiveProps(nextProps) {
this.applyPropChanges(this.props, nextProps);
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.unsubscribeMentionProvider(this.props.resourceProvider);
this.unsubscribePresenceProvider(this.props.presenceProvider);
}
}, {
key: "subscribeMentionProvider",
value:
// internal
function subscribeMentionProvider(mentionProvider) {
if (mentionProvider) {
mentionProvider.subscribe(this.subscriberKey, this.filterChange, this.filterError, undefined, undefined, this.sendAnalytics);
}
}
}, {
key: "subscribePresenceProvider",
value: function subscribePresenceProvider(presenceProvider) {
if (presenceProvider) {
presenceProvider.subscribe(this.subscriberKey, this.presenceUpdate);
}
}
}, {
key: "unsubscribeMentionProvider",
value: function unsubscribeMentionProvider(mentionProvider) {
if (mentionProvider) {
mentionProvider.unsubscribe(this.subscriberKey);
}
}
}, {
key: "unsubscribePresenceProvider",
value: function unsubscribePresenceProvider(presenceProvider) {
if (presenceProvider) {
presenceProvider.unsubscribe(this.subscriberKey);
}
}
}, {
key: "applyPropChanges",
value: function applyPropChanges(prevProps, nextProps) {
var oldResourceProvider = prevProps.resourceProvider;
var oldPresenceProvider = prevProps.presenceProvider;
var oldQuery = prevProps.query;
var newResourceProvider = nextProps.resourceProvider;
var newPresenceProvider = nextProps.presenceProvider;
var newQuery = nextProps.query;
var resourceProviderChanged = oldResourceProvider !== newResourceProvider;
var queryChanged = oldQuery !== newQuery;
var canFilter = !!(typeof newQuery === 'string' && newResourceProvider);
var shouldFilter = canFilter && (queryChanged || resourceProviderChanged);
// resource provider
if (resourceProviderChanged) {
this.unsubscribeMentionProvider(oldResourceProvider);
this.subscribeMentionProvider(newResourceProvider);
}
// presence provider
if (oldPresenceProvider !== newPresenceProvider) {
this.unsubscribePresenceProvider(oldPresenceProvider);
this.subscribePresenceProvider(newPresenceProvider);
}
if (shouldFilter) {
newResourceProvider.filter(newQuery);
}
}
}, {
key: "refreshPresences",
value: function refreshPresences(mentions) {
if (this.props.presenceProvider) {
var ids = mentions.map(function (mention) {
return mention.id;
});
this.props.presenceProvider.refreshPresence(ids);
}
}
}, {
key: "render",
value: function render() {
var _this$state = this.state,
mentions = _this$state.mentions,
resourceError = _this$state.resourceError;
return /*#__PURE__*/React.createElement(MentionList, {
mentions: mentions,
resourceError: resourceError,
onSelection: this.notifySelection,
ref: this.handleMentionListRef
});
}
}]);
}(React.PureComponent);
var ResourcedMentionList = withAnalyticsEvents({})(ResourcedMentionListWithoutAnalytics);
export default ResourcedMentionList;