File indexing completed on 2024-10-06 07:36:31
0001 /* 0002 SPDX-FileCopyrightText: 2017-2024 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "usersmodel.h" 0008 #include "ruqola_debug.h" 0009 #include "utils.h" 0010 #include <KLocalizedString> 0011 #include <QJsonObject> 0012 0013 UsersModel::UsersModel(QObject *parent) 0014 : QAbstractListModel(parent) 0015 { 0016 } 0017 0018 UsersModel::~UsersModel() = default; 0019 0020 int UsersModel::rowCount(const QModelIndex &parent) const 0021 { 0022 Q_UNUSED(parent) 0023 return mUsers.size(); 0024 } 0025 0026 QVariant UsersModel::data(const QModelIndex &index, int role) const 0027 { 0028 if (index.row() < 0 || index.row() >= mUsers.count()) { 0029 return {}; 0030 } 0031 const User &user = mUsers.at(index.row()); 0032 switch (role) { 0033 case UserName: 0034 return user.name(); 0035 case UserId: 0036 return user.userId(); 0037 case UserStatus: 0038 return Utils::presenceStatusToString(user.status()); 0039 case UserIcon: 0040 return user.iconFromStatus(); 0041 case UserStatusText: 0042 return user.statusText(); 0043 } 0044 0045 return {}; 0046 } 0047 0048 bool UsersModel::userIsOffline(const QString &name) const 0049 { 0050 const int userCount = mUsers.count(); 0051 for (int i = 0; i < userCount; ++i) { 0052 const auto &user = mUsers.at(i); 0053 if (user.userName() == name) { 0054 return user.status() == User::PresenceStatus::PresenceOffline; 0055 } 0056 } 0057 return true; 0058 } 0059 0060 QString UsersModel::userStatusStr(const QString &name) const 0061 { 0062 const int userCount = mUsers.count(); 0063 for (int i = 0; i < userCount; ++i) { 0064 const auto &user = mUsers.at(i); 0065 if (user.userName() == name) { 0066 return user.generateStatusStr(); 0067 } 0068 } 0069 0070 // qCWarning(RUQOLA_LOG) << "User for name " << name << " not defined yet"; 0071 return i18n("Offline"); 0072 } 0073 0074 QString UsersModel::userStatusIconFileName(const QString &name) const 0075 { 0076 const int userCount = mUsers.count(); 0077 for (int i = 0; i < userCount; ++i) { 0078 const auto &user = mUsers.at(i); 0079 if (user.userName() == name) { 0080 return user.iconFromStatus(); 0081 } 0082 } 0083 0084 // qCWarning(RUQOLA_LOG) << "User for name " << name << " not defined yet"; 0085 return QStringLiteral("user-offline"); 0086 } 0087 0088 User::PresenceStatus UsersModel::status(const QString &userId) const 0089 { 0090 const int userCount = mUsers.count(); 0091 0092 for (int i = 0; i < userCount; ++i) { 0093 const auto &user = mUsers.at(i); 0094 if (user.userId() == userId) { 0095 return user.status(); 0096 } 0097 } 0098 // Return offline as default; 0099 return User::PresenceStatus::PresenceOffline; 0100 } 0101 0102 User UsersModel::fullUserInfo(const QString &userName) const 0103 { 0104 const int userCount = mUsers.count(); 0105 0106 for (int i = 0; i < userCount; ++i) { 0107 const User user = mUsers.at(i); 0108 if (user.userName() == userName) { 0109 return user; 0110 } 0111 } 0112 return {}; 0113 } 0114 0115 void UsersModel::removeUser(const QString &userId) 0116 { 0117 qCDebug(RUQOLA_LOG) << " User removed " << userId; 0118 const int userCount = mUsers.count(); 0119 for (int i = 0; i < userCount; ++i) { 0120 if (mUsers.at(i).userId() == userId) { 0121 qCDebug(RUQOLA_LOG) << " User removed " << mUsers.at(i).name(); 0122 // Send info as it's disconnected. But don't remove it from list 0123 User &user = mUsers[i]; 0124 user.setStatus(User::PresenceStatus::PresenceOffline); 0125 const QModelIndex idx = createIndex(i, 0); 0126 Q_EMIT userStatusChanged(user); 0127 Q_EMIT dataChanged(idx, idx); 0128 break; 0129 } 0130 } 0131 } 0132 0133 void UsersModel::addUser(const User &newuser) 0134 { 0135 // It can be duplicate as we don't remove user from list when user is disconnected. Otherwise it will not sync with 0136 // user for room list 0137 qCDebug(RUQOLA_LOG) << " User added " << newuser; 0138 const int userCount = mUsers.count(); 0139 bool found = false; 0140 for (int i = 0; i < userCount; ++i) { 0141 if (mUsers.at(i).userId() == newuser.userId()) { 0142 found = true; 0143 User &user = mUsers[i]; 0144 user.setStatus(newuser.status()); 0145 const QModelIndex idx = createIndex(i, 0); 0146 Q_EMIT userStatusChanged(user); 0147 Q_EMIT dataChanged(idx, idx); 0148 break; 0149 } 0150 } 0151 if (!found) { 0152 const int pos = mUsers.size(); 0153 beginInsertRows(QModelIndex(), pos, pos); 0154 mUsers.append(newuser); 0155 endInsertRows(); 0156 } 0157 } 0158 0159 void UsersModel::updateUser(const QJsonObject &array) 0160 { 0161 const QString id = array.value(QLatin1String("id")).toString(); 0162 const int userCount = mUsers.count(); 0163 for (int i = 0; i < userCount; ++i) { 0164 if (mUsers.at(i).userId() == id) { 0165 User &user = mUsers[i]; 0166 const QJsonObject fields = array.value(QLatin1String("fields")).toObject(); 0167 0168 const QString newStatus = fields.value(QLatin1String("status")).toString(); 0169 bool userDataChanged = false; 0170 if (!newStatus.isEmpty()) { 0171 user.setStatus(Utils::presenceStatusFromString(newStatus)); 0172 const QModelIndex idx = createIndex(i, 0); 0173 Q_EMIT dataChanged(idx, idx); 0174 Q_EMIT userStatusChanged(user); 0175 userDataChanged = true; 0176 } 0177 const QString newName = fields.value(QLatin1String("name")).toString(); 0178 if (!newName.isEmpty()) { 0179 user.setName(newName); 0180 const QModelIndex idx = createIndex(i, 0); 0181 Q_EMIT dataChanged(idx, idx); 0182 Q_EMIT userNameChanged(user); 0183 userDataChanged = true; 0184 } 0185 const QString newuserName = fields.value(QLatin1String("username")).toString(); 0186 if (!newuserName.isEmpty()) { 0187 user.setUserName(newuserName); 0188 const QModelIndex idx = createIndex(i, 0); 0189 Q_EMIT dataChanged(idx, idx); 0190 Q_EMIT nameChanged(user); 0191 userDataChanged = true; 0192 } 0193 const QString statusMessage = fields.value(QLatin1String("statusText")).toString(); 0194 if (!statusMessage.isEmpty()) { 0195 user.setStatusText(statusMessage); 0196 const QModelIndex idx = createIndex(i, 0); 0197 Q_EMIT dataChanged(idx, idx); 0198 Q_EMIT statusMessageChanged(user); 0199 userDataChanged = true; 0200 } 0201 if (!userDataChanged) { 0202 qCWarning(RUQOLA_LOG) << " Unsupported yet user data modification " << array; 0203 } 0204 break; 0205 } 0206 } 0207 } 0208 0209 #include "moc_usersmodel.cpp"