mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 03:18:07 +00:00
Chat message edition
This commit is contained in:
parent
d40045d5bb
commit
1bae93aab5
17 changed files with 232 additions and 11 deletions
|
|
@ -120,8 +120,12 @@ ChatMessageCore::ChatMessageCore(const std::shared_ptr<linphone::ChatMessage> &c
|
||||||
mHasTextContent = mChatMessageModel->getHasTextContent();
|
mHasTextContent = mChatMessageModel->getHasTextContent();
|
||||||
mTimestamp = QDateTime::fromSecsSinceEpoch(chatmessage->getTime());
|
mTimestamp = QDateTime::fromSecsSinceEpoch(chatmessage->getTime());
|
||||||
mIsOutgoing = chatmessage->isOutgoing();
|
mIsOutgoing = chatmessage->isOutgoing();
|
||||||
mIsRetractable = chatmessage->isRetractable();
|
mIsRetractable =
|
||||||
|
chatmessage->isOutgoing() && chatmessage->isRetractable() && !chatmessage->getChatRoom()->isReadOnly();
|
||||||
mIsRetracted = chatmessage->isRetracted();
|
mIsRetracted = chatmessage->isRetracted();
|
||||||
|
mIsEditable =
|
||||||
|
chatmessage->isOutgoing() && chatmessage->isEditable() && !chatmessage->getChatRoom()->isReadOnly();
|
||||||
|
mIsEdited = chatmessage->isEdited();
|
||||||
mIsRemoteMessage = !chatmessage->isOutgoing();
|
mIsRemoteMessage = !chatmessage->isOutgoing();
|
||||||
mPeerAddress = Utils::coreStringToAppString(chatmessage->getPeerAddress()->asStringUriOnly());
|
mPeerAddress = Utils::coreStringToAppString(chatmessage->getPeerAddress()->asStringUriOnly());
|
||||||
mPeerName = ToolModel::getDisplayName(chatmessage->getPeerAddress());
|
mPeerName = ToolModel::getDisplayName(chatmessage->getPeerAddress());
|
||||||
|
|
@ -364,6 +368,13 @@ void ChatMessageCore::setSelf(QSharedPointer<ChatMessageCore> me) {
|
||||||
setRetracted();
|
setRetracted();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
mChatMessageModelConnection->makeConnectToModel(&ChatMessageModel::contentEdited,
|
||||||
|
[this](const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||||
|
mChatMessageModelConnection->invokeToCore([this] {
|
||||||
|
mIsEdited = true;
|
||||||
|
emit edited();
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<ImdnStatus> ChatMessageCore::computeDeliveryStatus(const std::shared_ptr<linphone::ChatMessage> &message) {
|
QList<ImdnStatus> ChatMessageCore::computeDeliveryStatus(const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||||
|
|
@ -498,6 +509,10 @@ bool ChatMessageCore::isRetracted() const {
|
||||||
return mIsRetracted;
|
return mIsRetracted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ChatMessageCore::isEdited() const {
|
||||||
|
return mIsEdited;
|
||||||
|
}
|
||||||
|
|
||||||
QString ChatMessageCore::getOwnReaction() const {
|
QString ChatMessageCore::getOwnReaction() const {
|
||||||
return mOwnReaction;
|
return mOwnReaction;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,6 +114,8 @@ class ChatMessageCore : public QObject, public AbstractObject {
|
||||||
Q_PROPERTY(bool isOutgoing MEMBER mIsOutgoing CONSTANT)
|
Q_PROPERTY(bool isOutgoing MEMBER mIsOutgoing CONSTANT)
|
||||||
Q_PROPERTY(bool isRetractable MEMBER mIsRetractable CONSTANT)
|
Q_PROPERTY(bool isRetractable MEMBER mIsRetractable CONSTANT)
|
||||||
Q_PROPERTY(bool isRetracted READ isRetracted NOTIFY isRetractedChanged)
|
Q_PROPERTY(bool isRetracted READ isRetracted NOTIFY isRetractedChanged)
|
||||||
|
Q_PROPERTY(bool isEditable MEMBER mIsEditable CONSTANT)
|
||||||
|
Q_PROPERTY(bool isEdited READ isEdited NOTIFY edited)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static QSharedPointer<ChatMessageCore> create(const std::shared_ptr<linphone::ChatMessage> &chatmessage);
|
static QSharedPointer<ChatMessageCore> create(const std::shared_ptr<linphone::ChatMessage> &chatmessage);
|
||||||
|
|
@ -148,6 +150,7 @@ public:
|
||||||
|
|
||||||
bool isRetracted() const;
|
bool isRetracted() const;
|
||||||
void setRetracted();
|
void setRetracted();
|
||||||
|
bool isEdited() const;
|
||||||
|
|
||||||
QString getOwnReaction() const;
|
QString getOwnReaction() const;
|
||||||
void setOwnReaction(const QString &reaction);
|
void setOwnReaction(const QString &reaction);
|
||||||
|
|
@ -183,6 +186,7 @@ signals:
|
||||||
void singletonReactionMapChanged();
|
void singletonReactionMapChanged();
|
||||||
void ephemeralDurationChanged(int duration);
|
void ephemeralDurationChanged(int duration);
|
||||||
void isRetractedChanged();
|
void isRetractedChanged();
|
||||||
|
void edited();
|
||||||
|
|
||||||
void lDelete();
|
void lDelete();
|
||||||
void deleted();
|
void deleted();
|
||||||
|
|
@ -224,6 +228,8 @@ private:
|
||||||
int mEphemeralDuration = 0;
|
int mEphemeralDuration = 0;
|
||||||
bool mIsRetractable = false;
|
bool mIsRetractable = false;
|
||||||
bool mIsRetracted = false;
|
bool mIsRetracted = false;
|
||||||
|
bool mIsEditable = false;
|
||||||
|
bool mIsEdited = false;
|
||||||
|
|
||||||
bool mIsOutgoing = false;
|
bool mIsOutgoing = false;
|
||||||
QString mTotalReactionsLabel;
|
QString mTotalReactionsLabel;
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ void EventLogList::disconnectItem(const QSharedPointer<EventLogCore> &item) {
|
||||||
if (message) {
|
if (message) {
|
||||||
disconnect(message.get(), &ChatMessageCore::isReadChanged, this, nullptr);
|
disconnect(message.get(), &ChatMessageCore::isReadChanged, this, nullptr);
|
||||||
disconnect(message.get(), &ChatMessageCore::deleted, this, nullptr);
|
disconnect(message.get(), &ChatMessageCore::deleted, this, nullptr);
|
||||||
|
disconnect(message.get(), &ChatMessageCore::edited, this, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,6 +78,20 @@ void EventLogList::connectItem(const QSharedPointer<EventLogCore> &item) {
|
||||||
if (mChatCore) emit mChatCore->lUpdateLastMessage();
|
if (mChatCore) emit mChatCore->lUpdateLastMessage();
|
||||||
remove(item);
|
remove(item);
|
||||||
});
|
});
|
||||||
|
connect(message.get(), &ChatMessageCore::edited, this, [this, item] {
|
||||||
|
auto eventLogModel = item->getModel();
|
||||||
|
mCoreModelConnection->invokeToModel([this, eventLogModel, item]() {
|
||||||
|
auto chatRoom = mChatCore->getModel()->getMonitor();
|
||||||
|
auto newEventLog = EventLogCore::create(eventLogModel->getEventLog(), chatRoom);
|
||||||
|
bool wasLastMessage =
|
||||||
|
mChatCore->getModel()->getLastChatMessage() == eventLogModel->getEventLog()->getChatMessage();
|
||||||
|
mCoreModelConnection->invokeToCore([this, newEventLog, wasLastMessage, item] {
|
||||||
|
connectItem(newEventLog);
|
||||||
|
replace(item, newEventLog);
|
||||||
|
if (wasLastMessage) mChatCore->setLastMessage(newEventLog->getChatMessageCore());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -205,4 +205,4 @@ void EventLogProxy::findIndexCorrespondingToFilter(int startIndex, bool forward,
|
||||||
auto listIndex = mapToSource(index(startIndex, 0)).row();
|
auto listIndex = mapToSource(index(startIndex, 0)).row();
|
||||||
eventLogList->findChatMessageWithFilter(filter, listIndex, forward, isFirstResearch);
|
eventLogList->findChatMessageWithFilter(filter, listIndex, forward, isFirstResearch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2225,6 +2225,12 @@
|
||||||
<extracomment>"Reception info"</extracomment>
|
<extracomment>"Reception info"</extracomment>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessage.qml" line="407"/>
|
||||||
|
<source>menu_edit_chat_message</source>
|
||||||
|
<extracomment>"Edit"</extracomment>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../view/Control/Display/Chat/ChatMessage.qml" line="419"/>
|
<location filename="../../view/Control/Display/Chat/ChatMessage.qml" line="419"/>
|
||||||
<source>chat_message_reply</source>
|
<source>chat_message_reply</source>
|
||||||
|
|
|
||||||
|
|
@ -2218,6 +2218,12 @@
|
||||||
<extracomment>"Reception info"</extracomment>
|
<extracomment>"Reception info"</extracomment>
|
||||||
<translation>Reception info</translation>
|
<translation>Reception info</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessage.qml" line="407"/>
|
||||||
|
<source>menu_edit_chat_message</source>
|
||||||
|
<extracomment>"Edit"</extracomment>
|
||||||
|
<translation>Edit</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../view/Control/Display/Chat/ChatMessage.qml" line="419"/>
|
<location filename="../../view/Control/Display/Chat/ChatMessage.qml" line="419"/>
|
||||||
<source>chat_message_reply</source>
|
<source>chat_message_reply</source>
|
||||||
|
|
@ -2236,6 +2242,12 @@
|
||||||
<extracomment>"Delete"</extracomment>
|
<extracomment>"Delete"</extracomment>
|
||||||
<translation>Delete</translation>
|
<translation>Delete</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessage.qml" line="469"/>
|
||||||
|
<source>conversation_message_edited_label</source>
|
||||||
|
<extracomment>"Edited"</extracomment>
|
||||||
|
<translation>Edited</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatMessageContentCore</name>
|
<name>ChatMessageContentCore</name>
|
||||||
|
|
@ -5795,6 +5807,12 @@ To enable them in a commercial project, please contact us.</translation>
|
||||||
<extracomment>Reply to %1</extracomment>
|
<extracomment>Reply to %1</extracomment>
|
||||||
<translation>Reply to %1</translation>
|
<translation>Reply to %1</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Page/Form/Chat/SelectedChatView.qml" line="417"/>
|
||||||
|
<source>conversation_editing_message_title</source>
|
||||||
|
<extracomment>Message beeing edited</extracomment>
|
||||||
|
<translation>Message beeing edited</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../view/Page/Form/Chat/SelectedChatView.qml" line="617"/>
|
<location filename="../../view/Page/Form/Chat/SelectedChatView.qml" line="617"/>
|
||||||
<source>shared_medias_title</source>
|
<source>shared_medias_title</source>
|
||||||
|
|
@ -6038,18 +6056,36 @@ To enable them in a commercial project, please contact us.</translation>
|
||||||
<extracomment>Cannot reply to invalid message</extracomment>
|
<extracomment>Cannot reply to invalid message</extracomment>
|
||||||
<translation>Cannot reply to invalid message</translation>
|
<translation>Cannot reply to invalid message</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../tool/Utils.cpp" line="2123"/>
|
||||||
|
<source>chat_message_edit_error</source>
|
||||||
|
<extracomment>Cannot modify invalid message</extracomment>
|
||||||
|
<translation>Cannot modify invalid message</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../tool/Utils.cpp" line="2129"/>
|
<location filename="../../tool/Utils.cpp" line="2129"/>
|
||||||
<source>info_popup_reply_message_error</source>
|
<source>info_popup_reply_message_error</source>
|
||||||
<extracomment>Could not send reply message : %1</extracomment>
|
<extracomment>Could not send reply message : %1</extracomment>
|
||||||
<translation>Could not send reply message : %1</translation>
|
<translation>Could not send reply message : %1</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../tool/Utils.cpp" line="2129"/>
|
||||||
|
<source>info_popup_edited_message_error</source>
|
||||||
|
<extracomment>Could not send edited message : %1</extracomment>
|
||||||
|
<translation>Could not send edited message : %1</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../tool/Utils.cpp" line="2156"/>
|
<location filename="../../tool/Utils.cpp" line="2156"/>
|
||||||
<source>info_popup_send_reply_message_error_message</source>
|
<source>info_popup_send_reply_message_error_message</source>
|
||||||
<extracomment>Failed to create reply message</extracomment>
|
<extracomment>Failed to create reply message</extracomment>
|
||||||
<translation>Failed to create reply message</translation>
|
<translation>Failed to create reply message</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../tool/Utils.cpp" line="2156"/>
|
||||||
|
<source>info_popup_send_edited_message_error_message</source>
|
||||||
|
<extracomment>Failed to create edited message</extracomment>
|
||||||
|
<translation>Failed to create edited message</translation>
|
||||||
|
</message>
|
||||||
<message numerus="yes">
|
<message numerus="yes">
|
||||||
<location filename="../../tool/Utils.cpp" line="2278"/>
|
<location filename="../../tool/Utils.cpp" line="2278"/>
|
||||||
<source>nHour</source>
|
<source>nHour</source>
|
||||||
|
|
|
||||||
|
|
@ -2218,6 +2218,12 @@
|
||||||
<extracomment>"Reception info"</extracomment>
|
<extracomment>"Reception info"</extracomment>
|
||||||
<translation>Info de réception</translation>
|
<translation>Info de réception</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessage.qml" line="407"/>
|
||||||
|
<source>menu_edit_chat_message</source>
|
||||||
|
<extracomment>"Edit"</extracomment>
|
||||||
|
<translation>Modifier</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../view/Control/Display/Chat/ChatMessage.qml" line="419"/>
|
<location filename="../../view/Control/Display/Chat/ChatMessage.qml" line="419"/>
|
||||||
<source>chat_message_reply</source>
|
<source>chat_message_reply</source>
|
||||||
|
|
@ -2236,6 +2242,12 @@
|
||||||
<extracomment>"Delete"</extracomment>
|
<extracomment>"Delete"</extracomment>
|
||||||
<translation>Supprimer</translation>
|
<translation>Supprimer</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Control/Display/Chat/ChatMessage.qml" line="469"/>
|
||||||
|
<source>conversation_message_edited_label</source>
|
||||||
|
<extracomment>"Edited"</extracomment>
|
||||||
|
<translation>Modifié</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatMessageContentCore</name>
|
<name>ChatMessageContentCore</name>
|
||||||
|
|
@ -5795,6 +5807,12 @@ Pour les activer dans un projet commercial, merci de nous contacter.</translatio
|
||||||
<extracomment>Reply to %1</extracomment>
|
<extracomment>Reply to %1</extracomment>
|
||||||
<translation>Réponse à %1</translation>
|
<translation>Réponse à %1</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../view/Page/Form/Chat/SelectedChatView.qml" line="417"/>
|
||||||
|
<source>conversation_editing_message_title</source>
|
||||||
|
<extracomment>Message beeing edited</extracomment>
|
||||||
|
<translation>Modification du message</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../view/Page/Form/Chat/SelectedChatView.qml" line="617"/>
|
<location filename="../../view/Page/Form/Chat/SelectedChatView.qml" line="617"/>
|
||||||
<source>shared_medias_title</source>
|
<source>shared_medias_title</source>
|
||||||
|
|
@ -6210,18 +6228,36 @@ Failed to create 1-1 conversation with %1 !</extracomment>
|
||||||
<extracomment>Cannot reply to invalid message</extracomment>
|
<extracomment>Cannot reply to invalid message</extracomment>
|
||||||
<translation>Impossible de répondre : message invalide</translation>
|
<translation>Impossible de répondre : message invalide</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../tool/Utils.cpp" line="2123"/>
|
||||||
|
<source>chat_message_edit_error</source>
|
||||||
|
<extracomment>Cannot modify invalid message</extracomment>
|
||||||
|
<translation>Impossible de modifier le message : message invalide</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../tool/Utils.cpp" line="2129"/>
|
<location filename="../../tool/Utils.cpp" line="2129"/>
|
||||||
<source>info_popup_reply_message_error</source>
|
<source>info_popup_reply_message_error</source>
|
||||||
<extracomment>Could not send reply message : %1</extracomment>
|
<extracomment>Could not send reply message : %1</extracomment>
|
||||||
<translation>Impossible d'envoyer la réponse : %1</translation>
|
<translation>Impossible d'envoyer la réponse : %1</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../tool/Utils.cpp" line="2129"/>
|
||||||
|
<source>info_popup_edited_message_error</source>
|
||||||
|
<extracomment>Could not send edited message : %1</extracomment>
|
||||||
|
<translation>Impossible d'envoyer le message modifié : %1</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../tool/Utils.cpp" line="2156"/>
|
<location filename="../../tool/Utils.cpp" line="2156"/>
|
||||||
<source>info_popup_send_reply_message_error_message</source>
|
<source>info_popup_send_reply_message_error_message</source>
|
||||||
<extracomment>Failed to create reply message</extracomment>
|
<extracomment>Failed to create reply message</extracomment>
|
||||||
<translation>Impossible de créer le message</translation>
|
<translation>Impossible de créer le message</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../../tool/Utils.cpp" line="2156"/>
|
||||||
|
<source>info_popup_send_edited_message_error_message</source>
|
||||||
|
<extracomment>Failed to create edited message</extracomment>
|
||||||
|
<translation>Impossible de créer le message modifié</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../../tool/Utils.cpp" line="2194"/>
|
<location filename="../../tool/Utils.cpp" line="2194"/>
|
||||||
<source>info_popup_send_voice_message_error_message</source>
|
<source>info_popup_send_voice_message_error_message</source>
|
||||||
|
|
|
||||||
|
|
@ -185,6 +185,11 @@ ChatModel::createReplyMessage(const std::shared_ptr<linphone::ChatMessage> &mess
|
||||||
return mMonitor->createReplyMessage(message);
|
return mMonitor->createReplyMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<linphone::ChatMessage>
|
||||||
|
ChatModel::createReplacesMessage(const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||||
|
return mMonitor->createReplacesMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<linphone::ChatMessage>
|
std::shared_ptr<linphone::ChatMessage>
|
||||||
ChatModel::createForwardMessage(const std::shared_ptr<linphone::ChatMessage> &message) {
|
ChatModel::createForwardMessage(const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||||
return mMonitor->createForwardMessage(message);
|
return mMonitor->createForwardMessage(message);
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ public:
|
||||||
|
|
||||||
std::shared_ptr<linphone::ChatMessage> createReplyMessage(const std::shared_ptr<linphone::ChatMessage> &message);
|
std::shared_ptr<linphone::ChatMessage> createReplyMessage(const std::shared_ptr<linphone::ChatMessage> &message);
|
||||||
std::shared_ptr<linphone::ChatMessage> createForwardMessage(const std::shared_ptr<linphone::ChatMessage> &message);
|
std::shared_ptr<linphone::ChatMessage> createForwardMessage(const std::shared_ptr<linphone::ChatMessage> &message);
|
||||||
|
std::shared_ptr<linphone::ChatMessage> createReplacesMessage(const std::shared_ptr<linphone::ChatMessage> &message);
|
||||||
|
|
||||||
std::shared_ptr<linphone::ChatMessage> createTextMessageFromText(QString text);
|
std::shared_ptr<linphone::ChatMessage> createTextMessageFromText(QString text);
|
||||||
std::shared_ptr<linphone::ChatMessage> createMessage(QString text,
|
std::shared_ptr<linphone::ChatMessage> createMessage(QString text,
|
||||||
|
|
|
||||||
|
|
@ -199,3 +199,7 @@ void ChatMessageModel::onEphemeralMessageDeleted(const std::shared_ptr<linphone:
|
||||||
void ChatMessageModel::onRetracted(const std::shared_ptr<linphone::ChatMessage> &message) {
|
void ChatMessageModel::onRetracted(const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||||
emit retracted(message);
|
emit retracted(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatMessageModel::onContentEdited(const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||||
|
emit contentEdited(message);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ signals:
|
||||||
void ephemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> &message);
|
void ephemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> &message);
|
||||||
void ephemeralMessageTimeUpdated(const std::shared_ptr<linphone::ChatMessage> &message, int expireTime);
|
void ephemeralMessageTimeUpdated(const std::shared_ptr<linphone::ChatMessage> &message, int expireTime);
|
||||||
void retracted(const std::shared_ptr<linphone::ChatMessage> &message);
|
void retracted(const std::shared_ptr<linphone::ChatMessage> &message);
|
||||||
|
void contentEdited(const std::shared_ptr<linphone::ChatMessage> &message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
linphone::ChatMessage::State mMessageState;
|
linphone::ChatMessage::State mMessageState;
|
||||||
|
|
@ -133,6 +134,7 @@ private:
|
||||||
void onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> &message) override;
|
void onEphemeralMessageTimerStarted(const std::shared_ptr<linphone::ChatMessage> &message) override;
|
||||||
void onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> &message) override;
|
void onEphemeralMessageDeleted(const std::shared_ptr<linphone::ChatMessage> &message) override;
|
||||||
void onRetracted(const std::shared_ptr<linphone::ChatMessage> &message) override;
|
void onRetracted(const std::shared_ptr<linphone::ChatMessage> &message) override;
|
||||||
|
void onContentEdited(const std::shared_ptr<linphone::ChatMessage> &message) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -2159,6 +2159,50 @@ void Utils::sendReplyMessage(ChatMessageGui *message, ChatGui *chatGui, QString
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Utils::sendReplaceMessage(ChatMessageGui *message, ChatGui *chatGui, QString text, QVariantList files) {
|
||||||
|
auto chatModel = chatGui && chatGui->mCore ? chatGui->mCore->getModel() : nullptr;
|
||||||
|
auto chatMessageModel = message && message->mCore ? message->mCore->getModel() : nullptr;
|
||||||
|
if (!chatModel || !chatMessageModel) {
|
||||||
|
//: Cannot edit to invalid message
|
||||||
|
QString error = !chatMessageModel ? tr("chat_message_edit_error")
|
||||||
|
//: Error in the chat
|
||||||
|
: tr("chat_error");
|
||||||
|
//: Error
|
||||||
|
showInformationPopup(tr("info_popup_error_title"),
|
||||||
|
//: Could not send edited message : %1
|
||||||
|
tr("info_popup_edited_message_error").arg(error));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QList<std::shared_ptr<ChatMessageContentModel>> filesContent;
|
||||||
|
for (auto &file : files) {
|
||||||
|
auto contentGui = qvariant_cast<ChatMessageContentGui *>(file);
|
||||||
|
if (contentGui) {
|
||||||
|
auto contentCore = contentGui->mCore;
|
||||||
|
filesContent.append(contentCore->getContentModel());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
App::postModelAsync([chatModel, chatMessageModel, text, filesContent] {
|
||||||
|
mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO));
|
||||||
|
auto chat = chatModel->getMonitor();
|
||||||
|
auto messageToEdit = chatMessageModel->getMonitor();
|
||||||
|
auto linMessage = chatModel->createReplacesMessage(messageToEdit);
|
||||||
|
if (linMessage) {
|
||||||
|
linMessage->addUtf8TextContent(Utils::appStringToCoreString(text));
|
||||||
|
for (auto &content : filesContent) {
|
||||||
|
linMessage->addFileContent(content->getContent());
|
||||||
|
}
|
||||||
|
linMessage->send();
|
||||||
|
} else {
|
||||||
|
App::postCoreAsync([] {
|
||||||
|
//: Error
|
||||||
|
showInformationPopup(tr("info_popup_error_title"),
|
||||||
|
//: Failed to create edited message
|
||||||
|
tr("info_popup_send_edited_message_error_message"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
VariantObject *Utils::createVoiceRecordingMessage(RecorderGui *recorderGui, ChatGui *chatGui) {
|
VariantObject *Utils::createVoiceRecordingMessage(RecorderGui *recorderGui, ChatGui *chatGui) {
|
||||||
VariantObject *data = new VariantObject("createVoiceRecordingMessage");
|
VariantObject *data = new VariantObject("createVoiceRecordingMessage");
|
||||||
if (!data) return nullptr;
|
if (!data) return nullptr;
|
||||||
|
|
|
||||||
|
|
@ -183,6 +183,8 @@ public:
|
||||||
Q_INVOKABLE static void
|
Q_INVOKABLE static void
|
||||||
sendReplyMessage(ChatMessageGui *message, ChatGui *chatGui, QString text, QVariantList files);
|
sendReplyMessage(ChatMessageGui *message, ChatGui *chatGui, QString text, QVariantList files);
|
||||||
Q_INVOKABLE static void forwardMessageTo(ChatMessageGui *message, ChatGui *chatGui);
|
Q_INVOKABLE static void forwardMessageTo(ChatMessageGui *message, ChatGui *chatGui);
|
||||||
|
Q_INVOKABLE static void
|
||||||
|
sendReplaceMessage(ChatMessageGui *message, ChatGui *chatGui, QString text, QVariantList files);
|
||||||
|
|
||||||
Q_INVOKABLE static void sendVoiceRecordingMessage(RecorderGui *recorderGui, ChatGui *chatGui);
|
Q_INVOKABLE static void sendVoiceRecordingMessage(RecorderGui *recorderGui, ChatGui *chatGui);
|
||||||
Q_INVOKABLE static QString getEphemeralFormatedTime(int selectedTime);
|
Q_INVOKABLE static QString getEphemeralFormatedTime(int selectedTime);
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@ Control.Control {
|
||||||
leftPadding: isRemoteMessage ? Utils.getSizeWithScreenRatio(5) : 0
|
leftPadding: isRemoteMessage ? Utils.getSizeWithScreenRatio(5) : 0
|
||||||
|
|
||||||
signal messageDeletionRequested()
|
signal messageDeletionRequested()
|
||||||
|
signal messageEditionRequested()
|
||||||
signal isFileHoveringChanged(bool isFileHovering)
|
signal isFileHoveringChanged(bool isFileHovering)
|
||||||
signal showReactionsForMessageRequested()
|
signal showReactionsForMessageRequested()
|
||||||
signal showImdnStatusForMessageRequested()
|
signal showImdnStatusForMessageRequested()
|
||||||
|
|
@ -297,16 +298,26 @@ Control.Control {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RowLayout {
|
RowLayout {
|
||||||
spacing: mainItem.isRemoteMessage ? 0 : Utils.getSizeWithScreenRatio(5)
|
spacing: mainItem.isRemoteMessage && !mainItem.chatMessage.core.isEdited ? 0 : Utils.getSizeWithScreenRatio(5)
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
Layout.preferredHeight: childrenRect.height
|
Layout.preferredHeight: childrenRect.height
|
||||||
|
Text {
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
text: qsTr("conversation_message_edited_label")
|
||||||
|
visible: mainItem.chatMessage.core.isEdited
|
||||||
|
color: DefaultStyle.main2_500_main
|
||||||
|
font {
|
||||||
|
pixelSize: Typography.p3.pixelSize
|
||||||
|
weight: Typography.p3.weight
|
||||||
|
}
|
||||||
|
}
|
||||||
Text {
|
Text {
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
text: UtilsCpp.formatDate(mainItem.chatMessage.core.timestamp, true, false, "dd/MM")
|
text: UtilsCpp.formatDate(mainItem.chatMessage.core.timestamp, true, false, "dd/MM")
|
||||||
color: DefaultStyle.main2_500_main
|
color: DefaultStyle.main2_500_main
|
||||||
font {
|
font {
|
||||||
pixelSize: Typography.p3.pixelSize
|
pixelSize: Typography.p3.pixelSize
|
||||||
weight: Typography.p3.weight
|
weight: Typography.p3.weight
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EffectImage {
|
EffectImage {
|
||||||
|
|
@ -423,6 +434,19 @@ Control.Control {
|
||||||
optionsMenu.close()
|
optionsMenu.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
IconLabelButton {
|
||||||
|
inverseLayout: true
|
||||||
|
//: "Edit"
|
||||||
|
text: qsTr("menu_edit_chat_message")
|
||||||
|
visible: mainItem.chatMessage.core.isEditable
|
||||||
|
icon.source: AppIcons.pencil
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: Utils.getSizeWithScreenRatio(45)
|
||||||
|
onClicked: {
|
||||||
|
mainItem.messageEditionRequested()
|
||||||
|
optionsMenu.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
IconLabelButton {
|
IconLabelButton {
|
||||||
inverseLayout: true
|
inverseLayout: true
|
||||||
visible: !mainItem.chatMessage.core.isRetracted
|
visible: !mainItem.chatMessage.core.isRetracted
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@ ListView {
|
||||||
signal showImdnStatusForMessageRequested(ChatMessageGui chatMessage)
|
signal showImdnStatusForMessageRequested(ChatMessageGui chatMessage)
|
||||||
signal replyToMessageRequested(ChatMessageGui chatMessage)
|
signal replyToMessageRequested(ChatMessageGui chatMessage)
|
||||||
signal forwardMessageRequested(ChatMessageGui chatMessage)
|
signal forwardMessageRequested(ChatMessageGui chatMessage)
|
||||||
|
signal editMessageRequested(ChatMessageGui chatMessage)
|
||||||
signal requestHighlight(int indexToHighlight)
|
signal requestHighlight(int indexToHighlight)
|
||||||
signal requestAutoPlayVoiceRecording(int indexToPlay)
|
signal requestAutoPlayVoiceRecording(int indexToPlay)
|
||||||
currentIndex: -1
|
currentIndex: -1
|
||||||
|
|
@ -315,6 +316,7 @@ ListView {
|
||||||
chatMessage.core.lDelete()
|
chatMessage.core.lDelete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
onMessageEditionRequested: mainItem.editMessageRequested(chatMessage)
|
||||||
onShowReactionsForMessageRequested: mainItem.showReactionsForMessageRequested(chatMessage)
|
onShowReactionsForMessageRequested: mainItem.showReactionsForMessageRequested(chatMessage)
|
||||||
onShowImdnStatusForMessageRequested: mainItem.showImdnStatusForMessageRequested(chatMessage)
|
onShowImdnStatusForMessageRequested: mainItem.showImdnStatusForMessageRequested(chatMessage)
|
||||||
onReplyToMessageRequested: mainItem.replyToMessageRequested(chatMessage)
|
onReplyToMessageRequested: mainItem.replyToMessageRequested(chatMessage)
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ Control.Control {
|
||||||
|
|
||||||
// disable record button if call ongoing
|
// disable record button if call ongoing
|
||||||
property bool callOngoing: false
|
property bool callOngoing: false
|
||||||
|
property bool isEditing: false
|
||||||
|
|
||||||
property ChatGui chat
|
property ChatGui chat
|
||||||
|
|
||||||
|
|
@ -78,6 +79,7 @@ Control.Control {
|
||||||
spacing: Utils.getSizeWithScreenRatio(16)
|
spacing: Utils.getSizeWithScreenRatio(16)
|
||||||
PopupButton {
|
PopupButton {
|
||||||
id: emojiPickerButton
|
id: emojiPickerButton
|
||||||
|
visible: !mainItem.isEditing
|
||||||
style: ButtonStyle.noBackground
|
style: ButtonStyle.noBackground
|
||||||
icon.source: checked ? AppIcons.closeX : AppIcons.smiley
|
icon.source: checked ? AppIcons.closeX : AppIcons.smiley
|
||||||
popup.width: Utils.getSizeWithScreenRatio(393)
|
popup.width: Utils.getSizeWithScreenRatio(393)
|
||||||
|
|
@ -189,7 +191,7 @@ Control.Control {
|
||||||
//: Cannot record a message while a call is ongoing
|
//: Cannot record a message while a call is ongoing
|
||||||
ToolTip.text: qsTr("cannot_record_while_in_call_tooltip")
|
ToolTip.text: qsTr("cannot_record_while_in_call_tooltip")
|
||||||
enabled: !mainItem.callOngoing
|
enabled: !mainItem.callOngoing
|
||||||
visible: !mainItem.callOngoing && sendingTextArea.text.length === 0 && mainItem.selectedFilesCount === 0
|
visible: !mainItem.callOngoing && sendingTextArea.text.length === 0 && mainItem.selectedFilesCount === 0 && !mainItem.isEditing
|
||||||
style: ButtonStyle.noBackground
|
style: ButtonStyle.noBackground
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
icon.source: AppIcons.microphone
|
icon.source: AppIcons.microphone
|
||||||
|
|
@ -202,7 +204,7 @@ Control.Control {
|
||||||
Layout.preferredHeight: height
|
Layout.preferredHeight: height
|
||||||
visible: sendingTextArea.text.length !== 0 || mainItem.selectedFilesCount > 0
|
visible: sendingTextArea.text.length !== 0 || mainItem.selectedFilesCount > 0
|
||||||
style: ButtonStyle.noBackgroundOrange
|
style: ButtonStyle.noBackgroundOrange
|
||||||
icon.source: AppIcons.paperPlaneRight
|
icon.source: mainItem.isEditing ? AppIcons.pencil : AppIcons.paperPlaneRight
|
||||||
onClicked: {
|
onClicked: {
|
||||||
mainItem.sendMessage()
|
mainItem.sendMessage()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ FocusScope {
|
||||||
property CallGui call
|
property CallGui call
|
||||||
property alias callHeaderContent: splitPanel.header.contentItem
|
property alias callHeaderContent: splitPanel.header.contentItem
|
||||||
property bool replyingToMessage: false
|
property bool replyingToMessage: false
|
||||||
|
property bool editingMessage: false
|
||||||
enum PanelType { MessageReactions, SharedFiles, Medias, ImdnStatus, ForwardToList, ManageParticipants, EphemeralSettings, None}
|
enum PanelType { MessageReactions, SharedFiles, Medias, ImdnStatus, ForwardToList, ManageParticipants, EphemeralSettings, None}
|
||||||
|
|
||||||
signal oneOneCall(bool video)
|
signal oneOneCall(bool video)
|
||||||
|
|
@ -299,11 +300,19 @@ FocusScope {
|
||||||
onReplyToMessageRequested: (chatMessage) => {
|
onReplyToMessageRequested: (chatMessage) => {
|
||||||
mainItem.chatMessage = chatMessage
|
mainItem.chatMessage = chatMessage
|
||||||
mainItem.replyingToMessage = true
|
mainItem.replyingToMessage = true
|
||||||
|
if (mainItem.editingMessage) mainItem.editingMessage = false
|
||||||
}
|
}
|
||||||
onForwardMessageRequested: (chatMessage) => {
|
onForwardMessageRequested: (chatMessage) => {
|
||||||
mainItem.chatMessage = chatMessage
|
mainItem.chatMessage = chatMessage
|
||||||
contentLoader.panelType = SelectedChatView.PanelType.ForwardToList
|
contentLoader.panelType = SelectedChatView.PanelType.ForwardToList
|
||||||
detailsPanel.visible = true
|
detailsPanel.visible = true
|
||||||
|
if (mainItem.editingMessage) mainItem.editingMessage = false
|
||||||
|
}
|
||||||
|
onEditMessageRequested: (chatMessage) => {
|
||||||
|
mainItem.chatMessage = chatMessage
|
||||||
|
mainItem.editingMessage = true
|
||||||
|
if (mainItem.replyingToMessage) mainItem.replyingToMessage = false
|
||||||
|
messageSender.text = chatMessage.core.text
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ScrollBar {
|
ScrollBar {
|
||||||
|
|
@ -367,7 +376,7 @@ FocusScope {
|
||||||
}
|
}
|
||||||
Control.Control {
|
Control.Control {
|
||||||
id: selectedFilesArea
|
id: selectedFilesArea
|
||||||
visible: selectedFiles.count > 0 || mainItem.replyingToMessage
|
visible: selectedFiles.count > 0 || mainItem.replyingToMessage || mainItem.editingMessage
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: implicitHeight
|
Layout.preferredHeight: implicitHeight
|
||||||
topPadding: Utils.getSizeWithScreenRatio(12)
|
topPadding: Utils.getSizeWithScreenRatio(12)
|
||||||
|
|
@ -384,7 +393,12 @@ FocusScope {
|
||||||
style: ButtonStyle.noBackground
|
style: ButtonStyle.noBackground
|
||||||
onClicked: {
|
onClicked: {
|
||||||
contents.clear()
|
contents.clear()
|
||||||
mainItem.replyingToMessage = false
|
if (mainItem.replyingToMessage)
|
||||||
|
mainItem.replyingToMessage = false
|
||||||
|
else if (mainItem.editingMessage) {
|
||||||
|
mainItem.editingMessage = false
|
||||||
|
messageSender.text = ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
background: Item{
|
background: Item{
|
||||||
|
|
@ -410,11 +424,13 @@ FocusScope {
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: replyLayout
|
id: replyLayout
|
||||||
spacing: 0
|
spacing: 0
|
||||||
visible: mainItem.chatMessage && mainItem.replyingToMessage
|
visible: mainItem.chatMessage && (mainItem.replyingToMessage || mainItem.editingMessage)
|
||||||
Text {
|
Text {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
//: Reply to %1
|
//: Reply to %1
|
||||||
text: mainItem.chatMessage ? qsTr("reply_to_label").arg(UtilsCpp.boldTextPart(mainItem.chatMessage.core.fromName, mainItem.chatMessage.core.fromName)) : ""
|
text: mainItem.replyingToMessage ?
|
||||||
|
(mainItem.chatMessage ? qsTr("reply_to_label").arg(UtilsCpp.boldTextPart(mainItem.chatMessage.core.fromName, mainItem.chatMessage.core.fromName)) : "")
|
||||||
|
: qsTr("conversation_editing_message_title")
|
||||||
color: DefaultStyle.main2_500_main
|
color: DefaultStyle.main2_500_main
|
||||||
font {
|
font {
|
||||||
pixelSize: Typography.p3.pixelSize
|
pixelSize: Typography.p3.pixelSize
|
||||||
|
|
@ -489,6 +505,7 @@ FocusScope {
|
||||||
chat: mainItem.chat
|
chat: mainItem.chat
|
||||||
selectedFilesCount: contents.count
|
selectedFilesCount: contents.count
|
||||||
callOngoing: mainItem.call != null
|
callOngoing: mainItem.call != null
|
||||||
|
isEditing: mainItem.editingMessage
|
||||||
onChatChanged: {
|
onChatChanged: {
|
||||||
if (chat) messageSender.text = mainItem.chat.core.sendingText
|
if (chat) messageSender.text = mainItem.chat.core.sendingText
|
||||||
}
|
}
|
||||||
|
|
@ -507,6 +524,10 @@ FocusScope {
|
||||||
mainItem.replyingToMessage = false
|
mainItem.replyingToMessage = false
|
||||||
UtilsCpp.sendReplyMessage(mainItem.chatMessage, mainItem.chat, text, filesContents)
|
UtilsCpp.sendReplyMessage(mainItem.chatMessage, mainItem.chat, text, filesContents)
|
||||||
}
|
}
|
||||||
|
else if (mainItem.editingMessage) {
|
||||||
|
UtilsCpp.sendReplaceMessage(mainItem.chatMessage, mainItem.chat, text, filesContents)
|
||||||
|
mainItem.editingMessage = false
|
||||||
|
}
|
||||||
else if (filesContents.length === 0)
|
else if (filesContents.length === 0)
|
||||||
mainItem.chat.core.lSendTextMessage(text)
|
mainItem.chat.core.lSendTextMessage(text)
|
||||||
else mainItem.chat.core.lSendMessage(text, filesContents)
|
else mainItem.chat.core.lSendMessage(text, filesContents)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue