[SMS App] Add thumbnail preview to ConversationList
This commit is contained in:
parent
cb51cb4adf
commit
8dd0111d99
5 changed files with 68 additions and 5 deletions
|
@ -32,6 +32,7 @@ ConversationListModel::ConversationListModel(QObject* parent)
|
|||
roles.insert(AddressesRole, "addresses");
|
||||
roles.insert(ConversationIdRole, "conversationId");
|
||||
roles.insert(MultitargetRole, "isMultitarget");
|
||||
roles.insert(AttachmentPreview, "attachmentPreview");
|
||||
setItemRoleNames(roles);
|
||||
|
||||
ConversationMessage::registerDbusType();
|
||||
|
@ -190,19 +191,23 @@ void ConversationListModel::createRowFromMessage(const ConversationMessage& mess
|
|||
displayBody = message.body();
|
||||
} else if (message.containsAttachment()) {
|
||||
const QString mimeType = message.attachments().last().mimeType();
|
||||
QString type;
|
||||
if (mimeType.startsWith(QStringLiteral("image"))) {
|
||||
type = i18nc("Used as a text placeholder when the most-recent message is an image", "Picture");
|
||||
displayBody = i18nc("Used as a text placeholder when the most-recent message is an image", "Picture");
|
||||
}
|
||||
else if (mimeType.startsWith(QStringLiteral("video"))) {
|
||||
type = i18nc("Used as a text placeholder when the most-recent message is a video", "Video");
|
||||
displayBody = i18nc("Used as a text placeholder when the most-recent message is a video", "Video");
|
||||
} else {
|
||||
// Craft a somewhat-descriptive string, like "pdf file"
|
||||
type = i18nc("Used as a text placeholder when the most-recent message is an arbitrary attachment, resulting in something like \"pdf file\"",
|
||||
displayBody = i18nc("Used as a text placeholder when the most-recent message is an arbitrary attachment, resulting in something like \"pdf file\"",
|
||||
"%1 file",
|
||||
mimeType.right(mimeType.indexOf(QStringLiteral("/"))));
|
||||
}
|
||||
displayBody = type;
|
||||
}
|
||||
|
||||
// Get the preview from the attachment, if it exists
|
||||
QIcon attachmentPreview;
|
||||
if (message.containsAttachment()) {
|
||||
attachmentPreview = SmsHelper::getThumbnailForAttachment(message.attachments().last());
|
||||
}
|
||||
|
||||
// For displaying single line subtitle out of the multiline messages to keep the ListItems consistent
|
||||
|
@ -231,6 +236,9 @@ void ConversationListModel::createRowFromMessage(const ConversationMessage& mess
|
|||
item->setData(displayBody, Qt::ToolTipRole);
|
||||
item->setData(message.date(), DateRole);
|
||||
item->setData(message.isMultitarget(), MultitargetRole);
|
||||
if (!attachmentPreview.isNull()) {
|
||||
item->setData(attachmentPreview, AttachmentPreview);
|
||||
}
|
||||
}
|
||||
|
||||
if (toadd)
|
||||
|
|
|
@ -32,6 +32,7 @@ public:
|
|||
AddressesRole, // The Addresses involved in the conversation
|
||||
ConversationIdRole, // The ThreadID of the conversation
|
||||
MultitargetRole, // Indicate that this conversation is multitarget
|
||||
AttachmentPreview, // A thumbnail of the attachment of the message, if any
|
||||
};
|
||||
Q_ENUM(Roles)
|
||||
|
||||
|
|
|
@ -221,6 +221,7 @@ Kirigami.ScrollablePage
|
|||
label: display
|
||||
subtitle: toolTip
|
||||
|
||||
property var thumbnail: attachmentPreview
|
||||
|
||||
function startChat() {
|
||||
applicationWindow().pageStack.push(chatView, {
|
||||
|
@ -236,6 +237,30 @@ Kirigami.ScrollablePage
|
|||
startChat();
|
||||
view.currentIndex = index
|
||||
}
|
||||
|
||||
Kirigami.Icon {
|
||||
id: thumbnailItem
|
||||
source: {
|
||||
if (!listItem.thumbnail) {
|
||||
return undefined
|
||||
}
|
||||
if (listItem.thumbnail.hasOwnProperty) {
|
||||
if (listItem.thumbnail.hasOwnProperty("name") && listItem.thumbnail.name !== "")
|
||||
return listItem.thumbnail.name;
|
||||
if (listItem.thumbnail.hasOwnProperty("source"))
|
||||
return listItem.thumbnail.source;
|
||||
}
|
||||
return listItem.thumbnail;
|
||||
}
|
||||
property int size: Kirigami.Units.iconSizes.huge
|
||||
Layout.minimumHeight: size
|
||||
Layout.maximumHeight: size
|
||||
Layout.minimumWidth: size
|
||||
selected: (listItem.highlighted || listItem.checked || (listItem.pressed && listItem.supportsMouseEvents))
|
||||
opacity: 1
|
||||
visible: source != undefined
|
||||
}
|
||||
|
||||
// Keep the currently-open chat highlighted even if this element is not focused
|
||||
highlighted: view.currentIndex == index
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include <QClipboard>
|
||||
#include <QGuiApplication>
|
||||
#include <QIcon>
|
||||
#include <QMimeDatabase>
|
||||
#include <QMimeType>
|
||||
#include <QPainter>
|
||||
#include <QRegularExpression>
|
||||
#include <QString>
|
||||
|
@ -453,3 +455,25 @@ quint64 SmsHelper::totalMessageSize(const QList<QUrl>& urls, const QString& text
|
|||
|
||||
return totalSize;
|
||||
}
|
||||
|
||||
QIcon SmsHelper::getThumbnailForAttachment(const Attachment& attachment) {
|
||||
static const QMimeDatabase mimeDatabase;
|
||||
const QByteArray rawData = QByteArray::fromBase64(attachment.base64EncodedFile().toUtf8());
|
||||
|
||||
if (attachment.mimeType().startsWith(QStringLiteral("image"))
|
||||
|| attachment.mimeType().startsWith(QStringLiteral("video"))) {
|
||||
QPixmap preview;
|
||||
preview.loadFromData(rawData);
|
||||
return QIcon(preview);
|
||||
} else {
|
||||
const QMimeType mimeType = mimeDatabase.mimeTypeForData(rawData);
|
||||
const QIcon mimeIcon = QIcon::fromTheme(mimeType.iconName());
|
||||
if (mimeIcon.isNull()) {
|
||||
// I am not sure if QIcon::isNull will actually tell us what we care about but I don't
|
||||
// know how to trigger the case where we need to use genericIconName instead of iconName
|
||||
return QIcon::fromTheme(mimeType.genericIconName());
|
||||
} else {
|
||||
return mimeIcon;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,6 +120,11 @@ public:
|
|||
*/
|
||||
Q_INVOKABLE static quint64 totalMessageSize(const QList<QUrl>& urls, const QString& text);
|
||||
|
||||
/**
|
||||
* Gets a thumbnail for the given attachment
|
||||
*/
|
||||
Q_INVOKABLE static QIcon getThumbnailForAttachment(const Attachment& attachment);
|
||||
|
||||
private:
|
||||
static bool isInGsmAlphabet(const QChar& ch);
|
||||
static bool isInGsmAlphabetExtension(const QChar& ch);
|
||||
|
|
Loading…
Reference in a new issue