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;
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
App::getInstance()->mEngine->setObjectOwnership(this, QQmlEngine::CppOwnership);
|
||||
mChatMessageModel = Utils::makeQObject_ptr<ChatMessageModel>(chatmessage);
|
||||
mChatMessageModel->setSelf(mChatMessageModel);
|
||||
mText = ToolModel::getMessageFromContent(chatmessage->getContents());
|
||||
mUtf8Text = mChatMessageModel->getUtf8Text();
|
||||
mHasTextContent = mChatMessageModel->getHasTextContent();
|
||||
mTimestamp = QDateTime::fromSecsSinceEpoch(chatmessage->getTime());
|
||||
mIsOutgoing = chatmessage->isOutgoing();
|
||||
mIsRemoteMessage = !chatmessage->isOutgoing();
|
||||
mPeerAddress = Utils::coreStringToAppString(chatmessage->getPeerAddress()->asStringUriOnly());
|
||||
mPeerName = ToolModel::getDisplayName(chatmessage->getPeerAddress());
|
||||
auto fromAddress = chatmessage->getFromAddress();
|
||||
// fromAddress->clean();
|
||||
mFromAddress = Utils::coreStringToAppString(fromAddress->asStringUriOnly());
|
||||
mFromName = ToolModel::getDisplayName(chatmessage->getFromAddress());
|
||||
mToName = ToolModel::getDisplayName(chatmessage->getToAddress());
|
||||
if (chatmessage) {
|
||||
mChatMessageModel = Utils::makeQObject_ptr<ChatMessageModel>(chatmessage);
|
||||
mChatMessageModel->setSelf(mChatMessageModel);
|
||||
mText = ToolModel::getMessageFromContent(chatmessage->getContents());
|
||||
mUtf8Text = mChatMessageModel->getUtf8Text();
|
||||
mHasTextContent = mChatMessageModel->getHasTextContent();
|
||||
mTimestamp = QDateTime::fromSecsSinceEpoch(chatmessage->getTime());
|
||||
mIsOutgoing = chatmessage->isOutgoing();
|
||||
mIsRemoteMessage = !chatmessage->isOutgoing();
|
||||
mPeerAddress = Utils::coreStringToAppString(chatmessage->getPeerAddress()->asStringUriOnly());
|
||||
mPeerName = ToolModel::getDisplayName(chatmessage->getPeerAddress());
|
||||
auto fromAddress = chatmessage->getFromAddress();
|
||||
// fromAddress->clean();
|
||||
mFromAddress = Utils::coreStringToAppString(fromAddress->asStringUriOnly());
|
||||
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();
|
||||
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();
|
||||
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;
|
||||
if (mIsEphemeral) {
|
||||
auto now = QDateTime::currentDateTime();
|
||||
mEphemeralDuration = chatmessage->getEphemeralExpireTime() == 0
|
||||
? chatmessage->getEphemeralLifetime()
|
||||
: now.secsTo(QDateTime::fromSecsSinceEpoch(chatmessage->getEphemeralExpireTime()));
|
||||
}
|
||||
}
|
||||
//: "Reactions": all reactions for one message label
|
||||
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);
|
||||
|
||||
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);
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
connect(this, &ChatMessageCore::messageReactionChanged, this, &ChatMessageCore::resetReactionsSingleton);
|
||||
//: "Reactions": all reactions for one message label
|
||||
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();
|
||||
mIsReply = chatmessage->isReply();
|
||||
if (mIsReply) {
|
||||
auto replymessage = chatmessage->getReplyMessage();
|
||||
if (replymessage) {
|
||||
mReplyText = ToolModel::getMessageFromContent(replymessage->getContents());
|
||||
if (mIsFromChatGroup) mRepliedToName = ToolModel::getDisplayName(replymessage->getFromAddress());
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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() {
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ ChatMessageContentCore::ChatMessageContentCore(const std::shared_ptr<linphone::C
|
|||
mName = QFileInfo(fileName).baseName();
|
||||
}
|
||||
}
|
||||
mFilePath = Utils::coreStringToAppString(content->getFilePath());
|
||||
mFilePath = QDir::fromNativeSeparators(Utils::coreStringToAppString(content->getFilePath()));
|
||||
mIsFile = content->isFile();
|
||||
mIsFileEncrypted = content->isFileEncrypted();
|
||||
mIsFileTransfer = content->isFileTransfer();
|
||||
|
|
@ -67,8 +67,8 @@ ChatMessageContentCore::ChatMessageContentCore(const std::shared_ptr<linphone::C
|
|||
mRichFormatText = ToolModel::encodeTextToQmlRichFormat(mUtf8Text, {}, chatRoom);
|
||||
mWasDownloaded = !mFilePath.isEmpty() && QFileInfo(mFilePath).isFile();
|
||||
mThumbnail = mFilePath.isEmpty()
|
||||
? QString()
|
||||
: QStringLiteral("image://%1/%2").arg(ThumbnailProvider::ProviderId).arg(mFilePath);
|
||||
? QUrl()
|
||||
: QUrl(QString("image://%1/%2").arg(ThumbnailProvider::ProviderId).arg(mFilePath));
|
||||
mChatMessageContentModel = Utils::makeQObject_ptr<ChatMessageContentModel>(content, chatMessageModel);
|
||||
}
|
||||
}
|
||||
|
|
@ -92,7 +92,7 @@ void ChatMessageContentCore::setSelf(QSharedPointer<ChatMessageContentCore> me)
|
|||
});
|
||||
mChatMessageContentModelConnection->makeConnectToModel(
|
||||
&ChatMessageContentModel::thumbnailChanged, [this, updateThumbnailType](QString thumbnail) {
|
||||
mChatMessageContentModelConnection->invokeToCore([this, thumbnail] { setThumbnail(thumbnail); });
|
||||
mChatMessageContentModelConnection->invokeToCore([this, thumbnail] { setThumbnail(QUrl(thumbnail)); });
|
||||
});
|
||||
|
||||
mChatMessageContentModelConnection->makeConnectToCore(&ChatMessageContentCore::lDownloadFile, [this]() {
|
||||
|
|
@ -250,11 +250,11 @@ bool ChatMessageContentCore::wasDownloaded() const {
|
|||
return mWasDownloaded;
|
||||
}
|
||||
|
||||
QString ChatMessageContentCore::getThumbnail() const {
|
||||
QUrl ChatMessageContentCore::getThumbnail() const {
|
||||
return mThumbnail;
|
||||
}
|
||||
|
||||
void ChatMessageContentCore::setThumbnail(const QString &data) {
|
||||
void ChatMessageContentCore::setThumbnail(const QUrl &data) {
|
||||
if (mThumbnail != data) {
|
||||
mThumbnail = data;
|
||||
emit thumbnailChanged();
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class ChatMessageContentCore : public QObject, public AbstractObject {
|
|||
Q_PROPERTY(QString name READ getName CONSTANT)
|
||||
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(QString filePath READ getFilePath WRITE setFilePath NOTIFY filePathChanged)
|
||||
Q_PROPERTY(QString utf8Text READ getUtf8Text CONSTANT)
|
||||
|
|
@ -84,8 +84,8 @@ public:
|
|||
int getFileDuration() const;
|
||||
ConferenceInfoGui *getConferenceInfoGui() const;
|
||||
|
||||
void setThumbnail(const QString &data);
|
||||
QString getThumbnail() const;
|
||||
void setThumbnail(const QUrl &data);
|
||||
QUrl getThumbnail() const;
|
||||
|
||||
bool wasDownloaded() const;
|
||||
void setWasDownloaded(bool downloaded);
|
||||
|
|
@ -121,7 +121,7 @@ private:
|
|||
bool mIsText;
|
||||
bool mIsVoiceRecording;
|
||||
int mFileDuration;
|
||||
QString mThumbnail;
|
||||
QUrl mThumbnail;
|
||||
QString mUtf8Text;
|
||||
QString mRichFormatText;
|
||||
QString mFilePath;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ Item {
|
|||
property string filePath: contentGui && contentGui.core.filePath
|
||||
property bool wasDownloaded: contentGui && contentGui.core.wasDownloaded
|
||||
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 bool isTransferring
|
||||
property bool isVideo: UtilsCpp.isVideo(filePath)
|
||||
|
|
@ -68,9 +68,10 @@ Item {
|
|||
fillMode: Image.PreserveAspectFit
|
||||
}
|
||||
Image {
|
||||
id: errorImage
|
||||
anchors.fill: parent
|
||||
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
|
||||
sourceSize.width: mainItem.width
|
||||
sourceSize.height: mainItem.height
|
||||
|
|
@ -79,7 +80,7 @@ Item {
|
|||
Item {
|
||||
id: loadingImageItem
|
||||
anchors.fill: parent
|
||||
visible: mainItem.isImage && image.status === Image.Loading
|
||||
visible: image.status === Image.Loading && !image.visible && !errorImage.visilbe
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: DefaultStyle.main1_200
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue