callview: redesign
Change-Id: I8ce1e02be798104aaca9d09d9dc5d931133ada6d
1
images/icons/check_box-24px.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"/></svg>
|
After Width: | Height: | Size: 269 B |
1
images/icons/check_box_outline_blank-24px.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M19 5v14H5V5h14m0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/></svg>
|
After Width: | Height: | Size: 228 B |
1
images/icons/close_fullscreen-24px.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24" viewBox="0 0 24 24" width="24"><rect fill="none" height="24" width="24"/><path d="M22,3.41l-5.29,5.29L20,12h-8V4l3.29,3.29L20.59,2L22,3.41z M3.41,22l5.29-5.29L12,20v-8H4l3.29,3.29L2,20.59L3.41,22z"/></svg>
|
After Width: | Height: | Size: 291 B |
4
images/icons/ic_call_end_white_24px.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<svg fill="#ffffff" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M12 9c-1.6 0-3.15.25-4.6.72v3.1c0 .39-.23.74-.56.9-.98.49-1.87 1.12-2.66 1.85-.18.18-.43.28-.7.28-.28 0-.53-.11-.71-.29L.29 13.08c-.18-.17-.29-.42-.29-.7 0-.28.11-.53.29-.71C3.34 8.78 7.46 7 12 7s8.66 1.78 11.71 4.67c.18.18.29.43.29.71 0 .28-.11.53-.29.71l-2.48 2.48c-.18.18-.43.29-.71.29-.27 0-.52-.11-.7-.28-.79-.74-1.69-1.36-2.67-1.85-.33-.16-.56-.5-.56-.9v-3.1C15.15 9.25 13.6 9 12 9z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 553 B |
Before Width: | Height: | Size: 1.3 KiB |
4
images/icons/ic_high_quality_24px.svg
Normal file
|
@ -0,0 +1,4 @@
|
|||
<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M0 0h24v24H0z" fill="none"/>
|
||||
<path d="M19 4H5c-1.11 0-2 .9-2 2v12c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2zm-8 11H9.5v-2h-2v2H6V9h1.5v2.5h2V9H11v6zm7-1c0 .55-.45 1-1 1h-.75v1.5h-1.5V15H14c-.55 0-1-.45-1-1v-4c0-.55.45-1 1-1h3c.55 0 1 .45 1 1v4zm-3.5-.5h2v-3h-2v3z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 398 B |
Before Width: | Height: | Size: 218 B |
Before Width: | Height: | Size: 90 B |
1
images/icons/insert_photo-24px.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/></svg>
|
After Width: | Height: | Size: 258 B |
3
images/icons/more_vert-24px.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/>
|
||||
<path fill="white" d="M12 8c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2zm0 2c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm0 6c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 302 B |
1
images/icons/open_in_full-24px.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" enable-background="new 0 0 24 24" height="24" viewBox="0 0 24 24" width="24"><rect fill="none" height="24" width="24"/><polygon points="21,11 21,3 13,3 16.29,6.29 6.29,16.29 3,13 3,21 11,21 7.71,17.71 17.71,7.71"/></svg>
|
After Width: | Height: | Size: 260 B |
1
images/icons/pause_circle_outline-24px.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M9 16h2V8H9v8zm3-14C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm1-4h2V8h-2v8z"/></svg>
|
After Width: | Height: | Size: 290 B |
1
images/icons/phone_forwarded-24px.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M18 11l5-5-5-5v3h-4v4h4v3zm2 4.5c-1.25 0-2.45-.2-3.57-.57-.35-.11-.74-.03-1.02.24l-2.2 2.2c-2.83-1.44-5.15-3.75-6.59-6.59l2.2-2.21c.28-.26.36-.65.25-1C8.7 6.45 8.5 5.25 8.5 4c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1z"/></svg>
|
After Width: | Height: | Size: 406 B |
1
images/icons/play_circle_outline-24px.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M10 16.5l6-4.5-6-4.5v9zM12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z"/></svg>
|
After Width: | Height: | Size: 285 B |
1
images/icons/screen_share-24px.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M20 18c1.1 0 1.99-.9 1.99-2L22 6c0-1.11-.9-2-2-2H4c-1.11 0-2 .89-2 2v10c0 1.1.89 2 2 2H0v2h24v-2h-4zm-7-3.53v-2.19c-2.78 0-4.61.85-6 2.72.56-2.67 2.11-5.33 6-5.87V7l4 3.73-4 3.74z"/></svg>
|
After Width: | Height: | Size: 319 B |
1
images/icons/videocam-24px.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0z" fill="none"/><path d="M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z"/></svg>
|
After Width: | Height: | Size: 239 B |
3
qml.qrc
|
@ -66,6 +66,7 @@
|
|||
<file>src/mainview/js/incomingcallpagecreation.js</file>
|
||||
<file>src/mainview/components/ContactSearchBar.qml</file>
|
||||
<file>src/mainview/components/VideoCallPage.qml</file>
|
||||
<file>src/mainview/components/CallAdvancedOptions.qml</file>
|
||||
<file>src/mainview/components/ChangeLogScrollView.qml</file>
|
||||
<file>src/mainview/components/ProjectCreditsScrollView.qml</file>
|
||||
<file>src/mainview/components/AccountComboBoxPopup.qml</file>
|
||||
|
@ -75,9 +76,9 @@
|
|||
<file>src/mainview/components/WelcomePageQrDialog.qml</file>
|
||||
<file>src/commoncomponents/GeneralMenuItem.qml</file>
|
||||
<file>src/mainview/components/ConversationSmartListContextMenu.qml</file>
|
||||
<file>src/mainview/components/CallViewContextMenu.qml</file>
|
||||
<file>src/commoncomponents/GeneralMenuSeparator.qml</file>
|
||||
<file>src/mainview/components/UserProfile.qml</file>
|
||||
<file>src/mainview/components/VideoCallPageContextMenu.qml</file>
|
||||
<file>src/mainview/js/videodevicecontextmenuitemcreation.js</file>
|
||||
<file>src/mainview/components/VideoCallPageContextMenuDeviceItem.qml</file>
|
||||
<file>src/mainview/components/SelectScreen.qml</file>
|
||||
|
|
|
@ -32,22 +32,23 @@
|
|||
<file>images/icons/ic_arrow_tab_next_black_9dp_2x.png</file>
|
||||
<file>images/icons/ic_arrow_tab_previous_black_9dp_2x.png</file>
|
||||
<file>images/icons/ic_block_24px.svg</file>
|
||||
<file>images/icons/ic_call_transfer_white_24px.png</file>
|
||||
<file>images/icons/phone_forwarded-24px.svg</file>
|
||||
<file>images/icons/ic_chat_black_24dp_2x.png</file>
|
||||
<file>images/icons/ic_chat_white_24dp.png</file>
|
||||
<file>images/icons/more_vert-24px.svg</file>
|
||||
<file>images/icons/ic_check_white_18dp_2x.png</file>
|
||||
<file>images/icons/ic_clear_24px.svg</file>
|
||||
<file>images/icons/ic_close_white_24dp.png</file>
|
||||
<file>images/icons/ic_content_copy.svg</file>
|
||||
<file>images/icons/ic_delete_black_18dp_2x.png</file>
|
||||
<file>images/icons/ic_done_white_24dp.png</file>
|
||||
<file>images/icons/ic_exit_full_screen_black.png</file>
|
||||
<file>images/icons/ic_folder_black_18dp_2x.png</file>
|
||||
<file>images/icons/ic_full_screen_black.png</file>
|
||||
<file>images/icons/open_in_full-24px.svg</file>
|
||||
<file>images/icons/close_fullscreen-24px.svg</file>
|
||||
<file>images/icons/ic_group_add_white_24dp.png</file>
|
||||
<file>images/icons/ic_high_quality_white_24dp.png</file>
|
||||
<file>images/icons/ic_mic_off_white_24dp.png</file>
|
||||
<file>images/icons/ic_pause_white_24dp.png</file>
|
||||
<file>images/icons/pause_circle_outline-24px.svg</file>
|
||||
<file>images/icons/play_circle_outline-24px.svg</file>
|
||||
<file>images/icons/ic_pause_white_100px.png</file>
|
||||
<file>images/icons/ic_person_add_black_24dp_2x.png</file>
|
||||
<file>images/icons/ic_person_add_white_24dp.png</file>
|
||||
|
@ -62,6 +63,7 @@
|
|||
<file>images/icons/ic_videocam_off_white_24dp.png</file>
|
||||
<file>images/icons/ic_videocam_white.png</file>
|
||||
<file>images/icons/ic_voicemail_white_24dp_2x.png</file>
|
||||
<file>images/icons/ic_call_end_white_24px.svg</file>
|
||||
<file>images/icons/round-add-24px.svg</file>
|
||||
<file>images/icons/round-arrow_drop_down-24px.svg</file>
|
||||
<file>images/icons/round-arrow_drop_up-24px.svg</file>
|
||||
|
@ -89,6 +91,9 @@
|
|||
<file>images/icons/ic_show_password.png</file>
|
||||
<file>images/icons/baseline-desktop_windows-24px.svg</file>
|
||||
<file>images/icons/baseline-people-24px.svg</file>
|
||||
<file>images/icons/ic_high_quality_24px.svg</file>
|
||||
<file>images/icons/insert_photo-24px.svg</file>
|
||||
<file>images/icons/screen_share-24px.svg</file>
|
||||
<file>images/icons/round-add_a_photo-24px.svg</file>
|
||||
<file>images/icons/ic_mic_white_24dp.png</file>
|
||||
<file>images/icons/icon-keypad-24.png</file>
|
||||
|
@ -104,6 +109,8 @@
|
|||
<file>images/icons/av_icons/send-24px.svg</file>
|
||||
<file>images/icons/av_icons/stop-24px.svg</file>
|
||||
<file>images/icons/av_icons/mic-24px.svg</file>
|
||||
<file>images/icons/check_box-24px.svg</file>
|
||||
<file>images/icons/check_box_outline_blank-24px.svg</file>
|
||||
<file>images/icons/ic_close_black_24dp.png</file>
|
||||
<file>images/icons/extension_24dp.svg</file>
|
||||
<file>images/icons/settings_backup_restore-black-18dp.svg</file>
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
/*
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Edric Ladent Milaret <edric.ladent-milaret@savoirfairelinux.com>
|
||||
* Author: Anthony Léonard <anthony.leonard@savoirfairelinux.com>
|
||||
* Author: Anthony Léonard <anthony.leonard@savoirfairelinux.com>
|
||||
* Author: Olivier Soldano <olivier.soldano@savoirfairelinux.com>
|
||||
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
||||
* Author: Isa Nanic <isa.nanic@savoirfairelinux.com>
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -333,7 +334,6 @@ CallAdapter::updateCallOverlay(const lrc::api::conversation::Info &convInfo)
|
|||
QObject::disconnect(oneSecondTimer_);
|
||||
QObject::connect(oneSecondTimer_, &QTimer::timeout, [this] { setTime(accountId_, convUid_); });
|
||||
oneSecondTimer_->start(20);
|
||||
|
||||
auto &accInfo = LRCInstance::accountModel().getAccountInfo(accountId_);
|
||||
|
||||
auto call = LRCInstance::getCallInfoForConversation(convInfo);
|
||||
|
@ -384,6 +384,15 @@ CallAdapter::hangUpThisCall()
|
|||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CallAdapter::isRecordingThisCall()
|
||||
{
|
||||
auto &accInfo = LRCInstance::accountModel().getAccountInfo(accountId_);
|
||||
auto convInfo = LRCInstance::getConversationFromConvUid(convUid_, accountId_);
|
||||
return accInfo.callModel->isRecording(convInfo.confId)
|
||||
|| accInfo.callModel->isRecording(convInfo.callId);
|
||||
}
|
||||
|
||||
void
|
||||
CallAdapter::holdThisCallToggle()
|
||||
{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/*
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -53,6 +54,7 @@ public:
|
|||
Q_INVOKABLE void muteThisCallToggle();
|
||||
Q_INVOKABLE void recordThisCallToggle();
|
||||
Q_INVOKABLE void videoPauseThisCallToggle();
|
||||
Q_INVOKABLE bool isRecordingThisCall();
|
||||
|
||||
signals:
|
||||
void showOutgoingCallPage(const QString &accountId, const QString &convUid);
|
||||
|
@ -106,8 +108,7 @@ private:
|
|||
/*
|
||||
* For Call Overlay
|
||||
*/
|
||||
void setTime(const QString &accountId, const QString &convUid);
|
||||
void updateCallOverlay(const lrc::api::conversation::Info &convInfo);
|
||||
|
||||
void setTime(const QString &accountId, const QString &convUid);
|
||||
QTimer *oneSecondTimer_;
|
||||
};
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import net.jami.Models 1.0
|
||||
import QtGraphicalEffects 1.15
|
||||
|
||||
|
||||
/*
|
||||
|
@ -31,6 +32,9 @@ import net.jami.Models 1.0
|
|||
Button {
|
||||
id: hoverableButton
|
||||
|
||||
checkable: true
|
||||
checked: false
|
||||
|
||||
property int fontPointSize: 9
|
||||
property int buttonImageHeight: hoverableButtonBackground.height - 10
|
||||
property int buttonImageWidth: hoverableButtonBackground.width - 10
|
||||
|
@ -43,6 +47,11 @@ Button {
|
|||
|
||||
property alias radius: hoverableButtonBackground.radius
|
||||
property alias source: hoverableButtonImage.source
|
||||
property var checkedImage: null
|
||||
property var baseImage: null
|
||||
property var checkedColor: null
|
||||
property var baseColor: null
|
||||
property alias color: hoverableButton.baseColor
|
||||
|
||||
font.pointSize: fontPointSize
|
||||
|
||||
|
@ -64,18 +73,31 @@ Button {
|
|||
fillMode: Image.PreserveAspectFit
|
||||
mipmap: true
|
||||
asynchronous: true
|
||||
|
||||
source: hoverableButton.checked && checkedImage? checkedImage : baseImage
|
||||
|
||||
layer {
|
||||
enabled: true
|
||||
effect: ColorOverlay {
|
||||
id: overlay
|
||||
color: hoverableButton.checked && checkedColor?
|
||||
checkedColor :
|
||||
(baseColor? baseColor : "transparent")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
||||
hoverEnabled: true
|
||||
hoverEnabled: false
|
||||
|
||||
onPressed: {
|
||||
hoverableButtonBackground.color = onPressColor
|
||||
}
|
||||
onReleased: {
|
||||
hoverableButtonBackground.color = onReleaseColor
|
||||
hoverableButton.toggle()
|
||||
hoverableButton.clicked()
|
||||
}
|
||||
onEntered: {
|
||||
|
|
|
@ -113,12 +113,14 @@ Window {
|
|||
|
||||
function onCloseCallStack(accountId, convUid) {
|
||||
|
||||
|
||||
var responsibleCallId = ClientWrapper.utilsAdaptor.getCallId(
|
||||
callStackView.responsibleAccountId, callStackView.responsibleConvUid)
|
||||
var callId = ClientWrapper.utilsAdaptor.getCallId(
|
||||
callStackView.responsibleAccountId, convUid)
|
||||
/*
|
||||
* Check if call stack view is on any of the stackview.
|
||||
*/
|
||||
if (callStackView.responsibleAccountId === accountId
|
||||
&& callStackView.responsibleConvUid === convUid) {
|
||||
if (responsibleCallId === callId || responsibleCallId.length === 0) {
|
||||
if (welcomeViewStack.find(function (item, index) {
|
||||
return item.objectName === "callStackViewObject"
|
||||
}) || sidePanelViewStack.find(function (item, index) {
|
||||
|
@ -156,7 +158,7 @@ Window {
|
|||
communicationPageMessageWebView.headerUserUserNameLabelText = (name !== id) ? id : ""
|
||||
|
||||
callStackView.needToCloseInCallConversationAndPotentialWindow()
|
||||
callStackView.setCorrspondingMessageWebView(
|
||||
callStackView.setLinkedWebview(
|
||||
communicationPageMessageWebView)
|
||||
|
||||
callStackView.responsibleAccountId = accountId
|
||||
|
@ -283,7 +285,7 @@ Window {
|
|||
* Set up chatview.
|
||||
*/
|
||||
MessagesAdapter.setupChatView(currentUID)
|
||||
callStackView.setCorrspondingMessageWebView(
|
||||
callStackView.setLinkedWebview(
|
||||
communicationPageMessageWebView)
|
||||
|
||||
if (welcomeViewStack.find(function (item, index) {
|
||||
|
@ -363,22 +365,6 @@ Window {
|
|||
visible: false
|
||||
|
||||
objectName: "callStackViewObject"
|
||||
|
||||
onCallPageBackButtonIsClicked: {
|
||||
mainViewWindowSidePanel.deselectConversationSmartList()
|
||||
if (welcomeViewStack.visible)
|
||||
welcomeViewStack.pop(welcomePage)
|
||||
else if (sidePanelViewStack.visible)
|
||||
sidePanelViewStack.pop(mainViewWindowSidePanel)
|
||||
}
|
||||
|
||||
onOutgoingCallPageBackButtonIsClicked: {
|
||||
mainViewWindowSidePanel.deselectConversationSmartList()
|
||||
if (welcomeViewStack.visible)
|
||||
welcomeViewStack.pop(welcomePage)
|
||||
else if (sidePanelViewStack.visible)
|
||||
sidePanelViewStack.pop(mainViewWindowSidePanel)
|
||||
}
|
||||
}
|
||||
|
||||
WelcomePage {
|
||||
|
|
|
@ -31,9 +31,7 @@ Rectangle {
|
|||
property string bestName: "Best Name"
|
||||
property string bestId: "Best Id"
|
||||
|
||||
property var corrspondingMessageWebView: null
|
||||
|
||||
signal audioCallPageBackButtonIsClicked
|
||||
property var linkedWebview: null
|
||||
|
||||
function updateUI(accountId, convUid) {
|
||||
contactImgSource = "data:image/png;base64," + ClientWrapper.utilsAdaptor.getContactImageString(
|
||||
|
@ -44,19 +42,19 @@ Rectangle {
|
|||
bestId = (bestName !== id) ? id : ""
|
||||
}
|
||||
|
||||
function setAudioCallPageCorrspondingMessageWebView(webViewId) {
|
||||
corrspondingMessageWebView = webViewId
|
||||
corrspondingMessageWebView.needToHideConversationInCall.disconnect(
|
||||
function setLinkedWebview(webViewId) {
|
||||
linkedWebview = webViewId
|
||||
linkedWebview.needToHideConversationInCall.disconnect(
|
||||
closeInCallConversation)
|
||||
corrspondingMessageWebView.needToHideConversationInCall.connect(
|
||||
linkedWebview.needToHideConversationInCall.connect(
|
||||
closeInCallConversation)
|
||||
}
|
||||
|
||||
function closeInCallConversation() {
|
||||
if (inAudioCallMessageWebViewStack.visible) {
|
||||
corrspondingMessageWebView.resetMessagingHeaderBackButtonSource(
|
||||
linkedWebview.resetMessagingHeaderBackButtonSource(
|
||||
true)
|
||||
corrspondingMessageWebView.setMessagingHeaderButtonsVisible(true)
|
||||
linkedWebview.setMessagingHeaderButtonsVisible(true)
|
||||
inAudioCallMessageWebViewStack.visible = false
|
||||
inAudioCallMessageWebViewStack.clear()
|
||||
}
|
||||
|
@ -109,7 +107,7 @@ Rectangle {
|
|||
isVideoMuted,
|
||||
isRecording, isSIP,
|
||||
isConferenceCall)
|
||||
audioCallOverlay.bestName = bestName
|
||||
audioCallPageRect.bestName = bestName
|
||||
}
|
||||
|
||||
function onShowOnHoldLabel(isPaused) {
|
||||
|
@ -118,34 +116,22 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
onBackButtonIsClicked: {
|
||||
if (inAudioCallMessageWebViewStack.visible) {
|
||||
corrspondingMessageWebView.resetMessagingHeaderBackButtonSource(
|
||||
true)
|
||||
corrspondingMessageWebView.setMessagingHeaderButtonsVisible(
|
||||
true)
|
||||
inAudioCallMessageWebViewStack.visible = false
|
||||
inAudioCallMessageWebViewStack.clear()
|
||||
}
|
||||
audioCallPageRect.audioCallPageBackButtonIsClicked()
|
||||
}
|
||||
|
||||
onOverlayChatButtonClicked: {
|
||||
if (inAudioCallMessageWebViewStack.visible) {
|
||||
corrspondingMessageWebView.resetMessagingHeaderBackButtonSource(
|
||||
linkedWebview.resetMessagingHeaderBackButtonSource(
|
||||
true)
|
||||
corrspondingMessageWebView.setMessagingHeaderButtonsVisible(
|
||||
linkedWebview.setMessagingHeaderButtonsVisible(
|
||||
true)
|
||||
inAudioCallMessageWebViewStack.visible = false
|
||||
inAudioCallMessageWebViewStack.clear()
|
||||
} else {
|
||||
corrspondingMessageWebView.resetMessagingHeaderBackButtonSource(
|
||||
linkedWebview.resetMessagingHeaderBackButtonSource(
|
||||
false)
|
||||
corrspondingMessageWebView.setMessagingHeaderButtonsVisible(
|
||||
linkedWebview.setMessagingHeaderButtonsVisible(
|
||||
false)
|
||||
inAudioCallMessageWebViewStack.visible = true
|
||||
inAudioCallMessageWebViewStack.push(
|
||||
corrspondingMessageWebView)
|
||||
linkedWebview)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
146
src/mainview/components/CallAdvancedOptions.qml
Normal file
|
@ -0,0 +1,146 @@
|
|||
|
||||
/*
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
import QtQuick.Controls.Universal 2.12
|
||||
import net.jami.Models 1.0
|
||||
|
||||
import "../../commoncomponents"
|
||||
|
||||
Popup {
|
||||
id: contactPickerPopup
|
||||
|
||||
property int type: ContactPicker.ContactPickerType.JAMICONFERENCE
|
||||
|
||||
|
||||
/*
|
||||
* Important to keep it one, since enum in c++ starts at one for conferences.
|
||||
*/
|
||||
enum ContactPickerType {
|
||||
JAMICONFERENCE = 1,
|
||||
SIPTRANSFER
|
||||
}
|
||||
|
||||
contentWidth: 250
|
||||
contentHeight: contactPickerPopupRectColumnLayout.height + 50
|
||||
|
||||
padding: 0
|
||||
|
||||
modal: true
|
||||
|
||||
contentItem: Rectangle {
|
||||
id: contactPickerPopupRect
|
||||
|
||||
width: 250
|
||||
|
||||
HoverableButton {
|
||||
id: closeButton
|
||||
|
||||
anchors.top: contactPickerPopupRect.top
|
||||
anchors.topMargin: 5
|
||||
anchors.right: contactPickerPopupRect.right
|
||||
anchors.rightMargin: 5
|
||||
|
||||
width: 30
|
||||
height: 30
|
||||
|
||||
radius: 30
|
||||
source: "qrc:/images/icons/ic_close_black_24dp.png"
|
||||
|
||||
onClicked: {
|
||||
contactPickerPopup.close()
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: contactPickerPopupRectColumnLayout
|
||||
|
||||
anchors.top: contactPickerPopupRect.top
|
||||
anchors.topMargin: 15
|
||||
|
||||
Text {
|
||||
id: contactPickerTitle
|
||||
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.preferredWidth: contactPickerPopupRect.width
|
||||
Layout.preferredHeight: 30
|
||||
|
||||
font.pointSize: JamiTheme.textFontSize
|
||||
font.bold: true
|
||||
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
text: type === ContactPicker.ContactPickerType.JAMICONFERENCE ? qsTr("Add to conference") : qsTr("Transfer this call")
|
||||
}
|
||||
|
||||
ContactSearchBar {
|
||||
id: contactPickerContactSearchBar
|
||||
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.topMargin: 5
|
||||
Layout.bottomMargin: 5
|
||||
Layout.preferredWidth: contactPickerPopupRect.width - 10
|
||||
Layout.preferredHeight: 35
|
||||
|
||||
onContactSearchBarTextChanged: {
|
||||
ContactAdapter.setSearchFilter(text)
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
contactPickerContactSearchBar.setPlaceholderString(
|
||||
qsTr("Search contacts"))
|
||||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: contactPickerListView
|
||||
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.preferredWidth: contactPickerPopupRect.width
|
||||
Layout.preferredHeight: 200
|
||||
|
||||
model: ContactAdapter.getContactSelectableModel(type)
|
||||
|
||||
clip: true
|
||||
|
||||
delegate: ContactPickerItemDelegate {
|
||||
id: contactPickerItemDelegate
|
||||
}
|
||||
|
||||
ScrollIndicator.vertical: ScrollIndicator {}
|
||||
}
|
||||
}
|
||||
|
||||
radius: 10
|
||||
color: "white"
|
||||
}
|
||||
|
||||
onAboutToShow: {
|
||||
// Reset the model on each show.
|
||||
contactPickerListView.model = ContactAdapter.getContactSelectableModel(
|
||||
type)
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
color: "transparent"
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -30,13 +31,21 @@ import "../../commoncomponents"
|
|||
Rectangle {
|
||||
id: callOverlayRect
|
||||
|
||||
property string bestName: "Best Name"
|
||||
property string timeText: "00:00"
|
||||
|
||||
signal backButtonIsClicked
|
||||
signal overlayChatButtonClicked
|
||||
|
||||
function setRecording(isRecording) {
|
||||
callViewContextMenu.isRecording = isRecording
|
||||
recordingRect.visible = isRecording
|
||||
}
|
||||
|
||||
function updateButtonStatus(isPaused, isAudioOnly, isAudioMuted, isVideoMuted, isRecording, isSIP, isConferenceCall) {
|
||||
callViewContextMenu.isSIP = isSIP
|
||||
callViewContextMenu.isPaused = isPaused
|
||||
callViewContextMenu.isAudioOnly = isAudioOnly
|
||||
callViewContextMenu.isRecording = isRecording
|
||||
recordingRect.visible = isRecording
|
||||
callOverlayButtonGroup.setButtonStatus(isPaused, isAudioOnly,
|
||||
isAudioMuted, isVideoMuted,
|
||||
isRecording, isSIP,
|
||||
|
@ -51,10 +60,6 @@ Rectangle {
|
|||
ContactPickerCreation.closeContactPicker()
|
||||
}
|
||||
|
||||
function setBackTintedButtonVisible(visible) {
|
||||
backTintedButton.visible = visible
|
||||
}
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
|
||||
|
@ -88,37 +93,17 @@ Rectangle {
|
|||
|
||||
anchors.fill: parent
|
||||
|
||||
TintedButton {
|
||||
id: backTintedButton
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
||||
Layout.leftMargin: 5
|
||||
Layout.preferredWidth: 30
|
||||
Layout.preferredHeight: 30
|
||||
|
||||
tintColor: JamiTheme.buttonTintedBlue
|
||||
normalPixmapSource: "qrc:/images/icons/ic_arrow_back_white_24dp.png"
|
||||
selectedPixmapSource: "qrc:/images/icons/ic_arrow_back_white_24dp.png"
|
||||
|
||||
onClicked: {
|
||||
callOverlayRect.backButtonIsClicked()
|
||||
}
|
||||
|
||||
onButtonEntered: {
|
||||
callOverlayRectMouseArea.entered()
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: jamiBestNameText
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
||||
Layout.preferredWidth: overlayUpperPartRect.width / 3
|
||||
Layout.preferredHeight: 50
|
||||
leftPadding: 16
|
||||
|
||||
font.pointSize: JamiTheme.textFontSize
|
||||
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
text: textMetricsjamiBestNameText.elidedText
|
||||
|
@ -127,35 +112,50 @@ Rectangle {
|
|||
TextMetrics {
|
||||
id: textMetricsjamiBestNameText
|
||||
font: jamiBestNameText.font
|
||||
text: bestName
|
||||
text: videoCallPageRect.bestName
|
||||
elideWidth: overlayUpperPartRect.width / 3
|
||||
elide: Qt.ElideMiddle
|
||||
elide: Qt.ElideRight
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
id: callTimerText
|
||||
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
Layout.preferredWidth: overlayUpperPartRect.width / 3
|
||||
Layout.preferredHeight: 50
|
||||
|
||||
Layout.preferredHeight: 48
|
||||
font.pointSize: JamiTheme.textFontSize
|
||||
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
horizontalAlignment: Text.AlignRight
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
text: textMetricscallTimerText.elidedText
|
||||
color: "white"
|
||||
|
||||
TextMetrics {
|
||||
id: textMetricscallTimerText
|
||||
font: callTimerText.font
|
||||
text: timeText
|
||||
elideWidth: overlayUpperPartRect.width / 3
|
||||
elide: Qt.ElideMiddle
|
||||
elide: Qt.ElideRight
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: recordingRect
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
height: 16
|
||||
width: 16
|
||||
radius: height / 2
|
||||
color: "red"
|
||||
|
||||
SequentialAnimation on color {
|
||||
loops: Animation.Infinite
|
||||
running: true
|
||||
ColorAnimation { from: "red"; to: "transparent"; duration: 500 }
|
||||
ColorAnimation { from: "transparent"; to: "red"; duration: 500 }
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
width: 8
|
||||
}
|
||||
}
|
||||
|
||||
color: "transparent"
|
||||
|
@ -215,8 +215,8 @@ Rectangle {
|
|||
anchors.bottomMargin: 10
|
||||
anchors.horizontalCenter: callOverlayRect.horizontalCenter
|
||||
|
||||
width: callOverlayRect.width / 3 * 2
|
||||
height: 60
|
||||
height: 56
|
||||
width: callOverlayRect.width
|
||||
opacity: 0
|
||||
|
||||
onChatButtonClicked: {
|
||||
|
@ -224,8 +224,6 @@ Rectangle {
|
|||
}
|
||||
|
||||
onAddToConferenceButtonClicked: {
|
||||
|
||||
|
||||
/*
|
||||
* Create contact picker - conference.
|
||||
*/
|
||||
|
@ -237,24 +235,6 @@ Rectangle {
|
|||
ContactPickerCreation.openContactPicker()
|
||||
}
|
||||
|
||||
onTransferCallButtonClicked: {
|
||||
|
||||
|
||||
/*
|
||||
* Create contact picker - sip transfer.
|
||||
*/
|
||||
ContactPickerCreation.createContactPickerObjects(
|
||||
ContactPicker.ContactPickerType.SIPTRANSFER,
|
||||
callOverlayRect)
|
||||
ContactPickerCreation.calculateCurrentGeo(
|
||||
callOverlayRect.width / 2, callOverlayRect.height / 2)
|
||||
ContactPickerCreation.openContactPicker()
|
||||
}
|
||||
|
||||
onButtonEntered: {
|
||||
callOverlayRectMouseArea.entered()
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "entered"
|
||||
|
@ -365,10 +345,6 @@ Rectangle {
|
|||
|
||||
color: "transparent"
|
||||
|
||||
onBestNameChanged: {
|
||||
ContactAdapter.setCalleeDisplayName(bestName)
|
||||
}
|
||||
|
||||
onWidthChanged: {
|
||||
ContactPickerCreation.calculateCurrentGeo(callOverlayRect.width / 2,
|
||||
callOverlayRect.height / 2)
|
||||
|
@ -378,4 +354,20 @@ Rectangle {
|
|||
ContactPickerCreation.calculateCurrentGeo(callOverlayRect.width / 2,
|
||||
callOverlayRect.height / 2)
|
||||
}
|
||||
|
||||
CallViewContextMenu {
|
||||
id: callViewContextMenu
|
||||
|
||||
onTransferCallButtonClicked: {
|
||||
/*
|
||||
* Create contact picker - sip transfer.
|
||||
*/
|
||||
ContactPickerCreation.createContactPickerObjects(
|
||||
ContactPicker.ContactPickerType.SIPTRANSFER,
|
||||
callOverlayRect)
|
||||
ContactPickerCreation.calculateCurrentGeo(
|
||||
callOverlayRect.width / 2, callOverlayRect.height / 2)
|
||||
ContactPickerCreation.openContactPicker()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
/*
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -26,286 +27,193 @@ import net.jami.Models 1.0
|
|||
import "../../commoncomponents"
|
||||
|
||||
Rectangle {
|
||||
id: callOverlayButtonGroupRect
|
||||
|
||||
id: root
|
||||
|
||||
/*
|
||||
* ButtonCounts here is to make sure that flow layout margin is calculated correctly,
|
||||
* since no other methods can make buttons at the layout center.
|
||||
*/
|
||||
property int buttonCounts: 9
|
||||
property int buttonPreferredSize: 30
|
||||
property int buttonPreferredSize: 24
|
||||
|
||||
signal buttonEntered
|
||||
signal chatButtonClicked
|
||||
signal addToConferenceButtonClicked
|
||||
signal transferCallButtonClicked
|
||||
|
||||
function setButtonStatus(isPaused, isAudioOnly, isAudioMuted, isVideoMuted, isRecording, isSIP, isConferenceCall) {
|
||||
noVideoButton.visible = !isAudioOnly
|
||||
addToConferenceButton.visible = !isSIP
|
||||
transferCallButton.visible = isSIP
|
||||
sipInputPanelButton.visible = isSIP
|
||||
|
||||
noMicButton.setChecked(isAudioMuted)
|
||||
noVideoButton.setChecked(isVideoMuted)
|
||||
recButton.setChecked(isRecording)
|
||||
holdButton.setChecked(isPaused)
|
||||
|
||||
holdButton.visible = !isConferenceCall
|
||||
noMicButton.checked = isAudioMuted
|
||||
noVideoButton.checked = isVideoMuted
|
||||
}
|
||||
|
||||
function calculateFlowMargin() {
|
||||
return (callOverlayButtonGroupRect.width - buttonCounts * buttonPreferredSize
|
||||
- callOverlayButtonGroupRectFlow.spacing * (buttonCounts - 1)) / 2
|
||||
}
|
||||
color: "transparent"
|
||||
z: 2
|
||||
|
||||
Flow {
|
||||
id: callOverlayButtonGroupRectFlow
|
||||
RowLayout {
|
||||
id: callOverlayButtonGroup
|
||||
|
||||
spacing: 8
|
||||
height: 56
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
|
||||
/*
|
||||
* Minus 1 is to make sure that button will not flick when doing flow layout.
|
||||
*/
|
||||
anchors.leftMargin: calculateFlowMargin(
|
||||
) < 0 ? 0 : calculateFlowMargin() - 1
|
||||
anchors.rightMargin: calculateFlowMargin(
|
||||
) < 0 ? 0 : calculateFlowMargin() - 1
|
||||
|
||||
spacing: 10
|
||||
|
||||
TintedButton {
|
||||
id: hangUpButton
|
||||
|
||||
width: buttonPreferredSize
|
||||
height: buttonPreferredSize
|
||||
|
||||
tintColor: JamiTheme.hangUpButtonTintedRed
|
||||
normalPixmapSource: "qrc:/images/icons/ic_close_white_24dp.png"
|
||||
selectedPixmapSource: "qrc:/images/icons/ic_close_white_24dp.png"
|
||||
|
||||
onButtonEntered: {
|
||||
callOverlayButtonGroupRect.buttonEntered()
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
CallAdapter.hangUpThisCall()
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (this.visible)
|
||||
buttonCounts++
|
||||
else
|
||||
buttonCounts--
|
||||
Item {
|
||||
Layout.preferredWidth: {
|
||||
// 6 is the number of button
|
||||
// If ~ 500px, go into wide mode
|
||||
(callOverlayButtonGroup.width < buttonPreferredSize * 12 - callOverlayButtonGroup.spacing * 6 + 300)?
|
||||
0 : callOverlayButtonGroup.width / 2 - buttonPreferredSize * 3 - callOverlayButtonGroup.spacing
|
||||
}
|
||||
}
|
||||
|
||||
TintedButton {
|
||||
id: holdButton
|
||||
|
||||
width: buttonPreferredSize
|
||||
height: buttonPreferredSize
|
||||
|
||||
tintColor: JamiTheme.buttonTintedBlue
|
||||
normalPixmapSource: "qrc:/images/icons/ic_pause_white_24dp.png"
|
||||
selectedPixmapSource: "qrc:/images/icons/ic_play_white_24dp.png"
|
||||
|
||||
onClicked: {
|
||||
CallAdapter.holdThisCallToggle()
|
||||
}
|
||||
|
||||
onButtonEntered: {
|
||||
callOverlayButtonGroupRect.buttonEntered()
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (this.visible)
|
||||
buttonCounts++
|
||||
else
|
||||
buttonCounts--
|
||||
}
|
||||
}
|
||||
|
||||
TintedButton {
|
||||
id: addToConferenceButton
|
||||
|
||||
width: buttonPreferredSize
|
||||
height: buttonPreferredSize
|
||||
|
||||
tintColor: JamiTheme.buttonTintedBlue
|
||||
normalPixmapSource: "qrc:/images/icons/ic_group_add_white_24dp.png"
|
||||
selectedPixmapSource: "qrc:/images/icons/ic_group_add_white_24dp.png"
|
||||
|
||||
onButtonEntered: {
|
||||
callOverlayButtonGroupRect.buttonEntered()
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
callOverlayButtonGroupRect.addToConferenceButtonClicked()
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (this.visible)
|
||||
buttonCounts++
|
||||
else
|
||||
buttonCounts--
|
||||
}
|
||||
}
|
||||
|
||||
TintedButton {
|
||||
id: transferCallButton
|
||||
|
||||
width: buttonPreferredSize
|
||||
height: buttonPreferredSize
|
||||
|
||||
tintColor: JamiTheme.buttonTintedBlue
|
||||
normalPixmapSource: "qrc:/images/icons/ic_call_transfer_white_24px.png"
|
||||
selectedPixmapSource: "qrc:/images/icons/ic_call_transfer_white_24px.png"
|
||||
|
||||
onButtonEntered: {
|
||||
callOverlayButtonGroupRect.buttonEntered()
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
callOverlayButtonGroupRect.transferCallButtonClicked()
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (this.visible)
|
||||
buttonCounts++
|
||||
else
|
||||
buttonCounts--
|
||||
}
|
||||
}
|
||||
|
||||
TintedButton {
|
||||
id: chatButton
|
||||
|
||||
width: buttonPreferredSize
|
||||
height: buttonPreferredSize
|
||||
|
||||
tintColor: JamiTheme.buttonTintedBlue
|
||||
normalPixmapSource: "qrc:/images/icons/ic_chat_white_24dp.png"
|
||||
selectedPixmapSource: "qrc:/images/icons/ic_chat_white_24dp.png"
|
||||
|
||||
onClicked: {
|
||||
callOverlayButtonGroupRect.chatButtonClicked()
|
||||
}
|
||||
|
||||
onButtonEntered: {
|
||||
callOverlayButtonGroupRect.buttonEntered()
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (this.visible)
|
||||
buttonCounts++
|
||||
else
|
||||
buttonCounts--
|
||||
}
|
||||
}
|
||||
|
||||
TintedButton {
|
||||
HoverableButton {
|
||||
id: noMicButton
|
||||
|
||||
width: buttonPreferredSize
|
||||
height: buttonPreferredSize
|
||||
Layout.preferredWidth: buttonPreferredSize * 2
|
||||
Layout.preferredHeight: buttonPreferredSize * 2
|
||||
|
||||
tintColor: JamiTheme.buttonTintedBlue
|
||||
normalPixmapSource: "qrc:/images/icons/ic_mic_white_24dp.png"
|
||||
selectedPixmapSource: "qrc:/images/icons/ic_mic_off_white_24dp.png"
|
||||
backgroundColor: Qt.rgba(0, 0, 0, 0.75)
|
||||
onEnterColor: Qt.rgba(0, 0, 0, 0.6)
|
||||
onPressColor: Qt.rgba(0, 0, 0, 0.5)
|
||||
onReleaseColor: Qt.rgba(0, 0, 0, 0.6)
|
||||
onExitColor: Qt.rgba(0, 0, 0, 0.75)
|
||||
|
||||
buttonImageHeight: buttonPreferredSize
|
||||
buttonImageWidth: buttonPreferredSize
|
||||
baseImage: "qrc:/images/icons/ic_mic_white_24dp.png"
|
||||
checkedImage: "qrc:/images/icons/ic_mic_off_white_24dp.png"
|
||||
baseColor: "white"
|
||||
checkedColor: JamiTheme.declineButtonPressedRed
|
||||
radius: 30
|
||||
|
||||
onClicked: {
|
||||
CallAdapter.muteThisCallToggle()
|
||||
}
|
||||
}
|
||||
|
||||
onButtonEntered: {
|
||||
callOverlayButtonGroupRect.buttonEntered()
|
||||
}
|
||||
HoverableButton {
|
||||
id: hangUpButton
|
||||
|
||||
onVisibleChanged: {
|
||||
if (this.visible)
|
||||
buttonCounts++
|
||||
else
|
||||
buttonCounts--
|
||||
Layout.preferredWidth: buttonPreferredSize * 2
|
||||
Layout.preferredHeight: buttonPreferredSize * 2
|
||||
|
||||
backgroundColor: JamiTheme.declineButtonRed
|
||||
onEnterColor: JamiTheme.declineButtonHoverRed
|
||||
onPressColor: JamiTheme.declineButtonPressedRed
|
||||
onReleaseColor: JamiTheme.declineButtonHoverRed
|
||||
onExitColor: JamiTheme.declineButtonRed
|
||||
|
||||
buttonImageHeight: buttonPreferredSize
|
||||
buttonImageWidth: buttonPreferredSize
|
||||
source: "qrc:/images/icons/ic_call_end_white_24px.svg"
|
||||
color: "white"
|
||||
radius: 30
|
||||
|
||||
onClicked: {
|
||||
CallAdapter.hangUpThisCall()
|
||||
}
|
||||
}
|
||||
|
||||
TintedButton {
|
||||
HoverableButton {
|
||||
id: noVideoButton
|
||||
|
||||
width: buttonPreferredSize
|
||||
height: buttonPreferredSize
|
||||
Layout.preferredWidth: buttonPreferredSize * 2
|
||||
Layout.preferredHeight: buttonPreferredSize * 2
|
||||
|
||||
tintColor: JamiTheme.buttonTintedBlue
|
||||
normalPixmapSource: "qrc:/images/icons/ic_videocam_white.png"
|
||||
selectedPixmapSource: "qrc:/images/icons/ic_videocam_off_white_24dp.png"
|
||||
backgroundColor: Qt.rgba(0, 0, 0, 0.75)
|
||||
onEnterColor: Qt.rgba(0, 0, 0, 0.6)
|
||||
onPressColor: Qt.rgba(0, 0, 0, 0.5)
|
||||
onReleaseColor: Qt.rgba(0, 0, 0, 0.6)
|
||||
onExitColor: Qt.rgba(0, 0, 0, 0.75)
|
||||
|
||||
onButtonEntered: {
|
||||
callOverlayButtonGroupRect.buttonEntered()
|
||||
}
|
||||
buttonImageHeight: buttonPreferredSize
|
||||
buttonImageWidth: buttonPreferredSize
|
||||
baseImage: "qrc:/images/icons/ic_videocam_white.png"
|
||||
checkedImage: "qrc:/images/icons/ic_videocam_off_white_24dp.png"
|
||||
baseColor: "white"
|
||||
checkedColor: JamiTheme.declineButtonPressedRed
|
||||
radius: 30
|
||||
|
||||
onClicked: {
|
||||
CallAdapter.videoPauseThisCallToggle()
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (this.visible)
|
||||
buttonCounts++
|
||||
else
|
||||
buttonCounts--
|
||||
}
|
||||
}
|
||||
|
||||
TintedButton {
|
||||
id: recButton
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
width: buttonPreferredSize
|
||||
height: buttonPreferredSize
|
||||
HoverableButton {
|
||||
id: addToConferenceButton
|
||||
|
||||
tintColor: JamiTheme.buttonTintedBlue
|
||||
normalPixmapSource: "qrc:/images/icons/ic_voicemail_white_24dp_2x.png"
|
||||
selectedPixmapSource: "qrc:/images/icons/ic_voicemail_white_24dp_2x.png"
|
||||
Layout.preferredWidth: buttonPreferredSize * 2
|
||||
Layout.preferredHeight: buttonPreferredSize * 2
|
||||
|
||||
onButtonEntered: {
|
||||
callOverlayButtonGroupRect.buttonEntered()
|
||||
}
|
||||
backgroundColor: Qt.rgba(0, 0, 0, 0.75)
|
||||
onEnterColor: Qt.rgba(0, 0, 0, 0.6)
|
||||
onPressColor: Qt.rgba(0, 0, 0, 0.5)
|
||||
onReleaseColor: Qt.rgba(0, 0, 0, 0.6)
|
||||
onExitColor: Qt.rgba(0, 0, 0, 0.75)
|
||||
|
||||
buttonImageHeight: buttonPreferredSize
|
||||
buttonImageWidth: buttonPreferredSize
|
||||
color: "white"
|
||||
source: "qrc:/images/icons/ic_group_add_white_24dp.png"
|
||||
radius: 30
|
||||
|
||||
onClicked: {
|
||||
CallAdapter.recordThisCallToggle()
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (this.visible)
|
||||
buttonCounts++
|
||||
else
|
||||
buttonCounts--
|
||||
root.addToConferenceButtonClicked()
|
||||
}
|
||||
}
|
||||
|
||||
TintedButton {
|
||||
id: sipInputPanelButton
|
||||
HoverableButton {
|
||||
id: chatButton
|
||||
|
||||
width: buttonPreferredSize
|
||||
height: buttonPreferredSize
|
||||
Layout.preferredWidth: buttonPreferredSize * 2
|
||||
Layout.preferredHeight: buttonPreferredSize * 2
|
||||
|
||||
tintColor: JamiTheme.buttonTintedBlue
|
||||
normalPixmapSource: "qrc:/images/icons/icon-keypad-24-2x.png"
|
||||
selectedPixmapSource: "qrc:/images/icons/icon-keypad-24-2x.png"
|
||||
backgroundColor: Qt.rgba(0, 0, 0, 0.75)
|
||||
onEnterColor: Qt.rgba(0, 0, 0, 0.6)
|
||||
onPressColor: Qt.rgba(0, 0, 0, 0.5)
|
||||
onReleaseColor: Qt.rgba(0, 0, 0, 0.6)
|
||||
onExitColor: Qt.rgba(0, 0, 0, 0.75)
|
||||
|
||||
onButtonEntered: {
|
||||
callOverlayButtonGroupRect.buttonEntered()
|
||||
}
|
||||
buttonImageHeight: buttonPreferredSize
|
||||
buttonImageWidth: buttonPreferredSize
|
||||
color: "white"
|
||||
source: "qrc:/images/icons/ic_chat_white_24dp.png"
|
||||
radius: 30
|
||||
|
||||
onVisibleChanged: {
|
||||
if (this.visible)
|
||||
buttonCounts++
|
||||
else
|
||||
buttonCounts--
|
||||
onClicked: {
|
||||
root.chatButtonClicked()
|
||||
}
|
||||
}
|
||||
|
||||
HoverableButton {
|
||||
id: optionsButton
|
||||
|
||||
Layout.preferredWidth: buttonPreferredSize * 2
|
||||
Layout.preferredHeight: buttonPreferredSize * 2
|
||||
|
||||
backgroundColor: Qt.rgba(0, 0, 0, 0.75)
|
||||
onEnterColor: Qt.rgba(0, 0, 0, 0.6)
|
||||
onPressColor: Qt.rgba(0, 0, 0, 0.5)
|
||||
onReleaseColor: Qt.rgba(0, 0, 0, 0.6)
|
||||
onExitColor: Qt.rgba(0, 0, 0, 0.75)
|
||||
|
||||
buttonImageHeight: buttonPreferredSize
|
||||
buttonImageWidth: buttonPreferredSize
|
||||
source: "qrc:/images/icons/more_vert-24px.svg"
|
||||
radius: 30
|
||||
|
||||
onClicked: {
|
||||
var rectPos = mapToItem(callStackViewWindow, optionsButton.x, optionsButton.y)
|
||||
callViewContextMenu.activate()
|
||||
callViewContextMenu.x = rectPos.x + optionsButton.width/2 - callViewContextMenu.width/2
|
||||
callViewContextMenu.y = rectPos.y - 12 - callViewContextMenu.height
|
||||
}
|
||||
}
|
||||
|
||||
Item { Layout.preferredWidth: 8 }
|
||||
}
|
||||
|
||||
color: "transparent"
|
||||
}
|
||||
|
|
|
@ -44,9 +44,6 @@ Rectangle {
|
|||
property string responsibleConvUid: ""
|
||||
property string responsibleAccountId: ""
|
||||
|
||||
signal outgoingCallPageBackButtonIsClicked
|
||||
signal callPageBackButtonIsClicked
|
||||
|
||||
function needToCloseInCallConversationAndPotentialWindow() {
|
||||
audioCallPage.closeInCallConversation()
|
||||
videoCallPage.closeInCallConversation()
|
||||
|
@ -58,13 +55,12 @@ Rectangle {
|
|||
audioCallPage.closeContextMenuAndRelatedWindows()
|
||||
|
||||
VideoCallFullScreenWindowContainerCreation.closeVideoCallFullScreenWindowContainer()
|
||||
videoCallPage.setCallOverlayBackButtonVisible(true)
|
||||
videoCallPage.closeContextMenuAndRelatedWindows()
|
||||
}
|
||||
|
||||
function setCorrspondingMessageWebView(webViewId) {
|
||||
audioCallPage.setAudioCallPageCorrspondingMessageWebView(webViewId)
|
||||
videoCallPage.setVideoCallPageCorrspondingMessageWebView(webViewId)
|
||||
function setLinkedWebview(webViewId) {
|
||||
audioCallPage.setLinkedWebview(webViewId)
|
||||
videoCallPage.setLinkedWebview(webViewId)
|
||||
}
|
||||
|
||||
function updateCorrspondingUI() {
|
||||
|
@ -172,10 +168,6 @@ Rectangle {
|
|||
id: audioCallPage
|
||||
|
||||
property int stackNumber: 0
|
||||
|
||||
onAudioCallPageBackButtonIsClicked: {
|
||||
callStackViewWindow.callPageBackButtonIsClicked()
|
||||
}
|
||||
}
|
||||
|
||||
OutgoingCallPage {
|
||||
|
@ -186,32 +178,24 @@ Rectangle {
|
|||
onCallCancelButtonIsClicked: {
|
||||
CallAdapter.hangUpACall(responsibleAccountId, responsibleConvUid)
|
||||
}
|
||||
|
||||
onBackButtonIsClicked: {
|
||||
callStackViewWindow.outgoingCallPageBackButtonIsClicked()
|
||||
}
|
||||
}
|
||||
|
||||
VideoCallPage {
|
||||
id: videoCallPage
|
||||
|
||||
property int stackNumber: 2
|
||||
|
||||
onVideoCallPageBackButtonIsClicked: {
|
||||
callStackViewWindow.callPageBackButtonIsClicked()
|
||||
}
|
||||
property bool isFullscreen: false
|
||||
|
||||
onNeedToShowInFullScreen: {
|
||||
isFullscreen = !isFullscreen
|
||||
VideoCallFullScreenWindowContainerCreation.createvideoCallFullScreenWindowContainerObject()
|
||||
|
||||
if (!VideoCallFullScreenWindowContainerCreation.checkIfVisible()) {
|
||||
VideoCallFullScreenWindowContainerCreation.setAsContainerChild(
|
||||
videoCallPage)
|
||||
videoCallPage.setCallOverlayBackButtonVisible(false)
|
||||
VideoCallFullScreenWindowContainerCreation.showVideoCallFullScreenWindowContainer()
|
||||
} else {
|
||||
videoCallPage.parent = callStackMainView
|
||||
videoCallPage.setCallOverlayBackButtonVisible(true)
|
||||
VideoCallFullScreenWindowContainerCreation.closeVideoCallFullScreenWindowContainer()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -18,44 +18,45 @@
|
|||
*/
|
||||
import QtQuick 2.14
|
||||
import QtQuick.Controls 2.14
|
||||
import QtGraphicalEffects 1.12
|
||||
import net.jami.Models 1.0
|
||||
|
||||
import "../../commoncomponents"
|
||||
|
||||
import "../js/videodevicecontextmenuitemcreation.js" as VideoDeviceContextMenuItemCreation
|
||||
import "../js/selectscreenwindowcreation.js" as SelectScreenWindowCreation
|
||||
import "../js/screenrubberbandcreation.js" as ScreenRubberBandCreation
|
||||
|
||||
Menu {
|
||||
id: contextMenu
|
||||
|
||||
property string responsibleAccountId: ""
|
||||
property string responsibleConvUid: ""
|
||||
id: root
|
||||
|
||||
property int generalMenuSeparatorCount: 0
|
||||
property int commonBorderWidth: 2
|
||||
property int commonBorderWidth: 1
|
||||
font.pointSize: JamiTheme.textFontSize+3
|
||||
|
||||
signal fullScreenNeeded
|
||||
property bool isSIP: false
|
||||
property bool isPaused: false
|
||||
property bool isAudioOnly: false
|
||||
property bool isRecording: false
|
||||
|
||||
signal transferCallButtonClicked
|
||||
|
||||
function activate() {
|
||||
var deviceContextMenuInfoMap = AvAdapter.populateVideoDeviceContextMenuItem()
|
||||
|
||||
|
||||
/*
|
||||
* Somehow, the map size is undefined, so use this instead.
|
||||
*/
|
||||
var mapSize = deviceContextMenuInfoMap["size"]
|
||||
|
||||
var count = 1
|
||||
var count = 2
|
||||
for (var deviceName in deviceContextMenuInfoMap) {
|
||||
if (deviceName === "size")
|
||||
if (deviceName === "size" || root.isAudioOnly)
|
||||
continue
|
||||
if (videoDeviceItem.itemName === "No video device") {
|
||||
videoDeviceItem.checkable = true
|
||||
videoDeviceItem.itemName = deviceName
|
||||
videoDeviceItem.checked = deviceContextMenuInfoMap[deviceName]
|
||||
if (count === mapSize)
|
||||
contextMenu.open()
|
||||
root.open()
|
||||
} else {
|
||||
VideoDeviceContextMenuItemCreation.createVideoDeviceContextMenuItemObjects(
|
||||
deviceName, deviceContextMenuInfoMap[deviceName],
|
||||
|
@ -63,14 +64,18 @@ Menu {
|
|||
}
|
||||
count++
|
||||
}
|
||||
root.open()
|
||||
}
|
||||
|
||||
function closePotentialWindows() {
|
||||
SelectScreenWindowCreation.destorySelectScreenWindow()
|
||||
ScreenRubberBandCreation.destoryScreenRubberBandWindow()
|
||||
Component.onCompleted: {
|
||||
VideoDeviceContextMenuItemCreation.setVideoContextMenuObject(root)
|
||||
}
|
||||
|
||||
implicitWidth: 200
|
||||
|
||||
onClosed: {
|
||||
videoDeviceItem.itemName = "No video device"
|
||||
VideoDeviceContextMenuItemCreation.removeCreatedItems()
|
||||
}
|
||||
|
||||
JamiFileDialog {
|
||||
id: jamiFileDialog
|
||||
|
@ -78,32 +83,112 @@ Menu {
|
|||
mode: JamiFileDialog.Mode.OpenFile
|
||||
|
||||
onAccepted: {
|
||||
var filePath = jamiFileDialog.file
|
||||
|
||||
|
||||
/*
|
||||
* No need to trim file:///.
|
||||
*/
|
||||
AvAdapter.shareFile(filePath)
|
||||
// No need to trim file:///.
|
||||
AvAdapter.shareFile(jamiFileDialog.file)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* All GeneralMenuItems should remain the same width / height.
|
||||
* The first videoDeviceItem is to make sure the border is correct.
|
||||
*/
|
||||
VideoCallPageContextMenuDeviceItem {
|
||||
id: videoDeviceItem
|
||||
GeneralMenuItem {
|
||||
id: holdCallButton
|
||||
|
||||
topBorderWidth: commonBorderWidth
|
||||
contextMenuPreferredWidth: contextMenu.implicitWidth
|
||||
visible: isSIP
|
||||
height: isSIP? undefined : 0
|
||||
|
||||
itemName: isPaused? qsTr("Resume call") : qsTr("Hold call")
|
||||
iconSource: isPaused? "qrc:/images/icons/play_circle_outline-24px.svg" : "qrc:/images/icons/pause_circle_outline-24px.svg"
|
||||
leftBorderWidth: commonBorderWidth
|
||||
rightBorderWidth: commonBorderWidth
|
||||
|
||||
onClicked: {
|
||||
CallAdapter.holdThisCallToggle()
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
|
||||
GeneralMenuItem {
|
||||
id: transferCallButton
|
||||
|
||||
visible: isSIP
|
||||
height: isSIP? undefined : 0
|
||||
|
||||
itemName: qsTr("Transfer call")
|
||||
iconSource: "qrc:/images/icons/phone_forwarded-24px.svg"
|
||||
leftBorderWidth: commonBorderWidth
|
||||
rightBorderWidth: commonBorderWidth
|
||||
|
||||
onClicked: {
|
||||
root.transferCallButtonClicked()
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
|
||||
GeneralMenuSeparator {
|
||||
preferredWidth: videoDeviceItem.preferredWidth
|
||||
preferredWidth: startRecordingItem.preferredWidth
|
||||
preferredHeight: commonBorderWidth
|
||||
|
||||
visible: isSIP
|
||||
height: isSIP? undefined : 0
|
||||
|
||||
Component.onCompleted: {
|
||||
generalMenuSeparatorCount++
|
||||
}
|
||||
}
|
||||
|
||||
GeneralMenuItem {
|
||||
id: startRecordingItem
|
||||
|
||||
itemName: isRecording? qsTr("Stop recording") : qsTr("Start recording")
|
||||
iconSource: "qrc:/images/icons/ic_video_call_24px.svg"
|
||||
leftBorderWidth: commonBorderWidth
|
||||
rightBorderWidth: commonBorderWidth
|
||||
|
||||
onClicked: {
|
||||
root.close()
|
||||
CallAdapter.recordThisCallToggle()
|
||||
}
|
||||
}
|
||||
|
||||
GeneralMenuItem {
|
||||
id: fullScreenItem
|
||||
|
||||
itemName: videoCallPage.isFullscreen ? qsTr("Exit full screen") : qsTr(
|
||||
"Full screen mode")
|
||||
iconSource: videoCallPage.isFullscreen ? "qrc:/images/icons/close_fullscreen-24px.svg" : "qrc:/images/icons/open_in_full-24px.svg"
|
||||
leftBorderWidth: commonBorderWidth
|
||||
rightBorderWidth: commonBorderWidth
|
||||
|
||||
onClicked: {
|
||||
root.close()
|
||||
videoCallPageRect.needToShowInFullScreen()
|
||||
}
|
||||
}
|
||||
|
||||
GeneralMenuSeparator {
|
||||
preferredWidth: startRecordingItem.preferredWidth
|
||||
preferredHeight: commonBorderWidth
|
||||
|
||||
Component.onCompleted: {
|
||||
generalMenuSeparatorCount++
|
||||
}
|
||||
}
|
||||
|
||||
VideoCallPageContextMenuDeviceItem {
|
||||
id: videoDeviceItem
|
||||
visible: !isAudioOnly
|
||||
height: !isAudioOnly? undefined : 0
|
||||
|
||||
contextMenuPreferredWidth: root.implicitWidth
|
||||
}
|
||||
|
||||
GeneralMenuSeparator {
|
||||
preferredWidth: startRecordingItem.preferredWidth
|
||||
preferredHeight: commonBorderWidth
|
||||
visible: !isAudioOnly
|
||||
height: !isAudioOnly? undefined : 0
|
||||
|
||||
Component.onCompleted: {
|
||||
generalMenuSeparatorCount++
|
||||
}
|
||||
|
@ -113,11 +198,14 @@ Menu {
|
|||
id: shareEntireScreenItem
|
||||
|
||||
itemName: qsTr("Share entire screen")
|
||||
iconSource: "qrc:/images/icons/screen_share-24px.svg"
|
||||
leftBorderWidth: commonBorderWidth
|
||||
rightBorderWidth: commonBorderWidth
|
||||
visible: !isAudioOnly
|
||||
height: !isAudioOnly? undefined : 0
|
||||
|
||||
onClicked: {
|
||||
contextMenu.close()
|
||||
root.close()
|
||||
if (Qt.application.screens.length === 1) {
|
||||
AvAdapter.shareEntireScreen(0)
|
||||
} else {
|
||||
|
@ -131,11 +219,14 @@ Menu {
|
|||
id: shareScreenAreaItem
|
||||
|
||||
itemName: qsTr("Share screen area")
|
||||
iconSource: "qrc:/images/icons/screen_share-24px.svg"
|
||||
leftBorderWidth: commonBorderWidth
|
||||
rightBorderWidth: commonBorderWidth
|
||||
visible: !isAudioOnly
|
||||
height: !isAudioOnly? undefined : 0
|
||||
|
||||
onClicked: {
|
||||
contextMenu.close()
|
||||
root.close()
|
||||
if (Qt.application.screens.length === 1) {
|
||||
ScreenRubberBandCreation.createScreenRubberBandWindowObject(
|
||||
null, 0)
|
||||
|
@ -151,59 +242,56 @@ Menu {
|
|||
id: shareFileItem
|
||||
|
||||
itemName: qsTr("Share file")
|
||||
iconSource: "qrc:/images/icons/insert_photo-24px.svg"
|
||||
leftBorderWidth: commonBorderWidth
|
||||
rightBorderWidth: commonBorderWidth
|
||||
visible: !isAudioOnly
|
||||
height: !isAudioOnly? undefined : 0
|
||||
|
||||
onClicked: {
|
||||
contextMenu.close()
|
||||
root.close()
|
||||
jamiFileDialog.open()
|
||||
}
|
||||
}
|
||||
|
||||
GeneralMenuSeparator {
|
||||
preferredWidth: videoDeviceItem.preferredWidth
|
||||
preferredHeight: commonBorderWidth
|
||||
/* TODO: In the future we want to implement this
|
||||
|
||||
Component.onCompleted: {
|
||||
generalMenuSeparatorCount++
|
||||
GeneralMenuItem {
|
||||
id: advancedInfosItem
|
||||
|
||||
itemName: qsTr("Advanced informations")
|
||||
iconSource: "qrc:/images/icons/info-24px.svg"
|
||||
leftBorderWidth: commonBorderWidth
|
||||
rightBorderWidth: commonBorderWidth
|
||||
|
||||
onClicked: {
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
|
||||
GeneralMenuItem {
|
||||
id: fullScreenItem
|
||||
id: pluginItem
|
||||
|
||||
property bool isFullScreen: false
|
||||
|
||||
itemName: isFullScreen ? qsTr("Exit full screen") : qsTr(
|
||||
"Full screen mode")
|
||||
iconSource: isFullScreen ? "qrc:/images/icons/ic_exit_full_screen_black.png" : "qrc:/images/icons/ic_full_screen_black.png"
|
||||
itemName: qsTr("Toggle plugin")
|
||||
iconSource: "qrc:/images/icons/extension_24dp.svg"
|
||||
leftBorderWidth: commonBorderWidth
|
||||
rightBorderWidth: commonBorderWidth
|
||||
bottomBorderWidth: commonBorderWidth
|
||||
|
||||
onClicked: {
|
||||
contextMenu.close()
|
||||
contextMenu.fullScreenNeeded()
|
||||
isFullScreen = !isFullScreen
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
|
||||
onClosed: {
|
||||
videoDeviceItem.itemName = "No video device"
|
||||
VideoDeviceContextMenuItemCreation.removeCreatedItems()
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
VideoDeviceContextMenuItemCreation.setVideoContextMenuObject(
|
||||
contextMenu)
|
||||
}
|
||||
}*/
|
||||
|
||||
background: Rectangle {
|
||||
implicitWidth: contextMenu.implicitWidth
|
||||
implicitHeight: videoDeviceItem.preferredHeight
|
||||
* (contextMenu.count - generalMenuSeparatorCount)
|
||||
implicitWidth: startRecordingItem.preferredWidth
|
||||
implicitHeight: startRecordingItem.preferredHeight
|
||||
* (root.count
|
||||
- (isSIP? 0 : 2)
|
||||
- (isAudioOnly? 6 : 0)
|
||||
- generalMenuSeparatorCount)
|
||||
|
||||
border.width: commonBorderWidth
|
||||
border.color: JamiTheme.tabbarBorderColor
|
||||
}
|
||||
}
|
||||
|
|
@ -34,7 +34,6 @@ Rectangle {
|
|||
property string bestId: "Best Id"
|
||||
|
||||
signal callCancelButtonIsClicked
|
||||
signal backButtonIsClicked
|
||||
|
||||
function updateUI(accountId, convUid) {
|
||||
contactImgSource = "data:image/png;base64," + ClientWrapper.utilsAdaptor.getContactImageString(
|
||||
|
@ -58,26 +57,6 @@ Rectangle {
|
|||
acceptedButtons: Qt.RightButton
|
||||
}
|
||||
|
||||
TintedButton {
|
||||
id: backTintedButton
|
||||
|
||||
anchors.top: outgoingCallPageRect.top
|
||||
anchors.topMargin: 10
|
||||
anchors.left: outgoingCallPageRect.left
|
||||
anchors.leftMargin: 5
|
||||
|
||||
width: 30
|
||||
height: 30
|
||||
|
||||
tintColor: JamiTheme.buttonTintedBlue
|
||||
normalPixmapSource: "qrc:/images/icons/ic_arrow_back_white_24dp.png"
|
||||
selectedPixmapSource: "qrc:/images/icons/ic_arrow_back_white_24dp.png"
|
||||
|
||||
onClicked: {
|
||||
outgoingCallPageRect.backButtonIsClicked()
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: outgoingCallPageRectColumnLayout
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
/*
|
||||
* Copyright (C) 2020 by Savoir-faire Linux
|
||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -32,12 +33,12 @@ Rectangle {
|
|||
property string bestId: "Best Id"
|
||||
property variant clickPos: "1,1"
|
||||
property int previewMargin: 15
|
||||
property int previewMarginY: previewMargin + 56
|
||||
property int previewToX: 0
|
||||
property int previewToY: 0
|
||||
|
||||
property var corrspondingMessageWebView: null
|
||||
property var linkedWebview: null
|
||||
|
||||
signal videoCallPageBackButtonIsClicked
|
||||
signal needToShowInFullScreen
|
||||
|
||||
function updateUI(accountId, convUid) {
|
||||
|
@ -51,27 +52,25 @@ Rectangle {
|
|||
distantRenderer.setRendererId(id)
|
||||
}
|
||||
|
||||
function setVideoCallPageCorrspondingMessageWebView(webViewId) {
|
||||
corrspondingMessageWebView = webViewId
|
||||
corrspondingMessageWebView.needToHideConversationInCall.disconnect(
|
||||
function setLinkedWebview(webViewId) {
|
||||
linkedWebview = webViewId
|
||||
linkedWebview.needToHideConversationInCall.disconnect(
|
||||
closeInCallConversation)
|
||||
corrspondingMessageWebView.needToHideConversationInCall.connect(
|
||||
linkedWebview.needToHideConversationInCall.connect(
|
||||
closeInCallConversation)
|
||||
}
|
||||
|
||||
function closeInCallConversation() {
|
||||
if (inVideoCallMessageWebViewStack.visible) {
|
||||
corrspondingMessageWebView.resetMessagingHeaderBackButtonSource(
|
||||
linkedWebview.resetMessagingHeaderBackButtonSource(
|
||||
true)
|
||||
corrspondingMessageWebView.setMessagingHeaderButtonsVisible(true)
|
||||
linkedWebview.setMessagingHeaderButtonsVisible(true)
|
||||
inVideoCallMessageWebViewStack.visible = false
|
||||
inVideoCallMessageWebViewStack.clear()
|
||||
}
|
||||
}
|
||||
|
||||
function closeContextMenuAndRelatedWindows() {
|
||||
videoCallPageContextMenu.closePotentialWindows()
|
||||
videoCallPageContextMenu.close()
|
||||
videoCallOverlay.closePotentialContactPicker()
|
||||
}
|
||||
|
||||
|
@ -99,7 +98,7 @@ Rectangle {
|
|||
return videoCallPageMainRect.width - previewRenderer.width - previewMargin
|
||||
})
|
||||
previewToY = Qt.binding(function () {
|
||||
return videoCallPageMainRect.height - previewRenderer.height - previewMargin
|
||||
return videoCallPageMainRect.height - previewRenderer.height - previewMarginY
|
||||
})
|
||||
} else {
|
||||
|
||||
|
@ -110,7 +109,7 @@ Rectangle {
|
|||
previewToX = Qt.binding(function () {
|
||||
return videoCallPageMainRect.width - previewRenderer.width - previewMargin
|
||||
})
|
||||
previewToY = previewMargin
|
||||
previewToY = previewMarginY
|
||||
}
|
||||
} else {
|
||||
if (previewRendererCenter.y >= distantRendererCenter.y) {
|
||||
|
@ -121,7 +120,7 @@ Rectangle {
|
|||
*/
|
||||
previewToX = previewMargin
|
||||
previewToY = Qt.binding(function () {
|
||||
return videoCallPageMainRect.height - previewRenderer.height - previewMargin
|
||||
return videoCallPageMainRect.height - previewRenderer.height - previewMarginY
|
||||
})
|
||||
} else {
|
||||
|
||||
|
@ -130,16 +129,12 @@ Rectangle {
|
|||
* Top left.
|
||||
*/
|
||||
previewToX = previewMargin
|
||||
previewToY = previewMargin
|
||||
previewToY = previewMarginY
|
||||
}
|
||||
}
|
||||
previewRenderer.state = "geoChanging"
|
||||
}
|
||||
|
||||
function setCallOverlayBackButtonVisible(visible) {
|
||||
videoCallOverlay.setBackTintedButtonVisible(visible)
|
||||
}
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
SplitView {
|
||||
|
@ -155,182 +150,182 @@ Rectangle {
|
|||
color: SplitHandle.pressed ? JamiTheme.pressColor : (SplitHandle.hovered ? JamiTheme.hoverColor : JamiTheme.tabbarBorderColor)
|
||||
}
|
||||
|
||||
|
||||
Rectangle {
|
||||
id: videoCallPageMainRect
|
||||
|
||||
SplitView.preferredHeight: (videoCallPageRect.height / 3) * 2
|
||||
SplitView.minimumHeight: videoCallPageRect.height / 2 + 20
|
||||
SplitView.fillWidth: true
|
||||
|
||||
CallOverlay {
|
||||
id: videoCallOverlay
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
propagateComposedEvents: true
|
||||
|
||||
Connections {
|
||||
target: CallAdapter
|
||||
acceptedButtons: Qt.LeftButton
|
||||
|
||||
function onUpdateTimeText(time) {
|
||||
videoCallOverlay.timeText = time
|
||||
}
|
||||
|
||||
function onUpdateOverlay(isPaused, isAudioOnly, isAudioMuted, isVideoMuted, isRecording, isSIP, isConferenceCall, bestName) {
|
||||
videoCallOverlay.showOnHoldImage(isPaused)
|
||||
videoCallOverlay.updateButtonStatus(isPaused,
|
||||
isAudioOnly,
|
||||
isAudioMuted,
|
||||
isVideoMuted,
|
||||
isRecording, isSIP,
|
||||
isConferenceCall)
|
||||
videoCallOverlay.bestName = bestName
|
||||
}
|
||||
|
||||
function onShowOnHoldLabel(isPaused) {
|
||||
videoCallOverlay.showOnHoldImage(isPaused)
|
||||
}
|
||||
onDoubleClicked: {
|
||||
needToShowInFullScreen()
|
||||
}
|
||||
|
||||
onBackButtonIsClicked: {
|
||||
if (inVideoCallMessageWebViewStack.visible) {
|
||||
corrspondingMessageWebView.resetMessagingHeaderBackButtonSource(
|
||||
true)
|
||||
corrspondingMessageWebView.setMessagingHeaderButtonsVisible(
|
||||
true)
|
||||
inVideoCallMessageWebViewStack.visible = false
|
||||
inVideoCallMessageWebViewStack.clear()
|
||||
}
|
||||
videoCallPageRect.videoCallPageBackButtonIsClicked()
|
||||
}
|
||||
CallOverlay {
|
||||
id: videoCallOverlay
|
||||
|
||||
onOverlayChatButtonClicked: {
|
||||
if (inVideoCallMessageWebViewStack.visible) {
|
||||
corrspondingMessageWebView.resetMessagingHeaderBackButtonSource(
|
||||
true)
|
||||
corrspondingMessageWebView.setMessagingHeaderButtonsVisible(
|
||||
true)
|
||||
inVideoCallMessageWebViewStack.visible = false
|
||||
inVideoCallMessageWebViewStack.clear()
|
||||
} else {
|
||||
corrspondingMessageWebView.resetMessagingHeaderBackButtonSource(
|
||||
false)
|
||||
corrspondingMessageWebView.setMessagingHeaderButtonsVisible(
|
||||
false)
|
||||
inVideoCallMessageWebViewStack.visible = true
|
||||
inVideoCallMessageWebViewStack.push(
|
||||
corrspondingMessageWebView)
|
||||
}
|
||||
}
|
||||
}
|
||||
anchors.fill: parent
|
||||
|
||||
DistantRenderer {
|
||||
id: distantRenderer
|
||||
Connections {
|
||||
target: CallAdapter
|
||||
|
||||
anchors.centerIn: videoCallPageMainRect
|
||||
z: -1
|
||||
function onUpdateTimeText(time) {
|
||||
videoCallOverlay.timeText = time
|
||||
videoCallOverlay.setRecording(CallAdapter.isRecordingThisCall())
|
||||
}
|
||||
|
||||
width: videoCallPageMainRect.width
|
||||
height: videoCallPageMainRect.height
|
||||
}
|
||||
function onUpdateOverlay(isPaused, isAudioOnly, isAudioMuted, isVideoMuted, isRecording, isSIP, isConferenceCall, bestName) {
|
||||
videoCallOverlay.showOnHoldImage(isPaused)
|
||||
videoCallOverlay.updateButtonStatus(isPaused,
|
||||
isAudioOnly,
|
||||
isAudioMuted,
|
||||
isVideoMuted,
|
||||
isRecording, isSIP,
|
||||
isConferenceCall)
|
||||
videoCallPageRect.bestName = bestName
|
||||
}
|
||||
|
||||
VideoCallPreviewRenderer {
|
||||
id: previewRenderer
|
||||
|
||||
|
||||
/*
|
||||
* Property is used in the {} expression for height (extra dependency),
|
||||
* it will not affect the true height expression, since expression
|
||||
* at last will be taken only, but it will force the height to update
|
||||
* and reevaluate getPreviewImageScalingFactor().
|
||||
*/
|
||||
property int previewImageScalingFactorUpdated: 0
|
||||
|
||||
Connections {
|
||||
target: CallAdapter
|
||||
|
||||
function onPreviewVisibilityNeedToChange(visible) {
|
||||
previewRenderer.visible = visible
|
||||
}
|
||||
}
|
||||
|
||||
width: videoCallPageMainRect.width / 4
|
||||
height: {
|
||||
previewImageScalingFactorUpdated
|
||||
return previewRenderer.width * previewRenderer.getPreviewImageScalingFactor()
|
||||
}
|
||||
x: videoCallPageMainRect.width - previewRenderer.width - previewMargin
|
||||
y: videoCallPageMainRect.height - previewRenderer.height - previewMargin
|
||||
z: -1
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "geoChanging"
|
||||
PropertyChanges {
|
||||
target: previewRenderer
|
||||
x: previewToX
|
||||
y: previewToY
|
||||
function onShowOnHoldLabel(isPaused) {
|
||||
videoCallOverlay.showOnHoldImage(isPaused)
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
transitions: Transition {
|
||||
PropertyAnimation {
|
||||
properties: "x,y"
|
||||
easing.type: Easing.OutExpo
|
||||
duration: 250
|
||||
onOverlayChatButtonClicked: {
|
||||
if (inVideoCallMessageWebViewStack.visible) {
|
||||
linkedWebview.resetMessagingHeaderBackButtonSource(
|
||||
true)
|
||||
linkedWebview.setMessagingHeaderButtonsVisible(
|
||||
true)
|
||||
inVideoCallMessageWebViewStack.visible = false
|
||||
inVideoCallMessageWebViewStack.clear()
|
||||
} else {
|
||||
linkedWebview.resetMessagingHeaderBackButtonSource(
|
||||
false)
|
||||
linkedWebview.setMessagingHeaderButtonsVisible(
|
||||
false)
|
||||
inVideoCallMessageWebViewStack.visible = true
|
||||
inVideoCallMessageWebViewStack.push(
|
||||
linkedWebview)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onStopped: {
|
||||
DistantRenderer {
|
||||
id: distantRenderer
|
||||
|
||||
anchors.centerIn: videoCallPageMainRect
|
||||
z: -1
|
||||
|
||||
width: videoCallPageMainRect.width
|
||||
height: videoCallPageMainRect.height
|
||||
}
|
||||
|
||||
VideoCallPreviewRenderer {
|
||||
id: previewRenderer
|
||||
|
||||
|
||||
/*
|
||||
* Property is used in the {} expression for height (extra dependency),
|
||||
* it will not affect the true height expression, since expression
|
||||
* at last will be taken only, but it will force the height to update
|
||||
* and reevaluate getPreviewImageScalingFactor().
|
||||
*/
|
||||
property int previewImageScalingFactorUpdated: 0
|
||||
|
||||
Connections {
|
||||
target: CallAdapter
|
||||
|
||||
onPreviewVisibilityNeedToChange: previewRenderer.visible = visible
|
||||
}
|
||||
|
||||
width: videoCallPageMainRect.width / 4
|
||||
height: {
|
||||
previewImageScalingFactorUpdated
|
||||
return previewRenderer.width * previewRenderer.getPreviewImageScalingFactor()
|
||||
}
|
||||
x: videoCallPageMainRect.width - previewRenderer.width - previewMargin
|
||||
y: videoCallPageMainRect.height - previewRenderer.height - previewMargin - 56 /* Avoid overlay */
|
||||
z: -1
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "geoChanging"
|
||||
PropertyChanges {
|
||||
target: previewRenderer
|
||||
x: previewToX
|
||||
y: previewToY
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
transitions: Transition {
|
||||
PropertyAnimation {
|
||||
properties: "x,y"
|
||||
easing.type: Easing.OutExpo
|
||||
duration: 250
|
||||
|
||||
onStopped: {
|
||||
previewRenderer.state = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: dragMouseArea
|
||||
|
||||
anchors.fill: previewRenderer
|
||||
|
||||
onPressed: {
|
||||
clickPos = Qt.point(mouse.x, mouse.y)
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
previewRenderer.state = ""
|
||||
previewMagneticSnap()
|
||||
}
|
||||
|
||||
onPositionChanged: {
|
||||
|
||||
|
||||
/*
|
||||
* Calculate mouse position relative change.
|
||||
*/
|
||||
var delta = Qt.point(mouse.x - clickPos.x,
|
||||
mouse.y - clickPos.y)
|
||||
var deltaW = previewRenderer.x + delta.x + previewRenderer.width
|
||||
var deltaH = previewRenderer.y + delta.y + previewRenderer.height
|
||||
|
||||
|
||||
/*
|
||||
* Check if the previewRenderer exceeds the border of videoCallPageMainRect.
|
||||
*/
|
||||
if (deltaW < videoCallPageMainRect.width
|
||||
&& previewRenderer.x + delta.x > 1)
|
||||
previewRenderer.x += delta.x
|
||||
if (deltaH < videoCallPageMainRect.height
|
||||
&& previewRenderer.y + delta.y > 1)
|
||||
previewRenderer.y += delta.y
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: dragMouseArea
|
||||
|
||||
anchors.fill: previewRenderer
|
||||
|
||||
onPressed: {
|
||||
clickPos = Qt.point(mouse.x, mouse.y)
|
||||
onPreviewImageAvailable: {
|
||||
previewImageScalingFactorUpdated++
|
||||
previewImageScalingFactorUpdated--
|
||||
}
|
||||
|
||||
onReleased: {
|
||||
previewRenderer.state = ""
|
||||
previewMagneticSnap()
|
||||
}
|
||||
|
||||
onPositionChanged: {
|
||||
|
||||
|
||||
/*
|
||||
* Calculate mouse position relative change.
|
||||
*/
|
||||
var delta = Qt.point(mouse.x - clickPos.x,
|
||||
mouse.y - clickPos.y)
|
||||
var deltaW = previewRenderer.x + delta.x + previewRenderer.width
|
||||
var deltaH = previewRenderer.y + delta.y + previewRenderer.height
|
||||
|
||||
|
||||
/*
|
||||
* Check if the previewRenderer exceeds the border of videoCallPageMainRect.
|
||||
*/
|
||||
if (deltaW < videoCallPageMainRect.width
|
||||
&& previewRenderer.x + delta.x > 1)
|
||||
previewRenderer.x += delta.x
|
||||
if (deltaH < videoCallPageMainRect.height
|
||||
&& previewRenderer.y + delta.y > 1)
|
||||
previewRenderer.y += delta.y
|
||||
}
|
||||
}
|
||||
|
||||
onPreviewImageAvailable: {
|
||||
previewImageScalingFactorUpdated++
|
||||
previewImageScalingFactorUpdated--
|
||||
}
|
||||
}
|
||||
|
||||
color: "transparent"
|
||||
}
|
||||
|
||||
|
||||
StackView {
|
||||
id: inVideoCallMessageWebViewStack
|
||||
|
||||
|
@ -343,32 +338,8 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
VideoCallPageContextMenu {
|
||||
id: videoCallPageContextMenu
|
||||
|
||||
onFullScreenNeeded: {
|
||||
videoCallPageRect.needToShowInFullScreen()
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
|
||||
propagateComposedEvents: true
|
||||
acceptedButtons: Qt.RightButton
|
||||
|
||||
onClicked: {
|
||||
|
||||
|
||||
/*
|
||||
* Make menu pos at mouse.
|
||||
*/
|
||||
var relativeMousePos = mapToItem(videoCallPageRect,
|
||||
mouse.x, mouse.y)
|
||||
videoCallPageContextMenu.x = relativeMousePos.x
|
||||
videoCallPageContextMenu.y = relativeMousePos.y
|
||||
videoCallPageContextMenu.activate()
|
||||
}
|
||||
onBestNameChanged: {
|
||||
ContactAdapter.setCalleeDisplayName(bestName)
|
||||
}
|
||||
|
||||
color: "black"
|
||||
|
|
|
@ -31,60 +31,26 @@ GeneralMenuItem {
|
|||
|
||||
property int contextMenuPreferredWidth: 250
|
||||
|
||||
itemName: qsTr("No video device")
|
||||
leftBorderWidth: commonBorderWidth
|
||||
rightBorderWidth: commonBorderWidth
|
||||
|
||||
TextMetrics {
|
||||
id: textMetrics
|
||||
font: deviceNameText.font
|
||||
elide: Text.ElideMiddle
|
||||
elideWidth: contextMenuPreferredWidth
|
||||
- videoCallPageContextMenuDeviceItem.implicitIndicatorWidth
|
||||
text: videoCallPageContextMenuDeviceItem.itemName
|
||||
}
|
||||
|
||||
contentItem: Text {
|
||||
id: deviceNameText
|
||||
itemName: textMetrics.elidedText.length !== 0 ?
|
||||
textMetrics.elidedText :
|
||||
qsTr("No video device")
|
||||
|
||||
leftPadding: 30
|
||||
rightPadding: videoCallPageContextMenuDeviceItem.arrow.width
|
||||
indicator: null
|
||||
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
font.pointSize: JamiTheme.textFontSize - 3
|
||||
text: textMetrics.elidedText
|
||||
}
|
||||
|
||||
indicator: Item {
|
||||
id: selectItem
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
implicitWidth: 32
|
||||
implicitHeight: 32
|
||||
|
||||
Rectangle {
|
||||
id: selectRect
|
||||
|
||||
width: selectItem.width / 2
|
||||
height: selectItem.height / 2
|
||||
anchors.centerIn: parent
|
||||
visible: videoCallPageContextMenuDeviceItem.checkable
|
||||
border.color: JamiTheme.selectionGreen
|
||||
radius: 3
|
||||
Rectangle {
|
||||
width: selectRect.width / 2
|
||||
height: selectRect.height / 2
|
||||
anchors.centerIn: parent
|
||||
visible: videoCallPageContextMenuDeviceItem.checked
|
||||
color: JamiTheme.selectionGreen
|
||||
radius: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
iconSource: videoCallPageContextMenuDeviceItem.checked ?
|
||||
"qrc:/images/icons/check_box-24px.svg" :
|
||||
"qrc:/images/icons/check_box_outline_blank-24px.svg"
|
||||
|
||||
onClicked: {
|
||||
var deviceName = videoCallPageContextMenuDeviceItem.itemName
|
||||
|
|
|
@ -54,11 +54,7 @@ function createVideoDeviceContextMenuItemObjects(deviceName, setChecked, last) {
|
|||
function finishCreation(deviceName, setChecked, last) {
|
||||
videoDeviceContextMenuItemObject = videoDeviceContextMenuItemComponent.createObject()
|
||||
if (videoDeviceContextMenuItemObject === null) {
|
||||
|
||||
|
||||
/*
|
||||
* Error Handling.
|
||||
*/
|
||||
// Error Handling.
|
||||
console.log("Error creating video context menu object")
|
||||
}
|
||||
|
||||
|
@ -72,7 +68,7 @@ function finishCreation(deviceName, setChecked, last) {
|
|||
* Push into the storage array, and insert it into context menu.
|
||||
*/
|
||||
itemArray.push(videoDeviceContextMenuItemObject)
|
||||
videoContextMenuObject.insertItem(1, videoDeviceContextMenuItemObject)
|
||||
videoContextMenuObject.insertItem(3 /* The button is at pos 3 in the menu */, videoDeviceContextMenuItemObject)
|
||||
|
||||
|
||||
/*
|
||||
|
|