diff --git a/resources/qml/TimelineView.qml b/resources/qml/TimelineView.qml index e596d8e2..fd08f0ca 100644 --- a/resources/qml/TimelineView.qml +++ b/resources/qml/TimelineView.qml @@ -52,6 +52,13 @@ Page { } + Component { + id: mobileCallInviteDialog + + CallInvite { + } + } + Menu { id: messageContextMenu @@ -151,6 +158,16 @@ Page { } } + Connections { + target: CallManager + onNewInviteState: { + if (CallManager.haveCallInvite && Settings.mobileMode) { + var dialog = mobileCallInviteDialog.createObject(msgView); + dialog.open(); + } + } + } + Label { visible: !TimelineManager.timeline && !TimelineManager.isInitialSync anchors.centerIn: parent @@ -184,6 +201,7 @@ Page { } Rectangle { + id: msgView Layout.fillWidth: true Layout.fillHeight: true color: colors.base diff --git a/resources/qml/voip/CallInvite.qml b/resources/qml/voip/CallInvite.qml new file mode 100644 index 00000000..6931b3c9 --- /dev/null +++ b/resources/qml/voip/CallInvite.qml @@ -0,0 +1,173 @@ +import "../" +import QtQuick 2.9 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.2 +import im.nheko 1.0 + +Popup { + closePolicy: Popup.NoAutoClose + width: parent.width + height: parent.height + palette: colors + background: Rectangle { + color: colors.window + border.color: colors.windowText + } + + Component { + id: deviceError + DeviceError { + } + } + + Connections { + target: CallManager + onNewInviteState: { + if (!CallManager.haveCallInvite) { + close(); + } + } + } + + ColumnLayout { + anchors.top: parent.top + anchors.bottom: parent.bottom + anchors.horizontalCenter: parent.horizontalCenter + + spacing: 48 + + Item { + Layout.fillHeight: true + } + + Label { + Layout.alignment: Qt.AlignCenter + text: CallManager.callParty + font.pointSize: fontMetrics.font.pointSize * 2 + color: colors.windowText + } + + Avatar { + Layout.alignment: Qt.AlignCenter + width: avatarSize * 4 + height: avatarSize * 4 + url: CallManager.callPartyAvatarUrl.replace("mxc://", "image://MxcImage/") + displayName: CallManager.callParty + } + + ColumnLayout { + Layout.alignment: Qt.AlignCenter + + Image { + Layout.alignment: Qt.AlignCenter + Layout.preferredWidth: avatarSize + Layout.preferredHeight: avatarSize + property string image: CallManager.isVideo ? ":/icons/icons/ui/video-call.png" : ":/icons/icons/ui/place-call.png" + source: "image://colorimage/" + image + "?" + colors.windowText + } + + Label { + Layout.alignment: Qt.AlignCenter + text: CallManager.isVideo ? qsTr("Video Call") : qsTr("Voice Call") + font.pointSize: fontMetrics.font.pointSize * 2 + color: colors.windowText + } + } + + ColumnLayout { + id: deviceCombos + Layout.alignment: Qt.AlignCenter + property int imageSize: 32 + + RowLayout { + + Layout.alignment: Qt.AlignCenter + + Image { + Layout.preferredWidth: deviceCombos.imageSize + Layout.preferredHeight: deviceCombos.imageSize + source: "image://colorimage/:/icons/icons/ui/microphone-unmute.png?" + colors.windowText + } + + ComboBox { + id: micCombo + Layout.fillWidth: true + model: CallManager.mics + } + } + + RowLayout { + + visible: CallManager.isVideo && CallManager.cameras.length > 0 + Layout.alignment: Qt.AlignCenter + + Image { + Layout.preferredWidth: deviceCombos.imageSize + Layout.preferredHeight: deviceCombos.imageSize + source: "image://colorimage/:/icons/icons/ui/video-call.png?" + colors.windowText + } + + ComboBox { + id: cameraCombo + Layout.fillWidth: true + model: CallManager.cameras + } + } + } + + RowLayout { + id: buttonLayout + + property int iconSize: 64 + Layout.alignment: Qt.AlignCenter + spacing: 160 + + function validateMic() { + if (CallManager.mics.length == 0) { + var dialog = deviceError.createObject(timelineRoot, { + "errorString": qsTr("No microphone found."), + "image": ":/icons/icons/ui/place-call.png" + }); + dialog.open(); + return false; + } + return true; + } + + RoundButton { + icon.source: "qrc:/icons/icons/ui/end-call.png" + icon.width: buttonLayout.iconSize + icon.height: buttonLayout.iconSize + icon.color: "#ffffff" + palette.button: "#ff0000" + + onClicked: { + CallManager.hangUp(); + close(); + } + } + + RoundButton { + icon.source: CallManager.isVideo ? "qrc:/icons/icons/ui/video-call.png" : "qrc:/icons/icons/ui/place-call.png" + icon.width: buttonLayout.iconSize + icon.height: buttonLayout.iconSize + icon.color: "#ffffff" + palette.button: "#00ff00" + + onClicked: { + if (buttonLayout.validateMic()) { + Settings.microphone = micCombo.currentText; + if (cameraCombo.visible) + Settings.camera = cameraCombo.currentText; + CallManager.acceptInvite(); + close(); + } + } + } + } + + Item { + Layout.fillHeight: true + } + } +} diff --git a/resources/qml/voip/CallInviteBar.qml b/resources/qml/voip/CallInviteBar.qml index 5c4b8f32..cc3f9005 100644 --- a/resources/qml/voip/CallInviteBar.qml +++ b/resources/qml/voip/CallInviteBar.qml @@ -5,7 +5,7 @@ import QtQuick.Layouts 1.2 import im.nheko 1.0 Rectangle { - visible: CallManager.haveCallInvite + visible: CallManager.haveCallInvite && !Settings.mobileMode color: "#2ECC71" implicitHeight: visible ? rowLayout.height + 8 : 0 diff --git a/resources/res.qrc b/resources/res.qrc index 71e8b997..e3998bd1 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -160,6 +160,7 @@ qml/ui/Ripple.qml qml/voip/ActiveCallBar.qml qml/voip/CallDevices.qml + qml/voip/CallInvite.qml qml/voip/CallInviteBar.qml qml/voip/DeviceError.qml qml/voip/PlaceCall.qml