fix missing read notifications
This commit is contained in:
@@ -16,11 +16,14 @@ import LogoView from './logo-view.jsx';
|
|||||||
import SendMessage from '../widgets/send-message.jsx';
|
import SendMessage from '../widgets/send-message.jsx';
|
||||||
|
|
||||||
import { DEFAULT_P2P_ACCESS_MODE, KEYPRESS_DELAY, MESSAGES_PAGE, MAX_EXTERN_ATTACHMENT_SIZE,
|
import { DEFAULT_P2P_ACCESS_MODE, KEYPRESS_DELAY, MESSAGES_PAGE, MAX_EXTERN_ATTACHMENT_SIZE,
|
||||||
MAX_IMAGE_DIM, MAX_INBAND_ATTACHMENT_SIZE } from '../config.js';
|
MAX_IMAGE_DIM, MAX_INBAND_ATTACHMENT_SIZE, READ_DELAY } from '../config.js';
|
||||||
import { SUPPORTED_IMAGE_FORMATS, filePasted, fileToBase64, imageFileToBase64,
|
import { SUPPORTED_IMAGE_FORMATS, filePasted, fileToBase64, imageFileToBase64,
|
||||||
imageFileScaledToBase64, makeImageUrl } from '../lib/blob-helpers.js';
|
imageFileScaledToBase64, makeImageUrl } from '../lib/blob-helpers.js';
|
||||||
import { bytesToHumanSize, shortDateFormat } from '../lib/strformat.js';
|
import { bytesToHumanSize, shortDateFormat } from '../lib/strformat.js';
|
||||||
|
|
||||||
|
// Run timer with this frequency (ms) for checking notification queue.
|
||||||
|
const NOTIFICATION_EXEC_INTERVAL = 300;
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
online_now: {
|
online_now: {
|
||||||
id: 'online_now',
|
id: 'online_now',
|
||||||
@@ -62,7 +65,6 @@ class MessagesView extends React.Component {
|
|||||||
|
|
||||||
this.state = MessagesView.getDerivedStateFromProps(props, {});
|
this.state = MessagesView.getDerivedStateFromProps(props, {});
|
||||||
|
|
||||||
// this.propsChange = this.propsChange.bind(this);
|
|
||||||
this.leave = this.leave.bind(this);
|
this.leave = this.leave.bind(this);
|
||||||
this.sendImageAttachment = this.sendImageAttachment.bind(this);
|
this.sendImageAttachment = this.sendImageAttachment.bind(this);
|
||||||
this.sendFileAttachment = this.sendFileAttachment.bind(this);
|
this.sendFileAttachment = this.sendFileAttachment.bind(this);
|
||||||
@@ -83,6 +85,11 @@ class MessagesView extends React.Component {
|
|||||||
this.handleEnablePeer = this.handleEnablePeer.bind(this);
|
this.handleEnablePeer = this.handleEnablePeer.bind(this);
|
||||||
this.handleAttachFile = this.handleAttachFile.bind(this);
|
this.handleAttachFile = this.handleAttachFile.bind(this);
|
||||||
this.handleAttachImage = this.handleAttachImage.bind(this);
|
this.handleAttachImage = this.handleAttachImage.bind(this);
|
||||||
|
this.postReadNotification = this.postReadNotification.bind(this);
|
||||||
|
this.clearNotificationQueue = this.clearNotificationQueue.bind(this);
|
||||||
|
|
||||||
|
this.readNotificationQueue = [];
|
||||||
|
this.readNotificationTimer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@@ -96,6 +103,9 @@ class MessagesView extends React.Component {
|
|||||||
if (this.messagesScroller) {
|
if (this.messagesScroller) {
|
||||||
this.messagesScroller.removeEventListener('scroll', this.handleScrollEvent);
|
this.messagesScroller.removeEventListener('scroll', this.handleScrollEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flush all notifications.
|
||||||
|
this.clearNotificationQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scroll last message into view on component update e.g. on message received
|
// Scroll last message into view on component update e.g. on message received
|
||||||
@@ -113,7 +123,6 @@ class MessagesView extends React.Component {
|
|||||||
if (this.state.topic != prevState.topic) {
|
if (this.state.topic != prevState.topic) {
|
||||||
if (prevState.topic && !Tinode.isNewGroupTopicName(prevState.topic)) {
|
if (prevState.topic && !Tinode.isNewGroupTopicName(prevState.topic)) {
|
||||||
this.leave(prevState.topic);
|
this.leave(prevState.topic);
|
||||||
this.props.readTimerHandler(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (topic) {
|
if (topic) {
|
||||||
@@ -126,6 +135,14 @@ class MessagesView extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.props.applicationVisible) {
|
||||||
|
// If application is not visible, flush all unsent 'read' notifications.
|
||||||
|
this.clearNotificationQueue();
|
||||||
|
} else {
|
||||||
|
// Otherwise assume there are unread messages.
|
||||||
|
this.postReadNotification(0);
|
||||||
|
}
|
||||||
|
|
||||||
if (topic && !topic.isSubscribed() && this.props.ready &&
|
if (topic && !topic.isSubscribed() && this.props.ready &&
|
||||||
((this.state.topic != prevState.topic) || !prevProps.ready)) {
|
((this.state.topic != prevState.topic) || !prevProps.ready)) {
|
||||||
// Is this a new topic?
|
// Is this a new topic?
|
||||||
@@ -362,6 +379,68 @@ class MessagesView extends React.Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
postReadNotification(seq) {
|
||||||
|
// Ignore notifications if the app is invisible.
|
||||||
|
if (!this.props.applicationVisible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up the timer if it's not running already.
|
||||||
|
if (!this.readNotificationTimer) {
|
||||||
|
this.readNotificationTimer = setInterval(() => {
|
||||||
|
if (this.readNotificationQueue.length == 0) {
|
||||||
|
// Shut down the timer if the queue is empty.
|
||||||
|
clearInterval(this.readNotificationTimer);
|
||||||
|
this.readNotificationTimer = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let seq = -1;
|
||||||
|
while (this.readNotificationQueue.length > 0) {
|
||||||
|
const n = this.readNotificationQueue[0];
|
||||||
|
if (n.topicName != this.state.topic) {
|
||||||
|
// Topic has changed. Drop the notification.
|
||||||
|
this.readNotificationQueue.shift();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
if (n.sendAt <= now) {
|
||||||
|
// Remove expired notification from queue.
|
||||||
|
this.readNotificationQueue.shift();
|
||||||
|
seq = Math.max(seq, n.seq);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send only one notification for the whole batch of messages.
|
||||||
|
if (seq >= 0) {
|
||||||
|
const topic = this.props.tinode.getTopic(this.state.topic);
|
||||||
|
if (topic) {
|
||||||
|
topic.noteRead(seq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, NOTIFICATION_EXEC_INTERVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
const now = new Date();
|
||||||
|
this.readNotificationQueue.push({
|
||||||
|
topicName: this.state.topic,
|
||||||
|
seq: seq,
|
||||||
|
sendAt: now.setMilliseconds(now.getMilliseconds() + READ_DELAY)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear notification queue and timer.
|
||||||
|
clearNotificationQueue() {
|
||||||
|
this.readNotificationQueue = [];
|
||||||
|
if (this.readNotificationTimer) {
|
||||||
|
clearInterval(this.readNotificationTimer);
|
||||||
|
this.readNotificationTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
handleSubsUpdated() {
|
handleSubsUpdated() {
|
||||||
if (this.state.topic) {
|
if (this.state.topic) {
|
||||||
const subs = [];
|
const subs = [];
|
||||||
@@ -408,9 +487,7 @@ class MessagesView extends React.Component {
|
|||||||
// automatically assumed to be read and recived.
|
// automatically assumed to be read and recived.
|
||||||
const status = topic.msgStatus(msg);
|
const status = topic.msgStatus(msg);
|
||||||
if (status >= Tinode.MESSAGE_STATUS_SENT && msg.from != this.props.myUserId) {
|
if (status >= Tinode.MESSAGE_STATUS_SENT && msg.from != this.props.myUserId) {
|
||||||
this.props.readTimerHandler(() => {
|
this.postReadNotification(msg.seq);
|
||||||
topic.noteRead(msg.seq);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
this.props.onData(msg);
|
this.props.onData(msg);
|
||||||
}
|
}
|
||||||
@@ -419,6 +496,8 @@ class MessagesView extends React.Component {
|
|||||||
|
|
||||||
handleAllMessagesReceived(count) {
|
handleAllMessagesReceived(count) {
|
||||||
this.setState({fetchingMessages: false});
|
this.setState({fetchingMessages: false});
|
||||||
|
// 0 means "latest".
|
||||||
|
this.postReadNotification(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
handleInfoReceipt(info) {
|
handleInfoReceipt(info) {
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ import InfoView from './info-view.jsx';
|
|||||||
import MessagesView from './messages-view.jsx';
|
import MessagesView from './messages-view.jsx';
|
||||||
import SidepanelView from './sidepanel-view.jsx';
|
import SidepanelView from './sidepanel-view.jsx';
|
||||||
|
|
||||||
import { API_KEY, APP_NAME, DEFAULT_P2P_ACCESS_MODE, LOGGING_ENABLED, MEDIA_BREAKPOINT,
|
import { API_KEY, APP_NAME, DEFAULT_P2P_ACCESS_MODE, LOGGING_ENABLED,
|
||||||
READ_DELAY, RECEIVED_DELAY } from '../config.js';
|
MEDIA_BREAKPOINT, RECEIVED_DELAY } from '../config.js';
|
||||||
import { base64ReEncode, makeImageUrl } from '../lib/blob-helpers.js';
|
import { base64ReEncode, makeImageUrl } from '../lib/blob-helpers.js';
|
||||||
import { detectServerAddress, isLocalHost, isSecureConnection } from '../lib/host-name.js';
|
import { detectServerAddress, isLocalHost, isSecureConnection } from '../lib/host-name.js';
|
||||||
import LocalStorageUtil from '../lib/local-storage.js';
|
import LocalStorageUtil from '../lib/local-storage.js';
|
||||||
@@ -55,8 +55,6 @@ class TinodeWeb extends React.Component {
|
|||||||
this.handleHashRoute = this.handleHashRoute.bind(this);
|
this.handleHashRoute = this.handleHashRoute.bind(this);
|
||||||
this.handleOnline = this.handleOnline.bind(this);
|
this.handleOnline = this.handleOnline.bind(this);
|
||||||
this.checkForAppUpdate = this.checkForAppUpdate.bind(this);
|
this.checkForAppUpdate = this.checkForAppUpdate.bind(this);
|
||||||
this.handleAppVisibility = this.handleAppVisibility.bind(this);
|
|
||||||
this.handleReadTimer = this.handleReadTimer.bind(this);
|
|
||||||
this.handleVisibilityEvent = this.handleVisibilityEvent.bind(this);
|
this.handleVisibilityEvent = this.handleVisibilityEvent.bind(this);
|
||||||
this.handleError = this.handleError.bind(this);
|
this.handleError = this.handleError.bind(this);
|
||||||
this.handleLoginRequest = this.handleLoginRequest.bind(this);
|
this.handleLoginRequest = this.handleLoginRequest.bind(this);
|
||||||
@@ -135,6 +133,8 @@ class TinodeWeb extends React.Component {
|
|||||||
(typeof FIREBASE_INIT != 'undefined'),
|
(typeof FIREBASE_INIT != 'undefined'),
|
||||||
firebaseToken: LocalStorageUtil.getObject('firebase-token'),
|
firebaseToken: LocalStorageUtil.getObject('firebase-token'),
|
||||||
|
|
||||||
|
applicationVisible: !document.hidden,
|
||||||
|
|
||||||
errorText: '',
|
errorText: '',
|
||||||
errorLevel: null,
|
errorLevel: null,
|
||||||
errorAction: undefined,
|
errorAction: undefined,
|
||||||
@@ -334,24 +334,8 @@ class TinodeWeb extends React.Component {
|
|||||||
this.setState({liveConnection: online});
|
this.setState({liveConnection: online});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handling read notifications here to be able to pause
|
|
||||||
// them then the window/tab is not visible.
|
|
||||||
handleAppVisibility(visible, callback) {
|
|
||||||
clearTimeout(this.readTimer);
|
|
||||||
this.readTimerCallback = callback;
|
|
||||||
if (visible && callback) {
|
|
||||||
this.readTimer = setTimeout(callback, READ_DELAY);
|
|
||||||
} else {
|
|
||||||
this.readTimer = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleReadTimer(callback) {
|
|
||||||
this.handleAppVisibility(!document.hidden, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleVisibilityEvent() {
|
handleVisibilityEvent() {
|
||||||
this.handleAppVisibility(!document.hidden, this.readTimerCallback);
|
this.setState({applicationVisible: !document.hidden});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleError(err, level, action, actionText) {
|
handleError(err, level, action, actionText) {
|
||||||
@@ -1417,6 +1401,7 @@ class TinodeWeb extends React.Component {
|
|||||||
myUserId={this.state.myUserId}
|
myUserId={this.state.myUserId}
|
||||||
serverVersion={this.state.serverVersion}
|
serverVersion={this.state.serverVersion}
|
||||||
serverAddress={this.state.serverAddress}
|
serverAddress={this.state.serverAddress}
|
||||||
|
applicationVisible={this.state.applicationVisible}
|
||||||
|
|
||||||
errorText={this.state.errorText}
|
errorText={this.state.errorText}
|
||||||
errorLevel={this.state.errorLevel}
|
errorLevel={this.state.errorLevel}
|
||||||
@@ -1429,7 +1414,6 @@ class TinodeWeb extends React.Component {
|
|||||||
onData={this.tnData}
|
onData={this.tnData}
|
||||||
onError={this.handleError}
|
onError={this.handleError}
|
||||||
onNewTopicCreated={this.handleNewTopicCreated}
|
onNewTopicCreated={this.handleNewTopicCreated}
|
||||||
readTimerHandler={this.handleReadTimer}
|
|
||||||
showContextMenu={this.handleShowContextMenu}
|
showContextMenu={this.handleShowContextMenu}
|
||||||
onChangePermissions={this.handleChangePermissions}
|
onChangePermissions={this.handleChangePermissions}
|
||||||
onNewChat={this.handleNewChatInvitation}
|
onNewChat={this.handleNewChatInvitation}
|
||||||
|
|||||||
+97
-36
@@ -2894,6 +2894,7 @@ var Drafty = tinode_sdk__WEBPACK_IMPORTED_MODULE_2___default.a.Drafty;
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var NOTIFICATION_EXEC_INTERVAL = 300;
|
||||||
var messages = Object(react_intl__WEBPACK_IMPORTED_MODULE_1__["defineMessages"])({
|
var messages = Object(react_intl__WEBPACK_IMPORTED_MODULE_1__["defineMessages"])({
|
||||||
online_now: {
|
online_now: {
|
||||||
"id": "online_now",
|
"id": "online_now",
|
||||||
@@ -2957,6 +2958,10 @@ var MessagesView = function (_React$Component) {
|
|||||||
_this.handleEnablePeer = _this.handleEnablePeer.bind(_assertThisInitialized(_this));
|
_this.handleEnablePeer = _this.handleEnablePeer.bind(_assertThisInitialized(_this));
|
||||||
_this.handleAttachFile = _this.handleAttachFile.bind(_assertThisInitialized(_this));
|
_this.handleAttachFile = _this.handleAttachFile.bind(_assertThisInitialized(_this));
|
||||||
_this.handleAttachImage = _this.handleAttachImage.bind(_assertThisInitialized(_this));
|
_this.handleAttachImage = _this.handleAttachImage.bind(_assertThisInitialized(_this));
|
||||||
|
_this.postReadNotification = _this.postReadNotification.bind(_assertThisInitialized(_this));
|
||||||
|
_this.clearNotificationQueue = _this.clearNotificationQueue.bind(_assertThisInitialized(_this));
|
||||||
|
_this.readNotificationQueue = [];
|
||||||
|
_this.readNotificationTimer = null;
|
||||||
return _this;
|
return _this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2973,6 +2978,8 @@ var MessagesView = function (_React$Component) {
|
|||||||
if (this.messagesScroller) {
|
if (this.messagesScroller) {
|
||||||
this.messagesScroller.removeEventListener('scroll', this.handleScrollEvent);
|
this.messagesScroller.removeEventListener('scroll', this.handleScrollEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.clearNotificationQueue();
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: "componentDidUpdate",
|
key: "componentDidUpdate",
|
||||||
@@ -2992,7 +2999,6 @@ var MessagesView = function (_React$Component) {
|
|||||||
if (this.state.topic != prevState.topic) {
|
if (this.state.topic != prevState.topic) {
|
||||||
if (prevState.topic && !tinode_sdk__WEBPACK_IMPORTED_MODULE_2___default.a.isNewGroupTopicName(prevState.topic)) {
|
if (prevState.topic && !tinode_sdk__WEBPACK_IMPORTED_MODULE_2___default.a.isNewGroupTopicName(prevState.topic)) {
|
||||||
this.leave(prevState.topic);
|
this.leave(prevState.topic);
|
||||||
this.props.readTimerHandler(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (topic) {
|
if (topic) {
|
||||||
@@ -3005,6 +3011,12 @@ var MessagesView = function (_React$Component) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.props.applicationVisible) {
|
||||||
|
this.clearNotificationQueue();
|
||||||
|
} else {
|
||||||
|
this.postReadNotification(0);
|
||||||
|
}
|
||||||
|
|
||||||
if (topic && !topic.isSubscribed() && this.props.ready && (this.state.topic != prevState.topic || !prevProps.ready)) {
|
if (topic && !topic.isSubscribed() && this.props.ready && (this.state.topic != prevState.topic || !prevProps.ready)) {
|
||||||
var newTopic = this.props.newTopicParams && this.props.newTopicParams._topicName == this.props.topic;
|
var newTopic = this.props.newTopicParams && this.props.newTopicParams._topicName == this.props.topic;
|
||||||
var getQuery = topic.startMetaQuery().withLaterDesc().withLaterSub();
|
var getQuery = topic.startMetaQuery().withLaterDesc().withLaterSub();
|
||||||
@@ -3138,16 +3150,82 @@ var MessagesView = function (_React$Component) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, {
|
||||||
|
key: "postReadNotification",
|
||||||
|
value: function postReadNotification(seq) {
|
||||||
|
var _this5 = this;
|
||||||
|
|
||||||
|
if (!this.props.applicationVisible) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.readNotificationTimer) {
|
||||||
|
this.readNotificationTimer = setInterval(function () {
|
||||||
|
if (_this5.readNotificationQueue.length == 0) {
|
||||||
|
clearInterval(_this5.readNotificationTimer);
|
||||||
|
_this5.readNotificationTimer = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var seq = -1;
|
||||||
|
|
||||||
|
while (_this5.readNotificationQueue.length > 0) {
|
||||||
|
var n = _this5.readNotificationQueue[0];
|
||||||
|
|
||||||
|
if (n.topicName != _this5.state.topic) {
|
||||||
|
_this5.readNotificationQueue.shift();
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var _now = new Date();
|
||||||
|
|
||||||
|
if (n.sendAt <= _now) {
|
||||||
|
_this5.readNotificationQueue.shift();
|
||||||
|
|
||||||
|
seq = Math.max(seq, n.seq);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (seq >= 0) {
|
||||||
|
var topic = _this5.props.tinode.getTopic(_this5.state.topic);
|
||||||
|
|
||||||
|
if (topic) {
|
||||||
|
topic.noteRead(seq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, NOTIFICATION_EXEC_INTERVAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
var now = new Date();
|
||||||
|
this.readNotificationQueue.push({
|
||||||
|
topicName: this.state.topic,
|
||||||
|
seq: seq,
|
||||||
|
sendAt: now.setMilliseconds(now.getMilliseconds() + _config_js__WEBPACK_IMPORTED_MODULE_13__["READ_DELAY"])
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
key: "clearNotificationQueue",
|
||||||
|
value: function clearNotificationQueue() {
|
||||||
|
this.readNotificationQueue = [];
|
||||||
|
|
||||||
|
if (this.readNotificationTimer) {
|
||||||
|
clearInterval(this.readNotificationTimer);
|
||||||
|
this.readNotificationTimer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
}, {
|
}, {
|
||||||
key: "handleSubsUpdated",
|
key: "handleSubsUpdated",
|
||||||
value: function handleSubsUpdated() {
|
value: function handleSubsUpdated() {
|
||||||
var _this5 = this;
|
var _this6 = this;
|
||||||
|
|
||||||
if (this.state.topic) {
|
if (this.state.topic) {
|
||||||
var subs = [];
|
var subs = [];
|
||||||
var topic = this.props.tinode.getTopic(this.state.topic);
|
var topic = this.props.tinode.getTopic(this.state.topic);
|
||||||
topic.subscribers(function (sub) {
|
topic.subscribers(function (sub) {
|
||||||
if (sub.online && sub.user != _this5.props.myUserId) {
|
if (sub.online && sub.user != _this6.props.myUserId) {
|
||||||
subs.push(sub);
|
subs.push(sub);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -3190,9 +3268,7 @@ var MessagesView = function (_React$Component) {
|
|||||||
var status = topic.msgStatus(msg);
|
var status = topic.msgStatus(msg);
|
||||||
|
|
||||||
if (status >= tinode_sdk__WEBPACK_IMPORTED_MODULE_2___default.a.MESSAGE_STATUS_SENT && msg.from != this.props.myUserId) {
|
if (status >= tinode_sdk__WEBPACK_IMPORTED_MODULE_2___default.a.MESSAGE_STATUS_SENT && msg.from != this.props.myUserId) {
|
||||||
this.props.readTimerHandler(function () {
|
this.postReadNotification(msg.seq);
|
||||||
topic.noteRead(msg.seq);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.props.onData(msg);
|
this.props.onData(msg);
|
||||||
@@ -3206,6 +3282,7 @@ var MessagesView = function (_React$Component) {
|
|||||||
this.setState({
|
this.setState({
|
||||||
fetchingMessages: false
|
fetchingMessages: false
|
||||||
});
|
});
|
||||||
|
this.postReadNotification(0);
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: "handleInfoReceipt",
|
key: "handleInfoReceipt",
|
||||||
@@ -3334,7 +3411,7 @@ var MessagesView = function (_React$Component) {
|
|||||||
}, {
|
}, {
|
||||||
key: "sendFileAttachment",
|
key: "sendFileAttachment",
|
||||||
value: function sendFileAttachment(file) {
|
value: function sendFileAttachment(file) {
|
||||||
var _this6 = this;
|
var _this7 = this;
|
||||||
|
|
||||||
if (file.size > _config_js__WEBPACK_IMPORTED_MODULE_13__["MAX_INBAND_ATTACHMENT_SIZE"]) {
|
if (file.size > _config_js__WEBPACK_IMPORTED_MODULE_13__["MAX_INBAND_ATTACHMENT_SIZE"]) {
|
||||||
var uploader = this.props.tinode.getLargeFileHelper();
|
var uploader = this.props.tinode.getLargeFileHelper();
|
||||||
@@ -3349,7 +3426,7 @@ var MessagesView = function (_React$Component) {
|
|||||||
this.props.sendMessage(msg, uploadCompletionPromise, uploader);
|
this.props.sendMessage(msg, uploadCompletionPromise, uploader);
|
||||||
} else {
|
} else {
|
||||||
Object(_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_14__["fileToBase64"])(file, function (mime, bits, fname) {
|
Object(_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_14__["fileToBase64"])(file, function (mime, bits, fname) {
|
||||||
_this6.props.sendMessage(Drafty.attachFile(null, mime, bits, fname));
|
_this7.props.sendMessage(Drafty.attachFile(null, mime, bits, fname));
|
||||||
}, this.props.onError);
|
}, this.props.onError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3387,11 +3464,11 @@ var MessagesView = function (_React$Component) {
|
|||||||
}, {
|
}, {
|
||||||
key: "handleAttachImage",
|
key: "handleAttachImage",
|
||||||
value: function handleAttachImage(file) {
|
value: function handleAttachImage(file) {
|
||||||
var _this7 = this;
|
var _this8 = this;
|
||||||
|
|
||||||
if (file.size > _config_js__WEBPACK_IMPORTED_MODULE_13__["MAX_INBAND_ATTACHMENT_SIZE"] || _lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_14__["SUPPORTED_IMAGE_FORMATS"].indexOf(file.type) < 0) {
|
if (file.size > _config_js__WEBPACK_IMPORTED_MODULE_13__["MAX_INBAND_ATTACHMENT_SIZE"] || _lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_14__["SUPPORTED_IMAGE_FORMATS"].indexOf(file.type) < 0) {
|
||||||
Object(_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_14__["imageFileScaledToBase64"])(file, _config_js__WEBPACK_IMPORTED_MODULE_13__["MAX_IMAGE_DIM"], _config_js__WEBPACK_IMPORTED_MODULE_13__["MAX_IMAGE_DIM"], false, function (bits, mime, width, height, fname) {
|
Object(_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_14__["imageFileScaledToBase64"])(file, _config_js__WEBPACK_IMPORTED_MODULE_13__["MAX_IMAGE_DIM"], _config_js__WEBPACK_IMPORTED_MODULE_13__["MAX_IMAGE_DIM"], false, function (bits, mime, width, height, fname) {
|
||||||
_this7.setState({
|
_this8.setState({
|
||||||
imagePreview: {
|
imagePreview: {
|
||||||
url: URL.createObjectURL(file),
|
url: URL.createObjectURL(file),
|
||||||
bits: bits,
|
bits: bits,
|
||||||
@@ -3403,11 +3480,11 @@ var MessagesView = function (_React$Component) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, function (err) {
|
}, function (err) {
|
||||||
_this7.props.onError(err, 'err');
|
_this8.props.onError(err, 'err');
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Object(_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_14__["imageFileToBase64"])(file, function (bits, mime, width, height, fname) {
|
Object(_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_14__["imageFileToBase64"])(file, function (bits, mime, width, height, fname) {
|
||||||
_this7.setState({
|
_this8.setState({
|
||||||
imagePreview: {
|
imagePreview: {
|
||||||
url: URL.createObjectURL(file),
|
url: URL.createObjectURL(file),
|
||||||
bits: bits,
|
bits: bits,
|
||||||
@@ -3419,14 +3496,14 @@ var MessagesView = function (_React$Component) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, function (err) {
|
}, function (err) {
|
||||||
_this7.props.onError(err, 'err');
|
_this8.props.onError(err, 'err');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: "render",
|
key: "render",
|
||||||
value: function render() {
|
value: function render() {
|
||||||
var _this8 = this;
|
var _this9 = this;
|
||||||
|
|
||||||
var formatMessage = this.props.intl.formatMessage;
|
var formatMessage = this.props.intl.formatMessage;
|
||||||
var component;
|
var component;
|
||||||
@@ -3552,7 +3629,7 @@ var MessagesView = function (_React$Component) {
|
|||||||
onClick: function onClick(e) {
|
onClick: function onClick(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
_this8.props.onHideMessagesView();
|
_this9.props.onHideMessagesView();
|
||||||
}
|
}
|
||||||
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("i", {
|
}, react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement("i", {
|
||||||
className: "material-icons"
|
className: "material-icons"
|
||||||
@@ -4576,8 +4653,6 @@ var TinodeWeb = function (_React$Component) {
|
|||||||
_this.handleHashRoute = _this.handleHashRoute.bind(_assertThisInitialized(_this));
|
_this.handleHashRoute = _this.handleHashRoute.bind(_assertThisInitialized(_this));
|
||||||
_this.handleOnline = _this.handleOnline.bind(_assertThisInitialized(_this));
|
_this.handleOnline = _this.handleOnline.bind(_assertThisInitialized(_this));
|
||||||
_this.checkForAppUpdate = _this.checkForAppUpdate.bind(_assertThisInitialized(_this));
|
_this.checkForAppUpdate = _this.checkForAppUpdate.bind(_assertThisInitialized(_this));
|
||||||
_this.handleAppVisibility = _this.handleAppVisibility.bind(_assertThisInitialized(_this));
|
|
||||||
_this.handleReadTimer = _this.handleReadTimer.bind(_assertThisInitialized(_this));
|
|
||||||
_this.handleVisibilityEvent = _this.handleVisibilityEvent.bind(_assertThisInitialized(_this));
|
_this.handleVisibilityEvent = _this.handleVisibilityEvent.bind(_assertThisInitialized(_this));
|
||||||
_this.handleError = _this.handleError.bind(_assertThisInitialized(_this));
|
_this.handleError = _this.handleError.bind(_assertThisInitialized(_this));
|
||||||
_this.handleLoginRequest = _this.handleLoginRequest.bind(_assertThisInitialized(_this));
|
_this.handleLoginRequest = _this.handleLoginRequest.bind(_assertThisInitialized(_this));
|
||||||
@@ -4653,6 +4728,7 @@ var TinodeWeb = function (_React$Component) {
|
|||||||
desktopAlerts: settings.desktopAlerts,
|
desktopAlerts: settings.desktopAlerts,
|
||||||
desktopAlertsEnabled: (Object(_lib_host_name_js__WEBPACK_IMPORTED_MODULE_13__["isSecureConnection"])() || Object(_lib_host_name_js__WEBPACK_IMPORTED_MODULE_13__["isLocalHost"])()) && typeof firebase_app__WEBPACK_IMPORTED_MODULE_3__ != 'undefined' && typeof navigator != 'undefined' && typeof FIREBASE_INIT != 'undefined',
|
desktopAlertsEnabled: (Object(_lib_host_name_js__WEBPACK_IMPORTED_MODULE_13__["isSecureConnection"])() || Object(_lib_host_name_js__WEBPACK_IMPORTED_MODULE_13__["isLocalHost"])()) && typeof firebase_app__WEBPACK_IMPORTED_MODULE_3__ != 'undefined' && typeof navigator != 'undefined' && typeof FIREBASE_INIT != 'undefined',
|
||||||
firebaseToken: _lib_local_storage_js__WEBPACK_IMPORTED_MODULE_14__["default"].getObject('firebase-token'),
|
firebaseToken: _lib_local_storage_js__WEBPACK_IMPORTED_MODULE_14__["default"].getObject('firebase-token'),
|
||||||
|
applicationVisible: !document.hidden,
|
||||||
errorText: '',
|
errorText: '',
|
||||||
errorLevel: null,
|
errorLevel: null,
|
||||||
errorAction: undefined,
|
errorAction: undefined,
|
||||||
@@ -4859,27 +4935,12 @@ var TinodeWeb = function (_React$Component) {
|
|||||||
liveConnection: online
|
liveConnection: online
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, {
|
|
||||||
key: "handleAppVisibility",
|
|
||||||
value: function handleAppVisibility(visible, callback) {
|
|
||||||
clearTimeout(this.readTimer);
|
|
||||||
this.readTimerCallback = callback;
|
|
||||||
|
|
||||||
if (visible && callback) {
|
|
||||||
this.readTimer = setTimeout(callback, _config_js__WEBPACK_IMPORTED_MODULE_11__["READ_DELAY"]);
|
|
||||||
} else {
|
|
||||||
this.readTimer = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
key: "handleReadTimer",
|
|
||||||
value: function handleReadTimer(callback) {
|
|
||||||
this.handleAppVisibility(!document.hidden, callback);
|
|
||||||
}
|
|
||||||
}, {
|
}, {
|
||||||
key: "handleVisibilityEvent",
|
key: "handleVisibilityEvent",
|
||||||
value: function handleVisibilityEvent() {
|
value: function handleVisibilityEvent() {
|
||||||
this.handleAppVisibility(!document.hidden, this.readTimerCallback);
|
this.setState({
|
||||||
|
applicationVisible: !document.hidden
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: "handleError",
|
key: "handleError",
|
||||||
@@ -6117,6 +6178,7 @@ var TinodeWeb = function (_React$Component) {
|
|||||||
myUserId: this.state.myUserId,
|
myUserId: this.state.myUserId,
|
||||||
serverVersion: this.state.serverVersion,
|
serverVersion: this.state.serverVersion,
|
||||||
serverAddress: this.state.serverAddress,
|
serverAddress: this.state.serverAddress,
|
||||||
|
applicationVisible: this.state.applicationVisible,
|
||||||
errorText: this.state.errorText,
|
errorText: this.state.errorText,
|
||||||
errorLevel: this.state.errorLevel,
|
errorLevel: this.state.errorLevel,
|
||||||
errorAction: this.state.errorAction,
|
errorAction: this.state.errorAction,
|
||||||
@@ -6126,7 +6188,6 @@ var TinodeWeb = function (_React$Component) {
|
|||||||
onData: this.tnData,
|
onData: this.tnData,
|
||||||
onError: this.handleError,
|
onError: this.handleError,
|
||||||
onNewTopicCreated: this.handleNewTopicCreated,
|
onNewTopicCreated: this.handleNewTopicCreated,
|
||||||
readTimerHandler: this.handleReadTimer,
|
|
||||||
showContextMenu: this.handleShowContextMenu,
|
showContextMenu: this.handleShowContextMenu,
|
||||||
onChangePermissions: this.handleChangePermissions,
|
onChangePermissions: this.handleChangePermissions,
|
||||||
onNewChat: this.handleNewChatInvitation,
|
onNewChat: this.handleNewChatInvitation,
|
||||||
|
|||||||
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
+6
-7
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user