From f62a36ac5423489a59954c8cb721b8257ac67081 Mon Sep 17 00:00:00 2001 From: Ming Rui Zhang <mingrui.zhang@savoirfairelinux.com> Date: Mon, 2 Nov 2020 11:44:20 -0500 Subject: [PATCH] wizardview: make user avatar in profile page change accordingly Gitlab: #161 Change-Id: I79d8f5e28f2025bd685ea760cd813eeca2e60c8b --- src/accountadapter.cpp | 33 +++++++++------ src/accountadapter.h | 3 +- src/avatarimageprovider.h | 6 ++- src/commoncomponents/AvatarImage.qml | 15 +++---- src/commoncomponents/PhotoboothView.qml | 50 +++++++++++++++-------- src/wizardview/WizardView.qml | 8 +++- src/wizardview/components/ProfilePage.qml | 38 +++++++++++++---- 7 files changed, 105 insertions(+), 48 deletions(-) diff --git a/src/accountadapter.cpp b/src/accountadapter.cpp index 545eff0a7..ebf0de238 100644 --- a/src/accountadapter.cpp +++ b/src/accountadapter.cpp @@ -100,21 +100,28 @@ AccountAdapter::createJamiAccount(QString registeredName, && !AppSettingsManager::getValue(Settings::Key::NeverShowMeAgain) .toBool(); if (!registeredName.isEmpty()) { - Utils::oneShotConnect(&LRCInstance::accountModel(), - &lrc::api::NewAccountModel::nameRegistrationEnded, - [this, showBackup](const QString& accountId) { - emit LRCInstance::instance().accountListChanged(); - emit accountAdded(showBackup, - LRCInstance::accountModel() - .getAccountList() - .indexOf(accountId)); - }); + QObject::disconnect(registeredNameSavedConnection_); + registeredNameSavedConnection_ = connect( + &LRCInstance::accountModel(), + &lrc::api::NewAccountModel::profileUpdated, + [this, showBackup, addedAccountId = accountId](const QString& accountId) { + if (addedAccountId == accountId) { + emit LRCInstance::instance().accountListChanged(); + emit accountAdded(accountId, + showBackup, + LRCInstance::accountModel().getAccountList().indexOf( + accountId)); + QObject::disconnect(registeredNameSavedConnection_); + } + }); + LRCInstance::accountModel().registerName(accountId, settings["password"].toString(), registeredName); } else { emit LRCInstance::instance().accountListChanged(); - emit accountAdded(showBackup, + emit accountAdded(accountId, + showBackup, LRCInstance::accountModel().getAccountList().indexOf(accountId)); } @@ -175,7 +182,8 @@ AccountAdapter::createSIPAccount(const QVariantMap& settings, QString photoBooth } emit LRCInstance::instance().accountListChanged(); - emit accountAdded(false, + emit accountAdded(accountId, + false, LRCInstance::accountModel().getAccountList().indexOf( accountId)); }); @@ -206,7 +214,8 @@ AccountAdapter::createJAMSAccount(const QVariantMap& settings) Q_UNUSED(accountId) if (!LRCInstance::accountModel().getAccountList().size()) return; - emit accountAdded(false, + emit accountAdded(accountId, + false, LRCInstance::accountModel().getAccountList().indexOf( accountId)); emit LRCInstance::instance().accountListChanged(); diff --git a/src/accountadapter.h b/src/accountadapter.h index 562c38e92..4405e345e 100644 --- a/src/accountadapter.h +++ b/src/accountadapter.h @@ -112,7 +112,7 @@ signals: * send report failure to QML to make it show the right UI state . */ void reportFailure(); - void accountAdded(bool showBackUp, int index); + void accountAdded(QString accountId, bool showBackUp, int index); void contactUnbanned(); private slots: @@ -145,5 +145,6 @@ private: QMetaObject::Connection addedToConferenceConnection_; QMetaObject::Connection accountProfileChangedConnection_; QMetaObject::Connection contactUnbannedConnection_; + QMetaObject::Connection registeredNameSavedConnection_; }; Q_DECLARE_METATYPE(AccountAdapter*) diff --git a/src/avatarimageprovider.h b/src/avatarimageprovider.h index b0cafc1c2..336a22bb3 100644 --- a/src/avatarimageprovider.h +++ b/src/avatarimageprovider.h @@ -49,7 +49,7 @@ public: // Id content -> every after account_ auto idContent = id.mid(id.indexOf(idType) + idType.length() + 1); - if (idContent.isEmpty()) + if (idContent.isEmpty() && idType != "default") return QImage(); if (idType == "account") { @@ -61,6 +61,10 @@ public: return Utils::contactPhoto(conv.participants[0], requestedSize); } else if (idType == "contact") { return Utils::contactPhoto(idContent, requestedSize); + } else if (idType == "fallback") { + return Utils::fallbackAvatar(QString(), idContent, requestedSize); + } else if (idType == "default") { + return Utils::fallbackAvatar(QString(), QString(), requestedSize); } else { auto image = Utils::cropImage(QImage(idContent)); return image.scaled(requestedSize, diff --git a/src/commoncomponents/AvatarImage.qml b/src/commoncomponents/AvatarImage.qml index 28497a438..715350128 100644 --- a/src/commoncomponents/AvatarImage.qml +++ b/src/commoncomponents/AvatarImage.qml @@ -31,6 +31,7 @@ Item { FromContactUri, FromConvUid, FromUrl, + FromTemporaryName, Default } @@ -47,6 +48,10 @@ Item { return "contact_" case AvatarImage.Mode.FromConvUid: return "conversation_" + case AvatarImage.Mode.FromTemporaryName: + return "fallback_" + case AvatarImage.Mode.Default: + return "default_" default: return "" } @@ -56,7 +61,6 @@ Item { property string imageProviderUrl: "image://avatarImage/" + forceUpdateUrl + "_" + imageProviderIdPrefix property string imageId: "" - property string defaultImgUrl: "qrc:/images/default_avatar_overlay.svg" property string forceUpdateUrl: Date.now() property alias presenceStatus: presenceIndicator.status property bool showPresenceIndicator: true @@ -73,15 +77,10 @@ Item { if (mode === AvatarImage.Mode.FromUrl) rootImage.source = imageId - else if (imageId) + else rootImage.source = imageProviderUrl + imageId } - onModeChanged: { - if (mode === AvatarImage.Mode.Default) - rootImage.source = defaultImgUrl - } - Image { id: rootImage @@ -89,6 +88,7 @@ Item { smooth: false antialiasing: true + asynchronous: true sourceSize.width: Math.max(24, width) sourceSize.height: Math.max(24, height) @@ -115,6 +115,7 @@ Item { smooth: false antialiasing: true + asynchronous: true sourceSize.width: Math.max(24, width) sourceSize.height: Math.max(24, height) diff --git a/src/commoncomponents/PhotoboothView.qml b/src/commoncomponents/PhotoboothView.qml index 1b7e2a0ef..c375d4546 100644 --- a/src/commoncomponents/PhotoboothView.qml +++ b/src/commoncomponents/PhotoboothView.qml @@ -8,8 +8,8 @@ import net.jami.Models 1.0 import net.jami.Adapters 1.0 ColumnLayout { - property bool takePhotoState: false - property bool hasAvatar: false + property int photoState: PhotoboothView.PhotoState.Default + property bool avatarSet: false // saveToConfig is to specify whether the image should be saved to account config property bool saveToConfig: false property string fileName: "" @@ -17,14 +17,25 @@ ColumnLayout { property int boothWidth: 224 + enum PhotoState { + Default = 0, + CameraRendering, + Taken + } + readonly property int size: boothWidth + buttonsRowLayout.height + JamiTheme.preferredMarginSize / 2 - function startBooth(force = false){ - hasAvatar = false + function initUI() { + photoState = PhotoboothView.PhotoState.Default + avatarSet = false + setAvatarImage(AvatarImage.Mode.Default, "") + } + + function startBooth(force = false) { AccountAdapter.startPreviewing(force) - takePhotoState = true + photoState = PhotoboothView.PhotoState.CameraRendering } function stopBooth(){ @@ -33,17 +44,18 @@ ColumnLayout { AccountAdapter.stopPreviewing() } } catch(erro){console.log("Exception: " + erro.message)} - - takePhotoState = false } function setAvatarImage(mode = AvatarImage.Mode.FromAccount, imageId = AccountAdapter.currentAccountId){ - if (mode === AvatarImage.Mode.Default) - boothImg = "" - avatarImg.mode = mode + if (mode === AvatarImage.Mode.Default) { + boothImg = "" + avatarImg.updateImage(imageId) + return + } + if (imageId) avatarImg.updateImage(imageId) } @@ -67,6 +79,9 @@ ColumnLayout { "All files") + " (*)"] onAccepted: { + avatarSet = true + photoState = PhotoboothView.PhotoState.Default + fileName = file if (fileName.length === 0) { SettingsAdapter.clearCurrentAvatar() @@ -82,7 +97,7 @@ ColumnLayout { Label { id: avatarLabel - visible: !takePhotoState + visible: photoState !== PhotoboothView.PhotoState.CameraRendering Layout.fillWidth: true Layout.maximumWidth: boothWidth @@ -101,8 +116,6 @@ ColumnLayout { anchors.fill: parent - imageId: AccountAdapter.currentAccountId - showPresenceIndicator: false fillMode: Image.PreserveAspectCrop @@ -139,7 +152,7 @@ ColumnLayout { onHideBooth: stopBooth() - visible: takePhotoState + visible: photoState === PhotoboothView.PhotoState.CameraRendering focus: visible Layout.alignment: Qt.AlignHCenter @@ -201,12 +214,12 @@ ColumnLayout { radius: height / 6 source: { - if(takePhotoState) { + if(photoState === PhotoboothView.PhotoState.Default) { toolTipText = qsTr("Take photo") return cameraAltIconUrl } - if(hasAvatar){ + if(photoState === PhotoboothView.PhotoState.Taken){ toolTipText = qsTr("Retake photo") return refreshIconUrl } else { @@ -216,7 +229,7 @@ ColumnLayout { } onClicked: { - if(!takePhotoState){ + if(photoState !== PhotoboothView.PhotoState.CameraRendering){ startBooth() return } else { @@ -228,7 +241,8 @@ ColumnLayout { setAvatarImage(AvatarImage.Mode.FromUrl, result.url) - hasAvatar = true + photoState = PhotoboothView.PhotoState.Taken + avatarSet = true stopBooth() }) } diff --git a/src/wizardview/WizardView.qml b/src/wizardview/WizardView.qml index e836c060d..96f249a3d 100644 --- a/src/wizardview/WizardView.qml +++ b/src/wizardview/WizardView.qml @@ -80,16 +80,20 @@ Rectangle { Connections{ target: AccountAdapter - function onAccountAdded(showBackUp, index) { + enabled: controlPanelStackView.currentIndex !== WizardView.WizardViewPageIndex.WELCOMEPAGE + + function onAccountAdded(accountId, showBackUp, index) { addedAccountIndex = index AccountAdapter.accountChanged(index) if (showProfile) { changePageQML(WizardView.WizardViewPageIndex.PROFILEPAGE) profilePage.readyToSaveDetails() profilePage.isRdv = isRdv + profilePage.createdAccountId = accountId } else if (controlPanelStackView.currentIndex === WizardView.WizardViewPageIndex.PROFILEPAGE) { profilePage.readyToSaveDetails() profilePage.isRdv = isRdv + profilePage.createdAccountId = accountId } else if (showBackUp) { changePageQML(WizardView.WizardViewPageIndex.BACKUPKEYSPAGE) } else { @@ -382,6 +386,8 @@ Rectangle { changePageQML(WizardView.WizardViewPageIndex.WELCOMEPAGE) needToShowMainViewWindow(addedAccountIndex) } + + profilePage.initializeOnShowUp() } onSaveProfile: { diff --git a/src/wizardview/components/ProfilePage.qml b/src/wizardview/components/ProfilePage.qml index adc7ac5d3..87efaf6cd 100644 --- a/src/wizardview/components/ProfilePage.qml +++ b/src/wizardview/components/ProfilePage.qml @@ -26,12 +26,18 @@ import "../../commoncomponents" Rectangle { id: root + property string createdAccountId: "" property alias profileImg: setAvatarWidget.boothImg property int preferredHeight: profilePageColumnLayout.implicitHeight + property var showBottom: false + property alias displayName: aliasEdit.text + property bool isRdv: false + + signal leavePage + signal saveProfile function initializeOnShowUp() { - setAvatarWidget.hasAvatar = false - setAvatarWidget.setAvatarImage(AvatarImage.Mode.Default, "") + setAvatarWidget.initUI() clearAllTextFields() saveProfileBtn.spinnerTriggered = true } @@ -46,12 +52,10 @@ Rectangle { color: JamiTheme.backgroundColor - signal leavePage - signal saveProfile - - property var showBottom: false - property alias displayName: aliasEdit.text - property bool isRdv: false + onCreatedAccountIdChanged: { + setAvatarWidget.setAvatarImage(AvatarImage.Mode.FromAccount, + createdAccountId) + } ColumnLayout { id: profilePageColumnLayout @@ -102,6 +106,8 @@ Rectangle { MaterialLineEdit { id: aliasEdit + property string lastInitialCharacter: "" + Layout.preferredHeight: fieldLayoutHeight Layout.preferredWidth: fieldLayoutWidth Layout.alignment: Qt.AlignCenter @@ -114,6 +120,22 @@ Rectangle { borderColorMode: MaterialLineEdit.NORMAL fieldLayoutWidth: saveProfileBtn.width + + onTextEdited: { + if (!(setAvatarWidget.avatarSet)) { + if (text.length === 0) { + setAvatarWidget.setAvatarImage(AvatarImage.Mode.FromAccount, + createdAccountId) + return + } + + if (text.length == 1 && text.charAt(0) !== lastInitialCharacter) { + lastInitialCharacter = text.charAt(0) + setAvatarWidget.setAvatarImage(AvatarImage.Mode.FromTemporaryName, + text) + } + } + } } SpinnerButton { -- GitLab