Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Network
KDE Connect
Commits
8dd0111d
Commit
8dd0111d
authored
Sep 27, 2020
by
Simon Redman
Browse files
[SMS App] Add thumbnail preview to ConversationList
parent
cb51cb4a
Pipeline
#35651
passed with stage
in 11 minutes and 16 seconds
Changes
5
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
smsapp/conversationlistmodel.cpp
View file @
8dd0111d
...
...
@@ -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
)
...
...
smsapp/conversationlistmodel.h
View file @
8dd0111d
...
...
@@ -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
)
...
...
smsapp/qml/ConversationList.qml
View file @
8dd0111d
...
...
@@ -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
}
...
...
smsapp/smshelper.cpp
View file @
8dd0111d
...
...
@@ -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
;
}
}
}
smsapp/smshelper.h
View file @
8dd0111d
...
...
@@ -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
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment