Merge pull request #97 from tinode/calls-head
Move video call message state and duration to head.
This commit is contained in:
+2
-2
@@ -4,5 +4,5 @@ export const CALL_STATE_OUTGOING_INITATED = 1;
|
||||
export const CALL_STATE_INCOMING_RECEIVED = 2;
|
||||
export const CALL_STATE_IN_PROGRESS = 3;
|
||||
|
||||
// Mime type used for video call messages.
|
||||
export const CALL_MESSAGE_MIME_TYPE = 'application/x-tinode-webrtc';
|
||||
// Video call drafty headers representing call state.
|
||||
export const CALL_HEAD_STARTED = 'started';
|
||||
|
||||
@@ -4,6 +4,8 @@ import { defineMessages } from 'react-intl';
|
||||
import { Drafty } from 'tinode-sdk';
|
||||
|
||||
import AudioPlayer from '../widgets/audio-player.jsx'
|
||||
import CallMessage from '../widgets/call-message.jsx'
|
||||
import CallStatus from '../widgets/call-status.jsx';
|
||||
import LazyImage from '../widgets/lazy-image.jsx'
|
||||
import UploadingImage from '../widgets/uploading-image.jsx'
|
||||
|
||||
@@ -163,6 +165,14 @@ export function fullFormatter(style, data, values, key, stack) {
|
||||
attr.className = 'reply-quote'
|
||||
attr.onClick = this.onQuoteClick;
|
||||
break;
|
||||
case 'VC':
|
||||
el = CallMessage;
|
||||
// Video call messages do not have content.
|
||||
values = null;
|
||||
attr.content = this.callState;
|
||||
attr.response = this.isResponse;
|
||||
attr.duration = this.callDuration;
|
||||
break;
|
||||
default:
|
||||
if (!el) {
|
||||
// Unknown element.
|
||||
@@ -245,6 +255,12 @@ export function previewFormatter(style, data, values, key) {
|
||||
el = React.Fragment;
|
||||
values = [<i key="ex" className="material-icons">attachment</i>, ' ', this.formatMessage(messages.drafty_attachment)];
|
||||
break;
|
||||
case 'VC':
|
||||
el = CallStatus;
|
||||
attr.incoming = this.previewIsResponse;
|
||||
attr.success = true; // FIXME: use actuall call completion status instead of TRUE.
|
||||
values = null;
|
||||
break;
|
||||
case 'QQ':
|
||||
case 'HD':
|
||||
el = null;
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
|
||||
import { Tinode } from 'tinode-sdk';
|
||||
|
||||
import { CALL_MESSAGE_MIME_TYPE } from '../constants.js'
|
||||
|
||||
// Make shortcut icon appear with a green dot + show unread count in title.
|
||||
export function updateFavicon(count) {
|
||||
const oldIcon = document.getElementById('shortcut-icon');
|
||||
@@ -208,11 +206,6 @@ export function cancelablePromise(promise) {
|
||||
};
|
||||
};
|
||||
|
||||
// Returns true if specified mime type represents a Tinode video call.
|
||||
export function isVideoCall(mime) {
|
||||
return mime == CALL_MESSAGE_MIME_TYPE;
|
||||
}
|
||||
|
||||
// Clips string to the specified length.
|
||||
export function clipStr(str, length) {
|
||||
return str && str.substring(0, length);
|
||||
|
||||
@@ -1137,20 +1137,14 @@ class MessagesView extends React.Component {
|
||||
);
|
||||
prevDate = thisDate;
|
||||
}
|
||||
let duration;
|
||||
if (msg.head && isVideoCall(msg.head.mime)) {
|
||||
topic.messageVersions(msg, (cur, before) => {
|
||||
if (cur.content == 'finished' && before.content == 'accepted') {
|
||||
duration = msg.ts - before.ts;
|
||||
}
|
||||
});
|
||||
}
|
||||
const duration = msg.head ? msg.head['webrtc-duration'] : undefined;
|
||||
messageNodes.push(
|
||||
<ChatMessage
|
||||
tinode={this.props.tinode}
|
||||
content={msg.content}
|
||||
mimeType={msg.head ? msg.head.mime : null}
|
||||
timestamp={msg.ts}
|
||||
callState={msg.head ? msg.head.webrtc : null}
|
||||
duration={duration}
|
||||
response={isReply}
|
||||
seq={msg.seq}
|
||||
|
||||
@@ -21,7 +21,7 @@ import { API_KEY, APP_NAME, DEFAULT_P2P_ACCESS_MODE, FORWARDED_PREVIEW_LENGTH, L
|
||||
MEDIA_BREAKPOINT, RECEIVED_DELAY } from '../config.js';
|
||||
import { CALL_STATE_NONE, CALL_STATE_OUTGOING_INITATED,
|
||||
CALL_STATE_INCOMING_RECEIVED, CALL_STATE_IN_PROGRESS,
|
||||
CALL_MESSAGE_MIME_TYPE } from '../constants.js';
|
||||
CALL_HEAD_STARTED } from '../constants.js';
|
||||
import { PACKAGE_VERSION } from '../version.js';
|
||||
import { base64ReEncode, makeImageUrl } from '../lib/blob-helpers.js';
|
||||
import { detectServerAddress, isLocalHost, isSecureConnection } from '../lib/host-name.js';
|
||||
@@ -1687,8 +1687,8 @@ class TinodeWeb extends React.Component {
|
||||
handleCallInvite(callTopic, callSeq, callState) {
|
||||
switch (callState) {
|
||||
case CALL_STATE_OUTGOING_INITATED:
|
||||
let head = {mime: CALL_MESSAGE_MIME_TYPE };
|
||||
this.handleSendMessage('started', undefined, undefined, head)
|
||||
let head = { webrtc: CALL_HEAD_STARTED };
|
||||
this.handleSendMessage(Drafty.videoCall(), undefined, undefined, head)
|
||||
.then((ctrl) => {
|
||||
if (ctrl.code < 200 || ctrl.code >= 300 || !ctrl.params || !ctrl.params.seq) {
|
||||
this.handleCallClose();
|
||||
|
||||
@@ -11,7 +11,7 @@ export default class CallStatus extends React.PureComponent {
|
||||
|
||||
return (
|
||||
<div className="composed-material">
|
||||
<i class="material-icons">call</i><i class="material-icons second">{icon2}</i>
|
||||
<i className="material-icons">call</i><i className="material-icons second">{icon2}</i>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import { FormattedMessage, injectIntl } from 'react-intl';
|
||||
import { Drafty, Tinode } from 'tinode-sdk';
|
||||
|
||||
import Attachment from './attachment.jsx';
|
||||
import CallMessage from './call-message.jsx';
|
||||
import LetterTile from './letter-tile.jsx';
|
||||
import ReceivedMarker from './received-marker.jsx'
|
||||
|
||||
@@ -34,6 +33,12 @@ class BaseChatMessage extends React.PureComponent {
|
||||
formatMessage: props.intl.formatMessage.bind(props.intl),
|
||||
viewportWidth: props.viewportWidth,
|
||||
authorizeURL: props.tinode.authorizeURL.bind(props.tinode),
|
||||
|
||||
// Video call related bits.
|
||||
callState: props.callState,
|
||||
isResponse: props.response,
|
||||
callDuration: props.duration,
|
||||
|
||||
onImagePreview: this.handleImagePreview,
|
||||
onFormButtonClick: this.handleFormButtonClick,
|
||||
onQuoteClick: this.handleQuoteClick
|
||||
@@ -147,12 +152,6 @@ class BaseChatMessage extends React.PureComponent {
|
||||
<FormattedMessage id="deleted_content"
|
||||
defaultMessage="content deleted" description="Shown when messages are deleted" />
|
||||
</i></>
|
||||
} else if (isVideoCall(this.props.mimeType)) {
|
||||
// Video call message.
|
||||
content = <CallMessage
|
||||
content={this.props.content}
|
||||
response={this.props.response}
|
||||
duration={this.props.duration} />
|
||||
} else if (typeof content != 'string') {
|
||||
content = <><i className="material-icons gray">warning_amber</i> <i className="gray">
|
||||
<FormattedMessage id="invalid_content"
|
||||
|
||||
@@ -9,7 +9,6 @@ import Contact from './contact.jsx';
|
||||
import ContactAction from './contact-action.jsx';
|
||||
|
||||
import { makeImageUrl } from '../lib/blob-helpers.js';
|
||||
import { isVideoCall } from '../lib/utils.js'
|
||||
|
||||
import { MESSAGE_PREVIEW_LENGTH } from '../config.js';
|
||||
|
||||
@@ -86,7 +85,7 @@ class ContactList extends React.Component {
|
||||
if (msg) {
|
||||
forwarded = msg.head ? msg.head.forwarded : null;
|
||||
deliveryStatus = msg._status || c.msgStatus(msg, true);
|
||||
previewIsVideoCall = msg.head ? isVideoCall(msg.head.mime) : null;
|
||||
previewIsVideoCall = msg.head ? (msg.head.webrtc !== undefined) : null;
|
||||
previewIsResponse = msg.from != this.props.myUserId;
|
||||
if (msg.content) {
|
||||
preview = typeof msg.content == 'string' ?
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage, injectIntl } from 'react-intl';
|
||||
|
||||
import CallStatus from './call-status.jsx';
|
||||
import ContactBadges from './contact-badges.jsx';
|
||||
import LetterTile from './letter-tile.jsx';
|
||||
import UnreadBadge from './unread-badge.jsx';
|
||||
@@ -71,16 +70,11 @@ class Contact extends React.Component {
|
||||
|
||||
// The this.props.preview contains alreay shortened Drafty or string.
|
||||
let preview;
|
||||
if (this.props.previewIsVideoCall) {
|
||||
// TODO: use words to describe call status and duration.
|
||||
preview = <CallStatus
|
||||
incoming={this.props.previewIsResponse}
|
||||
success={true} />; // FIXME: use actuall call completion status instead of TRUE.
|
||||
} else if (typeof this.props.preview == 'string') {
|
||||
if (typeof this.props.preview == 'string') {
|
||||
preview = this.props.preview;
|
||||
} else if (Drafty.isValid(this.props.preview)) {
|
||||
preview = React.createElement(React.Fragment, null, Drafty.format(this.props.preview, previewFormatter,
|
||||
{formatMessage: this.props.intl.formatMessage}));
|
||||
{formatMessage: this.props.intl.formatMessage, previewIsResponse: this.props.previewIsResponse}));
|
||||
} else if (this.props.preview) {
|
||||
preview =
|
||||
<><i className="material-icons gray">warning_amber</i> <i className="gray">
|
||||
|
||||
+364
-538
File diff suppressed because it is too large
Load Diff
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
+74
-88
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