1
0
Fork 0
mirror of https://git.jami.net/savoirfairelinux/jami-client-qt.git synced 2025-07-19 06:55:24 +02:00

swarm: make conversation filters great again

PENDING profile is no longer a valid filter criteria. isReqeust is
now used instead and the profile type is restricted to account
types and tracked as a separate property.

Change-Id: I4848e32f005ea7a6a8b5f2fa25d40b7e1e4d63b8
This commit is contained in:
Andreas Traczyk 2021-06-18 13:48:21 -04:00
parent 0e602266c8
commit 85bbcf37d6
7 changed files with 80 additions and 43 deletions

View file

@ -102,20 +102,39 @@ ConversationListProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex& s
flags |= URI::Section::SCHEME; flags |= URI::Section::SCHEME;
} }
rx.setPattern(uriStripper.format(flags)); rx.setPattern(uriStripper.format(flags));
auto uri = index.data(ConversationList::Role::URI).toString();
auto alias = index.data(ConversationList::Role::Alias).toString(); using namespace ConversationList;
auto registeredName = index.data(ConversationList::Role::RegisteredName).toString();
auto itemProfileType = index.data(ConversationList::Role::ContactType).toInt(); // name/id
auto typeFilter = static_cast<profile::Type>(itemProfileType) == currentTypeFilter_; 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}; bool match {false};
if (index.data(ConversationList::Role::IsBanned).toBool()) {
// banned contacts require exact match
if (index.data(Role::IsBanned).toBool()) {
match = !rx.isEmpty() match = !rx.isEmpty()
&& (rx.exactMatch(uri) || rx.exactMatch(alias) || rx.exactMatch(registeredName)); && (rx.exactMatch(uri) || rx.exactMatch(alias) || rx.exactMatch(registeredName));
} else { } else {
match = (rx.indexIn(uri) != -1 || rx.indexIn(alias) != -1 match = (rx.indexIn(uri) != -1 || rx.indexIn(alias) != -1
|| rx.indexIn(registeredName) != -1); || rx.indexIn(registeredName) != -1);
} }
return typeFilter && match;
return typeFilter && requestFilter && match;
} }
bool bool
@ -128,10 +147,24 @@ ConversationListProxyModel::lessThan(const QModelIndex& left, const QModelIndex&
} }
void 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(); beginResetModel();
currentTypeFilter_ = typeFilter; profileTypeFilter_ = profileTypeFilter;
endResetModel();
updateSelection();
};
void
ConversationListProxyModel::setFilterRequests(bool filterRequests)
{
beginResetModel();
filterRequests_ = filterRequests;
endResetModel(); endResetModel();
updateSelection(); updateSelection();
}; };

View file

@ -48,8 +48,16 @@ public:
bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override; bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override;
bool lessThan(const QModelIndex& left, const QModelIndex& right) 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: 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};
}; };

View file

@ -165,6 +165,9 @@ ConversationListModelBase::dataForItem(item_t item, int role) const
} }
return QVariant(""); return QVariant("");
} }
case Role::IsRequest: {
return QVariant(item.isRequest);
}
} }
return QVariant(); return QVariant();
} }

View file

@ -44,7 +44,8 @@
X(SectionName) \ X(SectionName) \
X(AccountId) \ X(AccountId) \
X(PictureUid) \ X(PictureUid) \
X(Draft) X(Draft) \
X(IsRequest)
namespace ConversationList { namespace ConversationList {
Q_NAMESPACE Q_NAMESPACE

View file

@ -33,7 +33,6 @@ ConversationsAdapter::ConversationsAdapter(SystemTray* systemTray,
LRCInstance* instance, LRCInstance* instance,
QObject* parent) QObject* parent)
: QmlAdapterBase(instance, parent) : QmlAdapterBase(instance, parent)
, currentTypeFilter_(profile::Type::JAMI)
, systemTray_(systemTray) , systemTray_(systemTray)
, convSrcModel_(new ConversationListModel(lrcInstance_)) , convSrcModel_(new ConversationListModel(lrcInstance_))
, convModel_(new ConversationListProxyModel(convSrcModel_.get())) , convModel_(new ConversationListProxyModel(convSrcModel_.get()))
@ -45,9 +44,16 @@ ConversationsAdapter::ConversationsAdapter(SystemTray* systemTray,
new SelectableListProxyGroupModel({convModel_.data(), searchModel_.data()}, this); new SelectableListProxyGroupModel({convModel_.data(), searchModel_.data()}, this);
setTypeFilter(currentTypeFilter_); // this will trigger when the conversations filter tab is selected
connect(this, &ConversationsAdapter::currentTypeFilterChanged, [this]() { connect(this, &ConversationsAdapter::profileTypeFilterChanged, [this]() {
setTypeFilter(currentTypeFilter_); 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]() { connect(lrcInstance_, &LRCInstance::selectedConvUidChanged, [this]() {
@ -73,7 +79,7 @@ ConversationsAdapter::ConversationsAdapter(SystemTray* systemTray,
auto& contact = accInfo.contactModel->getContact(convInfo.participants.front()); auto& contact = accInfo.contactModel->getContact(convInfo.participants.front());
if (contact.profileInfo.type != profile::Type::INVALID if (contact.profileInfo.type != profile::Type::INVALID
&& contact.profileInfo.type != profile::Type::TEMPORARY) && contact.profileInfo.type != profile::Type::TEMPORARY)
set_currentTypeFilter(contact.profileInfo.type); set_profileTypeFilter(contact.profileInfo.type);
} catch (const std::out_of_range& e) { } catch (const std::out_of_range& e) {
qWarning() << e.what(); qWarning() << e.what();
} }
@ -167,7 +173,7 @@ ConversationsAdapter::safeInit()
connectConversationModel(); connectConversationModel();
set_currentTypeFilter(lrcInstance_->getCurrentAccountInfo().profileInfo.type); set_profileTypeFilter(lrcInstance_->getCurrentAccountInfo().profileInfo.type);
} }
void void
@ -177,7 +183,7 @@ ConversationsAdapter::onCurrentAccountIdChanged()
connectConversationModel(); connectConversationModel();
set_currentTypeFilter(lrcInstance_->getCurrentAccountInfo().profileInfo.type); set_profileTypeFilter(lrcInstance_->getCurrentAccountInfo().profileInfo.type);
} }
void void
@ -346,8 +352,8 @@ ConversationsAdapter::updateConversationFilterData()
} }
set_totalUnreadMessageCount(totalUnreadMessages); set_totalUnreadMessageCount(totalUnreadMessages);
set_pendingRequestCount(accountInfo.conversationModel->pendingRequestCount()); set_pendingRequestCount(accountInfo.conversationModel->pendingRequestCount());
if (pendingRequestCount_ == 0 && currentTypeFilter_ == profile::Type::PENDING) { if (pendingRequestCount_ == 0 && profileTypeFilter_ == profile::Type::PENDING) {
set_currentTypeFilter(profile::Type::JAMI); set_profileTypeFilter(profile::Type::JAMI);
} }
} }
@ -358,12 +364,6 @@ ConversationsAdapter::setFilter(const QString& filterString)
searchSrcModel_->setFilter(filterString); searchSrcModel_->setFilter(filterString);
} }
void
ConversationsAdapter::setTypeFilter(const profile::Type& typeFilter)
{
convModel_->setTypeFilter(typeFilter);
}
QVariantMap QVariantMap
ConversationsAdapter::getConvInfoMap(const QString& convId) ConversationsAdapter::getConvInfoMap(const QString& convId)
{ {
@ -414,7 +414,7 @@ ConversationsAdapter::getConvInfoMap(const QString& convId)
} }
bool bool
ConversationsAdapter::connectConversationModel(bool updateFilter) ConversationsAdapter::connectConversationModel()
{ {
// Signal connections // Signal connections
auto currentConversationModel = lrcInstance_->getCurrentConversationModel(); auto currentConversationModel = lrcInstance_->getCurrentConversationModel();
@ -467,10 +467,6 @@ ConversationsAdapter::connectConversationModel(bool updateFilter)
&ConversationsAdapter::onSearchResultUpdated, &ConversationsAdapter::onSearchResultUpdated,
Qt::UniqueConnection); Qt::UniqueConnection);
if (updateFilter) {
currentTypeFilter_ = profile::Type::INVALID;
}
convSrcModel_.reset(new ConversationListModel(lrcInstance_)); convSrcModel_.reset(new ConversationListModel(lrcInstance_));
convModel_->bindSourceModel(convSrcModel_.get()); convModel_->bindSourceModel(convSrcModel_.get());
searchSrcModel_.reset(new SearchResultsListModel(lrcInstance_)); searchSrcModel_.reset(new SearchResultsListModel(lrcInstance_));

View file

@ -33,7 +33,8 @@ class SystemTray;
class ConversationsAdapter final : public QmlAdapterBase class ConversationsAdapter final : public QmlAdapterBase
{ {
Q_OBJECT 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, totalUnreadMessageCount)
QML_PROPERTY(int, pendingRequestCount) QML_PROPERTY(int, pendingRequestCount)
@ -47,9 +48,8 @@ protected:
void safeInit() override; void safeInit() override;
public: public:
Q_INVOKABLE bool connectConversationModel(bool updateFilter = true); Q_INVOKABLE bool connectConversationModel();
Q_INVOKABLE void setFilter(const QString& filterString); Q_INVOKABLE void setFilter(const QString& filterString);
Q_INVOKABLE void setTypeFilter(const profile::Type& typeFilter);
Q_INVOKABLE QVariantMap getConvInfoMap(const QString& convId); Q_INVOKABLE QVariantMap getConvInfoMap(const QString& convId);
Q_SIGNALS: Q_SIGNALS:

View file

@ -31,8 +31,6 @@ import "../../commoncomponents"
TabBar { TabBar {
id: tabBar id: tabBar
property int currentTypeFilter: ConversationsAdapter.currentTypeFilter
currentIndex: 0 currentIndex: 0
enum TabIndex { enum TabIndex {
@ -40,17 +38,15 @@ TabBar {
Requests Requests
} }
function selectTab(tabIndex) { function selectTab(idx) {
ConversationsAdapter.currentTypeFilter = ConversationsAdapter.profileTypeFilter = LRCInstance.currentAccountType
(tabIndex === SidePanelTabBar.Conversations) ? ConversationsAdapter.filterRequests = (idx === SidePanelTabBar.Requests)
LRCInstance.currentAccountType :
Profile.Type.PENDING
} }
FilterTabButton { FilterTabButton {
id: conversationsTabButton id: conversationsTabButton
down: currentTypeFilter !== Profile.Type.PENDING down: !ConversationsAdapter.filterRequests
tabBar: parent tabBar: parent
labelText: JamiStrings.conversations labelText: JamiStrings.conversations
onSelected: selectTab(SidePanelTabBar.Conversations) onSelected: selectTab(SidePanelTabBar.Conversations)