- Fix navigation to login screen upon last account removed

- Implemented navigation to multi accounts
- Implemented navigation back to home screen when removing an account but other remains
- removed focus on "DND" menu entry.
This commit is contained in:
Christophe Deschamps 2024-08-29 18:12:44 +02:00
parent 1cf436263a
commit 08a822991b
8 changed files with 51 additions and 11 deletions

View file

@ -84,6 +84,17 @@ void AccountList::setSelf(QSharedPointer<AccountList> me) {
mModelConnection->makeConnectToModel(&CoreModel::accountAdded, &AccountList::lUpdate); mModelConnection->makeConnectToModel(&CoreModel::accountAdded, &AccountList::lUpdate);
lUpdate(); lUpdate();
mModelConnection->makeConnectToModel(
&CoreModel::accountRemoved,
[this](const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::Account> &account) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
bool wasLast = CoreModel::getInstance()->getCore()->getAccountList().size() == 0;
mModelConnection->invokeToCore([this, wasLast]() {
mustBeInMainThread(log().arg(Q_FUNC_INFO));
emit accountRemoved(wasLast);
});
});
} }
QSharedPointer<AccountCore> AccountList::getDefaultAccountCore() const { QSharedPointer<AccountCore> AccountList::getDefaultAccountCore() const {
@ -114,6 +125,15 @@ AccountGui *AccountList::findAccountByAddress(const QString &address) {
return nullptr; return nullptr;
} }
AccountGui *AccountList::firstAccount() {
for (auto &item : mList) {
if (auto isAccount = item.objectCast<AccountCore>()) {
return new AccountGui(isAccount);
}
}
return nullptr;
}
bool AccountList::getHaveAccount() const { bool AccountList::getHaveAccount() const {
return mHaveAccount; return mHaveAccount;
} }

View file

@ -1,4 +1,4 @@
/* /*
* Copyright (c) 2010-2024 Belledonne Communications SARL. * Copyright (c) 2010-2024 Belledonne Communications SARL.
* *
* This file is part of linphone-desktop * This file is part of linphone-desktop
@ -44,6 +44,7 @@ public:
QSharedPointer<AccountCore> getDefaultAccountCore() const; QSharedPointer<AccountCore> getDefaultAccountCore() const;
void setDefaultAccount(QSharedPointer<AccountCore> account); void setDefaultAccount(QSharedPointer<AccountCore> account);
AccountGui *findAccountByAddress(const QString &address); AccountGui *findAccountByAddress(const QString &address);
AccountGui *firstAccount();
bool getHaveAccount() const; bool getHaveAccount() const;
void setHaveAccount(bool haveAccount); void setHaveAccount(bool haveAccount);
@ -53,6 +54,7 @@ signals:
void lUpdate(); void lUpdate();
void haveAccountChanged(); void haveAccountChanged();
void defaultAccountChanged(); void defaultAccountChanged();
void accountRemoved(bool wasLast);
private: private:
bool mHaveAccount = false; bool mHaveAccount = false;

View file

@ -27,6 +27,7 @@ AccountProxy::AccountProxy(QObject *parent) : SortFilterProxy(parent) {
connect(mAccountList.get(), &AccountList::countChanged, this, &AccountProxy::resetDefaultAccount); connect(mAccountList.get(), &AccountList::countChanged, this, &AccountProxy::resetDefaultAccount);
connect(mAccountList.get(), &AccountList::defaultAccountChanged, this, &AccountProxy::resetDefaultAccount); connect(mAccountList.get(), &AccountList::defaultAccountChanged, this, &AccountProxy::resetDefaultAccount);
connect(mAccountList.get(), &AccountList::haveAccountChanged, this, &AccountProxy::haveAccountChanged); connect(mAccountList.get(), &AccountList::haveAccountChanged, this, &AccountProxy::haveAccountChanged);
connect(mAccountList.get(), &AccountList::accountRemoved, this, &AccountProxy::accountRemoved);
setSourceModel(mAccountList.get()); setSourceModel(mAccountList.get());
sort(0); sort(0);
} }
@ -65,6 +66,10 @@ AccountGui *AccountProxy::findAccountByAddress(const QString &address) {
return dynamic_cast<AccountList *>(sourceModel())->findAccountByAddress(address); return dynamic_cast<AccountList *>(sourceModel())->findAccountByAddress(address);
} }
AccountGui *AccountProxy::firstAccount() {
return dynamic_cast<AccountList *>(sourceModel())->firstAccount();
}
bool AccountProxy::getHaveAccount() const { bool AccountProxy::getHaveAccount() const {
return dynamic_cast<AccountList *>(sourceModel())->getHaveAccount(); return dynamic_cast<AccountList *>(sourceModel())->getHaveAccount();
} }

View file

@ -45,6 +45,7 @@ public:
void setDefaultAccount(AccountGui *account); // TODO void setDefaultAccount(AccountGui *account); // TODO
void resetDefaultAccount(); // Reset the default account to let UI build its new object if needed. void resetDefaultAccount(); // Reset the default account to let UI build its new object if needed.
Q_INVOKABLE AccountGui *findAccountByAddress(const QString &address); Q_INVOKABLE AccountGui *findAccountByAddress(const QString &address);
Q_INVOKABLE AccountGui *firstAccount();
bool getHaveAccount() const; bool getHaveAccount() const;
@ -52,6 +53,7 @@ signals:
void filterTextChanged(); void filterTextChanged();
void defaultAccountChanged(); void defaultAccountChanged();
void haveAccountChanged(); void haveAccountChanged();
void accountRemoved(bool wasLast);
protected: protected:
virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; virtual bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;

View file

@ -59,6 +59,11 @@ Item {
mainItem.contextualMenuOpenedComponent = undefined mainItem.contextualMenuOpenedComponent = undefined
} }
function openAccountSettings(account: AccountGui) {
var page = accountSettingsPageComponent.createObject(parent, {"account": account});
openContextualMenuComponent(page)
}
AccountProxy { AccountProxy {
id: accountProxy id: accountProxy
onDefaultAccountChanged: if (tabbar.currentIndex === 0 && defaultAccount) defaultAccount.core.lResetMissedCalls() onDefaultAccountChanged: if (tabbar.currentIndex === 0 && defaultAccount) defaultAccount.core.lResetMissedCalls()
@ -394,6 +399,10 @@ Item {
id: accounts id: accounts
accountProxy: accountProxy accountProxy: accountProxy
onAddAccountRequest: mainItem.addAccountRequest() onAddAccountRequest: mainItem.addAccountRequest()
onEditAccount: function(account) {
avatarButton.popup.close()
openAccountSettings(account)
}
} }
} }
} }
@ -444,7 +453,7 @@ Item {
iconSize: 32 * DefaultStyle.dp iconSize: 32 * DefaultStyle.dp
text: qsTr("Mon compte") text: qsTr("Mon compte")
iconSource: AppIcons.manageProfile iconSource: AppIcons.manageProfile
onClicked: openContextualMenuComponent(myAccountSettingsPageComponent) onClicked: openAccountSettings(accountProxy.defaultAccount ? accountProxy.defaultAccount : accountProxy.firstAccount())
KeyNavigation.up: visibleChildren.length != 0 ? settingsButtons.getPreviousItem(0) : null KeyNavigation.up: visibleChildren.length != 0 ? settingsButtons.getPreviousItem(0) : null
KeyNavigation.down: visibleChildren.length != 0 ? settingsButtons.getNextItem(0) : null KeyNavigation.down: visibleChildren.length != 0 ? settingsButtons.getNextItem(0) : null
} }
@ -452,7 +461,6 @@ Item {
id: dndButton id: dndButton
Layout.preferredHeight: 32 * DefaultStyle.dp Layout.preferredHeight: 32 * DefaultStyle.dp
Layout.fillWidth: true Layout.fillWidth: true
focus: visible
iconSize: 32 * DefaultStyle.dp iconSize: 32 * DefaultStyle.dp
text: SettingsCpp.dnd ? qsTr("Désactiver ne pas déranger") : qsTr("Activer ne pas déranger") text: SettingsCpp.dnd ? qsTr("Désactiver ne pas déranger") : qsTr("Activer ne pas déranger")
iconSource: AppIcons.bellDnd iconSource: AppIcons.bellDnd
@ -559,9 +567,8 @@ Item {
} }
} }
Component { Component {
id: myAccountSettingsPageComponent id: accountSettingsPageComponent
AccountSettingsPage { AccountSettingsPage {
account: accountProxy.defaultAccount
onGoBack: closeContextualMenuComponent() onGoBack: closeContextualMenuComponent()
} }
} }

View file

@ -49,10 +49,9 @@ AppWindow {
AccountProxy { AccountProxy {
id: accountProxy id: accountProxy
onHaveAccountChanged: { onAccountRemoved:function (wasLast) {
// this function can't be used like this. It will show the main page when if (wasLast) mainWindowStackView.replace(loginPage, StackView.Immediate)
// trying to connect and then return to login page if connection fails. else mainWindowStackView.replace(mainPage, StackView.Immediate)
// initStackViewItem()
} }
} }
StackView { StackView {

View file

@ -19,6 +19,8 @@ Item {
property AccountProxy accountProxy property AccountProxy accountProxy
signal addAccountRequest() signal addAccountRequest()
signal editAccount(AccountGui account)
implicitHeight: list.contentHeight + topPadding + bottomPadding + 32 * DefaultStyle.dp + 1 + newAccountArea.height implicitHeight: list.contentHeight + topPadding + bottomPadding + 32 * DefaultStyle.dp + 1 + newAccountArea.height
ColumnLayout{ ColumnLayout{
id: childLayout id: childLayout
@ -42,6 +44,7 @@ Item {
account: modelData account: modelData
onAvatarClicked: fileDialog.open() onAvatarClicked: fileDialog.open()
onBackgroundClicked: modelData.core.lSetDefaultAccount() onBackgroundClicked: modelData.core.lSetDefaultAccount()
onEdit: editAccount(modelData)
FileDialog { FileDialog {
id: fileDialog id: fileDialog
currentFolder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0] currentFolder: StandardPaths.standardLocations(StandardPaths.PicturesLocation)[0]

View file

@ -15,6 +15,7 @@ Rectangle{
signal avatarClicked() signal avatarClicked()
signal backgroundClicked() signal backgroundClicked()
signal edit()
height: 45 * DefaultStyle.dp height: 45 * DefaultStyle.dp
MouseArea{ MouseArea{
@ -148,9 +149,10 @@ Rectangle{
width: 24 * DefaultStyle.dp width: 24 * DefaultStyle.dp
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
colorizationColor: DefaultStyle.main2_500main colorizationColor: DefaultStyle.main2_500main
MouseArea{ // TODO MouseArea{
anchors.fill: parent anchors.fill: parent
onClicked: console.log('TODO: Manage!') onClicked: mainItem.edit()
cursorShape: Qt.PointingHandCursor
} }
} }
} }