mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-02-07 15:08:24 +00:00
feat(ui/modules/Linphone/Chat/FileMessage): file download is supported
This commit is contained in:
parent
530c3129f4
commit
d706b4c7c9
7 changed files with 123 additions and 26 deletions
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#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);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
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 {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue