UNPKG

instantjob-recruiter-client

Version:

a set of tools for creating an instantjob recruiter react client

517 lines (434 loc) 19.5 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _taggedTemplateLiteral2 = require('babel-runtime/helpers/taggedTemplateLiteral'); var _taggedTemplateLiteral3 = _interopRequireDefault(_taggedTemplateLiteral2); var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _assign = require('babel-runtime/core-js/object/assign'); var _assign2 = _interopRequireDefault(_assign); var _defineProperty2 = require('babel-runtime/helpers/defineProperty'); var _defineProperty3 = _interopRequireDefault(_defineProperty2); var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of'); var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn'); var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2); var _inherits2 = require('babel-runtime/helpers/inherits'); var _inherits3 = _interopRequireDefault(_inherits2); var _templateObject = (0, _taggedTemplateLiteral3.default)(['\n font-size: 14px;\n padding: 10px 15px;\n width: 85%;\n margin: 2px;\n border-radius: 5px;\n'], ['\n font-size: 14px;\n padding: 10px 15px;\n width: 85%;\n margin: 2px;\n border-radius: 5px;\n']); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _reactRedux = require('react-redux'); var _styledComponents = require('styled-components'); var _styledComponents2 = _interopRequireDefault(_styledComponents); var _reactTextareaAutosize = require('react-textarea-autosize'); var _reactTextareaAutosize2 = _interopRequireDefault(_reactTextareaAutosize); var _reactRouter = require('react-router'); var _fa = require('react-icons/lib/fa'); var _reactLinkify = require('react-linkify'); var _reactLinkify2 = _interopRequireDefault(_reactLinkify); var _profile_image = require('components/profile_image'); var _profile_image2 = _interopRequireDefault(_profile_image); var _messages = require('../actions/messages'); var _mutes = require('../actions/mutes'); var _users = require('../actions/users'); var _display = require('../actions/display'); var _constants = require('../common/constants'); var _moment = require('../common/moment'); var _moment2 = _interopRequireDefault(_moment); var _store = require('../common/store'); var _store2 = _interopRequireDefault(_store); var _request = require('../common/request'); var _request2 = _interopRequireDefault(_request); var _messages2 = require('../common/messages'); var _utilities = require('../common/utilities'); var _auto_bind = require('../common/auto_bind'); var _auto_bind2 = _interopRequireDefault(_auto_bind); var _messages3 = require('../selectors/messages'); var _users2 = require('../selectors/users'); var _base = require('../selectors/base'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var MessagesStatic = function (_Component) { (0, _inherits3.default)(MessagesStatic, _Component); function MessagesStatic(props) { (0, _classCallCheck3.default)(this, MessagesStatic); var _this = (0, _possibleConstructorReturn3.default)(this, (MessagesStatic.__proto__ || (0, _getPrototypeOf2.default)(MessagesStatic)).call(this, props)); (0, _auto_bind2.default)(_this); return _this; } (0, _createClass3.default)(MessagesStatic, [{ key: 'send_message', value: function send_message(draft) { this.props.send_message(draft); if (this.props.muted) { this.props.unmute_user(); } } }, { key: 'componentDidMount', value: function componentDidMount() { var _this2 = this; this.props.fetch_messages().then(function () { return (0, _messages2.read_last_messages)(_this2.props.recipient.id); }); this.scroll_bottom(); } }, { key: 'componentWillReceiveProps', value: function componentWillReceiveProps(props) { if (props.recipient.id != this.props.recipient.id) { this.props.fetch_messages(); } if (!(0, _base.tolerant_equal)(props.messages, this.props.messages) && (0, _utilities.exist)(props.messages, function (message) { return !message.read_at && message.recipient_type == "Agency"; })) { (0, _messages2.read_last_messages)(props.recipient.id); } this.should_scroll_bottom = this.should_scroll_bottom || props.messages.length !== this.props.messages.length; } }, { key: 'scroll_bottom', value: function scroll_bottom() { this.scroll_container.scrollTop = this.scroll_container.scrollHeight; } }, { key: 'componentWillUpdate', value: function componentWillUpdate() { this.should_scroll_bottom = this.should_scroll_bottom || this.scroll_container.scrollTop + this.scroll_container.offsetHeight === this.scroll_container.scrollHeight; } }, { key: 'componentDidUpdate', value: function componentDidUpdate() { if (this.should_scroll_bottom) { this.scroll_bottom(); this.should_scroll_bottom = false; } } }, { key: 'render', value: function render() { var _this3 = this; return _react2.default.createElement( 'div', { style: { justifyContent: 'space-between', alignItems: 'stretch', flexDirection: 'column', display: "flex", height: "100%", flex: 1 } }, _react2.default.createElement( 'div', { style: { height: 50, display: 'flex', flexShrink: 0, borderBottomStyle: 'solid', borderBottomColor: (0, _constants.color)('black', 'bright'), borderBottomWidth: 1, padding: 5, flexDirection: 'row', alignItems: 'center' } }, _react2.default.createElement( 'div', { style: (0, _defineProperty3.default)({ display: 'flex', flex: 1, flexDirection: 'row', alignItems: 'space-between' }, 'alignItems', 'center') }, _react2.default.createElement( 'div', { className: 'link', onClick: function onClick() { return _store2.default.dispatch((0, _users.set_current_recipient)()); }, style: { height: 50, alignItems: "center", display: "flex" } }, _react2.default.createElement(_fa.FaAngleLeft, { style: { fontSize: 30 } }), this.props.unread_messages > 0 ? _react2.default.createElement( 'div', null, '(', this.props.unread_messages, ')' ) : null ), _react2.default.createElement( 'div', { className: 'link', onClick: function onClick() { return _this3.props.set_current_user(); }, style: { marginLeft: 10 } }, this.props.recipient.full_name ) ) ), _react2.default.createElement( 'div', { style: { flexGrow: 10000, flexShrink: 1, overflow: 'scroll' }, ref: function ref(scroll_container) { return _this3.scroll_container = scroll_container; } }, _react2.default.createElement( 'div', { style: { display: 'flex', flexDirection: 'column', alignItems: 'stretch' } }, _react2.default.createElement(Conversations, this.props) ) ), _react2.default.createElement(MessageInput, { send_message: this.send_message }) ); } }]); return MessagesStatic; }(_react.Component); var MessageInput = function (_Component2) { (0, _inherits3.default)(MessageInput, _Component2); function MessageInput(props) { (0, _classCallCheck3.default)(this, MessageInput); var _this4 = (0, _possibleConstructorReturn3.default)(this, (MessageInput.__proto__ || (0, _getPrototypeOf2.default)(MessageInput)).call(this, props)); _this4.state = { draft: '' }; return _this4; } (0, _createClass3.default)(MessageInput, [{ key: 'render', value: function render() { var _this5 = this; return _react2.default.createElement( 'div', { style: { flexGrow: 1, flexShrink: 0, bottom: 0, minHeight: 40, backgroundColor: (0, _constants.color)('black', 'bright'), padding: 3 } }, _react2.default.createElement(Textarea, { placeholder: 'Message', value: this.state.draft, onChange: function onChange(event) { var draft = event.target.value; if (draft.slice(0, -1) != _this5.state.draft) { _this5.setState({ draft: draft }); } else { if (draft.slice(-1) === '\n') { _this5.props.send_message(_this5.state.draft); _this5.setState({ draft: '' }); } else { _this5.setState({ draft: draft }); } } }, onFocus: function onFocus(event) { event.target.select(); }, style: { borderStyle: 'none', paddingHeight: 2 } }) ); } }]); return MessageInput; }(_react.Component); var conversation_gap = { unit: 'hours', value: 1 }; var Conversations = function Conversations(props) { var conversations = (0, _utilities.group_consecutive)(props.messages, function (m1, m2) { return (0, _moment2.default)(m2.created_at).diff((0, _moment2.default)(m1.created_at), conversation_gap.unit) < conversation_gap.value; }); return _react2.default.createElement( 'div', { style: { display: 'flex', flexDirection: 'column', alignItems: 'stretch' } }, conversations.map(function (conversation, index) { return _react2.default.createElement(Conversation, { messages: conversation, key: index, recruiter: props.recruiter, recipient: props.recipient }); }) ); }; var Conversation = function (_Component3) { (0, _inherits3.default)(Conversation, _Component3); function Conversation() { (0, _classCallCheck3.default)(this, Conversation); return (0, _possibleConstructorReturn3.default)(this, (Conversation.__proto__ || (0, _getPrototypeOf2.default)(Conversation)).apply(this, arguments)); } (0, _createClass3.default)(Conversation, [{ key: 'componentDidMount', value: function componentDidMount() { (0, _messages2.read_last_messages)(this.props.recipient.id); } }, { key: 'shouldComponentUpdate', value: function shouldComponentUpdate(_ref2) { var recruiter = _ref2.recruiter, recipient = _ref2.recipient, messages = _ref2.messages; return recipient !== this.props.recipient || recruiter !== this.props.recruiter || !(0, _base.tolerant_equal)(messages, this.props.messages); } }, { key: 'render', value: function render() { var _this7 = this; var message_groups = (0, _utilities.group_consecutive)(this.props.messages, function (m1, m2) { return m1.sender_id == m2.sender_id && m1.sender_type == m2.sender_type; }); return _react2.default.createElement( 'div', { style: { display: 'flex', flexDirection: 'column', alignItems: 'stretch' } }, _react2.default.createElement( 'span', { style: { marginRight: 0, flex: 1, textAlign: 'center', color: (0, _constants.color)('black', 'bright') } }, (0, _moment2.default)(this.props.messages[this.props.messages.length - 1].created_at).calendar() ), message_groups.map(function (group, index) { return _react2.default.createElement(MessageGroup, { messages: group, key: index, recruiter: _this7.props.recruiter }); }) ); } }]); return Conversation; }(_react.Component); var MessageGroup = function MessageGroup(props) { var group_length = props.messages.length - 1; var from_user = props.messages[0].sender_type === 'User'; return _react2.default.createElement( 'div', { style: { display: 'flex', flexDirection: 'column', alignItems: 'stretch', paddingTop: 10, paddingBottom: 10 } }, _react2.default.createElement( 'div', { style: { display: 'flex', flexDirection: 'row', alignItems: 'flex-end' } }, _react2.default.createElement( 'div', { style: (0, _assign2.default)({ display: 'flex', flexDirection: 'column', alignItems: 'stretch' }, !from_user ? { marginLeft: 'auto' } : {}) }, props.messages.map(function (message, index) { return _react2.default.createElement(Message, { message: message, key: message.id, recruiter: props.recruiter, first: index == 0, last: index == group_length }); }) ), from_user ? null : _react2.default.createElement(_profile_image2.default, (0, _extends3.default)({}, props.messages[0].sender, { hide_status: true })) ), props.messages[group_length].last_read_message ? _react2.default.createElement( 'p', { style: { marginRight: 0, flex: 1, textAlign: 'right', color: (0, _constants.color)('black', 'bright') } }, 'Lu ', (0, _moment2.default)(props.messages[group_length].read_at).fromNow() ) : props.messages[group_length].last_message ? _react2.default.createElement( 'p', { style: { marginRight: 0, flex: 1, textAlign: 'right', color: (0, _constants.color)('black', 'bright') } }, 'Envoy\xE9 ', (0, _moment2.default)(props.messages[group_length].created_at).fromNow() ) : null ); }; var border_normal = 10; var border_small = 3; var Message = function Message(props) { var from_user = props.message.sender_type === 'User'; var from_self = props.message.sender_type === 'Recruiter' && props.message.sender_id === props.recruiter; return _react2.default.createElement( 'div', null, _react2.default.createElement( 'div', { style: (0, _assign2.default)({ display: "flex", flexDirection: 'column' }, !from_user ? { marginRight: 5, float: 'right', alignItems: 'flex-end' } : { marginLeft: 5, float: 'left', alignItems: 'flex-start' }, props.message.last_read_message ? {} : { marginBottom: 2 }) }, _react2.default.createElement( 'div', { style: (0, _assign2.default)({ padding: 10, maxWidth: 200, borderRadius: border_normal, wordWrap: "break-word" }, from_self ? { backgroundColor: (0, _constants.color)('primary', 'light'), color: 'white' } : { backgroundColor: '#DDD', color: 'black' }, !from_user ? { borderTopRightRadius: props.first ? border_normal : border_small, borderBottomRightRadius: props.last ? border_normal : border_small } : { borderTopLeftRadius: props.first ? border_normal : border_small, borderBottomLeftRadius: props.last ? border_normal : border_small }) }, _react2.default.createElement( _reactLinkify2.default, { properties: { className: 'link', style: { color: (0, _constants.color)('white'), textDecoration: 'underline' } } }, props.message.content ) ) ) ); }; var Messages = (0, _reactRedux.connect)(function (state) { var messages = (0, _messages3.get_messages)(state).filter(function (message) { return (0, _messages2.with_recipient)(message, state.users.current_recipient); }).sort(function (m1, m2) { return (0, _moment2.default)(m1.created_at).isAfter(m2.created_at) ? 1 : -1; }); var i = messages.length - 1; var last_message = messages[i]; messages[i] = (0, _extends3.default)({}, last_message, { last_message: true }); while (i >= 0 && (messages[i].sender_type === 'User' || messages[i].read_at == null)) { i--; } if (i >= 0) { messages[i] = (0, _extends3.default)({}, messages[i], { last_read_message: true, last_message: false }); } return { messages: messages, recipient: (0, _users2.get_current_recipient)(state), recruiter: state.profile.id, muted: (0, _utilities.array_contains)(state.mutes.muted_users, state.users.current_recipient), can_mute: messages.reduce(function (can_mute, message) { return can_mute || message.sender_type === 'Recruiter' && message.sender_id != state.profile.id && !(0, _utilities.array_contains)(state.mutes.mutes_by_user[state.users.current_recipient], message.sender_id); }, false) && messages.filter(function (message) { return message.sender_type === 'Recruiter'; }).length > 0, unread_messages: (0, _messages3.get_unread_messages)(state) }; }, function (dispatch) { var toggle_mute_user = function toggle_mute_user(mute) { var state = _store2.default.getState(); var user = (0, _users2.get_current_recipient)(state); var action = void 0, triggered_action = void 0, alert_text = void 0; if (mute) { action = _mutes.unmute_user; triggered_action = 'mutes.unmute'; alert_text = 'Vous recevrez \xE0 nouveau les alertes pour les nouveaux messages de ' + user.full_name; } else { action = _mutes.mute_user; triggered_action = 'mutes.mute'; alert_text = 'Vous ne recevrez plus d\'alertes pour les nouveaux messages de ' + user.full_name; } dispatch(action(user.id)); dispatch((0, _display.alert_success)(alert_text)); }; return { send_message: function send_message(content) { var state = _store2.default.getState(); var user_id = state.users.current_recipient; var temp_id = state.messages.idGenerator; var message = { id: temp_id, content: content, sender_id: state.profile.id, sender_type: "Recruiter", recipient_id: user_id, recipient_type: "User" }; dispatch((0, _messages.create_message)(message)); _request2.default.post('messages', { message: { content: content }, user_id: user_id }).then(function (message) { return dispatch((0, _messages.update_message_id)(message, temp_id)); }); }, fetch_messages: function fetch_messages() { var state = _store2.default.getState(); _request2.default.get('users/' + state.users.current_recipient + '/muting_recruiters').then(function (recruiters) { return dispatch((0, _mutes.store_muting_recruiters)(state.users.current_recipient, recruiters.map(function (recruiter) { return recruiter.id; }))); }); return _request2.default.get('messages', { user_id: state.users.current_recipient }).then(function (messages) { return dispatch((0, _messages.store_messages)(messages)); }); }, set_current_user: function set_current_user() { _reactRouter.browserHistory.push('/users/' + _store2.default.getState().users.current_recipient); }, mute_user: function mute_user() { return toggle_mute_user(false); }, unmute_user: function unmute_user() { return toggle_mute_user(true); } }; })(MessagesStatic); exports.default = Messages; var Textarea = (0, _styledComponents2.default)(_reactTextareaAutosize2.default)(_templateObject);