2020-08-03 13:27:42 -04:00
|
|
|
import QtQuick 2.14
|
|
|
|
import QtQuick.Controls 2.14
|
|
|
|
import QtQuick.Layouts 1.14
|
|
|
|
import QtQuick.Controls.Styles 1.4
|
|
|
|
import Qt.labs.platform 1.1
|
|
|
|
import QtGraphicalEffects 1.0
|
|
|
|
import net.jami.Models 1.0
|
2020-09-04 17:53:24 -04:00
|
|
|
import net.jami.Adapters 1.0
|
2020-08-03 13:27:42 -04:00
|
|
|
|
2020-09-03 21:19:10 -04:00
|
|
|
ColumnLayout {
|
2020-08-03 13:27:42 -04:00
|
|
|
property bool takePhotoState: false
|
|
|
|
property bool hasAvatar: false
|
|
|
|
property bool isDefaultIcon: false
|
|
|
|
property string imgBase64: ""
|
|
|
|
property string fileName: ""
|
|
|
|
|
2020-08-10 19:13:28 +02:00
|
|
|
property int boothWidth: 224
|
2020-08-03 13:27:42 -04:00
|
|
|
|
|
|
|
signal imageAcquired
|
|
|
|
signal imageCleared
|
|
|
|
|
|
|
|
function startBooth(force = false){
|
|
|
|
hasAvatar = false
|
2020-09-04 17:53:24 -04:00
|
|
|
AccountAdapter.startPreviewing(force)
|
2020-08-03 13:27:42 -04:00
|
|
|
takePhotoState = true
|
|
|
|
}
|
|
|
|
|
|
|
|
function stopBooth(){
|
|
|
|
try{
|
2020-09-04 17:53:24 -04:00
|
|
|
if(!AccountAdapter.hasVideoCall()) {
|
|
|
|
AccountAdapter.stopPreviewing()
|
2020-08-03 13:27:42 -04:00
|
|
|
}
|
|
|
|
} catch(erro){console.log("Exception: " + erro.message)}
|
|
|
|
|
|
|
|
takePhotoState = false
|
|
|
|
}
|
|
|
|
|
|
|
|
function setAvatarPixmap(avatarPixmapBase64, defaultValue = false){
|
|
|
|
imgBase64 = avatarPixmapBase64
|
|
|
|
stopBooth()
|
|
|
|
if(defaultValue){
|
|
|
|
isDefaultIcon = defaultValue
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
onVisibleChanged: {
|
|
|
|
if(!visible){
|
|
|
|
stopBooth()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
JamiFileDialog{
|
|
|
|
id: importFromFileToAvatar_Dialog
|
|
|
|
|
|
|
|
mode: JamiFileDialog.OpenFile
|
|
|
|
title: qsTr("Choose an image to be the avatar")
|
|
|
|
folder: StandardPaths.writableLocation(StandardPaths.PicturesLocation)
|
|
|
|
|
|
|
|
nameFilters: [ qsTr("Image Files") + " (*.png *.jpg *.jpeg)",qsTr(
|
|
|
|
"All files") + " (*)"]
|
|
|
|
|
|
|
|
onAccepted: {
|
|
|
|
fileName = file
|
2020-09-04 14:51:39 -04:00
|
|
|
if (fileName.length === 0) {
|
2020-08-03 13:27:42 -04:00
|
|
|
imageCleared()
|
|
|
|
return
|
|
|
|
}
|
2020-09-04 14:51:39 -04:00
|
|
|
imgBase64 = UtilsAdapter.getCroppedImageBase64FromFile(
|
|
|
|
UtilsAdapter.getAbsPath(fileName),
|
|
|
|
boothWidth)
|
2020-08-03 13:27:42 -04:00
|
|
|
imageAcquired()
|
|
|
|
stopBooth()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-03 21:19:10 -04:00
|
|
|
Label {
|
2020-08-03 13:27:42 -04:00
|
|
|
id: avatarLabel
|
|
|
|
|
|
|
|
visible: !takePhotoState
|
|
|
|
|
2020-09-08 12:59:34 -04:00
|
|
|
Layout.fillWidth: true
|
|
|
|
Layout.maximumWidth: boothWidth
|
2020-08-10 19:13:28 +02:00
|
|
|
Layout.preferredHeight: boothWidth
|
2020-08-03 13:27:42 -04:00
|
|
|
Layout.alignment: Qt.AlignHCenter
|
|
|
|
|
|
|
|
background: Rectangle {
|
|
|
|
id: avatarLabelBackground
|
|
|
|
|
|
|
|
anchors.fill: parent
|
2020-08-04 20:54:02 -04:00
|
|
|
color: "grey"
|
|
|
|
radius: height / 2
|
2020-08-03 13:27:42 -04:00
|
|
|
|
2020-09-03 21:19:10 -04:00
|
|
|
Image {
|
2020-08-03 13:27:42 -04:00
|
|
|
id: avatarImg
|
|
|
|
|
|
|
|
anchors.fill: parent
|
2020-09-03 21:19:10 -04:00
|
|
|
source: {
|
2020-08-03 13:27:42 -04:00
|
|
|
if(imgBase64.length === 0){
|
2020-08-04 20:54:02 -04:00
|
|
|
return "qrc:/images/default_avatar_overlay.svg"
|
2020-08-03 13:27:42 -04:00
|
|
|
} else {
|
|
|
|
return "data:image/png;base64," + imgBase64
|
|
|
|
}
|
|
|
|
}
|
|
|
|
fillMode: Image.PreserveAspectCrop
|
|
|
|
layer.enabled: true
|
|
|
|
layer.effect: OpacityMask {
|
2020-09-03 21:19:10 -04:00
|
|
|
maskSource: Rectangle {
|
2020-08-03 13:27:42 -04:00
|
|
|
width: avatarImg.width
|
|
|
|
height: avatarImg.height
|
|
|
|
radius: {
|
|
|
|
var size = ((avatarImg.width <= avatarImg.height)? avatarImg.width:avatarImg.height)
|
|
|
|
return size /2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-03 21:19:10 -04:00
|
|
|
PhotoboothPreviewRender {
|
2020-08-03 13:27:42 -04:00
|
|
|
id:previewWidget
|
|
|
|
|
|
|
|
onHideBooth:{
|
|
|
|
stopBooth()
|
|
|
|
}
|
2020-09-03 21:19:10 -04:00
|
|
|
|
2020-08-03 13:27:42 -04:00
|
|
|
visible: takePhotoState
|
|
|
|
focus: visible
|
|
|
|
|
|
|
|
Layout.alignment: Qt.AlignHCenter
|
2020-08-10 19:13:28 +02:00
|
|
|
Layout.preferredWidth: boothWidth
|
|
|
|
Layout.preferredHeight: boothWidth
|
2020-08-03 13:27:42 -04:00
|
|
|
|
|
|
|
layer.enabled: true
|
|
|
|
layer.effect: OpacityMask {
|
2020-09-03 21:19:10 -04:00
|
|
|
maskSource: Rectangle {
|
2020-08-03 13:27:42 -04:00
|
|
|
width: previewWidget.width
|
|
|
|
height: previewWidget.height
|
|
|
|
radius: {
|
|
|
|
var size = ((previewWidget.width <= previewWidget.height)? previewWidget.width:previewWidget.height)
|
|
|
|
return size /2
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-03 21:19:10 -04:00
|
|
|
Label {
|
2020-08-03 13:27:42 -04:00
|
|
|
id: flashOverlay
|
|
|
|
|
|
|
|
anchors.fill: previewWidget
|
|
|
|
visible: false
|
|
|
|
color: "#fff"
|
|
|
|
|
2020-09-08 12:59:34 -04:00
|
|
|
OpacityAnimator on opacity {
|
2020-08-03 13:27:42 -04:00
|
|
|
id: flashAnimation
|
|
|
|
|
|
|
|
from: 1
|
|
|
|
to: 0
|
|
|
|
duration: 600
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-03 21:19:10 -04:00
|
|
|
RowLayout {
|
2020-09-03 09:58:01 -04:00
|
|
|
id: buttonsRowLayout
|
|
|
|
|
2020-08-03 13:27:42 -04:00
|
|
|
Layout.fillWidth: true
|
2020-09-03 09:58:01 -04:00
|
|
|
Layout.alignment: Qt.AlignHCenter
|
2020-09-08 12:59:34 -04:00
|
|
|
Layout.preferredHeight: JamiTheme.preferredFieldHeight
|
2020-09-03 21:19:10 -04:00
|
|
|
Layout.topMargin: JamiTheme.preferredMarginSize / 2
|
2020-08-03 13:27:42 -04:00
|
|
|
|
|
|
|
HoverableButton {
|
|
|
|
id: takePhotoButton
|
|
|
|
|
|
|
|
property string cameraAltIconUrl: "qrc:/images/icons/baseline-camera_alt-24px.svg"
|
|
|
|
property string addPhotoIconUrl: "qrc:/images/icons/round-add_a_photo-24px.svg"
|
|
|
|
property string refreshIconUrl: "qrc:/images/icons/baseline-refresh-24px.svg"
|
|
|
|
|
2020-09-08 12:59:34 -04:00
|
|
|
Layout.preferredWidth: JamiTheme.preferredFieldHeight
|
|
|
|
Layout.preferredHeight: JamiTheme.preferredFieldHeight
|
2020-09-03 09:58:01 -04:00
|
|
|
Layout.alignment: Qt.AlignHCenter
|
2020-08-03 13:27:42 -04:00
|
|
|
|
|
|
|
text: ""
|
|
|
|
font.pointSize: 10
|
|
|
|
font.kerning: true
|
|
|
|
|
2020-08-07 11:24:18 -04:00
|
|
|
toolTipText: qsTr("Press this button to take photo")
|
|
|
|
|
2020-08-03 13:27:42 -04:00
|
|
|
radius: height / 6
|
|
|
|
source: {
|
|
|
|
|
|
|
|
if(takePhotoState) {
|
2020-08-07 11:24:18 -04:00
|
|
|
toolTipText = qsTr("Press this button to finish taking photo")
|
2020-08-03 13:27:42 -04:00
|
|
|
return cameraAltIconUrl
|
|
|
|
}
|
|
|
|
|
|
|
|
if(hasAvatar){
|
2020-08-07 11:24:18 -04:00
|
|
|
toolTipText = qsTr("Press this button to retake photo")
|
2020-08-03 13:27:42 -04:00
|
|
|
return refreshIconUrl
|
|
|
|
} else {
|
2020-08-07 11:24:18 -04:00
|
|
|
toolTipText = qsTr("Press this button to take photo")
|
2020-08-03 13:27:42 -04:00
|
|
|
return addPhotoIconUrl
|
|
|
|
}
|
|
|
|
}
|
|
|
|
onClicked: {
|
|
|
|
if(!takePhotoState){
|
|
|
|
imageCleared()
|
|
|
|
startBooth()
|
|
|
|
return
|
|
|
|
} else {
|
|
|
|
// show flash overlay
|
|
|
|
flashOverlay.visible = true
|
|
|
|
flashAnimation.restart()
|
|
|
|
|
|
|
|
// run concurrent function call to take photo
|
2020-08-10 19:13:28 +02:00
|
|
|
imgBase64 = previewWidget.takeCroppedPhotoToBase64(boothWidth)
|
2020-08-03 13:27:42 -04:00
|
|
|
hasAvatar = true
|
|
|
|
imageAcquired()
|
|
|
|
stopBooth()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
HoverableButton {
|
|
|
|
id: importButton
|
|
|
|
|
2020-09-08 12:59:34 -04:00
|
|
|
Layout.preferredWidth: JamiTheme.preferredFieldHeight
|
|
|
|
Layout.preferredHeight: JamiTheme.preferredFieldHeight
|
2020-09-03 09:58:01 -04:00
|
|
|
Layout.alignment: Qt.AlignHCenter
|
2020-08-03 13:27:42 -04:00
|
|
|
|
|
|
|
text: ""
|
|
|
|
font.pointSize: 10
|
|
|
|
font.kerning: true
|
|
|
|
|
|
|
|
radius: height / 6
|
|
|
|
source: "qrc:/images/icons/round-folder-24px.svg"
|
|
|
|
|
2020-08-07 11:24:18 -04:00
|
|
|
toolTipText: qsTr("Import avatar from image file")
|
|
|
|
|
2020-08-03 13:27:42 -04:00
|
|
|
onClicked: {
|
|
|
|
importFromFileToAvatar_Dialog.open()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|