received marker in message previews
This commit is contained in:
@@ -551,6 +551,11 @@ div.alert .content {
|
||||
margin-left: 1rem;
|
||||
}
|
||||
|
||||
/* Extra spece on the right */
|
||||
.space-right {
|
||||
margin-right: 0.25rem;
|
||||
}
|
||||
|
||||
/* Container with whitish background and rounded corners */
|
||||
.rounded-container {
|
||||
position: relative;
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -1,5 +1,7 @@
|
||||
// Odds and ends
|
||||
|
||||
import Tinode from 'tinode-sdk';
|
||||
|
||||
// Make shortcut icon appear with a green dot + show unread count in title.
|
||||
export function updateFavicon(count) {
|
||||
const oldIcon = document.getElementById('shortcut-icon');
|
||||
@@ -144,3 +146,20 @@ export function sanitizeImageUrl(url) {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Given message's received status, return name and color of a delivery indicator icon.
|
||||
export function deliveryMarker(received) {
|
||||
switch (received) {
|
||||
case Tinode.MESSAGE_STATUS_SENDING:
|
||||
return { name: 'access_time' }; // watch face
|
||||
case Tinode.MESSAGE_STATUS_FAILED:
|
||||
return { name: 'warning', color: 'amber' }; // yellow icon /!\
|
||||
case Tinode.MESSAGE_STATUS_SENT:
|
||||
return { name: 'done' }; // checkmark
|
||||
case Tinode.MESSAGE_STATUS_RECEIVED:
|
||||
return { name: 'done_all' }; // double checkmark
|
||||
case Tinode.MESSAGE_STATUS_READ:
|
||||
return { name: 'done_all', color: 'blue' }; // blue double checkmark
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -77,11 +77,15 @@ class ContactList extends React.Component {
|
||||
const comment = Array.isArray(c.private) ?
|
||||
c.private.join(',') : (c.private ? c.private.comment : null);
|
||||
let preview;
|
||||
let deliveryStatus;
|
||||
if (!this.props.showMode) {
|
||||
const content = (c.latestMessage() || { content: '' }).content;
|
||||
preview = typeof content == 'string' ?
|
||||
content.substr(0, MESSAGE_PREVIEW_LENGTH) :
|
||||
Drafty.preview(content, MESSAGE_PREVIEW_LENGTH);
|
||||
const msg = c.latestMessage();
|
||||
if (msg) {
|
||||
deliveryStatus = c.msgStatus(msg);
|
||||
preview = typeof msg.content == 'string' ?
|
||||
msg.content.substr(0, MESSAGE_PREVIEW_LENGTH) :
|
||||
Drafty.preview(msg.content, MESSAGE_PREVIEW_LENGTH);
|
||||
}
|
||||
}
|
||||
contactNodes.push(
|
||||
<Contact
|
||||
@@ -89,6 +93,7 @@ class ContactList extends React.Component {
|
||||
avatar={makeImageUrl(c.public ? c.public.photo : null)}
|
||||
comment={comment}
|
||||
preview={preview}
|
||||
received={deliveryStatus}
|
||||
unread={this.props.showUnread ? c.unread : 0}
|
||||
now={c.online && this.props.connected}
|
||||
acs={c.acs}
|
||||
|
||||
@@ -2,12 +2,15 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import LetterTile from './letter-tile.jsx';
|
||||
import ContactBadges from './contact-badges.jsx';
|
||||
import LetterTile from './letter-tile.jsx';
|
||||
import ReceivedMarker from './received-marker.jsx'
|
||||
import UnreadBadge from './unread-badge.jsx';
|
||||
|
||||
import { Drafty } from 'tinode-sdk';
|
||||
|
||||
import { deliveryMarker } from '../lib/utils.js';
|
||||
|
||||
export default class Contact extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@@ -60,8 +63,11 @@ export default class Contact extends React.Component {
|
||||
React.createElement(React.Fragment, null, Drafty.format(this.props.preview, draftyFormatter, this))) :
|
||||
this.props.comment;
|
||||
|
||||
const icon = deliveryMarker(this.props.received);
|
||||
const marker = icon ? <i className={'material-icons small space-right ' + icon.color}>{icon.name}</i> : null;
|
||||
|
||||
return (
|
||||
<li className={!this.props.showCheckmark && this.props.selected ? "selected" : null} onClick={this.handleClick}>
|
||||
<li className={!this.props.showCheckmark && this.props.selected ? 'selected' : null} onClick={this.handleClick}>
|
||||
<div className="avatar-box">
|
||||
<LetterTile
|
||||
avatar={avatar}
|
||||
@@ -77,7 +83,7 @@ export default class Contact extends React.Component {
|
||||
{this.props.isChannel ? <img src="/img/channel.png" className="channel" alt="channel" /> : null}
|
||||
<UnreadBadge count={this.props.unread} /><ContactBadges badges={icon_badges} />
|
||||
</div>
|
||||
<div className="contact-comment">{subtitle || '\u00A0'}</div>
|
||||
<div className="contact-comment">{marker}{subtitle || '\u00A0'}</div>
|
||||
<span><ContactBadges badges={badges} /></span>
|
||||
</div>
|
||||
{this.props.showContextMenu ?
|
||||
|
||||
@@ -5,6 +5,7 @@ import { defineMessages, injectIntl } from 'react-intl';
|
||||
import Tinode from 'tinode-sdk';
|
||||
|
||||
import { shortDateFormat } from '../lib/strformat.js';
|
||||
import { deliveryMarker } from '../lib/utils.js';
|
||||
|
||||
const messages = defineMessages({
|
||||
'sending': {
|
||||
@@ -31,18 +32,8 @@ class ReceivedMarker extends React.PureComponent {
|
||||
timestamp = shortDateFormat(this.props.timestamp, this.props.intl.locale);
|
||||
}
|
||||
|
||||
let marker = null;
|
||||
if (this.props.received <= Tinode.MESSAGE_STATUS_SENDING) {
|
||||
marker = (<i className="material-icons small">access_time</i>); // watch face
|
||||
} else if (this.props.received == Tinode.MESSAGE_STATUS_FAILED) {
|
||||
marker = (<i className="material-icons small amber">warning</i>); // yellow icon /!\
|
||||
} else if (this.props.received == Tinode.MESSAGE_STATUS_SENT) {
|
||||
marker = (<i className="material-icons small">done</i>); // checkmark
|
||||
} else if (this.props.received == Tinode.MESSAGE_STATUS_RECEIVED) {
|
||||
marker = (<i className="material-icons small">done_all</i>); // double checkmark
|
||||
} else if (this.props.received == Tinode.MESSAGE_STATUS_READ) {
|
||||
marker = (<i className="material-icons small blue">done_all</i>); // blue double checkmark
|
||||
}
|
||||
const icon = deliveryMarker(this.props.received);
|
||||
const marker = icon ? <i className={'material-icons small ' + icon.color}>{icon.name}</i> : null;
|
||||
|
||||
return (
|
||||
<span className="timestamp">
|
||||
|
||||
+71
-41
@@ -564,8 +564,12 @@ __webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ "asEmail": function() { return /* binding */ asEmail; },
|
||||
/* harmony export */ "isUrlRelative": function() { return /* binding */ isUrlRelative; },
|
||||
/* harmony export */ "sanitizeUrl": function() { return /* binding */ sanitizeUrl; },
|
||||
/* harmony export */ "sanitizeImageUrl": function() { return /* binding */ sanitizeImageUrl; }
|
||||
/* harmony export */ "sanitizeImageUrl": function() { return /* binding */ sanitizeImageUrl; },
|
||||
/* harmony export */ "deliveryMarker": function() { return /* binding */ deliveryMarker; }
|
||||
/* harmony export */ });
|
||||
/* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tinode-sdk */ "tinode-sdk");
|
||||
/* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(tinode_sdk__WEBPACK_IMPORTED_MODULE_0__);
|
||||
|
||||
function updateFavicon(count) {
|
||||
const oldIcon = document.getElementById('shortcut-icon');
|
||||
const head = document.head || document.getElementsByTagName('head')[0];
|
||||
@@ -689,6 +693,38 @@ function sanitizeImageUrl(url) {
|
||||
|
||||
return null;
|
||||
}
|
||||
function deliveryMarker(received) {
|
||||
switch (received) {
|
||||
case (tinode_sdk__WEBPACK_IMPORTED_MODULE_0___default().MESSAGE_STATUS_SENDING):
|
||||
return {
|
||||
name: 'access_time'
|
||||
};
|
||||
|
||||
case (tinode_sdk__WEBPACK_IMPORTED_MODULE_0___default().MESSAGE_STATUS_FAILED):
|
||||
return {
|
||||
name: 'warning',
|
||||
color: 'amber'
|
||||
};
|
||||
|
||||
case (tinode_sdk__WEBPACK_IMPORTED_MODULE_0___default().MESSAGE_STATUS_SENT):
|
||||
return {
|
||||
name: 'done'
|
||||
};
|
||||
|
||||
case (tinode_sdk__WEBPACK_IMPORTED_MODULE_0___default().MESSAGE_STATUS_RECEIVED):
|
||||
return {
|
||||
name: 'done_all'
|
||||
};
|
||||
|
||||
case (tinode_sdk__WEBPACK_IMPORTED_MODULE_0___default().MESSAGE_STATUS_READ):
|
||||
return {
|
||||
name: 'done_all',
|
||||
color: 'blue'
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/***/ }),
|
||||
|
||||
@@ -7244,12 +7280,15 @@ class ContactList extends (react__WEBPACK_IMPORTED_MODULE_0___default().Componen
|
||||
|
||||
const comment = Array.isArray(c.private) ? c.private.join(',') : c.private ? c.private.comment : null;
|
||||
let preview;
|
||||
let deliveryStatus;
|
||||
|
||||
if (!this.props.showMode) {
|
||||
const content = (c.latestMessage() || {
|
||||
content: ''
|
||||
}).content;
|
||||
preview = typeof content == 'string' ? content.substr(0, _config_js__WEBPACK_IMPORTED_MODULE_6__.MESSAGE_PREVIEW_LENGTH) : tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.preview(content, _config_js__WEBPACK_IMPORTED_MODULE_6__.MESSAGE_PREVIEW_LENGTH);
|
||||
const msg = c.latestMessage();
|
||||
|
||||
if (msg) {
|
||||
deliveryStatus = c.msgStatus(msg);
|
||||
preview = typeof msg.content == 'string' ? msg.content.substr(0, _config_js__WEBPACK_IMPORTED_MODULE_6__.MESSAGE_PREVIEW_LENGTH) : tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Drafty.preview(msg.content, _config_js__WEBPACK_IMPORTED_MODULE_6__.MESSAGE_PREVIEW_LENGTH);
|
||||
}
|
||||
}
|
||||
|
||||
contactNodes.push(react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_contact_jsx__WEBPACK_IMPORTED_MODULE_3__.default, {
|
||||
@@ -7257,6 +7296,7 @@ class ContactList extends (react__WEBPACK_IMPORTED_MODULE_0___default().Componen
|
||||
avatar: (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_5__.makeImageUrl)(c.public ? c.public.photo : null),
|
||||
comment: comment,
|
||||
preview: preview,
|
||||
received: deliveryStatus,
|
||||
unread: this.props.showUnread ? c.unread : 0,
|
||||
now: c.online && this.props.connected,
|
||||
acs: c.acs,
|
||||
@@ -7310,11 +7350,15 @@ __webpack_require__.r(__webpack_exports__);
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-intl */ "react-intl");
|
||||
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__);
|
||||
/* harmony import */ var _letter_tile_jsx__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./letter-tile.jsx */ "./src/widgets/letter-tile.jsx");
|
||||
/* harmony import */ var _contact_badges_jsx__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./contact-badges.jsx */ "./src/widgets/contact-badges.jsx");
|
||||
/* harmony import */ var _unread_badge_jsx__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./unread-badge.jsx */ "./src/widgets/unread-badge.jsx");
|
||||
/* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! tinode-sdk */ "tinode-sdk");
|
||||
/* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(tinode_sdk__WEBPACK_IMPORTED_MODULE_5__);
|
||||
/* harmony import */ var _contact_badges_jsx__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./contact-badges.jsx */ "./src/widgets/contact-badges.jsx");
|
||||
/* harmony import */ var _letter_tile_jsx__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./letter-tile.jsx */ "./src/widgets/letter-tile.jsx");
|
||||
/* harmony import */ var _received_marker_jsx__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./received-marker.jsx */ "./src/widgets/received-marker.jsx");
|
||||
/* harmony import */ var _unread_badge_jsx__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./unread-badge.jsx */ "./src/widgets/unread-badge.jsx");
|
||||
/* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! tinode-sdk */ "tinode-sdk");
|
||||
/* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_6___default = /*#__PURE__*/__webpack_require__.n(tinode_sdk__WEBPACK_IMPORTED_MODULE_6__);
|
||||
/* harmony import */ var _lib_utils_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ../lib/utils.js */ "./src/lib/utils.js");
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -7384,13 +7428,17 @@ class Contact extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component) {
|
||||
}
|
||||
}
|
||||
|
||||
const subtitle = this.props.preview ? typeof this.props.preview == 'string' ? this.props.preview : react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, tinode_sdk__WEBPACK_IMPORTED_MODULE_5__.Drafty.format(this.props.preview, draftyFormatter, this)) : this.props.comment;
|
||||
const subtitle = this.props.preview ? typeof this.props.preview == 'string' ? this.props.preview : react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, tinode_sdk__WEBPACK_IMPORTED_MODULE_6__.Drafty.format(this.props.preview, draftyFormatter, this)) : this.props.comment;
|
||||
const icon = (0,_lib_utils_js__WEBPACK_IMPORTED_MODULE_7__.deliveryMarker)(this.props.received);
|
||||
const marker = icon ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", {
|
||||
className: 'material-icons small space-right ' + icon.color
|
||||
}, icon.name) : null;
|
||||
return react__WEBPACK_IMPORTED_MODULE_0___default().createElement("li", {
|
||||
className: !this.props.showCheckmark && this.props.selected ? "selected" : null,
|
||||
className: !this.props.showCheckmark && this.props.selected ? 'selected' : null,
|
||||
onClick: this.handleClick
|
||||
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
||||
className: "avatar-box"
|
||||
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_letter_tile_jsx__WEBPACK_IMPORTED_MODULE_2__.default, {
|
||||
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_letter_tile_jsx__WEBPACK_IMPORTED_MODULE_3__.default, {
|
||||
avatar: avatar,
|
||||
title: this.props.title,
|
||||
topic: this.props.item
|
||||
@@ -7406,13 +7454,13 @@ class Contact extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component) {
|
||||
src: "/img/channel.png",
|
||||
className: "channel",
|
||||
alt: "channel"
|
||||
}) : null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_unread_badge_jsx__WEBPACK_IMPORTED_MODULE_4__.default, {
|
||||
}) : null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_unread_badge_jsx__WEBPACK_IMPORTED_MODULE_5__.default, {
|
||||
count: this.props.unread
|
||||
}), react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_contact_badges_jsx__WEBPACK_IMPORTED_MODULE_3__.default, {
|
||||
}), react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_contact_badges_jsx__WEBPACK_IMPORTED_MODULE_2__.default, {
|
||||
badges: icon_badges
|
||||
})), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
|
||||
className: "contact-comment"
|
||||
}, subtitle || '\u00A0'), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_contact_badges_jsx__WEBPACK_IMPORTED_MODULE_3__.default, {
|
||||
}, marker, subtitle || '\u00A0'), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_contact_badges_jsx__WEBPACK_IMPORTED_MODULE_2__.default, {
|
||||
badges: badges
|
||||
}))), this.props.showContextMenu ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", {
|
||||
className: "menuTrigger"
|
||||
@@ -7428,7 +7476,7 @@ class Contact extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component) {
|
||||
;
|
||||
|
||||
function draftyFormatter(style, data, values, key) {
|
||||
let el = tinode_sdk__WEBPACK_IMPORTED_MODULE_5__.Drafty.tagName(style);
|
||||
let el = tinode_sdk__WEBPACK_IMPORTED_MODULE_6__.Drafty.tagName(style);
|
||||
const attr = {
|
||||
key: key
|
||||
};
|
||||
@@ -9561,6 +9609,8 @@ __webpack_require__.r(__webpack_exports__);
|
||||
/* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tinode-sdk */ "tinode-sdk");
|
||||
/* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(tinode_sdk__WEBPACK_IMPORTED_MODULE_2__);
|
||||
/* harmony import */ var _lib_strformat_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../lib/strformat.js */ "./src/lib/strformat.js");
|
||||
/* harmony import */ var _lib_utils_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../lib/utils.js */ "./src/lib/utils.js");
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -9593,30 +9643,10 @@ class ReceivedMarker extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
|
||||
timestamp = (0,_lib_strformat_js__WEBPACK_IMPORTED_MODULE_3__.shortDateFormat)(this.props.timestamp, this.props.intl.locale);
|
||||
}
|
||||
|
||||
let marker = null;
|
||||
|
||||
if (this.props.received <= (tinode_sdk__WEBPACK_IMPORTED_MODULE_2___default().MESSAGE_STATUS_SENDING)) {
|
||||
marker = react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", {
|
||||
className: "material-icons small"
|
||||
}, "access_time");
|
||||
} else if (this.props.received == (tinode_sdk__WEBPACK_IMPORTED_MODULE_2___default().MESSAGE_STATUS_FAILED)) {
|
||||
marker = react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", {
|
||||
className: "material-icons small amber"
|
||||
}, "warning");
|
||||
} else if (this.props.received == (tinode_sdk__WEBPACK_IMPORTED_MODULE_2___default().MESSAGE_STATUS_SENT)) {
|
||||
marker = react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", {
|
||||
className: "material-icons small"
|
||||
}, "done");
|
||||
} else if (this.props.received == (tinode_sdk__WEBPACK_IMPORTED_MODULE_2___default().MESSAGE_STATUS_RECEIVED)) {
|
||||
marker = react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", {
|
||||
className: "material-icons small"
|
||||
}, "done_all");
|
||||
} else if (this.props.received == (tinode_sdk__WEBPACK_IMPORTED_MODULE_2___default().MESSAGE_STATUS_READ)) {
|
||||
marker = react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", {
|
||||
className: "material-icons small blue"
|
||||
}, "done_all");
|
||||
}
|
||||
|
||||
const icon = (0,_lib_utils_js__WEBPACK_IMPORTED_MODULE_4__.deliveryMarker)(this.props.received);
|
||||
const marker = icon ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", {
|
||||
className: 'material-icons small ' + icon.color
|
||||
}, icon.name) : null;
|
||||
return react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", {
|
||||
className: "timestamp"
|
||||
}, timestamp, '\u00a0', marker);
|
||||
|
||||
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user