Fix hidden timelines.

Do timeline deletion on SDK callabacks to avoid using deleted objects.
From secure chats rooms, forward messages on the secure chat rooms if selected from contacts.
Update SDK.
This commit is contained in:
Julien Wadel 2022-10-27 13:55:07 +02:00
parent cb2cc3cef9
commit 39f72680ea
11 changed files with 39 additions and 33 deletions

View file

@ -242,7 +242,9 @@ bool CallModel::isConference () const{
// Check status to avoid crash when requesting a conference on an ended call.
bool isConf = false;
if(mCall){
isConf = getStatus() != CallStatusEnded && (mCall->getConference() != nullptr || mConferenceInfoModel != nullptr);
// Do not call getConference on Ended status.
isConf = (getStatus() != CallStatusEnded && mCall->getConference() != nullptr) || mConferenceInfoModel != nullptr;
if(!isConf){// Check special cases for Linphone. Having conf-id for a conference URI is not standard.
auto remoteAddress = mCall->getRemoteAddress();
if( remoteAddress->getDomain() == Constants::LinphoneDomain){

View file

@ -55,8 +55,8 @@ class CallModel : public QObject {
Q_PROPERTY(bool isOutgoing READ isOutgoing CONSTANT)
Q_PROPERTY(bool isInConference READ isInConference NOTIFY isInConferenceChanged)
Q_PROPERTY(bool isConference READ isConference CONSTANT)
Q_PROPERTY(bool isOneToOne READ isOneToOne CONSTANT)
Q_PROPERTY(bool isConference READ isConference NOTIFY conferenceInfoModelChanged)
Q_PROPERTY(bool isOneToOne READ isOneToOne NOTIFY conferenceInfoModelChanged)
Q_PROPERTY(int duration READ getDuration CONSTANT) // Constants but called with a timer in qml.

View file

@ -343,7 +343,7 @@ QVariantMap CallsListModel::createChatRoom(const QString& subject, const int& se
initializer->setAdminsData(admins);
ChatRoomInitializer::start(initializer);
}
timeline = timelineList->getTimeline(chatRoom, ChatRoomModel::isTerminated(chatRoom));
timeline = timelineList->getTimeline(chatRoom, true);
}else{
if(admins.size() > 0){
ChatRoomInitializer::create(chatRoom)->setAdmins(admins);

View file

@ -107,7 +107,7 @@ void ChatRoomModel::connectTo(ChatRoomListener * listener){
}
// -----------------------------------------------------------------------------
QSharedPointer<ChatRoomModel> ChatRoomModel::create(std::shared_ptr<linphone::ChatRoom> chatRoom, const std::list<std::shared_ptr<linphone::CallLog>>& callLogs){
QSharedPointer<ChatRoomModel> ChatRoomModel::create(const std::shared_ptr<linphone::ChatRoom>& chatRoom, const std::list<std::shared_ptr<linphone::CallLog>>& callLogs){
QSharedPointer<ChatRoomModel> model = QSharedPointer<ChatRoomModel>::create(chatRoom, callLogs);
if(model){
model->mSelf = model;
@ -117,7 +117,7 @@ QSharedPointer<ChatRoomModel> ChatRoomModel::create(std::shared_ptr<linphone::Ch
return nullptr;
}
ChatRoomModel::ChatRoomModel (std::shared_ptr<linphone::ChatRoom> chatRoom, const std::list<std::shared_ptr<linphone::CallLog>>& callLogs, QObject * parent) : ProxyListModel(parent){
ChatRoomModel::ChatRoomModel (const std::shared_ptr<linphone::ChatRoom>& chatRoom, const std::list<std::shared_ptr<linphone::CallLog>>& callLogs, QObject * parent) : ProxyListModel(parent){
App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
CoreManager *coreManager = CoreManager::getInstance();
mCoreHandlers = coreManager->getHandlers();
@ -311,11 +311,11 @@ QString ChatRoomModel::getLocalAddress () const {
}
QString ChatRoomModel::getFullPeerAddress () const {
return mChatRoom ? Utils::coreStringToAppString(mChatRoom->getPeerAddress()->asString()) : "";
return mChatRoom && mChatRoom->getPeerAddress() ? Utils::coreStringToAppString(mChatRoom->getPeerAddress()->asString()) : "";
}
QString ChatRoomModel::getFullLocalAddress () const {
return mChatRoom ? Utils::coreStringToAppString(mChatRoom->getLocalAddress()->asString()) : "";
return mChatRoom && mChatRoom->getLocalAddress()? Utils::coreStringToAppString(mChatRoom->getLocalAddress()->asString()) : "";
}
QString ChatRoomModel::getConferenceAddress () const {
@ -620,15 +620,14 @@ void ChatRoomModel::markAsToDelete(){
void ChatRoomModel::deleteChatRoom(){
qInfo() << "Deleting ChatRoom : " << getSubject() << ", address=" << getFullPeerAddress();
if(mChatRoom){
mChatRoom->removeListener(mChatRoomListener);
CoreManager::getInstance()->getCore()->deleteChatRoom(mChatRoom);
}
emit chatRoomDeleted();
}
void ChatRoomModel::leaveChatRoom (){
if(mChatRoom){
mChatRoom->leave();
if(!isReadOnly())
mChatRoom->leave();
if( mChatRoom->getHistorySize() == 0 && mChatRoom->getHistoryEventsSize() == 0)
deleteChatRoom();
}
@ -1311,6 +1310,11 @@ void ChatRoomModel::onParticipantAdminStatusChanged(const std::shared_ptr<linpho
void ChatRoomModel::onStateChanged(const std::shared_ptr<linphone::ChatRoom> & chatRoom, linphone::ChatRoom::State newState){
updateLastUpdateTime();
emit stateChanged(getState());
if(newState == linphone::ChatRoom::State::Deleted){
mChatRoom->removeListener(mChatRoomListener);
mChatRoom = nullptr;
emit chatRoomDeleted();
}
}
void ChatRoomModel::onSecurityEvent(const std::shared_ptr<linphone::ChatRoom> & chatRoom, const std::shared_ptr<const linphone::EventLog> & eventLog){

View file

@ -93,8 +93,8 @@ public:
Q_PROPERTY(bool entriesLoading READ isEntriesLoading WRITE setEntriesLoading NOTIFY entriesLoadingChanged)
static QSharedPointer<ChatRoomModel> create(std::shared_ptr<linphone::ChatRoom> chatRoom, const std::list<std::shared_ptr<linphone::CallLog>>& callLogs = std::list<std::shared_ptr<linphone::CallLog>>());
ChatRoomModel (std::shared_ptr<linphone::ChatRoom> chatRoom, const std::list<std::shared_ptr<linphone::CallLog>>& callLogs = std::list<std::shared_ptr<linphone::CallLog>>(), QObject * parent = nullptr);
static QSharedPointer<ChatRoomModel> create(const std::shared_ptr<linphone::ChatRoom>& chatRoom, const std::list<std::shared_ptr<linphone::CallLog>>& callLogs = std::list<std::shared_ptr<linphone::CallLog>>());
ChatRoomModel (const std::shared_ptr<linphone::ChatRoom>& chatRoom, const std::list<std::shared_ptr<linphone::CallLog>>& callLogs = std::list<std::shared_ptr<linphone::CallLog>>(), QObject * parent = nullptr);
~ChatRoomModel ();

View file

@ -335,7 +335,7 @@ void ChatRoomProxyModel::setChatRoomModel (ChatRoomModel *chatRoomModel){
}else{
if(mIsCall && mChatRoomModel)
mChatRoomModel->removeBindingCall();
mChatRoomModel = nullptr;
mChatRoomModel = nullptr;
}
}
// -----------------------------------------------------------------------------

View file

@ -69,7 +69,6 @@ SettingsModel::SettingsModel (QObject *parent) : QObject(parent) {
connect(coreManager->getAccountSettingsModel(), &AccountSettingsModel::accountSettingsUpdated, this, &SettingsModel::videoConferenceEnabledChanged);
connect(coreManager->getAccountSettingsModel(), &AccountSettingsModel::accountSettingsUpdated, this, &SettingsModel::secureChatEnabledChanged);
configureRlsUri();
}

View file

@ -455,8 +455,10 @@ void SipAddressesModel::handleMessageCountReset (ChatRoomModel *chatRoomModel) {
}
void SipAddressesModel::handleMessageSent (const shared_ptr<linphone::ChatMessage> &message) {
const QString peerAddress(Utils::coreStringToAppString(message->getChatRoom()->getPeerAddress()->asStringUriOnly()));
addOrUpdateSipAddress(peerAddress, message);
if(message->getChatRoom() && message->getChatRoom()->getPeerAddress()){
const QString peerAddress(Utils::coreStringToAppString(message->getChatRoom()->getPeerAddress()->asStringUriOnly()));
addOrUpdateSipAddress(peerAddress, message);
}
}
void SipAddressesModel::handleIsComposingChanged (const shared_ptr<linphone::ChatRoom> &chatRoom) {

View file

@ -71,7 +71,6 @@ TimelineListModel::TimelineListModel(const TimelineListModel* model){
auto newItem = qobject_cast<TimelineModel*>(item)->clone();
connect(newItem.get(), SIGNAL(selectedChanged(bool)), this, SLOT(onSelectedHasChanged(bool)));
connect(newItem.get(), &TimelineModel::chatRoomDeleted, this, &TimelineListModel::onChatRoomDeleted);
connect(newItem->getChatRoomModel(), &ChatRoomModel::allEntriesRemoved, this, &TimelineListModel::removeChatRoomModel);
mList << newItem;
}
}
@ -141,7 +140,6 @@ QSharedPointer<TimelineModel> TimelineListModel::getTimeline(std::shared_ptr<lin
QSharedPointer<TimelineModel> model = TimelineModel::create(this, chatRoom);
if(model){
connect(model.get(), SIGNAL(selectedChanged(bool)), this, SLOT(onSelectedHasChanged(bool)));
connect(model->getChatRoomModel(), &ChatRoomModel::allEntriesRemoved, this, &TimelineListModel::removeChatRoomModel);
add(model);
return model;
}
@ -189,7 +187,6 @@ QSharedPointer<ChatRoomModel> TimelineListModel::getChatRoomModel(std::shared_pt
QSharedPointer<TimelineModel> model = TimelineModel::create(this, chatRoom);
if(model){
connect(model.get(), SIGNAL(selectedChanged(bool)), this, SLOT(onSelectedHasChanged(bool)));
connect(model->getChatRoomModel(), &ChatRoomModel::allEntriesRemoved, this, &TimelineListModel::removeChatRoomModel);
add(model);
return model->mChatRoomModel;
}
@ -249,7 +246,7 @@ void TimelineListModel::updateTimelines () {
allChatRooms.remove_if([](std::shared_ptr<linphone::ChatRoom> chatRoom){
if( ChatRoomModel::isTerminated(chatRoom) && chatRoom->getUnreadMessagesCount() > 0)
chatRoom->markAsRead();
return !chatRoom->hasCapability((int)linphone::ChatRoomCapabilities::Basic) && chatRoom->getConferenceAddress() && chatRoom->getHistoryEventsSize() == 0;
return chatRoom->getState() == linphone::ChatRoom::State::Deleted || (!chatRoom->hasCapability((int)linphone::ChatRoomCapabilities::Basic) && chatRoom->getConferenceAddress() && chatRoom->getHistoryEventsSize() == 0);
});
//Remove no more chat rooms
@ -294,7 +291,6 @@ void TimelineListModel::updateTimelines () {
QSharedPointer<TimelineModel> model = TimelineModel::create(this, dbChatRoom, callLogs);
if( model){
connect(model.get(), SIGNAL(selectedChanged(bool)), this, SLOT(onSelectedHasChanged(bool)));
connect(model->getChatRoomModel(), &ChatRoomModel::allEntriesRemoved, this, &TimelineListModel::removeChatRoomModel);
add(model);
}
}
@ -306,12 +302,10 @@ void TimelineListModel::add (QSharedPointer<TimelineModel> timeline){
auto chatRoomModel = timeline->getChatRoomModel();
auto chatRoom = chatRoomModel->getChatRoom();
connect(timeline.get(), &TimelineModel::chatRoomDeleted, this, &TimelineListModel::onChatRoomDeleted);
if( !chatRoomModel->haveConferenceAddress() || chatRoom->getHistoryEventsSize() != 0) {
connect(chatRoomModel, &ChatRoomModel::lastUpdateTimeChanged, this, &TimelineListModel::updated);
ProxyListModel::add(timeline);
emit layoutChanged();
emit countChanged();
}
connect(chatRoomModel, &ChatRoomModel::lastUpdateTimeChanged, this, &TimelineListModel::updated);
ProxyListModel::add(timeline);
emit layoutChanged();
emit countChanged();
}
void TimelineListModel::removeChatRoomModel(QSharedPointer<ChatRoomModel> model){
@ -356,7 +350,6 @@ void TimelineListModel::onChatRoomStateChanged(const std::shared_ptr<linphone::C
QSharedPointer<TimelineModel> model = TimelineModel::create(this, chatRoom);
if(model){
connect(model.get(), SIGNAL(selectedChanged(bool)), this, SLOT(onSelectedHasChanged(bool)));
connect(model->getChatRoomModel(), &ChatRoomModel::allEntriesRemoved, this, &TimelineListModel::removeChatRoomModel);
add(model);
}
}else if(state == linphone::ChatRoom::State::Deleted || state == linphone::ChatRoom::State::Terminated){
@ -368,6 +361,11 @@ void TimelineListModel::onChatRoomStateChanged(const std::shared_ptr<linphone::C
remove(timeline);// This will call removeRows()
}
}
}else if(state == linphone::ChatRoom::State::CreationFailed){
auto timeline = getTimeline(chatRoom, false);
if(timeline) {
remove(timeline);// This will call removeRows()
}
}
}

View file

@ -12,6 +12,7 @@ import LinphoneEnums 1.0
import Units 1.0
import 'Chat.js' as Logic
import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
@ -290,10 +291,10 @@ Rectangle {
//: 'Choose where to forward the message' : Dialog title for choosing where to forward the current message.
, {title: qsTr('forwardDialogTitle'),
addressSelectedCallback: function (sipAddress) {
var chat = CallsListModel.createChat(sipAddress)
var chat = CallsListModel.createChatRoom( '', proxyModel.chatRoomModel.haveEncryption, [sipAddress], false )
if(chat){
chat.forwardMessage($chatEntry)
TimelineListModel.select(chat)
chat.chatRoomModel.forwardMessage($chatEntry)
TimelineListModel.select(chat.chatRoomModel)
}
},
chatRoomSelectedCallback: function (chatRoomModel){

@ -1 +1 @@
Subproject commit af1b28595eb3ca9406c24ed3683e6e524eeaddbe
Subproject commit b5cc94b43b9ad5644f5d7ec8bd8f9f7a81127a54