add chat history button in call list for meetings with chat #LINQT-2449

This commit is contained in:
Gaelle Braud 2026-03-06 11:38:42 +01:00
parent 5b78daf372
commit e7598bef1e
10 changed files with 195 additions and 82 deletions

View file

@ -20,6 +20,7 @@
#include "CallHistoryCore.hpp"
#include "core/App.hpp"
#include "core/chat/ChatGui.hpp"
#include "core/conference/ConferenceInfoCore.hpp"
#include "core/friend/FriendGui.hpp"
#include "model/call-history/CallHistoryModel.hpp"
@ -58,6 +59,9 @@ CallHistoryCore::CallHistoryCore(const std::shared_ptr<linphone::CallLog> &callL
mConferenceInfo = ConferenceInfoCore::create(confinfo);
mRemoteAddress = Utils::coreStringToAppString(confinfo->getUri()->asStringUriOnly());
mDisplayName = Utils::coreStringToAppString(confinfo->getSubject());
if (auto chatroom = callLog->getChatRoom()) {
mChatCore = ChatCore::create(chatroom);
}
} else {
mRemoteAddress = Utils::coreStringToAppString(addr->asStringUriOnly());
auto linphoneFriend = ToolModel::findFriendByAddress(addr);
@ -156,6 +160,10 @@ void CallHistoryCore::setDuration(const QString &duration) {
}
}
ChatGui *CallHistoryCore::getChatGui() const {
return mChatCore ? new ChatGui(mChatCore) : nullptr;
}
void CallHistoryCore::remove() {
mHistoryModelConnection->invokeToModel([this]() {
mCallHistoryModel->removeCallHistory();

View file

@ -30,6 +30,8 @@
#include <linphone++/linphone.hh>
class CallHistoryModel;
class ChatCore;
class ChatGui;
class FriendModel;
class CallHistoryCore : public QObject, public AbstractObject {
@ -40,6 +42,7 @@ class CallHistoryCore : public QObject, public AbstractObject {
Q_PROPERTY(bool isOutgoing MEMBER mIsOutgoing CONSTANT)
Q_PROPERTY(bool isConference MEMBER mIsConference CONSTANT)
Q_PROPERTY(ConferenceInfoGui *conferenceInfo READ getConferenceInfoGui CONSTANT)
Q_PROPERTY(ChatGui *chatGui READ getChatGui CONSTANT)
Q_PROPERTY(QDateTime date MEMBER mDate CONSTANT)
Q_PROPERTY(LinphoneEnums::CallStatus status MEMBER mStatus CONSTANT)
Q_PROPERTY(QString duration READ getDuration WRITE setDuration NOTIFY durationChanged)
@ -55,6 +58,8 @@ public:
QString getDuration() const;
void setDuration(const QString &duration);
ChatGui *getChatGui() const;
void onRemoved(const std::shared_ptr<linphone::Friend> &updatedFriend);
Q_INVOKABLE void remove();
@ -76,6 +81,7 @@ signals:
private:
QString mDuration;
QSharedPointer<ConferenceInfoCore> mConferenceInfo = nullptr;
QSharedPointer<ChatCore> mChatCore = nullptr;
std::shared_ptr<CallHistoryModel> mCallHistoryModel;
std::shared_ptr<FriendModel> mFriendModel;
QSharedPointer<SafeConnection<CallHistoryCore, FriendModel>> mFriendModelConnection;

View file

@ -16,6 +16,7 @@ ColumnLayout {
property FriendGui contact
property var conferenceInfo: callHistoryGui?.core.conferenceInfo
property var chatGui: callHistoryGui?.core.chatGui
property bool isConference: conferenceInfo != undefined && conferenceInfo != null
property string contactAddress: specificAddress != "" ? specificAddress : contact && contact.core.defaultAddress || ""
property var computedContactNameObj: UtilsCpp.getDisplayName(contactAddress)
@ -33,8 +34,12 @@ ColumnLayout {
property alias buttonContent: rightButton.data
property alias detailContent: detailControl.data
signal conferenceChatDisplayRequested()
signal conferenceCallHistoryDisplayRequested()
ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(13)
Layout.alignment: Qt.AlignHCenter
Item {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
Layout.preferredHeight: detailAvatar.height
@ -65,6 +70,7 @@ ColumnLayout {
ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(2)
Layout.alignment: Qt.AlignHCenter
Text {
Layout.preferredWidth: implicitWidth
Layout.alignment: Qt.AlignHCenter
@ -81,7 +87,7 @@ ColumnLayout {
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
horizontalAlignment: Text.AlignHCenter
visible: mainItem.specificAddress != ""
visible: mainItem.specificAddress != "" && !mainItem.isConference
text: SettingsCpp.hideSipAddresses ? UtilsCpp.getUsername(mainItem.specificAddress) : mainItem.specificAddress
elide: Text.ElideMiddle
maximumLineCount: 1
@ -106,7 +112,7 @@ ColumnLayout {
}
}
MediumButton {
visible: mainItem.isConference && !SettingsCpp.disableMeetingsFeature
visible: mainItem.isConference && !SettingsCpp.disableMeetingsFeature && !confWithChatLayout.visible
Layout.alignment: Qt.AlignHCenter
//: "Rejoindre la réunion"
text: qsTr("meeting_info_join_title")
@ -119,6 +125,47 @@ ColumnLayout {
}
}
}
RowLayout {
id: confWithChatLayout
visible: mainItem.isConference && !SettingsCpp.disableMeetingsFeature && mainItem.chatGui !== null
Layout.alignment: Qt.AlignHCenter
spacing: Utils.getSizeWithScreenRatio(72)
// Layout.fillWidth: true
Layout.preferredHeight: childrenRect.height
LabelButton {
visible: !SettingsCpp.disableChatFeature
width: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56)
button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: AppIcons.videoconference
//: "Join"
label: qsTr("meeting_info_join_title")
button.onClicked: if (mainItem.conferenceInfo) {
var callsWindow = UtilsCpp.getOrCreateCallsWindow()
callsWindow.setupConference(mainItem.conferenceInfo)
UtilsCpp.smartShowWindow(callsWindow)
}
}
LabelButton {
visible: !SettingsCpp.disableChatFeature
button.checkable: true
width: Utils.getSizeWithScreenRatio(56)
height: Utils.getSizeWithScreenRatio(56)
button.icon.width: Utils.getSizeWithScreenRatio(24)
button.icon.height: Utils.getSizeWithScreenRatio(24)
button.icon.source: button.checked ? AppIcons.callList : AppIcons.chatTeardropText
label: button.checked
//: "Call history"
? qsTr("contact_call_history_action")
//: "Conversation"
: qsTr("contact_conversation_action")
button.onCheckedChanged: {
if (button.checked) mainItem.conferenceChatDisplayRequested()
else mainItem.conferenceCallHistoryDisplayRequested()
}
}
}
RowLayout {
Layout.alignment: Qt.AlignHCenter
spacing: Utils.getSizeWithScreenRatio(72)

View file

@ -18,6 +18,7 @@ Item {
property bool shadowEnabled: false
property bool isImageReady: false
property bool retainWhileLoading: true
property alias status: image.status
Image {
id: image
visible: !effect2.effectEnabled

View file

@ -7,6 +7,20 @@ Quick.Text {
id: mainItem
property double scaleLettersFactor: 1.
width: txtMeter.advanceWidth
property alias tooltip: tooltip
property alias mouseArea: mouseArea
Quick.MouseArea {
id: mouseArea
anchors.fill: parent
acceptedButtons: Qt.NoButton
hoverEnabled: true
onContainsMouseChanged: console.log("mouse area contains mouse", containsMouse)
}
ToolTip {
id: tooltip
visible: mainItem.visible && mouseArea.containsMouse && mainItem.truncated
text: mainItem.text
}
font {
family: DefaultStyle.defaultFont
pixelSize: Utils.getSizeWithScreenRatio(10)

View file

@ -1,23 +1,28 @@
import QtQuick
import QtQuick as Quick
import QtQuick.Controls.Basic as Control
import Linphone
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.ToolTip {
id: mainItem
delay: 1000
delay: 800
clip: true
background: Rectangle {
background: Quick.Rectangle {
id: tooltipBackground
opacity: 0.7
color: DefaultStyle.main2_200
radius: Utils.getSizeWithScreenRatio(15)
}
contentItem: Text {
contentItem: Quick.Text {
text: mainItem.text
color: DefaultStyle.main2_600
width: tooltipBackground.width
wrapMode: Text.Wrap
elide: Text.ElideRight
font {
family: DefaultStyle.defaultFont
pixelSize: Utils.getSizeWithScreenRatio(10)
weight: Typography.p1.weight
}
}
}

View file

@ -115,6 +115,7 @@ FocusScope {
ColumnLayout {
Text {
Layout.fillWidth: true
Component.onCompleted: console.log(text, "width", width, "implicitWidth", implicitWidth, "advance", advance, contentWidth)
text: UtilsCpp.encodeEmojiToQmlRichFormat(mainItem.chat?.core.title) || ""
color: DefaultStyle.main2_600
maximumLineCount: 1
@ -166,6 +167,7 @@ FocusScope {
imageSource: AppIcons.bellSlash
}
}
Item{Layout.fillWidth: true}
RowLayout {
id: headerActionButtons
spacing: Utils.getSizeWithScreenRatio(16)
@ -211,12 +213,17 @@ FocusScope {
onCheckedChanged: {
detailsPanel.visible = checked
}
Connections {
target: detailsPanel
function onVisibleChanged() {
if (!detailsPanel.visible) detailsPanelButton.checked = false
}
}
}
}
}
RowLayout {
id: searchBarLayout
visible: searchInHistoryButton.checked
onVisibleChanged: {
if(!visible) chatMessagesSearchBar.clearText()
else chatMessagesSearchBar.forceActiveFocus()
@ -291,7 +298,14 @@ FocusScope {
anchors.fill: parent
orientation: Qt.Vertical
handle: Rectangle {
visible: !mainItem.chat?.core.isReadOnly
id: splitViewHandle
visible: !mainItem.chat?.core.isReadOnly || false
// Hack for keeping handle unvisible in call history chat
// (It somehow becomes visible when switching from call history to chat
// history even if chat is read only)
onVisibleChanged: {
visible = !mainItem.chat?.core.isReadOnly || false
}
enabled: visible
implicitHeight: Utils.getSizeWithScreenRatio(8)
color: Control.SplitHandle.hovered ? DefaultStyle.grey_200 : DefaultStyle.grey_100
@ -574,7 +588,7 @@ FocusScope {
}
}
Rectangle {
visible: detailsPanel.visible
visible: detailsPanel.visible && detailsPanel.width < mainItem.width
color: DefaultStyle.main2_200
Layout.preferredWidth: Utils.getSizeWithScreenRatio(1)
Layout.fillHeight: true
@ -583,7 +597,7 @@ FocusScope {
id: detailsPanel
visible: false
Layout.fillHeight: true
Layout.preferredWidth: Utils.getSizeWithScreenRatio(387)
Layout.preferredWidth: Math.min(Utils.getSizeWithScreenRatio(387), mainItem.width)
onVisibleChanged: if(!visible) {
contentLoader.panelType = SelectedChatView.PanelType.None
}
@ -591,6 +605,11 @@ FocusScope {
background: Rectangle {
color: DefaultStyle.grey_0
anchors.fill: parent
RoundButton {
style: ButtonStyle.noBackgroundOrange
icon.source: AppIcons.leftArrow
onClicked: detailsPanel.visible = false
}
}
contentItem: Loader {

View file

@ -192,8 +192,8 @@ ColumnLayout {
spacing: Utils.getSizeWithScreenRatio(10)
Layout.alignment: Qt.AlignHCenter
Layout.topMargin: Utils.getSizeWithScreenRatio(30)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(110)
Layout.minimumHeight: Utils.getSizeWithScreenRatio(110)
Layout.preferredHeight: visible ? Utils.getSizeWithScreenRatio(110) : 0
Layout.minimumHeight: visible ? Utils.getSizeWithScreenRatio(110) : 0
LabelButton {
text.Layout.fillWidth: true
text.horizontalAlignment: Text.AlignHCenter

View file

@ -580,14 +580,18 @@ AbstractMainPage {
}
}
}
onConferenceChatDisplayRequested: detailContentStack.currentIndex = 1
onConferenceCallHistoryDisplayRequested: detailContentStack.currentIndex = 0
detailContent: Item {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(360)
Layout.fillHeight: true
RoundedPane {
id: detailControl
visible: detailListView.count > 0
visible: detailContentStack.currentIndex !== 0 || detailListView.count > 0
width: parent.width
height: Math.min(parent.height, detailListView.contentHeight) + topPadding + bottomPadding
height: detailContentStack.currentIndex === 0
? Math.min(parent.height, detailListView.contentHeight) + topPadding + bottomPadding
: parent.height
background: Rectangle {
id: detailListBackground
anchors.fill: parent
@ -595,7 +599,10 @@ AbstractMainPage {
radius: Utils.getSizeWithScreenRatio(15)
}
contentItem: Control.ScrollView {
contentItem: StackLayout {
id: detailContentStack
currentIndex: 0
Control.ScrollView {
id: historyScrollView
Control.ScrollBar.vertical: ScrollBar {
id: historyScrollBar
@ -682,6 +689,12 @@ AbstractMainPage {
}
}
}
SelectedChatView {
Layout.fillWidth: true
Layout.fillHeight: true
chat: contactDetail.callHistoryGui.core.chatGui
}
}
}
}
Item {