do not display notification when it comes from the currently displayed chat #LINQT-2079

do not create account model for each chat, too much listener sending signals

fix crash in ConferenceInfoList #LINQT-2080
fix warnings on endResetModel
fix messages added twice because of displayMore() function called when lUpdate is running
Plain text in sending text area
This commit is contained in:
Gaelle Braud 2025-10-22 14:44:16 +02:00 committed by gaelle
parent 55a54dc10e
commit 8e10decd65
14 changed files with 182 additions and 79 deletions

View file

@ -451,7 +451,7 @@ App *App::getInstance() {
return dynamic_cast<App *>(QApplication::instance()); return dynamic_cast<App *>(QApplication::instance());
} }
QThread *App::getLinphoneThread() { Thread *App::getLinphoneThread() {
return App::getInstance()->mLinphoneThread; return App::getInstance()->mLinphoneThread;
} }
@ -1436,6 +1436,17 @@ QString App::getSdkVersion() {
#endif #endif
} }
ChatGui *App::getCurrentChat() const {
return mCurrentChat;
}
void App::setCurrentChat(ChatGui *chat) {
if (chat != mCurrentChat) {
mCurrentChat = chat;
emit currentChatChanged();
}
}
float App::getScreenRatio() const { float App::getScreenRatio() const {
return mScreenRatio; return mScreenRatio;
} }

View file

@ -25,6 +25,7 @@
#include "core/account/AccountProxy.hpp" #include "core/account/AccountProxy.hpp"
#include "core/call/CallProxy.hpp" #include "core/call/CallProxy.hpp"
#include "core/chat/ChatGui.hpp"
#include "core/setting/SettingsCore.hpp" #include "core/setting/SettingsCore.hpp"
#include "core/singleapplication/singleapplication.h" #include "core/singleapplication/singleapplication.h"
#include "model/cli/CliModel.hpp" #include "model/cli/CliModel.hpp"
@ -32,6 +33,7 @@
#include "tool/AbstractObject.hpp" #include "tool/AbstractObject.hpp"
class CallGui; class CallGui;
class ChatGui;
class Thread; class Thread;
class Notifier; class Notifier;
class QQuickWindow; class QQuickWindow;
@ -46,13 +48,14 @@ class App : public SingleApplication, public AbstractObject {
Q_PROPERTY(QString shortApplicationVersion READ getShortApplicationVersion CONSTANT) Q_PROPERTY(QString shortApplicationVersion READ getShortApplicationVersion CONSTANT)
Q_PROPERTY(QString gitBranchName READ getGitBranchName CONSTANT) Q_PROPERTY(QString gitBranchName READ getGitBranchName CONSTANT)
Q_PROPERTY(QString sdkVersion READ getSdkVersion CONSTANT) Q_PROPERTY(QString sdkVersion READ getSdkVersion CONSTANT)
Q_PROPERTY(ChatGui *currentChat READ getCurrentChat WRITE setCurrentChat NOTIFY currentChatChanged)
public: public:
App(int &argc, char *argv[]); App(int &argc, char *argv[]);
~App(); ~App();
void setSelf(QSharedPointer<App>(me)); void setSelf(QSharedPointer<App>(me));
static App *getInstance(); static App *getInstance();
static QThread *getLinphoneThread(); static Thread *getLinphoneThread();
Notifier *getNotifier() const; Notifier *getNotifier() const;
EventCountNotifier *getEventCountNotifier(); EventCountNotifier *getEventCountNotifier();
@ -162,6 +165,9 @@ public:
QString getGitBranchName(); QString getGitBranchName();
QString getSdkVersion(); QString getSdkVersion();
ChatGui *getCurrentChat() const;
void setCurrentChat(ChatGui *chat);
float getScreenRatio() const; float getScreenRatio() const;
Q_INVOKABLE void setScreenRatio(float ratio); Q_INVOKABLE void setScreenRatio(float ratio);
@ -186,6 +192,7 @@ signals:
void defaultAccountChanged(); void defaultAccountChanged();
void callsChanged(); void callsChanged();
void currentDateChanged(); void currentDateChanged();
void currentChatChanged();
// void executeCommand(QString command); // void executeCommand(QString command);
private: private:
@ -203,6 +210,9 @@ private:
QQuickWindow *mMainWindow = nullptr; QQuickWindow *mMainWindow = nullptr;
QQuickWindow *mCallsWindow = nullptr; QQuickWindow *mCallsWindow = nullptr;
QQuickWindow *mLastActiveWindow = nullptr; QQuickWindow *mLastActiveWindow = nullptr;
// Holds the current chat displayed in the view
// to know if we need to display the notification
ChatGui *mCurrentChat = nullptr;
QSharedPointer<SettingsCore> mSettings; QSharedPointer<SettingsCore> mSettings;
QSharedPointer<AccountList> mAccountList; QSharedPointer<AccountList> mAccountList;
QSharedPointer<CallList> mCallList; QSharedPointer<CallList> mCallList;

View file

@ -95,7 +95,7 @@ ChatCore::ChatCore(const std::shared_ptr<linphone::ChatRoom> &chatRoom) : QObjec
mChatRoomState = LinphoneEnums::fromLinphone(chatRoom->getState()); mChatRoomState = LinphoneEnums::fromLinphone(chatRoom->getState());
mIsEncrypted = chatRoom->hasCapability((int)linphone::ChatRoom::Capabilities::Encrypted); mIsEncrypted = chatRoom->hasCapability((int)linphone::ChatRoom::Capabilities::Encrypted);
auto localAccount = ToolModel::findAccount(chatRoom->getLocalAddress()); auto localAccount = ToolModel::findAccount(chatRoom->getLocalAddress());
if (localAccount) mLocalAccount = AccountCore::create(localAccount); mLocalAddress = Utils::coreStringToAppString(chatRoom->getLocalAddress()->asStringUriOnly());
bool associatedAccountHasIMEncryptionMandatory = bool associatedAccountHasIMEncryptionMandatory =
localAccount && localAccount->getParams() && localAccount && localAccount->getParams() &&
localAccount->getParams()->getInstantMessagingEncryptionMandatory(); localAccount->getParams()->getInstantMessagingEncryptionMandatory();
@ -628,8 +628,8 @@ QList<QSharedPointer<ParticipantCore>> ChatCore::getParticipants() const {
return mParticipants; return mParticipants;
} }
QSharedPointer<AccountCore> ChatCore::getLocalAccount() const { QString ChatCore::getLocalAddress() const {
return mLocalAccount; return mLocalAddress;
} }
void ChatCore::updateInfo(const std::shared_ptr<linphone::Friend> &updatedFriend, bool isRemoval) { void ChatCore::updateInfo(const std::shared_ptr<linphone::Friend> &updatedFriend, bool isRemoval) {

View file

@ -150,7 +150,7 @@ public:
QVariantList getParticipantsGui() const; QVariantList getParticipantsGui() const;
QStringList getParticipantsAddresses() const; QStringList getParticipantsAddresses() const;
QSharedPointer<AccountCore> getLocalAccount() const; QString getLocalAddress() const;
void updateInfo(const std::shared_ptr<linphone::Friend> &updatedFriend, bool isRemoval = false); void updateInfo(const std::shared_ptr<linphone::Friend> &updatedFriend, bool isRemoval = false);
@ -210,6 +210,7 @@ private:
int mUnreadMessagesCount; int mUnreadMessagesCount;
QString mComposingName; QString mComposingName;
QString mComposingAddress; QString mComposingAddress;
QString mLocalAddress;
bool mIsGroupChat = false; bool mIsGroupChat = false;
bool mIsEncrypted = false; bool mIsEncrypted = false;
bool mIsReadOnly = false; bool mIsReadOnly = false;
@ -227,7 +228,6 @@ private:
LinphoneEnums::ChatRoomState mChatRoomState; LinphoneEnums::ChatRoomState mChatRoomState;
std::shared_ptr<ChatModel> mChatModel; std::shared_ptr<ChatModel> mChatModel;
QSharedPointer<ChatMessageCore> mLastMessage; QSharedPointer<ChatMessageCore> mLastMessage;
QSharedPointer<AccountCore> mLocalAccount;
std::shared_ptr<FriendModel> mFriendModel; std::shared_ptr<FriendModel> mFriendModel;
QSharedPointer<SafeConnection<ChatCore, ChatModel>> mChatModelConnection; QSharedPointer<SafeConnection<ChatCore, ChatModel>> mChatModelConnection;
QSharedPointer<SafeConnection<ChatCore, CoreModel>> mCoreModelConnection; QSharedPointer<SafeConnection<ChatCore, CoreModel>> mCoreModelConnection;

View file

@ -81,14 +81,28 @@ void ChatList::connectItem(QSharedPointer<ChatCore> chat) {
void ChatList::setSelf(QSharedPointer<ChatList> me) { void ChatList::setSelf(QSharedPointer<ChatList> me) {
mModelConnection = SafeConnection<ChatList, CoreModel>::create(me, CoreModel::getInstance()); mModelConnection = SafeConnection<ChatList, CoreModel>::create(me, CoreModel::getInstance());
mModelConnection->makeConnectToCore(&ChatList::lUpdate, [this]() { mModelConnection->makeConnectToCore(&ChatList::lUpdate, [this]() {
beginResetModel(); if (mIsUpdating) {
mList.clear(); connect(this, &ChatList::isUpdatingChanged, this, [this] {
if (!mIsUpdating) {
disconnect(this, &ChatList::isUpdatingChanged, this, nullptr);
lUpdate();
}
});
return;
}
setIsUpdating(true);
mModelConnection->invokeToModel([this]() { mModelConnection->invokeToModel([this]() {
mustBeInLinphoneThread(getClassName()); mustBeInLinphoneThread(getClassName());
beginResetModel();
mList.clear();
// Avoid copy to lambdas // Avoid copy to lambdas
QList<QSharedPointer<ChatCore>> *chats = new QList<QSharedPointer<ChatCore>>(); QList<QSharedPointer<ChatCore>> *chats = new QList<QSharedPointer<ChatCore>>();
auto currentAccount = CoreModel::getInstance()->getCore()->getDefaultAccount(); auto currentAccount = CoreModel::getInstance()->getCore()->getDefaultAccount();
if (!currentAccount) return; if (!currentAccount) {
setIsUpdating(false);
endResetModel();
return;
}
auto linphoneChatRooms = currentAccount->filterChatRooms(Utils::appStringToCoreString(mFilter)); auto linphoneChatRooms = currentAccount->filterChatRooms(Utils::appStringToCoreString(mFilter));
for (auto it : linphoneChatRooms) { for (auto it : linphoneChatRooms) {
auto model = createChatCore(it); auto model = createChatCore(it);
@ -109,6 +123,7 @@ void ChatList::setSelf(QSharedPointer<ChatList> me) {
} }
add(*chats); add(*chats);
endResetModel(); endResetModel();
setIsUpdating(false);
delete chats; delete chats;
}); });
}); });

View file

@ -81,13 +81,6 @@ void EventLogList::connectItem(const QSharedPointer<EventLogCore> &item) {
} }
} }
void EventLogList::setIsUpdating(bool updating) {
if (mIsUpdating != updating) {
mIsUpdating = updating;
emit isUpdatingChanged();
}
}
void EventLogList::setChatCore(QSharedPointer<ChatCore> core) { void EventLogList::setChatCore(QSharedPointer<ChatCore> core) {
auto updateChatCore = [this](QSharedPointer<ChatCore> core) { auto updateChatCore = [this](QSharedPointer<ChatCore> core) {
if (mChatCore != core) { if (mChatCore != core) {
@ -144,31 +137,42 @@ void EventLogList::setDisplayItemsStep(int displayItemsStep) {
} }
void EventLogList::displayMore() { void EventLogList::displayMore() {
if (!mChatCore) return; auto loadMoreItems = [this] {
auto chatModel = mChatCore->getModel(); if (!mChatCore) return;
if (!chatModel) return; auto chatModel = mChatCore->getModel();
mCoreModelConnection->invokeToModel([this, chatModel]() { if (!chatModel) return;
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); mCoreModelConnection->invokeToModel([this, chatModel]() {
int maxSize = chatModel->getHistorySizeEvents(); mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
int totalItemsCount = mList.count(); int maxSize = chatModel->getHistorySizeEvents();
auto newCount = std::min(totalItemsCount + mDisplayItemsStep, maxSize); int totalItemsCount = mList.count();
if (newCount <= totalItemsCount) { auto newCount = std::min(totalItemsCount + mDisplayItemsStep, maxSize);
return; if (newCount <= totalItemsCount) {
} return;
auto linphoneLogs = chatModel->getHistoryRange(totalItemsCount, newCount); }
QList<QSharedPointer<EventLogCore>> *events = new QList<QSharedPointer<EventLogCore>>(); auto linphoneLogs = chatModel->getHistoryRange(totalItemsCount, newCount);
for (auto it : linphoneLogs) { QList<QSharedPointer<EventLogCore>> *events = new QList<QSharedPointer<EventLogCore>>();
auto model = EventLogCore::create(it); for (auto it : linphoneLogs) {
events->push_back(model); auto model = EventLogCore::create(it);
} events->push_back(model);
mCoreModelConnection->invokeToCore([this, events] { }
int currentCount = mList.count(); mCoreModelConnection->invokeToCore([this, events] {
for (auto it = events->end() - 1; it >= events->begin(); --it) { int currentCount = mList.count();
connectItem(*it); for (auto it = events->end() - 1; it >= events->begin(); --it) {
prepend(*it); connectItem(*it);
prepend(*it);
}
});
});
};
if (mIsUpdating) {
connect(this, &EventLogList::isUpdatingChanged, this, [this, loadMoreItems] {
if (!mIsUpdating) {
disconnect(this, &EventLogList::isUpdatingChanged, this, nullptr);
loadMoreItems();
} }
}); });
}); return;
} else loadMoreItems();
} }
void EventLogList::loadMessagesUpTo(std::shared_ptr<linphone::EventLog> event) { void EventLogList::loadMessagesUpTo(std::shared_ptr<linphone::EventLog> event) {
@ -262,6 +266,15 @@ void EventLogList::setSelf(QSharedPointer<EventLogList> me) {
mCoreModelConnection->makeConnectToCore(&EventLogList::lUpdate, [this]() { mCoreModelConnection->makeConnectToCore(&EventLogList::lUpdate, [this]() {
mustBeInMainThread(log().arg(Q_FUNC_INFO)); mustBeInMainThread(log().arg(Q_FUNC_INFO));
if (mIsUpdating) {
connect(this, &EventLogList::isUpdatingChanged, this, [this] {
if (!mIsUpdating) {
disconnect(this, &EventLogList::isUpdatingChanged, this, nullptr);
lUpdate();
}
});
return;
}
setIsUpdating(true); setIsUpdating(true);
beginResetModel(); beginResetModel();
mList.clear(); mList.clear();

View file

@ -48,8 +48,6 @@ public:
void connectItem(const QSharedPointer<EventLogCore> &item); void connectItem(const QSharedPointer<EventLogCore> &item);
void disconnectItem(const QSharedPointer<EventLogCore> &item); void disconnectItem(const QSharedPointer<EventLogCore> &item);
void setIsUpdating(bool updating);
void loadMessagesUpTo(std::shared_ptr<linphone::EventLog> event); void loadMessagesUpTo(std::shared_ptr<linphone::EventLog> event);
void setLastFoundResult(const QSharedPointer<EventLogCore> &eventLog); void setLastFoundResult(const QSharedPointer<EventLogCore> &eventLog);
@ -75,7 +73,6 @@ signals:
void messageWithFilterFound(int index); void messageWithFilterFound(int index);
void listAboutToBeReset(); void listAboutToBeReset();
void chatGuiChanged(); void chatGuiChanged();
void isUpdatingChanged();
void displayItemsStepChanged(); void displayItemsStepChanged();
void messagesLoadedUpTo(std::shared_ptr<linphone::EventLog> event); void messagesLoadedUpTo(std::shared_ptr<linphone::EventLog> event);
@ -84,7 +81,6 @@ private:
QSharedPointer<ChatCore> mChatCore; QSharedPointer<ChatCore> mChatCore;
QSharedPointer<SafeConnection<ChatCore, ChatModel>> mChatModelConnection; QSharedPointer<SafeConnection<ChatCore, ChatModel>> mChatModelConnection;
QSharedPointer<SafeConnection<EventLogList, CoreModel>> mCoreModelConnection; QSharedPointer<SafeConnection<EventLogList, CoreModel>> mCoreModelConnection;
bool mIsUpdating = false;
int mDisplayItemsStep = 0; int mDisplayItemsStep = 0;
int mItemsToLoadBeforeSearchResult = 3; int mItemsToLoadBeforeSearchResult = 3;
QSharedPointer<EventLogCore> mLastFoundResult; QSharedPointer<EventLogCore> mLastFoundResult;

View file

@ -59,6 +59,16 @@ void ConferenceInfoList::setSelf(QSharedPointer<ConferenceInfoList> me) {
mCoreModelConnection = SafeConnection<ConferenceInfoList, CoreModel>::create(me, CoreModel::getInstance()); mCoreModelConnection = SafeConnection<ConferenceInfoList, CoreModel>::create(me, CoreModel::getInstance());
mCoreModelConnection->makeConnectToCore(&ConferenceInfoList::lUpdate, [this]() { mCoreModelConnection->makeConnectToCore(&ConferenceInfoList::lUpdate, [this]() {
if (mIsUpdating) {
connect(this, &ConferenceInfoList::isUpdatingChanged, this, [this] {
if (!mIsUpdating) {
disconnect(this, &ConferenceInfoList::isUpdatingChanged, this, nullptr);
lUpdate();
}
});
return;
}
setIsUpdating(true);
mCoreModelConnection->invokeToModel([this]() { mCoreModelConnection->invokeToModel([this]() {
mustBeInLinphoneThread(getClassName()); mustBeInLinphoneThread(getClassName());
beginResetModel(); beginResetModel();
@ -68,12 +78,14 @@ void ConferenceInfoList::setSelf(QSharedPointer<ConferenceInfoList> me) {
setAccountConnected(defaultAccount && defaultAccount->getState() == linphone::RegistrationState::Ok); setAccountConnected(defaultAccount && defaultAccount->getState() == linphone::RegistrationState::Ok);
if (!defaultAccount || !mAccountConnected) { if (!defaultAccount || !mAccountConnected) {
endResetModel(); endResetModel();
setIsUpdating(false);
return; return;
} }
std::list<std::shared_ptr<linphone::ConferenceInfo>> conferenceInfos = std::list<std::shared_ptr<linphone::ConferenceInfo>> conferenceInfos =
defaultAccount->getConferenceInformationList(); defaultAccount->getConferenceInformationList();
if (conferenceInfos.empty()) { if (conferenceInfos.empty()) {
endResetModel(); endResetModel();
setIsUpdating(false);
return; return;
} }
items->push_back(nullptr); // Add Dummy conference for today items->push_back(nullptr); // Add Dummy conference for today
@ -96,6 +108,7 @@ void ConferenceInfoList::setSelf(QSharedPointer<ConferenceInfoList> me) {
} }
updateHaveCurrentDate(); updateHaveCurrentDate();
endResetModel(); endResetModel();
setIsUpdating(false);
delete items; delete items;
}); });
}); });
@ -138,9 +151,12 @@ void ConferenceInfoList::setSelf(QSharedPointer<ConferenceInfoList> me) {
auto accountCore = defaultAccount ? AccountCore::create(defaultAccount) : nullptr; auto accountCore = defaultAccount ? AccountCore::create(defaultAccount) : nullptr;
mCoreModelConnection->invokeToCore([this, accountCore] { mCoreModelConnection->invokeToCore([this, accountCore] {
mCurrentAccountCore = accountCore; mCurrentAccountCore = accountCore;
if (mCurrentAccountCore) if (mCurrentAccountCore) {
connect(mCurrentAccountCore.get(), &AccountCore::registrationStateChanged, this, connect(mCurrentAccountCore.get(), &AccountCore::registrationStateChanged, this,
[this] { emit lUpdate(); }); [this] { emit lUpdate(); });
connect(mCurrentAccountCore.get(), &AccountCore::conferenceInformationUpdated, this,
[this] { emit lUpdate(); });
}
}); });
}); });
emit lUpdate(); emit lUpdate();

View file

@ -280,7 +280,6 @@ void Notifier::notifyReceivedCall(const shared_ptr<linphone::Call> &call) {
auto account = ToolModel::findAccount(call->getToAddress()); auto account = ToolModel::findAccount(call->getToAddress());
if (account) { if (account) {
auto accountModel = Utils::makeQObject_ptr<AccountModel>(account); auto accountModel = Utils::makeQObject_ptr<AccountModel>(account);
accountModel->setSelf(accountModel);
if (!accountModel->getNotificationsAllowed()) { if (!accountModel->getNotificationsAllowed()) {
lInfo() << log().arg( lInfo() << log().arg(
"Notifications have been disabled for this account - not creating a notification for incoming call"); "Notifications have been disabled for this account - not creating a notification for incoming call");
@ -295,6 +294,7 @@ void Notifier::notifyReceivedCall(const shared_ptr<linphone::Call> &call) {
} }
return; return;
} }
accountModel->deleteLater();
} }
auto model = CallCore::create(call); auto model = CallCore::create(call);
@ -329,6 +329,7 @@ void Notifier::notifyReceivedMessages(const std::shared_ptr<linphone::ChatRoom>
QString remoteAddress; QString remoteAddress;
if (messages.size() > 0) { if (messages.size() > 0) {
shared_ptr<linphone::ChatMessage> message = messages.front(); shared_ptr<linphone::ChatMessage> message = messages.front();
auto receiverAccount = ToolModel::findAccount(message->getToAddress()); auto receiverAccount = ToolModel::findAccount(message->getToAddress());
if (receiverAccount) { if (receiverAccount) {
@ -339,13 +340,13 @@ void Notifier::notifyReceivedMessages(const std::shared_ptr<linphone::ChatRoom>
return; return;
} }
auto accountModel = Utils::makeQObject_ptr<AccountModel>(receiverAccount); auto accountModel = Utils::makeQObject_ptr<AccountModel>(receiverAccount);
accountModel->setSelf(accountModel);
if (!accountModel->getNotificationsAllowed()) { if (!accountModel->getNotificationsAllowed()) {
lInfo() << log().arg( lInfo() << log().arg(
"Notifications have been disabled for this account - not creating a notification for " "Notifications have been disabled for this account - not creating a notification for "
"incoming message"); "incoming message");
return; return;
} }
accountModel->deleteLater();
} }
auto getMessage = [this, &remoteAddress, &txt](const shared_ptr<linphone::ChatMessage> &message) { auto getMessage = [this, &remoteAddress, &txt](const shared_ptr<linphone::ChatMessage> &message) {
@ -387,14 +388,33 @@ void Notifier::notifyReceivedMessages(const std::shared_ptr<linphone::ChatRoom>
txt = tr("new_chat_room_messages"); txt = tr("new_chat_room_messages");
} }
auto chatCore = ChatCore::create(room); // Play noitification sound
auto settings = SettingsModel::getInstance();
if (settings && !settings->dndEnabled()) {
CoreModel::getInstance()->getCore()->playLocal(
Utils::appStringToCoreString(settings->getChatNotificationSoundPath()));
}
// Accessibility alert // If chat currently displayed, do not display notification
//: New message on chatroom %1 auto currentlyDisplayedChat = App::getInstance()->getCurrentChat();
AccessibilityHelper::announceMessage(tr("new_message_alert_accessible_name").arg(chatCore->getTitle())); auto mainWin = App::getInstance()->getMainWindow();
if (currentlyDisplayedChat && mainWin->isActive()) {
auto linphoneCurrent = currentlyDisplayedChat->mCore->getModel()->getMonitor();
if (linphoneCurrent->getIdentifier() == room->getIdentifier()) {
lInfo() << log().arg("Chat is currently displayed in the view, do not show notification");
return;
}
}
auto chatCore = ChatCore::create(room);
App::postCoreAsync([this, txt, chatCore, remoteAddress]() { App::postCoreAsync([this, txt, chatCore, remoteAddress]() {
mustBeInMainThread(getClassName()); mustBeInMainThread(getClassName());
// Accessibility alert
//: New message on chatroom %1
AccessibilityHelper::announceMessage(tr("new_message_alert_accessible_name").arg(chatCore->getTitle()));
QVariantMap map; QVariantMap map;
map["message"] = txt; map["message"] = txt;
map["remoteAddress"] = remoteAddress; map["remoteAddress"] = remoteAddress;
@ -405,11 +425,6 @@ void Notifier::notifyReceivedMessages(const std::shared_ptr<linphone::ChatRoom>
map["chat"] = QVariant::fromValue(chatCore ? new ChatGui(chatCore) : nullptr); map["chat"] = QVariant::fromValue(chatCore ? new ChatGui(chatCore) : nullptr);
CREATE_NOTIFICATION(Notifier::ReceivedMessage, map) CREATE_NOTIFICATION(Notifier::ReceivedMessage, map)
}); });
auto settings = SettingsModel::getInstance();
if (settings && !settings->dndEnabled()) {
CoreModel::getInstance()->getCore()->playLocal(
Utils::appStringToCoreString(settings->getChatNotificationSoundPath()));
}
} }
} }
/* /*

View file

@ -93,6 +93,17 @@ public:
endResetModel(); endResetModel();
} }
// This can be used to wait for the list
// to be updated before updating it again
// (when multiple calls of lUpdate, if beginResetModel has been called, wait
// for endResetModel to be called to call lUpdate again)
void setIsUpdating(bool updating) {
if (mIsUpdating != updating) {
mIsUpdating = updating;
emit isUpdatingChanged();
}
}
template <class T> template <class T>
void resetData(QList<QSharedPointer<T>> items) { void resetData(QList<QSharedPointer<T>> items) {
beginResetModel(); beginResetModel();
@ -138,6 +149,12 @@ public:
QModelIndex modelIndex = createIndex(index, 0); QModelIndex modelIndex = createIndex(index, 0);
emit dataChanged(modelIndex, modelIndex); emit dataChanged(modelIndex, modelIndex);
} }
signals:
void isUpdatingChanged();
protected:
bool mIsUpdating = false;
}; };
#endif #endif

View file

@ -1672,24 +1672,24 @@ void Utils::openChat(ChatGui *chat) {
smartShowWindow(mainWindow); smartShowWindow(mainWindow);
if (mainWindow && chat) { if (mainWindow && chat) {
emit chat->mCore->messageOpen(); emit chat->mCore->messageOpen();
auto localChatAccount = chat->mCore->getLocalAccount(); auto localChatAddress = chat->mCore->getLocalAddress();
auto accountList = App::getInstance()->getAccountList(); QMetaObject::invokeMethod(App::getInstance()->getLinphoneThread()->getThreadId(), [localChatAddress, chat] {
auto defaultAccount = accountList->getDefaultAccountCore(); auto core = CoreModel::getInstance()->getCore();
// If multiple accounts, we must switch to the correct account before opening the chatroom, otherwise, std::shared_ptr<linphone::Account> localAccount = ToolModel::findAccount(localChatAddress);
// a chat room corresponding to the wrong account could be added in the chat list if (!localAccount) return;
if (localChatAccount && localChatAccount->getIdentityAddress() != defaultAccount->getIdentityAddress()) { auto defaultAccount = core->getDefaultAccount();
connect(accountList.get(), &AccountList::defaultAccountChanged, accountList.get(), if (defaultAccount &&
[localChatAccount, accountList, chat] { localAccount->getParams()->getIdentityAddress() != defaultAccount->getParams()->getIdentityAddress()) {
auto defaultAccount = accountList->getDefaultAccountCore(); connect(CoreModel::getInstance().get(), &CoreModel::defaultAccountChanged,
if (defaultAccount->getIdentityAddress() == localChatAccount->getIdentityAddress()) { CoreModel::getInstance().get(), [chat] {
disconnect(accountList.get(), &AccountList::defaultAccountChanged, accountList.get(),
nullptr);
QMetaObject::invokeMethod(getMainWindow(), "openChat", QMetaObject::invokeMethod(getMainWindow(), "openChat",
Q_ARG(QVariant, QVariant::fromValue(chat))); Q_ARG(QVariant, QVariant::fromValue(chat)));
} });
}); core->setDefaultAccount(localAccount);
localChatAccount->lSetDefaultAccount(); } else {
} else QMetaObject::invokeMethod(mainWindow, "openChat", Q_ARG(QVariant, QVariant::fromValue(chat))); QMetaObject::invokeMethod(getMainWindow(), "openChat", Q_ARG(QVariant, QVariant::fromValue(chat)));
}
});
} }
} }

View file

@ -51,12 +51,18 @@ Control.Button {
property real borderWidth: Utils.getSizeWithScreenRatio(1) property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3) property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
// Image properties // Image properties
property var contentImageColor: style?.image?.normal || DefaultStyle.main2_600 property var contentImageColor: style?.image? style.image.normal : DefaultStyle.main2_600
property var hoveredImageColor: style?.image?.pressed || Qt.darker(contentImageColor, 1.05) property var hoveredImageColor: style?.image? style.image.pressed : Qt.darker(contentImageColor, 1.05)
property var checkedImageColor: style?.image?.checked || Qt.darker(contentImageColor, 1.1) property var checkedImageColor: style?.image? style.image.checked : Qt.darker(contentImageColor, 1.1)
property var pressedImageColor: style?.image?.pressed || Qt.darker(contentImageColor, 1.1) property var pressedImageColor: style?.image? style.image.pressed : Qt.darker(contentImageColor, 1.1)
icon.source: style?.iconSource || "" icon.source: style?.iconSource || ""
property color colorizationColor: mainItem.checkable && mainItem.checked ? mainItem.checkedImageColor : mainItem.pressed ? mainItem.pressedImageColor : mainItem.hovered ? mainItem.hoveredImageColor : mainItem.contentImageColor property color colorizationColor: checkable && checked
? checkedImageColor
: pressed
? pressedImageColor
: hovered
? hoveredImageColor
: contentImageColor
// Size properties // Size properties
spacing: Utils.getSizeWithScreenRatio(5) spacing: Utils.getSizeWithScreenRatio(5)
property real radius: Math.ceil(height / 2) property real radius: Math.ceil(height / 2)

View file

@ -142,7 +142,7 @@ Control.Control {
// RectangleTest{anchors.fill: parent} // RectangleTest{anchors.fill: parent}
width: sendingAreaFlickable.width width: sendingAreaFlickable.width
height: implicitHeight// sendingAreaFlickable.height height: implicitHeight// sendingAreaFlickable.height
textFormat: TextEdit.AutoText textFormat: TextEdit.PlainText
onTextChanged: { onTextChanged: {
mainItem.text = text mainItem.text = text
} }
@ -321,4 +321,4 @@ Control.Control {
PropertyChanges { target: hoverContent; visible: true } PropertyChanges { target: hoverContent; visible: true }
} }
} }
} }

View file

@ -41,6 +41,10 @@ AbstractMainPage {
if (listStackView.depth === 0 || listStackView.currentItem.objectName !== "chatListItem") listStackView.push(chatListItem) if (listStackView.depth === 0 || listStackView.currentItem.objectName !== "chatListItem") listStackView.push(chatListItem)
} }
} }
AppCpp.currentChat = visible ? selectedChatGui : null
}
onVisibleChanged: {
AppCpp.currentChat = visible ? selectedChatGui : null
} }
rightPanelStackView.initialItem: currentChatComp rightPanelStackView.initialItem: currentChatComp