File indexing completed on 2024-05-12 16:28:08
0001 // SPDX-FileCopyrightText: 2022 Carl Schwan <carlschwan@kde.org> 0002 // SPDX-License-Identifier: LGPL-2.0-or-later 0003 0004 #include "conversationmodel.h" 0005 0006 #include "account/abstractaccount.h" 0007 #include "account/accountmanager.h" 0008 #include "account/identity.h" 0009 #include <KLocalizedString> 0010 #include <QTextDocumentFragment> 0011 #include <algorithm> 0012 #include <qvariant.h> 0013 0014 ConversationModel::ConversationModel(QObject *parent) 0015 : AbstractTimelineModel(parent) 0016 { 0017 if (AccountManager::instance().selectedAccount()) { 0018 fetchConversation(AccountManager::instance().selectedAccount()); 0019 } 0020 connect(&AccountManager::instance(), &AccountManager::accountSelected, this, [this](AbstractAccount *account) { 0021 fetchConversation(account); 0022 }); 0023 } 0024 0025 ConversationModel::~ConversationModel() = default; 0026 0027 QHash<int, QByteArray> ConversationModel::roleNames() const 0028 { 0029 auto roles = AbstractTimelineModel::roleNames(); 0030 roles.insert(UnreadRole, QByteArrayLiteral("unread")); 0031 roles.insert(ConversationIdRole, QByteArrayLiteral("conversationId")); 0032 return roles; 0033 } 0034 0035 int ConversationModel::rowCount(const QModelIndex &parent) const 0036 { 0037 Q_UNUSED(parent); 0038 return m_conversations.count(); 0039 } 0040 0041 QVariant ConversationModel::data(const QModelIndex &index, int role) const 0042 { 0043 const auto row = index.row(); 0044 const auto lastPost = m_conversations[row].lastPost; 0045 const auto &identities = m_conversations[row].accounts; 0046 const auto &firstIdentity = identities[0]; 0047 0048 switch (role) { 0049 case AuthorIdentityRole: 0050 return QVariant::fromValue<Identity *>(firstIdentity.get()); 0051 case ConversationIdRole: 0052 return m_conversations[row].id; 0053 case UnreadRole: 0054 return m_conversations[row].unread; 0055 case ContentRole: 0056 return QTextDocumentFragment::fromHtml(lastPost->content()).toPlainText(); 0057 case ConversationAuthorsRole: 0058 if (identities.count() == 0) { 0059 return i18n("Empty conversation"); 0060 } else if (identities.count() == 1) { 0061 return firstIdentity->displayNameHtml(); 0062 } else if (identities.count() == 2) { 0063 return i18n("%1 and %2", firstIdentity->displayNameHtml(), identities[2]->displayNameHtml()); 0064 } else { 0065 return i18np("%2 and one other", "%2 and %1 others", identities.count() - 1, firstIdentity->displayNameHtml()); 0066 } 0067 default: 0068 return postData(lastPost, role); 0069 } 0070 } 0071 0072 void ConversationModel::fetchConversation(AbstractAccount *account) 0073 { 0074 setLoading(true); 0075 0076 account->get(account->apiUrl("/api/v1/conversations"), true, this, [account, this](QNetworkReply *reply) { 0077 beginResetModel(); 0078 m_conversations.clear(); 0079 const auto conversationArray = QJsonDocument::fromJson(reply->readAll()).array(); 0080 for (const auto &conversation : conversationArray) { 0081 const auto obj = conversation.toObject(); 0082 const auto accountsArray = obj["accounts"].toArray(); 0083 QList<std::shared_ptr<Identity>> accounts; 0084 std::transform( 0085 accountsArray.cbegin(), 0086 accountsArray.cend(), 0087 std::back_inserter(accounts), 0088 [account](const QJsonValue &value) -> auto{ 0089 const auto accountObj = value.toObject(); 0090 return account->identityLookup(accountObj["id"].toString(), accountObj); 0091 }); 0092 m_conversations.append(Conversation{ 0093 accounts, 0094 new Post(account, obj["last_status"].toObject(), this), 0095 obj["unread"].toBool(), 0096 obj["id"].toString(), 0097 }); 0098 } 0099 setLoading(false); 0100 endResetModel(); 0101 }); 0102 } 0103 0104 void ConversationModel::markAsRead(const QString &id) 0105 { 0106 auto account = AccountManager::instance().selectedAccount(); 0107 0108 account->post(account->apiUrl(QString("/api/v1/conversations/%1/read").arg(id)), QJsonDocument(), true, this, [id, this](QNetworkReply *reply) { 0109 const auto conversationObj = QJsonDocument::fromJson(reply->readAll()).object(); 0110 int i = 0; 0111 for (auto &conversation : m_conversations) { 0112 if (conversation.id == id) { 0113 conversation.unread = false; 0114 Q_EMIT dataChanged(index(i, 0), index(i, 0), {UnreadRole}); 0115 break; 0116 } 0117 i++; 0118 } 0119 }); 0120 }