Reduce layout shift when loading mutual rooms in user profiles

Instead of making the visibility of this section in user profiles
dependent on the model, its now checking if you can check mutual rooms
and using a busy indicator. There's also a label for when you have no
rooms in common, which is a rare case (for example, banned or left
users.)
This commit is contained in:
Joshua Goins
2026-02-19 18:08:18 -05:00
parent 3a964bae20
commit ae9b2abdc7
3 changed files with 50 additions and 11 deletions

View File

@@ -74,6 +74,11 @@ QHash<int, QByteArray> CommonRoomsModel::roleNames() const
}; };
} }
bool CommonRoomsModel::loading() const
{
return m_loading;
}
void CommonRoomsModel::reload() void CommonRoomsModel::reload()
{ {
if (!m_connection || m_userId.isEmpty()) { if (!m_connection || m_userId.isEmpty()) {
@@ -89,15 +94,26 @@ void CommonRoomsModel::reload()
return; return;
} }
m_connection->callApi<NeochatGetCommonRoomsJob>(m_userId).then([this](const auto job) { m_loading = true;
const auto &replyData = job->jsonData(); Q_EMIT loadingChanged();
beginResetModel();
for (const auto &roomId : replyData[u"joined"_s].toArray()) { m_connection->callApi<NeochatGetCommonRoomsJob>(m_userId)
m_commonRooms.push_back(roomId.toString()); .then([this](const auto job) {
} const auto &replyData = job->jsonData();
endResetModel(); beginResetModel();
Q_EMIT countChanged(); for (const auto &roomId : replyData[u"joined"_s].toArray()) {
}); m_commonRooms.push_back(roomId.toString());
}
endResetModel();
Q_EMIT countChanged();
m_loading = false;
Q_EMIT loadingChanged();
})
.onFailure([this] {
m_loading = false;
Q_EMIT loadingChanged();
});
} }
#include "moc_commonroomsmodel.cpp" #include "moc_commonroomsmodel.cpp"

View File

@@ -21,6 +21,7 @@ class CommonRoomsModel : public QAbstractListModel
Q_PROPERTY(NeoChatConnection *connection WRITE setConnection READ connection NOTIFY connectionChanged REQUIRED) Q_PROPERTY(NeoChatConnection *connection WRITE setConnection READ connection NOTIFY connectionChanged REQUIRED)
Q_PROPERTY(QString userId WRITE setUserId READ userId NOTIFY userIdChanged REQUIRED) Q_PROPERTY(QString userId WRITE setUserId READ userId NOTIFY userIdChanged REQUIRED)
Q_PROPERTY(int count READ rowCount NOTIFY countChanged) Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged)
public: public:
enum Roles { enum Roles {
@@ -43,10 +44,13 @@ public:
QHash<int, QByteArray> roleNames() const override; QHash<int, QByteArray> roleNames() const override;
bool loading() const;
Q_SIGNALS: Q_SIGNALS:
void connectionChanged(); void connectionChanged();
void userIdChanged(); void userIdChanged();
void countChanged(); void countChanged();
void loadingChanged();
private: private:
void reload(); void reload();
@@ -54,4 +58,5 @@ private:
QPointer<NeoChatConnection> m_connection; QPointer<NeoChatConnection> m_connection;
QString m_userId; QString m_userId;
QList<QString> m_commonRooms; QList<QString> m_commonRooms;
bool m_loading = false;
}; };

View File

@@ -401,18 +401,36 @@ Kirigami.Dialog {
Kirigami.Heading { Kirigami.Heading {
text: i18nc("@title The set of common rooms between your current user and the one shown", "Mutual Rooms") text: i18nc("@title The set of common rooms between your current user and the one shown", "Mutual Rooms")
level: 4 level: 4
visible: !root.isSelf && root.hasMutualRooms visible: !root.isSelf && root.connection.canCheckMutualRooms
Layout.topMargin: Kirigami.Units.largeSpacing Layout.topMargin: Kirigami.Units.largeSpacing
} }
RowLayout { RowLayout {
spacing: Kirigami.Units.smallSpacing spacing: Kirigami.Units.smallSpacing
visible: !root.isSelf && root.hasMutualRooms visible: !root.isSelf && root.connection.canCheckMutualRooms
Layout.topMargin: Kirigami.Units.smallSpacing Layout.topMargin: Kirigami.Units.smallSpacing
QQC2.BusyIndicator {
visible: roomRepeater.count === 0 && root.model.loading
Layout.preferredWidth: Kirigami.Units.iconSizes.medium
Layout.preferredHeight: Kirigami.Units.iconSizes.medium
}
QQC2.Label {
visible: roomRepeater.count === 0 && !root.model.loading
text: i18nc("@info:label", "No rooms in common")
verticalAlignment: Text.AlignVCenter
Layout.preferredHeight: Kirigami.Units.iconSizes.medium
Layout.fillHeight: true
}
Repeater { Repeater {
id: roomRepeater
model: root.limiterModel model: root.limiterModel
delegate: KirigamiComponents.AvatarButton { delegate: KirigamiComponents.AvatarButton {