fix unread messages

fix do not add chat in list if events intended for another account

chat notif in vertical bar / account list

fix cursor on hovered link

fix sending area height
This commit is contained in:
Gaelle Braud 2025-07-01 11:18:22 +02:00
parent 0655672c32
commit c015375ae9
10 changed files with 187 additions and 137 deletions

View file

@ -476,6 +476,14 @@ QList<QSharedPointer<EventLogCore>> ChatCore::getEventLogList() const {
} }
void ChatCore::resetEventLogList(QList<QSharedPointer<EventLogCore>> list) { void ChatCore::resetEventLogList(QList<QSharedPointer<EventLogCore>> 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; mEventLogList = list;
emit eventListChanged(); emit eventListChanged();
} }
@ -484,6 +492,8 @@ void ChatCore::appendEventLogsToEventLogList(QList<QSharedPointer<EventLogCore>>
int nbAdded = 0; int nbAdded = 0;
for (auto &e : list) { for (auto &e : list) {
if (mEventLogList.contains(e)) continue; if (mEventLogList.contains(e)) continue;
if (auto message = e->getChatMessageCore())
connect(message.get(), &ChatMessageCore::isReadChanged, this, [this] { emit lUpdateUnreadCount(); });
mEventLogList.append(e); mEventLogList.append(e);
++nbAdded; ++nbAdded;
} }
@ -496,6 +506,8 @@ void ChatCore::appendEventLogToEventLogList(QSharedPointer<EventLogCore> e) {
return e->getEventLogId() == event->getEventLogId(); return e->getEventLogId() == event->getEventLogId();
}); });
if (it == mEventLogList.end()) { if (it == mEventLogList.end()) {
if (auto message = e->getChatMessageCore())
connect(message.get(), &ChatMessageCore::isReadChanged, this, [this] { emit lUpdateUnreadCount(); });
mEventLogList.append(e); mEventLogList.append(e);
emit eventsInserted({e}); emit eventsInserted({e});
} }
@ -505,6 +517,7 @@ void ChatCore::removeEventLogsFromEventLogList(QList<QSharedPointer<EventLogCore
int nbRemoved = 0; int nbRemoved = 0;
for (auto &e : list) { for (auto &e : list) {
if (mEventLogList.contains(e)) { if (mEventLogList.contains(e)) {
if (auto message = e->getChatMessageCore()) disconnect(message.get());
mEventLogList.removeAll(e); mEventLogList.removeAll(e);
++nbRemoved; ++nbRemoved;
} }
@ -513,6 +526,9 @@ void ChatCore::removeEventLogsFromEventLogList(QList<QSharedPointer<EventLogCore
} }
void ChatCore::clearEventLogList() { void ChatCore::clearEventLogList() {
for (auto &e : mEventLogList) {
disconnect(e.get());
}
mEventLogList.clear(); mEventLogList.clear();
emit eventListChanged(); emit eventListChanged();
} }

View file

@ -22,6 +22,7 @@
#include "ChatCore.hpp" #include "ChatCore.hpp"
#include "ChatGui.hpp" #include "ChatGui.hpp"
#include "core/App.hpp" #include "core/App.hpp"
#include "model/tool/ToolModel.hpp"
#include <QSharedPointer> #include <QSharedPointer>
#include <linphone++/linphone.hh> #include <linphone++/linphone.hh>
@ -109,63 +110,60 @@ void ChatList::setSelf(QSharedPointer<ChatList> me) {
mModelConnection->makeConnectToModel( mModelConnection->makeConnectToModel(
&CoreModel::defaultAccountChanged, &CoreModel::defaultAccountChanged,
[this](std::shared_ptr<linphone::Core> core, std::shared_ptr<linphone::Account> account) { lUpdate(); }); [this](std::shared_ptr<linphone::Core> core, std::shared_ptr<linphone::Account> account) { lUpdate(); });
mModelConnection->makeConnectToModel( auto addChatToList = [this](const std::shared_ptr<linphone::Core> &core,
&CoreModel::messageReceived, const std::shared_ptr<linphone::ChatRoom> &room,
[this](const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::ChatRoom> &room, const std::shared_ptr<linphone::ChatMessage> &message) {
const std::shared_ptr<linphone::ChatMessage> &message) { mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
auto chatCore = ChatCore::create(room); auto receiverAccount = ToolModel::findAccount(message->getToAddress());
mModelConnection->invokeToCore([this, chatCore] { if (!receiverAccount) {
auto chatList = getSharedList<ChatCore>(); qWarning() << log().arg("Receiver account not found in account list, return");
auto it = return;
std::find_if(chatList.begin(), chatList.end(), [chatCore](const QSharedPointer<ChatCore> item) { }
return item && chatCore && item->getModel() && chatCore->getModel() && auto receiverAddress = receiverAccount->getContactAddress();
item->getModel()->getMonitor() == chatCore->getModel()->getMonitor(); if (!receiverAddress) {
}); qWarning() << log().arg("Receiver account has no address, return");
if (it == chatList.end()) { return;
connectItem(chatCore); }
add(chatCore); auto defaultAddress = core->getDefaultAccount()->getContactAddress();
emit chatAdded(); if (!defaultAddress->weakEqual(receiverAddress)) {
} qDebug() << log().arg("Receiver account is not the default one, do not add chat to list");
}); return;
}); }
auto chatCore = ChatCore::create(room);
mModelConnection->invokeToCore([this, chatCore] {
auto chatList = getSharedList<ChatCore>();
auto it = std::find_if(chatList.begin(), chatList.end(), [chatCore](const QSharedPointer<ChatCore> item) {
return item && chatCore && item->getModel() && chatCore->getModel() &&
item->getModel()->getMonitor() == chatCore->getModel()->getMonitor();
});
if (it == chatList.end()) {
connectItem(chatCore);
add(chatCore);
emit chatAdded();
}
});
};
mModelConnection->makeConnectToModel(&CoreModel::messageReceived,
[this, addChatToList](const std::shared_ptr<linphone::Core> &core,
const std::shared_ptr<linphone::ChatRoom> &room,
const std::shared_ptr<linphone::ChatMessage> &message) {
addChatToList(core, room, message);
});
mModelConnection->makeConnectToModel( mModelConnection->makeConnectToModel(
&CoreModel::messagesReceived, &CoreModel::messagesReceived,
[this](const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::ChatRoom> &room, [this, addChatToList](const std::shared_ptr<linphone::Core> &core,
const std::list<std::shared_ptr<linphone::ChatMessage>> &messages) { const std::shared_ptr<linphone::ChatRoom> &room,
auto chatCore = ChatCore::create(room); const std::list<std::shared_ptr<linphone::ChatMessage>> &messages) {
mModelConnection->invokeToCore([this, chatCore] { addChatToList(core, room, messages.front());
auto chatList = getSharedList<ChatCore>();
auto it =
std::find_if(chatList.begin(), chatList.end(), [chatCore](const QSharedPointer<ChatCore> item) {
return item && chatCore && item->getModel() && chatCore->getModel() &&
item->getModel()->getMonitor() == chatCore->getModel()->getMonitor();
});
if (it == chatList.end()) {
connectItem(chatCore);
add(chatCore);
emit chatAdded();
}
});
}); });
mModelConnection->makeConnectToModel( mModelConnection->makeConnectToModel(
&CoreModel::newMessageReaction, &CoreModel::newMessageReaction,
[this](const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::ChatRoom> &room, [this, addChatToList](const std::shared_ptr<linphone::Core> &core,
const std::shared_ptr<linphone::ChatMessage> &message, const std::shared_ptr<linphone::ChatRoom> &room,
const std::shared_ptr<const linphone::ChatMessageReaction> &reaction) { const std::shared_ptr<linphone::ChatMessage> &message,
auto chatCore = ChatCore::create(room); const std::shared_ptr<const linphone::ChatMessageReaction> &reaction) {
mModelConnection->invokeToCore([this, chatCore] { addChatToList(core, room, message);
auto chatList = getSharedList<ChatCore>();
auto it =
std::find_if(chatList.begin(), chatList.end(), [chatCore](const QSharedPointer<ChatCore> item) {
return item && chatCore && item->getModel() && chatCore->getModel() &&
item->getModel()->getMonitor() == chatCore->getModel()->getMonitor();
});
if (it == chatList.end()) {
connectItem(chatCore);
add(chatCore);
emit chatAdded();
}
});
}); });
connect(this, &ChatList::filterChanged, [this](QString filter) { connect(this, &ChatList::filterChanged, [this](QString filter) {

View file

@ -1,7 +1,6 @@
list(APPEND _LINPHONEAPP_RC_FILES data/assistant/use-app-sip-account.rc list(APPEND _LINPHONEAPP_RC_FILES data/assistant/use-app-sip-account.rc
data/assistant/create-app-sip-account.rc data/assistant/create-app-sip-account.rc
data/assistant/use-other-sip-account.rc data/assistant/use-other-sip-account.rc
data/shaders/opacityMask.frag.qsb
data/shaders/roundEffect.frag.qsb data/shaders/roundEffect.frag.qsb
data/emoji/emoji.json data/emoji/emoji.json
) )

View file

@ -45,8 +45,7 @@ AccountModel::AccountModel(const std::shared_ptr<linphone::Account> &account, QO
}); });
connect(CoreModel::getInstance().get(), &CoreModel::unreadNotificationsChanged, this, [this]() { connect(CoreModel::getInstance().get(), &CoreModel::unreadNotificationsChanged, this, [this]() {
emit unreadNotificationsChanged(0 /*mMonitor->getUnreadChatMessageCount()*/, emit unreadNotificationsChanged(mMonitor->getUnreadChatMessageCount(), mMonitor->getMissedCallsCount());
mMonitor->getMissedCallsCount()); // TODO
}); });
connect(CoreModel::getInstance().get(), &CoreModel::accountRemoved, this, connect(CoreModel::getInstance().get(), &CoreModel::accountRemoved, this,
[this](const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::Account> &account) { [this](const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::Account> &account) {

View file

@ -14,26 +14,24 @@ ListView {
spacing: Math.round(4 * DefaultStyle.dp) spacing: Math.round(4 * DefaultStyle.dp)
property ChatGui chat property ChatGui chat
property color backgroundColor property color backgroundColor
property bool lastItemVisible: false
signal showReactionsForMessageRequested(ChatMessageGui chatMessage) signal showReactionsForMessageRequested(ChatMessageGui chatMessage)
signal showImdnStatusForMessageRequested(ChatMessageGui chatMessage) signal showImdnStatusForMessageRequested(ChatMessageGui chatMessage)
signal replyToMessageRequested(ChatMessageGui chatMessage) signal replyToMessageRequested(ChatMessageGui chatMessage)
Component.onCompleted: { Component.onCompleted: {
var index = eventLogProxy.findFirstUnreadIndex() Qt.callLater(function() {
positionViewAtIndex(index, ListView.End) var index = eventLogProxy.findFirstUnreadIndex()
var chatMessage = eventLogProxy.getEventAtIndex(index)?.core?.chatMessage positionViewAtIndex(index, ListView.End)
if (chatMessage && !chatMessage.isRead) chatMessage.lMarkAsRead() })
} }
onCountChanged: if (atYEnd) { onCountChanged: if (atYEnd) {
var index = eventLogProxy.findFirstUnreadIndex() positionViewAtEnd()
mainItem.positionViewAtIndex(index, ListView.End)
var chatMessage = eventLogProxy.getEventAtIndex(index)?.core?.chatMessage
if (chatMessage && !chatMessage.isRead) chatMessage.lMarkAsRead()
} }
Button { Button {
visible: !mainItem.atYEnd visible: !mainItem.lastItemVisible
icon.source: AppIcons.downArrow icon.source: AppIcons.downArrow
leftPadding: Math.round(16 * DefaultStyle.dp) leftPadding: Math.round(16 * DefaultStyle.dp)
rightPadding: Math.round(16 * DefaultStyle.dp) rightPadding: Math.round(16 * DefaultStyle.dp)
@ -46,11 +44,14 @@ ListView {
onClicked: { onClicked: {
var index = eventLogProxy.findFirstUnreadIndex() var index = eventLogProxy.findFirstUnreadIndex()
mainItem.positionViewAtIndex(index, ListView.End) mainItem.positionViewAtIndex(index, ListView.End)
var chatMessage = eventLogProxy.getEventAtIndex(index)?.core?.chatMessage
if (chatMessage && !chatMessage.isRead) chatMessage.lMarkAsRead()
} }
} }
onAtYEndChanged: if (atYEnd) {
if (eventLogProxy.haveMore)
eventLogProxy.displayMore()
}
model: EventLogProxy { model: EventLogProxy {
id: eventLogProxy id: eventLogProxy
chatGui: mainItem.chat chatGui: mainItem.chat
@ -58,8 +59,6 @@ ListView {
onEventInserted: (index, gui) => { onEventInserted: (index, gui) => {
if (!mainItem.visible) return if (!mainItem.visible) return
mainItem.positionViewAtIndex(index, ListView.End) mainItem.positionViewAtIndex(index, ListView.End)
if (gui.core.chatMessage && !gui.core.chatMessage.isRead)
gui.core.chatMessage.lMarkAsRead()
} }
} }
@ -114,67 +113,92 @@ ListView {
} }
delegate: DelegateChooser { delegate: DelegateChooser {
role: "eventType" role: "eventType"
DelegateChoice { DelegateChoice {
roleValue: "chatMessage" roleValue: "chatMessage"
delegate: delegate: ChatMessage {
ChatMessage { id: chatMessageDelegate
chatMessage: modelData property int yoff: Math.round(chatMessageDelegate.y - mainItem.contentY)
chat: mainItem.chat property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height)
maxWidth: Math.round(mainItem.width * (3/4)) onIsFullyVisibleChanged: {
onVisibleChanged: { if (index === mainItem.count - 1) {
if (visible && !modelData.core.isRead) modelData.core.lMarkAsRead() mainItem.lastItemVisible = isFullyVisible
} }
width: mainItem.width if (isFullyVisible)
property var previousIndex: index - 1 modelData.core.lMarkAsRead()
property var previousFromAddress: eventLogProxy.getEventAtIndex(index-1)?.core.chatMessage?.fromAddress }
backgroundColor: isRemoteMessage ? DefaultStyle.main2_100 : DefaultStyle.main1_100 chatMessage: modelData
isFirstMessage: !previousFromAddress || previousFromAddress !== modelData.core.fromAddress chat: mainItem.chat
anchors.right: !isRemoteMessage && parent maxWidth: Math.round(mainItem.width * (3/4))
? parent.right onVisibleChanged: {
: undefined if (visible) {
modelData.core.lMarkAsRead()
}
}
width: mainItem.width
property var previousIndex: index - 1
property var previousFromAddress: eventLogProxy.getEventAtIndex(index-1)?.core.chatMessage?.fromAddress
backgroundColor: isRemoteMessage ? DefaultStyle.main2_100 : DefaultStyle.main1_100
isFirstMessage: !previousFromAddress || previousFromAddress !== modelData.core.fromAddress
anchors.right: !isRemoteMessage && parent
? parent.right
: undefined
onMessageDeletionRequested: modelData.core.lDelete() onMessageDeletionRequested: modelData.core.lDelete()
onShowReactionsForMessageRequested: mainItem.showReactionsForMessageRequested(modelData) onShowReactionsForMessageRequested: mainItem.showReactionsForMessageRequested(modelData)
onShowImdnStatusForMessageRequested: mainItem.showImdnStatusForMessageRequested(modelData) onShowImdnStatusForMessageRequested: mainItem.showImdnStatusForMessageRequested(modelData)
onReplyToMessageRequested: mainItem.replyToMessageRequested(modelData) onReplyToMessageRequested: mainItem.replyToMessageRequested(modelData)
} }
} }
DelegateChoice { DelegateChoice {
roleValue: "event" roleValue: "event"
delegate: delegate: Item {
Item { id: eventDelegate
property bool showTopMargin: !header.visible && index == 0 property int yoff: Math.round(eventDelegate.y - mainItem.contentY)
width: mainItem.width property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height)
height: (showTopMargin ? 30 : 0 * DefaultStyle.dp) + eventItem.implicitHeight onIsFullyVisibleChanged: {
Event { if (index === mainItem.count - 1) {
id: eventItem mainItem.lastItemVisible = isFullyVisible
anchors.top: parent.top }
anchors.topMargin: showTopMargin ? 30 : 0 * DefaultStyle.dp }
width: parent.width property bool showTopMargin: !header.visible && index == 0
eventLogGui: modelData width: mainItem.width
} height: (showTopMargin ? 30 : 0 * DefaultStyle.dp) + eventItem.implicitHeight
} Event {
id: eventItem
anchors.top: parent.top
anchors.topMargin: showTopMargin ? 30 : 0 * DefaultStyle.dp
width: parent.width
eventLogGui: modelData
}
}
} }
DelegateChoice { DelegateChoice {
roleValue: "ephemeralEvent" roleValue: "ephemeralEvent"
delegate: delegate: Item {
Item { id: ephemeralEventDelegate
property bool showTopMargin: !header.visible && index == 0 property int yoff: Math.round(ephemeralEventDelegate.y - mainItem.contentY)
width: mainItem.width property bool isFullyVisible: (yoff > mainItem.y && yoff + height < mainItem.y + mainItem.height)
//height: 40 * DefaultStyle.dp onIsFullyVisibleChanged: {
height: (showTopMargin ? 30 : 0 * DefaultStyle.dp) + eventItem.height if (index === mainItem.count - 1) {
EphemeralEvent { mainItem.lastItemVisible = isFullyVisible
id: eventItem }
anchors.top: parent.top }
anchors.topMargin: showTopMargin ? 30 : 0 * DefaultStyle.dp property bool showTopMargin: !header.visible && index == 0
eventLogGui: modelData width: mainItem.width
} //height: 40 * DefaultStyle.dp
} height: (showTopMargin ? 30 : 0 * DefaultStyle.dp) + eventItem.height
EphemeralEvent {
id: eventItem
anchors.top: parent.top
anchors.topMargin: showTopMargin ? 30 : 0 * DefaultStyle.dp
eventLogGui: modelData
}
}
} }
} }

View file

@ -27,7 +27,7 @@ TextEdit {
property var encodeTextObj: visible ? UtilsCpp.encodeTextToQmlRichFormat(contentGui.core.utf8Text, {}, mainItem.chatGui) property var encodeTextObj: visible ? UtilsCpp.encodeTextToQmlRichFormat(contentGui.core.utf8Text, {}, mainItem.chatGui)
: '' : ''
text: encodeTextObj ? encodeTextObj.value : "" text: encodeTextObj && encodeTextObj.value || ""
textFormat: Text.RichText // To supports links and imgs. textFormat: Text.RichText // To supports links and imgs.
wrapMode: TextEdit.Wrap wrapMode: TextEdit.Wrap
@ -43,11 +43,10 @@ TextEdit {
} }
onSelectedTextChanged:{ onSelectedTextChanged:{
if(selectedText != '') lastTextSelected = selectedText if(selectedText != '') lastTextSelected = selectedText
// else { }
// if(mouseArea.keepLastSelection) { onLinkHovered: {
// mouseArea.keepLastSelection = false if (hoveredLink !== "") UtilsCpp.setGlobalCursor(Qt.PointingHandCursor)
// } else UtilsCpp.restoreGlobalCursor()
// }
} }
onActiveFocusChanged: { onActiveFocusChanged: {
if(activeFocus) { if(activeFocus) {

View file

@ -17,20 +17,23 @@ Item {
property string thumbnail: contentGui && contentGui.core.thumbnail property string thumbnail: contentGui && contentGui.core.thumbnail
property string name: contentGui && contentGui.core.name property string name: contentGui && contentGui.core.name
property string filePath: contentGui && contentGui.core.filePath property string filePath: contentGui && contentGui.core.filePath
property bool active: true
property real animationScale : FileViewStyle.animation.to
property alias imageScale: thumbnailProvider.scale
property bool wasDownloaded: contentGui && contentGui.core.wasDownloaded property bool wasDownloaded: contentGui && contentGui.core.wasDownloaded
property bool isAnimatedImage : contentGui && contentGui.core.wasDownloaded && UtilsCpp.isAnimatedImage(filePath) property bool isAnimatedImage : contentGui && contentGui.core.wasDownloaded && UtilsCpp.isAnimatedImage(filePath)
property bool haveThumbnail: contentGui && UtilsCpp.canHaveThumbnail(filePath) property bool haveThumbnail: contentGui && UtilsCpp.canHaveThumbnail(filePath)
property int fileSize: contentGui ? contentGui.core.fileSize : 0 property int fileSize: contentGui ? contentGui.core.fileSize : 0
property bool isTransferring property bool isTransferring
property bool isVideo: UtilsCpp.isVideo(filePath)
property bool isImage: UtilsCpp.isImage(filePath)
property bool isPdf: UtilsCpp.isPdf(filePath)
property bool isThumbnail: isVideo || isImage || isPdf
property int overriddenWidth
property int overriddenHeight
Connections { Connections {
enabled: contentGui enabled: contentGui
target: contentGui.core target: contentGui.core
function onMsgStateChanged(state) { function onMsgStateChanged(state) {
isTransferring = state === LinphoneEnums.ChatMessageState.StateFileTransferInProgress mainItem.isTransferring = state === LinphoneEnums.ChatMessageState.StateFileTransferInProgress
|| state === LinphoneEnums.ChatMessageState.StateInProgress || state === LinphoneEnums.ChatMessageState.StateInProgress
} }
} }

View file

@ -145,7 +145,7 @@ Control.Control{
Layout.preferredHeight: Math.round(26 * DefaultStyle.dp) Layout.preferredHeight: Math.round(26 * DefaultStyle.dp)
Layout.fillHeight: true Layout.fillHeight: true
Layout.leftMargin: Math.round(40 * DefaultStyle.dp) Layout.leftMargin: Math.round(40 * DefaultStyle.dp)
visible: mainItem.account.core.unreadCallNotifications > 0 visible: mainItem.account.core.unreadNotifications > 0
Rectangle{ Rectangle{
id: unreadNotifications id: unreadNotifications
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
@ -166,7 +166,7 @@ Control.Control{
fontSizeMode: Text.Fit fontSizeMode: Text.Fit
font.pixelSize: Math.round(11 * DefaultStyle.dp) font.pixelSize: Math.round(11 * DefaultStyle.dp)
font.weight: Math.round(700 * DefaultStyle.dp) font.weight: Math.round(700 * DefaultStyle.dp)
text: mainItem.account.core.unreadCallNotifications >= 100 ? '99+' : mainItem.account.core.unreadCallNotifications text: mainItem.account.core.unreadNotifications >= 100 ? '99+' : mainItem.account.core.unreadNotifications
} }
} }
MultiEffect { MultiEffect {

View file

@ -58,7 +58,7 @@ Control.Control {
// height: mainItem.height // height: mainItem.height
leftPadding: Math.round(15 * DefaultStyle.dp) leftPadding: Math.round(15 * DefaultStyle.dp)
rightPadding: Math.round(15 * DefaultStyle.dp) rightPadding: Math.round(15 * DefaultStyle.dp)
topPadding: Math.round(24 * DefaultStyle.dp) topPadding: Math.round(16 * DefaultStyle.dp)
bottomPadding: Math.round(16 * DefaultStyle.dp) bottomPadding: Math.round(16 * DefaultStyle.dp)
background: Rectangle { background: Rectangle {
anchors.fill: parent anchors.fill: parent
@ -67,6 +67,10 @@ Control.Control {
contentItem: Control.StackView { contentItem: Control.StackView {
id: sendingAreaStackView id: sendingAreaStackView
initialItem: textAreaComp initialItem: textAreaComp
width: currentItem.width
onHeightChanged: {
mainItem.height = height + mainItem.topPadding + mainItem.bottomPadding
}
Component { Component {
id: textAreaComp id: textAreaComp
RowLayout { RowLayout {
@ -97,11 +101,16 @@ Control.Control {
} }
} }
Control.Control { Control.Control {
id: sendingControl
onHeightChanged: {
sendingAreaStackView.height = height
}
Layout.fillWidth: true Layout.fillWidth: true
leftPadding: Math.round(15 * DefaultStyle.dp) Layout.alignment: Qt.AlignCenter
rightPadding: Math.round(15 * DefaultStyle.dp) leftPadding: Math.round(24 * DefaultStyle.dp)
topPadding: Math.round(15 * DefaultStyle.dp) rightPadding: Math.round(20 * DefaultStyle.dp)
bottomPadding: Math.round(15 * DefaultStyle.dp) topPadding: Math.round(12 * DefaultStyle.dp)
bottomPadding: Math.round(12 * DefaultStyle.dp)
background: Rectangle { background: Rectangle {
id: inputBackground id: inputBackground
anchors.fill: parent anchors.fill: parent
@ -116,7 +125,7 @@ Control.Control {
contentItem: RowLayout { contentItem: RowLayout {
Flickable { Flickable {
id: sendingAreaFlickable id: sendingAreaFlickable
Layout.preferredHeight: Math.min(Math.round(60 * DefaultStyle.dp), contentHeight) Layout.preferredHeight: Math.min(Math.round(100 * DefaultStyle.dp), contentHeight)
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
contentHeight: sendingTextArea.contentHeight contentHeight: sendingTextArea.contentHeight
@ -224,6 +233,9 @@ Control.Control {
} }
ChatAudioContent { ChatAudioContent {
id: voiceMessage id: voiceMessage
onHeightChanged: {
sendingAreaStackView.height = height
}
recording: true recording: true
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Math.round(48 * DefaultStyle.dp) Layout.preferredHeight: Math.round(48 * DefaultStyle.dp)

View file

@ -213,7 +213,7 @@ RowLayout {
Control.Control { Control.Control {
id: participantListPopup id: participantListPopup
width: parent.width width: parent.width
height: Math.min(contentItem.height, Math.round(200 * DefaultStyle.dp)) height: Math.min(participantInfoList.height, Math.round(200 * DefaultStyle.dp))
visible: false visible: false
anchors.bottom: chatMessagesListView.bottom anchors.bottom: chatMessagesListView.bottom
anchors.left: chatMessagesListView.left anchors.left: chatMessagesListView.left
@ -378,7 +378,7 @@ RowLayout {
} }
ChatDroppableTextArea { ChatDroppableTextArea {
id: messageSender id: messageSender
Control.SplitView.preferredHeight: mainItem.chat.core.isReadOnly ? 0 : Math.round(79 * DefaultStyle.dp) Control.SplitView.preferredHeight: mainItem.chat.core.isReadOnly ? 0 : height
Control.SplitView.minimumHeight: mainItem.chat.core.isReadOnly ? 0 : Math.round(79 * DefaultStyle.dp) Control.SplitView.minimumHeight: mainItem.chat.core.isReadOnly ? 0 : Math.round(79 * DefaultStyle.dp)
chat: mainItem.chat chat: mainItem.chat
onChatChanged: { onChatChanged: {