only load 20 elements each time in chat messages list to improve perf

fix image error ui
black rectangle on unstarted video

fix text edit loses focus when message sent (#LINQT-2009)

try to fix wrong message spinner icon #LINQT-2010

hide security parameters #LINQT-2019

fix open contextual menu component to open settings/help pages #LINQT-2021/2022

fix muted status not visible on local preview #LINQT-2023
This commit is contained in:
Gaelle Braud 2025-10-07 11:40:06 +02:00
parent 7e5f037332
commit c4db4d132d
17 changed files with 89 additions and 30 deletions

View file

@ -136,6 +136,41 @@ void EventLogList::setChatGui(ChatGui *chat) {
setChatCore(chatCore);
}
void EventLogList::setDisplayItemsStep(int displayItemsStep) {
if (mDisplayItemsStep != displayItemsStep) {
mDisplayItemsStep = displayItemsStep;
emit displayItemsStepChanged();
}
}
void EventLogList::displayMore() {
if (!mChatCore) return;
auto chatModel = mChatCore->getModel();
if (!chatModel) return;
mCoreModelConnection->invokeToModel([this, chatModel]() {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
int maxSize = chatModel->getHistorySizeEvents();
int totalItemsCount = mList.count();
auto newCount = std::min(totalItemsCount + mDisplayItemsStep, maxSize);
if (newCount <= totalItemsCount) {
return;
}
auto linphoneLogs = chatModel->getHistoryRange(totalItemsCount, newCount);
QList<QSharedPointer<EventLogCore>> *events = new QList<QSharedPointer<EventLogCore>>();
for (auto it : linphoneLogs) {
auto model = EventLogCore::create(it);
events->push_back(model);
}
mCoreModelConnection->invokeToCore([this, events, newCount] {
int currentCount = mList.count();
for (auto &event : *events) {
connectItem(event);
add(event);
}
});
});
}
int EventLogList::findFirstUnreadIndex() {
auto eventList = getSharedList<EventLogCore>();
auto it = std::find_if(eventList.begin(), eventList.end(), [](const QSharedPointer<EventLogCore> item) {
@ -199,7 +234,8 @@ void EventLogList::setSelf(QSharedPointer<EventLogList> me) {
}
mCoreModelConnection->invokeToModel([this, chatModel]() {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
auto linphoneLogs = chatModel->getHistory();
qDebug() << "update history till" << mDisplayItemsStep;
auto linphoneLogs = chatModel->getHistoryRange(0, mDisplayItemsStep);
QList<QSharedPointer<EventLogCore>> *events = new QList<QSharedPointer<EventLogCore>>();
for (auto it : linphoneLogs) {
auto model = EventLogCore::create(it);

View file

@ -52,6 +52,9 @@ public:
int findFirstUnreadIndex();
void displayMore();
void setDisplayItemsStep(int displayItemsStep);
void findChatMessageWithFilter(QString filter,
QSharedPointer<EventLogCore> startEvent,
bool forward = true,
@ -69,6 +72,7 @@ signals:
void listAboutToBeReset();
void chatGuiChanged();
void isUpdatingChanged();
void displayItemsStepChanged();
private:
QString mFilter;
@ -76,6 +80,7 @@ private:
QSharedPointer<SafeConnection<ChatCore, ChatModel>> mChatModelConnection;
QSharedPointer<SafeConnection<EventLogList, CoreModel>> mCoreModelConnection;
bool mIsUpdating = false;
int mDisplayItemsStep = 0;
DECLARE_ABSTRACT_OBJECT
};

View file

@ -43,6 +43,8 @@ void EventLogProxy::setSourceModel(QAbstractItemModel *model) {
if (newEventLogList) {
connect(newEventLogList, &EventLogList::listAboutToBeReset, this, &EventLogProxy::listAboutToBeReset);
connect(newEventLogList, &EventLogList::chatGuiChanged, this, &EventLogProxy::chatGuiChanged);
connect(this, &EventLogProxy::displayItemsStepChanged, newEventLogList,
[this, newEventLogList] { newEventLogList->setDisplayItemsStep(mDisplayItemsStep); });
connect(newEventLogList, &EventLogList::eventInserted, this,
[this, newEventLogList](int index, EventLogGui *event) {
invalidate();
@ -90,6 +92,13 @@ QSharedPointer<EventLogCore> EventLogProxy::getEventCoreAtIndex(int i) {
return getItemAt<SortFilterList, EventLogList, EventLogCore>(i);
}
void EventLogProxy::displayMore() {
auto model = getListModel<EventLogList>();
if (model) {
model->displayMore();
}
}
void EventLogProxy::loadUntil(int index) {
auto confInfoList = getListModel<EventLogList>();
if (mMaxDisplayItems < index) setMaxDisplayItems(index + mDisplayItemsStep);

View file

@ -44,6 +44,7 @@ public:
void setSourceModel(QAbstractItemModel *sourceModel) override;
Q_INVOKABLE void displayMore() override;
Q_INVOKABLE void loadUntil(int index);
Q_INVOKABLE EventLogGui *getEventAtIndex(int i);
QSharedPointer<EventLogCore> getEventCoreAtIndex(int i);

View file

@ -45,7 +45,7 @@ public:
// Helper for setting the limit with sorted/filtered list
void setSourceModels(SortFilterProxy *firstList);
Q_INVOKABLE void displayMore();
Q_INVOKABLE virtual void displayMore();
Q_INVOKABLE QVariant getAt(const int &index) const;
Q_INVOKABLE QVariantList getAll() const;
virtual int getCount() const;

View file

@ -61,11 +61,11 @@ std::list<std::shared_ptr<linphone::Content>> ChatModel::getSharedDocuments() co
}
std::list<std::shared_ptr<linphone::EventLog>> ChatModel::getHistory() const {
int filter = mMonitor->hasCapability((int)linphone::ChatRoom::Capabilities::Conference)
? static_cast<int>(linphone::ChatRoom::HistoryFilter::ChatMessage) |
static_cast<int>(linphone::ChatRoom::HistoryFilter::InfoNoDevice)
: static_cast<int>(linphone::ChatRoom::HistoryFilter::ChatMessage);
return mMonitor->getHistory(0, filter);
return mMonitor->getHistoryEvents(0);
}
std::list<std::shared_ptr<linphone::EventLog>> ChatModel::getHistoryRange(int begin, int end) {
return mMonitor->getHistoryRangeEvents(begin, end);
}
std::list<std::shared_ptr<linphone::ChatMessage>> ChatModel::getChatMessageHistory() const {
@ -78,6 +78,10 @@ std::list<std::shared_ptr<linphone::ChatMessage>> ChatModel::getChatMessageHisto
return res;
}
int ChatModel::getHistorySizeEvents() {
return mMonitor->getHistoryEventsSize();
}
QString ChatModel::getIdentifier() const {
return Utils::coreStringToAppString(mMonitor->getIdentifier());
}
@ -123,9 +127,6 @@ int ChatModel::getUnreadMessagesCount() const {
void ChatModel::markAsRead() {
mMonitor->markAsRead();
for (auto &message : getChatMessageHistory()) {
message->markAsRead();
}
emit messagesRead();
}

View file

@ -49,7 +49,9 @@ public:
std::list<std::shared_ptr<linphone::Content>> getSharedMedias() const;
std::list<std::shared_ptr<linphone::Content>> getSharedDocuments() const;
std::list<std::shared_ptr<linphone::EventLog>> getHistory() const;
std::list<std::shared_ptr<linphone::EventLog>> getHistoryRange(int begin, int end);
std::list<std::shared_ptr<linphone::ChatMessage>> getChatMessageHistory() const;
int getHistorySizeEvents();
QString getIdentifier() const;
void deleteHistory();
void deleteMessage(std::shared_ptr<linphone::ChatMessage> message);

View file

@ -20,6 +20,11 @@ Item {
property int conferenceLayout: call ? call.core.conferenceVideoLayout : LinphoneEnums.ConferenceLayout.ActiveSpeaker
property int participantDeviceCount: conference ? conference.core.participantDeviceCount : -1
property int lastConfLayoutBeforeSharing: -1
property string localAddress: call
? call.conference
? call.conference.core.me.core.sipAddress
: call.core.localAddress
: ""
onParticipantDeviceCountChanged: {
setConferenceLayout()
}

View file

@ -453,7 +453,6 @@ ListView {
id: mouseArea
hoverEnabled: true
anchors.fill: parent
focus: true
acceptedButtons: Qt.RightButton | Qt.LeftButton
onContainsMouseChanged: {
if (containsMouse)

View file

@ -317,7 +317,8 @@ Control.Control {
: ""
BusyIndicator {
anchors.fill: parent
z: parent.z + 1
Layout.preferredWidth: visible ? 14 * DefaultStyle.dp : 0
Layout.preferredHeight: visible ? 14 * DefaultStyle.dp : 0
visible: mainItem.msgState === LinphoneEnums.ChatMessageState.StateIdle
|| mainItem.msgState === LinphoneEnums.ChatMessageState.StateInProgress
|| mainItem.msgState === LinphoneEnums.ChatMessageState.StateFileTransferInProgress

View file

@ -48,11 +48,6 @@ ListView {
eventLogProxy.markIndexAsRead(index)
})
}
onChatChanged: {
lastItemVisible = false
forceActiveFocus()
}
Button {
visible: !mainItem.lastItemVisible
@ -77,15 +72,15 @@ ListView {
chat.core.lMarkAsRead()
}
onAtYBeginningChanged: if (atYBeginning) {
if (eventLogProxy.haveMore)
eventLogProxy.displayMore()
eventLogProxy.displayMore()
}
model: EventLogProxy {
id: eventLogProxy
chatGui: mainItem.chat
filterText: mainItem.filterText
initialDisplayItems: 10
initialDisplayItems: 20
displayItemsStep: 20
onEventInserted: (index, gui) => {
if (!mainItem.visible) return
if(mainItem.lastItemVisible) {

View file

@ -70,7 +70,7 @@ Item {
Image {
anchors.fill: image
z: image.z + 1
visible: image.status == Image.Error || image.status == Image.Null
visible: image.status == Image.Error || image.status == Image.Null || image.frameCount === 0
source: AppIcons.fileImage
sourceSize.width: mainItem.width
sourceSize.height: mainItem.height

View file

@ -11,7 +11,7 @@ import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
Rectangle {
id: mainItem
color: "transparent"//DefaultStyle.grey_1000
color: DefaultStyle.grey_1000
property ChatMessageContentGui contentGui
property string filePath: contentGui && contentGui.core.filePath
property var fillMode: playbackState === MediaPlayer.PlayingState ? VideoOutput.PreserveAspectFit : VideoOutput.PreserveAspectCrop

View file

@ -147,7 +147,6 @@ Flickable {
}
}
onSearchTextChanged: {
console.log("search texte changed, loading…")
loading = true
}

View file

@ -24,7 +24,7 @@ AbstractSettingsMenu {
//: "Affichage"
//{title: qsTr("settings_user_interface_title"), layout: "DisplaySettingsLayout"},
//: "Security"
{title: qsTr("settings_security_title"), layout: "SecuritySettingsLayout"},
// {title: qsTr("settings_security_title"), layout: "SecuritySettingsLayout"},
//: "Réseau"
{title: qsTr("settings_network_title"), layout: "NetworkSettingsLayout"},
//: "Paramètres avancés"

View file

@ -471,7 +471,10 @@ Item {
icon.height: Math.round(32 * DefaultStyle.dp)
text: qsTr("settings_title")
icon.source: AppIcons.settings
onClicked: openContextualMenuComponent(settingsPageComponent)
onClicked: {
var page = settingsPageComponent.createObject(parent);
openContextualMenuComponent(page)
}
KeyNavigation.up: visibleChildren.length
!= 0 ? settingsMenuButton.getPreviousItem(
2) : null
@ -503,8 +506,10 @@ Item {
//: "Aide"
text: qsTr("help_title")
icon.source: AppIcons.question
onClicked: openContextualMenuComponent(
helpPageComponent)
onClicked: {
var page = helpPageComponent.createObject(parent);
openContextualMenuComponent(page)
}
KeyNavigation.up: visibleChildren.length
!= 0 ? settingsMenuButton.getPreviousItem(
4) : null

View file

@ -68,8 +68,9 @@ AbstractSettingsLayout {
toValidate: true
Connections {
enabled: account
target: account.core
function onMwiServerAddressAddressChanged() {
function onMwiServerAddressChanged() {
if (mwiServerAddressField.text != mwiServerAddressField.propertyOwnerGui.core[mwiServerAddressField.propertyName])
mwiServerAddressField.text = mwiServerAddressField.propertyOwnerGui.core[mwiServerAddressField.propertyName]
}
@ -80,14 +81,14 @@ AbstractSettingsLayout {
propertyName: "voicemailAddress"
propertyOwnerGui: account
//: "URI de messagerie vocale"
title: qsTr("account_settings_voicemail_uri_title")
Layout.fillWidth: true
toValidate: true
Connections {
enabled: account
target: account.core
function onVoicemailAddressAddressChanged() {
function onVoicemailAddressChanged() {
if (voicemailAddressField.text != voicemailAddressField.propertyOwnerGui.core[voicemailAddressField.propertyName])
voicemailAddressField.text = voicemailAddressField.propertyOwnerGui.core[voicemailAddressField.propertyName]
}