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:
parent
0e602266c8
commit
85bbcf37d6
7 changed files with 80 additions and 43 deletions
|
@ -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();
|
||||||
};
|
};
|
||||||
|
|
|
@ -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};
|
||||||
};
|
};
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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_));
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Reference in a new issue