diff --git a/.loki/reference/chrome_Components_Icons_all.png b/.loki/reference/chrome_Components_Icons_all.png
index 9ee15f4ff..173c74e32 100644
Binary files a/.loki/reference/chrome_Components_Icons_all.png and b/.loki/reference/chrome_Components_Icons_all.png differ
diff --git a/.loki/reference/chrome_Components_Icons_phone.png b/.loki/reference/chrome_Components_Icons_phone.png
new file mode 100644
index 000000000..ea142fac6
Binary files /dev/null and b/.loki/reference/chrome_Components_Icons_phone.png differ
diff --git a/.loki/reference/chrome_Components_Icons_phoneOff.png b/.loki/reference/chrome_Components_Icons_phoneOff.png
new file mode 100644
index 000000000..d621a0f3a
Binary files /dev/null and b/.loki/reference/chrome_Components_Icons_phoneOff.png differ
diff --git a/src/components/Messages/Message/index.js b/src/components/Messages/Message/index.js
index 70d815955..bd9540c03 100644
--- a/src/components/Messages/Message/index.js
+++ b/src/components/Messages/Message/index.js
@@ -1,7 +1,7 @@
import { h } from 'preact';
import I18n from '../../../i18n';
-import { getAttachmentUrl, memo, normalizeTransferHistoryMessage } from '../../helpers';
+import { getAttachmentUrl, memo, normalizeTransferHistoryMessage, normalizeCallTimeMessage } from '../../helpers';
import { AudioAttachment } from '../AudioAttachment';
import { FileAttachment } from '../FileAttachment';
import { ImageAttachment } from '../ImageAttachment';
@@ -22,6 +22,8 @@ import {
MESSAGE_TYPE_WELCOME,
MESSAGE_TYPE_LIVECHAT_CLOSED,
MESSAGE_TYPE_LIVECHAT_STARTED,
+ MESSAGE_WEBRTC_CALL,
+ MESSAGE_JITSI_CALL,
MESSAGE_TYPE_LIVECHAT_TRANSFER_HISTORY,
} from '../constants';
@@ -80,7 +82,7 @@ const renderContent = ({
),
].filter(Boolean);
-const getSystemMessageText = ({ t, conversationFinishedMessage, transferData }) =>
+const getSystemMessageText = ({ t, conversationFinishedMessage, transferData, callStatus }) =>
(t === MESSAGE_TYPE_ROOM_NAME_CHANGED && I18n.t('Room name changed'))
|| (t === MESSAGE_TYPE_USER_ADDED && I18n.t('User added by'))
|| (t === MESSAGE_TYPE_USER_REMOVED && I18n.t('User removed by'))
@@ -89,6 +91,8 @@ const getSystemMessageText = ({ t, conversationFinishedMessage, transferData })
|| (t === MESSAGE_TYPE_WELCOME && I18n.t('Welcome'))
|| (t === MESSAGE_TYPE_LIVECHAT_CLOSED && (conversationFinishedMessage || I18n.t('Conversation finished')))
|| (t === MESSAGE_TYPE_LIVECHAT_STARTED && I18n.t('Chat started'))
+ || (t === MESSAGE_WEBRTC_CALL && normalizeCallTimeMessage(callStatus))
+ || (t === MESSAGE_JITSI_CALL && normalizeCallTimeMessage(callStatus))
|| (t === MESSAGE_TYPE_LIVECHAT_TRANSFER_HISTORY && normalizeTransferHistoryMessage(transferData));
const getMessageUsernames = (compact, message) => {
diff --git a/src/components/Messages/MessageList/livechatCall.js b/src/components/Messages/MessageList/livechatCall.js
new file mode 100644
index 000000000..ae2625e32
--- /dev/null
+++ b/src/components/Messages/MessageList/livechatCall.js
@@ -0,0 +1,68 @@
+import { h } from 'preact';
+import { useState } from 'preact/compat';
+
+import { Livechat } from '../../../api';
+import I18n from '../../../i18n';
+import PhoneAccept from '../../../icons/phone.svg';
+import PhoneDecline from '../../../icons/phoneOff.svg';
+import { store } from '../../../store';
+import { Avatar } from '../../Avatar';
+import { Button } from '../../Button';
+import { Screen } from '../../Screen';
+import { createClassName, getAvatarUrl, createToken } from '../../helpers';
+import styles from './styles.scss';
+
+
+const DisplayCallIframe = (rid) => (
+
+
+
+
+
+);
+
+
+export const CallNotification = (props) => {
+ const [isframe, setIframe] = useState(false);
+ const [show, setShow] = useState(true);
+
+ const acceptClick = async () => {
+ setShow(!{ show });
+ if (props.rid.t === 'jitsi_call_started') {
+ const { state } = store;
+ const { alerts } = state;
+ try {
+ const result = await Livechat.videoCall(props.rid);
+ window.open(`https://${ result.videoCall.domain }/${ result.videoCall.room }`);
+ return;
+ } catch (error) {
+ console.error(error);
+ const alert = { id: createToken(), children: I18n.t('Error in connecting call'), error: true, timeout: 5000 };
+ await store.setState({ alerts: (alerts.push(alert), alerts) });
+ return;
+ }
+ }
+ setIframe(true);
+ await Livechat.updateCallStatus('accept');
+ };
+
+ const declineClick = async () => {
+ setShow(false);
+ await Livechat.updateCallStatus('decline');
+ };
+
+ return (
+
+ { show ? (
+
+
+ {I18n.t('Incoming video Call')}
+
+
+
) : null}
+ {isframe ? (
) : null }
+
);
+};
diff --git a/src/components/Messages/MessageList/styles.scss b/src/components/Messages/MessageList/styles.scss
index eaea3151d..290e5d054 100644
--- a/src/components/Messages/MessageList/styles.scss
+++ b/src/components/Messages/MessageList/styles.scss
@@ -33,3 +33,85 @@
list-style: none;
}
}
+
+.notifyCall {
+ position: absolute;
+ top: 0;
+
+ display: flex;
+ flex-direction: column;
+
+ width: 100%;
+ height: 50%;
+ margin-bottom: 5px;
+
+ padding-top: 40px;
+ padding-bottom: 0;
+
+ text-align: center;
+
+ color: #ffffff;
+
+ border: 1px solid black;
+
+ background: #1f2329;
+
+ font-size: 15px;
+ font-weight: 600;
+ font-style: normal;
+ line-height: 16px;
+ justify-content: space-between;
+}
+
+.button {
+ display: flex;
+ flex-direction: row;
+
+ margin-bottom: 1px;
+ padding: 10px;
+ padding-top: 0;
+
+ color: white;
+ justify-content: center;
+}
+
+.avatar {
+ display: flex;
+ flex-direction: row;
+
+ margin-bottom: -17%;
+ justify-content: center;
+}
+
+.declineButton {
+ margin-right: 10px;
+ margin-bottom: 0;
+
+ border-color: red;
+ background-color: #f5455c;
+}
+
+.acceptButton {
+ margin-bottom: 0;
+ margin-left: 10px;
+
+ border-color: green;
+ background-color: #2de0a5;
+}
+
+.iframe {
+ position: absolute;
+ top: 0;
+
+ display: flex;
+ flex-direction: column;
+
+ width: 100%;
+ height: 50%;
+}
+
+@media screen and (min-width: 410px) {
+ .avatar {
+ margin-bottom: -7%;
+ }
+}
diff --git a/src/components/Messages/constants.js b/src/components/Messages/constants.js
index 94be2ca13..6c8bc70ea 100644
--- a/src/components/Messages/constants.js
+++ b/src/components/Messages/constants.js
@@ -7,3 +7,5 @@ export const MESSAGE_TYPE_WELCOME = 'wm';
export const MESSAGE_TYPE_LIVECHAT_CLOSED = 'livechat-close';
export const MESSAGE_TYPE_LIVECHAT_STARTED = 'livechat-started';
export const MESSAGE_TYPE_LIVECHAT_TRANSFER_HISTORY = 'livechat_transfer_history';
+export const MESSAGE_JITSI_CALL = 'webrtc_call_started';
+export const MESSAGE_WEBRTC_CALL = 'jitsi_call_started';
diff --git a/src/components/helpers.js b/src/components/helpers.js
index 7544d0d07..7cea103b9 100644
--- a/src/components/helpers.js
+++ b/src/components/helpers.js
@@ -1,3 +1,6 @@
+import format from 'date-fns/format';
+import { parseISO } from 'date-fns/fp';
+import isToday from 'date-fns/isToday';
import { Component } from 'preact';
import { Livechat } from '../api';
@@ -126,6 +129,20 @@ export const sortArrayByColumn = (array, column, inverted) => array.sort((a, b)
return 1;
});
+export const normalizeCallTimeMessage = (callStatus) => {
+ const timestamp = new Date().toISOString();
+ const time = format(parseISO(timestamp), isToday(parseISO(timestamp)) ? 'HH:mm' : 'dddd HH:mm');
+ if (!callStatus) {
+ return;
+ }
+ if (callStatus === 'accept') {
+ return I18n.t('Call Started at %{time}', { time });
+ }
+ if (callStatus === 'endCall') {
+ return I18n.t('Call Ended at %{time}', { time });
+ }
+};
+
export const normalizeTransferHistoryMessage = (transferData) => {
if (!transferData) {
return;
diff --git a/src/icons/phone.svg b/src/icons/phone.svg
new file mode 100644
index 000000000..074a7c13c
--- /dev/null
+++ b/src/icons/phone.svg
@@ -0,0 +1,6 @@
+
\ No newline at end of file
diff --git a/src/icons/phoneOff.svg b/src/icons/phoneOff.svg
new file mode 100644
index 000000000..a92af93a4
--- /dev/null
+++ b/src/icons/phoneOff.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/routes/Chat/component.js b/src/routes/Chat/component.js
index 0fa0774b3..cf726ceea 100644
--- a/src/routes/Chat/component.js
+++ b/src/routes/Chat/component.js
@@ -7,6 +7,7 @@ import { FilesDropTarget } from '../../components/FilesDropTarget';
import { FooterOptions, CharCounter } from '../../components/Footer';
import { Menu } from '../../components/Menu';
import { MessageList } from '../../components/Messages';
+import { CallNotification } from '../../components/Messages/MessageList/livechatCall';
import { Screen } from '../../components/Screen';
import { createClassName } from '../../components/helpers';
import I18n from '../../i18n';
@@ -165,6 +166,9 @@ export default class Chat extends Component {
autoFocus={true}
/>}
+
+ {(messages[messages.length - 1] ? messages[messages.length - 1].t === 'webRTC_call_started' || messages[messages.length - 1].t === 'jitsi_call_started' : messages[messages.length - 1]) ? : null}
+