Unify getUser

Always use `NeoChatRoom::getUser` for getting user details in a room context.
- `MessageEventModel` now calls `getUser`
- `getUser` is now overloaded to also be able to take a `NeoChatUser*`
- add params to `getUser` that are needed for the model outputs
This commit is contained in:
James Graham
2023-05-27 18:27:28 +00:00
parent f2aa375b43
commit e1d4b66479
8 changed files with 120 additions and 61 deletions

View File

@@ -431,33 +431,6 @@ void MessageEventModel::fetchMore(const QModelIndex &parent)
}
}
static const QVariantMap emptyUser = {
{"isLocalUser", false},
{"id", QString()},
{"avatarSource", QUrl()},
{"avatarMediaId", QString()},
{"avatarUrl", QString()},
{"displayName", QString()},
{"display", QString()},
{"color", QColor()},
{"object", QVariant()},
};
inline QVariantMap userInContext(NeoChatUser *user, NeoChatRoom *room)
{
return QVariantMap{
{"isLocalUser", user->id() == room->localUser()->id()},
{"id", user->id()},
{"avatarSource", room->avatarForMember(user)},
{"avatarMediaId", user->avatarMediaId(room)},
{"avatarUrl", user->avatarUrl(room)},
{"displayName", user->displayname(room)},
{"display", user->name()},
{"color", user->color()},
{"object", QVariant::fromValue(user)},
};
}
static LinkPreviewer *emptyLinkPreview = new LinkPreviewer;
QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
@@ -572,7 +545,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
if (role == AuthorRole) {
auto author = static_cast<NeoChatUser *>(isPending ? m_currentRoom->localUser() : m_currentRoom->user(evt.senderId()));
return userInContext(author, m_currentRoom);
return m_currentRoom->getUser(author);
}
if (role == ContentRole) {
@@ -715,9 +688,9 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
if (replyPtr) {
auto replyUser = static_cast<NeoChatUser *>(m_currentRoom->user(replyPtr->senderId()));
return userInContext(replyUser, m_currentRoom);
return m_currentRoom->getUser(replyUser);
} else {
return emptyUser;
return m_currentRoom->getUser(nullptr);
}
}
@@ -853,7 +826,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
#else
auto user = static_cast<NeoChatUser *>(userId);
#endif
users += userInContext(user, m_currentRoom);
users += m_currentRoom->getUser(user);
}
return users;
@@ -1195,7 +1168,7 @@ void MessageEventModel::createReactionModelForEvent(const Quotient::RoomMessageE
while (i != reactions.constEnd()) {
QVariantList authors;
for (const auto &author : i.value()) {
authors.append(userInContext(author, m_currentRoom));
authors.append(m_currentRoom->getUser(author));
}
res.append(ReactionModel::Reaction{i.key(), authors});

View File

@@ -459,13 +459,38 @@ QVariantList NeoChatRoom::getUsers(const QString &keyword, int limit) const
return matchedList;
}
// An empty user is useful for returning as a model value to avoid properties being undefined.
static const QVariantMap emptyUser = {
{"isLocalUser", false},
{"id", QString()},
{"displayName", QString()},
{"avatarSource", QUrl()},
{"avatarMediaId", QString()},
{"color", QColor()},
{"object", QVariant()},
};
QVariantMap NeoChatRoom::getUser(const QString &userID) const
{
NeoChatUser user(userID, connection());
return QVariantMap{{QStringLiteral("id"), user.id()},
{QStringLiteral("displayName"), user.displayname(this)},
{QStringLiteral("avatarMediaId"), user.avatarMediaId(this)},
{QStringLiteral("color"), user.color()}};
NeoChatUser *userObject = static_cast<NeoChatUser *>(user(userID));
return getUser(userObject);
}
QVariantMap NeoChatRoom::getUser(NeoChatUser *user) const
{
if (user == nullptr) {
return emptyUser;
}
return QVariantMap{
{QStringLiteral("isLocalUser"), user->id() == localUser()->id()},
{QStringLiteral("id"), user->id()},
{QStringLiteral("displayName"), user->displayname(this)},
{QStringLiteral("avatarSource"), avatarForMember(user)},
{QStringLiteral("avatarMediaId"), user->avatarMediaId(this)},
{QStringLiteral("color"), user->color()},
{QStringLiteral("object"), QVariant::fromValue(user)},
};
}
QString NeoChatRoom::avatarMediaId() const
@@ -1768,12 +1793,12 @@ void NeoChatRoom::setChatBoxEditId(const QString &editId)
Q_EMIT chatBoxEditIdChanged();
}
NeoChatUser *NeoChatRoom::chatBoxReplyUser() const
QVariantMap NeoChatRoom::chatBoxReplyUser() const
{
if (m_chatBoxReplyId.isEmpty()) {
return nullptr;
return emptyUser;
}
return static_cast<NeoChatUser *>(user((*findInTimeline(m_chatBoxReplyId))->senderId()));
return getUser(static_cast<NeoChatUser *>(user((*findInTimeline(m_chatBoxReplyId))->senderId())));
}
QString NeoChatRoom::chatBoxReplyMessage() const
@@ -1784,12 +1809,12 @@ QString NeoChatRoom::chatBoxReplyMessage() const
return eventToString(*static_cast<const RoomMessageEvent *>(&**findInTimeline(m_chatBoxReplyId)));
}
NeoChatUser *NeoChatRoom::chatBoxEditUser() const
QVariantMap NeoChatRoom::chatBoxEditUser() const
{
if (m_chatBoxEditId.isEmpty()) {
return nullptr;
return emptyUser;
}
return static_cast<NeoChatUser *>(user((*findInTimeline(m_chatBoxEditId))->senderId()));
return getUser(static_cast<NeoChatUser *>(user((*findInTimeline(m_chatBoxEditId))->senderId())));
}
QString NeoChatRoom::chatBoxEditMessage() const

View File

@@ -315,11 +315,26 @@ class NeoChatRoom : public Quotient::Room
Q_PROPERTY(QString chatBoxEditId READ chatBoxEditId WRITE setChatBoxEditId NOTIFY chatBoxEditIdChanged)
/**
* @brief Get the user object for the message being replied to.
* @brief Get the user for the message being replied to.
*
* Returns a nullptr if not replying to a message.
* This is different to getting a NeoChatUser object or Quotient::User object
* as neither of those can provide details like the displayName or avatarMediaId
* without the room context as these can vary from room to room.
*
* Returns an empty user if not replying to a message.
*
* The user QVariantMap has the following properties:
* - isLocalUser - Whether the user is the local user.
* - id - The matrix ID of the user.
* - displayName - Display name in the context of this room.
* - avatarSource - The mxc URL for the user's avatar in the current room.
* - avatarMediaId - Avatar id in the context of this room.
* - color - Color for the user.
* - object - The NeoChatUser object for the user.
*
* @sa getUser, Quotient::User, NeoChatUser
*/
Q_PROPERTY(NeoChatUser *chatBoxReplyUser READ chatBoxReplyUser NOTIFY chatBoxReplyIdChanged)
Q_PROPERTY(QVariantMap chatBoxReplyUser READ chatBoxReplyUser NOTIFY chatBoxReplyIdChanged)
/**
* @brief The content of the message being replied to.
@@ -329,11 +344,26 @@ class NeoChatRoom : public Quotient::Room
Q_PROPERTY(QString chatBoxReplyMessage READ chatBoxReplyMessage NOTIFY chatBoxReplyIdChanged)
/**
* @brief Get the user object for the message being edited.
* @brief Get the user for the message being edited.
*
* Returns a nullptr if not editing a message.
* This is different to getting a NeoChatUser object or Quotient::User object
* as neither of those can provide details like the displayName or avatarMediaId
* without the room context as these can vary from room to room.
*
* Returns an empty user if not replying to a message.
*
* The user QVariantMap has the following properties:
* - isLocalUser - Whether the user is the local user.
* - id - The matrix ID of the user.
* - displayName - Display name in the context of this room.
* - avatarSource - The mxc URL for the user's avatar in the current room.
* - avatarMediaId - Avatar id in the context of this room.
* - color - Color for the user.
* - object - The NeoChatUser object for the user.
*
* @sa getUser, Quotient::User, NeoChatUser
*/
Q_PROPERTY(NeoChatUser *chatBoxEditUser READ chatBoxEditUser NOTIFY chatBoxEditIdChanged)
Q_PROPERTY(QVariantMap chatBoxEditUser READ chatBoxEditUser NOTIFY chatBoxEditIdChanged)
/**
* @brief The content of the message being edited.
@@ -390,18 +420,50 @@ public:
* without the room context as these can vary from room to room. This function
* provides the room context and outputs the result as QVariantMap.
*
* Can be called with an empty QString to return an empty user, which is a useful return
* from models to avoid undefined properties.
*
* @param userID the ID of the user to output.
*
* @return a QVariantMap for the user with the following properties:
* - id - User ID.
* - isLocalUser - Whether the user is the local user.
* - id - The matrix ID of the user.
* - displayName - Display name in the context of this room.
* - avatarSource - The mxc URL for the user's avatar in the current room.
* - avatarMediaId - Avatar id in the context of this room.
* - color - Color for the user.
* - object - The NeoChatUser object for the user.
*
* @sa Quotient::User, NeoChatUser
*/
Q_INVOKABLE [[nodiscard]] QVariantMap getUser(const QString &userID) const;
/**
* @brief Get a user in the context of this room.
*
* This is different to getting a NeoChatUser object or Quotient::User object
* as neither of those can provide details like the displayName or avatarMediaId
* without the room context as these can vary from room to room. This function
* provides the room context and outputs the result as QVariantMap.
*
* Can be called with a nullptr to return an empty user, which is a useful return
* from models to avoid undefined properties.
*
* @param user the user to output.
*
* @return a QVariantMap for the user with the following properties:
* - isLocalUser - Whether the user is the local user.
* - id - The matrix ID of the user.
* - displayName - Display name in the context of this room.
* - avatarSource - The mxc URL for the user's avatar in the current room.
* - avatarMediaId - Avatar id in the context of this room.
* - color - Color for the user.
* - object - The NeoChatUser object for the user.
*
* @sa Quotient::User, NeoChatUser
*/
Q_INVOKABLE [[nodiscard]] QVariantMap getUser(NeoChatUser *user) const;
[[nodiscard]] QVariantList getUsersTyping() const;
[[nodiscard]] QDateTime lastActiveTime();
@@ -704,13 +766,13 @@ public:
QString chatBoxReplyId() const;
void setChatBoxReplyId(const QString &replyId);
NeoChatUser *chatBoxReplyUser() const;
QVariantMap chatBoxReplyUser() const;
QString chatBoxReplyMessage() const;
QString chatBoxEditId() const;
void setChatBoxEditId(const QString &editId);
NeoChatUser *chatBoxEditUser() const;
QVariantMap chatBoxEditUser() const;
QString chatBoxEditMessage() const;
QString chatBoxAttachmentPath() const;

