Move contacts to an own model
This commit is contained in:
parent
7da8957423
commit
86599b2859
7 changed files with 192 additions and 76 deletions
|
@ -24,6 +24,7 @@ SOURCES += src/harbour-fernschreiber.cpp \
|
|||
src/appsettings.cpp \
|
||||
src/chatlistmodel.cpp \
|
||||
src/chatmodel.cpp \
|
||||
src/contactsmodel.cpp \
|
||||
src/dbusadaptor.cpp \
|
||||
src/dbusinterface.cpp \
|
||||
src/emojisearchworker.cpp \
|
||||
|
@ -146,6 +147,7 @@ HEADERS += \
|
|||
src/appsettings.h \
|
||||
src/chatlistmodel.h \
|
||||
src/chatmodel.h \
|
||||
src/contactsmodel.h \
|
||||
src/dbusadaptor.h \
|
||||
src/dbusinterface.h \
|
||||
src/debuglog.h \
|
||||
|
|
|
@ -26,12 +26,12 @@ Page {
|
|||
id: newChatPage
|
||||
allowedOrientations: Orientation.All
|
||||
|
||||
property var contacts;
|
||||
property bool isLoading: true;
|
||||
|
||||
onStatusChanged: {
|
||||
if (status === PageStatus.Active) {
|
||||
newChatPage.contacts = tdLibWrapper.getContactsFullInfo();
|
||||
contactsModel.hydrateContacts();
|
||||
contactsListView.model = contactsModel;
|
||||
newChatPage.isLoading = false;
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,6 @@ Page {
|
|||
|
||||
SilicaListView {
|
||||
id: contactsListView
|
||||
model: newChatPage.contacts
|
||||
clip: true
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
@ -87,15 +86,15 @@ Page {
|
|||
Behavior on opacity { FadeAnimation {} }
|
||||
|
||||
pictureThumbnail {
|
||||
photoData: (typeof modelData.profile_photo !== "undefined") ? modelData.profile_photo.small : {}
|
||||
photoData: (typeof display.profile_photo !== "undefined") ? display.profile_photo.small : {}
|
||||
}
|
||||
width: parent.width
|
||||
|
||||
primaryText.text: Emoji.emojify(Functions.getUserName(modelData), primaryText.font.pixelSize, "../js/emoji/")
|
||||
prologSecondaryText.text: "@" + ( modelData.username !== "" ? modelData.username : modelData.id )
|
||||
primaryText.text: Emoji.emojify(Functions.getUserName(display), primaryText.font.pixelSize, "../js/emoji/")
|
||||
prologSecondaryText.text: "@" + ( display.username !== "" ? display.username : display.id )
|
||||
tertiaryText {
|
||||
maximumLineCount: 1
|
||||
text: Functions.getChatPartnerStatusText(modelData.status["@type"], modelData.status.was_online);
|
||||
text: Functions.getChatPartnerStatusText(display.status["@type"], display.status.was_online);
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
|
@ -159,7 +158,7 @@ Page {
|
|||
icon.source: "image://theme/icon-m-chat"
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
onClicked: {
|
||||
tdLibWrapper.createPrivateChat(modelData.id);
|
||||
tdLibWrapper.createPrivateChat(display.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -196,7 +195,7 @@ Page {
|
|||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
tdLibWrapper.createPrivateChat(modelData.id);
|
||||
tdLibWrapper.createPrivateChat(display.id);
|
||||
}
|
||||
onPressed: {
|
||||
privateChatHighlightBackground.visible = true;
|
||||
|
|
118
src/contactsmodel.cpp
Normal file
118
src/contactsmodel.cpp
Normal file
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||
|
||||
This file is part of Fernschreiber.
|
||||
|
||||
Fernschreiber is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Fernschreiber is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "contactsmodel.h"
|
||||
#include <QListIterator>
|
||||
|
||||
#define DEBUG_MODULE ContactsModel
|
||||
#include "debuglog.h"
|
||||
|
||||
namespace {
|
||||
const QString STATUS("status");
|
||||
const QString ID("id");
|
||||
const QString TYPE("type");
|
||||
const QString LAST_NAME("last_name");
|
||||
const QString FIRST_NAME("first_name");
|
||||
const QString USERNAME("username");
|
||||
const QString _TYPE("@type");
|
||||
const QString _EXTRA("@extra");
|
||||
}
|
||||
|
||||
ContactsModel::ContactsModel(TDLibWrapper *tdLibWrapper, QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
this->tdLibWrapper = tdLibWrapper;
|
||||
|
||||
connect(this->tdLibWrapper, SIGNAL(usersReceived(QString, QVariantList, int)), this, SLOT(handleUsersReceived(QString, QVariantList, int)));
|
||||
}
|
||||
|
||||
int ContactsModel::rowCount(const QModelIndex &) const
|
||||
{
|
||||
return this->contacts.size();
|
||||
}
|
||||
|
||||
QVariant ContactsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (index.isValid() && role == Qt::DisplayRole) {
|
||||
return QVariant(contacts.value(index.row()));
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void ContactsModel::handleUsersReceived(const QString &extra, const QVariantList &userIds, int totalUsers)
|
||||
{
|
||||
if (extra == "contactsRequested") {
|
||||
LOG("Received contacts list..." << totalUsers);
|
||||
this->contactIds.clear();
|
||||
QListIterator<QVariant> userIdIterator(userIds);
|
||||
while (userIdIterator.hasNext()) {
|
||||
QString nextUserId = userIdIterator.next().toString();
|
||||
if (!this->tdLibWrapper->hasUserInformation(nextUserId)) {
|
||||
this->tdLibWrapper->getUserFullInfo(nextUserId);
|
||||
}
|
||||
this->contactIds.append(nextUserId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool compareUsers(const QVariant &user1, const QVariant &user2)
|
||||
{
|
||||
const QVariantMap userMap1 = user1.toMap();
|
||||
const QVariantMap userMap2 = user2.toMap();
|
||||
|
||||
const QString lastName1 = userMap1.value(LAST_NAME).toString();
|
||||
const QString lastName2 = userMap2.value(LAST_NAME).toString();
|
||||
if (!lastName1.isEmpty()) {
|
||||
if (lastName1 < lastName2) {
|
||||
return true;
|
||||
} else if (lastName1 > lastName2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const QString firstName1 = userMap1.value(FIRST_NAME).toString();
|
||||
const QString firstName2 = userMap2.value(FIRST_NAME).toString();
|
||||
if (firstName1 < firstName2) {
|
||||
return true;
|
||||
} else if (firstName1 > firstName2) {
|
||||
return false;
|
||||
}
|
||||
const QString userName1 = userMap1.value(USERNAME).toString();
|
||||
const QString userName2 = userMap2.value(USERNAME).toString();
|
||||
if (userName1 < userName2) {
|
||||
return true;
|
||||
} else if (userName1 > userName2) {
|
||||
return false;
|
||||
}
|
||||
return userMap1.value(ID).toLongLong() < userMap2.value(ID).toLongLong();
|
||||
}
|
||||
|
||||
void ContactsModel::hydrateContacts()
|
||||
{
|
||||
LOG("Hydrating contacts...");
|
||||
this->contacts.clear();
|
||||
QListIterator<QString> userIdIterator(contactIds);
|
||||
while (userIdIterator.hasNext()) {
|
||||
QString nextUserId = userIdIterator.next();
|
||||
LOG("Hydrating contact:" << nextUserId);
|
||||
this->contacts.append(this->tdLibWrapper->getUserInformation(nextUserId));
|
||||
}
|
||||
LOG("Hydrated contacts:" << this->contacts.size());
|
||||
std::sort(this->contacts.begin(), this->contacts.end(), compareUsers);
|
||||
}
|
48
src/contactsmodel.h
Normal file
48
src/contactsmodel.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
Copyright (C) 2020 Sebastian J. Wolf and other contributors
|
||||
|
||||
This file is part of Fernschreiber.
|
||||
|
||||
Fernschreiber is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
Fernschreiber is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CONTACTSMODEL_H
|
||||
#define CONTACTSMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QVariantList>
|
||||
|
||||
#include "tdlibwrapper.h"
|
||||
|
||||
class ContactsModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ContactsModel(TDLibWrapper *tdLibWrapper, QObject *parent = nullptr);
|
||||
|
||||
virtual int rowCount(const QModelIndex &) const;
|
||||
virtual QVariant data(const QModelIndex &index, int role) const;
|
||||
|
||||
Q_INVOKABLE void hydrateContacts();
|
||||
|
||||
public slots:
|
||||
void handleUsersReceived(const QString &extra, const QVariantList &userIds, int totalUsers);
|
||||
|
||||
private:
|
||||
TDLibWrapper *tdLibWrapper;
|
||||
QVariantList contacts;
|
||||
QList<QString> contactIds;
|
||||
};
|
||||
|
||||
#endif // CONTACTSMODEL_H
|
|
@ -42,6 +42,7 @@
|
|||
#include "stickermanager.h"
|
||||
#include "tgsplugin.h"
|
||||
#include "fernschreiberutils.h"
|
||||
#include "contactsmodel.h"
|
||||
|
||||
// The default filter can be overridden by QT_LOGGING_RULES envinronment variable, e.g.
|
||||
// QT_LOGGING_RULES="fernschreiber.*=true" harbour-fernschreiber
|
||||
|
@ -96,6 +97,9 @@ int main(int argc, char *argv[])
|
|||
StickerManager stickerManager(tdLibWrapper);
|
||||
context->setContextProperty("stickerManager", &stickerManager);
|
||||
|
||||
ContactsModel contactsModel(tdLibWrapper, view.data());
|
||||
context->setContextProperty("contactsModel", &contactsModel);
|
||||
|
||||
view->setSource(SailfishApp::pathTo("qml/harbour-fernschreiber.qml"));
|
||||
view->show();
|
||||
return app->exec();
|
||||
|
|
|
@ -111,7 +111,7 @@ TDLibWrapper::TDLibWrapper(AppSettings *appSettings, MceInterface *mceInterface,
|
|||
connect(this->tdLibReceiver, SIGNAL(chatPhotoUpdated(qlonglong, QVariantMap)), this, SIGNAL(chatPhotoUpdated(qlonglong, QVariantMap)));
|
||||
connect(this->tdLibReceiver, SIGNAL(chatTitleUpdated(QString, QString)), this, SIGNAL(chatTitleUpdated(QString, QString)));
|
||||
connect(this->tdLibReceiver, SIGNAL(chatPinnedMessageUpdated(qlonglong, qlonglong)), this, SIGNAL(chatPinnedMessageUpdated(qlonglong, qlonglong)));
|
||||
connect(this->tdLibReceiver, SIGNAL(usersReceived(QString, QVariantList, int)), this, SLOT(handleUsersReceived(QString, QVariantList, int)));
|
||||
connect(this->tdLibReceiver, SIGNAL(usersReceived(QString, QVariantList, int)), this, SIGNAL(usersReceived(QString, QVariantList, int)));
|
||||
connect(this->tdLibReceiver, SIGNAL(errorReceived(int, QString)), this, SIGNAL(errorReceived(int, QString)));
|
||||
|
||||
connect(&emojiSearchWorker, SIGNAL(searchCompleted(QString, QVariantList)), this, SLOT(handleEmojiSearchCompleted(QString, QVariantList)));
|
||||
|
@ -621,6 +621,16 @@ void TDLibWrapper::createPrivateChat(const QString &userId)
|
|||
this->sendRequest(requestObject);
|
||||
}
|
||||
|
||||
void TDLibWrapper::createNewSecretChat(const QString &userId)
|
||||
{
|
||||
LOG("Creating new secret chat");
|
||||
QVariantMap requestObject;
|
||||
requestObject.insert(_TYPE, "createNewSecretChat");
|
||||
requestObject.insert("user_id", userId);
|
||||
requestObject.insert(_EXTRA, "openDirectly"); //gets matched in qml
|
||||
this->sendRequest(requestObject);
|
||||
}
|
||||
|
||||
void TDLibWrapper::createSupergroupChat(const QString &supergroupId)
|
||||
{
|
||||
LOG("Creating Supergroup Chat");
|
||||
|
@ -927,52 +937,6 @@ void TDLibWrapper::registerJoinChat()
|
|||
this->joinChatRequested = false;
|
||||
}
|
||||
|
||||
static bool compareUsers(const QVariant &user1, const QVariant &user2)
|
||||
{
|
||||
const QVariantMap userMap1 = user1.toMap();
|
||||
const QVariantMap userMap2 = user2.toMap();
|
||||
|
||||
const QString lastName1 = userMap1.value(LAST_NAME).toString();
|
||||
const QString lastName2 = userMap2.value(LAST_NAME).toString();
|
||||
if (!lastName1.isEmpty()) {
|
||||
if (lastName1 < lastName2) {
|
||||
return true;
|
||||
} else if (lastName1 > lastName2) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const QString firstName1 = userMap1.value(FIRST_NAME).toString();
|
||||
const QString firstName2 = userMap2.value(FIRST_NAME).toString();
|
||||
if (firstName1 < firstName2) {
|
||||
return true;
|
||||
} else if (firstName1 > firstName2) {
|
||||
return false;
|
||||
}
|
||||
const QString userName1 = userMap1.value(USERNAME).toString();
|
||||
const QString userName2 = userMap2.value(USERNAME).toString();
|
||||
if (userName1 < userName2) {
|
||||
return true;
|
||||
} else if (userName1 > userName2) {
|
||||
return false;
|
||||
}
|
||||
return userMap1.value(ID).toLongLong() < userMap2.value(ID).toLongLong();
|
||||
}
|
||||
|
||||
QVariantList TDLibWrapper::getContactsFullInfo()
|
||||
{
|
||||
QVariantList preparedContacts;
|
||||
QListIterator<QString> userIdIterator(contacts);
|
||||
while (userIdIterator.hasNext()) {
|
||||
QString nextUserId = userIdIterator.next();
|
||||
if (allUsers.contains(nextUserId)) {
|
||||
preparedContacts.append(allUsers.value(nextUserId));
|
||||
}
|
||||
}
|
||||
std::sort(preparedContacts.begin(), preparedContacts.end(), compareUsers);
|
||||
return preparedContacts;
|
||||
}
|
||||
|
||||
DBusAdaptor *TDLibWrapper::getDBusAdaptor()
|
||||
{
|
||||
return this->dbusInterface->getDBusAdaptor();
|
||||
|
@ -1185,23 +1149,6 @@ void TDLibWrapper::handleOpenWithChanged()
|
|||
}
|
||||
}
|
||||
|
||||
void TDLibWrapper::handleUsersReceived(const QString &extra, const QVariantList &userIds, int totalUsers)
|
||||
{
|
||||
if (extra == "contactsRequested") {
|
||||
LOG("Received contacts list...");
|
||||
contacts.clear();
|
||||
QListIterator<QVariant> userIdIterator(userIds);
|
||||
while (userIdIterator.hasNext()) {
|
||||
QString nextUserId = userIdIterator.next().toString();
|
||||
if (!this->hasUserInformation(nextUserId)) {
|
||||
this->getUserFullInfo(nextUserId);
|
||||
}
|
||||
contacts.append(nextUserId);
|
||||
}
|
||||
}
|
||||
emit usersReceived(extra, userIds, totalUsers);
|
||||
}
|
||||
|
||||
void TDLibWrapper::setInitialParameters()
|
||||
{
|
||||
LOG("Sending initial parameters to TD Lib");
|
||||
|
|
|
@ -107,7 +107,6 @@ public:
|
|||
Q_INVOKABLE void controlScreenSaver(bool enabled);
|
||||
Q_INVOKABLE bool getJoinChatRequested();
|
||||
Q_INVOKABLE void registerJoinChat();
|
||||
Q_INVOKABLE QVariantList getContactsFullInfo();
|
||||
|
||||
DBusAdaptor *getDBusAdaptor();
|
||||
|
||||
|
@ -147,6 +146,7 @@ public:
|
|||
Q_INVOKABLE void getGroupFullInfo(const QString &groupId, bool isSuperGroup);
|
||||
Q_INVOKABLE void getUserFullInfo(const QString &userId);
|
||||
Q_INVOKABLE void createPrivateChat(const QString &userId);
|
||||
Q_INVOKABLE void createNewSecretChat(const QString &userId);
|
||||
Q_INVOKABLE void createSupergroupChat(const QString &supergroupId);
|
||||
Q_INVOKABLE void createBasicGroupChat(const QString &basicGroupId);
|
||||
Q_INVOKABLE void getGroupsInCommon(const QString &userId, int limit, int offset);
|
||||
|
@ -245,7 +245,6 @@ public slots:
|
|||
void handleStickerSets(const QVariantList &stickerSets);
|
||||
void handleEmojiSearchCompleted(const QString &queryString, const QVariantList &resultList);
|
||||
void handleOpenWithChanged();
|
||||
void handleUsersReceived(const QString &extra, const QVariantList &userIds, int totalUsers);
|
||||
|
||||
private:
|
||||
void setInitialParameters();
|
||||
|
@ -268,7 +267,6 @@ private:
|
|||
QVariantMap allUsers;
|
||||
QVariantMap allUserNames;
|
||||
QVariantMap chats;
|
||||
QList<QString> contacts;
|
||||
QVariantMap unreadMessageInformation;
|
||||
QVariantMap unreadChatInformation;
|
||||
QHash<qlonglong,Group*> basicGroups;
|
||||
|
|
Loading…
Reference in a new issue