diff --git a/Linphone/core/chat/ChatCore.cpp b/Linphone/core/chat/ChatCore.cpp index 03abe3593..81771150a 100644 --- a/Linphone/core/chat/ChatCore.cpp +++ b/Linphone/core/chat/ChatCore.cpp @@ -51,7 +51,7 @@ ChatCore::ChatCore(const std::shared_ptr &chatRoom) : QObjec if (chatRoom->hasCapability((int)linphone::ChatRoom::Capabilities::Basic)) { mTitle = ToolModel::getDisplayName(chatRoomAddress); mAvatarUri = ToolModel::getDisplayName(chatRoomAddress); - mPeerAddress = Utils::coreStringToAppString(chatRoomAddress->asStringUriOnly()); + mParticipantAddress = Utils::coreStringToAppString(chatRoomAddress->asStringUriOnly()); mIsGroupChat = false; mIsBasic = true; mConferenceJoined = true; @@ -65,7 +65,7 @@ ChatCore::ChatCore(const std::shared_ptr &chatRoom) : QObjec mAvatarUri = ToolModel::getDisplayName(peer->getAddress()->clone()); if (participants.size() == 1) { auto peerAddress = peer->getAddress(); - if (peerAddress) mPeerAddress = Utils::coreStringToAppString(peerAddress->asStringUriOnly()); + if (peerAddress) mParticipantAddress = Utils::coreStringToAppString(peerAddress->asStringUriOnly()); } } mIsGroupChat = false; @@ -90,24 +90,24 @@ ChatCore::ChatCore(const std::shared_ptr &chatRoom) : QObjec static_cast(linphone::ChatRoom::HistoryFilter::InfoNoDevice) : static_cast(linphone::ChatRoom::HistoryFilter::ChatMessage); - auto history = chatRoom->getHistory(0, filter); - std::list> lHistory; - for (auto &eventLog : history) { - lHistory.push_back(eventLog); - } - QList> eventList; - for (auto &event : lHistory) { - auto eventLogCore = EventLogCore::create(event); - eventList.append(eventLogCore); - if (auto isMessage = eventLogCore->getChatMessageCore()) { - for (auto content : isMessage->getChatMessageContentList()) { - if (content->isFile() && !content->isVoiceRecording()) { - mFileList.append(content); - } - } - } - } - resetEventLogList(eventList); + // auto history = chatRoom->getHistory(0, filter); + // std::list> lHistory; + // for (auto &eventLog : history) { + // lHistory.push_back(eventLog); + // } + // QList> eventList; + // for (auto &event : lHistory) { + // auto eventLogCore = EventLogCore::create(event); + // eventList.append(eventLogCore); + // if (auto isMessage = eventLogCore->getChatMessageCore()) { + // for (auto content : isMessage->getChatMessageContentList()) { + // if (content->isFile() && !content->isVoiceRecording()) { + // mFileList.append(content); + // } + // } + // } + // } + // resetEventLogList(eventList); mIdentifier = Utils::coreStringToAppString(chatRoom->getIdentifier()); mChatRoomState = LinphoneEnums::fromLinphone(chatRoom->getState()); mIsEncrypted = chatRoom->hasCapability((int)linphone::ChatRoom::Capabilities::Encrypted); @@ -122,15 +122,15 @@ ChatCore::ChatCore(const std::shared_ptr &chatRoom) : QObjec connect(this, &ChatCore::eventRemoved, this, &ChatCore::lUpdateLastMessage); auto resetFileListLambda = [this] { QList> fileList; - for (auto &eventLogCore : mEventLogList) { - if (auto isMessage = eventLogCore->getChatMessageCore()) { - for (auto content : isMessage->getChatMessageContentList()) { - if (content->isFile() && !content->isVoiceRecording()) { - fileList.append(content); - } - } - } - } + // for (auto &eventLogCore : mEventLogList) { + // if (auto isMessage = eventLogCore->getChatMessageCore()) { + // for (auto content : isMessage->getChatMessageContentList()) { + // if (content->isFile() && !content->isVoiceRecording()) { + // fileList.append(content); + // } + // } + // } + // } resetFileList(fileList); }; connect(this, &ChatCore::eventListChanged, this, resetFileListLambda); @@ -172,7 +172,7 @@ void ChatCore::setSelf(QSharedPointer me) { &ChatCore::lLeave, [this]() { mChatModelConnection->invokeToModel([this]() { mChatModel->leave(); }); }); mChatModelConnection->makeConnectToModel(&ChatModel::historyDeleted, [this]() { mChatModelConnection->invokeToCore([this]() { - clearEventLogList(); + emit eventListCleared(); //: Deleted Utils::showInformationPopup(tr("info_toast_deleted_title"), //: Message history has been deleted @@ -221,7 +221,8 @@ void ChatCore::setSelf(QSharedPointer me) { avatarUri = ToolModel::getDisplayName(peer->getAddress()->clone()); if (linParticipants.size() == 1) { auto peerAddress = peer->getAddress(); - if (peerAddress) mPeerAddress = Utils::coreStringToAppString(peerAddress->asStringUriOnly()); + if (peerAddress) + mParticipantAddress = Utils::coreStringToAppString(peerAddress->asStringUriOnly()); } } mChatModelConnection->invokeToCore([this, title, avatarUri]() { @@ -242,7 +243,7 @@ void ChatCore::setSelf(QSharedPointer me) { qDebug() << "EVENT LOG RECEIVED IN CHATROOM" << mChatModel->getTitle(); auto event = EventLogCore::create(eventLog); if (event->isHandled()) { - mChatModelConnection->invokeToCore([this, event]() { appendEventLogToEventLogList(event); }); + mChatModelConnection->invokeToCore([this, event]() { emit eventsInserted({event}); }); } mChatModelConnection->invokeToCore([this, event]() { emit lUpdateLastUpdatedTime(); }); }); @@ -259,7 +260,7 @@ void ChatCore::setSelf(QSharedPointer me) { list.push_back(event); } mChatModelConnection->invokeToCore([this, list]() { - appendEventLogsToEventLogList(list); + emit eventsInserted(list); emit lUpdateUnreadCount(); emit lUpdateLastUpdatedTime(); }); @@ -309,7 +310,7 @@ void ChatCore::setSelf(QSharedPointer me) { &ChatModel::chatMessageSending, [this](const std::shared_ptr &chatRoom, const std::shared_ptr &eventLog) { auto event = EventLogCore::create(eventLog); - mChatModelConnection->invokeToCore([this, event]() { appendEventLogToEventLogList(event); }); + mChatModelConnection->invokeToCore([this, event]() { emit eventsInserted({event}); }); }); mChatModelConnection->makeConnectToCore( &ChatCore::lCompose, [this]() { mChatModelConnection->invokeToModel([this]() { mChatModel->compose(); }); }); @@ -405,7 +406,7 @@ void ChatCore::setSelf(QSharedPointer me) { }); mCoreModelConnection = SafeConnection::create(me, CoreModel::getInstance()); - if (!ToolModel::findFriendByAddress(mPeerAddress)) + if (!ToolModel::findFriendByAddress(mParticipantAddress)) mCoreModelConnection->makeConnectToModel(&CoreModel::friendCreated, [this](std::shared_ptr f) { updateInfo(f); }); mCoreModelConnection->makeConnectToModel(&CoreModel::friendUpdated, @@ -459,8 +460,8 @@ QString ChatCore::getIdentifier() const { return mIdentifier; } -QString ChatCore::getPeerAddress() const { - return mPeerAddress; +QString ChatCore::getParticipantAddress() const { + return mParticipantAddress; } QString ChatCore::getChatRoomAddress() const { @@ -532,72 +533,6 @@ void ChatCore::setUnreadMessagesCount(int count) { } } -QList> ChatCore::getEventLogList() const { - return mEventLogList; -} - -void ChatCore::resetEventLogList(QList> list) { - for (auto &e : mEventLogList) { - disconnect(e.get()); - } - for (auto &e : list) { - if (auto message = e->getChatMessageCore()) { - connect(message.get(), &ChatMessageCore::isReadChanged, this, [this] { emit lUpdateUnreadCount(); }); - } - } - mEventLogList = list; - emit eventListChanged(); -} - -void ChatCore::appendEventLogsToEventLogList(QList> list) { - int nbAdded = 0; - for (auto &e : list) { - auto it = std::find_if(mEventLogList.begin(), mEventLogList.end(), [e](QSharedPointer event) { - return e->getEventLogId() == event->getEventLogId(); - }); - if (it == mEventLogList.end()) { - if (auto message = e->getChatMessageCore()) - connect(message.get(), &ChatMessageCore::isReadChanged, this, [this] { emit lUpdateUnreadCount(); }); - mEventLogList.append(e); - ++nbAdded; - } - } - if (nbAdded > 0) emit eventsInserted(list); -} - -void ChatCore::appendEventLogToEventLogList(QSharedPointer e) { - if (mEventLogList.contains(e)) return; - auto it = std::find_if(mEventLogList.begin(), mEventLogList.end(), [e](QSharedPointer event) { - return e->getEventLogId() == event->getEventLogId(); - }); - if (it == mEventLogList.end()) { - if (auto message = e->getChatMessageCore()) - connect(message.get(), &ChatMessageCore::isReadChanged, this, [this] { emit lUpdateUnreadCount(); }); - mEventLogList.append(e); - emit eventsInserted({e}); - } -} - -void ChatCore::removeEventLogsFromEventLogList(QList> list) { - int nbRemoved = 0; - for (auto &e : list) { - if (mEventLogList.contains(e)) { - if (auto message = e->getChatMessageCore()) disconnect(message.get()); - mEventLogList.removeAll(e); - ++nbRemoved; - } - } - if (nbRemoved > 0) emit eventRemoved(); -} - -void ChatCore::clearEventLogList() { - for (auto &e : mEventLogList) { - disconnect(e.get()); - } - mEventLogList.clear(); - emit eventListChanged(); -} - QString ChatCore::getComposingName() const { return mComposingName; } @@ -723,7 +658,7 @@ QSharedPointer ChatCore::getLocalAccount() const { void ChatCore::updateInfo(const std::shared_ptr &updatedFriend, bool isRemoval) { mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); - auto fAddress = ToolModel::interpretUrl(mPeerAddress); + auto fAddress = ToolModel::interpretUrl(mParticipantAddress); bool isThisFriend = mFriendModel && updatedFriend == mFriendModel->getFriend(); if (!isThisFriend) for (auto f : updatedFriend->getAddresses()) { @@ -753,7 +688,8 @@ void ChatCore::updateInfo(const std::shared_ptr &updatedFriend mAvatarUri = ToolModel::getDisplayName(peer->getAddress()->clone()); if (participants.size() == 1) { auto peerAddress = peer->getAddress(); - if (peerAddress) mPeerAddress = Utils::coreStringToAppString(peerAddress->asStringUriOnly()); + if (peerAddress) + mParticipantAddress = Utils::coreStringToAppString(peerAddress->asStringUriOnly()); } } } else if (mChatModel->hasCapability((int)linphone::ChatRoom::Capabilities::Conference)) { diff --git a/Linphone/core/chat/ChatCore.hpp b/Linphone/core/chat/ChatCore.hpp index 2c69b6e96..b0ee6b36a 100644 --- a/Linphone/core/chat/ChatCore.hpp +++ b/Linphone/core/chat/ChatCore.hpp @@ -42,7 +42,7 @@ class ChatCore : public QObject, public AbstractObject { public: Q_PROPERTY(QString title READ getTitle WRITE setTitle NOTIFY titleChanged) Q_PROPERTY(QString identifier READ getIdentifier CONSTANT) - Q_PROPERTY(QString peerAddress READ getPeerAddress CONSTANT) + Q_PROPERTY(QString peerAddress READ getParticipantAddress CONSTANT) Q_PROPERTY(QString chatRoomAddress READ getChatRoomAddress CONSTANT) Q_PROPERTY(QString avatarUri READ getAvatarUri WRITE setAvatarUri NOTIFY avatarUriChanged) Q_PROPERTY(QDateTime lastUpdatedTime READ getLastUpdatedTime WRITE setLastUpdatedTime NOTIFY lastUpdatedTimeChanged) @@ -118,7 +118,7 @@ public: void setUnreadMessagesCount(int count); QString getChatRoomAddress() const; - QString getPeerAddress() const; + QString getParticipantAddress() const; bool getMeAdmin() const; void setMeAdmin(bool admin); @@ -127,12 +127,11 @@ public: void setIsSecured(bool secured); bool computeSecuredStatus() const; - QList> getEventLogList() const; - void resetEventLogList(QList> list); - void appendEventLogToEventLogList(QSharedPointer event); - void appendEventLogsToEventLogList(QList> list); - void removeEventLogsFromEventLogList(QList> list); - void clearEventLogList(); + // void resetEventLogList(QList> list); + // void appendEventLogToEventLogList(QSharedPointer event); + // void appendEventLogsToEventLogList(QList> list); + // void removeEventLogsFromEventLogList(QList> list); + // void clearEventLogList(); QString getAvatarUri() const; void setAvatarUri(QString avatarUri); @@ -163,6 +162,7 @@ signals: void titleChanged(QString title); void unreadMessagesCountChanged(int count); void eventListChanged(); + void eventListCleared(); void eventsInserted(QList> list); void eventRemoved(); void avatarUriChanged(); @@ -203,7 +203,7 @@ signals: private: QString id; QDateTime mLastUpdatedTime; - QString mPeerAddress; + QString mParticipantAddress; QString mChatRoomAddress; QString mTitle; QString mIdentifier; @@ -229,7 +229,6 @@ private: LinphoneEnums::ChatRoomState mChatRoomState; std::shared_ptr mChatModel; QSharedPointer mLastMessage; - QList> mEventLogList; QSharedPointer mLocalAccount; std::shared_ptr mFriendModel; QSharedPointer> mChatModelConnection; diff --git a/Linphone/core/chat/ChatList.cpp b/Linphone/core/chat/ChatList.cpp index e34294eab..e7cfd43fd 100644 --- a/Linphone/core/chat/ChatList.cpp +++ b/Linphone/core/chat/ChatList.cpp @@ -81,8 +81,8 @@ void ChatList::connectItem(QSharedPointer chat) { void ChatList::setSelf(QSharedPointer me) { mModelConnection = SafeConnection::create(me, CoreModel::getInstance()); mModelConnection->makeConnectToCore(&ChatList::lUpdate, [this]() { - clearData(); beginResetModel(); + mList.clear(); mModelConnection->invokeToModel([this]() { mustBeInLinphoneThread(getClassName()); // Avoid copy to lambdas @@ -95,6 +95,7 @@ void ChatList::setSelf(QSharedPointer me) { chats->push_back(model); } mModelConnection->invokeToCore([this, chats]() { + mustBeInMainThread(getClassName()); for (auto &chat : getSharedList()) { if (chat) { disconnect(chat.get(), &ChatCore::deleted, this, nullptr); @@ -106,7 +107,6 @@ void ChatList::setSelf(QSharedPointer me) { for (auto &chat : *chats) { connectItem(chat); } - mustBeInMainThread(getClassName()); add(*chats); endResetModel(); delete chats; @@ -117,27 +117,16 @@ void ChatList::setSelf(QSharedPointer me) { mModelConnection->makeConnectToModel( &CoreModel::defaultAccountChanged, [this](std::shared_ptr core, std::shared_ptr account) { lUpdate(); }); + auto addChatToList = [this](const std::shared_ptr &core, const std::shared_ptr &room, const std::shared_ptr &message) { mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); if (!message) return; - auto receiverAddress = message->getToAddress(); - if (!receiverAddress) { - qWarning() << log().arg("Receiver account has no address, return"); + if (room->getAccount() != core->getDefaultAccount()) { + qWarning() << log().arg("Chat room does not refer to current account, return"); return; } - auto defaultAddress = core->getDefaultAccount()->getContactAddress(); - if (defaultAddress && !defaultAddress->weakEqual(receiverAddress)) { - qDebug() << log().arg("Receiver account is not the default one, do not add chat to list"); - return; - } - auto senderAddress = message->getFromAddress(); - if (defaultAddress && defaultAddress->weakEqual(senderAddress)) { - qDebug() << log().arg("Sender account is the default one, do not add chat to list"); - return; - } - auto chatCore = ChatCore::create(room); mModelConnection->invokeToCore([this, chatCore] { auto chatList = getSharedList(); @@ -191,8 +180,7 @@ int ChatList::findChatIndex(ChatGui *chatGui) { return it == chatList.end() ? -1 : std::distance(chatList.begin(), it); } -void ChatList::addChatInList(ChatGui *chatGui) { - auto chatCore = chatGui->mCore; +void ChatList::addChatInList(QSharedPointer chatCore) { auto chatList = getSharedList(); auto it = std::find_if(chatList.begin(), chatList.end(), [chatCore](const QSharedPointer item) { return item && chatCore && item->getModel() && chatCore->getModel() && diff --git a/Linphone/core/chat/ChatList.hpp b/Linphone/core/chat/ChatList.hpp index 3623b02f9..b6fad074c 100644 --- a/Linphone/core/chat/ChatList.hpp +++ b/Linphone/core/chat/ChatList.hpp @@ -42,7 +42,7 @@ public: void connectItem(QSharedPointer chat); int findChatIndex(ChatGui *chat); - void addChatInList(ChatGui *chatGui); + void addChatInList(QSharedPointer chatCore); virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; signals: diff --git a/Linphone/core/chat/ChatProxy.cpp b/Linphone/core/chat/ChatProxy.cpp index 47d683415..12a82087e 100644 --- a/Linphone/core/chat/ChatProxy.cpp +++ b/Linphone/core/chat/ChatProxy.cpp @@ -69,8 +69,8 @@ int ChatProxy::findChatIndex(ChatGui *chatGui) { void ChatProxy::addChatInList(ChatGui *chatGui) { auto chatList = getListModel(); - if (chatList) { - chatList->addChatInList(chatGui); + if (chatList && chatGui) { + chatList->addChatInList(chatGui->mCore); } } diff --git a/Linphone/core/chat/files/ChatMessageFileList.cpp b/Linphone/core/chat/files/ChatMessageFileList.cpp index 10b97bcfa..ea311c0f3 100644 --- a/Linphone/core/chat/files/ChatMessageFileList.cpp +++ b/Linphone/core/chat/files/ChatMessageFileList.cpp @@ -32,6 +32,7 @@ DEFINE_ABSTRACT_OBJECT(ChatMessageFileList) QSharedPointer ChatMessageFileList::create() { auto model = QSharedPointer(new ChatMessageFileList(), &QObject::deleteLater); + model->setSelf(model); model->moveToThread(App::getInstance()->thread()); return model; } @@ -46,24 +47,77 @@ ChatMessageFileList::~ChatMessageFileList() { mList.clear(); } +void ChatMessageFileList::setSelf(QSharedPointer me) { + mCoreModelConnection = SafeConnection::create(me, CoreModel::getInstance()); + mCoreModelConnection->makeConnectToCore(&ChatMessageFileList::lUpdate, [this]() { + mustBeInMainThread(log().arg(Q_FUNC_INFO)); + beginResetModel(); + mList.clear(); + if (!mChat) { + endResetModel(); + return; + } + auto chatModel = mChat->getModel(); + if (!chatModel) { + endResetModel(); + return; + } + mCoreModelConnection->invokeToModel([this, chatModel]() { + mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); + std::list> medias; + std::list> docs; + QList> *contents = + new QList>(); + if (mFilterType == (int)FilterContentType::Medias) { + medias = chatModel->getSharedMedias(); + } else if (mFilterType == (int)FilterContentType::Documents) { + docs = chatModel->getSharedDocuments(); + } else { + medias = chatModel->getSharedMedias(); + docs = chatModel->getSharedDocuments(); + } + for (auto it : medias) { + auto model = ChatMessageContentCore::create(it, nullptr); + contents->push_back(model); + } + for (auto it : docs) { + auto model = ChatMessageContentCore::create(it, nullptr); + contents->push_back(model); + } + mCoreModelConnection->invokeToCore([this, contents] { + for (auto i : *contents) + mList << i.template objectCast(); + endResetModel(); + }); + }); + }); +} + QSharedPointer ChatMessageFileList::getChatCore() const { return mChat; } void ChatMessageFileList::setChatCore(QSharedPointer chatCore) { if (mChat != chatCore) { - if (mChat) disconnect(mChat.get()); + // if (mChat) disconnect(mChat.get()); mChat = chatCore; - auto lUpdate = [this] { - auto fileList = mChat->getFileList(); - resetData(fileList); - }; - if (mChat) connect(mChat.get(), &ChatCore::fileListChanged, this, lUpdate); + // if (mChat) connect(mChat.get(), &ChatCore::fileListChanged, this, lUpdate); lUpdate(); emit chatChanged(); } } +int ChatMessageFileList::getFilterType() const { + return mFilterType; +} + +void ChatMessageFileList::setFilterType(int filterType) { + if (mFilterType != filterType) { + mFilterType = filterType; + lUpdate(); + } +} + QVariant ChatMessageFileList::data(const QModelIndex &index, int role) const { int row = index.row(); if (!index.isValid() || row < 0 || row >= mList.count()) return QVariant(); diff --git a/Linphone/core/chat/files/ChatMessageFileList.hpp b/Linphone/core/chat/files/ChatMessageFileList.hpp index 7ad069ef8..e1b67ae2b 100644 --- a/Linphone/core/chat/files/ChatMessageFileList.hpp +++ b/Linphone/core/chat/files/ChatMessageFileList.hpp @@ -32,20 +32,29 @@ class ChatMessageFileList : public ListProxy, public AbstractObject { Q_OBJECT public: + enum class FilterContentType { All = 0, Medias = 1, Documents = 2 }; static QSharedPointer create(); ChatMessageFileList(QObject *parent = Q_NULLPTR); ~ChatMessageFileList(); + void setSelf(QSharedPointer me); + QSharedPointer getChatCore() const; void setChatCore(QSharedPointer chatCore); + int getFilterType() const; + void setFilterType(int filterType); virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; signals: void chatChanged(); + void lUpdate(); + void filterTypeChanged(); private: + int mFilterType; QSharedPointer mChat; + QSharedPointer> mCoreModelConnection; DECLARE_ABSTRACT_OBJECT }; diff --git a/Linphone/core/chat/message/EventLogList.cpp b/Linphone/core/chat/message/EventLogList.cpp index 7486c5c05..bdfec0544 100644 --- a/Linphone/core/chat/message/EventLogList.cpp +++ b/Linphone/core/chat/message/EventLogList.cpp @@ -59,9 +59,21 @@ QSharedPointer EventLogList::getChatCore() const { return mChatCore; } +void EventLogList::disconnectItem(const QSharedPointer &item) { + auto message = item->getChatMessageCore(); + if (message) { + disconnect(message.get(), &ChatMessageCore::isReadChanged, this, nullptr); + disconnect(message.get(), &ChatMessageCore::deleted, this, nullptr); + disconnect(message.get(), &ChatMessageCore::ephemeralDurationChanged, this, nullptr); + } +} + void EventLogList::connectItem(const QSharedPointer &item) { auto message = item->getChatMessageCore(); if (message) { + connect(message.get(), &ChatMessageCore::isReadChanged, this, [this] { + if (mChatCore) emit mChatCore->lUpdateUnreadCount(); + }); connect(message.get(), &ChatMessageCore::deleted, this, [this, item] { if (mChatCore) emit mChatCore->lUpdateLastMessage(); remove(item); @@ -83,6 +95,7 @@ void EventLogList::setChatCore(QSharedPointer core) { mChatCore = core; if (mChatCore) { connect(mChatCore.get(), &ChatCore::eventListChanged, this, &EventLogList::lUpdate); + connect(mChatCore.get(), &ChatCore::eventListCleared, this, [this] { resetData(); }); connect(mChatCore.get(), &ChatCore::eventsInserted, this, [this](QList> list) { auto eventsList = getSharedList(); for (auto &event : list) { @@ -98,8 +111,8 @@ void EventLogList::setChatCore(QSharedPointer core) { } }); } - emit eventChanged(); lUpdate(); + emit chatGuiChanged(); } } @@ -150,22 +163,45 @@ void EventLogList::findChatMessageWithFilter(QString filter, } void EventLogList::setSelf(QSharedPointer me) { - connect(this, &EventLogList::lUpdate, this, [this]() { - resetData(); - emit listAboutToBeReset(); - for (auto &event : getSharedList()) { - auto message = event->getChatMessageCore(); - if (message) { - disconnect(message.get(), &ChatMessageCore::ephemeralDurationChanged, this, nullptr); - disconnect(message.get(), &ChatMessageCore::deleted, this, nullptr); + mCoreModelConnection = SafeConnection::create(me, CoreModel::getInstance()); + + mCoreModelConnection->makeConnectToCore(&EventLogList::lUpdate, [this]() { + mustBeInMainThread(log().arg(Q_FUNC_INFO)); + beginResetModel(); + mList.clear(); + if (!mChatCore) { + endResetModel(); + return; + } + auto chatModel = mChatCore->getModel(); + if (!chatModel) { + endResetModel(); + return; + } + mCoreModelConnection->invokeToModel([this, chatModel]() { + mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); + auto linphoneLogs = chatModel->getHistory(); + QList> *events = new QList>(); + for (auto it : linphoneLogs) { + auto model = EventLogCore::create(it); + events->push_back(model); } - } - if (!mChatCore) return; - auto events = mChatCore->getEventLogList(); - for (auto &event : events) { - connectItem(event); - } - resetData(events); + mCoreModelConnection->invokeToCore([this, events] { + for (auto &event : getSharedList()) { + auto message = event->getChatMessageCore(); + if (message) { + disconnect(message.get(), &ChatMessageCore::ephemeralDurationChanged, this, nullptr); + disconnect(message.get(), &ChatMessageCore::deleted, this, nullptr); + } + } + for (auto &event : *events) { + connectItem(event); + } + for (auto i : *events) + mList << i.template objectCast(); + endResetModel(); + }); + }); }); connect(this, &EventLogList::filterChanged, [this](QString filter) { diff --git a/Linphone/core/chat/message/EventLogList.hpp b/Linphone/core/chat/message/EventLogList.hpp index 8b1b37592..94b2e04e8 100644 --- a/Linphone/core/chat/message/EventLogList.hpp +++ b/Linphone/core/chat/message/EventLogList.hpp @@ -46,6 +46,7 @@ public: void setChatGui(ChatGui *chat); void connectItem(const QSharedPointer &item); + void disconnectItem(const QSharedPointer &item); int findFirstUnreadIndex(); @@ -61,15 +62,16 @@ public: signals: void lUpdate(); void filterChanged(QString filter); - void eventChanged(); void eventInserted(int index, EventLogGui *message); void messageWithFilterFound(int index); void listAboutToBeReset(); + void chatGuiChanged(); private: QString mFilter; QSharedPointer mChatCore; - QSharedPointer> mModelConnection; + QSharedPointer> mChatModelConnection; + QSharedPointer> mCoreModelConnection; DECLARE_ABSTRACT_OBJECT }; diff --git a/Linphone/core/chat/message/EventLogProxy.cpp b/Linphone/core/chat/message/EventLogProxy.cpp index 1f0e26d57..c6a7a5827 100644 --- a/Linphone/core/chat/message/EventLogProxy.cpp +++ b/Linphone/core/chat/message/EventLogProxy.cpp @@ -41,8 +41,8 @@ void EventLogProxy::setSourceModel(QAbstractItemModel *model) { } auto newEventLogList = dynamic_cast(model); if (newEventLogList) { - connect(newEventLogList, &EventLogList::eventChanged, this, &EventLogProxy::eventChanged); connect(newEventLogList, &EventLogList::listAboutToBeReset, this, &EventLogProxy::listAboutToBeReset); + connect(newEventLogList, &EventLogList::chatGuiChanged, this, &EventLogProxy::chatGuiChanged); connect(newEventLogList, &EventLogList::eventInserted, this, [this, newEventLogList](int index, EventLogGui *event) { invalidate(); diff --git a/Linphone/core/chat/message/EventLogProxy.hpp b/Linphone/core/chat/message/EventLogProxy.hpp index 164cbb615..c9a57dbb1 100644 --- a/Linphone/core/chat/message/EventLogProxy.hpp +++ b/Linphone/core/chat/message/EventLogProxy.hpp @@ -31,7 +31,7 @@ class ChatGui; class EventLogProxy : public LimitProxy, public AbstractObject { Q_OBJECT - Q_PROPERTY(ChatGui *chatGui READ getChatGui WRITE setChatGui NOTIFY eventChanged) + Q_PROPERTY(ChatGui *chatGui READ getChatGui WRITE setChatGui NOTIFY chatGuiChanged) public: DECLARE_SORTFILTER_CLASS() @@ -52,10 +52,10 @@ public: Q_INVOKABLE void findIndexCorrespondingToFilter(int startIndex, bool forward = true, bool isFirstResearch = true); signals: - void eventChanged(); void eventInserted(int index, EventLogGui *message); void indexWithFilterFound(int index); void listAboutToBeReset(); + void chatGuiChanged(); protected: QSharedPointer mList; diff --git a/Linphone/core/conference/ConferenceInfoList.cpp b/Linphone/core/conference/ConferenceInfoList.cpp index 53f297e91..9042c22f0 100644 --- a/Linphone/core/conference/ConferenceInfoList.cpp +++ b/Linphone/core/conference/ConferenceInfoList.cpp @@ -60,16 +60,22 @@ void ConferenceInfoList::setSelf(QSharedPointer me) { mCoreModelConnection->makeConnectToCore(&ConferenceInfoList::lUpdate, [this]() { mCoreModelConnection->invokeToModel([this]() { - QList> *items = new QList>(); mustBeInLinphoneThread(getClassName()); + beginResetModel(); + mList.clear(); + QList> *items = new QList>(); auto defaultAccount = CoreModel::getInstance()->getCore()->getDefaultAccount(); setAccountConnected(defaultAccount && defaultAccount->getState() == linphone::RegistrationState::Ok); if (!defaultAccount || !mAccountConnected) { + endResetModel(); return; } std::list> conferenceInfos = defaultAccount->getConferenceInformationList(); - if (conferenceInfos.empty()) return; + if (conferenceInfos.empty()) { + endResetModel(); + return; + } items->push_back(nullptr); // Add Dummy conference for today for (auto conferenceInfo : conferenceInfos) { if (conferenceInfo->getState() == linphone::ConferenceInfo::State::Cancelled) { @@ -86,8 +92,9 @@ void ConferenceInfoList::setSelf(QSharedPointer me) { mustBeInMainThread(getClassName()); for (auto &item : *items) { connectItem(item); + mList << item.template objectCast(); } - resetData(*items); + endResetModel(); delete items; }); }); diff --git a/Linphone/data/languages/de.ts b/Linphone/data/languages/de.ts index 9f954a7bd..375a3e0ae 100644 --- a/Linphone/data/languages/de.ts +++ b/Linphone/data/languages/de.ts @@ -1852,65 +1852,65 @@ ChatListView - + chat_message_is_writing_info %1 is writing… - + chat_message_draft_sending_text - + chat_room_delete "Delete" - + chat_room_mute - + chat_room_unmute "Mute" - + chat_room_mark_as_read "Mark as read" - + chat_room_leave "leave" - + chat_list_leave_chat_popup_title leave the conversation ? - + chat_list_leave_chat_popup_message You will not be able to send or receive messages in this conversation anymore. Do You want to continue ? - + chat_list_delete_chat_popup_title Delete the conversation ? - + chat_list_delete_chat_popup_message This conversation and all its messages will be deleted. Do You want to continue ? @@ -2153,45 +2153,45 @@ Error ChatMessagesListView - - + + popup_info_find_message_title Find message - + info_popup_no_result_message No result found - + info_popup_first_result_message First result reached - + info_popup_last_result_message Last result reached - + chat_message_list_encrypted_header_title End to end encrypted chat - + chat_message_list_encrypted_header_message Les messages de cette conversation sont chiffrés de bout en bout. Seul votre correspondant peut les déchiffrer. - + chat_message_is_writing_info %1 is writing… @@ -2212,79 +2212,79 @@ Error - + chat_dialog_delete_chat_title Supprimer la conversation ? - + chat_dialog_delete_chat_message "La conversation et tous ses messages seront supprimés." - + chat_list_title "Conversations" - + menu_mark_all_as_read "mark all as read" - + chat_search_in_history "Rechercher une conversation" - + list_filter_no_result_found "Aucun résultat…" - + chat_list_empty_history "Aucune conversation dans votre historique" - + chat_action_start_new_chat "New chat" - + chat_start_group_chat_title "Nouveau groupe" - + chat_action_start_group_chat "Créer" - - + + information_popup_error_title - + group_chat_error_must_have_name "Un nom doit être donné au groupe - + group_call_error_not_connected "Vous n'etes pas connecté" Sie sind nicht verbunden @@ -4029,13 +4029,13 @@ Error MeetingListView - + meeting_info_cancelled "Réunion annulée" Besprechung abgesagt - + meetings_list_no_meeting_for_today "Aucune réunion aujourd'hui" Heute keine Besprechungen @@ -4300,6 +4300,21 @@ Error + + MessageSharedFilesInfos + + + no_shared_medias + No media + + + + + no_shared_documents + No document + + + MultimediaSettings @@ -5094,31 +5109,31 @@ Pour les activer dans un projet commercial, merci de nous contacter. Start a group call ? - + reply_to_label Reply to %1 - + shared_medias_title Shared medias - + shared_documents_title Shared documents - + forward_to_title Forward to… - + conversations_title Conversations diff --git a/Linphone/data/languages/en.ts b/Linphone/data/languages/en.ts index 62a999369..57f7502df 100644 --- a/Linphone/data/languages/en.ts +++ b/Linphone/data/languages/en.ts @@ -1814,65 +1814,65 @@ ChatListView - + chat_message_is_writing_info %1 is writing… %1 is writing… - + chat_message_draft_sending_text Draft : %1 - + chat_room_delete "Delete" Delete - + chat_room_mute Mute - + chat_room_unmute "Mute" Unmute - + chat_room_mark_as_read "Mark as read" Mark as read - + chat_room_leave "leave" Leave - + chat_list_leave_chat_popup_title leave the conversation ? Leave the conversation ? - + chat_list_leave_chat_popup_message You will not be able to send or receive messages in this conversation anymore. Do You want to continue ? You will not be able to send or receive messages in this conversation anymore. Do You want to continue ? - + chat_list_delete_chat_popup_title Delete the conversation ? Delete the conversation ? - + chat_list_delete_chat_popup_message This conversation and all its messages will be deleted. Do You want to continue ? This conversation and all its messages will be deleted. Do You want to continue ? @@ -2115,38 +2115,38 @@ Error ChatMessagesListView - - + + popup_info_find_message_title Find message Find message - + info_popup_no_result_message No result found No result found - + info_popup_first_result_message First result reached First result reached - + info_popup_last_result_message Last result reached Last result reached - + chat_message_list_encrypted_header_title End to end encrypted chat End to end encrypted chat - + chat_message_list_encrypted_header_message Les messages de cette conversation sont chiffrés de bout en bout. Seul votre correspondant peut les déchiffrer. @@ -2154,7 +2154,7 @@ Error Only your correspondent can decrypt them. - + chat_message_is_writing_info %1 is writing… %1 is writing… @@ -2175,79 +2175,79 @@ Only your correspondent can decrypt them. No conversation - + chat_dialog_delete_chat_title Supprimer la conversation ? Delete conversation ? - + chat_dialog_delete_chat_message "La conversation et tous ses messages seront supprimés." This conversation and all its messages will be deleted. - + chat_list_title "Conversations" Conversations - + menu_mark_all_as_read "mark all as read" Mark all as read - + chat_search_in_history "Rechercher une conversation" Search for a chat - + list_filter_no_result_found "Aucun résultat…" No result… - + chat_list_empty_history "Aucune conversation dans votre historique" No conversation in history - + chat_action_start_new_chat "New chat" New conversation - + chat_start_group_chat_title "Nouveau groupe" New group - + chat_action_start_group_chat "Créer" Create - - + + information_popup_error_title Error - + group_chat_error_must_have_name "Un nom doit être donné au groupe A name must be set for the group - + group_call_error_not_connected "Vous n'etes pas connecté" You are not connected @@ -3939,13 +3939,13 @@ Expiration : %1 MeetingListView - + meeting_info_cancelled "Réunion annulée" Meeting canceled - + meetings_list_no_meeting_for_today "Aucune réunion aujourd'hui" No meeting for today @@ -4206,6 +4206,21 @@ Expiration : %1 Click to delete + + MessageSharedFilesInfos + + + no_shared_medias + No media + No media + + + + no_shared_documents + No document + No document + + MultimediaSettings @@ -4983,31 +4998,31 @@ To enable them in a commercial project, please contact us. Start a group call ? - + reply_to_label Reply to %1 Reply to %1 - + shared_medias_title Shared medias Shared medias - + shared_documents_title Shared documents Shared documents - + forward_to_title Forward to… Froward to… - + conversations_title Conversations Conversations diff --git a/Linphone/data/languages/fr_FR.ts b/Linphone/data/languages/fr_FR.ts index 852716a96..cbbe89409 100644 --- a/Linphone/data/languages/fr_FR.ts +++ b/Linphone/data/languages/fr_FR.ts @@ -1814,65 +1814,65 @@ ChatListView - + chat_message_is_writing_info %1 is writing… %1 est en train d'écrire… - + chat_message_draft_sending_text Brouillon : %1 - + chat_room_delete "Delete" Supprimer - + chat_room_mute Mettre en sourdine - + chat_room_unmute "Mute" Enlever la sourdine - + chat_room_mark_as_read "Mark as read" Marquer comme lu - + chat_room_leave "leave" Quitter la conversation - + chat_list_leave_chat_popup_title leave the conversation ? Quitter la conversation ? - + chat_list_leave_chat_popup_message You will not be able to send or receive messages in this conversation anymore. Do You want to continue ? Vous ne pourrez plus envoyer ou recevoir de messages dans cette conversation. Souhaitez-vous continuer ? - + chat_list_delete_chat_popup_title Delete the conversation ? Supprimer la conversation ? - + chat_list_delete_chat_popup_message This conversation and all its messages will be deleted. Do You want to continue ? La conversation et tous ses messages seront supprimés. Souhaitez-vous continuer ? @@ -2115,38 +2115,38 @@ Error ChatMessagesListView - - + + popup_info_find_message_title Find message Trouver un message - + info_popup_no_result_message No result found Aucun résultat trouvé - + info_popup_first_result_message First result reached Premier résultat atteint - + info_popup_last_result_message Last result reached Dernier résultat atteint - + chat_message_list_encrypted_header_title End to end encrypted chat Conversation chiffrée de bout en bout - + chat_message_list_encrypted_header_message Les messages de cette conversation sont chiffrés de bout en bout. Seul votre correspondant peut les déchiffrer. @@ -2154,7 +2154,7 @@ Error en bout. Seul votre correspondant peut les déchiffrer. - + chat_message_is_writing_info %1 is writing… %1 est en train d'écrire… @@ -2175,79 +2175,79 @@ en bout. Seul votre correspondant peut les déchiffrer. Aucune conversation - + chat_dialog_delete_chat_title Supprimer la conversation ? Supprimer la conversation ? - + chat_dialog_delete_chat_message "La conversation et tous ses messages seront supprimés." La conversation et tous ses messages seront supprimés. - + chat_list_title "Conversations" Conversations - + menu_mark_all_as_read "mark all as read" Tout marquer comme lu - + chat_search_in_history "Rechercher une conversation" Rechercher une conversation - + list_filter_no_result_found "Aucun résultat…" Aucun résultat… - + chat_list_empty_history "Aucune conversation dans votre historique" Aucune conversation dans votre historique - + chat_action_start_new_chat "New chat" Nouvelle conversation - + chat_start_group_chat_title "Nouveau groupe" Nouveau groupe - + chat_action_start_group_chat "Créer" Créer - - + + information_popup_error_title Erreur - + group_chat_error_must_have_name "Un nom doit être donné au groupe Un nom doit être donné au groupe - + group_call_error_not_connected "Vous n'etes pas connecté" Vous n'êtes pas connecté @@ -3939,13 +3939,13 @@ Expiration : %1 MeetingListView - + meeting_info_cancelled "Réunion annulée" Réunion annulée - + meetings_list_no_meeting_for_today "Aucune réunion aujourd'hui" Aucune réunion aujourd'hui @@ -4206,6 +4206,21 @@ Expiration : %1 Appuyez pour supprimer + + MessageSharedFilesInfos + + + no_shared_medias + No media + Aucun média + + + + no_shared_documents + No document + Aucun document + + MultimediaSettings @@ -4983,31 +4998,31 @@ Pour les activer dans un projet commercial, merci de nous contacter.Démarrer un appel de groupe ? - + reply_to_label Reply to %1 Réponse à %1 - + shared_medias_title Shared medias Médias partagés - + shared_documents_title Shared documents Documents partagés - + forward_to_title Forward to… Transférer à… - + conversations_title Conversations Conversations diff --git a/Linphone/model/chat/ChatModel.cpp b/Linphone/model/chat/ChatModel.cpp index 8187c8e00..59fbcac56 100644 --- a/Linphone/model/chat/ChatModel.cpp +++ b/Linphone/model/chat/ChatModel.cpp @@ -52,11 +52,28 @@ QDateTime ChatModel::getLastUpdateTime() { return QDateTime::fromSecsSinceEpoch(mMonitor->getLastUpdateTime()); } -std::list> ChatModel::getHistory() const { +std::list> ChatModel::getSharedMedias() const { + return mMonitor->getMediaContents(); +} + +std::list> ChatModel::getSharedDocuments() const { + return mMonitor->getDocumentContents(); +} + +std::list> ChatModel::getHistory() const { + int filter = mMonitor->hasCapability((int)linphone::ChatRoom::Capabilities::Conference) + ? static_cast(linphone::ChatRoom::HistoryFilter::ChatMessage) | + static_cast(linphone::ChatRoom::HistoryFilter::InfoNoDevice) + : static_cast(linphone::ChatRoom::HistoryFilter::ChatMessage); + return mMonitor->getHistory(0, filter); +} + +std::list> ChatModel::getChatMessageHistory() const { auto history = mMonitor->getHistory(0, (int)linphone::ChatRoom::HistoryFilter::ChatMessage); std::list> res; for (auto &eventLog : history) { - if (!eventLog->getChatMessage()) res.push_back(eventLog->getChatMessage()); + auto chatMessage = eventLog->getChatMessage(); + if (chatMessage) res.push_back(chatMessage); } return res; } @@ -106,7 +123,7 @@ int ChatModel::getUnreadMessagesCount() const { void ChatModel::markAsRead() { mMonitor->markAsRead(); - for (auto &message : getHistory()) { + for (auto &message : getChatMessageHistory()) { message->markAsRead(); } emit messagesRead(); diff --git a/Linphone/model/chat/ChatModel.hpp b/Linphone/model/chat/ChatModel.hpp index 96bacf187..c57a02b43 100644 --- a/Linphone/model/chat/ChatModel.hpp +++ b/Linphone/model/chat/ChatModel.hpp @@ -46,7 +46,10 @@ public: bool hasCapability(int capability) const; int getUnreadMessagesCount() const; void markAsRead(); - std::list> getHistory() const; + std::list> getSharedMedias() const; + std::list> getSharedDocuments() const; + std::list> getHistory() const; + std::list> getChatMessageHistory() const; QString getIdentifier() const; void deleteHistory(); void deleteMessage(std::shared_ptr message); diff --git a/Linphone/view/Control/Button/CountryIndicatorCombobox.qml b/Linphone/view/Control/Button/CountryIndicatorCombobox.qml index f1db297fd..79ba6a8ef 100644 --- a/Linphone/view/Control/Button/CountryIndicatorCombobox.qml +++ b/Linphone/view/Control/Button/CountryIndicatorCombobox.qml @@ -81,10 +81,7 @@ ColumnLayout { anchors.left: selectedItemFlag.right anchors.verticalCenter: parent.verticalCenter elide: Text.ElideRight - font { - pixelSize: Typography.p1.pixelSize - weight: Typography.p1.weight - } + font: Typography.p1 } } diff --git a/Linphone/view/Control/Display/BusyIndicator.qml b/Linphone/view/Control/Display/BusyIndicator.qml index 0c76add3a..70ca7ecc0 100644 --- a/Linphone/view/Control/Display/BusyIndicator.qml +++ b/Linphone/view/Control/Display/BusyIndicator.qml @@ -13,6 +13,8 @@ Item { height: busyIndicator.height Control.BusyIndicator { id: busyIndicator + width: Math.round(60 * DefaultStyle.dp) + height: width running: mainItem.visible anchors.centerIn: mainItem contentItem: EffectImage { diff --git a/Linphone/view/Control/Display/Chat/ChatListView.qml b/Linphone/view/Control/Display/Chat/ChatListView.qml index 73c6438fa..8b0bd4070 100644 --- a/Linphone/view/Control/Display/Chat/ChatListView.qml +++ b/Linphone/view/Control/Display/Chat/ChatListView.qml @@ -18,17 +18,20 @@ ListView { property real busyIndicatorSize: Math.round(60 * DefaultStyle.dp) property ChatGui currentChatGui: model.getAt(currentIndex) || null + property ChatGui chatToSelect: null + onChatToSelectChanged: { + var index = chatProxy.findChatIndex(chatToSelect) + if (index != -1) { + currentIndex = index + chatToSelect = null + } + } + onChatClicked: (chat) => {selectChat(chat)} - signal resultsReceived() signal markAllAsRead() signal chatClicked(ChatGui chat) - onResultsReceived: { - loading = false - // contentY = 0 - } - model: ChatProxy { id: chatProxy Component.onCompleted: { @@ -41,7 +44,10 @@ ListView { 2 * mainItem.height / (Math.round(56 * DefaultStyle.dp))) displayItemsStep: 3 * initialDisplayItems / 2 onModelReset: { - mainItem.resultsReceived() + loading = false + if (mainItem.chatToSelect) { + selectChat(mainItem.chatToSelect) + } } onModelAboutToBeReset: { loading = true @@ -160,6 +166,7 @@ ListView { } delegate: FocusScope { + visible: !mainItem.loading width: mainItem.width height: Math.round(63 * DefaultStyle.dp) Connections { diff --git a/Linphone/view/Control/Display/Chat/ChatMessagesListView.qml b/Linphone/view/Control/Display/Chat/ChatMessagesListView.qml index 643884d2d..2ce6c1a2b 100644 --- a/Linphone/view/Control/Display/Chat/ChatMessagesListView.qml +++ b/Linphone/view/Control/Display/Chat/ChatMessagesListView.qml @@ -93,8 +93,7 @@ ListView { markIndexAsRead(index) } } - Component.onCompleted: loading = true - onListAboutToBeReset: loading = true + onModelAboutToBeReset: loading = true onModelReset: Qt.callLater(function() { loading = false var index = eventLogProxy.findFirstUnreadIndex() @@ -130,7 +129,7 @@ ListView { } footer: Item { - visible: mainItem.chat && mainItem.chat.core.isEncrypted && !eventLogProxy.haveMore + visible: mainItem.chat && !mainItem.loading && mainItem.chat.core.isEncrypted && !eventLogProxy.haveMore height: visible ? headerMessage.height + headerMessage.topMargin + headerMessage.bottomMargin : Math.round(30 * DefaultStyle.dp) width: headerMessage.width anchors.horizontalCenter: parent.horizontalCenter @@ -216,6 +215,7 @@ ListView { BusyIndicator { anchors.horizontalCenter: mainItem.horizontalCenter + anchors.verticalCenter: mainItem.verticalCenter visible: mainItem.loading height: visible ? mainItem.busyIndicatorSize : 0 width: mainItem.busyIndicatorSize @@ -226,11 +226,11 @@ ListView { delegate: DelegateChooser { role: "eventType" - DelegateChoice { roleValue: "chatMessage" delegate: ChatMessage { id: chatMessageDelegate + visible: !mainItem.loading property int yoff: Math.round(chatMessageDelegate.y - mainItem.contentY) property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height) chatMessage: modelData.core.chatMessageGui @@ -288,6 +288,7 @@ ListView { roleValue: "event" delegate: Item { id: eventDelegate + visible: !mainItem.loading property int yoff: Math.round(eventDelegate.y - mainItem.contentY) property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height) onIsFullyVisibleChanged: { @@ -312,6 +313,7 @@ ListView { roleValue: "ephemeralEvent" delegate: Item { id: ephemeralEventDelegate + visible: !mainItem.loading property int yoff: Math.round(ephemeralEventDelegate.y - mainItem.contentY) property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height) onIsFullyVisibleChanged: { diff --git a/Linphone/view/Control/Display/Chat/FileView.qml b/Linphone/view/Control/Display/Chat/FileView.qml index 0a0481108..9a6153e4d 100644 --- a/Linphone/view/Control/Display/Chat/FileView.qml +++ b/Linphone/view/Control/Display/Chat/FileView.qml @@ -72,7 +72,17 @@ Item { fillMode: Image.PreserveAspectFit } Image { - visible: thumbnailSource.isImage + anchors.fill: image + z: image.z + 1 + visible: image.status == Image.Error || image.status == Image.Null + source: AppIcons.fileImage + sourceSize.width: mainItem.width + sourceSize.height: mainItem.height + fillMode: Image.PreserveAspectFit + } + Image { + id: image + visible: thumbnailSource.isImage && status !== Image.Loading mipmap: false//SettingsModel.mipmapEnabled source: mainItem.thumbnail sourceSize.width: mainItem.width @@ -80,15 +90,6 @@ Item { autoTransform: true fillMode: Image.PreserveAspectCrop anchors.fill: parent - Image { - anchors.fill: parent - z: parent.z + 1 - visible: parent.status !== Image.Ready - source: AppIcons.fileImage - sourceSize.width: mainItem.width - sourceSize.height: mainItem.height - fillMode: Image.PreserveAspectFit - } } Rectangle { visible: thumbnailSource.isVideo diff --git a/Linphone/view/Control/Display/Meeting/MeetingListView.qml b/Linphone/view/Control/Display/Meeting/MeetingListView.qml index 9129cfb7e..c8922310b 100644 --- a/Linphone/view/Control/Display/Meeting/MeetingListView.qml +++ b/Linphone/view/Control/Display/Meeting/MeetingListView.qml @@ -160,6 +160,7 @@ ListView { delegate: FocusScope { id: itemDelegate + visible: !mainItem.loading height: Math.round(63 * DefaultStyle.dp) + (!isFirst && dateDay.visible ? topOffset : 0) width: mainItem.width enabled: !isCanceled && haveModel diff --git a/Linphone/view/Page/Form/Chat/SelectedChatView.qml b/Linphone/view/Page/Form/Chat/SelectedChatView.qml index e80ef2f34..8d049372d 100644 --- a/Linphone/view/Page/Form/Chat/SelectedChatView.qml +++ b/Linphone/view/Page/Form/Chat/SelectedChatView.qml @@ -63,10 +63,6 @@ FocusScope { anchors.fill: parent spacing: 0 - //onEventChanged: { - // TODO : call when all messages read after scroll to unread feature available - // if (chat) chat.core.lMarkAsRead() - //} MainRightPanel { id: splitPanel Layout.fillWidth: true diff --git a/Linphone/view/Page/Layout/Chat/MessageInfosLayout.qml b/Linphone/view/Page/Layout/Chat/MessageInfosLayout.qml index 6dd307bad..c26066c41 100644 --- a/Linphone/view/Page/Layout/Chat/MessageInfosLayout.qml +++ b/Linphone/view/Page/Layout/Chat/MessageInfosLayout.qml @@ -34,10 +34,7 @@ ColumnLayout { } Text { text: mainItem.title - font { - pixelSize: Typography.h4.pixelSize - weight: Typography.h4.weight - } + font: Typography.h4 } } @@ -48,7 +45,6 @@ ColumnLayout { spacing: Math.round(21 * DefaultStyle.dp) TabBar { id: tabbar - onCurrentIndexChanged: console.log("current index", currentIndex) visible: mainItem.tabbarModel !== undefined Layout.fillWidth: true Layout.preferredWidth: implicitWidth diff --git a/Linphone/view/Page/Layout/Chat/MessageSharedFilesInfos.qml b/Linphone/view/Page/Layout/Chat/MessageSharedFilesInfos.qml index c2b880704..cca6fd975 100644 --- a/Linphone/view/Page/Layout/Chat/MessageSharedFilesInfos.qml +++ b/Linphone/view/Page/Layout/Chat/MessageSharedFilesInfos.qml @@ -19,9 +19,26 @@ MessageInfosLayout { Layout.preferredHeight: contentHeight cellWidth: mainItem.filter === ChatMessageFileProxy.FilterContentType.Documents ? width : width / 4 cellHeight: mainItem.filter === ChatMessageFileProxy.FilterContentType.Documents ? Math.round(69 * DefaultStyle.dp) : width / 4 + property bool loading: true model: ChatMessageFileProxy { chat: mainItem.chatGui filterType: mainItem.filter + onModelAboutToBeReset: gridView.loading = true + onModelReset: gridView.loading = false + } + BusyIndicator { + anchors.centerIn: parent + visible: gridView.loading + } + Text { + anchors.centerIn: parent + visible: !gridView.loading && gridView.count === 0 + font: Typography.p2l + text: mainItem.filter === ChatMessageFileProxy.FilterContentType.Medias + //: No media + ? qsTr("no_shared_medias") + //: No document + : qsTr("no_shared_documents") } delegate: FileView { contentGui: modelData diff --git a/Linphone/view/Page/Layout/Main/MainLayout.qml b/Linphone/view/Page/Layout/Main/MainLayout.qml index 2903965ba..ca2fb2262 100644 --- a/Linphone/view/Page/Layout/Main/MainLayout.qml +++ b/Linphone/view/Page/Layout/Main/MainLayout.qml @@ -641,7 +641,7 @@ Item { } function onOpenChatRequested(chat) { console.log("open chat requested, open", chat.core.title) - chatPage.selectedChatGui = chat + chatPage.openChatRequested(chat) } } } diff --git a/Linphone/view/Page/Main/Chat/ChatPage.qml b/Linphone/view/Page/Main/Chat/ChatPage.qml index d6d18343f..127bc90b8 100644 --- a/Linphone/view/Page/Main/Chat/ChatPage.qml +++ b/Linphone/view/Page/Main/Chat/ChatPage.qml @@ -60,6 +60,7 @@ AbstractMainPage { && listStackView.currentItem.objectName != "newChatItem") listStackView.push(newChatItem) } + signal openChatRequested(ChatGui chat) Dialog { id: deleteChatPopup @@ -193,9 +194,13 @@ AbstractMainPage { Connections { target: mainItem - onSelectedChatGuiChanged: { + function onSelectedChatGuiChanged() { + console.log("selected chat gui changed") chatListView.selectChat(mainItem.selectedChatGui) } + function onOpenChatRequested(chat) { + chatListView.chatToSelect = chat + } } } }