Commit d706b4c7 authored by Ronan Abhamon's avatar Ronan Abhamon

feat(ui/modules/Linphone/Chat/FileMessage): file download is supported

parent 530c3129
......@@ -311,6 +311,13 @@ Server url not configured.</translation>
<translation>Missed outgoing call</translation>
</message>
</context>
<context>
<name>FileMessage</name>
<message>
<source>downloadFileTitle</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Home</name>
<message>
......
......@@ -299,6 +299,13 @@ Url du serveur non configurée.</translation>
<translation>Appel sortant sans réponse</translation>
</message>
</context>
<context>
<name>FileMessage</name>
<message>
<source>downloadFileTitle</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>Home</name>
<message>
......
#include <algorithm>
#include <QDateTime>
#include <QFileDialog>
#include <QFileInfo>
#include <QImage>
#include <QtDebug>
......@@ -22,10 +23,36 @@ using namespace std;
// =============================================================================
inline void fillThumbnailProperty (QVariantMap &dest, const shared_ptr<linphone::ChatMessage> &message) {
string data = message->getAppdata();
if (!data.empty())
string file_id = message->getAppdata();
if (!file_id.empty() && !dest.contains("thumbnail"))
dest["thumbnail"] = QStringLiteral("image://%1/%2")
.arg(ThumbnailProvider::PROVIDER_ID).arg(::Utils::linphoneStringToQString(data));
.arg(ThumbnailProvider::PROVIDER_ID).arg(::Utils::linphoneStringToQString(file_id));
}
inline void createThumbnail (const shared_ptr<linphone::ChatMessage> &message) {
if (!message->getAppdata().empty())
return;
QString thumbnail_path = ::Utils::linphoneStringToQString(message->getFileTransferFilepath());
QImage image(thumbnail_path);
if (image.isNull())
return;
QImage thumbnail = image.scaled(
THUMBNAIL_IMAGE_FILE_WIDTH, THUMBNAIL_IMAGE_FILE_HEIGHT,
Qt::KeepAspectRatio, Qt::SmoothTransformation
);
QString uuid = QUuid::createUuid().toString();
QString file_id = QStringLiteral("%1.jpg").arg(uuid.mid(1, uuid.length() - 2));
if (!thumbnail.save(::Utils::linphoneStringToQString(Paths::getThumbnailsDirPath()) + file_id, "jpg", 100)) {
qWarning() << QStringLiteral("Unable to create thumbnail of: `%1`.").arg(thumbnail_path);
return;
}
message->setAppdata(::Utils::qStringToLinphoneString(file_id));
}
inline void removeFileMessageThumbnail (const shared_ptr<linphone::ChatMessage> &message) {
......@@ -112,24 +139,8 @@ private:
if (state == linphone::ChatMessageStateFileTransferError)
state = linphone::ChatMessageStateNotDelivered;
else if (state == linphone::ChatMessageStateFileTransferDone) {
QString thumbnail_path = ::Utils::linphoneStringToQString(message->getFileTransferFilepath());
QImage image(thumbnail_path);
if (!image.isNull()) {
QImage thumbnail = image.scaled(
THUMBNAIL_IMAGE_FILE_WIDTH, THUMBNAIL_IMAGE_FILE_HEIGHT,
Qt::KeepAspectRatio, Qt::SmoothTransformation
);
QString uuid = QUuid::createUuid().toString();
QString file_id = QStringLiteral("%1.jpg").arg(uuid.mid(1, uuid.length() - 2));
if (!thumbnail.save(::Utils::linphoneStringToQString(Paths::getThumbnailsDirPath()) + file_id, "jpg", 100)) {
qWarning() << QStringLiteral("Unable to create thumbnail of: `%1`.").arg(thumbnail_path);
return;
}
message->setAppdata(::Utils::qStringToLinphoneString(file_id));
if (!message->isOutgoing()) {
createThumbnail(message);
fillThumbnailProperty((*it).first, message);
}
......@@ -348,7 +359,8 @@ void ChatModel::resendMessage (int id) {
}
shared_ptr<linphone::ChatMessage> message = static_pointer_cast<linphone::ChatMessage>(entry.second);
if (message->getState() != linphone::ChatMessageStateNotDelivered) {
int state = message->getState();
if (state != linphone::ChatMessageStateNotDelivered && state != linphone::ChatMessageStateFileTransferError) {
qWarning() << QStringLiteral("Unable to resend message: %1. Bad state.").arg(id);
return;
}
......@@ -381,6 +393,45 @@ void ChatModel::sendFileMessage (const QString &path) {
emit messageSent(message);
}
void ChatModel::downloadFile (int id, const QString &download_path) {
if (!m_chat_room)
return;
if (id < 0 || id > m_entries.count()) {
qWarning() << QStringLiteral("Entry %1 not exists.").arg(id);
return;
}
const ChatEntryData &entry = m_entries[id];
if (entry.first["type"] != EntryType::MessageEntry) {
qWarning() << QStringLiteral("Unable to download entry %1. It's not a message.").arg(id);
return;
}
shared_ptr<linphone::ChatMessage> message = static_pointer_cast<linphone::ChatMessage>(entry.second);
if (!message->getFileTransferInformation()) {
qWarning() << QStringLiteral("Entry %1 is not a file message.").arg(id);
return;
}
int state = message->getState();
if (state != linphone::ChatMessageStateDelivered && state != linphone::ChatMessageStateFileTransferDone) {
qWarning() << QStringLiteral("Unable to download file of entry %1. It was not uploaded.").arg(id);
return;
}
message->setFileTransferFilepath(
::Utils::qStringToLinphoneString(download_path.startsWith("file://")
? download_path.mid(sizeof("file://") - 1)
: download_path
)
);
message->setListener(m_message_handlers);
if (message->downloadFile() < 0)
qWarning() << QStringLiteral("Unable to download file of entry %1.").arg(id);
}
// -----------------------------------------------------------------------------
void ChatModel::fillMessageEntry (QVariantMap &dest, const shared_ptr<linphone::ChatMessage> &message) {
......
......@@ -70,6 +70,8 @@ public:
void sendFileMessage (const QString &path);
void downloadFile (int id, const QString &download_path);
signals:
void sipAddressChanged (const QString &sip_address);
void allEntriesRemoved ();
......
......@@ -109,6 +109,13 @@ void ChatProxyModel::sendFileMessage (const QString &path) {
static_cast<ChatModel *>(m_chat_model_filter->sourceModel())->sendFileMessage(path);
}
void ChatProxyModel::downloadFile (int id, const QString &download_path) {
QModelIndex source_index = mapToSource(index(id, 0));
static_cast<ChatModel *>(m_chat_model_filter->sourceModel())->downloadFile(
m_chat_model_filter->mapToSource(source_index).row(), download_path
);
}
// -----------------------------------------------------------------------------
bool ChatProxyModel::filterAcceptsRow (int source_row, const QModelIndex &) const {
......
......@@ -28,6 +28,8 @@ public:
Q_INVOKABLE void sendFileMessage (const QString &path);
Q_INVOKABLE void downloadFile (int id, const QString &download_path);
signals:
void sipAddressChanged (const QString &sip_address);
void moreEntriesLoaded (int n);
......
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.3
import Common 1.0
......@@ -47,6 +48,8 @@ Row {
Rectangle {
id: rectangle
readonly property bool isNotDelivered: $chatEntry.status === ChatModel.MessageStatusNotDelivered
color: $chatEntry.isOutgoing
? ChatStyle.entry.message.outgoing.backgroundColor
: ChatStyle.entry.message.incoming.backgroundColor
......@@ -169,6 +172,27 @@ Row {
}
}
}
MouseArea {
FileDialog {
id: fileDialog
folder: shortcuts.home
title: qsTr('downloadFileTitle')
selectExisting: false
onAccepted: proxyModel.downloadFile(index, fileUrl)
}
anchors.fill: parent
cursorShape: containsMouse
? Qt.PointingHandCursor
: Qt.ArrowCursor
hoverEnabled: true
onClicked: fileDialog.open()
visible: !rectangle.isNotDelivered && !$chatEntry.isOutgoing
}
}
// -------------------------------------------------------------------------
......@@ -182,10 +206,7 @@ Row {
id: icon
Icon {
readonly property bool isNotDelivered:
$chatEntry.status === ChatModel.MessageStatusNotDelivered
icon: isNotDelivered ? 'chat_error' : 'chat_send'
icon: rectangle.isNotDelivered ? 'chat_error' : 'chat_send'
iconSize: ChatStyle.entry.message.outgoing.sendIconSize
MouseArea {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment