diff --git a/CHANGELOG.md b/CHANGELOG.md
index 024ce7e20..e07a0a005 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- OAuth2 connection to retrieve remote provisioning (Experimental and not usable without configuration).
- Add/View contact from a message.
- Mute option for each chatrooms.
+- New Chat Layout.
## 5.0.11 - undefined
diff --git a/linphone-app/assets/languages/da.ts b/linphone-app/assets/languages/da.ts
index 86f306933..d59b94375 100644
--- a/linphone-app/assets/languages/da.ts
+++ b/linphone-app/assets/languages/da.ts
@@ -2215,6 +2215,11 @@ Klik her: <a href="%1">%1</a>
'New messages received!' Notification that warn the user of new messages.
+
+ newConferenceInvitation
+ 'Conference invitation received!' : Notification about receiving an invitation to a conference.
+
+
OnlineInstallerDialog
diff --git a/linphone-app/assets/languages/de.ts b/linphone-app/assets/languages/de.ts
index d1be49498..de0b005d8 100644
--- a/linphone-app/assets/languages/de.ts
+++ b/linphone-app/assets/languages/de.ts
@@ -2215,6 +2215,11 @@ Klicken Sie hier: <a href="%1">%1</a>
'New messages received!' Notification that warn the user of new messages.
+
+ newConferenceInvitation
+ 'Conference invitation received!' : Notification about receiving an invitation to a conference.
+
+
OnlineInstallerDialog
diff --git a/linphone-app/assets/languages/en.ts b/linphone-app/assets/languages/en.ts
index ce34206f0..3146b9396 100644
--- a/linphone-app/assets/languages/en.ts
+++ b/linphone-app/assets/languages/en.ts
@@ -2215,6 +2215,11 @@ Click here: <a href="%1">%1</a>
'New messages received!' Notification that warn the user of new messages.
New messages received!
+
+ newConferenceInvitation
+ 'Conference invitation received!' : Notification about receiving an invitation to a conference.
+ Conference invitation received!
+
OnlineInstallerDialog
diff --git a/linphone-app/assets/languages/es.ts b/linphone-app/assets/languages/es.ts
index ebd873a8e..f16ebb924 100644
--- a/linphone-app/assets/languages/es.ts
+++ b/linphone-app/assets/languages/es.ts
@@ -2215,6 +2215,11 @@ Haga clic aquí: <a href="%1">%1 </a>
'New messages received!' Notification that warn the user of new messages.
+
+ newConferenceInvitation
+ 'Conference invitation received!' : Notification about receiving an invitation to a conference.
+
+
OnlineInstallerDialog
diff --git a/linphone-app/assets/languages/fr_FR.ts b/linphone-app/assets/languages/fr_FR.ts
index 771ed783e..c0da5979f 100644
--- a/linphone-app/assets/languages/fr_FR.ts
+++ b/linphone-app/assets/languages/fr_FR.ts
@@ -2215,6 +2215,11 @@ Cliquez ici : <a href="%1">%1</a>
'New messages received!' Notification that warn the user of new messages.
Nouveaux messages arrivés !
+
+ newConferenceInvitation
+ 'Conference invitation received!' : Notification about receiving an invitation to a conference.
+
+
OnlineInstallerDialog
diff --git a/linphone-app/assets/languages/hu.ts b/linphone-app/assets/languages/hu.ts
index d284ab57e..255eb9672 100644
--- a/linphone-app/assets/languages/hu.ts
+++ b/linphone-app/assets/languages/hu.ts
@@ -2202,6 +2202,11 @@ Kattintson ide: <a href="%1">%1</a>
'New messages received!' Notification that warn the user of new messages.
+
+ newConferenceInvitation
+ 'Conference invitation received!' : Notification about receiving an invitation to a conference.
+
+
OnlineInstallerDialog
diff --git a/linphone-app/assets/languages/it.ts b/linphone-app/assets/languages/it.ts
index 585b308c1..a32597a2c 100644
--- a/linphone-app/assets/languages/it.ts
+++ b/linphone-app/assets/languages/it.ts
@@ -2215,6 +2215,11 @@ Clicca: <a href="%1">%1</a>
'New messages received!' Notification that warn the user of new messages.
E' stato ricevuto un nuovo messaggio!
+
+ newConferenceInvitation
+ 'Conference invitation received!' : Notification about receiving an invitation to a conference.
+
+
OnlineInstallerDialog
diff --git a/linphone-app/assets/languages/ja.ts b/linphone-app/assets/languages/ja.ts
index e881da227..a59dfe225 100644
--- a/linphone-app/assets/languages/ja.ts
+++ b/linphone-app/assets/languages/ja.ts
@@ -2202,6 +2202,11 @@
'New messages received!' Notification that warn the user of new messages.
+
+ newConferenceInvitation
+ 'Conference invitation received!' : Notification about receiving an invitation to a conference.
+
+
OnlineInstallerDialog
diff --git a/linphone-app/assets/languages/lt.ts b/linphone-app/assets/languages/lt.ts
index 3fbd15949..0650c5675 100644
--- a/linphone-app/assets/languages/lt.ts
+++ b/linphone-app/assets/languages/lt.ts
@@ -2228,6 +2228,11 @@ Spustelėkite čia: <a href="%1">%1</a>
'New messages received!' Notification that warn the user of new messages.
+
+ newConferenceInvitation
+ 'Conference invitation received!' : Notification about receiving an invitation to a conference.
+
+
OnlineInstallerDialog
diff --git a/linphone-app/assets/languages/pt_BR.ts b/linphone-app/assets/languages/pt_BR.ts
index cd0007ef0..305a3715a 100644
--- a/linphone-app/assets/languages/pt_BR.ts
+++ b/linphone-app/assets/languages/pt_BR.ts
@@ -2215,6 +2215,11 @@ Clique aqui: <a href="%1">%1 </a>
'New messages received!' Notification that warn the user of new messages.
+
+ newConferenceInvitation
+ 'Conference invitation received!' : Notification about receiving an invitation to a conference.
+
+
OnlineInstallerDialog
diff --git a/linphone-app/assets/languages/ru.ts b/linphone-app/assets/languages/ru.ts
index e92ae1bc4..be17030fe 100644
--- a/linphone-app/assets/languages/ru.ts
+++ b/linphone-app/assets/languages/ru.ts
@@ -2228,6 +2228,11 @@
'New messages received!' Notification that warn the user of new messages.
Получены новые сообщения!
+
+ newConferenceInvitation
+ 'Conference invitation received!' : Notification about receiving an invitation to a conference.
+
+
OnlineInstallerDialog
diff --git a/linphone-app/assets/languages/sv.ts b/linphone-app/assets/languages/sv.ts
index 52c4bd2a3..71c4e24d6 100644
--- a/linphone-app/assets/languages/sv.ts
+++ b/linphone-app/assets/languages/sv.ts
@@ -2215,6 +2215,11 @@ Klicka här: <a href="%1">%1</a>
'New messages received!' Notification that warn the user of new messages.
+
+ newConferenceInvitation
+ 'Conference invitation received!' : Notification about receiving an invitation to a conference.
+
+
OnlineInstallerDialog
diff --git a/linphone-app/assets/languages/tr.ts b/linphone-app/assets/languages/tr.ts
index 83631d8fe..d1c333740 100644
--- a/linphone-app/assets/languages/tr.ts
+++ b/linphone-app/assets/languages/tr.ts
@@ -2202,6 +2202,11 @@ Buraya tıklayın: <a href="%1">%1</a>
'New messages received!' Notification that warn the user of new messages.
+
+ newConferenceInvitation
+ 'Conference invitation received!' : Notification about receiving an invitation to a conference.
+
+
OnlineInstallerDialog
diff --git a/linphone-app/assets/languages/uk.ts b/linphone-app/assets/languages/uk.ts
index 5e7e2bca5..068e51048 100644
--- a/linphone-app/assets/languages/uk.ts
+++ b/linphone-app/assets/languages/uk.ts
@@ -2228,6 +2228,11 @@
'New messages received!' Notification that warn the user of new messages.
+
+ newConferenceInvitation
+ 'Conference invitation received!' : Notification about receiving an invitation to a conference.
+
+
OnlineInstallerDialog
diff --git a/linphone-app/assets/languages/zh_CN.ts b/linphone-app/assets/languages/zh_CN.ts
index 9b5e16f57..37186c1bd 100644
--- a/linphone-app/assets/languages/zh_CN.ts
+++ b/linphone-app/assets/languages/zh_CN.ts
@@ -2202,6 +2202,11 @@
'New messages received!' Notification that warn the user of new messages.
+
+ newConferenceInvitation
+ 'Conference invitation received!' : Notification about receiving an invitation to a conference.
+
+
OnlineInstallerDialog
diff --git a/linphone-app/resources.qrc b/linphone-app/resources.qrc
index e82f84e91..8cb1da927 100644
--- a/linphone-app/resources.qrc
+++ b/linphone-app/resources.qrc
@@ -331,6 +331,7 @@
ui/modules/Linphone/Chat/Chat.qml
ui/modules/Linphone/Chat/ChatContent.qml
ui/modules/Linphone/Chat/ChatDeliveries.qml
+ ui/modules/Linphone/Chat/ChatFullContent.qml
ui/modules/Linphone/Chat/ChatMenu.qml
ui/modules/Linphone/Chat/ChatAudioMessage.qml
ui/modules/Linphone/Chat/ChatAudioPreview.qml
diff --git a/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp b/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp
index fd37071b3..75e6b10ae 100644
--- a/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp
+++ b/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp
@@ -40,9 +40,9 @@ QString ChatRoomProxyModel::gCachedText;
// =============================================================================
-ChatRoomProxyModel::ChatRoomProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
+ChatRoomProxyModel::ChatRoomProxyModel (QObject *parent) : SortFilterProxyModel(parent) {
mMarkAsReadEnabled = true;
-
+ mDeleteSourceModel= false;
App *app = App::getInstance();
QObject::connect(app->getMainWindow(), &QWindow::activeChanged, this, [this]() {
handleIsActiveChanged(App::getInstance()->getMainWindow());
diff --git a/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp b/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp
index 39a5dc675..95866a746 100644
--- a/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp
+++ b/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp
@@ -21,7 +21,7 @@
#ifndef CHAT_ROOM_PROXY_MODEL_H_
#define CHAT_ROOM_PROXY_MODEL_H_
-#include
+#include "app/proxyModel/SortFilterProxyModel.hpp"
#include "ChatRoomModel.hpp"
@@ -29,7 +29,7 @@
class QWindow;
-class ChatRoomProxyModel : public QSortFilterProxyModel {
+class ChatRoomProxyModel : public SortFilterProxyModel {
class ChatRoomModelFilter;
Q_OBJECT
diff --git a/linphone-app/src/components/content/ContentProxyModel.cpp b/linphone-app/src/components/content/ContentProxyModel.cpp
index 0d140a06d..285861fd4 100644
--- a/linphone-app/src/components/content/ContentProxyModel.cpp
+++ b/linphone-app/src/components/content/ContentProxyModel.cpp
@@ -63,9 +63,25 @@ bool ContentProxyModel::filterAcceptsRow (
int sourceRow,
const QModelIndex &sourceParent
) const {
- Q_UNUSED(sourceRow)
- Q_UNUSED(sourceParent)
- return true;
+
+ bool show = false;
+
+ if (mFilter == FilterContentType::All)
+ show = true;
+ else{
+ QModelIndex index = sourceModel()->index(sourceRow, 0, QModelIndex());
+ auto contentModel = sourceModel()->data(index).value();
+
+ if( mFilter == FilterContentType::Text && contentModel->isText())
+ show = true;
+ else if( mFilter == FilterContentType::Voice && contentModel->isVoiceRecording())
+ show = true;
+ else if( mFilter == FilterContentType::Conference && contentModel->getConferenceInfoModel())
+ show = true;
+ else if( mFilter == FilterContentType::File && !contentModel->isIcalendar() && (contentModel->isFile() || contentModel->isFileTransfer()|| contentModel->isFileEncrypted()) && !contentModel->isVoiceRecording() )
+ show = true;
+ }
+ return show;
}
bool ContentProxyModel::lessThan (const QModelIndex &left, const QModelIndex &right) const {
@@ -98,4 +114,15 @@ void ContentProxyModel::remove(ContentModel * model){
void ContentProxyModel::clear(){
qobject_cast(sourceModel())->clear();
+}
+
+ContentProxyModel::FilterContentType ContentProxyModel::getFilter() const{
+ return mFilter;
+}
+void ContentProxyModel::setFilter(const FilterContentType& contentType){
+ if(contentType != mFilter){
+ mFilter = contentType;
+ emit filterChanged();
+ invalidate();
+ }
}
\ No newline at end of file
diff --git a/linphone-app/src/components/content/ContentProxyModel.hpp b/linphone-app/src/components/content/ContentProxyModel.hpp
index d0e6c75f9..fa4055e7b 100644
--- a/linphone-app/src/components/content/ContentProxyModel.hpp
+++ b/linphone-app/src/components/content/ContentProxyModel.hpp
@@ -39,10 +39,24 @@ class ContentProxyModel : public QSortFilterProxyModel {
public:
ContentProxyModel (QObject *parent = nullptr);
Q_PROPERTY(ChatMessageModel * chatMessageModel READ getChatMessageModel WRITE setChatMessageModel NOTIFY chatMessageModelChanged)
+ Q_PROPERTY(FilterContentType filter READ getFilter WRITE setFilter NOTIFY filterChanged)
+
+ enum FilterContentType {
+ All,
+ File,
+ Text,
+ Voice,
+ Conference,
+ Unknown
+ };
+ Q_ENUM(FilterContentType)
ChatMessageModel * getChatMessageModel() const;
+
void setChatMessageModel(ChatMessageModel * message);
+ FilterContentType getFilter() const;
+ void setFilter(const FilterContentType& contentType);
Q_INVOKABLE void setContentListModel(ContentListModel * model);
Q_INVOKABLE void addFile(const QString& path);
Q_INVOKABLE void remove(ContentModel * model);
@@ -50,13 +64,14 @@ public:
signals:
void chatMessageModelChanged();
+ void filterChanged();
protected:
virtual bool filterAcceptsRow (int sourceRow, const QModelIndex &sourceParent) const override;
virtual bool lessThan (const QModelIndex &left, const QModelIndex &right) const override;
std::shared_ptr mContents;
-
+ FilterContentType mFilter = All;
};
#endif
diff --git a/linphone-app/src/components/notifier/Notifier.cpp b/linphone-app/src/components/notifier/Notifier.cpp
index 75a707824..498377128 100644
--- a/linphone-app/src/components/notifier/Notifier.cpp
+++ b/linphone-app/src/components/notifier/Notifier.cpp
@@ -288,6 +288,9 @@ void Notifier::notifyReceivedMessages (const listhasConferenceInvitationContent())
+ //: 'Conference invitation received!' : Notification about receiving an invitation to a conference.
+ txt = tr("newConferenceInvitation");
}else
//: 'New messages received!' Notification that warn the user of new messages.
txt = tr("newChatRoomMessages");
diff --git a/linphone-app/src/components/other/colors/ColorListModel.hpp b/linphone-app/src/components/other/colors/ColorListModel.hpp
index 2f386f48c..3ca9d7bdf 100644
--- a/linphone-app/src/components/other/colors/ColorListModel.hpp
+++ b/linphone-app/src/components/other/colors/ColorListModel.hpp
@@ -76,8 +76,14 @@ class ColorListModel : public ProxyListModel {
ADD_COLOR("n", "#A1A1A1", "Primary color for pressed button")
ADD_COLOR("o", "#D0D8DE", "Primary color for disabled button")
- ADD_COLOR("outgoing_bg","#F3F3F3","Outgoing message background")
- ADD_COLOR("incoming_bg","#D0D8DE","Incoming message background")
+ ADD_COLOR("outgoing_bg","#FFEEE5","Outgoing message background")
+ ADD_COLOR("incoming_bg","#F3F3F3","Incoming message background")
+
+ ADD_COLOR("outgoing_reply_mark_bg","#FF9E67","Outgoing reply message mark background")
+ ADD_COLOR("incoming_reply_mark_bg","#9B9B9B","Incoming reply message mark background")
+
+ ADD_COLOR("reply_file_bg","#F4F4F4","File icon background in reply")
+ ADD_COLOR("extension_file_border","#DEDEDE","File icon border in reply")
ADD_COLOR("primary_accept", "#9ECD1D", "Primary color for accepting button")
diff --git a/linphone-app/src/utils/Utils.cpp b/linphone-app/src/utils/Utils.cpp
index a2d963991..51840c771 100644
--- a/linphone-app/src/utils/Utils.cpp
+++ b/linphone-app/src/utils/Utils.cpp
@@ -125,8 +125,8 @@ QString Utils::toTimeString(QDateTime date, const QString& format){
return getOffsettedUTC(date).toString(format);
}
-QString Utils::toDateString(QDateTime date){
- return getOffsettedUTC(date).toString("yyyy/MM/dd");
+QString Utils::toDateString(QDateTime date, const QString& format){
+ return getOffsettedUTC(date).toString(format);
}
QString Utils::getDisplayName(const QString& address){
diff --git a/linphone-app/src/utils/Utils.hpp b/linphone-app/src/utils/Utils.hpp
index 4c82dfc67..b14104e9b 100644
--- a/linphone-app/src/utils/Utils.hpp
+++ b/linphone-app/src/utils/Utils.hpp
@@ -61,7 +61,7 @@ public:
static QDateTime getOffsettedUTC(const QDateTime& date);
Q_INVOKABLE static QString toDateTimeString(QDateTime date);
Q_INVOKABLE static QString toTimeString(QDateTime date, const QString& format = "hh:mm:ss");
- Q_INVOKABLE static QString toDateString(QDateTime date);
+ Q_INVOKABLE static QString toDateString(QDateTime date, const QString& format = "yyyy/MM/dd");
Q_INVOKABLE static QString getDisplayName(const QString& address);
Q_INVOKABLE static QString getInitials(const QString& username); // Support UTF32
Q_INVOKABLE static QString toString(const LinphoneEnums::TunnelMode& mode);
diff --git a/linphone-app/ui/modules/Linphone/Chat/Chat.qml b/linphone-app/ui/modules/Linphone/Chat/Chat.qml
index 3227cffba..4cce4b47e 100644
--- a/linphone-app/ui/modules/Linphone/Chat/Chat.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/Chat.qml
@@ -97,13 +97,7 @@ Rectangle {
container.proxyModel.loadMoreEntriesAsync()
}
}
- section {
- criteria: ViewSection.FullString
- delegate: sectionHeading
- property: '$sectionDate'
- }
// -----------------------------------------------------------------------
-
Component.onCompleted: Logic.initView()
onMovementStarted: {Logic.handleMovementStarted(); chat.isMoving = true}
onMovementEnded: {Logic.handleMovementEnded(); chat.isMoving = false}
@@ -124,47 +118,6 @@ Rectangle {
}
}
- // -----------------------------------------------------------------------
- // Heading.
- // -----------------------------------------------------------------------
-
- Component {
- id: sectionHeading
-
- Item {
- implicitHeight: container.height + ChatStyle.sectionHeading.bottomMargin
- width: parent.width
- clip: false
- Borders {
- id: container
-
- borderColor: ChatStyle.sectionHeading.border.colorModel.color
- bottomWidth: ChatStyle.sectionHeading.border.width
- implicitHeight: text.contentHeight +
- ChatStyle.sectionHeading.padding * 2 +
- ChatStyle.sectionHeading.border.width * 2
- topWidth: ChatStyle.sectionHeading.border.width
- width: parent.width
-
- Text {
- id: text
-
- anchors.fill: parent
- color: ChatStyle.sectionHeading.text.colorModel.color
- font {
- bold: true
- pointSize: ChatStyle.sectionHeading.text.pointSize
- capitalization: Font.Capitalize
- }
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
-
- text: new Date(section).toLocaleDateString(App.locale)
- }
- }
- }
- }
-
// -----------------------------------------------------------------------
// Message/Event renderer.
// -----------------------------------------------------------------------
@@ -174,7 +127,22 @@ Rectangle {
property bool isNotice : $chatEntry.type === ChatRoomModel.NoticeEntry
property bool isCall : $chatEntry.type === ChatRoomModel.CallEntry
property bool isMessage : $chatEntry.type === ChatRoomModel.MessageEntry
+ property var previousItem : proxyModel.count > 0 && index >0 ? proxyModel.getAt(index-1) : null
+ property var nextItem : proxyModel.count > 0 ? proxyModel.getAt(index+1) : null // bind to count
+ property bool displayDate: !Utils.equalDate(new Date($chatEntry.timestamp), new Date())
+ property bool isTopGrouped: isGrouped(entry.previousItem, $chatEntry) || false
+ property bool isBottomGrouped: isGrouped($chatEntry, entry.nextItem) || false
+ onIsBottomGroupedChanged: if(loader.item) loader.item.isBottomGrouped = isBottomGrouped
+ onIsTopGroupedChanged: if(loader.item) loader.item.isTopGrouped = isTopGrouped
+
+ function isGrouped(item1, item2){
+ return item1 && item2 //Have a previous entry
+ && item1.type == ChatRoomModel.MessageEntry // Previous entry is a message
+ && item2.type == ChatRoomModel.MessageEntry // Previous entry is a message
+ && item2.fromSipAddress == item1.fromSipAddress // Same user
+ && Math.abs((new Date(item2.timestamp)).getTime() - (new Date(item1.timestamp)).getTime())/1000 < 60
+ }
function isHoverEntry () {
return mouseArea.containsMouse
}
@@ -182,23 +150,13 @@ Rectangle {
function removeEntry () {
proxyModel.removeRow(index)
}
-
- anchors {
- left: parent ? parent.left : undefined
- leftMargin: isNotice?0:ChatStyle.entry.leftMargin
- right: parent ? parent.right : undefined
-
- rightMargin: isNotice?0:ChatStyle.entry.deleteIconSize +
- ChatStyle.entry.message.extraContent.spacing +
- ChatStyle.entry.message.extraContent.rightMargin +
- ChatStyle.entry.message.extraContent.leftMargin +
- ChatStyle.entry.message.outgoing.areaSize
- }
-
color: ChatStyle.colorModel.color
- implicitHeight: layout.height + ChatStyle.entry.bottomMargin
+ implicitHeight: layout.height + (entry.isBottomGrouped? 1 : ChatStyle.entry.bottomMargin)
+
+ width: chat.contentWidth // Fill all space
clip: false
+
// ---------------------------------------------------------------------
MouseArea {
@@ -208,51 +166,37 @@ Rectangle {
hoverEnabled: true
implicitHeight: layout.height
width: parent.width + parent.anchors.rightMargin
+ anchors.top: parent.top
+ //anchors.topMargin: (entry.isTopGrouped? 1 : ChatStyle.entry.bottomMargin)
clip: false
acceptedButtons: Qt.NoButton
+ onContainsMouseChanged: if(loader.item) loader.item.isHovering = containsMouse
ColumnLayout{
id: layout
spacing: 0
width: entry.width
- Text{
- id:authorName
- Layout.leftMargin: timeDisplay.width + 10
+ RowLayout{
+ id: headerLayout
Layout.fillWidth: true
- text : $chatEntry.fromDisplayName ? $chatEntry.fromDisplayName : ''
- property var previousItem : {
- if(index >0)
- return proxyModel.getAt(index-1)
- else
- return null
- }
-
- color: ChatStyle.entry.event.text.colorModel.color
- font.pointSize: ChatStyle.entry.event.text.pointSize
- visible: isMessage
- && $chatEntry != undefined
- && !$chatEntry.isOutgoing // Only outgoing
- && (!previousItem //No previous entry
- || previousItem.type != ChatRoomModel.MessageEntry // Previous entry is a message
- || previousItem.fromSipAddress != $chatEntry.fromSipAddress // Different user
- || (new Date(previousItem.timestamp)).setHours(0, 0, 0, 0) != (new Date($chatEntry.timestamp)).setHours(0, 0, 0, 0) // Same day == section
- )
- }
- RowLayout {
-
- spacing: 0
- width: entry.width
-
+ Layout.alignment: Qt.AlignTop | ($chatEntry.isOutgoing ? Qt.AlignRight : Qt.AlignLeft)
+ Layout.leftMargin: ChatStyle.entry.metaWidth// + ChatStyle.entry.message.extraContent.spacing
+ Layout.rightMargin: ChatStyle.entry.message.outgoing.areaSize
+ spacing:0
// Display time.
+ visible: !entry.isTopGrouped
Text {
id:timeDisplay
- Layout.alignment: Qt.AlignTop
- Layout.preferredHeight: ChatStyle.entry.lineHeight
- Layout.preferredWidth: ChatStyle.entry.time.width
+ Layout.alignment: Qt.AlignTop | ($chatEntry.isOutgoing ? Qt.AlignRight : Qt.AlignLeft)
+ Layout.preferredHeight: implicitHeight// ChatStyle.entry.lineHeight
+ //Layout.preferredWidth: ChatStyle.entry.time.width
color: ChatStyle.entry.event.text.colorModel.color
font.pointSize: ChatStyle.entry.time.pointSize
-
- text: UtilsCpp.toTimeString($chatEntry.timestamp, 'hh:mm')
+ property bool displayYear: entry.displayDate && (new Date($chatEntry.timestamp)).getFullYear() != (new Date()).getFullYear()
+ text: $chatEntry
+ ? (entry.displayDate ? UtilsCpp.toDateString($chatEntry.timestamp, (displayYear ? 'yyyy/':'') + 'MM/dd') + ' ' : '')
+ + UtilsCpp.toTimeString($chatEntry.timestamp, 'hh:mm') + (authorName.visible ? ' - ' : '')
+ : ''
verticalAlignment: Text.AlignVCenter
@@ -261,65 +205,85 @@ Rectangle {
}
visible:!isNotice
}
-
- // Display content.
- Loader {
- id: loader
- height: (item !== null && typeof(item)!== 'undefined')? item.height: 0
- Layout.fillWidth: true
- source: Logic.getComponentFromEntry($chatEntry)
- property int loaderIndex: 0 // index of loader from remaining loaders
- property int remainingIndex : loaderIndex % ((chat.remainingLoadersCount) / chat.syncLoaderBatch) != 0 // Check loader index to remaining loader.
- onRemainingIndexChanged: if( remainingIndex == 0 && asynchronous) asynchronous = false
- asynchronous: true
- z:1
-
- onStatusChanged: if( status == Loader.Ready) {
- remainingIndex = -1 // overwrite to remove signal changed. That way, there is no more binding loops.
- --chat.remainingLoadersCount // Loader is ready: remove one from remaining count.
- }
+ Text{
+ id:authorName
+ //Layout.leftMargin: timeDisplay.width + ChatStyle.entry.metaWidth + ChatStyle.entry.message.extraContent.spacing
+ property var displayName: $chatEntry.fromDisplayName ? $chatEntry.fromDisplayName : $chatEntry.name
+ text : displayName != undefined ? displayName : ''
- Component.onCompleted: loaderIndex = ++chat.remainingLoadersCount // on new Loader : one more remaining
- Component.onDestruction: if( status != Loader.Ready) --chat.remainingLoadersCount // Remove remaining count if not loaded
+ color: ChatStyle.entry.event.text.colorModel.color
+ font.pointSize: ChatStyle.entry.event.text.pointSize
+ visible: isMessage
+ && $chatEntry != undefined
+ && !$chatEntry.isOutgoing // Only outgoing
+ && (!entry.previousItem //No previous entry
+ || entry.previousItem.type != ChatRoomModel.MessageEntry // Previous entry is a message
+ || entry.previousItem.fromSipAddress != $chatEntry.fromSipAddress // Different user
+ || (new Date(entry.previousItem.timestamp)).setHours(0, 0, 0, 0) != (new Date($chatEntry.timestamp)).setHours(0, 0, 0, 0) // Same day == section
+ )
+ }
+ }
+ // Display content.
+ Loader {
+ id: loader
+ height: (item !== null && typeof(item)!== 'undefined')? item.height: 0
+ Layout.fillWidth: true
+ source: Logic.getComponentFromEntry($chatEntry)
+ property int loaderIndex: 0 // index of loader from remaining loaders
+ property int remainingIndex : loaderIndex % ((chat.remainingLoadersCount) / chat.syncLoaderBatch) != 0 // Check loader index to remaining loader.
+ onRemainingIndexChanged: if( remainingIndex == 0 && asynchronous) asynchronous = false
+ asynchronous: true
+ z:1
+
+ onStatusChanged: if( status == Loader.Ready) {
+ loader.item.isTopGrouped = entry.isTopGrouped
+ loader.item.isBottomGrouped = entry.isBottomGrouped
+ remainingIndex = -1 // overwrite to remove signal changed. That way, there is no more binding loops.
+ --chat.remainingLoadersCount // Loader is ready: remove one from remaining count.
+ }
+
+ Component.onCompleted: {
+ loaderIndex = ++chat.remainingLoadersCount // on new Loader : one more remaining
+ }
+ Component.onDestruction: if( status != Loader.Ready) --chat.remainingLoadersCount // Remove remaining count if not loaded
+ }
+
+ Connections{
+ target: loader.item
+ ignoreUnknownSignals: true
+ //: "Copied to clipboard" : when a user copy a text from the menu, this message show up.
+ onCopyAllDone: container.noticeBannerText = qsTr("allTextCopied")
+ //: "Selection copied to clipboard" : when a user copy a text from the menu, this message show up.
+ onCopySelectionDone: container.noticeBannerText = qsTr("selectedTextCopied")
+ onReplyClicked: {
+ proxyModel.chatRoomModel.reply = $chatEntry
+ }
+ onForwardClicked:{
+ window.attachVirtualWindow(Qt.resolvedUrl('../Dialog/SipAddressDialog.qml')
+ //: 'Choose where to forward the message' : Dialog title for choosing where to forward the current message.
+ , {title: qsTr('forwardDialogTitle'),
+ addressSelectedCallback: function (sipAddress) {
+ var chat = CallsListModel.createChatRoom( '', proxyModel.chatRoomModel.haveEncryption, [sipAddress], false )
+ if(chat){
+ chat.chatRoomModel.forwardMessage($chatEntry)
+ TimelineListModel.select(chat.chatRoomModel)
+ }
+ },
+ chatRoomSelectedCallback: function (chatRoomModel){
+ if(chatRoomModel){
+ chatRoomModel.forwardMessage($chatEntry)
+ TimelineListModel.select(chatRoomModel)
+ }
+ }
+ })
}
- Connections{
- target: loader.item
- ignoreUnknownSignals: true
- //: "Copied to clipboard" : when a user copy a text from the menu, this message show up.
- onCopyAllDone: container.noticeBannerText = qsTr("allTextCopied")
- //: "Selection copied to clipboard" : when a user copy a text from the menu, this message show up.
- onCopySelectionDone: container.noticeBannerText = qsTr("selectedTextCopied")
- onReplyClicked: {
- proxyModel.chatRoomModel.reply = $chatEntry
- }
- onForwardClicked:{
- window.attachVirtualWindow(Qt.resolvedUrl('../Dialog/SipAddressDialog.qml')
- //: 'Choose where to forward the message' : Dialog title for choosing where to forward the current message.
- , {title: qsTr('forwardDialogTitle'),
- addressSelectedCallback: function (sipAddress) {
- var chat = CallsListModel.createChatRoom( '', proxyModel.chatRoomModel.haveEncryption, [sipAddress], false )
- if(chat){
- chat.chatRoomModel.forwardMessage($chatEntry)
- TimelineListModel.select(chat.chatRoomModel)
- }
- },
- chatRoomSelectedCallback: function (chatRoomModel){
- if(chatRoomModel){
- chatRoomModel.forwardMessage($chatEntry)
- TimelineListModel.select(chatRoomModel)
- }
- }
- })
- }
-
- onGoToMessage:{
- container.goToMessage(message) // sometimes, there is no access to chat id (maybe because of cleaning component while loading new items). Use a global intermediate.
- }
- onConferenceIcsCopied: container.noticeBannerText = qsTr('conferencesCopiedICS')
- onAddContactClicked: container.addContactClicked(contactAddress)
- onViewContactClicked: container.viewContactClicked(contactAddress)
+ onGoToMessage:{
+ container.goToMessage(message) // sometimes, there is no access to chat id (maybe because of cleaning component while loading new items). Use a global intermediate.
}
+ onConferenceIcsCopied: container.noticeBannerText = qsTr('conferencesCopiedICS')
+ onAddContactClicked: container.addContactClicked(contactAddress)
+ onViewContactClicked: container.viewContactClicked(contactAddress)
}
}
}
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatAudioMessage.qml b/linphone-app/ui/modules/Linphone/Chat/ChatAudioMessage.qml
index 56f443955..1c1501b21 100644
--- a/linphone-app/ui/modules/Linphone/Chat/ChatAudioMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatAudioMessage.qml
@@ -24,8 +24,8 @@ import 'Message.js' as Logic
Loader{
id: mainItem
property ContentModel contentModel
- property int maxWidth : parent.width
- property int fitWidth: active ? Math.max(maxWidth - ChatAudioMessageStyle.emptySpace, ChatAudioMessageStyle.minWidth) : 0
+ property int availableWidth : parent.width
+ property int fitWidth: active ? Math.max(availableWidth - ChatAudioMessageStyle.emptySpace, ChatAudioMessageStyle.minWidth) : 0
property int fitHeight: active ? 60 : 0
property font customFont : SettingsModel.textMessageFont
@@ -49,7 +49,7 @@ Loader{
property bool isPlaying : vocalPlayer.item && vocalPlayer.item.playbackState === SoundPlayer.PlayingState
onIsPlayingChanged: isPlaying ? mediaProgressBar.resume() : mediaProgressBar.stop()
- width: maxWidth < 0 || maxWidth > fitWidth ? fitWidth : maxWidth
+ width: availableWidth < 0 || availableWidth > fitWidth ? fitWidth : availableWidth
height: mainItem.fitHeight
clip: false
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatCalendarMessage.qml b/linphone-app/ui/modules/Linphone/Chat/ChatCalendarMessage.qml
index 78ee5000c..b06553210 100644
--- a/linphone-app/ui/modules/Linphone/Chat/ChatCalendarMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatCalendarMessage.qml
@@ -25,9 +25,9 @@ Loader{
id: mainItem
property ContentModel contentModel
property ConferenceInfoModel conferenceInfoModel: contentModel ? contentModel.conferenceInfoModel : null
- property int maxWidth : parent.width
+ property int availableWidth : parent.width
property int fitHeight: active && item ? item.fitHeight : 0
- property int fitWidth: active && item ? maxWidth/2 + ChatCalendarMessageStyle.widthMargin*2 : 0
+ property int fitWidth: active && item ? availableWidth/2 + ChatCalendarMessageStyle.widthMargin*2 : 0
property bool containsMouse: false
property int gotoButtonMode: -1 //-1: hide, 0:goto, 1:MoreInfo
property bool isExpanded : false
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatConferenceInvitationMessage.qml b/linphone-app/ui/modules/Linphone/Chat/ChatConferenceInvitationMessage.qml
index 85d69a90b..bf7c883ee 100644
--- a/linphone-app/ui/modules/Linphone/Chat/ChatConferenceInvitationMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatConferenceInvitationMessage.qml
@@ -25,9 +25,9 @@ Loader{
id: mainItem
property ContentModel contentModel
property ConferenceInfoModel conferenceInfoModel: contentModel ? contentModel.conferenceInfoModel : null
- property int maxWidth : parent.width
+ property int availableWidth : parent.width
property int fitHeight: active && item ? item.fitHeight : 0 // + (isExpanded? 200 : 0): 0
- property int fitWidth: active && item ? Math.min(maxWidth > 0 ? maxWidth : 9999999, item.fitWidth + ChatCalendarMessageStyle.widthMargin*2) : 0
+ property int fitWidth: active && item ? Math.min(availableWidth > 0 ? availableWidth : 9999999, item.fitWidth + ChatCalendarMessageStyle.widthMargin*2) : 0
property bool containsMouse: false
property int gotoButtonMode: -1 //-1: hide, 0:goto, 1:MoreInfo
property bool isExpanded : false
@@ -56,7 +56,12 @@ Loader{
hoverEnabled: true
onClicked: CallsListModel.prepareConferenceCall(mainItem.conferenceInfoModel)
- onHoveredChanged: mainItem.containsMouse = loadedItem.containsMouse
+ onHoveredChanged: mainItem.containsMouse = loadedItem.containsMouse
+ Rectangle{
+ anchors.fill: parent
+ color: ChatCalendarMessageStyle.backgroundColor.normal.color
+ radius: 5
+ }
ColumnLayout{
id: layout
@@ -104,7 +109,6 @@ Loader{
elide: Text.ElideRight
color: ChatCalendarMessageStyle.subject.colorModel.color
font.pointSize: ChatCalendarMessageStyle.subject.pointSize
- font.weight: Font.Bold
text: mainItem.conferenceInfoModel.subject
}
RowLayout {
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatContent.qml b/linphone-app/ui/modules/Linphone/Chat/ChatContent.qml
index 342adcc03..7c0b12072 100644
--- a/linphone-app/ui/modules/Linphone/Chat/ChatContent.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatContent.qml
@@ -16,58 +16,199 @@ import LinphoneEnums 1.0
import ColorsList 1.0
// =============================================================================
-Column{
+// Simple content display without reply and forward. These modules need to be splitted because of cyclic dependencies.
+// See ChatFullContent
+
+Loader{// Use of Loader because of Repeater (items cannot be loaded dynamically)
id: mainItem
- property ContentModel contentModel
+ property ChatMessageModel chatMessageModel: null
+ property int availableWidth //const
+ property int fileWidth: ChatStyle.entry.message.file.height * 4 / 3 + 2*ChatStyle.entry.message.file.margins
- property int fitHeight: calendarMessage.fitHeight + message.fitHeight + fileMessage.fitHeight + audioMessage.fitHeight
- property int fitWidth: calendarMessage.fitWidth + message.fitWidth + fileMessage.fitWidth + audioMessage.fitWidth
- property color backgroundColor
- property string lastTextSelected
- property alias textColor: message.color
- property alias textFont: message.font
- property alias fileIsHovering: fileMessage.isHovering
+ // Readonly
+ property int bestWidth: Math.min(availableWidth, Math.max(filesBestWidth, conferencesBestWidth, textsBestWidth, voicesBestWidth))
+ property int filesBestWidth: 0
+ property int filesCount: 0
+ property int conferencesCount: 0
+ property int conferencesBestWidth: 0
+ property int textsBestWidth: 0
+ property int textsCount: 0
+ property int voicesBestWidth: 0
+ property int voicesCount: 0
+ signal isFileHoveringChanged(bool isFileHovering)
+ signal lastTextSelectedChanged(string lastTextSelected)
signal rightClicked()
signal conferenceIcsCopied()
- property int maxWidth
- height: fitHeight
- anchors.left: parent ? parent.left : undefined
- anchors.right: parent ? parent.right : undefined
+ property bool useTextColor: false
+ property color textColor
- spacing: 0
+ property int fileBorderWidth : 0
+ property color fileBackgroundColor: ChatStyle.entry.message.file.extension.background.colorModel.color
+ property int fileBackgroundRadius: ChatStyle.entry.message.file.extension.radius
- property bool isOutgoing : contentModel && contentModel.chatMessageModel && (contentModel.chatMessageModel.isOutgoing || contentModel.chatMessageModel.state == LinphoneEnums.ChatMessageStateIdle);
- z: message.visible ? 0 : 1
- ChatConferenceInvitationMessage{
- id: calendarMessage
- contentModel: mainItem.contentModel
- width: parent.width
- maxWidth: mainItem.maxWidth
- gotoButtonMode: 1
- onExpandToggle: isExpanded=!isExpanded
- height: fitHeight
- z: 1
- onConferenceIcsCopied:mainItem.conferenceIcsCopied()
- }
- ChatAudioMessage{
- id: audioMessage
- contentModel: mainItem.contentModel
- visible: contentModel
- z: 1
- }
- ChatFileMessage{
- id: fileMessage
- contentModel: mainItem.contentModel
- width: parent.width
- z: 2
- }
- ChatTextMessage {
- id: message
- contentModel: mainItem.contentModel
- onLastTextSelectedChanged: mainItem.lastTextSelected = lastTextSelected
- color: isOutgoing ? ChatStyle.entry.message.outgoing.text.colorModel.color : ChatStyle.entry.message.incoming.text.colorModel.color
- onRightClicked: mainItem.rightClicked()
+ active: chatMessageModel
+
+ sourceComponent: Component{
+ Column{
+ id: mainComponent
+ spacing: 0
+ function updateFilesBestWidth(){
+ var newBestWidth = 0
+ var count = 0
+ for(var child in messageFilesList.children) {
+ var item = messageFilesList.children[child]
+ if(item){
+ var a = item.fitWidth
+ if(a) {
+ ++count
+ newBestWidth = Math.max(newBestWidth,a)
+ }
+ }
+ }
+ if(count > 1){
+ newBestWidth = Math.max(newBestWidth, mainItem.fileWidth*count)
+ }
+ mainItem.filesCount = count
+ mainItem.filesBestWidth = newBestWidth
+ }
+ function updateListBestWidth(listView){
+ var newBestWidth = 0
+ var count = 0
+ for(var child in listView.contentItem.children) {
+ var a = listView.contentItem.children[child].fitWidth
+ if(a) {
+ ++count
+ newBestWidth = Math.max(newBestWidth,a)
+ }
+ }
+ return [count, newBestWidth];
+ }
+ ListView {
+ id: messagesVoicesList
+ width: parent.width
+ visible: count > 0
+ spacing: 0
+ clip: false
+ model: ContentProxyModel{
+ filter: ContentProxyModel.ContentType.Voice
+ chatMessageModel: mainItem.chatMessageModel
+ }
+ height: contentHeight
+ boundsBehavior: Flickable.StopAtBounds
+ interactive: false
+ function updateBestWidth(){
+ var newWidth = mainComponent.updateListBestWidth(messagesVoicesList)
+ mainItem.voicesCount = newWidth[0]
+ mainItem.voicesBestWidth = newWidth[1]
+ }
+ delegate: ChatAudioMessage{
+ id: audioMessage
+ contentModel: $modelData
+ visible: contentModel
+ z: 1
+ Component.onCompleted: messagesVoicesList.updateBestWidth()
+ }
+ Component.onCompleted: messagesVoicesList.updateBestWidth
+ }
+// CONFERENCE
+ ListView {
+ id: messagesConferencesList
+ width: parent.width
+ visible: count > 0
+ spacing: 0
+ clip: false
+ model: ContentProxyModel{
+ filter: ContentProxyModel.ContentType.Conference
+ chatMessageModel: mainItem.chatMessageModel
+ }
+ height: contentHeight
+ boundsBehavior: Flickable.StopAtBounds
+ interactive: false
+ function updateBestWidth(){
+ var newWidth = mainComponent.updateListBestWidth(messagesConferencesList)
+ mainItem.conferencesCount = newWidth[0]
+ mainItem.conferencesBestWidth = newWidth[1]
+ }
+ Component.onCompleted: messagesConferencesList.updateBestWidth()
+ delegate: ChatConferenceInvitationMessage{
+ id: calendarMessage
+ contentModel: $modelData
+ width: parent.width
+ availableWidth: mainItem.availableWidth
+ gotoButtonMode: 1
+ onExpandToggle: isExpanded=!isExpanded
+ height: fitHeight
+ z: 1
+ onConferenceIcsCopied:mainItem.conferenceIcsCopied()
+ onFitWidthChanged: messagesConferencesList.updateBestWidth()
+ Component.onCompleted: messagesConferencesList.updateBestWidth()
+ }
+ }
+// FILES
+ GridLayout {
+ id: messageFilesList
+ property alias count: repeater.count
+ visible: count > 0
+ clip: false
+
+ property int availableSection: mainItem.availableWidth / mainItem.fileWidth
+ property int bestFitSection: mainItem.bestWidth / mainItem.fileWidth
+ columns: Math.max(1, Math.min(availableSection , bestFitSection))
+ columnSpacing: 0
+ rowSpacing: 0
+ width: parent.width
+ Repeater{
+ id: repeater
+ model: ContentProxyModel{
+ filter: ContentProxyModel.ContentType.File
+ chatMessageModel: mainItem.chatMessageModel
+ }
+ ChatFileMessage{
+ contentModel: $modelData
+ onIsHoveringChanged: mainItem.isFileHoveringChanged(isHovering)
+ borderWidth: mainItem.fileBorderWidth
+ backgroundColor: mainItem.fileBackgroundColor
+ backgroundRadius: mainItem.fileBackgroundRadius
+ Component.onCompleted: mainComponent.updateFilesBestWidth()
+ }
+ }
+ }
+// TEXTS
+ ListView {
+ id: messagesTextsList
+ width: parent.width
+ visible: count > 0
+ spacing: 0
+ clip: false
+ model: ContentProxyModel{
+ filter: ContentProxyModel.ContentType.Text
+ chatMessageModel: mainItem.chatMessageModel
+ }
+ height: contentHeight
+ boundsBehavior: Flickable.StopAtBounds
+ interactive: false
+ function updateBestWidth(){
+ var newWidth = mainComponent.updateListBestWidth(messagesTextsList)
+ mainItem.textsCount = newWidth[0]
+ mainItem.textsBestWidth = newWidth[1]
+ }
+ Component.onCompleted: messagesTextsList.updateBestWidth()
+ delegate:
+ ChatTextMessage {
+ contentModel: $modelData
+ onLastTextSelectedChanged: mainItem.lastTextSelectedChanged(lastTextSelected)
+ color: mainItem.useTextColor
+ ? mainItem.textColor
+ : $modelData.isOutgoing
+ ? ChatStyle.entry.message.outgoing.text.colorModel.color
+ : ChatStyle.entry.message.incoming.text.colorModel.color
+ onRightClicked: mainItem.rightClicked()
+ onFitWidthChanged: messagesTextsList.updateBestWidth()
+ Component.onCompleted: messagesTextsList.updateBestWidth()
+ }
+ }
+ }
}
}
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatFileMessage.qml b/linphone-app/ui/modules/Linphone/Chat/ChatFileMessage.qml
index f2a22daed..24559f82d 100644
--- a/linphone-app/ui/modules/Linphone/Chat/ChatFileMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatFileMessage.qml
@@ -19,11 +19,21 @@ Row {
property ChatMessageModel chatMessageModel: contentModel && contentModel.chatMessageModel
property ContentModel contentModel
property bool isOutgoing : chatMessageModel && ( chatMessageModel.isOutgoing || chatMessageModel.state == LinphoneEnums.ChatMessageStateIdle);
- property int fitWidth: visible ? Math.max( Math.max((thumbnailProvider.sourceComponent == extension ? thumbnailProvider.item.fitWidth : 0)
+ property int fitHeight: ChatStyle.entry.message.file.height
+ property int fitWidth: ChatStyle.entry.message.file.height * 4 / 3 + 2*ChatStyle.entry.message.file.margins
+ property int borderWidth : 0
+ property color backgroundColor: ChatStyle.entry.message.file.extension.background.colorModel.color
+ property int backgroundRadius: ChatStyle.entry.message.file.extension.radius
+ /*
+ property int fitWidth: visible
+ ? Math.max( Math.max((thumbnailProvider.sourceComponent == extension
+ ? thumbnailProvider.item.fitWidth
+ : 0)
, thumbnailProvider.width + 3*ChatStyle.entry.message.file.margins)
- , Math.max(ChatStyle.entry.message.file.width, ChatStyle.entry.message.outgoing.areaSize)) : 0
+ , Math.max(ChatStyle.entry.message.file.width, ChatStyle.entry.message.outgoing.areaSize))
+ : 0
property int fitHeight: visible ? rectangle.height : 0
-
+ */
property bool isAnimatedImage : mainRow.contentModel && mainRow.contentModel.wasDownloaded && UtilsCpp.isAnimatedImage(mainRow.contentModel.filePath)
property bool haveThumbnail: mainRow.contentModel && mainRow.contentModel.thumbnail
property bool isHovering: thumbnailProvider.state == 'hovered'
@@ -32,7 +42,8 @@ Row {
signal copySelectionDone()
signal forwardClicked()
height: fitHeight
- visible: contentModel && !contentModel.isIcalendar() && (contentModel.isFile() || contentModel.isFileTransfer()) && !contentModel.isVoiceRecording()
+ width: fitWidth
+ visible: true
// ---------------------------------------------------------------------------
// File message.
// ---------------------------------------------------------------------------
@@ -56,15 +67,14 @@ Row {
property string thumbnail : mainRow.contentModel ? mainRow.contentModel.thumbnail : ''
color: 'transparent'
anchors.left: parent.left
+ anchors.right: parent.right
anchors.top: parent.top
- anchors.leftMargin: ChatStyle.entry.message.file.margins
- anchors.topMargin: ChatStyle.entry.message.file.margins
- height: 2*ChatStyle.entry.message.file.margins + (mainRow.isAnimatedImage ? ChatStyle.entry.message.file.heightbetter
- : thumbnailProvider.sourceComponent == extension ? thumbnailProvider.item.fitHeight
- : ChatStyle.entry.message.file.height
+ height: 2*ChatStyle.entry.message.file.margins + (mainRow.isAnimatedImage
+ ? ChatStyle.entry.message.file.heightbetter
+ : thumbnailProvider.sourceComponent == extension
+ ? ChatStyle.entry.message.file.height
+ : ChatStyle.entry.message.file.height
)
- width: mainRow.width
-
radius: ChatStyle.entry.message.radius
// ---------------------------------------------------------------------
@@ -77,12 +87,14 @@ Row {
Image {
id: thumbnailImageSource
property real scaleAnimatorTo : ChatStyle.entry.message.file.animation.thumbnailTo
+ anchors.centerIn: parent
mipmap: SettingsModel.mipmapEnabled
source: mainRow.contentModel.thumbnail
autoTransform: true
fillMode: Image.PreserveAspectFit
height: ChatStyle.entry.message.file.height
width: height*4/3
+
Loader{
anchors.fill: parent
sourceComponent: Image{// Better quality on zoom
@@ -117,14 +129,18 @@ Row {
Rectangle {
property int fitWidth: Math.max(downloadText.implicitWidth, Math.max(fileName.visible ? fileName.implicitWidth : 0, fileIcon.iconSize)) + 20
- property int fitHeight: fileIcon.iconSize + (fileName.visible ? fileName.implicitHeight + ChatStyle.entry.message.file.spacing : 0 )
- + (downloadText.visible? downloadText.implicitHeight + ChatStyle.entry.message.file.spacing : 0) + 2*ChatStyle.entry.message.file.margins
+ //property int fitHeight: fileIcon.iconSize + (fileName.visible ? fileName.implicitHeight + ChatStyle.entry.message.file.spacing : 0 )
+// + (downloadText.visible? downloadText.implicitHeight + ChatStyle.entry.message.file.spacing : 0) + 2*ChatStyle.entry.message.file.margins
property real scaleAnimatorTo : ChatStyle.entry.message.file.animation.to
- height: fitHeight
- width: fitWidth
- color: ChatStyle.entry.message.file.extension.background.colorModel.color
- radius: ChatStyle.entry.message.file.extension.radius
+ anchors.centerIn: parent
+ height: ChatStyle.entry.message.file.height
+ width: height*4/3
+ color: mainRow.backgroundColor
+ radius: mainRow.backgroundRadius
+ border.width: mainRow.borderWidth
+ border.color: ChatStyle.entry.message.file.extension.background.borderColorModel.color
+
ColumnLayout{
anchors.fill: parent
anchors.topMargin: ChatStyle.entry.message.file.margins
@@ -135,6 +151,8 @@ Row {
Layout.alignment: Qt.AlignCenter
icon: extensionText.text != '' ? ChatStyle.entry.message.file.extension.icon : ChatStyle.entry.message.file.extension.unknownIcon
iconSize: ChatStyle.entry.message.file.extension.iconSize
+ Layout.fillHeight: true
+ Layout.fillWidth: true
Layout.preferredHeight: iconSize
Layout.preferredWidth: iconSize
Text {
@@ -176,10 +194,10 @@ Row {
visible: mainRow.contentModel && !mainRow.isAnimatedImage && !mainRow.haveThumbnail
color: ChatStyle.entry.message.file.extension.text.colorModel.color
- elide: Text.ElideRight
font.pointSize: ChatStyle.entry.message.file.name.pointSize
wrapMode: Text.WrapAnywhere
- horizontalAlignment: Qt.AlignCenter
+ horizontalAlignment: Text.AlignHCenter
+ maximumLineCount: 2
text: (mainRow.contentModel ? mainRow.contentModel.name : '')
}
@@ -187,7 +205,7 @@ Row {
id: downloadText
Layout.fillWidth: true
Layout.fillHeight: true
- Layout.preferredHeight: visible ? ChatStyle.entry.message.file.download.height : 0
+ Layout.preferredHeight: visible ? contentHeight : 0
//: 'Cancel' : Message link to cancel a transfer (upload/download)
text: mainRow.contentModel ? rectangle.isTransferring ? qsTr('fileTransferCancel')
//: 'Download' : Message link to download a file
@@ -197,8 +215,8 @@ Row {
font.pointSize: ChatStyle.entry.message.file.download.pointSize
color:ChatStyle.entry.message.file.extension.text.colorModel.color
visible: (mainRow.contentModel? (!mainItem.isOutgoing && !mainRow.contentModel.wasDownloaded) || rectangle.isTransferring : false)
- horizontalAlignment: Qt.AlignCenter
- verticalAlignment: Qt.AlignCenter
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
}
}
@@ -206,7 +224,7 @@ Row {
}
Loader {
id: thumbnailProvider
-
+ anchors.centerIn: parent
sourceComponent: (mainRow.contentModel ?
(mainRow.isAnimatedImage ? animatedImage
: (mainRow.haveThumbnail ? thumbnailImage : extension )
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatForwardMessage.qml b/linphone-app/ui/modules/Linphone/Chat/ChatForwardMessage.qml
index c7136b9e6..8a6789495 100644
--- a/linphone-app/ui/modules/Linphone/Chat/ChatForwardMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatForwardMessage.qml
@@ -22,13 +22,13 @@ import 'Message.js' as Logic
Item {
id: mainItem
property ChatMessageModel mainChatMessageModel
- property int maxWidth : parent.width
+ property int availableWidth : parent.width
property int fitWidth: visible ? headerArea.fitWidth + 7 + ChatForwardMessageStyle.padding * 2 : 0
- property int fitHeight: visible ? icon.height : 0
+ property int fitHeight: visible ? icon.height + 5 : 0
property font customFont : SettingsModel.textMessageFont
visible: mainChatMessageModel && mainChatMessageModel.isForward
- width: maxWidth > fitWidth ? fitWidth : maxWidth
+ width: availableWidth > fitWidth ? fitWidth : availableWidth
height: fitHeight
ColumnLayout{
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatFullContent.qml b/linphone-app/ui/modules/Linphone/Chat/ChatFullContent.qml
new file mode 100644
index 000000000..38c2aeae3
--- /dev/null
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatFullContent.qml
@@ -0,0 +1,66 @@
+import QtQuick 2.7
+import QtQuick.Layouts 1.3
+
+import Clipboard 1.0
+import Common 1.0
+import Linphone 1.0
+
+import Common.Styles 1.0
+import Linphone.Styles 1.0
+import TextToSpeech 1.0
+import Utils 1.0
+import Units 1.0
+import UtilsCpp 1.0
+import LinphoneEnums 1.0
+
+import ColorsList 1.0
+
+// =============================================================================
+// Full content display with reply and forward. These modules need to be splitted because of cyclic dependencies.
+// See ChatContent
+
+Column{
+ id: mainItem
+ property ChatMessageModel chatMessageModel: null
+ property int availableWidth //const
+
+// Readonly
+ property int bestWidth: Math.min(availableWidth, Math.max(forwardMessage.fitWidth, replyMessage.fitWidth, chatContent.bestWidth ))
+ property alias filesBestWidth: chatContent.filesBestWidth
+ property alias filesCount: chatContent.filesCount
+ property alias textsBestWidth: chatContent.textsBestWidth
+ property alias textsCount: chatContent.textsCount
+
+ signal isFileHoveringChanged(bool isFileHovering)
+ signal lastTextSelectedChanged(string lastTextSelected)
+ signal rightClicked()
+ signal conferenceIcsCopied()
+ signal goToMessage(var message)
+
+ spacing: 0
+ ChatForwardMessage{
+ id: forwardMessage
+ mainChatMessageModel: mainItem.chatMessageModel
+ visible: mainChatMessageModel && mainChatMessageModel.isForward
+ availableWidth: mainItem.availableWidth
+ }
+ ChatReplyMessage{
+ id: replyMessage
+ z: 1
+ mainChatMessageModel: mainItem.chatMessageModel
+ visible: mainChatMessageModel && mainChatMessageModel.isReply
+ availableWidth: mainItem.availableWidth
+ onGoToMessage: mainItem.goToMessage(message)
+ }
+ ChatContent{
+ id: chatContent
+ chatMessageModel: mainItem.chatMessageModel
+ availableWidth: mainItem.availableWidth
+ width: parent.width
+
+ onIsFileHoveringChanged: mainItem.isFileHoveringChanged(isFileHovering)
+ onLastTextSelectedChanged: mainItem.lastTextSelectedChanged(lastTextSelected)
+ onRightClicked: mainItem.rightClicked()
+ onConferenceIcsCopied: mainItem.conferenceIcsCopied()
+ }
+}
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatReplyMessage.qml b/linphone-app/ui/modules/Linphone/Chat/ChatReplyMessage.qml
index a477aaa82..e6114afc3 100644
--- a/linphone-app/ui/modules/Linphone/Chat/ChatReplyMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatReplyMessage.qml
@@ -23,16 +23,18 @@ Item {
id: mainItem
property ChatMessageModel chatMessageModel
property ChatMessageModel mainChatMessageModel
- property int maxWidth : parent.width
+ property int availableWidth : parent.width
property int headerHeight: ChatReplyMessageStyle.header.replyIcon.iconSize
- property int replyHeight: (chatMessageModel ? replyMessage.height + usernameReplied.implicitHeight + ChatStyle.entry.message.padding * 3 + 3 : 0)
- property int fitWidth: visible ? Math.max(usernameReplied.implicitWidth + replyMessage.fitWidth , headerArea.fitWidth) + 7 + ChatReplyMessageStyle.padding * 2 : 0
+ //property int replyHeight: (chatMessageModel ? replyMessage.height + usernameReplied.implicitHeight + ChatStyle.entry.message.padding * 3 + 3 : 0)
+ //property int fitWidth: visible ? Math.max(usernameReplied.implicitWidth + replyMessage.fitWidth , headerArea.fitWidth) + 7 + ChatReplyMessageStyle.padding * 2 : 0
+ property int replyHeight: (chatMessageModel ? chatContent.height + usernameReplied.implicitHeight + ChatStyle.entry.message.padding * 3 + 3 : 0)
+ property int fitWidth: visible ? Math.max(usernameReplied.implicitWidth, chatContent.bestWidth , headerArea.fitWidth) + 7 + ChatReplyMessageStyle.padding * 2 : 0
property int fitHeight: visible ? headerHeight + replyHeight : 0
property font customFont : SettingsModel.textMessageFont
visible: mainChatMessageModel && mainChatMessageModel.isReply
- width: maxWidth < 0 || maxWidth > fitWidth ? fitWidth : maxWidth
+ width: availableWidth < 0 || availableWidth > fitWidth ? fitWidth : availableWidth
height: fitHeight
onMainChatMessageModelChanged: if( mainChatMessageModel && mainChatMessageModel.replyChatMessageModel) chatMessageModel = mainChatMessageModel.replyChatMessageModel
@@ -80,15 +82,25 @@ Item {
Layout.bottomMargin: ChatStyle.entry.message.padding
Layout.leftMargin: 10
Layout.rightMargin: 10
+ clip: true
Rectangle{
+ id: colorBar
anchors.left: parent.left
anchors.top: parent.top
anchors.bottom: parent.bottom
- width: 7
+ width: 15
+ radius: 8
color: chatMessageModel && chatMessageModel.isOutgoing ? ChatReplyMessageStyle.replyArea.outgoingMarkColor.color : ChatReplyMessageStyle.replyArea.incomingMarkColor.color
+ Rectangle{
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ width: 5
+ color: ChatReplyMessageStyle.replyArea.backgroundColor.color
+ }
}
- radius: 5
+ radius: 8
color: ChatReplyMessageStyle.replyArea.backgroundColor.color
visible: chatMessageModel != undefined
Text{
@@ -98,7 +110,6 @@ Item {
anchors.right: parent.right
anchors.topMargin: 3
-
leftPadding: 2 * ChatStyle.entry.message.padding
text: mainChatMessageModel && mainChatMessageModel.fromDisplayNameReplyMessage
@@ -108,48 +119,20 @@ Item {
color: ChatReplyMessageStyle.replyArea.foregroundColor.color
}
- ScrollableListView {
- id: replyMessage
- property int fitWidth : 0
- hideScrollBars: true
+ ChatContent{
+ id: chatContent
anchors.top: usernameReplied.bottom
- anchors.left: parent.left
+ chatMessageModel: mainItem.chatMessageModel
+ availableWidth: mainItem.availableWidth
+ anchors.left: colorBar.right
anchors.right: parent.right
anchors.topMargin: 3
- anchors.leftMargin: 5
- interactive: false
- clip: false
+ useTextColor: true
+ textColor: ChatReplyMessageStyle.replyArea.foregroundColor.color
- function updateWidth(){
- var maxWidth = 0
- for(var child in replyMessage.contentItem.children) {
- var a = replyMessage.contentItem.children[child].fitWidth
- if(a)
- maxWidth = Math.max(maxWidth,a)
- }
- fitWidth = maxWidth
- }
-
- model: ContentProxyModel{
- chatMessageModel: mainItem.chatMessageModel
- }
-
- onContentHeightChanged: Qt.callLater( function(){replyMessage.height = replyMessage.contentHeight})
-
- delegate: ChatContent{
- contentModel: $modelData
- textColor: ChatReplyMessageStyle.replyArea.foregroundColor.color
- onFitWidthChanged:{
- replyMessage.updateWidth()
- }
- Rectangle{
- anchors.left: parent.left
- anchors.right: parent.right
- color: ChatStyle.entry.separator.colorModel.color
- height: visible ? ChatStyle.entry.separator.width : 0
- visible: (index !== (replyMessage.count - 1))
- }
- }
+ fileBackgroundRadius:5
+ fileBackgroundColor: ChatReplyMessageStyle.replyArea.fileBackgroundColor.color
+ fileBorderWidth:1
}
}
}
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatReplyPreview.qml b/linphone-app/ui/modules/Linphone/Chat/ChatReplyPreview.qml
index 2999d1327..8ce8e186f 100644
--- a/linphone-app/ui/modules/Linphone/Chat/ChatReplyPreview.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatReplyPreview.qml
@@ -17,8 +17,9 @@ import 'Chat.js' as Logic
Rectangle{
id: replyPreviewBlock
property ChatRoomModel chatRoomModel
+ property ChatMessageModel replyModel: chatRoomModel ? chatRoomModel.reply : null
property int maxHeight : parent.maxHeight
- Layout.preferredHeight: visible ? Math.min(messageContentsList.height + replyPreviewHeaderArea.implicitHeight + 15, replyPreviewBlock.maxHeight) : 0
+ Layout.preferredHeight: visible ? Math.min(messageContents.height + replyPreviewHeaderArea.implicitHeight + 15, replyPreviewBlock.maxHeight) : 0
property int leftMargin: 10
property int rightMargin: 10
@@ -71,33 +72,19 @@ Rectangle{
Flickable {
id: replyPreviewTextArea
- ScrollBar.vertical: ForceScrollBar {visible: replyPreviewTextArea.height < messageContentsList.height}
+ ScrollBar.vertical: ForceScrollBar {visible: replyPreviewTextArea.height < messageContents.height}
boundsBehavior: Flickable.StopAtBounds
- contentHeight: messageContentsList.height
+ contentHeight: messageContents.height
contentWidth: width - ScrollBar.vertical.width
flickableDirection: Flickable.VerticalFlick
clip: true
Layout.fillHeight: true
Layout.fillWidth: true
- ListView {
- id: messageContentsList
- anchors.left: parent.left
- anchors.right: parent.right
- model: ContentProxyModel{
- chatMessageModel: replyPreviewBlock.chatRoomModel && replyPreviewBlock.chatRoomModel.reply
- }
- height: contentHeight
- clip: true
- delegate: ChatContent{
- contentModel: $modelData
- Rectangle{
- anchors.left: parent.left
- anchors.right: parent.right
- color: ChatStyle.entry.separator.colorModel.color
- height: visible ? ChatStyle.entry.separator.width : 0
- visible: (index !== (messageContentsList.count - 1))
- }
- }
+ ChatContent{
+ id: messageContents
+ width: replyPreviewTextArea.contentWidth
+ chatMessageModel: replyPreviewBlock.replyModel
+ availableWidth: parent.width
}
}
}
diff --git a/linphone-app/ui/modules/Linphone/Chat/ChatTextMessage.qml b/linphone-app/ui/modules/Linphone/Chat/ChatTextMessage.qml
index 2db19344d..3c179ccc8 100644
--- a/linphone-app/ui/modules/Linphone/Chat/ChatTextMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/ChatTextMessage.qml
@@ -23,8 +23,8 @@ TextEdit {
property ContentModel contentModel
property string lastTextSelected : ''
property font customFont : SettingsModel.textMessageFont
- property int fitHeight: visible ? contentHeight + padding + 8 : 0
- property int fitWidth: visible ? implicitWidth + 2: 0 // add 2 because there is a bug on border that lead to not fit text exactly
+ property int fitHeight: contentHeight + padding + 8
+ property int fitWidth: implicitWidth + 2 // add 2 because there is a bug on border that lead to not fit text exactly
signal rightClicked()
@@ -32,8 +32,8 @@ TextEdit {
property int removeWarningFromBindingLoop : implicitWidth // Just a dummy variable to remove meaningless binding loop on implicitWidth
height: fitHeight
- width: parent.width
- visible: contentModel && contentModel.isText()
+ width: parent && parent.width || 1
+ visible: contentModel// && contentModel.isText()
clip: false
padding: ChatStyle.entry.message.padding
textMargin: 0
diff --git a/linphone-app/ui/modules/Linphone/Chat/Event.qml b/linphone-app/ui/modules/Linphone/Chat/Event.qml
index b56de58a6..bdab26917 100644
--- a/linphone-app/ui/modules/Linphone/Chat/Event.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/Event.qml
@@ -12,6 +12,9 @@ Row {
id: mainItem
property QtObject iconData
property string translation
+ property bool isHovering : false
+ property bool isTopGrouped: false
+ property bool isBottomGrouped: false
Component.onCompleted: {
if ($chatEntry.status == LinphoneEnums.CallStatusSuccess) {
if(!$chatEntry.isStart){
diff --git a/linphone-app/ui/modules/Linphone/Chat/IncomingMessage.qml b/linphone-app/ui/modules/Linphone/Chat/IncomingMessage.qml
index 7fb191bd8..da2222cfd 100644
--- a/linphone-app/ui/modules/Linphone/Chat/IncomingMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/IncomingMessage.qml
@@ -12,6 +12,10 @@ RowLayout {
Layout.fillWidth: true
+ property alias isHovering: message.isHovering
+ property alias isTopGrouped: message.isTopGrouped
+ property alias isBottomGrouped: message.isBottomGrouped
+
signal copyAllDone()
signal copySelectionDone()
signal replyClicked()
@@ -66,16 +70,17 @@ RowLayout {
Message {
id: message
- onCopyAllDone: parent.copyAllDone()
- onCopySelectionDone: parent.copySelectionDone()
- onReplyClicked: parent.replyClicked()
- onForwardClicked: parent.forwardClicked()
- onGoToMessage: parent.goToMessage(message)
- onConferenceIcsCopied: parent.conferenceIcsCopied()
- onAddContactClicked: parent.addContactClicked(contactAddress)
- onViewContactClicked: parent.viewContactClicked(contactAddress)
+ onCopyAllDone: mainRow.copyAllDone()
+ onCopySelectionDone: mainRow.copySelectionDone()
+ onReplyClicked: mainRow.replyClicked()
+ onForwardClicked: mainRow.forwardClicked()
+ onGoToMessage: mainRow.goToMessage(message)
+ onConferenceIcsCopied: mainRow.conferenceIcsCopied()
+ onAddContactClicked: mainRow.addContactClicked(contactAddress)
+ onViewContactClicked: mainRow.viewContactClicked(contactAddress)
Layout.fillWidth: true
+ Layout.rightMargin: 10
// Not a style. Workaround to avoid a 0 width.
// Arbitrary value.
diff --git a/linphone-app/ui/modules/Linphone/Chat/Message.qml b/linphone-app/ui/modules/Linphone/Chat/Message.qml
index 2903361f0..1b7f3f3f9 100644
--- a/linphone-app/ui/modules/Linphone/Chat/Message.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/Message.qml
@@ -1,5 +1,6 @@
import QtQuick 2.7
import QtQuick.Layouts 1.3
+import QtQml.Models 2.15
import Clipboard 1.0
import Common 1.0
@@ -16,6 +17,7 @@ import LinphoneEnums 1.0
import ColorsList 1.0
import 'Message.js' as Logic
+import 'qrc:/ui/scripts/Utils/utils.js' as Utils
// =============================================================================
@@ -25,8 +27,10 @@ Item {
// ---------------------------------------------------------------------------
property alias backgroundColorModel: rectangle.colorModel
-
+ property bool isHovering : false
default property alias _content: content.data
+ property bool isTopGrouped: false
+ property bool isBottomGrouped: false
// ---------------------------------------------------------------------------
@@ -41,94 +45,52 @@ Item {
// ---------------------------------------------------------------------------
property string lastTextSelected
- implicitHeight: (deliveryLayout.visible? deliveryLayout.height : 0) +(ephemeralTimerRow.visible? 16 : 0) + messageData.height
-
+ implicitHeight: (deliveryLayout.visible? deliveryLayout.height : 0) +(ephemeralTimerRow.visible? 16 : 0) + chatContent.height
Rectangle {
id: rectangle
- property int maxWidth: parent.width
- property int dataWidth: maxWidth
+ property int availableWidth: parent.width
property bool ephemeral : $chatEntry.isEphemeral
property var colorModel:{'color': 'transparent'}
- function updateWidth(){
- var maxWidth = Math.max(forwardMessage.fitWidth, replyMessage.fitWidth)
- for(var child in messageContentsList.contentItem.children) {
- var a = messageContentsList.contentItem.children[child].fitWidth
- if(a)
- maxWidth = Math.max(maxWidth,a)
- }
- rectangle.dataWidth = maxWidth
- }
+
+ anchors.left: !$chatEntry.isOutgoing ? parent.left : undefined
+ anchors.right: $chatEntry.isOutgoing ? parent.right : undefined
+
height: parent.height - (deliveryLayout.visible? deliveryLayout.height : 0)
radius: ChatStyle.entry.message.radius
clip: false
color: colorModel.color
- width: (
- ephemeralTimerRow.visible && dataWidth < ephemeralTimerRow.width + 2*ChatStyle.entry.message.padding
+ width: (//implicitWidth
+ ephemeralTimerRow.visible && (chatContent.bestWidth < ephemeralTimerRow.width + 2*ChatStyle.entry.message.padding)
? ephemeralTimerRow.width + 2*ChatStyle.entry.message.padding
- : Math.min(dataWidth, maxWidth)
+ : Math.min(chatContent.bestWidth, availableWidth)
)
+
// ---------------------------------------------------------------------------
// Message.
// ---------------------------------------------------------------------------
-
- Column{
- id: messageData
+ Rectangle{
+ visible: container.isTopGrouped || container.isBottomGrouped
+ color: parent.color
+ anchors.left: !$chatEntry.isOutgoing ? parent.left : undefined
+ anchors.right: $chatEntry.isOutgoing ? parent.right : undefined
+ anchors.top: parent.top
+ anchors.bottom: parent.bottom
+ anchors.topMargin: container.isTopGrouped ? 0 : parent.radius
+ anchors.bottomMargin: container.isBottomGrouped ? 0 : parent.radius
+ width: parent.radius
+ }
+ ChatFullContent{
+ id: chatContent
+ anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
- spacing: 0
- ChatForwardMessage{
- id: forwardMessage
- mainChatMessageModel: $chatEntry
- visible: $chatEntry.isForward
- maxWidth: container.width
- onFitWidthChanged:{
- rectangle.updateWidth()
- }
- }
- ChatReplyMessage{
- id: replyMessage
- z: 1
- mainChatMessageModel: $chatEntry
- visible: $chatEntry.isReply
- maxWidth: container.width
- onFitWidthChanged:{
- rectangle.updateWidth()
- }
- onGoToMessage: container.goToMessage(message)
- }
- ListView {
- id: messageContentsList
- anchors.left: parent.left
- anchors.right: parent.right
- visible: count > 0
- spacing: 0
- clip: false
- model: ContentProxyModel{
- chatMessageModel: $chatEntry
- }
- height: contentHeight
- boundsBehavior: Flickable.StopAtBounds
- interactive: false
- delegate:
- ChatContent{
- maxWidth: container.width
- contentModel: $modelData
- onFitWidthChanged:{
- rectangle.updateWidth()
- }
- onLastTextSelectedChanged: container.lastTextSelected= lastTextSelected
- onRightClicked: chatMenu.open()
- onConferenceIcsCopied: container.conferenceIcsCopied()
- onFileIsHoveringChanged: menuButton.visible = !fileIsHovering
- Rectangle{
- anchors.left: parent.left
- anchors.right: parent.right
- color: ChatStyle.entry.separator.colorModel.color
- height: visible ? ChatStyle.entry.separator.width : 0
- visible: (index !== (messageContentsList.count - 1))
- }
- }
- }
+ chatMessageModel: $chatEntry
+ availableWidth: rectangle.availableWidth
+ onLastTextSelectedChanged: container.lastTextSelected= lastTextSelected
+ onGoToMessage: container.goToMessage(message)
+ onRightClicked: chatMenu.open()
+ onConferenceIcsCopied: container.conferenceIcsCopied()
+ onIsFileHoveringChanged: menuButton.visible = !isFileHovering
}
Row{
id:ephemeralTimerRow
@@ -158,7 +120,6 @@ Item {
}
}
}
-
// ---------------------------------------------------------------------------
// Extra content.
// ---------------------------------------------------------------------------
@@ -168,8 +129,10 @@ Item {
anchors {
left: rectangle.right
+ bottom: rectangle.bottom
leftMargin: ChatStyle.entry.message.extraContent.leftMargin
}
+
}
ChatDeliveries{
id: deliveryLayout
@@ -193,7 +156,7 @@ Item {
backgroundRadius: 8
colorSet : ChatStyle.entry.menu
- visible: isHoverEntry()
+ visible: container.isHovering
onClicked: chatMenu.open()
}
diff --git a/linphone-app/ui/modules/Linphone/Chat/Notice.qml b/linphone-app/ui/modules/Linphone/Chat/Notice.qml
index 2a0e845f3..d3a48080f 100644
--- a/linphone-app/ui/modules/Linphone/Chat/Notice.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/Notice.qml
@@ -95,6 +95,9 @@ RowLayout{
property color eventColor : (isError ? ChatStyle.entry.event.notice.errorColor.color
: ( isImportant ? ChatStyle.entry.event.notice.importantColor.color
: ChatStyle.entry.event.notice.colorModel.color ))
+ property bool isHovering : false
+ property bool isTopGrouped: false
+ property bool isBottomGrouped: false
Layout.preferredHeight: ChatStyle.entry.lineHeight
spacing: ChatStyle.entry.message.extraContent.spacing
diff --git a/linphone-app/ui/modules/Linphone/Chat/OutgoingMessage.qml b/linphone-app/ui/modules/Linphone/Chat/OutgoingMessage.qml
index 7d33d5ada..5b04ca996 100644
--- a/linphone-app/ui/modules/Linphone/Chat/OutgoingMessage.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/OutgoingMessage.qml
@@ -11,9 +11,15 @@ import Utils 1.0
// =============================================================================
Item {
+ id: mainItem
implicitHeight: message.height
//width: parent.width
Layout.fillWidth: true
+ //onWidthChanged: console.log(width)
+
+ property alias isHovering: message.isHovering
+ property alias isTopGrouped: message.isTopGrouped
+ property alias isBottomGrouped: message.isBottomGrouped
signal copyAllDone()
signal copySelectionDone()
@@ -23,64 +29,91 @@ Item {
signal conferenceIcsCopied()
signal addContactClicked(string contactAddress)
signal viewContactClicked(string contactAddress)
-
- Message {
- id: message
-
- onCopyAllDone: parent.copyAllDone()
- onCopySelectionDone: parent.copySelectionDone()
- onReplyClicked: parent.replyClicked()
- onForwardClicked: parent.forwardClicked()
- onGoToMessage: parent.goToMessage(message)
- onConferenceIcsCopied: parent.conferenceIcsCopied()
- onAddContactClicked: parent.addContactClicked(contactAddress)
- onViewContactClicked: parent.viewContactClicked(contactAddress)
-
+ RowLayout{
+ /*
anchors {
- left: parent.left
- leftMargin: ChatStyle.entry.metaWidth
- right: parent.right
+ left: parent.left
+ //leftMargin: ChatStyle.entry.metaWidth
+ right: parent.right
+ }
+ */
+ //width: parent.width
+ anchors.fill: parent
+ //onWidthChanged: console.log(width)
+ spacing: 0
+ //spacing: ChatStyle.entry.message.extraContent.spacing
+ Message {
+ id: message
+
+ onCopyAllDone: mainItem.copyAllDone()
+ onCopySelectionDone: mainItem.copySelectionDone()
+ onReplyClicked: mainItem.replyClicked()
+ onForwardClicked: mainItem.forwardClicked()
+ onGoToMessage: mainItem.goToMessage(message)
+ onConferenceIcsCopied: mainItem.conferenceIcsCopied()
+ onAddContactClicked: mainItem.addContactClicked(contactAddress)
+ onViewContactClicked: mainItem.viewContactClicked(contactAddress)
+ /*
+ anchors {
+ left: parent.left
+ leftMargin: ChatStyle.entry.metaWidth
+ right: parent.right
+ }*/
+ backgroundColorModel: ChatStyle.entry.message.outgoing.backgroundColor
+ Layout.fillWidth: true
+ //Layout.fillHeight: true
+ Layout.leftMargin: 10
+ //onImplicitHeightChanged: Layout.preferredHeight= implicitHeight
+ Layout.minimumHeight: implicitHeight // Avoid bug where UI is not computed by Qt
+ Layout.preferredHeight: implicitHeight
+ //Layout.preferredWidth: parent.width
+ //width: parent.width
+ // Not a style. Workaround to avoid a 0 width.
+ // Arbitrary value.
+ Layout.minimumWidth: 1
+ //onWidthChanged: console.log(width)
+
}
- backgroundColorModel: ChatStyle.entry.message.outgoing.backgroundColor
- width: parent.width
-
- Row {
+ /*
+ RowLayout {
anchors.fill: parent
anchors.leftMargin: ChatStyle.entry.message.extraContent.leftMargin
spacing: ChatStyle.entry.message.extraContent.spacing
-
+ */
Component {
id: iconComponent
-
- Icon {
- id: iconId
- readonly property var isError: Utils.includes([
- LinphoneEnums.ChatMessageStateFileTransferError,
- LinphoneEnums.ChatMessageStateNotDelivered,
- ], $chatEntry.state)
- readonly property bool isUploaded: $chatEntry.state == LinphoneEnums.ChatMessageStateDelivered
- readonly property bool isDelivered: $chatEntry.state == LinphoneEnums.ChatMessageStateDeliveredToUser
- readonly property bool isRead: $chatEntry.state == LinphoneEnums.ChatMessageStateDisplayed
-
- icon: iconId.isError
- ? 'chat_error'
- : (iconId.isRead ? 'chat_read' : (iconId.isDelivered ? 'chat_delivered' : '' ) )
- iconSize: ChatStyle.entry.message.outgoing.sendIconSize
-
- MouseArea {
- id:retryAction
- anchors.fill: parent
- visible: iconId.isError || $chatEntry.state == LinphoneEnums.ChatMessageStateIdle
- onClicked: $chatEntry.resendMessage()
- }
-
- TooltipArea {
- id:tooltip
- visible: text != ''
- text: iconId.isError
- ? qsTr('messageError')
- : (iconId.isRead ? qsTr('messageRead') : (isDelivered ? qsTr('messageDelivered') : ''))
- hoveringCursor : retryAction.visible?Qt.PointingHandCursor:Qt.ArrowCursor
+ Item{
+ Icon {
+ id: iconId
+ readonly property var isError: Utils.includes([
+ LinphoneEnums.ChatMessageStateFileTransferError,
+ LinphoneEnums.ChatMessageStateNotDelivered,
+ ], $chatEntry.state)
+ readonly property bool isUploaded: $chatEntry.state == LinphoneEnums.ChatMessageStateDelivered
+ readonly property bool isDelivered: $chatEntry.state == LinphoneEnums.ChatMessageStateDeliveredToUser
+ readonly property bool isRead: $chatEntry.state == LinphoneEnums.ChatMessageStateDisplayed
+
+ icon: iconId.isError
+ ? 'chat_error'
+ : (iconId.isRead ? 'chat_read' : (iconId.isDelivered ? 'chat_delivered' : '' ) )
+ iconSize: ChatStyle.entry.message.outgoing.sendIconSize
+ anchors.bottom: parent.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ MouseArea {
+ id:retryAction
+ anchors.fill: parent
+ visible: iconId.isError || $chatEntry.state == LinphoneEnums.ChatMessageStateIdle
+ onClicked: $chatEntry.resendMessage()
+ }
+
+ TooltipArea {
+ id:tooltip
+ visible: text != ''
+ text: iconId.isError
+ ? qsTr('messageError')
+ : (iconId.isRead ? qsTr('messageRead') : (iconId.isDelivered ? qsTr('messageDelivered') : ''))
+ hoveringCursor : retryAction.visible?Qt.PointingHandCursor:Qt.ArrowCursor
+ }
}
}
}
@@ -89,8 +122,6 @@ Item {
id: indicator
Item {
- anchors.fill: parent
-
BusyIndicator {
anchors.centerIn: parent
@@ -101,13 +132,23 @@ Item {
}
Loader {
- height: ChatStyle.entry.lineHeight
- width: ChatStyle.entry.message.outgoing.areaSize
+ //height: ChatStyle.entry.lineHeight
+ //anchors.bottom: parent.bottom
+ //Layout.alignment: Qt.AlignBottom | Qt.AlignHCenter
+ Layout.preferredWidth: ChatStyle.entry.message.outgoing.areaSize
+ Layout.fillHeight: true
+ //Layout.rightMargin: 10
sourceComponent: $chatEntry.state == LinphoneEnums.ChatMessageStateInProgress || $chatEntry.state == LinphoneEnums.ChatMessageStateFileTransferInProgress
? indicator
: iconComponent
}
- }
+ //}
}
+ /*
+ Rectangle{
+ anchors.fill: parent
+ color: 'yellow'
+ }
+ */
}
diff --git a/linphone-app/ui/modules/Linphone/Contact/ContactDescription.qml b/linphone-app/ui/modules/Linphone/Contact/ContactDescription.qml
index 8b515724e..bd944a223 100644
--- a/linphone-app/ui/modules/Linphone/Contact/ContactDescription.qml
+++ b/linphone-app/ui/modules/Linphone/Contact/ContactDescription.qml
@@ -76,12 +76,7 @@ Column {
}
Text{
id:status
- Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
- //anchors.top:parent.top
- //anchors.bottom : parent.bottom
- //anchors.left:parent.right
- //anchors.leftMargin:5
verticalAlignment: Text.AlignVCenter
visible: text != ''
text : ''
diff --git a/linphone-app/ui/modules/Linphone/Styles/Chat/ChatReplyMessageStyle.qml b/linphone-app/ui/modules/Linphone/Styles/Chat/ChatReplyMessageStyle.qml
index da4dae88e..b4ff711d8 100644
--- a/linphone-app/ui/modules/Linphone/Styles/Chat/ChatReplyMessageStyle.qml
+++ b/linphone-app/ui/modules/Linphone/Styles/Chat/ChatReplyMessageStyle.qml
@@ -18,12 +18,14 @@ QtObject {
}
}
property QtObject replyArea: QtObject{
- property var outgoingMarkColor: ColorsList.add(sectionName+'_reply_outgoing_mark', 'm')
- property var incomingMarkColor: ColorsList.add(sectionName+'_reply_incoming_mark', 'r')
+ property var outgoingMarkColor: ColorsList.add(sectionName+'_reply_outgoing_mark', 'outgoing_reply_mark_bg')
+ property var incomingMarkColor: ColorsList.add(sectionName+'_reply_incoming_mark', 'incoming_reply_mark_bg')
property var backgroundColor: ColorsList.add(sectionName+'_reply_bg', 'q')
property var foregroundColor: ColorsList.add(sectionName+'_reply_fg', 'h')
+ property var fileBackgroundColor: ColorsList.add(sectionName+'_reply_file_bg', 'reply_file_bg')
property int usernamePointSizeOffset: -2
property int pointSizeOffset: -2
+
}
property int padding: 8
diff --git a/linphone-app/ui/modules/Linphone/Styles/Chat/ChatStyle.qml b/linphone-app/ui/modules/Linphone/Styles/Chat/ChatStyle.qml
index 2c6a5b814..b363eab10 100644
--- a/linphone-app/ui/modules/Linphone/Styles/Chat/ChatStyle.qml
+++ b/linphone-app/ui/modules/Linphone/Styles/Chat/ChatStyle.qml
@@ -173,7 +173,7 @@ QtObject {
property QtObject message: QtObject {
property int padding: 8
- property int radius: 4
+ property int radius: 8
property QtObject extraContent: QtObject {
property int leftMargin: 10
@@ -182,7 +182,7 @@ QtObject {
}
property QtObject file: QtObject {
- property int height: 80
+ property int height: 120
property int heightbetter: 200
property int iconSize: 18
property int margins: 8
@@ -212,10 +212,11 @@ QtObject {
property string icon: 'file_extension_custom'
property string unknownIcon: 'file_unknown_custom'
property int iconSize: 60
- property int radius: 5
+ property int radius: 0
property QtObject background: QtObject {
property var colorModel: ColorsList.add(sectionName+'_file_extension_bg', 'q')
+ property var borderColorModel: ColorsList.add(sectionName+'_file_extension_border', 'extension_file_border')
}
property QtObject text: QtObject {
@@ -249,7 +250,7 @@ QtObject {
property QtObject incoming: QtObject {
property var backgroundColor: ColorsList.add(sectionName+'_incoming_bg', 'incoming_bg')
- property int avatarSize: 20
+ property int avatarSize: 30
property QtObject text: QtObject {
property var colorModel: ColorsList.add(sectionName+'_incoming_text', 'd')
@@ -259,9 +260,9 @@ QtObject {
property QtObject outgoing: QtObject {
property var backgroundColor: ColorsList.add(sectionName+'_outgoing_bg', 'outgoing_bg')
- property int areaSize: 12
+ property int areaSize: 32
property int busyIndicatorSize: 12
- property int sendIconSize: 60
+ property int sendIconSize: 12
property QtObject text: QtObject {
property var colorModel: ColorsList.add(sectionName+'_outgoing_text', 'd')
diff --git a/linphone-app/ui/modules/Linphone/qmldir b/linphone-app/ui/modules/Linphone/qmldir
index 6953676c1..1a289dc89 100644
--- a/linphone-app/ui/modules/Linphone/qmldir
+++ b/linphone-app/ui/modules/Linphone/qmldir
@@ -18,11 +18,14 @@ IncallAvatar 1.0 Calls/IncallAvatar.qml
CameraItem 1.0 Camera/CameraItem.qml
CameraView 1.0 Camera/CameraView.qml
+
Chat 1.0 Chat/Chat.qml
ChatAudioMessage 1.0 Chat/ChatAudioMessage.qml
ChatAudioPreview 1.0 Chat/ChatAudioPreview.qml
ChatCalendarMessage 1.0 Chat/ChatCalendarMessage.qml
ChatConferenceInvitationMessage 1.0 Chat/ChatConferenceInvitationMessage.qml
+ChatContent 1.0 Chat/ChatContent.qml
+ChatFullContent 1.0 Chat/ChatFullContent.qml
ChatMessagePreview 1.0 Chat/ChatMessagePreview.qml
ChatForwardMessage 1.0 Chat/ChatForwardMessage.qml
ChatReplyMessage 1.0 Chat/ChatReplyMessage.qml
diff --git a/linphone-app/ui/scripts/Utils/utils.js b/linphone-app/ui/scripts/Utils/utils.js
index 698b25b5b..83c3a7042 100644
--- a/linphone-app/ui/scripts/Utils/utils.js
+++ b/linphone-app/ui/scripts/Utils/utils.js
@@ -722,5 +722,8 @@ function printObject(o) {
for (var p in o) {
out += p + ': ' + o[p] + '\n';
}
- return out;
+ if(!o)
+ return 'Empty'
+ else
+ return out;
}