Compare commits

...

4 Commits

Author SHA1 Message Date
Torrie Fischer
4139421e8e roomlist: first pass at some new, different extensible sorting options 2022-10-11 15:48:52 +02:00
Tobias Fella
b2fa269515 Send correct width and height for images 2022-10-10 18:49:43 +00:00
James Graham
589f9f88a3 Handle images with size (0,0) in fullscreen mode 2022-10-10 18:41:28 +00:00
Tobias Fella
de0b138992 Handle images with incorrect (0, 0) size better
BUG: 460205
BUG: 460150
2022-10-10 20:06:27 +02:00
7 changed files with 83 additions and 31 deletions

View File

@@ -209,8 +209,8 @@ Popup {
property var scaleFactor: 1
property int rotationAngle: 0
property var rotationInsensitiveWidth: Math.min(root.imageWidth !== -1 ? root.imageWidth : sourceSize.width, imageContainer.width - Kirigami.Units.largeSpacing * 2)
property var rotationInsensitiveHeight: Math.min(root.imageHeight !== -1 ? root.imageHeight : sourceSize.height, imageContainer.height - Kirigami.Units.largeSpacing * 2)
property var rotationInsensitiveWidth: Math.min(root.imageWidth > 0 ? root.imageWidth : sourceSize.width, imageContainer.width - Kirigami.Units.largeSpacing * 2)
property var rotationInsensitiveHeight: Math.min(root.imageHeight > 0 ? root.imageHeight : sourceSize.height, imageContainer.height - Kirigami.Units.largeSpacing * 2)
anchors.centerIn: parent
width: rotationAngle % 180 === 0 ? rotationInsensitiveWidth : rotationInsensitiveHeight

View File

@@ -37,9 +37,9 @@ TimelineContainer {
id: img
Layout.maximumWidth: imageDelegate.contentMaxWidth
Layout.maximumHeight: imageDelegate.contentMaxWidth / imageDelegate.info.w * imageDelegate.info.h
Layout.preferredWidth: imageDelegate.info.w
Layout.preferredHeight: imageDelegate.info.h
Layout.maximumHeight: imageDelegate.contentMaxWidth / sourceSize.width * sourceSize.height
Layout.preferredWidth: imageDelegate.info.w > 0 ? imageDelegate.info.w : sourceSize.width
Layout.preferredHeight: imageDelegate.info.h > 0 ? imageDelegate.info.h : sourceSize.height
source: model.mediaUrl
Image {

View File

@@ -99,7 +99,7 @@ QCoro::Task<void> NeoChatRoom::doUploadFile(QUrl url, QString body)
QFileInfo fileInfo(url.toLocalFile());
EventContent::TypedBase *content;
if (mime.name().startsWith("image/")) {
QImage image;
QImage image(url.toLocalFile());
content = new EventContent::ImageContent(url, fileInfo.size(), mime, image.size(), fileInfo.fileName());
} else if (mime.name().startsWith("audio/")) {
content = new EventContent::AudioContent(url, fileInfo.size(), mime, fileInfo.fileName());

View File

@@ -340,6 +340,12 @@ QVariant RoomListModel::data(const QModelIndex &index, int role) const
if (role == TopicRole) {
return room->topic();
}
if (role == FavoritedRole) {
return room->isFavourite();
}
if (role == AttentionRole) {
return room->notificationCount() + room->unreadCount() + room->highlightCount() > 0;
}
if (role == CategoryRole) {
if (room->joinState() == JoinState::Invite) {
return NeoChatRoomType::Invited;

View File

@@ -56,6 +56,10 @@ public:
AvatarImageRole,
IdRole,
IsSpaceRole,
// Whether or not the room is favorited
FavoritedRole,
// Whether or not the room needs attention, ie, pings, mentions, unread
AttentionRole,
};
Q_ENUM(EventRoles)

View File

@@ -33,34 +33,72 @@ SortFilterRoomListModel::RoomSortOrder SortFilterRoomListModel::roomSortOrder()
return m_sortOrder;
}
static const QVector<RoomListModel::EventRoles> categorySortPriorities{
// Favorites at the top
RoomListModel::FavoritedRole,
// Group by categories
RoomListModel::CategoryRole,
// Within each category, pull relevant ones to the top
RoomListModel::AttentionRole,
RoomListModel::HighlightCountRole,
RoomListModel::NotificationCountRole,
RoomListModel::UnreadCountRole,
// Finally sort by last activity time
RoomListModel::LastActiveTimeRole
};
static const QVector<RoomListModel::EventRoles> alphabeticalSortPriorities {
// Does exactly what it says on the tin.
(RoomListModel::EventRoles)Qt::DisplayRole
};
static const QVector<RoomListModel::EventRoles> activitySortPriorities{
// Anything useful at the top, quiet rooms at the bottom
RoomListModel::AttentionRole,
// Organize by highlights, notifications, unread favorites, all other unread, in that order
RoomListModel::HighlightCountRole,
RoomListModel::NotificationCountRole,
RoomListModel::FavoritedRole,
RoomListModel::UnreadCountRole,
// Finally sort by last activity time
RoomListModel::LastActiveTimeRole
};
bool SortFilterRoomListModel::roleCmp(RoomListModel::EventRoles role, const QVariant &sortLeft, const QVariant &sortRight) const
{
switch(role) {
case RoomListModel::FavoritedRole:
return (sortLeft == sortRight) ? false : sortLeft.toBool();
case RoomListModel::CategoryRole:
return sortLeft < sortRight;
default:
return sortLeft > sortRight;
}
}
bool SortFilterRoomListModel::prioritiesCmp(const QVector<RoomListModel::EventRoles>& priorities, const QModelIndex &source_left, const QModelIndex &source_right) const
{
for(RoomListModel::EventRoles sortRole : priorities) {
const auto sortLeft = sourceModel()->data(source_left, sortRole);
const auto sortRight = sourceModel()->data(source_right, sortRole);
if (sortLeft != sortRight) {
return roleCmp(sortRole, sortLeft, sortRight);
}
}
return QSortFilterProxyModel::lessThan(source_left, source_right);
}
bool SortFilterRoomListModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
if (m_sortOrder == SortFilterRoomListModel::LastActivity) {
// display favorite rooms always on top
const auto categoryLeft = static_cast<NeoChatRoomType::Types>(sourceModel()->data(source_left, RoomListModel::CategoryRole).toInt());
const auto categoryRight = static_cast<NeoChatRoomType::Types>(sourceModel()->data(source_right, RoomListModel::CategoryRole).toInt());
if (categoryLeft == NeoChatRoomType::Types::Favorite && categoryRight == NeoChatRoomType::Types::Favorite) {
return sourceModel()->data(source_left, RoomListModel::LastActiveTimeRole).toDateTime()
> sourceModel()->data(source_right, RoomListModel::LastActiveTimeRole).toDateTime();
}
if (categoryLeft == NeoChatRoomType::Types::Favorite) {
return true;
} else if (categoryRight == NeoChatRoomType::Types::Favorite) {
return false;
}
return sourceModel()->data(source_left, RoomListModel::LastActiveTimeRole).toDateTime()
> sourceModel()->data(source_right, RoomListModel::LastActiveTimeRole).toDateTime();
switch(m_sortOrder) {
case SortFilterRoomListModel::Alphabetical:
return prioritiesCmp(alphabeticalSortPriorities, source_left, source_right);
case SortFilterRoomListModel::Categories:
return prioritiesCmp(categorySortPriorities, source_left, source_right);
case SortFilterRoomListModel::LastActivity:
return prioritiesCmp(activitySortPriorities, source_left, source_right);
}
if (m_sortOrder != SortFilterRoomListModel::Categories) {
return QSortFilterProxyModel::lessThan(source_left, source_right);
}
if (sourceModel()->data(source_left, RoomListModel::CategoryRole) != sourceModel()->data(source_right, RoomListModel::CategoryRole)) {
return sourceModel()->data(source_left, RoomListModel::CategoryRole).toInt() < sourceModel()->data(source_right, RoomListModel::CategoryRole).toInt();
}
return sourceModel()->data(source_left, RoomListModel::LastActiveTimeRole).toDateTime()
> sourceModel()->data(source_right, RoomListModel::LastActiveTimeRole).toDateTime();
return QSortFilterProxyModel::lessThan(source_left, source_right);
}
void SortFilterRoomListModel::setFilterText(const QString &text)

View File

@@ -4,6 +4,7 @@
#pragma once
#include <QSortFilterProxyModel>
#include "roomlistmodel.h"
class SortFilterRoomListModel : public QSortFilterProxyModel
{
@@ -46,4 +47,7 @@ private:
RoomSortOrder m_sortOrder = Categories;
QString m_filterText;
QString m_activeSpaceId;
bool prioritiesCmp(const QVector<RoomListModel::EventRoles>& priorities, const QModelIndex &left, const QModelIndex &right) const;
bool roleCmp(RoomListModel::EventRoles role, const QVariant& left, const QVariant& right) const;
};