enlarge video size if single file sent

wait for chat messages model to be reset before changing chat (fix #LINQT-2011)
This commit is contained in:
Gaelle Braud 2025-10-02 11:38:07 +02:00
parent 924224abc5
commit 8a2e842cd7
7 changed files with 151 additions and 27 deletions

View file

@ -81,31 +81,53 @@ void EventLogList::connectItem(const QSharedPointer<EventLogCore> &item) {
}
}
void EventLogList::setIsUpdating(bool updating) {
if (mIsUpdating != updating) {
mIsUpdating = updating;
emit isUpdatingChanged();
}
}
void EventLogList::setChatCore(QSharedPointer<ChatCore> core) {
if (mChatCore != core) {
if (mChatCore) {
disconnect(mChatCore.get(), &ChatCore::eventsInserted, this, nullptr);
auto updateChatCore = [this](QSharedPointer<ChatCore> core) {
if (mChatCore != core) {
if (mChatCore) {
disconnect(mChatCore.get(), &ChatCore::eventsInserted, this, nullptr);
disconnect(mChatCore.get(), &ChatCore::eventListCleared, this, nullptr);
}
mChatCore = core;
if (mChatCore) {
connect(mChatCore.get(), &ChatCore::eventListCleared, this, [this] { resetData(); });
connect(mChatCore.get(), &ChatCore::eventsInserted, this,
[this](QList<QSharedPointer<EventLogCore>> list) {
auto eventsList = getSharedList<EventLogCore>();
for (auto &event : list) {
auto it = std::find_if(
eventsList.begin(), eventsList.end(),
[event](const QSharedPointer<EventLogCore> item) { return item == event; });
if (it == eventsList.end()) {
connectItem(event);
add(event);
int index;
get(event.get(), &index);
emit eventInserted(index, new EventLogGui(event));
}
}
});
}
lUpdate();
emit chatGuiChanged();
}
mChatCore = core;
if (mChatCore) {
connect(mChatCore.get(), &ChatCore::eventListCleared, this, [this] { resetData(); });
connect(mChatCore.get(), &ChatCore::eventsInserted, this, [this](QList<QSharedPointer<EventLogCore>> list) {
auto eventsList = getSharedList<EventLogCore>();
for (auto &event : list) {
auto it = std::find_if(eventsList.begin(), eventsList.end(),
[event](const QSharedPointer<EventLogCore> item) { return item == event; });
if (it == eventsList.end()) {
connectItem(event);
add(event);
int index;
get(event.get(), &index);
emit eventInserted(index, new EventLogGui(event));
}
}
});
}
lUpdate();
emit chatGuiChanged();
};
if (mIsUpdating) {
connect(this, &EventLogList::isUpdatingChanged, this, [this, core, updateChatCore] {
if (!mIsUpdating) {
updateChatCore(core);
disconnect(this, &EventLogList::isUpdatingChanged, this, nullptr);
}
});
} else {
updateChatCore(core);
}
}
@ -160,15 +182,19 @@ void EventLogList::setSelf(QSharedPointer<EventLogList> me) {
mCoreModelConnection->makeConnectToCore(&EventLogList::lUpdate, [this]() {
mustBeInMainThread(log().arg(Q_FUNC_INFO));
if (mChatCore) qDebug() << "reset messages model for chat core" << mChatCore << mChatCore->getTitle();
setIsUpdating(true);
beginResetModel();
mList.clear();
if (!mChatCore) {
endResetModel();
setIsUpdating(false);
return;
}
auto chatModel = mChatCore->getModel();
if (!chatModel) {
endResetModel();
setIsUpdating(false);
return;
}
mCoreModelConnection->invokeToModel([this, chatModel]() {
@ -193,6 +219,7 @@ void EventLogList::setSelf(QSharedPointer<EventLogList> me) {
for (auto i : *events)
mList << i.template objectCast<QObject>();
endResetModel();
setIsUpdating(false);
});
});
});

View file

@ -48,6 +48,8 @@ public:
void connectItem(const QSharedPointer<EventLogCore> &item);
void disconnectItem(const QSharedPointer<EventLogCore> &item);
void setIsUpdating(bool updating);
int findFirstUnreadIndex();
void findChatMessageWithFilter(QString filter,
@ -66,12 +68,14 @@ signals:
void messageWithFilterFound(int index);
void listAboutToBeReset();
void chatGuiChanged();
void isUpdatingChanged();
private:
QString mFilter;
QSharedPointer<ChatCore> mChatCore;
QSharedPointer<SafeConnection<ChatCore, ChatModel>> mChatModelConnection;
QSharedPointer<SafeConnection<EventLogList, CoreModel>> mCoreModelConnection;
bool mIsUpdating = false;
DECLARE_ABSTRACT_OBJECT
};

View file

@ -69,6 +69,7 @@ list(APPEND _LINPHONEAPP_QML_FILES
view/Control/Display/Chat/FileView.qml
view/Control/Display/Chat/ImageFileView.qml
view/Control/Display/Chat/AnimatedImageFileView.qml
view/Control/Display/Chat/VideoFileView.qml
view/Control/Display/Contact/Avatar.qml
view/Control/Display/Contact/Contact.qml
view/Control/Display/Contact/Presence.qml

View file

@ -2,6 +2,8 @@ import QtQuick
import QtQuick.Effects
import QtQuick.Layouts
import QtQuick.Controls.Basic as Control
import QtMultimedia
import Linphone
import UtilsCpp
@ -98,12 +100,27 @@ ColumnLayout {
Layout.alignment: Qt.AlignHCenter
fillMode: Image.PreserveAspectFit
}
VideoFileView {
id: singleVideoFile
visible: mainItem.filescontentProxy.count === 1 && UtilsCpp.isVideo(contentGui.core.filePath)
contentGui: mainItem.filescontentProxy.count === 1
? mainItem.filescontentProxy.getChatMessageContentAtIndex(0)
: null
width: Math.round(285 * DefaultStyle.dp)
height: Math.round(285 * DefaultStyle.dp)
Layout.preferredWidth: videoOutput.contentRect.width
Layout.preferredHeight: videoOutput.contentRect.height
Layout.alignment: Qt.AlignHCenter
fillMode: VideoOutput.PreserveAspectFit
}
// FILES
ChatFilesGridLayout {
id: messageFilesList
visible: mainItem.filescontentProxy.count > 0
&& !singleImageFile.visible
&& !singleAnimatedImageFile.visible
&& !singleVideoFile.visible
Layout.fillWidth: visible
Layout.fillHeight: visible
maxWidth: Math.round(115*3 * DefaultStyle.dp)

View file

@ -93,13 +93,16 @@ ListView {
markIndexAsRead(index)
}
}
onModelAboutToBeReset: loading = true
onModelReset: Qt.callLater(function() {
onModelAboutToBeReset: {
loading = true
}
onModelReset: {
loading = false
var index = eventLogProxy.findFirstUnreadIndex()
positionViewAtIndex(index, ListView.Beginning)
eventLogProxy.markIndexAsRead(index)
})
}
onChatGuiChanged: forceLayout()
onIndexWithFilterFound: (index) => {
if (index !== -1) {
currentIndex = index

View file

@ -0,0 +1,72 @@
import QtQuick
import QtQuick.Controls as Control
import QtQuick.Layouts
import QtMultimedia
import Linphone
import UtilsCpp
import 'qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js' as Utils
// =============================================================================
Rectangle {
id: mainItem
color: "transparent"//DefaultStyle.grey_1000
property ChatMessageContentGui contentGui
property string filePath: contentGui && contentGui.core.filePath
property var fillMode: playbackState === MediaPlayer.PlayingState ? VideoOutput.PreserveAspectFit : VideoOutput.PreserveAspectCrop
property alias videoOutput: output
property string source: mediaPlayer.source
MediaPlayer {
id: mediaPlayer
source: UtilsCpp.isVideo(mainItem.filePath) ? "file:///" + mainItem.filePath : ""
position: 100
videoOutput: output
}
VideoOutput {
id: output
fillMode: mainItem.fillMode
endOfStreamPolicy: VideoOutput.KeepLastFrame
width: mainItem.width
height: mainItem.height
Component.onCompleted: {
// We need to start the video so the content rect of the
// video output is updated
mediaPlayer.play()
mediaPlayer.pause()
}
Text {
z: parent.z + 1
property int timeDisplayed: mediaPlayer.playbackState === MediaPlayer.PlayingState ? mediaPlayer.position : mediaPlayer.duration
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.bottomMargin: Math.round(6 * DefaultStyle.dp)
anchors.leftMargin: Math.round(6 * DefaultStyle.dp)
text: UtilsCpp.formatDuration(timeDisplayed)
color: DefaultStyle.grey_0
font {
pixelSize: Typography.d1.pixelSize
weight: Typography.d1.weight
}
}
}
MouseArea {
propagateComposedEvents: false
enabled: mainItem.visible
anchors.fill: parent
hoverEnabled: false
acceptedButtons: Qt.LeftButton
onClicked: (mouse) => {
mouse.accepted = true
mediaPlayer.playbackState === MediaPlayer.PlayingState ? mediaPlayer.pause() : mediaPlayer.play()
}
}
EffectImage {
anchors.centerIn: parent
visible: mediaPlayer.playbackState !== MediaPlayer.PlayingState
width: Math.round(24 * DefaultStyle.dp)
height: Math.round(24 * DefaultStyle.dp)
imageSource: AppIcons.playFill
colorizationColor: DefaultStyle.main2_0
}
}

View file

@ -12,7 +12,7 @@ MessageInfosLayout {
tabbarModel: chatMessageGui ? chatMessageGui.core.imdnStatusListAsString : []
listModel: ImdnStatusProxy {
imdnStatusList: chatMessageGui ? chatMessageGui.core.imdnStatusList : []
filter: chatMessageGui && chatMessageGui.core.imdnStatusAsSingletons[mainItem.tabbar.currentIndex]?.state || ""
filter: chatMessageGui && chatMessageGui.core.imdnStatusAsSingletons[mainItem.tabbar.currentIndex]?.state || LinphoneEnums.ChatMessageState.StateIdle
}
listView.delegate: Item {