instantjob-recruiter-client
Version:
a set of tools for creating an instantjob recruiter react client
517 lines (434 loc) • 19.5 kB
JavaScript
'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);