From 68e8ad46aaa7eef33569e6333cd7f3fffe887624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Blin?= Date: Thu, 14 Apr 2022 17:13:02 -0400 Subject: [PATCH] photoboothview: implement new design Implement new design. Now the photobooth got a modal for preview. This uses the RecordBox item which is simplified into a popup instead weird Pathes Change-Id: Id95c90f853870605ecf21c33217381092ca1a709 --- resources/icons/baseline_camera_alt_24dp.svg | 20 +- resources/icons/delete_24dp.svg | 10 +- resources/icons/round_folder_24dp.svg | 11 +- src/commoncomponents/PhotoboothView.qml | 477 ++++++++-------- src/commoncomponents/PushButton.qml | 1 + src/mainview/components/NewSwarmPage.qml | 6 +- src/mainview/components/RecordBox.qml | 512 ++++++++++-------- src/mainview/components/SwarmDetailsPanel.qml | 5 +- .../components/AccountProfile.qml | 1 + src/wizardview/components/ProfilePage.qml | 1 + 10 files changed, 598 insertions(+), 446 deletions(-) diff --git a/resources/icons/baseline_camera_alt_24dp.svg b/resources/icons/baseline_camera_alt_24dp.svg index 83479645..94b088f2 100644 --- a/resources/icons/baseline_camera_alt_24dp.svg +++ b/resources/icons/baseline_camera_alt_24dp.svg @@ -1 +1,19 @@ - \ No newline at end of file + + + + + + + + + + + + + diff --git a/resources/icons/delete_24dp.svg b/resources/icons/delete_24dp.svg index 47e4e302..5c05fc8c 100644 --- a/resources/icons/delete_24dp.svg +++ b/resources/icons/delete_24dp.svg @@ -1 +1,9 @@ - \ No newline at end of file + + + + + diff --git a/resources/icons/round_folder_24dp.svg b/resources/icons/round_folder_24dp.svg index 4f02e223..6f201df3 100644 --- a/resources/icons/round_folder_24dp.svg +++ b/resources/icons/round_folder_24dp.svg @@ -1 +1,10 @@ - \ No newline at end of file + + + + + diff --git a/src/commoncomponents/PhotoboothView.qml b/src/commoncomponents/PhotoboothView.qml index c5c8d2f2..57dea273 100644 --- a/src/commoncomponents/PhotoboothView.qml +++ b/src/commoncomponents/PhotoboothView.qml @@ -25,30 +25,28 @@ import net.jami.Models 1.1 import net.jami.Adapters 1.1 import net.jami.Constants 1.1 +import "../mainview/components" + Item { id: root - property bool isPreviewing: false property alias imageId: avatar.imageId property bool newConversation: false property real avatarSize + property real buttonSize: avatarSize + property bool inverted: false signal focusOnPreviousItem signal focusOnNextItem - width: avatarSize - height: boothLayout.height + height: Math.max(avatarSize, buttonSize) function startBooth() { - preview.startWithId(VideoDevices.getDefaultDevice()) - isPreviewing = true + recordBox.openRecorder(true) } function stopBooth(){ - if (!AccountAdapter.hasVideoCall()) { - VideoDevices.stopDevice(preview.deviceId) - } - isPreviewing = false + recordBox.closeRecorder() } function focusOnNextPhotoBoothItem () { @@ -56,10 +54,7 @@ Item { } function focusOnPreviousPhotoBoothItem () { - if (isPreviewing) - clearButton.forceActiveFocus() - else - importButton.forceActiveFocus() + importButton.forceActiveFocus() } onVisibleChanged: { @@ -68,6 +63,21 @@ Item { } } + RecordBox { + id: recordBox + + isPhoto: true + visible: false + + onValidatePhoto: function(photo) { + if (!root.newConversation) + AccountAdapter.setCurrentAccountAvatarBase64(photo) + else + UtilsAdapter.setSwarmCreationImageFromString(photo, imageId) + buttonsRowLayout.backToAvatar() + } + } + JamiFileDialog { id: importFromFileDialog @@ -109,228 +119,273 @@ Item { } } - ColumnLayout { - id: boothLayout + Item { + id: imageLayer - spacing: JamiTheme.preferredMarginSize / 2 + anchors.centerIn: parent + width: avatarSize + height: avatarSize - Item { - id: imageLayer + Avatar { + id: avatar - Layout.preferredWidth: avatarSize - Layout.preferredHeight: avatarSize - Layout.alignment: Qt.AlignHCenter + anchors.fill: parent + anchors.margins: 1 - Avatar { - id: avatar + mode: newConversation? Avatar.Mode.Conversation : Avatar.Mode.Account - anchors.fill: parent - anchors.margins: 1 + fillMode: Image.PreserveAspectCrop + showPresenceIndicator: false - visible: !preview.visible - - mode: newConversation? Avatar.Mode.Conversation : Avatar.Mode.Account - - fillMode: Image.PreserveAspectCrop - showPresenceIndicator: false + HoverHandler { + target: parent + enabled: parent.visible + onHoveredChanged: { + overlayHighlighted.visible = hovered + } } - LocalVideo { - id: preview - - anchors.fill: parent - anchors.margins: 1 - - visible: isPreviewing - - rendererId: VideoDevices.getDefaultDevice() - - function takePhoto() { - return videoProvider.captureVideoFrame(videoSink) - } - - layer.enabled: true - layer.effect: OpacityMask { - maskSource: Rectangle { - width: avatarSize - height: avatarSize - radius: avatarSize / 2 - } + TapHandler { + target: parent + enabled: parent.visible + onTapped: { + imageLayer.visible = false + buttonsRowLayout.visible = true } } Rectangle { - id: flashRect + id: overlayHighlighted + visible: false anchors.fill: parent - anchors.margins: 0 - radius: avatarSize / 2 - color: "white" - opacity: 0 + color: Qt.rgba(0, 0, 0, 0.5) + radius: parent.height / 2 - SequentialAnimation { - id: flashAnimation + opacity: visible + Behavior on opacity { NumberAnimation { - target: flashRect; property: "opacity" - to: 1; duration: 0 - } - NumberAnimation { - target: flashRect; property: "opacity" - to: 0; duration: 500 - } - } - } - } - - RowLayout { - id: buttonsRowLayout - - Layout.fillWidth: true - Layout.preferredHeight: childrenRect.height - Layout.bottomMargin: parent.spacing - Layout.alignment: Qt.AlignHCenter - - PushButton { - id: takePhotoButton - - objectName: "takePhotoButton" - - Layout.alignment: Qt.AlignHCenter - - radius: JamiTheme.primaryRadius - imageColor: JamiTheme.textColor - toolTipText: JamiStrings.takePhoto - source: isPreviewing ? - JamiResources.round_add_a_photo_24dp_svg : - JamiResources.baseline_camera_alt_24dp_svg - - Keys.onPressed: function (keyEvent) { - if (keyEvent.key === Qt.Key_Enter || - keyEvent.key === Qt.Key_Return) { - clicked() - keyEvent.accepted = true - } else if (keyEvent.key === Qt.Key_Up) { - root.focusOnPreviousItem() - keyEvent.accepted = true + from: 0 + duration: JamiTheme.shortFadeDuration } } - KeyNavigation.tab: { - if (clearButton.visible) - return clearButton - return importButton - } - KeyNavigation.down: KeyNavigation.tab + Image { + id: overlayImage - onClicked: { - if (isPreviewing) { - flashAnimation.start() - var photo = preview.takePhoto(avatarSize) - if (!root.newConversation) - AccountAdapter.setCurrentAccountAvatarBase64(photo) - else - UtilsAdapter.setSwarmCreationImageFromString(photo, imageId) - stopBooth() - return + width: JamiTheme.smartListAvatarSize / 2 + height: JamiTheme.smartListAvatarSize / 2 + anchors.centerIn: parent + + layer { + enabled: true + effect: ColorOverlay { + color: "white" + } } - - startBooth() - } - } - - PushButton { - id: clearButton - - objectName: "photoboothViewClearButton" - - Layout.alignment: Qt.AlignHCenter - - visible: { - if (isPreviewing) - return true - if (!newConversation && LRCInstance.currentAccountAvatarSet) - return true - if (newConversation && UtilsAdapter.swarmCreationImage(imageId).length !== 0) - return true - return false - } - - radius: JamiTheme.primaryRadius - source: JamiResources.round_close_24dp_svg - toolTipText: isPreviewing ? JamiStrings.stopTakingPhoto : - JamiStrings.clearAvatar - imageColor: JamiTheme.textColor - - KeyNavigation.up: takePhotoButton - - Keys.onPressed: function (keyEvent) { - if (keyEvent.key === Qt.Key_Enter || - keyEvent.key === Qt.Key_Return) { - clicked() - takePhotoButton.forceActiveFocus() - keyEvent.accepted = true - } else if (keyEvent.key === Qt.Key_Down || - keyEvent.key === Qt.Key_Tab) { - if (isPreviewing) { - root.focusOnNextItem() - } else - importButton.forceActiveFocus() - keyEvent.accepted = true - } - } - - onClicked: { - stopBooth() - if (!isPreviewing) { - if (!root.newConversation) - AccountAdapter.setCurrentAccountAvatarBase64() - else - UtilsAdapter.setSwarmCreationImageFromString("", imageId) - } - } - } - - PushButton { - id: importButton - - objectName: "photoboothViewImportButton" - - property bool focusAfterFileDialogClosed: false - - Layout.alignment: Qt.AlignHCenter - - visible: !isPreviewing - - radius: JamiTheme.primaryRadius - source: JamiResources.round_folder_24dp_svg - toolTipText: JamiStrings.importFromFile - imageColor: JamiTheme.textColor - - Keys.onPressed: function (keyEvent) { - if (keyEvent.key === Qt.Key_Enter || - keyEvent.key === Qt.Key_Return) { - focusAfterFileDialogClosed = true - clicked() - keyEvent.accepted = true - } else if (keyEvent.key === Qt.Key_Down || - keyEvent.key === Qt.Key_Tab) { - root.focusOnNextItem() - keyEvent.accepted = true - } - } - - KeyNavigation.up: { - if (clearButton.visible) - return clearButton - return takePhotoButton - } - - onClicked: { - stopBooth() - importFromFileDialog.open() + source: JamiResources.round_edit_24dp_svg } } } } + + RowLayout { + id: buttonsRowLayout + visible: false + + anchors.centerIn: parent + Layout.preferredHeight: childrenRect.height + spacing: 12 + + function backToAvatar() { + imageLayer.visible = true + buttonsRowLayout.visible = false + } + + PushButton { + id: takePhotoButton + + objectName: "takePhotoButton" + + Layout.alignment: Qt.AlignHCenter + + height: buttonSize + width: buttonSize + radius: height / 2 + border.width: 2 + border.color: JamiTheme.textColor + normalColor: "transparent" + imageColor: JamiTheme.textColor + toolTipText: JamiStrings.takePhoto + source: JamiResources.baseline_camera_alt_24dp_svg + hoveredColor: Qt.rgba(255, 255, 255, 0.2) + + Keys.onPressed: function (keyEvent) { + if (keyEvent.key === Qt.Key_Enter || + keyEvent.key === Qt.Key_Return) { + clicked() + keyEvent.accepted = true + } else if (keyEvent.key === Qt.Key_Up) { + root.focusOnPreviousItem() + keyEvent.accepted = true + } + } + + KeyNavigation.tab: { + if (clearButton.visible) + return clearButton + return importButton + } + KeyNavigation.down: KeyNavigation.tab + + onClicked: { + recordBox.parent = takePhotoButton + + recordBox.x = Qt.binding(function() { + var buttonCenterX = takePhotoButton.x + takePhotoButton.width / 2 + return buttonCenterX - recordBox.width / 2 + }) + recordBox.y = Qt.binding(function() { + var buttonY = takePhotoButton.y + return inverted? buttonY + takePhotoButton.height : buttonY - recordBox.height + }) + startBooth() + } + } + + PushButton { + id: importButton + + objectName: "photoboothViewImportButton" + + property bool focusAfterFileDialogClosed: false + + Layout.alignment: Qt.AlignHCenter + visible: parent.visible + + height: buttonSize + width: buttonSize + radius: height / 2 + border.width: 2 + border.color: JamiTheme.textColor + normalColor: "transparent" + source: JamiResources.round_folder_24dp_svg + toolTipText: JamiStrings.importFromFile + imageColor: JamiTheme.textColor + hoveredColor: Qt.rgba(255, 255, 255, 0.2) + + Keys.onPressed: function (keyEvent) { + if (keyEvent.key === Qt.Key_Enter || + keyEvent.key === Qt.Key_Return) { + focusAfterFileDialogClosed = true + clicked() + keyEvent.accepted = true + } else if (keyEvent.key === Qt.Key_Down || + keyEvent.key === Qt.Key_Tab) { + clearButton.forceActiveFocus() + keyEvent.accepted = true + } + } + + KeyNavigation.up: takePhotoButton + + onClicked: { + stopBooth() + buttonsRowLayout.backToAvatar() + importFromFileDialog.open() + } + } + + + PushButton { + id: clearButton + + objectName: "photoboothViewClearButton" + + Layout.alignment: Qt.AlignHCenter + + height: buttonSize + width: buttonSize + radius: height / 2 + border.width: 2 + border.color: JamiTheme.textColor + normalColor: "transparent" + source: JamiResources.ic_hangup_participant_24dp_svg + toolTipText: JamiStrings.clearAvatar + imageColor: JamiTheme.textColor + hoveredColor: Qt.rgba(255, 255, 255, 0.2) + + visible: { + if (!newConversation && LRCInstance.currentAccountAvatarSet) + return true + if (newConversation && UtilsAdapter.swarmCreationImage(imageId).length !== 0) + return true + return false + } + + KeyNavigation.up: importButton + + Keys.onPressed: function (keyEvent) { + if (keyEvent.key === Qt.Key_Enter || + keyEvent.key === Qt.Key_Return) { + clicked() + importButton.forceActiveFocus() + keyEvent.accepted = true + } else if (keyEvent.key === Qt.Key_Down || + keyEvent.key === Qt.Key_Tab) { + cancelButton.forceActiveFocus() + keyEvent.accepted = true + } + } + + onClicked: { + if (!root.newConversation) + AccountAdapter.setCurrentAccountAvatarBase64() + else + UtilsAdapter.setSwarmCreationImageFromString("", imageId) + stopBooth() + buttonsRowLayout.backToAvatar() + } + } + + PushButton { + id: cancelButton + + preferredSize: 18 + radius: height / 2 + normalColor: "transparent" + source: JamiResources.round_close_24dp_svg + toolTipText: JamiStrings.cancel + imageColor: JamiTheme.textColor + hoveredColor: Qt.rgba(255, 255, 255, 0.2) + Layout.leftMargin: -8 + + Keys.onPressed: function (keyEvent) { + if (keyEvent.key === Qt.Key_Enter || + keyEvent.key === Qt.Key_Return) { + clicked() + takePhotoButton.forceActiveFocus() + keyEvent.accepted = true + } else if (keyEvent.key === Qt.Key_Down || + keyEvent.key === Qt.Key_Tab) { + importButton.forceActiveFocus() + keyEvent.accepted = true + } + } + + KeyNavigation.up: { + if (clearButton.visible) + return clearButton + if (importButton.visible) + return importButton + return takePhotoButton + } + + onClicked: { + stopBooth() + buttonsRowLayout.backToAvatar() + } + } + } } diff --git a/src/commoncomponents/PushButton.qml b/src/commoncomponents/PushButton.qml index 4ec286ee..46dfe319 100644 --- a/src/commoncomponents/PushButton.qml +++ b/src/commoncomponents/PushButton.qml @@ -41,6 +41,7 @@ AbstractButton { property int preferredMargin: 16 // Note the radius will default to preferredSize property alias radius: background.radius + property alias border: background.border // Text properties property alias buttonText: textContent.text diff --git a/src/mainview/components/NewSwarmPage.qml b/src/mainview/components/NewSwarmPage.qml index e28a629c..ab44ae88 100644 --- a/src/mainview/components/NewSwarmPage.qml +++ b/src/mainview/components/NewSwarmPage.qml @@ -114,6 +114,7 @@ Rectangle { newConversation: true imageId: root.visible ? "temp" : "" avatarSize: 180 + buttonSize: JamiTheme.smartListAvatarSize } EditableLineEdit { @@ -123,7 +124,7 @@ Rectangle { font.pointSize: JamiTheme.titleFontSize - horizontalAlignment: Text.AlignHCenter + horizontalAlignment: editable ? Text.AlignLeft : Text.AlignHCenter verticalAlignment: Text.AlignVCenter placeholderText: JamiStrings.editTitle @@ -139,6 +140,9 @@ Rectangle { font.pointSize: JamiTheme.titleFontSize + horizontalAlignment: editable ? Text.AlignLeft : Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + placeholderText: JamiStrings.editDescription tooltipText: JamiStrings.editDescription backgroundColor: root.color diff --git a/src/mainview/components/RecordBox.qml b/src/mainview/components/RecordBox.qml index 75679e3c..83957535 100644 --- a/src/mainview/components/RecordBox.qml +++ b/src/mainview/components/RecordBox.qml @@ -19,7 +19,6 @@ import QtQuick import QtQuick.Controls import Qt5Compat.GraphicalEffects -import QtQuick.Shapes import net.jami.Models 1.1 import net.jami.Adapters 1.1 @@ -27,7 +26,7 @@ import net.jami.Constants 1.1 import "../../commoncomponents" -Rectangle { +Popup { id: root enum States { @@ -37,10 +36,10 @@ Rectangle { } property string pathRecorder: "" - property string timeText: "00:00" property int duration: 0 property int state: RecordBox.States.INIT property bool isVideo: false + property bool isPhoto: false property int preferredWidth: 320 property int preferredHeight: 240 property int btnSize: 40 @@ -49,9 +48,11 @@ Rectangle { property int curveRadius: 6 property int spikeHeight: 10 + offset + property string photo: "" + + signal validatePhoto(string photo) + function openRecorder(vid) { - focus = true - visible = true isVideo = vid scaleHeight() @@ -60,6 +61,7 @@ Rectangle { if (isVideo) { previewWidget.startWithId(VideoDevices.getDefaultDevice()) } + open() } function scaleHeight() { @@ -80,14 +82,22 @@ Rectangle { if (isVideo) { VideoDevices.stopDevice(previewWidget.deviceId) } - stopRecording() - visible = false + if (!root.isPhoto) + stopRecording() + close() } function updateState(new_state) { state = new_state - recordButton.visible = (state === RecordBox.States.INIT) - btnStop.visible = (state === RecordBox.States.RECORDING) + if (isPhoto) { + screenshotBtn.visible = (state === RecordBox.States.INIT) + recordButton.visible = false + btnStop.visible = false + } else { + screenshotBtn.visible = false + recordButton.visible = (state === RecordBox.States.INIT) + btnStop.visible = (state === RecordBox.States.RECORDING) + } btnRestart.visible = (state === RecordBox.States.REC_SUCCESS) btnSend.visible = (state === RecordBox.States.REC_SUCCESS) @@ -135,9 +145,8 @@ Rectangle { width: 320 height: 240 - radius: 5 - border.color: JamiTheme.tabbarBorderColor - color: JamiTheme.backgroundColor + modal: true + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent onActiveFocusChanged: { if (visible) { @@ -151,239 +160,284 @@ Rectangle { } } - Shape { - id: backgroundShape - - anchors.centerIn: parent - - width: root.width - height: root.height - - x: -offset - y: -offset - - ShapePath { - fillColor: JamiTheme.backgroundColor - - strokeWidth: 1 - strokeColor: JamiTheme.tabbarBorderColor - - startX: -offset + curveRadius - startY: -offset - joinStyle: ShapePath.RoundJoin - - PathLine { - x: width + offset - curveRadius - y: -offset - } - - PathArc { - x: width + offset - y: -offset + curveRadius - radiusX: curveRadius - radiusY: curveRadius - } - - PathLine { - x: width + offset - y: height + offset - curveRadius - } - - PathArc { - x: width + offset - curveRadius - y: height + offset - radiusX: curveRadius - radiusY: curveRadius - } - - PathLine { - x: width / 2 + 10 - y: height + offset - } - PathLine { - x: width / 2 - y: height + spikeHeight - } - PathLine { - x: width / 2 - 10 - y: height + offset - } - - PathLine { - x: -offset + curveRadius - y: height + offset - } - - PathArc { - x: -offset - y: height + offset - curveRadius - radiusX: curveRadius - radiusY: curveRadius - } - - PathLine { - x: -offset - y: -offset + curveRadius - } - - PathArc { - x: -offset + curveRadius - y: -offset - radiusX: curveRadius - radiusY: curveRadius - } - } - } - - Rectangle { - id: rectBox - + background: Rectangle { anchors.fill: parent - - visible: (isVideo && VideoDevices.listSize !== 0) - color: JamiTheme.blackColor + visible: !root.isVideo radius: 5 - - LocalVideo { - id: previewWidget - - anchors.fill: rectBox - anchors.margins: 1 - - rendererId: VideoDevices.getDefaultDevice() - - layer.enabled: true - layer.effect: OpacityMask { - maskSource: rectBox - } - } + border.color: JamiTheme.tabbarBorderColor + color: JamiTheme.backgroundColor } - Label { - anchors.centerIn: parent + Item { + anchors.fill: parent + anchors.margins: 0 - width: root.width + Rectangle { + id: rectBox - visible: (isVideo && VideoDevices.listSize === 0) + anchors.fill: parent - onVisibleChanged: { - if (visible) { + visible: (isVideo && VideoDevices.listSize !== 0) + color: JamiTheme.blackColor + radius: 5 + + Item { + // Else it will be resized by the layer effect + id: photoMask + visible: false + anchors.fill: rectBox + Rectangle { + anchors.centerIn: parent + height: parent.height + width: parent.height + radius: height / 2 + } + } + + Image { + id: screenshotImg + visible: parent.visible && root.isPhoto && btnSend.visible + + anchors.fill: parent + + layer.enabled: true + layer.effect: OpacityMask { + maskSource: rectBox + } + + Rectangle { + anchors.fill: parent + color: "black" + opacity: 0.6 + + layer.enabled: true + layer.effect: OpacityMask { + anchors.centerIn: parent + maskSource: photoMask + invert: true + } + } + source: root.photo === "" ? "" : "data:image/png;base64," + root.photo + } + + LocalVideo { + id: previewWidget + + visible: parent.visible && !screenshotImg.visible + + anchors.fill: rectBox + anchors.margins: 1 + + rendererId: VideoDevices.getDefaultDevice() + + layer.enabled: true + layer.effect: OpacityMask { + maskSource: rectBox + } + + Rectangle { + anchors.fill: parent + color: "black" + opacity: 0.6 + visible: root.isPhoto + + layer.enabled: true + layer.effect: OpacityMask { + anchors.centerIn: parent + maskSource: photoMask + invert: true + } + } + } + } + + Label { + anchors.centerIn: parent + + width: root.width + + visible: (isVideo && VideoDevices.listSize === 0) + + onVisibleChanged: { + if (visible) { + closeRecorder() + } + } + + text: JamiStrings.previewUnavailable + font.pointSize: JamiTheme.settingsFontSize + font.kerning: true + color: JamiTheme.primaryForegroundColor + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + } + + Timer { + id: timer + + interval: 1000 + running: false + repeat: true + + onTriggered: updateTimer() + } + + Text { + id: time + + anchors.centerIn: recordButton + anchors.horizontalCenterOffset: (isVideo ? 100 : 0) + anchors.verticalCenterOffset: (isVideo ? 0 : -100) + + visible: !root.isPhoto + text: "00:00" + color: (isVideo ? JamiTheme.whiteColor : JamiTheme.textColor) + font.pointSize: (isVideo ? 12 : 20) + } + + PushButton { + id: recordButton + + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + anchors.bottomMargin: 5 + + preferredSize: btnSize + + normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor + hoveredColor: Qt.rgba(255, 255, 255, 0.2) + + source: JamiResources.fiber_manual_record_24dp_svg + imageColor: JamiTheme.recordIconColor + + onClicked: { + updateState(RecordBox.States.RECORDING) + if (!root.isPhoto) + startRecording() + } + } + + PushButton { + id: screenshotBtn + + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + anchors.bottomMargin: 5 + + preferredSize: btnSize + + normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor + hoveredColor: Qt.rgba(255, 255, 255, 0.2) + border.width: 1 + border.color: imageColor + + source: JamiResources.fiber_manual_record_24dp_svg + imageColor: JamiTheme.whiteColor + + onClicked: { + root.photo = videoProvider.captureVideoFrame(previewWidget.videoSink) + updateState(RecordBox.States.REC_SUCCESS) + } + } + + PushButton { + id: btnStop + + anchors.horizontalCenter: parent.horizontalCenter + anchors.bottom: parent.bottom + anchors.bottomMargin: 5 + + preferredSize: btnSize + + normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor + hoveredColor: Qt.rgba(255, 255, 255, 0.2) + + source: JamiResources.stop_24dp_red_svg + imageColor: isVideo ? JamiTheme.whiteColor : JamiTheme.textColor + border.width: 1 + border.color: imageColor + + onClicked: { + if (!root.isPhoto) + stopRecording() + updateState(RecordBox.States.REC_SUCCESS) + } + } + + PushButton { + id: btnRestart + + anchors.horizontalCenter: parent.horizontalCenter + anchors.horizontalCenterOffset: -25 + anchors.bottom: parent.bottom + anchors.bottomMargin: 5 + + preferredSize: btnSize + + normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor + + source: JamiResources.re_record_24dp_svg + hoveredColor: Qt.rgba(255, 255, 255, 0.2) + imageColor: isVideo ? JamiTheme.whiteColor : JamiTheme.textColor + border.width: 1 + border.color: imageColor + + onClicked: { + if (!root.isPhoto) + stopRecording() + updateState(RecordBox.States.INIT) + } + } + + PushButton { + id: btnSend + + anchors.horizontalCenter: parent.horizontalCenter + anchors.horizontalCenterOffset: 25 + anchors.bottom: parent.bottom + anchors.bottomMargin: 5 + + preferredSize: btnSize + + normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor + + source: JamiResources.check_black_24dp_svg + imageColor: isVideo ? JamiTheme.whiteColor : JamiTheme.textColor + border.width: 1 + border.color: imageColor + + onClicked: { + if (!root.isPhoto) { + stopRecording() + sendRecord() + } else if (root.photo !== "") { + root.validatePhoto(root.photo) + } closeRecorder() + updateState(RecordBox.States.INIT) } } - text: JamiStrings.previewUnavailable - font.pointSize: JamiTheme.settingsFontSize - font.kerning: true - color: JamiTheme.primaryForegroundColor - horizontalAlignment: Text.AlignHCenter - verticalAlignment: Text.AlignVCenter - } + PushButton { + id: cancelBtn - Timer { - id: timer + normalColor: "transparent" + hoveredColor: Qt.rgba(255, 255, 255, 0.2) + imageColor: JamiTheme.primaryForegroundColor - interval: 1000 - running: false - repeat: true + preferredSize: 12 - onTriggered: updateTimer() - } + source: JamiResources.round_close_24dp_svg + toolTipText: JamiStrings.back - Text { - id: time + anchors.right: parent.right + anchors.top: parent.top + anchors.margins: 8 - anchors.centerIn: recordButton - anchors.horizontalCenterOffset: (isVideo ? 100 : 0) - anchors.verticalCenterOffset: (isVideo ? 0 : -100) - - visible: true - text: "00:00" - color: (isVideo ? JamiTheme.whiteColor : JamiTheme.textColor) - font.pointSize: (isVideo ? 12 : 20) - } - - PushButton { - id: recordButton - - anchors.horizontalCenter: root.horizontalCenter - anchors.bottom: root.bottom - anchors.bottomMargin: 5 - - preferredSize: btnSize - - normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor - - source: JamiResources.fiber_manual_record_24dp_svg - imageColor: JamiTheme.recordIconColor - - onClicked: { - updateState(RecordBox.States.RECORDING) - startRecording() - } - } - - PushButton { - id: btnStop - - anchors.horizontalCenter: root.horizontalCenter - anchors.bottom: root.bottom - anchors.bottomMargin: 5 - - preferredSize: btnSize - - normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor - - source: JamiResources.stop_24dp_red_svg - imageColor: isVideo ? JamiTheme.whiteColor : JamiTheme.textColor - - onClicked: { - stopRecording() - updateState(RecordBox.States.REC_SUCCESS) - } - } - - PushButton { - id: btnRestart - - anchors.horizontalCenter: root.horizontalCenter - anchors.horizontalCenterOffset: -25 - anchors.bottom: root.bottom - anchors.bottomMargin: 5 - - preferredSize: btnSize - - normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor - - source: JamiResources.re_record_24dp_svg - imageColor: isVideo ? JamiTheme.whiteColor : JamiTheme.textColor - - onClicked: { - stopRecording() - updateState(RecordBox.States.INIT) - } - } - - PushButton { - id: btnSend - - anchors.horizontalCenter: root.horizontalCenter - anchors.horizontalCenterOffset: 25 - anchors.bottom: parent.bottom - anchors.bottomMargin: 5 - - preferredSize: btnSize - - normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor - - source: JamiResources.send_24dp_svg - imageColor: isVideo ? JamiTheme.whiteColor : JamiTheme.textColor - - onClicked: { - stopRecording() - sendRecord() - closeRecorder() - updateState(RecordBox.States.INIT) + onClicked: { + closeRecorder() + updateState(RecordBox.States.INIT) + } } } } diff --git a/src/mainview/components/SwarmDetailsPanel.qml b/src/mainview/components/SwarmDetailsPanel.qml index b28a32a2..e3ac8d56 100644 --- a/src/mainview/components/SwarmDetailsPanel.qml +++ b/src/mainview/components/SwarmDetailsPanel.qml @@ -46,14 +46,15 @@ Rectangle { PhotoboothView { id: currentAccountAvatar + inverted: true - Layout.alignment: Qt.AlignCenter Layout.topMargin: JamiTheme.swarmDetailsPageTopMargin Layout.bottomMargin: JamiTheme.preferredMarginSize + Layout.alignment: Qt.AlignHCenter newConversation: true imageId: LRCInstance.selectedConvUid - avatarSize: JamiTheme.avatarSizeInCall + avatarSize: JamiTheme.smartListAvatarSize } EditableLineEdit { diff --git a/src/settingsview/components/AccountProfile.qml b/src/settingsview/components/AccountProfile.qml index 55efe335..fa6ffe76 100644 --- a/src/settingsview/components/AccountProfile.qml +++ b/src/settingsview/components/AccountProfile.qml @@ -62,6 +62,7 @@ ColumnLayout { imageId: LRCInstance.currentAccountId avatarSize: 180 + buttonSize: JamiTheme.smartListAvatarSize } MaterialLineEdit { diff --git a/src/wizardview/components/ProfilePage.qml b/src/wizardview/components/ProfilePage.qml index cba86402..a1c13140 100644 --- a/src/wizardview/components/ProfilePage.qml +++ b/src/wizardview/components/ProfilePage.qml @@ -105,6 +105,7 @@ Rectangle { enabled: !saveProfileBtn.spinnerTriggered imageId: createdAccountId avatarSize: 200 + buttonSize: JamiTheme.smartListAvatarSize onFocusOnPreviousItem: { skipProfileSavingButton.forceActiveFocus()