View File

@@ -15,7 +15,6 @@ QQC2.Control {
property alias textField: textField
property bool isReplying: currentRoom.chatBoxReplyId.length > 0
property NeoChatUser replyUser: currentRoom.chatBoxReplyUser
property bool attachmentPaneVisible: currentRoom.chatBoxAttachmentPath.length > 0
signal messageSent()
@@ -244,9 +243,9 @@ QQC2.Control {
Component {
id: replyPane
ReplyPane {
userName: root.replyUser ? root.replyUser.displayName : ""
userColor: root.replyUser ? root.replyUser.color : ""
userAvatar: root.replyUser ? "image://mxc/" + currentRoom.getUser(root.replyUser.id).avatarMediaId : ""
userName: currentRoom.chatBoxReplyUser.displayName
userColor: currentRoom.chatBoxReplyUser.color
userAvatar: currentRoom.chatBoxReplyUser.avatarSource
text: currentRoom.chatBoxReplyMessage
}
}

View File

@@ -54,7 +54,7 @@ Components.AlbumMaximizeComponent {
implicitWidth: Kirigami.Units.iconSizes.medium
implicitHeight: Kirigami.Units.iconSizes.medium
name: root.author.name ?? root.author.displayName
name: root.author.displayName
source: root.author.avatarSource
color: root.author.color
}
@@ -62,7 +62,7 @@ Components.AlbumMaximizeComponent {
spacing: 0
QQC2.Label {
id: userLabel
text: root.author.name ?? root.author.displayName
text: root.author.displayName
color: root.author.color
font.weight: Font.Bold
elide: Text.ElideRight

View File

@@ -93,7 +93,7 @@ TimelineContainer {
visible: root.asset === "m.self"
width: height
height: parent.height / 3 + 1
name: root.author.name ?? root.author.displayName
name: root.author.displayName
source: root.author.avatarSource
color: root.author.color
}

View File

@@ -100,7 +100,7 @@ Item {
implicitHeight: Kirigami.Units.iconSizes.small
source: root.author.avatarSource
name: root.author.displayName || ""
name: root.author.displayName
color: root.author.color
}
QQC2.Label {

View File

@@ -381,7 +381,7 @@ ColumnLayout {
visible: root.showAuthor &&
Config.showAvatarInTimeline &&
(Config.compactLayout || !showUserMessageOnRight)
name: root.author.name ?? root.author.displayName
name: root.author.displayName
source: root.author.avatarSource
color: root.author.color