Skip to content
Snippets Groups Projects
Commit 68e8ad46 authored by Sébastien Blin's avatar Sébastien Blin
Browse files

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
parent 303639fe
No related branches found
No related tags found
No related merge requests found
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><circle cx="12" cy="12" r="3.2"/><path d="M9 2L7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-3.17L15 2H9zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<g id="Icones_Outline">
<g id="Camera_Black_24dp">
<g id="Ico_Camera" transform="translate(2.000000, 4.000000)">
<g id="Fill-1">
<path d="M1.6,16.3c-0.4,0-0.8-0.2-1.1-0.5c-0.2-0.2-0.4-0.6-0.4-0.9l0-0.2l0-11C0,3.4,0.2,3,0.5,2.7C0.7,2.4,1,2.3,1.3,2.2
l0.2,0l4.4,0l1.2-2.5h5.7l1.2,2.5h4.3c0.4,0,0.8,0.2,1.1,0.5c0.2,0.2,0.4,0.6,0.4,0.9l0,0.2l0,11c0,0.4-0.2,0.8-0.5,1.1
c-0.2,0.2-0.6,0.4-0.9,0.4l-0.2,0L1.6,16.3z M1.6,3.7L1.6,3.7l-0.1,11l0,0.1l17,0l0.1,0l0-11l0-0.1l-5.3,0L12,1.2H8L6.8,3.7H1.6
z M10,13.4c-1.2,0-2.3-0.5-3.2-1.3c-0.8-0.8-1.3-2-1.3-3.2c0-1.2,0.5-2.3,1.3-3.2c0.8-0.8,2-1.3,3.2-1.3c1.2,0,2.3,0.5,3.2,1.3
c0.8,0.8,1.3,2,1.3,3.2s-0.5,2.3-1.3,3.2C12.3,12.9,11.2,13.4,10,13.4z M10,5.9c-0.8,0-1.6,0.3-2.1,0.9S7,8.1,7,8.9
c0,0.8,0.3,1.6,0.9,2.1c1.1,1.1,3.1,1.1,4.3,0c0.6-0.6,0.9-1.3,0.9-2.1c0-0.8-0.3-1.6-0.9-2.1C11.6,6.2,10.8,5.9,10,5.9z"/>
</g>
</g>
</g>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" fill="white"/><path d="M0 0h24v24H0z" fill="none"/></svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<path d="M20.9,4.6H15V4.2C15,3,14,2,12.8,2h-1.6C10,2,9,3,9,4.2v0.3H3.1c-0.4,0-0.7,0.3-0.7,0.7s0.3,0.7,0.7,0.7h1.4l0.7,13.8
C5.2,21,6.3,22,7.6,22h8.9c1.3,0,2.4-1,2.4-2.3l0.7-13.8h1.4c0.4,0,0.7-0.3,0.7-0.7S21.3,4.6,20.9,4.6z M10.3,4.6V4.2
c0-0.5,0.4-0.8,0.8-0.8h1.6c0.5,0,0.8,0.4,0.8,0.8v0.3H10.3z M18.1,5.9l-0.7,13.7c0,0.6-0.5,1-1,1H7.6c-0.6,0-1-0.4-1-1L5.8,5.9
H18.1z"/>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0V0z"/><path d="M10.59 4.59C10.21 4.21 9.7 4 9.17 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8l-1.41-1.41z"/></svg>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.3.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 24 24" style="enable-background:new 0 0 24 24;" xml:space="preserve">
<path d="M20.7,8.5c-0.1-1.3-1.1-2.3-2.4-2.3h-5.6c-0.3,0-0.7-0.2-0.9-0.5l-0.5-0.8c-0.4-0.7-1.2-1.2-2-1.2H5.7
c-1.3,0-2.4,1.1-2.4,2.4l0.1,2.3c-0.4,0-0.7,0.2-1,0.5C2.2,9.2,2,9.6,2,10c0,0.1,0,0.2,0,0.3l1.1,7.9c0.2,1.2,1.2,2.1,2.4,2.1h13.1
c1.2,0,2.2-0.9,2.4-2.1l1.1-7.9C22.1,9.4,21.5,8.6,20.7,8.5z M5.7,5.1h3.6c0.4,0,0.7,0.2,0.9,0.5l0.5,0.8c0.4,0.7,1.2,1.2,2,1.2h5.6
c0.5,0,0.9,0.4,1,0.9H4.8L4.7,6.2l0,0C4.7,5.6,5.2,5.1,5.7,5.1z M19.5,18c-0.1,0.5-0.5,0.9-1,0.9H5.5c-0.5,0-0.9-0.4-1-0.9l-1.1-8
c0-0.1,0-0.1,0.1-0.2c0,0,0.1-0.1,0.1-0.1l16.9,0c0.1,0,0.2,0.1,0.2,0.2L19.5,18z"/>
</svg>
......@@ -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
spacing: JamiTheme.preferredMarginSize / 2
Item {
id: imageLayer
Layout.preferredWidth: avatarSize
Layout.preferredHeight: avatarSize
Layout.alignment: Qt.AlignHCenter
Avatar {
id: avatar
anchors.fill: parent
anchors.margins: 1
visible: !preview.visible
Item {
id: imageLayer
mode: newConversation? Avatar.Mode.Conversation : Avatar.Mode.Account
fillMode: Image.PreserveAspectCrop
showPresenceIndicator: false
}
anchors.centerIn: parent
width: avatarSize
height: avatarSize
LocalVideo {
id: preview
Avatar {
id: avatar
anchors.fill: parent
anchors.margins: 1
anchors.fill: parent
anchors.margins: 1
visible: isPreviewing
mode: newConversation? Avatar.Mode.Conversation : Avatar.Mode.Account
rendererId: VideoDevices.getDefaultDevice()
fillMode: Image.PreserveAspectCrop
showPresenceIndicator: false
function takePhoto() {
return videoProvider.captureVideoFrame(videoSink)
HoverHandler {
target: parent
enabled: parent.visible
onHoveredChanged: {
overlayHighlighted.visible = hovered
}
}
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
from: 0
duration: JamiTheme.shortFadeDuration
}
NumberAnimation {
target: flashRect; property: "opacity"
to: 0; duration: 500
}
Image {
id: overlayImage
width: JamiTheme.smartListAvatarSize / 2
height: JamiTheme.smartListAvatarSize / 2
anchors.centerIn: parent
layer {
enabled: true
effect: ColorOverlay {
color: "white"
}
}
source: JamiResources.round_edit_24dp_svg
}
}
}
}
RowLayout {
id: buttonsRowLayout
Layout.fillWidth: true
Layout.preferredHeight: childrenRect.height
Layout.bottomMargin: parent.spacing
Layout.alignment: Qt.AlignHCenter
RowLayout {
id: buttonsRowLayout
visible: false
PushButton {
id: takePhotoButton
anchors.centerIn: parent
Layout.preferredHeight: childrenRect.height
spacing: 12
objectName: "takePhotoButton"
function backToAvatar() {
imageLayer.visible = true
buttonsRowLayout.visible = false
}
Layout.alignment: Qt.AlignHCenter
PushButton {
id: takePhotoButton
radius: JamiTheme.primaryRadius
imageColor: JamiTheme.textColor
toolTipText: JamiStrings.takePhoto
source: isPreviewing ?
JamiResources.round_add_a_photo_24dp_svg :
JamiResources.baseline_camera_alt_24dp_svg
objectName: "takePhotoButton"
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
}
}
Layout.alignment: Qt.AlignHCenter
KeyNavigation.tab: {
if (clearButton.visible)
return clearButton
return importButton
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.down: KeyNavigation.tab
onClicked: {
if (isPreviewing) {
flashAnimation.start()
var photo = preview.takePhoto(avatarSize)
if (!root.newConversation)
AccountAdapter.setCurrentAccountAvatarBase64(photo)
else
UtilsAdapter.setSwarmCreationImageFromString(photo, imageId)
stopBooth()
return
}
}
startBooth()
}
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: clearButton
PushButton {
id: importButton
objectName: "photoboothViewClearButton"
objectName: "photoboothViewImportButton"
Layout.alignment: Qt.AlignHCenter
property bool focusAfterFileDialogClosed: false
visible: {
if (isPreviewing)
return true
if (!newConversation && LRCInstance.currentAccountAvatarSet)
return true
if (newConversation && UtilsAdapter.swarmCreationImage(imageId).length !== 0)
return true
return 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
}
}
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
}
}
KeyNavigation.up: takePhotoButton
onClicked: {
stopBooth()
if (!isPreviewing) {
if (!root.newConversation)
AccountAdapter.setCurrentAccountAvatarBase64()
else
UtilsAdapter.setSwarmCreationImageFromString("", imageId)
}
}
onClicked: {
stopBooth()
buttonsRowLayout.backToAvatar()
importFromFileDialog.open()
}
}
PushButton {
id: importButton
objectName: "photoboothViewImportButton"
property bool focusAfterFileDialogClosed: false
PushButton {
id: clearButton
Layout.alignment: Qt.AlignHCenter
objectName: "photoboothViewClearButton"
visible: !isPreviewing
Layout.alignment: Qt.AlignHCenter
radius: JamiTheme.primaryRadius
source: JamiResources.round_folder_24dp_svg
toolTipText: JamiStrings.importFromFile
imageColor: JamiTheme.textColor
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
}
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: 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
}
}
KeyNavigation.up: {
if (clearButton.visible)
return clearButton
return takePhotoButton
}
onClicked: {
if (!root.newConversation)
AccountAdapter.setCurrentAccountAvatarBase64()
else
UtilsAdapter.setSwarmCreationImageFromString("", imageId)
stopBooth()
buttonsRowLayout.backToAvatar()
}
}
onClicked: {
stopBooth()
importFromFileDialog.open()
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()
}
}
}
}
......@@ -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
......
......@@ -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
......
......@@ -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
background: Rectangle {
anchors.fill: parent
visible: !root.isVideo
radius: 5
border.color: JamiTheme.tabbarBorderColor
color: JamiTheme.backgroundColor
}
anchors.centerIn: parent
Item {
anchors.fill: parent
anchors.margins: 0
Rectangle {
id: rectBox
anchors.fill: parent
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
}
}
width: root.width
height: root.height
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
}
x: -offset
y: -offset
LocalVideo {
id: previewWidget
ShapePath {
fillColor: JamiTheme.backgroundColor
visible: parent.visible && !screenshotImg.visible
strokeWidth: 1
strokeColor: JamiTheme.tabbarBorderColor
anchors.fill: rectBox
anchors.margins: 1
startX: -offset + curveRadius
startY: -offset
joinStyle: ShapePath.RoundJoin
rendererId: VideoDevices.getDefaultDevice()
PathLine {
x: width + offset - curveRadius
y: -offset
}
layer.enabled: true
layer.effect: OpacityMask {
maskSource: rectBox
}
PathArc {
x: width + offset
y: -offset + curveRadius
radiusX: curveRadius
radiusY: curveRadius
}
Rectangle {
anchors.fill: parent
color: "black"
opacity: 0.6
visible: root.isPhoto
PathLine {
x: width + offset
y: height + offset - curveRadius
}
PathArc {
x: width + offset - curveRadius
y: height + offset
radiusX: curveRadius
radiusY: curveRadius
layer.enabled: true
layer.effect: OpacityMask {
anchors.centerIn: parent
maskSource: photoMask
invert: true
}
}
}
}
PathLine {
x: width / 2 + 10
y: height + offset
}
PathLine {
x: width / 2
y: height + spikeHeight
}
PathLine {
x: width / 2 - 10
y: height + offset
}
Label {
anchors.centerIn: parent
PathLine {
x: -offset + curveRadius
y: height + offset
}
width: root.width
PathArc {
x: -offset
y: height + offset - curveRadius
radiusX: curveRadius
radiusY: curveRadius
}
visible: (isVideo && VideoDevices.listSize === 0)
PathLine {
x: -offset
y: -offset + curveRadius
onVisibleChanged: {
if (visible) {
closeRecorder()
}
}
PathArc {
x: -offset + curveRadius
y: -offset
radiusX: curveRadius
radiusY: curveRadius
}
text: JamiStrings.previewUnavailable
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
color: JamiTheme.primaryForegroundColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
Rectangle {
id: rectBox
Timer {
id: timer
anchors.fill: parent
visible: (isVideo && VideoDevices.listSize !== 0)
color: JamiTheme.blackColor
radius: 5
interval: 1000
running: false
repeat: true
LocalVideo {
id: previewWidget
onTriggered: updateTimer()
}
anchors.fill: rectBox
anchors.margins: 1
Text {
id: time
rendererId: VideoDevices.getDefaultDevice()
anchors.centerIn: recordButton
anchors.horizontalCenterOffset: (isVideo ? 100 : 0)
anchors.verticalCenterOffset: (isVideo ? 0 : -100)
layer.enabled: true
layer.effect: OpacityMask {
maskSource: rectBox
}
visible: !root.isPhoto
text: "00:00"
color: (isVideo ? JamiTheme.whiteColor : JamiTheme.textColor)
font.pointSize: (isVideo ? 12 : 20)
}
}
Label {
anchors.centerIn: parent
PushButton {
id: recordButton
width: root.width
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 5
visible: (isVideo && VideoDevices.listSize === 0)
preferredSize: btnSize
onVisibleChanged: {
if (visible) {
closeRecorder()
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()
}
}
text: JamiStrings.previewUnavailable
font.pointSize: JamiTheme.settingsFontSize
font.kerning: true
color: JamiTheme.primaryForegroundColor
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
PushButton {
id: screenshotBtn
Timer {
id: timer
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 5
interval: 1000
running: false
repeat: true
preferredSize: btnSize
onTriggered: updateTimer()
}
Text {
id: time
normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor
hoveredColor: Qt.rgba(255, 255, 255, 0.2)
border.width: 1
border.color: imageColor
anchors.centerIn: recordButton
anchors.horizontalCenterOffset: (isVideo ? 100 : 0)
anchors.verticalCenterOffset: (isVideo ? 0 : -100)
source: JamiResources.fiber_manual_record_24dp_svg
imageColor: JamiTheme.whiteColor
visible: true
text: "00:00"
color: (isVideo ? JamiTheme.whiteColor : JamiTheme.textColor)
font.pointSize: (isVideo ? 12 : 20)
}
onClicked: {
root.photo = videoProvider.captureVideoFrame(previewWidget.videoSink)
updateState(RecordBox.States.REC_SUCCESS)
}
}
PushButton {
id: recordButton
PushButton {
id: btnStop
anchors.horizontalCenter: root.horizontalCenter
anchors.bottom: root.bottom
anchors.bottomMargin: 5
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 5
preferredSize: btnSize
preferredSize: btnSize
normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor
normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor
hoveredColor: Qt.rgba(255, 255, 255, 0.2)
source: JamiResources.fiber_manual_record_24dp_svg
imageColor: JamiTheme.recordIconColor
source: JamiResources.stop_24dp_red_svg
imageColor: isVideo ? JamiTheme.whiteColor : JamiTheme.textColor
border.width: 1
border.color: imageColor
onClicked: {
updateState(RecordBox.States.RECORDING)
startRecording()
onClicked: {
if (!root.isPhoto)
stopRecording()
updateState(RecordBox.States.REC_SUCCESS)
}
}
}
PushButton {
id: btnStop
PushButton {
id: btnRestart
anchors.horizontalCenter: root.horizontalCenter
anchors.bottom: root.bottom
anchors.bottomMargin: 5
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: -25
anchors.bottom: parent.bottom
anchors.bottomMargin: 5
preferredSize: btnSize
preferredSize: btnSize
normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor
normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor
source: JamiResources.stop_24dp_red_svg
imageColor: isVideo ? JamiTheme.whiteColor : JamiTheme.textColor
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: {
stopRecording()
updateState(RecordBox.States.REC_SUCCESS)
onClicked: {
if (!root.isPhoto)
stopRecording()
updateState(RecordBox.States.INIT)
}
}
}
PushButton {
id: btnRestart
PushButton {
id: btnSend
anchors.horizontalCenter: root.horizontalCenter
anchors.horizontalCenterOffset: -25
anchors.bottom: root.bottom
anchors.bottomMargin: 5
anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenterOffset: 25
anchors.bottom: parent.bottom
anchors.bottomMargin: 5
preferredSize: btnSize
preferredSize: btnSize
normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor
normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor
source: JamiResources.re_record_24dp_svg
imageColor: isVideo ? JamiTheme.whiteColor : JamiTheme.textColor
source: JamiResources.check_black_24dp_svg
imageColor: isVideo ? JamiTheme.whiteColor : JamiTheme.textColor
border.width: 1
border.color: imageColor
onClicked: {
stopRecording()
updateState(RecordBox.States.INIT)
onClicked: {
if (!root.isPhoto) {
stopRecording()
sendRecord()
} else if (root.photo !== "") {
root.validatePhoto(root.photo)
}
closeRecorder()
updateState(RecordBox.States.INIT)
}
}
}
PushButton {
id: btnSend
PushButton {
id: cancelBtn
anchors.horizontalCenter: root.horizontalCenter
anchors.horizontalCenterOffset: 25
anchors.bottom: parent.bottom
anchors.bottomMargin: 5
normalColor: "transparent"
hoveredColor: Qt.rgba(255, 255, 255, 0.2)
imageColor: JamiTheme.primaryForegroundColor
preferredSize: btnSize
preferredSize: 12
normalColor: isVideo ? "transparent" : JamiTheme.backgroundColor
source: JamiResources.round_close_24dp_svg
toolTipText: JamiStrings.back
source: JamiResources.send_24dp_svg
imageColor: isVideo ? JamiTheme.whiteColor : JamiTheme.textColor
anchors.right: parent.right
anchors.top: parent.top
anchors.margins: 8
onClicked: {
stopRecording()
sendRecord()
closeRecorder()
updateState(RecordBox.States.INIT)
onClicked: {
closeRecorder()
updateState(RecordBox.States.INIT)
}
}
}
}
......@@ -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 {
......
......@@ -62,6 +62,7 @@ ColumnLayout {
imageId: LRCInstance.currentAccountId
avatarSize: 180
buttonSize: JamiTheme.smartListAvatarSize
}
MaterialLineEdit {
......
......@@ -105,6 +105,7 @@ Rectangle {
enabled: !saveProfileBtn.spinnerTriggered
imageId: createdAccountId
avatarSize: 200
buttonSize: JamiTheme.smartListAvatarSize
onFocusOnPreviousItem: {
skipProfileSavingButton.forceActiveFocus()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment