mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 03:18:07 +00:00
fix thumbnail path initialized with \\ when sent from Windows device
This commit is contained in:
parent
d0cf951fe4
commit
db5f6dc2af
4 changed files with 92 additions and 88 deletions
|
|
@ -112,88 +112,91 @@ ChatMessageCore::ChatMessageCore(const std::shared_ptr<linphone::ChatMessage> &c
|
||||||
// lDebug() << "[ChatMessageCore] new" << this;
|
// lDebug() << "[ChatMessageCore] new" << this;
|
||||||
mustBeInLinphoneThread(getClassName());
|
mustBeInLinphoneThread(getClassName());
|
||||||
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||||
mChatMessageModel = Utils::makeQObject_ptr<ChatMessageModel>(chatmessage);
|
if (chatmessage) {
|
||||||
mChatMessageModel->setSelf(mChatMessageModel);
|
mChatMessageModel = Utils::makeQObject_ptr<ChatMessageModel>(chatmessage);
|
||||||
mText = ToolModel::getMessageFromContent(chatmessage->getContents());
|
mChatMessageModel->setSelf(mChatMessageModel);
|
||||||
mUtf8Text = mChatMessageModel->getUtf8Text();
|
mText = ToolModel::getMessageFromContent(chatmessage->getContents());
|
||||||
mHasTextContent = mChatMessageModel->getHasTextContent();
|
mUtf8Text = mChatMessageModel->getUtf8Text();
|
||||||
mTimestamp = QDateTime::fromSecsSinceEpoch(chatmessage->getTime());
|
mHasTextContent = mChatMessageModel->getHasTextContent();
|
||||||
mIsOutgoing = chatmessage->isOutgoing();
|
mTimestamp = QDateTime::fromSecsSinceEpoch(chatmessage->getTime());
|
||||||
mIsRemoteMessage = !chatmessage->isOutgoing();
|
mIsOutgoing = chatmessage->isOutgoing();
|
||||||
mPeerAddress = Utils::coreStringToAppString(chatmessage->getPeerAddress()->asStringUriOnly());
|
mIsRemoteMessage = !chatmessage->isOutgoing();
|
||||||
mPeerName = ToolModel::getDisplayName(chatmessage->getPeerAddress());
|
mPeerAddress = Utils::coreStringToAppString(chatmessage->getPeerAddress()->asStringUriOnly());
|
||||||
auto fromAddress = chatmessage->getFromAddress();
|
mPeerName = ToolModel::getDisplayName(chatmessage->getPeerAddress());
|
||||||
// fromAddress->clean();
|
auto fromAddress = chatmessage->getFromAddress();
|
||||||
mFromAddress = Utils::coreStringToAppString(fromAddress->asStringUriOnly());
|
// fromAddress->clean();
|
||||||
mFromName = ToolModel::getDisplayName(chatmessage->getFromAddress());
|
mFromAddress = Utils::coreStringToAppString(fromAddress->asStringUriOnly());
|
||||||
mToName = ToolModel::getDisplayName(chatmessage->getToAddress());
|
mFromName = ToolModel::getDisplayName(chatmessage->getFromAddress());
|
||||||
|
mToName = ToolModel::getDisplayName(chatmessage->getToAddress());
|
||||||
|
auto chatroom = chatmessage->getChatRoom();
|
||||||
|
mIsFromChatGroup = chatroom->hasCapability((int)linphone::ChatRoom::Capabilities::Conference) &&
|
||||||
|
!chatroom->hasCapability((int)linphone::ChatRoom::Capabilities::OneToOne);
|
||||||
|
mIsRead = chatmessage->isRead();
|
||||||
|
mMessageState = LinphoneEnums::fromLinphone(chatmessage->getState());
|
||||||
|
mIsEphemeral = chatmessage->isEphemeral();
|
||||||
|
|
||||||
auto chatroom = chatmessage->getChatRoom();
|
if (mIsEphemeral) {
|
||||||
mIsFromChatGroup = chatroom->hasCapability((int)linphone::ChatRoom::Capabilities::Conference) &&
|
auto now = QDateTime::currentDateTime();
|
||||||
!chatroom->hasCapability((int)linphone::ChatRoom::Capabilities::OneToOne);
|
mEphemeralDuration = chatmessage->getEphemeralExpireTime() == 0
|
||||||
mIsRead = chatmessage->isRead();
|
? chatmessage->getEphemeralLifetime()
|
||||||
mMessageState = LinphoneEnums::fromLinphone(chatmessage->getState());
|
: now.secsTo(QDateTime::fromSecsSinceEpoch(chatmessage->getEphemeralExpireTime()));
|
||||||
mIsEphemeral = chatmessage->isEphemeral();
|
|
||||||
if (mIsEphemeral) {
|
|
||||||
auto now = QDateTime::currentDateTime();
|
|
||||||
mEphemeralDuration = chatmessage->getEphemeralExpireTime() == 0
|
|
||||||
? chatmessage->getEphemeralLifetime()
|
|
||||||
: now.secsTo(QDateTime::fromSecsSinceEpoch(chatmessage->getEphemeralExpireTime()));
|
|
||||||
}
|
|
||||||
mMessageId = Utils::coreStringToAppString(chatmessage->getMessageId());
|
|
||||||
for (auto content : chatmessage->getContents()) {
|
|
||||||
auto contentCore = ChatMessageContentCore::create(content, mChatMessageModel);
|
|
||||||
mChatMessageContentList.push_back(contentCore);
|
|
||||||
if ((content->isFile() || content->isFileTransfer()) && !content->isVoiceRecording()) mHasFileContent = true;
|
|
||||||
if (content->isIcalendar()) mIsCalendarInvite = true;
|
|
||||||
if (content->isVoiceRecording()) {
|
|
||||||
mIsVoiceRecording = true;
|
|
||||||
mVoiceRecordingContent = contentCore;
|
|
||||||
}
|
}
|
||||||
}
|
mMessageId = Utils::coreStringToAppString(chatmessage->getMessageId());
|
||||||
//: "Reactions": all reactions for one message label
|
for (auto content : chatmessage->getContents()) {
|
||||||
mTotalReactionsLabel = tr("all_reactions_label");
|
auto contentCore = ChatMessageContentCore::create(content, mChatMessageModel);
|
||||||
auto reac = chatmessage->getOwnReaction();
|
mChatMessageContentList.push_back(contentCore);
|
||||||
mOwnReaction = reac ? Utils::coreStringToAppString(reac->getBody()) : QString();
|
if ((content->isFile() || content->isFileTransfer()) && !content->isVoiceRecording())
|
||||||
for (auto &reaction : chatmessage->getReactions()) {
|
mHasFileContent = true;
|
||||||
if (reaction) {
|
if (content->isIcalendar()) mIsCalendarInvite = true;
|
||||||
auto fromAddr = reaction->getFromAddress()->clone();
|
if (content->isVoiceRecording()) {
|
||||||
fromAddr->clean();
|
mIsVoiceRecording = true;
|
||||||
auto reac =
|
mVoiceRecordingContent = contentCore;
|
||||||
Reaction::createMessageReactionVariant(Utils::coreStringToAppString(reaction->getBody()),
|
|
||||||
Utils::coreStringToAppString(fromAddr->asStringUriOnly()));
|
|
||||||
mReactions.append(reac);
|
|
||||||
|
|
||||||
auto it = std::find_if(mReactionsSingletonMap.begin(), mReactionsSingletonMap.end(),
|
|
||||||
[body = reac.mBody](QVariant data) {
|
|
||||||
auto dataBody = data.toMap()["body"].toString();
|
|
||||||
return body == dataBody;
|
|
||||||
});
|
|
||||||
if (it == mReactionsSingletonMap.end())
|
|
||||||
mReactionsSingletonMap.push_back(createReactionSingletonVariant(reac.mBody, 1));
|
|
||||||
else {
|
|
||||||
auto map = it->toMap();
|
|
||||||
auto count = map["count"].toInt();
|
|
||||||
++count;
|
|
||||||
map.remove("count");
|
|
||||||
map.insert("count", count);
|
|
||||||
mReactionsSingletonMap.erase(it);
|
|
||||||
mReactionsSingletonMap.push_back(map);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
//: "Reactions": all reactions for one message label
|
||||||
connect(this, &ChatMessageCore::messageReactionChanged, this, &ChatMessageCore::resetReactionsSingleton);
|
mTotalReactionsLabel = tr("all_reactions_label");
|
||||||
|
auto reac = chatmessage->getOwnReaction();
|
||||||
|
mOwnReaction = reac ? Utils::coreStringToAppString(reac->getBody()) : QString();
|
||||||
|
for (auto &reaction : chatmessage->getReactions()) {
|
||||||
|
if (reaction) {
|
||||||
|
auto fromAddr = reaction->getFromAddress()->clone();
|
||||||
|
fromAddr->clean();
|
||||||
|
auto reac =
|
||||||
|
Reaction::createMessageReactionVariant(Utils::coreStringToAppString(reaction->getBody()),
|
||||||
|
Utils::coreStringToAppString(fromAddr->asStringUriOnly()));
|
||||||
|
mReactions.append(reac);
|
||||||
|
|
||||||
mIsForward = chatmessage->isForward();
|
auto it = std::find_if(mReactionsSingletonMap.begin(), mReactionsSingletonMap.end(),
|
||||||
mIsReply = chatmessage->isReply();
|
[body = reac.mBody](QVariant data) {
|
||||||
if (mIsReply) {
|
auto dataBody = data.toMap()["body"].toString();
|
||||||
auto replymessage = chatmessage->getReplyMessage();
|
return body == dataBody;
|
||||||
if (replymessage) {
|
});
|
||||||
mReplyText = ToolModel::getMessageFromContent(replymessage->getContents());
|
if (it == mReactionsSingletonMap.end())
|
||||||
if (mIsFromChatGroup) mRepliedToName = ToolModel::getDisplayName(replymessage->getFromAddress());
|
mReactionsSingletonMap.push_back(createReactionSingletonVariant(reac.mBody, 1));
|
||||||
|
else {
|
||||||
|
auto map = it->toMap();
|
||||||
|
auto count = map["count"].toInt();
|
||||||
|
++count;
|
||||||
|
map.remove("count");
|
||||||
|
map.insert("count", count);
|
||||||
|
mReactionsSingletonMap.erase(it);
|
||||||
|
mReactionsSingletonMap.push_back(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
connect(this, &ChatMessageCore::messageReactionChanged, this, &ChatMessageCore::resetReactionsSingleton);
|
||||||
|
|
||||||
|
mIsForward = chatmessage->isForward();
|
||||||
|
mIsReply = chatmessage->isReply();
|
||||||
|
if (mIsReply) {
|
||||||
|
auto replymessage = chatmessage->getReplyMessage();
|
||||||
|
if (replymessage) {
|
||||||
|
mReplyText = ToolModel::getMessageFromContent(replymessage->getContents());
|
||||||
|
if (mIsFromChatGroup) mRepliedToName = ToolModel::getDisplayName(replymessage->getFromAddress());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mImdnStatusList = computeDeliveryStatus(chatmessage);
|
||||||
}
|
}
|
||||||
mImdnStatusList = computeDeliveryStatus(chatmessage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatMessageCore::~ChatMessageCore() {
|
ChatMessageCore::~ChatMessageCore() {
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ ChatMessageContentCore::ChatMessageContentCore(const std::shared_ptr<linphone::C
|
||||||
mName = QFileInfo(fileName).baseName();
|
mName = QFileInfo(fileName).baseName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mFilePath = Utils::coreStringToAppString(content->getFilePath());
|
mFilePath = QDir::fromNativeSeparators(Utils::coreStringToAppString(content->getFilePath()));
|
||||||
mIsFile = content->isFile();
|
mIsFile = content->isFile();
|
||||||
mIsFileEncrypted = content->isFileEncrypted();
|
mIsFileEncrypted = content->isFileEncrypted();
|
||||||
mIsFileTransfer = content->isFileTransfer();
|
mIsFileTransfer = content->isFileTransfer();
|
||||||
|
|
@ -67,8 +67,8 @@ ChatMessageContentCore::ChatMessageContentCore(const std::shared_ptr<linphone::C
|
||||||
mRichFormatText = ToolModel::encodeTextToQmlRichFormat(mUtf8Text, {}, chatRoom);
|
mRichFormatText = ToolModel::encodeTextToQmlRichFormat(mUtf8Text, {}, chatRoom);
|
||||||
mWasDownloaded = !mFilePath.isEmpty() && QFileInfo(mFilePath).isFile();
|
mWasDownloaded = !mFilePath.isEmpty() && QFileInfo(mFilePath).isFile();
|
||||||
mThumbnail = mFilePath.isEmpty()
|
mThumbnail = mFilePath.isEmpty()
|
||||||
? QString()
|
? QUrl()
|
||||||
: QStringLiteral("image://%1/%2").arg(ThumbnailProvider::ProviderId).arg(mFilePath);
|
: QUrl(QString("image://%1/%2").arg(ThumbnailProvider::ProviderId).arg(mFilePath));
|
||||||
mChatMessageContentModel = Utils::makeQObject_ptr<ChatMessageContentModel>(content, chatMessageModel);
|
mChatMessageContentModel = Utils::makeQObject_ptr<ChatMessageContentModel>(content, chatMessageModel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -92,7 +92,7 @@ void ChatMessageContentCore::setSelf(QSharedPointer<ChatMessageContentCore> me)
|
||||||
});
|
});
|
||||||
mChatMessageContentModelConnection->makeConnectToModel(
|
mChatMessageContentModelConnection->makeConnectToModel(
|
||||||
&ChatMessageContentModel::thumbnailChanged, [this, updateThumbnailType](QString thumbnail) {
|
&ChatMessageContentModel::thumbnailChanged, [this, updateThumbnailType](QString thumbnail) {
|
||||||
mChatMessageContentModelConnection->invokeToCore([this, thumbnail] { setThumbnail(thumbnail); });
|
mChatMessageContentModelConnection->invokeToCore([this, thumbnail] { setThumbnail(QUrl(thumbnail)); });
|
||||||
});
|
});
|
||||||
|
|
||||||
mChatMessageContentModelConnection->makeConnectToCore(&ChatMessageContentCore::lDownloadFile, [this]() {
|
mChatMessageContentModelConnection->makeConnectToCore(&ChatMessageContentCore::lDownloadFile, [this]() {
|
||||||
|
|
@ -250,11 +250,11 @@ bool ChatMessageContentCore::wasDownloaded() const {
|
||||||
return mWasDownloaded;
|
return mWasDownloaded;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ChatMessageContentCore::getThumbnail() const {
|
QUrl ChatMessageContentCore::getThumbnail() const {
|
||||||
return mThumbnail;
|
return mThumbnail;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatMessageContentCore::setThumbnail(const QString &data) {
|
void ChatMessageContentCore::setThumbnail(const QUrl &data) {
|
||||||
if (mThumbnail != data) {
|
if (mThumbnail != data) {
|
||||||
mThumbnail = data;
|
mThumbnail = data;
|
||||||
emit thumbnailChanged();
|
emit thumbnailChanged();
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ class ChatMessageContentCore : public QObject, public AbstractObject {
|
||||||
Q_PROPERTY(QString name READ getName CONSTANT)
|
Q_PROPERTY(QString name READ getName CONSTANT)
|
||||||
Q_PROPERTY(quint64 fileOffset READ getFileOffset WRITE setFileOffset NOTIFY fileOffsetChanged)
|
Q_PROPERTY(quint64 fileOffset READ getFileOffset WRITE setFileOffset NOTIFY fileOffsetChanged)
|
||||||
|
|
||||||
Q_PROPERTY(QString thumbnail READ getThumbnail WRITE setThumbnail NOTIFY thumbnailChanged)
|
Q_PROPERTY(QUrl thumbnail READ getThumbnail WRITE setThumbnail NOTIFY thumbnailChanged)
|
||||||
Q_PROPERTY(bool wasDownloaded READ wasDownloaded WRITE setWasDownloaded NOTIFY wasDownloadedChanged)
|
Q_PROPERTY(bool wasDownloaded READ wasDownloaded WRITE setWasDownloaded NOTIFY wasDownloadedChanged)
|
||||||
Q_PROPERTY(QString filePath READ getFilePath WRITE setFilePath NOTIFY filePathChanged)
|
Q_PROPERTY(QString filePath READ getFilePath WRITE setFilePath NOTIFY filePathChanged)
|
||||||
Q_PROPERTY(QString utf8Text READ getUtf8Text CONSTANT)
|
Q_PROPERTY(QString utf8Text READ getUtf8Text CONSTANT)
|
||||||
|
|
@ -84,8 +84,8 @@ public:
|
||||||
int getFileDuration() const;
|
int getFileDuration() const;
|
||||||
ConferenceInfoGui *getConferenceInfoGui() const;
|
ConferenceInfoGui *getConferenceInfoGui() const;
|
||||||
|
|
||||||
void setThumbnail(const QString &data);
|
void setThumbnail(const QUrl &data);
|
||||||
QString getThumbnail() const;
|
QUrl getThumbnail() const;
|
||||||
|
|
||||||
bool wasDownloaded() const;
|
bool wasDownloaded() const;
|
||||||
void setWasDownloaded(bool downloaded);
|
void setWasDownloaded(bool downloaded);
|
||||||
|
|
@ -121,7 +121,7 @@ private:
|
||||||
bool mIsText;
|
bool mIsText;
|
||||||
bool mIsVoiceRecording;
|
bool mIsVoiceRecording;
|
||||||
int mFileDuration;
|
int mFileDuration;
|
||||||
QString mThumbnail;
|
QUrl mThumbnail;
|
||||||
QString mUtf8Text;
|
QString mUtf8Text;
|
||||||
QString mRichFormatText;
|
QString mRichFormatText;
|
||||||
QString mFilePath;
|
QString mFilePath;
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ Item {
|
||||||
property string filePath: contentGui && contentGui.core.filePath
|
property string filePath: contentGui && contentGui.core.filePath
|
||||||
property bool wasDownloaded: contentGui && contentGui.core.wasDownloaded
|
property bool wasDownloaded: contentGui && contentGui.core.wasDownloaded
|
||||||
property bool isAnimatedImage : contentGui && contentGui.core.wasDownloaded && UtilsCpp.isAnimatedImage(filePath)
|
property bool isAnimatedImage : contentGui && contentGui.core.wasDownloaded && UtilsCpp.isAnimatedImage(filePath)
|
||||||
property bool haveThumbnail: contentGui && UtilsCpp.canHaveThumbnail(filePath)
|
property bool haveThumbnail: contentGui && UtilsCpp.canHaveThumbnail(filePath) && UtilsCpp.fileExists(filePath)
|
||||||
property int fileSize: contentGui ? contentGui.core.fileSize : 0
|
property int fileSize: contentGui ? contentGui.core.fileSize : 0
|
||||||
property bool isTransferring
|
property bool isTransferring
|
||||||
property bool isVideo: UtilsCpp.isVideo(filePath)
|
property bool isVideo: UtilsCpp.isVideo(filePath)
|
||||||
|
|
@ -68,9 +68,10 @@ Item {
|
||||||
fillMode: Image.PreserveAspectFit
|
fillMode: Image.PreserveAspectFit
|
||||||
}
|
}
|
||||||
Image {
|
Image {
|
||||||
|
id: errorImage
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
z: image.z + 1
|
z: image.z + 1
|
||||||
visible: image.status == Image.Error || image.status == Image.Null || !UtilsCpp.fileExists(mainItem.filePath)
|
visible: image.status == Image.Error || image.status == Image.Null
|
||||||
source: AppIcons.fileImage
|
source: AppIcons.fileImage
|
||||||
sourceSize.width: mainItem.width
|
sourceSize.width: mainItem.width
|
||||||
sourceSize.height: mainItem.height
|
sourceSize.height: mainItem.height
|
||||||
|
|
@ -79,7 +80,7 @@ Item {
|
||||||
Item {
|
Item {
|
||||||
id: loadingImageItem
|
id: loadingImageItem
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: mainItem.isImage && image.status === Image.Loading
|
visible: image.status === Image.Loading && !image.visible && !errorImage.visilbe
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: DefaultStyle.main1_200
|
color: DefaultStyle.main1_200
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue