mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-02-01 10:49:26 +00:00
Restore the ability for a user to define if a ChatMessage is to be stored or not.
This commit is contained in:
parent
b39e220d5a
commit
7c4533b8fc
10 changed files with 136 additions and 86 deletions
|
|
@ -167,6 +167,21 @@ LINPHONE_PUBLIC const char * linphone_chat_message_get_file_transfer_filepath(Li
|
|||
|
||||
// =============================================================================
|
||||
|
||||
/**
|
||||
* Get if a chat message is to be stored.
|
||||
* @param[in] message LinphoneChatMessage object
|
||||
* @return Whether or not the message is to be stored
|
||||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_chat_message_get_to_be_stored(const LinphoneChatMessage *message);
|
||||
|
||||
/**
|
||||
* Set if a chat message is to be stored.
|
||||
* This content type must match a content that is text representable, such as text/plain, text/html or image/svg+xml.
|
||||
* @param[in] message LinphoneChatMessage object
|
||||
* @param[in] to_be_stored Whether or not the chat message is to be stored
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_message_set_to_be_stored(LinphoneChatMessage *message, bool_t to_be_stored);
|
||||
|
||||
LINPHONE_PUBLIC unsigned int linphone_chat_message_store(LinphoneChatMessage *msg);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -177,6 +177,14 @@ const LinphoneErrorInfo *linphone_chat_message_get_error_info(const LinphoneChat
|
|||
return L_GET_CPP_PTR_FROM_C_OBJECT(msg)->getErrorInfo();
|
||||
}
|
||||
|
||||
bool_t linphone_chat_message_get_to_be_stored(const LinphoneChatMessage *message) {
|
||||
return L_GET_CPP_PTR_FROM_C_OBJECT(message)->getToBeStored();
|
||||
}
|
||||
|
||||
void linphone_chat_message_set_to_be_stored(LinphoneChatMessage *message, bool_t to_be_stored) {
|
||||
L_GET_CPP_PTR_FROM_C_OBJECT(message)->setToBeStored(!!to_be_stored);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Methods
|
||||
// =============================================================================
|
||||
|
|
|
|||
|
|
@ -59,11 +59,11 @@ public:
|
|||
|
||||
void setDirection (ChatMessage::Direction dir);
|
||||
|
||||
void setState(ChatMessage::State state, bool force = false, bool storeInDb = true);
|
||||
void setState (ChatMessage::State state, bool force = false);
|
||||
|
||||
void setTime(time_t time);
|
||||
void setTime (time_t time);
|
||||
|
||||
void setIsReadOnly(bool readOnly);
|
||||
void setIsReadOnly (bool readOnly);
|
||||
|
||||
void setImdnMessageId (const std::string &imdnMessageId);
|
||||
|
||||
|
|
@ -75,20 +75,20 @@ public:
|
|||
this->toAddress = toAddress;
|
||||
}
|
||||
|
||||
belle_http_request_t *getHttpRequest() const;
|
||||
void setHttpRequest(belle_http_request_t *request);
|
||||
belle_http_request_t *getHttpRequest () const;
|
||||
void setHttpRequest (belle_http_request_t *request);
|
||||
|
||||
SalOp *getSalOp() const;
|
||||
void setSalOp(SalOp *op);
|
||||
SalOp *getSalOp () const;
|
||||
void setSalOp (SalOp *op);
|
||||
|
||||
SalCustomHeader *getSalCustomHeaders() const;
|
||||
void setSalCustomHeaders(SalCustomHeader *headers);
|
||||
SalCustomHeader *getSalCustomHeaders () const;
|
||||
void setSalCustomHeaders (SalCustomHeader *headers);
|
||||
|
||||
void addSalCustomHeader(const std::string& name, const std::string& value);
|
||||
void removeSalCustomHeader(const std::string& name);
|
||||
std::string getSalCustomHeaderValue(const std::string& name);
|
||||
void addSalCustomHeader (const std::string& name, const std::string& value);
|
||||
void removeSalCustomHeader (const std::string& name);
|
||||
std::string getSalCustomHeaderValue (const std::string& name);
|
||||
|
||||
void loadFileTransferUrlFromBodyToContent();
|
||||
void loadFileTransferUrlFromBodyToContent ();
|
||||
|
||||
void setChatRoom (const std::shared_ptr<AbstractChatRoom> &chatRoom);
|
||||
|
||||
|
|
@ -96,11 +96,11 @@ public:
|
|||
// Deprecated methods only used for C wrapper, to be removed some day...
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
const ContentType &getContentType();
|
||||
void setContentType(const ContentType &contentType);
|
||||
const ContentType &getContentType ();
|
||||
void setContentType (const ContentType &contentType);
|
||||
|
||||
const std::string &getText();
|
||||
void setText(const std::string &text);
|
||||
const std::string &getText ();
|
||||
void setText (const std::string &text);
|
||||
|
||||
const std::string &getFileTransferFilepath () const;
|
||||
void setFileTransferFilepath (const std::string &path);
|
||||
|
|
@ -110,23 +110,25 @@ public:
|
|||
|
||||
const std::string &getExternalBodyUrl () const;
|
||||
|
||||
bool hasTextContent() const;
|
||||
const Content* getTextContent() const;
|
||||
bool hasTextContent () const;
|
||||
const Content* getTextContent () const;
|
||||
|
||||
bool hasFileTransferContent() const;
|
||||
const Content* getFileTransferContent() const;
|
||||
bool hasFileTransferContent () const;
|
||||
const Content* getFileTransferContent () const;
|
||||
|
||||
LinphoneContent *getFileTransferInformation() const;
|
||||
void setFileTransferInformation(const LinphoneContent *content);
|
||||
LinphoneContent *getFileTransferInformation () const;
|
||||
void setFileTransferInformation (const LinphoneContent *content);
|
||||
|
||||
bool downloadFile ();
|
||||
|
||||
void sendImdn(Imdn::Type imdnType, LinphoneReason reason);
|
||||
void sendImdn (Imdn::Type imdnType, LinphoneReason reason);
|
||||
|
||||
LinphoneReason receive();
|
||||
void send();
|
||||
void notifyReceiving ();
|
||||
LinphoneReason receive ();
|
||||
void send ();
|
||||
|
||||
void store();
|
||||
void storeInDb ();
|
||||
void updateInDb ();
|
||||
|
||||
private:
|
||||
// TODO: Clean attributes.
|
||||
|
|
@ -166,6 +168,8 @@ private:
|
|||
ChatMessage::State state = ChatMessage::State::Idle;
|
||||
ChatMessage::Direction direction = ChatMessage::Direction::Incoming;
|
||||
|
||||
bool toBeStored = true;
|
||||
|
||||
L_DECLARE_PUBLIC(ChatMessage);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ void ChatMessagePrivate::setIsReadOnly (bool readOnly) {
|
|||
isReadOnly = readOnly;
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::setState (ChatMessage::State s, bool force, bool storeInDb) {
|
||||
void ChatMessagePrivate::setState (ChatMessage::State s, bool force) {
|
||||
L_Q();
|
||||
|
||||
if (force)
|
||||
|
|
@ -98,9 +98,7 @@ void ChatMessagePrivate::setState (ChatMessage::State s, bool force, bool storeI
|
|||
if (cbs && linphone_chat_message_cbs_get_msg_state_changed(cbs))
|
||||
linphone_chat_message_cbs_get_msg_state_changed(cbs)(msg, linphone_chat_message_get_state(msg));
|
||||
|
||||
if (storeInDb) {
|
||||
store();
|
||||
}
|
||||
updateInDb();
|
||||
}
|
||||
|
||||
belle_http_request_t *ChatMessagePrivate::getHttpRequest () const {
|
||||
|
|
@ -205,7 +203,7 @@ void ChatMessagePrivate::setAppdata (const string &data) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
store();
|
||||
updateInDb();
|
||||
}
|
||||
|
||||
const string &ChatMessagePrivate::getExternalBodyUrl () const {
|
||||
|
|
@ -381,6 +379,29 @@ static void forceUtf8Content (Content &content) {
|
|||
L_END_LOG_EXCEPTION
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::notifyReceiving () {
|
||||
L_Q();
|
||||
|
||||
if ((getContentType() == ContentType::Imdn) || (getContentType() == ContentType::ImIsComposing))
|
||||
return;
|
||||
|
||||
LinphoneChatRoom *chatRoom = L_GET_C_BACK_PTR(q->getChatRoom());
|
||||
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(chatRoom);
|
||||
LinphoneChatRoomCbsParticipantAddedCb cb = linphone_chat_room_cbs_get_chat_message_received(cbs);
|
||||
shared_ptr<ConferenceChatMessageEvent> event = make_shared<ConferenceChatMessageEvent>(
|
||||
::time(nullptr), q->getSharedFromThis()
|
||||
);
|
||||
if (cb)
|
||||
cb(chatRoom, L_GET_C_BACK_PTR(event));
|
||||
// Legacy
|
||||
q->getChatRoom()->getPrivate()->notifyChatMessageReceived(q->getSharedFromThis());
|
||||
|
||||
if (toBeStored)
|
||||
storeInDb();
|
||||
|
||||
q->sendDeliveryNotification(LinphoneReasonNone);
|
||||
}
|
||||
|
||||
LinphoneReason ChatMessagePrivate::receive () {
|
||||
L_Q();
|
||||
int errorCode = 0;
|
||||
|
|
@ -389,8 +410,6 @@ LinphoneReason ChatMessagePrivate::receive () {
|
|||
shared_ptr<Core> core = q->getCore();
|
||||
shared_ptr<AbstractChatRoom> chatRoom = q->getChatRoom();
|
||||
|
||||
setState(ChatMessage::State::Delivered, false, false); // Wait for decryption and CPIM to reveal the real message to know if it must be stored or not
|
||||
|
||||
// ---------------------------------------
|
||||
// Start of message modification
|
||||
// ---------------------------------------
|
||||
|
|
@ -451,6 +470,8 @@ LinphoneReason ChatMessagePrivate::receive () {
|
|||
// End of message modification
|
||||
// ---------------------------------------
|
||||
|
||||
setState(ChatMessage::State::Delivered, false);
|
||||
|
||||
if (errorCode <= 0) {
|
||||
bool foundSupportContentType = false;
|
||||
for (Content *c : contents) {
|
||||
|
|
@ -482,7 +503,8 @@ LinphoneReason ChatMessagePrivate::receive () {
|
|||
return reason;
|
||||
}
|
||||
|
||||
store();
|
||||
if ((getContentType() == ContentType::ImIsComposing) || (getContentType() == ContentType::Imdn))
|
||||
toBeStored = false;
|
||||
|
||||
return reason;
|
||||
}
|
||||
|
|
@ -493,6 +515,8 @@ void ChatMessagePrivate::send () {
|
|||
LinphoneCall *lcall = nullptr;
|
||||
int errorCode = 0;
|
||||
|
||||
storeInDb();
|
||||
|
||||
if ((currentSendStep & ChatMessagePrivate::Step::FileUpload) == ChatMessagePrivate::Step::FileUpload) {
|
||||
lInfo() << "File upload step already done, skipping";
|
||||
} else {
|
||||
|
|
@ -634,8 +658,6 @@ void ChatMessagePrivate::send () {
|
|||
if (imdnId.empty())
|
||||
setImdnMessageId(op->get_call_id()); /* must be known at that time */
|
||||
|
||||
//store(); // Store will be done right below in the setState(InProgress)
|
||||
|
||||
if (lcall && linphone_call_get_op(lcall) == op) {
|
||||
/* In this case, chat delivery status is not notified, so unrefing chat message right now */
|
||||
/* Might be better fixed by delivering status, but too costly for now */
|
||||
|
|
@ -649,43 +671,17 @@ void ChatMessagePrivate::send () {
|
|||
}
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::store() {
|
||||
void ChatMessagePrivate::storeInDb () {
|
||||
L_Q();
|
||||
|
||||
// TODO: store message in the future
|
||||
if (linphone_core_conference_server_enabled(q->getCore()->getCCore())) return;
|
||||
|
||||
bool messageToBeStored = true;
|
||||
for (Content *c : contents) {
|
||||
ContentType contentType = c->getContentType();
|
||||
if (contentType == ContentType::Imdn || contentType == ContentType::ImIsComposing) {
|
||||
messageToBeStored = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!messageToBeStored) {
|
||||
return;
|
||||
}
|
||||
|
||||
unique_ptr<MainDb> &mainDb = q->getChatRoom()->getCore()->getPrivate()->mainDb;
|
||||
if (dbKey.isValid()) {
|
||||
shared_ptr<EventLog> eventLog = mainDb->getEventFromKey(dbKey);
|
||||
mainDb->updateEvent(eventLog);
|
||||
|
||||
if (direction == ChatMessage::Direction::Incoming) {
|
||||
if (!hasFileTransferContent()) {
|
||||
// Incoming message doesn't have any download waiting anymore, we can remove it's event from the transients
|
||||
q->getChatRoom()->getPrivate()->removeTransientEvent(eventLog);
|
||||
}
|
||||
} else {
|
||||
if (state == ChatMessage::State::Delivered || state == ChatMessage::State::NotDelivered) {
|
||||
// Once message has reached this state it won't change anymore so we can remove the event from the transients
|
||||
q->getChatRoom()->getPrivate()->removeTransientEvent(eventLog);
|
||||
}
|
||||
}
|
||||
updateInDb();
|
||||
} else {
|
||||
shared_ptr<EventLog> eventLog = make_shared<ConferenceChatMessageEvent>(time, q->getSharedFromThis());
|
||||
mainDb->addEvent(eventLog);
|
||||
q->getChatRoom()->getCore()->getPrivate()->mainDb->addEvent(eventLog);
|
||||
|
||||
if (direction == ChatMessage::Direction::Incoming) {
|
||||
if (hasFileTransferContent()) {
|
||||
|
|
@ -699,6 +695,29 @@ void ChatMessagePrivate::store() {
|
|||
}
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::updateInDb () {
|
||||
L_Q();
|
||||
|
||||
if (!dbKey.isValid())
|
||||
return;
|
||||
|
||||
unique_ptr<MainDb> &mainDb = q->getChatRoom()->getCore()->getPrivate()->mainDb;
|
||||
shared_ptr<EventLog> eventLog = mainDb->getEventFromKey(dbKey);
|
||||
mainDb->updateEvent(eventLog);
|
||||
|
||||
if (direction == ChatMessage::Direction::Incoming) {
|
||||
if (!hasFileTransferContent()) {
|
||||
// Incoming message doesn't have any download waiting anymore, we can remove it's event from the transients
|
||||
q->getChatRoom()->getPrivate()->removeTransientEvent(eventLog);
|
||||
}
|
||||
} else {
|
||||
if (state == ChatMessage::State::Delivered || state == ChatMessage::State::NotDelivered) {
|
||||
// Once message has reached this state it won't change anymore so we can remove the event from the transients
|
||||
q->getChatRoom()->getPrivate()->removeTransientEvent(eventLog);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
ChatMessage::ChatMessage (const shared_ptr<AbstractChatRoom> &chatRoom, ChatMessage::Direction direction) :
|
||||
|
|
@ -799,6 +818,16 @@ const IdentityAddress &ChatMessage::getToAddress () const {
|
|||
return d->toAddress;
|
||||
}
|
||||
|
||||
bool ChatMessage::getToBeStored () const {
|
||||
L_D();
|
||||
return d->toBeStored;
|
||||
}
|
||||
|
||||
void ChatMessage::setToBeStored (bool value) {
|
||||
L_D();
|
||||
d->toBeStored = value;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
const LinphoneErrorInfo *ChatMessage::getErrorInfo () const {
|
||||
|
|
|
|||
|
|
@ -90,6 +90,9 @@ public:
|
|||
bool isRead () const;
|
||||
bool isReadOnly () const;
|
||||
|
||||
bool getToBeStored () const;
|
||||
void setToBeStored (bool value);
|
||||
|
||||
const std::list<Content *> &getContents () const;
|
||||
void addContent (Content &content);
|
||||
void removeContent (const Content &content);
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ public:
|
|||
virtual void addTransientEvent (const std::shared_ptr<EventLog> &eventLog) = 0;
|
||||
virtual void removeTransientEvent (const std::shared_ptr<EventLog> &eventLog) = 0;
|
||||
|
||||
virtual void notifyChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) = 0;
|
||||
virtual void notifyUndecryptableChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) = 0;
|
||||
|
||||
virtual LinphoneReason onSipMessageReceived (SalOp *op, const SalMessage *message) = 0;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ public:
|
|||
std::shared_ptr<ChatMessage> createChatMessage (ChatMessage::Direction direction);
|
||||
std::list<std::shared_ptr<ChatMessage>> findChatMessages (const std::string &messageId) const;
|
||||
|
||||
void notifyChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage);
|
||||
void notifyChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) override;
|
||||
void notifyIsComposingReceived (const Address &remoteAddress, bool isComposing);
|
||||
void notifyStateChanged ();
|
||||
void notifyUndecryptableChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) override;
|
||||
|
|
|
|||
|
|
@ -244,24 +244,10 @@ end:
|
|||
}
|
||||
|
||||
void ChatRoomPrivate::onChatMessageReceived (const shared_ptr<ChatMessage> &chatMessage) {
|
||||
L_Q();
|
||||
|
||||
ContentType contentType = chatMessage->getPrivate()->getContentType();
|
||||
if (contentType != ContentType::Imdn && contentType != ContentType::ImIsComposing) {
|
||||
LinphoneChatRoom *chatRoom = L_GET_C_BACK_PTR(q);
|
||||
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(chatRoom);
|
||||
LinphoneChatRoomCbsParticipantAddedCb cb = linphone_chat_room_cbs_get_chat_message_received(cbs);
|
||||
shared_ptr<ConferenceChatMessageEvent> event = make_shared<ConferenceChatMessageEvent>(time(nullptr), chatMessage);
|
||||
if (cb)
|
||||
cb(chatRoom, L_GET_C_BACK_PTR(event));
|
||||
// Legacy
|
||||
notifyChatMessageReceived(chatMessage);
|
||||
|
||||
const IdentityAddress &fromAddress = chatMessage->getFromAddress();
|
||||
isComposingHandler->stopRemoteRefreshTimer(fromAddress.asString());
|
||||
notifyIsComposingReceived(fromAddress, false);
|
||||
chatMessage->sendDeliveryNotification(LinphoneReasonNone);
|
||||
}
|
||||
const IdentityAddress &fromAddress = chatMessage->getFromAddress();
|
||||
isComposingHandler->stopRemoteRefreshTimer(fromAddress.asString());
|
||||
notifyIsComposingReceived(fromAddress, false);
|
||||
chatMessage->getPrivate()->notifyReceiving();
|
||||
}
|
||||
|
||||
void ChatRoomPrivate::onImdnReceived (const string &text) {
|
||||
|
|
|
|||
|
|
@ -52,6 +52,10 @@ public:
|
|||
chatRoom->getPrivate()->removeTransientEvent(eventLog);
|
||||
}
|
||||
|
||||
inline void notifyChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) override {
|
||||
chatRoom->getPrivate()->notifyChatMessageReceived(chatMessage);
|
||||
}
|
||||
|
||||
inline void notifyUndecryptableChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) override {
|
||||
chatRoom->getPrivate()->notifyUndecryptableChatMessageReceived(chatMessage);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ void RealTimeTextChatRoomPrivate::realtimeTextReceived (uint32_t character, Linp
|
|||
pendingMessage->getPrivate()->setDirection(ChatMessage::Direction::Incoming);
|
||||
|
||||
if (lp_config_get_int(linphone_core_get_config(cCore), "misc", "store_rtt_messages", 1) == 1)
|
||||
pendingMessage->getPrivate()->store();
|
||||
pendingMessage->getPrivate()->storeInDb();
|
||||
|
||||
onChatMessageReceived(pendingMessage);
|
||||
pendingMessage = nullptr;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue