mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-07-08 09:35:24 +02:00
avatars: add clear feature to photobooth
A property is provided to notify of changes to the content of the current account's stored avatar. If one is stored, then a button used to clear the avatar becomes available. Gitlab: #473 Change-Id: I37640acaea3ca43e5abd14678d68b4eeebb3829e
This commit is contained in:
parent
275530746a
commit
ab4c68adb5
6 changed files with 149 additions and 128 deletions
|
@ -26,39 +26,34 @@ import net.jami.Models 1.0
|
|||
import net.jami.Adapters 1.0
|
||||
import net.jami.Constants 1.0
|
||||
|
||||
ColumnLayout {
|
||||
Item {
|
||||
id: root
|
||||
|
||||
enum Mode { Static, Previewing }
|
||||
property int mode: PhotoboothView.Mode.Static
|
||||
property bool isPreviewing: false
|
||||
property alias imageId: avatar.imageId
|
||||
required property real avatarSize
|
||||
|
||||
property int size: 224
|
||||
|
||||
signal avatarSet
|
||||
width: avatarSize
|
||||
height: boothLayout.height
|
||||
|
||||
function startBooth() {
|
||||
AccountAdapter.startPreviewing(false)
|
||||
mode = PhotoboothView.Mode.Previewing
|
||||
isPreviewing = true
|
||||
}
|
||||
|
||||
function stopBooth(){
|
||||
if (!AccountAdapter.hasVideoCall()) {
|
||||
AccountAdapter.stopPreviewing()
|
||||
}
|
||||
mode = PhotoboothView.Mode.Static
|
||||
isPreviewing = false
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible) {
|
||||
mode = PhotoboothView.Mode.Static
|
||||
} else {
|
||||
if (!visible) {
|
||||
stopBooth()
|
||||
}
|
||||
}
|
||||
|
||||
spacing: 0
|
||||
|
||||
JamiFileDialog {
|
||||
id: importFromFileDialog
|
||||
|
||||
|
@ -74,125 +69,139 @@ ColumnLayout {
|
|||
onAccepted: {
|
||||
var filePath = UtilsAdapter.getAbsPath(file)
|
||||
AccountAdapter.setCurrentAccountAvatarFile(filePath)
|
||||
avatarSet()
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: imageLayer
|
||||
ColumnLayout {
|
||||
id: boothLayout
|
||||
|
||||
Layout.preferredWidth: size
|
||||
Layout.preferredHeight: size
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: JamiTheme.preferredMarginSize / 2
|
||||
|
||||
Avatar {
|
||||
id: avatar
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
|
||||
visible: !preview.visible
|
||||
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
showPresenceIndicator: false
|
||||
}
|
||||
|
||||
PhotoboothPreviewRender {
|
||||
id: preview
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
|
||||
visible: mode === PhotoboothView.Mode.Previewing
|
||||
|
||||
onRenderingStopped: stopBooth()
|
||||
lrcInstance: LRCInstance
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: Rectangle {
|
||||
width: size
|
||||
height: size
|
||||
radius: size / 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: flashRect
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: 0
|
||||
radius: size / 2
|
||||
color: "white"
|
||||
opacity: 0
|
||||
|
||||
SequentialAnimation {
|
||||
id: flashAnimation
|
||||
|
||||
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: JamiTheme.preferredFieldHeight
|
||||
Layout.topMargin: JamiTheme.preferredMarginSize / 2
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
|
||||
PushButton {
|
||||
id: takePhotoButton
|
||||
Item {
|
||||
id: imageLayer
|
||||
|
||||
Layout.preferredWidth: avatarSize
|
||||
Layout.preferredHeight: avatarSize
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
radius: JamiTheme.primaryRadius
|
||||
|
||||
imageColor: JamiTheme.textColor
|
||||
toolTipText: JamiStrings.takePhoto
|
||||
Avatar {
|
||||
id: avatar
|
||||
|
||||
source: mode === PhotoboothView.Mode.Static ?
|
||||
"qrc:/images/icons/baseline-camera_alt-24px.svg" :
|
||||
"qrc:/images/icons/round-add_a_photo-24px.svg"
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
|
||||
onClicked: {
|
||||
if (mode === PhotoboothView.Mode.Previewing) {
|
||||
flashAnimation.start()
|
||||
AccountAdapter.setCurrentAccountAvatarBase64(
|
||||
preview.takePhoto(size))
|
||||
avatarSet()
|
||||
visible: !preview.visible
|
||||
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
showPresenceIndicator: false
|
||||
}
|
||||
|
||||
PhotoboothPreviewRender {
|
||||
id: preview
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: 1
|
||||
|
||||
visible: isPreviewing
|
||||
|
||||
onRenderingStopped: stopBooth()
|
||||
lrcInstance: LRCInstance
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: OpacityMask {
|
||||
maskSource: Rectangle {
|
||||
width: avatarSize
|
||||
height: avatarSize
|
||||
radius: avatarSize / 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
id: flashRect
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.margins: 0
|
||||
radius: avatarSize / 2
|
||||
color: "white"
|
||||
opacity: 0
|
||||
|
||||
SequentialAnimation {
|
||||
id: flashAnimation
|
||||
|
||||
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
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
radius: JamiTheme.primaryRadius
|
||||
imageColor: JamiTheme.textColor
|
||||
toolTipText: JamiStrings.takePhoto
|
||||
source: isPreviewing ?
|
||||
"qrc:/images/icons/round-add_a_photo-24px.svg" :
|
||||
"qrc:/images/icons/baseline-camera_alt-24px.svg"
|
||||
|
||||
onClicked: {
|
||||
if (isPreviewing) {
|
||||
flashAnimation.start()
|
||||
AccountAdapter.setCurrentAccountAvatarBase64(
|
||||
preview.takePhoto(avatarSize))
|
||||
stopBooth()
|
||||
return
|
||||
}
|
||||
|
||||
startBooth()
|
||||
}
|
||||
}
|
||||
|
||||
PushButton {
|
||||
id: clearButton
|
||||
|
||||
visible: LRCInstance.currentAccountAvatarSet
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
radius: JamiTheme.primaryRadius
|
||||
source: "qrc:/images/icons/round-close-24px.svg"
|
||||
toolTipText: JamiStrings.clearAvatar
|
||||
imageColor: JamiTheme.textColor
|
||||
|
||||
onClicked: {
|
||||
stopBooth()
|
||||
return
|
||||
AccountAdapter.setCurrentAccountAvatarBase64()
|
||||
}
|
||||
|
||||
startBooth()
|
||||
}
|
||||
}
|
||||
|
||||
PushButton {
|
||||
id: importButton
|
||||
PushButton {
|
||||
id: importButton
|
||||
|
||||
Layout.preferredWidth: JamiTheme.preferredFieldHeight
|
||||
Layout.preferredHeight: JamiTheme.preferredFieldHeight
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
radius: JamiTheme.primaryRadius
|
||||
source: "qrc:/images/icons/round-folder-24px.svg"
|
||||
toolTipText: JamiStrings.importFromFile
|
||||
imageColor: JamiTheme.textColor
|
||||
|
||||
radius: JamiTheme.primaryRadius
|
||||
source: "qrc:/images/icons/round-folder-24px.svg"
|
||||
|
||||
toolTipText: JamiStrings.importFromFile
|
||||
imageColor: JamiTheme.textColor
|
||||
|
||||
onClicked: {
|
||||
stopBooth()
|
||||
importFromFileDialog.open()
|
||||
onClicked: {
|
||||
stopBooth()
|
||||
importFromFileDialog.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -400,6 +400,7 @@ Item {
|
|||
// PhotoBoothView
|
||||
property string chooseAvatarImage: qsTr("Choose a picture as avatar")
|
||||
property string importFromFile: qsTr("Import avatar from image file")
|
||||
property string clearAvatar: qsTr("Clear avatar image")
|
||||
property string takePhoto: qsTr("Take photo")
|
||||
|
||||
// PluginSettingsPage
|
||||
|
|
|
@ -44,8 +44,21 @@ LRCInstance::LRCInstance(migrateCallback willMigrateCb,
|
|||
accountModel().setTopAccount(currentAccountId_);
|
||||
Q_EMIT accountListChanged();
|
||||
|
||||
auto profileInfo = getCurrentAccountInfo().profileInfo;
|
||||
|
||||
// update type
|
||||
set_currentAccountType(getCurrentAccountInfo().profileInfo.type);
|
||||
set_currentAccountType(profileInfo.type);
|
||||
|
||||
// notify if the avatar is stored locally
|
||||
set_currentAccountAvatarSet(!profileInfo.avatar.isEmpty());
|
||||
});
|
||||
|
||||
connect(&accountModel(), &NewAccountModel::profileUpdated, [this](const QString& id) {
|
||||
if (id != currentAccountId_)
|
||||
return;
|
||||
|
||||
auto profileInfo = getCurrentAccountInfo().profileInfo;
|
||||
set_currentAccountAvatarSet(!getCurrentAccountInfo().profileInfo.avatar.isEmpty());
|
||||
});
|
||||
|
||||
// set the current account if any
|
||||
|
|
|
@ -57,6 +57,7 @@ class LRCInstance : public QObject
|
|||
QML_PROPERTY(QString, selectedConvUid)
|
||||
QML_PROPERTY(QString, currentAccountId)
|
||||
QML_RO_PROPERTY(lrc::api::profile::Type, currentAccountType)
|
||||
QML_PROPERTY(bool, currentAccountAvatarSet)
|
||||
|
||||
public:
|
||||
explicit LRCInstance(migrateCallback willMigrateCb = {},
|
||||
|
|
|
@ -66,12 +66,10 @@ ColumnLayout {
|
|||
PhotoboothView {
|
||||
id: currentAccountAvatar
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
|
||||
imageId: LRCInstance.currentAccountId
|
||||
|
||||
size: 180
|
||||
avatarSize: 180
|
||||
}
|
||||
|
||||
MaterialLineEdit {
|
||||
|
|
|
@ -32,11 +32,10 @@ Rectangle {
|
|||
// trigger a default avatar prior to account generation
|
||||
property string createdAccountId: "dummy"
|
||||
property int preferredHeight: profilePageColumnLayout.implicitHeight
|
||||
property var showBottom: false
|
||||
property bool showBottom: false
|
||||
property alias displayName: aliasEdit.text
|
||||
property bool isRdv: false
|
||||
property alias avatarBooth: setAvatarWidget
|
||||
property bool avatarSet
|
||||
|
||||
signal leavePage
|
||||
signal saveProfile
|
||||
|
@ -45,7 +44,6 @@ Rectangle {
|
|||
createdAccountId = "dummy"
|
||||
clearAllTextFields()
|
||||
saveProfileBtn.spinnerTriggered = true
|
||||
avatarSet = false
|
||||
}
|
||||
|
||||
function clearAllTextFields() {
|
||||
|
@ -99,13 +97,14 @@ Rectangle {
|
|||
id: setAvatarWidget
|
||||
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
Layout.preferredWidth: size
|
||||
Layout.fillHeight: true
|
||||
|
||||
imageId: createdAccountId
|
||||
onAvatarSet: root.avatarSet = true
|
||||
avatarSize: 200
|
||||
|
||||
size: 200
|
||||
onVisibleChanged: {
|
||||
if (visible)
|
||||
LRCInstance.currentAccountAvatarSet = false
|
||||
}
|
||||
}
|
||||
|
||||
MaterialLineEdit {
|
||||
|
@ -127,7 +126,7 @@ Rectangle {
|
|||
fieldLayoutWidth: saveProfileBtn.width
|
||||
|
||||
onTextEdited: {
|
||||
if (root.avatarSet)
|
||||
if (LRCInstance.currentAccountAvatarSet)
|
||||
return
|
||||
if (text.length === 0) {
|
||||
lastFirstChar = ""
|
||||
|
|
Loading…
Add table
Reference in a new issue