mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 03:18:07 +00:00
fix #LINQT-11899 text in messages disappearing (compute encoding to rich format only once for each message instead of doing it everytime something changes in the list)
This commit is contained in:
parent
836d0b1da3
commit
be531b5e9f
6 changed files with 120 additions and 8 deletions
|
|
@ -63,6 +63,8 @@ ChatMessageContentCore::ChatMessageContentCore(const std::shared_ptr<linphone::C
|
|||
mFileDuration = content->getFileDuration();
|
||||
mFileOffset = 0;
|
||||
mUtf8Text = Utils::coreStringToAppString(content->getUtf8Text());
|
||||
auto chatRoom = chatMessageModel ? chatMessageModel->getMonitor()->getChatRoom() : nullptr;
|
||||
mRichFormatText = ToolModel::encodeTextToQmlRichFormat(mUtf8Text, {}, chatRoom);
|
||||
mWasDownloaded = !mFilePath.isEmpty() && QFileInfo(mFilePath).isFile();
|
||||
mThumbnail = mFilePath.isEmpty()
|
||||
? QString()
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ class ChatMessageContentCore : public QObject, public AbstractObject {
|
|||
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)
|
||||
Q_PROPERTY(QString richFormatText MEMBER mRichFormatText CONSTANT)
|
||||
Q_PROPERTY(bool isFile READ isFile WRITE setIsFile NOTIFY isFileChanged)
|
||||
Q_PROPERTY(bool isFileEncrypted READ isFileEncrypted WRITE setIsFileEncrypted NOTIFY isFileEncryptedChanged)
|
||||
Q_PROPERTY(bool isFileTransfer READ isFileTransfer WRITE setIsFileTransfer NOTIFY isFileTransferChanged)
|
||||
|
|
@ -122,6 +123,7 @@ private:
|
|||
int mFileDuration;
|
||||
QString mThumbnail;
|
||||
QString mUtf8Text;
|
||||
QString mRichFormatText;
|
||||
QString mFilePath;
|
||||
QString mName;
|
||||
quint64 mFileSize;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "core/path/Paths.hpp"
|
||||
#include "model/core/CoreModel.hpp"
|
||||
#include "model/friend/FriendsManager.hpp"
|
||||
#include "tool/UriTools.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
#include <QDebug>
|
||||
#include <QDirIterator>
|
||||
|
|
@ -117,6 +118,108 @@ QString ToolModel::getDisplayName(QString address) {
|
|||
return nameSplitted.join(" ");
|
||||
}
|
||||
|
||||
QString ToolModel::encodeTextToQmlRichFormat(const QString &text,
|
||||
const QVariantMap &options,
|
||||
std::shared_ptr<linphone::ChatRoom> chatRoom) {
|
||||
QStringList formattedText;
|
||||
bool lastWasUrl = false;
|
||||
auto primaryColor = QColor::fromString("#4AA8FF");
|
||||
|
||||
if (options.contains("noLink") && options["noLink"].toBool()) {
|
||||
formattedText.append(Utils::encodeEmojiToQmlRichFormat(text));
|
||||
} else {
|
||||
|
||||
auto iriParsed = UriTools::parseIri(text);
|
||||
|
||||
for (int i = 0; i < iriParsed.size(); ++i) {
|
||||
QString iri = iriParsed[i]
|
||||
.second.replace('&', "&")
|
||||
.replace('<', "\u2063<")
|
||||
.replace('>', "\u2063>")
|
||||
.replace('"', """)
|
||||
.replace('\'', "'");
|
||||
if (!iriParsed[i].first) {
|
||||
if (lastWasUrl) {
|
||||
lastWasUrl = false;
|
||||
if (iri.front() != ' ') iri.push_front(' ');
|
||||
}
|
||||
formattedText.append(Utils::encodeEmojiToQmlRichFormat(iri));
|
||||
} else {
|
||||
QString uri =
|
||||
iriParsed[i].second.left(3) == "www" ? "http://" + iriParsed[i].second : iriParsed[i].second;
|
||||
/* TODO : preview from link
|
||||
int extIndex = iriParsed[i].second.lastIndexOf('.');
|
||||
QString ext;
|
||||
if( extIndex >= 0)
|
||||
ext = iriParsed[i].second.mid(extIndex+1).toUpper();
|
||||
if(imageFormat.contains(ext.toLatin1())){// imagesHeight is not used because of bugs on display
|
||||
(blank image if set without width) images += "<a href=\"" + uri + "\"><img" + (
|
||||
options.contains("imagesWidth") ? QString(" width='") + options["imagesWidth"].toString() + "'" : ""
|
||||
) + (
|
||||
options.contains("imagesWidth")
|
||||
? QString(" height='auto'")
|
||||
: ""
|
||||
) + " src=\"" + iriParsed[i].second + "\" />"+uri+"</a>";
|
||||
}else{
|
||||
*/
|
||||
formattedText.append("<a style=\"color:" + primaryColor.name() + ";\" href=\"" + uri + "\">" + iri +
|
||||
"</a>");
|
||||
lastWasUrl = true;
|
||||
/*}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lastWasUrl && formattedText.last().back() != ' ') {
|
||||
formattedText.push_back(" ");
|
||||
}
|
||||
if (chatRoom) {
|
||||
auto participants = chatRoom->getParticipants();
|
||||
auto mentionsParsed = UriTools::parseMention(formattedText.join(""));
|
||||
formattedText.clear();
|
||||
|
||||
for (int i = 0; i < mentionsParsed.size(); ++i) {
|
||||
QString mention = mentionsParsed[i].second;
|
||||
|
||||
if (mentionsParsed[i].first) {
|
||||
QString mentions = mentionsParsed[i].second;
|
||||
QStringList finalMentions;
|
||||
QStringList parts = mentions.split(" ");
|
||||
for (auto part : parts) {
|
||||
if (part.startsWith("@")) { // mention
|
||||
QString username = part;
|
||||
username.removeFirst();
|
||||
auto it = std::find_if(participants.begin(), participants.end(),
|
||||
[username](std::shared_ptr<linphone::Participant> p) {
|
||||
return p->getAddress() && username == p->getAddress()->getUsername();
|
||||
});
|
||||
if (it != participants.end()) {
|
||||
auto foundParticipant = *it;
|
||||
// participants.at(std::distance(participants.begin(), it));
|
||||
auto address = foundParticipant->getAddress()->clone();
|
||||
auto isFriend = findFriendByAddress(address);
|
||||
address->clean();
|
||||
auto addressString = Utils::coreStringToAppString(address->asStringUriOnly());
|
||||
if (isFriend)
|
||||
part = "@" + Utils::coreStringToAppString(isFriend->getAddress()->getDisplayName());
|
||||
QString participantLink = "<a style=\"color:" + primaryColor.name() +
|
||||
";\" href=\"mention:" + addressString + "\">" + part + "</a>";
|
||||
finalMentions.append(participantLink);
|
||||
} else {
|
||||
finalMentions.append(part);
|
||||
}
|
||||
} else {
|
||||
finalMentions.append(part);
|
||||
}
|
||||
}
|
||||
formattedText.push_back(finalMentions.join(" "));
|
||||
} else {
|
||||
formattedText.push_back(mentionsParsed[i].second);
|
||||
}
|
||||
}
|
||||
}
|
||||
return "<p style=\"white-space:pre-wrap;\">" + formattedText.join("");
|
||||
}
|
||||
|
||||
std::shared_ptr<linphone::Friend> ToolModel::findFriendByAddress(const QString &address) {
|
||||
auto defaultFriendList = CoreModel::getInstance()->getCore()->getDefaultFriendList();
|
||||
if (!defaultFriendList) return nullptr;
|
||||
|
|
|
|||
|
|
@ -50,6 +50,10 @@ public:
|
|||
static QString getDisplayName(const std::shared_ptr<linphone::Address> &address);
|
||||
static QString getDisplayName(QString address);
|
||||
|
||||
static QString encodeTextToQmlRichFormat(const QString &text,
|
||||
const QVariantMap &options,
|
||||
std::shared_ptr<linphone::ChatRoom> chatRoom);
|
||||
|
||||
static std::shared_ptr<linphone::Friend> findFriendByAddress(const QString &address);
|
||||
static std::shared_ptr<linphone::Friend> findFriendByAddress(std::shared_ptr<linphone::Address> linphoneAddr);
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,10 @@ ListView {
|
|||
initialDisplayItems: 10
|
||||
onEventInserted: (index, gui) => {
|
||||
if (!mainItem.visible) return
|
||||
if(mainItem.lastItemVisible) mainItem.positionViewAtIndex(index, ListView.Beginning)
|
||||
if(mainItem.lastItemVisible) {
|
||||
mainItem.positionViewAtIndex(index, ListView.Beginning)
|
||||
markIndexAsRead(index)
|
||||
}
|
||||
}
|
||||
Component.onCompleted: loading = true
|
||||
onListAboutToBeReset: loading = true
|
||||
|
|
@ -239,6 +242,7 @@ ListView {
|
|||
Component.onCompleted: {
|
||||
if (index === 0) mainItem.lastItemVisible = isFullyVisible
|
||||
}
|
||||
onYChanged: if (index === 0) mainItem.lastItemVisible = isFullyVisible
|
||||
chat: mainItem.chat
|
||||
searchedTextPart: mainItem.filterText
|
||||
maxWidth: Math.round(mainItem.width * (3/4))
|
||||
|
|
|
|||
|
|
@ -26,13 +26,10 @@ TextEdit {
|
|||
readOnly: true
|
||||
selectByMouse: true
|
||||
|
||||
property var encodeTextObj: visible ? UtilsCpp.encodeTextToQmlRichFormat(contentGui.core.utf8Text, {}, mainItem.chatGui)
|
||||
: ''
|
||||
text: encodeTextObj
|
||||
&& (searchedTextPart !== ""
|
||||
? UtilsCpp.boldTextPart(encodeTextObj.value, searchedTextPart)
|
||||
: encodeTextObj.value)
|
||||
|| ""
|
||||
text: searchedTextPart !== ""
|
||||
? UtilsCpp.boldTextPart(contentGui.core.richFormatText, searchedTextPart)
|
||||
: contentGui.core.richFormatText
|
||||
|
||||
textFormat: Text.RichText // To supports links and imgs.
|
||||
wrapMode: TextEdit.Wrap
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue