diff --git a/src/conversationlistmodel.cpp b/src/conversationlistmodel.cpp index 4f896bcaf7e377c1f03725bafd5514e93f62a107..fd0b16c0a83452abdaf7aa89c0e5ce2c745f9e97 100644 --- a/src/conversationlistmodel.cpp +++ b/src/conversationlistmodel.cpp @@ -102,20 +102,39 @@ ConversationListProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex& s flags |= URI::Section::SCHEME; } rx.setPattern(uriStripper.format(flags)); - auto uri = index.data(ConversationList::Role::URI).toString(); - auto alias = index.data(ConversationList::Role::Alias).toString(); - auto registeredName = index.data(ConversationList::Role::RegisteredName).toString(); - auto itemProfileType = index.data(ConversationList::Role::ContactType).toInt(); - auto typeFilter = static_cast<profile::Type>(itemProfileType) == currentTypeFilter_; + + using namespace ConversationList; + + // name/id + auto uri = index.data(Role::URI).toString(); + auto alias = index.data(Role::Alias).toString(); + auto registeredName = index.data(Role::RegisteredName).toString(); + + // account type + auto itemProfileType = static_cast<profile::Type>(index.data(Role::ContactType).toInt()); + // this is workaround for profile::Type including both account types and extended types + // - PENDING is implicitly also JAMI + // - TEMPORARY should never be in this list + if (itemProfileType == profile::Type::PENDING) + itemProfileType = profile::Type::JAMI; + auto typeFilter = itemProfileType == profileTypeFilter_; + + // requests + auto isRequest = index.data(Role::IsRequest).toBool(); + bool requestFilter = filterRequests_ ? isRequest : !isRequest; + bool match {false}; - if (index.data(ConversationList::Role::IsBanned).toBool()) { + + // banned contacts require exact match + if (index.data(Role::IsBanned).toBool()) { match = !rx.isEmpty() && (rx.exactMatch(uri) || rx.exactMatch(alias) || rx.exactMatch(registeredName)); } else { match = (rx.indexIn(uri) != -1 || rx.indexIn(alias) != -1 || rx.indexIn(registeredName) != -1); } - return typeFilter && match; + + return typeFilter && requestFilter && match; } bool @@ -128,10 +147,24 @@ ConversationListProxyModel::lessThan(const QModelIndex& left, const QModelIndex& } void -ConversationListProxyModel::setTypeFilter(const profile::Type& typeFilter) +ConversationListProxyModel::setProfileTypeFilter(const profile::Type& profileTypeFilter) +{ + if (profileTypeFilter != lrc::api::profile::Type::JAMI + && profileTypeFilter != lrc::api::profile::Type::SIP) { + qWarning() << "Profile filter parameter must be an account type"; + return; + } + beginResetModel(); + profileTypeFilter_ = profileTypeFilter; + endResetModel(); + updateSelection(); +}; + +void +ConversationListProxyModel::setFilterRequests(bool filterRequests) { beginResetModel(); - currentTypeFilter_ = typeFilter; + filterRequests_ = filterRequests; endResetModel(); updateSelection(); }; diff --git a/src/conversationlistmodel.h b/src/conversationlistmodel.h index 3e143d740fb79b7e71c9f35081accc2bb44d7901..b41dad1fe898d04e01ff714e95bb8870dba93078 100644 --- a/src/conversationlistmodel.h +++ b/src/conversationlistmodel.h @@ -48,8 +48,16 @@ public: bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override; bool lessThan(const QModelIndex& left, const QModelIndex& right) const override; - Q_INVOKABLE void setTypeFilter(const profile::Type& typeFilter); + Q_INVOKABLE void setProfileTypeFilter(const profile::Type& profileTypeFilter); + Q_INVOKABLE void setFilterRequests(bool filterRequests); private: - profile::Type currentTypeFilter_; + // With swarm in place, this filter should only ever be set to profile::Type::JAMI + // and profile::Type::SIP as profile::Type::PENDING should no longer be used to + // filter for invites, and instead use the isRequest property of a conversation. + profile::Type profileTypeFilter_; + + // This flag can be toggled when switching tabs to show the current account's + // conversation invites. + bool filterRequests_ {false}; }; diff --git a/src/conversationlistmodelbase.cpp b/src/conversationlistmodelbase.cpp index b896f8db1a3a79bd6921f31d485e07c25903bef9..7a05374091c33911e752cc99f37dce43514a35f5 100644 --- a/src/conversationlistmodelbase.cpp +++ b/src/conversationlistmodelbase.cpp @@ -165,6 +165,9 @@ ConversationListModelBase::dataForItem(item_t item, int role) const } return QVariant(""); } + case Role::IsRequest: { + return QVariant(item.isRequest); + } } return QVariant(); } diff --git a/src/conversationlistmodelbase.h b/src/conversationlistmodelbase.h index 8940b81214f4642af118fb12a63925687a84047b..45ef4c912b63e9bbd5575ced9567c74e139f082b 100644 --- a/src/conversationlistmodelbase.h +++ b/src/conversationlistmodelbase.h @@ -44,7 +44,8 @@ X(SectionName) \ X(AccountId) \ X(PictureUid) \ - X(Draft) + X(Draft) \ + X(IsRequest) namespace ConversationList { Q_NAMESPACE diff --git a/src/conversationsadapter.cpp b/src/conversationsadapter.cpp index 263a172411ca218c181bab4a9aa7084f48cc3c5c..bddfb44979be7f3ef995fb291e1c9fa316820e16 100644 --- a/src/conversationsadapter.cpp +++ b/src/conversationsadapter.cpp @@ -33,7 +33,6 @@ ConversationsAdapter::ConversationsAdapter(SystemTray* systemTray, LRCInstance* instance, QObject* parent) : QmlAdapterBase(instance, parent) - , currentTypeFilter_(profile::Type::JAMI) , systemTray_(systemTray) , convSrcModel_(new ConversationListModel(lrcInstance_)) , convModel_(new ConversationListProxyModel(convSrcModel_.get())) @@ -45,9 +44,16 @@ ConversationsAdapter::ConversationsAdapter(SystemTray* systemTray, new SelectableListProxyGroupModel({convModel_.data(), searchModel_.data()}, this); - setTypeFilter(currentTypeFilter_); - connect(this, &ConversationsAdapter::currentTypeFilterChanged, [this]() { - setTypeFilter(currentTypeFilter_); + // this will trigger when the conversations filter tab is selected + connect(this, &ConversationsAdapter::profileTypeFilterChanged, [this]() { + convModel_->setProfileTypeFilter(profileTypeFilter_); + }); + set_profileTypeFilter(profile::Type::JAMI); + + // this will trigger when the invite filter tab is selected + connect(this, &ConversationsAdapter::filterRequestsChanged, [this]() { + // it is assumed that profileTypeFilter is profile::Type::JAMI here + convModel_->setFilterRequests(filterRequests_); }); connect(lrcInstance_, &LRCInstance::selectedConvUidChanged, [this]() { @@ -73,7 +79,7 @@ ConversationsAdapter::ConversationsAdapter(SystemTray* systemTray, auto& contact = accInfo.contactModel->getContact(convInfo.participants.front()); if (contact.profileInfo.type != profile::Type::INVALID && contact.profileInfo.type != profile::Type::TEMPORARY) - set_currentTypeFilter(contact.profileInfo.type); + set_profileTypeFilter(contact.profileInfo.type); } catch (const std::out_of_range& e) { qWarning() << e.what(); } @@ -167,7 +173,7 @@ ConversationsAdapter::safeInit() connectConversationModel(); - set_currentTypeFilter(lrcInstance_->getCurrentAccountInfo().profileInfo.type); + set_profileTypeFilter(lrcInstance_->getCurrentAccountInfo().profileInfo.type); } void @@ -177,7 +183,7 @@ ConversationsAdapter::onCurrentAccountIdChanged() connectConversationModel(); - set_currentTypeFilter(lrcInstance_->getCurrentAccountInfo().profileInfo.type); + set_profileTypeFilter(lrcInstance_->getCurrentAccountInfo().profileInfo.type); } void @@ -346,8 +352,8 @@ ConversationsAdapter::updateConversationFilterData() } set_totalUnreadMessageCount(totalUnreadMessages); set_pendingRequestCount(accountInfo.conversationModel->pendingRequestCount()); - if (pendingRequestCount_ == 0 && currentTypeFilter_ == profile::Type::PENDING) { - set_currentTypeFilter(profile::Type::JAMI); + if (pendingRequestCount_ == 0 && profileTypeFilter_ == profile::Type::PENDING) { + set_profileTypeFilter(profile::Type::JAMI); } } @@ -358,12 +364,6 @@ ConversationsAdapter::setFilter(const QString& filterString) searchSrcModel_->setFilter(filterString); } -void -ConversationsAdapter::setTypeFilter(const profile::Type& typeFilter) -{ - convModel_->setTypeFilter(typeFilter); -} - QVariantMap ConversationsAdapter::getConvInfoMap(const QString& convId) { @@ -414,7 +414,7 @@ ConversationsAdapter::getConvInfoMap(const QString& convId) } bool -ConversationsAdapter::connectConversationModel(bool updateFilter) +ConversationsAdapter::connectConversationModel() { // Signal connections auto currentConversationModel = lrcInstance_->getCurrentConversationModel(); @@ -467,10 +467,6 @@ ConversationsAdapter::connectConversationModel(bool updateFilter) &ConversationsAdapter::onSearchResultUpdated, Qt::UniqueConnection); - if (updateFilter) { - currentTypeFilter_ = profile::Type::INVALID; - } - convSrcModel_.reset(new ConversationListModel(lrcInstance_)); convModel_->bindSourceModel(convSrcModel_.get()); searchSrcModel_.reset(new SearchResultsListModel(lrcInstance_)); diff --git a/src/conversationsadapter.h b/src/conversationsadapter.h index 4641022c579694c48d0c6973214aa22debd69566..eac72404dea42b0c378f761880b1acbf6f1de5e1 100644 --- a/src/conversationsadapter.h +++ b/src/conversationsadapter.h @@ -33,7 +33,8 @@ class SystemTray; class ConversationsAdapter final : public QmlAdapterBase { Q_OBJECT - QML_PROPERTY(lrc::api::profile::Type, currentTypeFilter) + QML_PROPERTY(lrc::api::profile::Type, profileTypeFilter) + QML_PROPERTY(bool, filterRequests) QML_PROPERTY(int, totalUnreadMessageCount) QML_PROPERTY(int, pendingRequestCount) @@ -47,9 +48,8 @@ protected: void safeInit() override; public: - Q_INVOKABLE bool connectConversationModel(bool updateFilter = true); + Q_INVOKABLE bool connectConversationModel(); Q_INVOKABLE void setFilter(const QString& filterString); - Q_INVOKABLE void setTypeFilter(const profile::Type& typeFilter); Q_INVOKABLE QVariantMap getConvInfoMap(const QString& convId); Q_SIGNALS: diff --git a/src/mainview/components/SidePanelTabBar.qml b/src/mainview/components/SidePanelTabBar.qml index a7f9abd5b7432ad7ad56a7334aa3532af03a2003..1e5141c91179d31705c35346966e9eb5fcf3eae8 100644 --- a/src/mainview/components/SidePanelTabBar.qml +++ b/src/mainview/components/SidePanelTabBar.qml @@ -31,8 +31,6 @@ import "../../commoncomponents" TabBar { id: tabBar - property int currentTypeFilter: ConversationsAdapter.currentTypeFilter - currentIndex: 0 enum TabIndex { @@ -40,17 +38,15 @@ TabBar { Requests } - function selectTab(tabIndex) { - ConversationsAdapter.currentTypeFilter = - (tabIndex === SidePanelTabBar.Conversations) ? - LRCInstance.currentAccountType : - Profile.Type.PENDING + function selectTab(idx) { + ConversationsAdapter.profileTypeFilter = LRCInstance.currentAccountType + ConversationsAdapter.filterRequests = (idx === SidePanelTabBar.Requests) } FilterTabButton { id: conversationsTabButton - down: currentTypeFilter !== Profile.Type.PENDING + down: !ConversationsAdapter.filterRequests tabBar: parent labelText: JamiStrings.conversations onSelected: selectTab(SidePanelTabBar.Conversations)