diff --git a/linphone-app/assets/images/move_to_bottom_custom.svg b/linphone-app/assets/images/move_to_bottom_custom.svg
new file mode 100644
index 000000000..32d352312
--- /dev/null
+++ b/linphone-app/assets/images/move_to_bottom_custom.svg
@@ -0,0 +1,84 @@
+
+
diff --git a/linphone-app/assets/languages/da.ts b/linphone-app/assets/languages/da.ts
index c04160dde..cdc2ee0c9 100644
--- a/linphone-app/assets/languages/da.ts
+++ b/linphone-app/assets/languages/da.ts
@@ -1563,6 +1563,14 @@ Klik her: <a href="%1">%1</a>
'Ephemeral messages have been updated: %1' : Little message to show on the event when ephemeral has been updated. %1 is a date time
+
+ unreadMessageNotice
+ '%1 unread messages' : Little message to show on an event where unread messages begin.
+
+
+
+
+
Notifier
diff --git a/linphone-app/assets/languages/de.ts b/linphone-app/assets/languages/de.ts
index 784ed26f6..6790d8942 100644
--- a/linphone-app/assets/languages/de.ts
+++ b/linphone-app/assets/languages/de.ts
@@ -1563,6 +1563,14 @@ Klicken Sie hier: <a href="%1">%1</a>
'Ephemeral messages have been updated: %1' : Little message to show on the event when ephemeral has been updated. %1 is a date time
Kurzlebige Nachrichten wurden aktualisiert: %1
+
+ unreadMessageNotice
+ '%1 unread messages' : Little message to show on an event where unread messages begin.
+
+
+
+
+
Notifier
diff --git a/linphone-app/assets/languages/en.ts b/linphone-app/assets/languages/en.ts
index de2ee4bd5..2e60808ce 100644
--- a/linphone-app/assets/languages/en.ts
+++ b/linphone-app/assets/languages/en.ts
@@ -1563,6 +1563,14 @@ Click here: <a href="%1">%1</a>
'Ephemeral messages have been updated: %1' : Little message to show on the event when ephemeral has been updated. %1 is a date time
Ephemeral messages have been updated: %1
+
+ unreadMessageNotice
+ '%1 unread messages' : Little message to show on an event where unread messages begin.
+
+ %1 unread message
+ %1 unread messages
+
+
Notifier
diff --git a/linphone-app/assets/languages/es.ts b/linphone-app/assets/languages/es.ts
index 6dd96dde1..6f145b0cb 100644
--- a/linphone-app/assets/languages/es.ts
+++ b/linphone-app/assets/languages/es.ts
@@ -1563,6 +1563,14 @@ Haga clic aquí: <a href="%1">%1 </a>
'Ephemeral messages have been updated: %1' : Little message to show on the event when ephemeral has been updated. %1 is a date time
+
+ unreadMessageNotice
+ '%1 unread messages' : Little message to show on an event where unread messages begin.
+
+
+
+
+
Notifier
diff --git a/linphone-app/assets/languages/fr_FR.ts b/linphone-app/assets/languages/fr_FR.ts
index adfb3dde6..42bca6f82 100644
--- a/linphone-app/assets/languages/fr_FR.ts
+++ b/linphone-app/assets/languages/fr_FR.ts
@@ -1563,6 +1563,14 @@ Cliquez ici : <a href="%1">%1</a>
'Ephemeral messages have been updated: %1' : Little message to show on the event when ephemeral has been updated. %1 is a date time
Délai d’expiration des messages : %1
+
+ unreadMessageNotice
+ '%1 unread messages' : Little message to show on an event where unread messages begin.
+
+
+
+
+
Notifier
diff --git a/linphone-app/assets/languages/hu.ts b/linphone-app/assets/languages/hu.ts
index 047d83ad4..c28508b65 100644
--- a/linphone-app/assets/languages/hu.ts
+++ b/linphone-app/assets/languages/hu.ts
@@ -1553,6 +1553,13 @@ Kattintson ide: <a href="%1">%1</a>
'Ephemeral messages have been updated: %1' : Little message to show on the event when ephemeral has been updated. %1 is a date time
Mulandó üzenetek frissítve: %1
+
+ unreadMessageNotice
+ '%1 unread messages' : Little message to show on an event where unread messages begin.
+
+
+
+
Notifier
diff --git a/linphone-app/assets/languages/it.ts b/linphone-app/assets/languages/it.ts
index a34f22946..344253319 100644
--- a/linphone-app/assets/languages/it.ts
+++ b/linphone-app/assets/languages/it.ts
@@ -1563,6 +1563,14 @@ Clicca: <a href="%1">%1</a>
'Ephemeral messages have been updated: %1' : Little message to show on the event when ephemeral has been updated. %1 is a date time
+
+ unreadMessageNotice
+ '%1 unread messages' : Little message to show on an event where unread messages begin.
+
+
+
+
+
Notifier
diff --git a/linphone-app/assets/languages/ja.ts b/linphone-app/assets/languages/ja.ts
index cec7c868b..9a4df0ec8 100644
--- a/linphone-app/assets/languages/ja.ts
+++ b/linphone-app/assets/languages/ja.ts
@@ -1553,6 +1553,13 @@
'Ephemeral messages have been updated: %1' : Little message to show on the event when ephemeral has been updated. %1 is a date time
+
+ unreadMessageNotice
+ '%1 unread messages' : Little message to show on an event where unread messages begin.
+
+
+
+
Notifier
diff --git a/linphone-app/assets/languages/lt.ts b/linphone-app/assets/languages/lt.ts
index 98b968793..2963d2ee3 100644
--- a/linphone-app/assets/languages/lt.ts
+++ b/linphone-app/assets/languages/lt.ts
@@ -1573,6 +1573,15 @@ Spustelėkite čia: <a href="%1">%1</a>
'Ephemeral messages have been updated: %1' : Little message to show on the event when ephemeral has been updated. %1 is a date time
+
+ unreadMessageNotice
+ '%1 unread messages' : Little message to show on an event where unread messages begin.
+
+
+
+
+
+
Notifier
diff --git a/linphone-app/assets/languages/pt_BR.ts b/linphone-app/assets/languages/pt_BR.ts
index 4461c601a..31c5964ce 100644
--- a/linphone-app/assets/languages/pt_BR.ts
+++ b/linphone-app/assets/languages/pt_BR.ts
@@ -1563,6 +1563,14 @@ Clique aqui: <a href="%1">%1 </a>
'Ephemeral messages have been updated: %1' : Little message to show on the event when ephemeral has been updated. %1 is a date time
Mensagens efêmeras foram atualizadas: %1
+
+ unreadMessageNotice
+ '%1 unread messages' : Little message to show on an event where unread messages begin.
+
+
+
+
+
Notifier
diff --git a/linphone-app/assets/languages/ru.ts b/linphone-app/assets/languages/ru.ts
index 349205e6a..e998b93a0 100644
--- a/linphone-app/assets/languages/ru.ts
+++ b/linphone-app/assets/languages/ru.ts
@@ -1573,6 +1573,15 @@
'Ephemeral messages have been updated: %1' : Little message to show on the event when ephemeral has been updated. %1 is a date time
+
+ unreadMessageNotice
+ '%1 unread messages' : Little message to show on an event where unread messages begin.
+
+
+
+
+
+
Notifier
diff --git a/linphone-app/assets/languages/sv.ts b/linphone-app/assets/languages/sv.ts
index 83d293da7..df01c1dcf 100644
--- a/linphone-app/assets/languages/sv.ts
+++ b/linphone-app/assets/languages/sv.ts
@@ -1563,6 +1563,14 @@ Klicka här: <a href="%1">%1</a>
'Ephemeral messages have been updated: %1' : Little message to show on the event when ephemeral has been updated. %1 is a date time
+
+ unreadMessageNotice
+ '%1 unread messages' : Little message to show on an event where unread messages begin.
+
+
+
+
+
Notifier
diff --git a/linphone-app/assets/languages/tr.ts b/linphone-app/assets/languages/tr.ts
index 6d0082047..56647e3a6 100644
--- a/linphone-app/assets/languages/tr.ts
+++ b/linphone-app/assets/languages/tr.ts
@@ -1553,6 +1553,13 @@ Buraya tıklayın: <a href="%1">%1</a>
'Ephemeral messages have been updated: %1' : Little message to show on the event when ephemeral has been updated. %1 is a date time
+
+ unreadMessageNotice
+ '%1 unread messages' : Little message to show on an event where unread messages begin.
+
+
+
+
Notifier
diff --git a/linphone-app/assets/languages/uk.ts b/linphone-app/assets/languages/uk.ts
index 021151aa2..6aeaae896 100644
--- a/linphone-app/assets/languages/uk.ts
+++ b/linphone-app/assets/languages/uk.ts
@@ -1573,6 +1573,15 @@
'Ephemeral messages have been updated: %1' : Little message to show on the event when ephemeral has been updated. %1 is a date time
+
+ unreadMessageNotice
+ '%1 unread messages' : Little message to show on an event where unread messages begin.
+
+
+
+
+
+
Notifier
diff --git a/linphone-app/assets/languages/zh_CN.ts b/linphone-app/assets/languages/zh_CN.ts
index b45bb1cec..420871429 100644
--- a/linphone-app/assets/languages/zh_CN.ts
+++ b/linphone-app/assets/languages/zh_CN.ts
@@ -1553,6 +1553,13 @@
'Ephemeral messages have been updated: %1' : Little message to show on the event when ephemeral has been updated. %1 is a date time
临时消息已被更新: %1
+
+ unreadMessageNotice
+ '%1 unread messages' : Little message to show on an event where unread messages begin.
+
+
+
+
Notifier
diff --git a/linphone-app/resources.qrc b/linphone-app/resources.qrc
index b2abbde85..40c729121 100644
--- a/linphone-app/resources.qrc
+++ b/linphone-app/resources.qrc
@@ -98,6 +98,7 @@
assets/images/micro_on_custom.svg
assets/images/missed_incoming_call_custom.svg
assets/images/missed_outgoing_call_custom.svg
+ assets/images/move_to_bottom_custom.svg
assets/images/new_call_custom.svg
assets/images/new_chat_group_custom.svg
assets/images/new_conference_custom.svg
diff --git a/linphone-app/src/components/chat-events/ChatNoticeModel.cpp b/linphone-app/src/components/chat-events/ChatNoticeModel.cpp
index 428300b1d..d8767282d 100644
--- a/linphone-app/src/components/chat-events/ChatNoticeModel.cpp
+++ b/linphone-app/src/components/chat-events/ChatNoticeModel.cpp
@@ -34,6 +34,14 @@ ChatNoticeModel::ChatNoticeModel ( std::shared_ptr eventLog,
mTimestamp = QDateTime::fromMSecsSinceEpoch(eventLog->getCreationTime() * 1000);
}
+ChatNoticeModel::ChatNoticeModel ( NoticeType noticeType, const QDateTime& timestamp, const QString& txt, QObject * parent) : ChatEvent(ChatRoomModel::EntryType::NoticeEntry, parent) {
+ App::getInstance()->getEngine()->setObjectOwnership(this, QQmlEngine::CppOwnership);// Avoid QML to destroy it when passing by Q_INVOKABLE
+ mEventLogType = LinphoneEnums::EventLogType::EventLogTypeNone;
+ setStatus(noticeType);
+ setName(txt);
+ mTimestamp = timestamp;
+}
+
ChatNoticeModel::~ChatNoticeModel(){
}
@@ -46,6 +54,15 @@ std::shared_ptr ChatNoticeModel::create(std::shared_ptr ChatNoticeModel::create(NoticeType noticeType, const QDateTime& timestamp, const QString& txt, QObject * parent){
+ auto model = std::make_shared(noticeType, timestamp, txt, parent);
+ if(model ){
+ model->mSelf = model;
+ return model;
+ }else
+ return nullptr;
+}
+
std::shared_ptr ChatNoticeModel::getEventLog(){
return mEventLog;
}
@@ -53,6 +70,8 @@ std::shared_ptr ChatNoticeModel::getEventLog(){
//---------------------------------------------------------------------------------------------
bool ChatNoticeModel::update(){
bool handledEvent = true;
+ if(!mEventLog)
+ return false;
auto participantAddress = mEventLog->getParticipantAddress();
switch(mEventLog->getType()){
@@ -158,5 +177,6 @@ void ChatNoticeModel::setEventLogType(const LinphoneEnums::EventLogType& data){
}
void ChatNoticeModel::deleteEvent(){
- mEventLog->deleteFromDatabase();
+ if(mEventLog)
+ mEventLog->deleteFromDatabase();
}
\ No newline at end of file
diff --git a/linphone-app/src/components/chat-events/ChatNoticeModel.hpp b/linphone-app/src/components/chat-events/ChatNoticeModel.hpp
index 6fe8a4e97..0b1e171e8 100644
--- a/linphone-app/src/components/chat-events/ChatNoticeModel.hpp
+++ b/linphone-app/src/components/chat-events/ChatNoticeModel.hpp
@@ -32,16 +32,19 @@ class ChatNoticeModel : public ChatEvent {
public:
enum NoticeType {
- NoticeMessage,
- NoticeError
+ NoticeMessage, // This is a Linphone message
+ NoticeError, // This is a Linphone error
+ NoticeUnreadMessages
};
Q_ENUM(NoticeType);
static std::shared_ptr create(std::shared_ptr eventLog, QObject * parent = nullptr);// Call it instead constructor
+ static std::shared_ptr create(NoticeType noticeType, const QDateTime& timestamp,const QString& txt, QObject * parent = nullptr);
ChatNoticeModel (std::shared_ptr eventLog, QObject * parent = nullptr);
+ ChatNoticeModel (NoticeType noticeType, const QDateTime& timestamp, const QString& txt, QObject * parent = nullptr);
virtual ~ChatNoticeModel();
- Q_PROPERTY(ChatRoomModel::EntryType type MEMBER mType CONSTANT)
+ Q_PROPERTY(ChatRoomModel::EntryType type MEMBER mType CONSTANT)// NoticeEntry
Q_PROPERTY(QDateTime timestamp MEMBER mTimestamp CONSTANT)
Q_PROPERTY(QString name MEMBER mName WRITE setName NOTIFY nameChanged)
Q_PROPERTY(NoticeType status MEMBER mStatus WRITE setStatus NOTIFY statusChanged)
diff --git a/linphone-app/src/components/chat-room/ChatRoomModel.cpp b/linphone-app/src/components/chat-room/ChatRoomModel.cpp
index 825aafd8e..59d03f1bc 100644
--- a/linphone-app/src/components/chat-room/ChatRoomModel.cpp
+++ b/linphone-app/src/components/chat-room/ChatRoomModel.cpp
@@ -205,6 +205,7 @@ ChatRoomModel::ChatRoomModel (std::shared_ptr chatRoom, QObj
QElapsedTimer timer;
timer.start();
CoreHandlers *coreHandlers = mCoreHandlers.get();
+ QObject::connect(this, &ChatRoomModel::messageSent, this, &ChatRoomModel::resetMessageCount);
//QObject::connect(coreHandlers, &CoreHandlers::messageReceived, this, &ChatRoomModel::handleMessageReceived);
QObject::connect(coreHandlers, &CoreHandlers::callCreated, this, &ChatRoomModel::handleCallCreated);
QObject::connect(coreHandlers, &CoreHandlers::callStateChanged, this, &ChatRoomModel::handleCallStateChanged);
@@ -482,6 +483,10 @@ bool ChatRoomModel::haveEncryption() const{
return mChatRoom && mChatRoom->getCurrentParams()->getEncryptionBackend() != linphone::ChatRoomEncryptionBackend::None;
}
+bool ChatRoomModel::markAsReadEnabled() const{
+ return mMarkAsReadEnabled;
+}
+
bool ChatRoomModel::isSecure() const{
return mChatRoom && (mChatRoom->getSecurityLevel() == linphone::ChatRoomSecurityLevel::Encrypted
|| mChatRoom->getSecurityLevel() == linphone::ChatRoomSecurityLevel::Safe);
@@ -514,11 +519,11 @@ bool ChatRoomModel::isCurrentProxy() const{
bool ChatRoomModel::canHandleParticipants() const{
return mChatRoom->canHandleParticipants();
}
-/*
+
bool ChatRoomModel::getIsRemoteComposing () const {
- return mIsRemoteComposing;
+ return mComposers.size() > 0;
}
-*/
+
std::shared_ptr ChatRoomModel::getChatRoom(){
return mChatRoom;
@@ -603,6 +608,13 @@ void ChatRoomModel::setEphemeralLifetime(long lifetime){
}
}
+void ChatRoomModel::enableMarkAsRead(const bool& enable){
+ if( mMarkAsReadEnabled != enable){
+ mMarkAsReadEnabled = enable;
+ emit markAsReadEnabledChanged();
+ }
+}
+
void ChatRoomModel::setReply(ChatMessageModel * model){
if(model != mReplyModel.get()){
if( model && model->getChatMessage() )
@@ -738,10 +750,16 @@ void ChatRoomModel::compose () {
}
void ChatRoomModel::resetMessageCount () {
- if(mChatRoom && !mDeleteChatRoom){
+ if(mChatRoom && !mDeleteChatRoom && markAsReadEnabled()){
if (mChatRoom->getUnreadMessagesCount() > 0){
mChatRoom->markAsRead();// Marking as read is only for messages. Not for calls.
}
+ if(!mUnreadMessageNotice.first)
+ mUnreadMessageNotice.first = true;
+ else if( mUnreadMessageNotice.second){
+ removeEntry(mUnreadMessageNotice.second.get());
+ mUnreadMessageNotice.second = nullptr;
+ }
setUnreadMessagesCount(mChatRoom->getUnreadMessagesCount());
setMissedCallsCount(0);
emit messageCountReset();
@@ -831,9 +849,14 @@ void ChatRoomModel::initEntries(){
// On call : reinitialize all entries. This allow to free up memory
QList > entries;
QList prepareEntries;
+ QDateTime lastUnreadMessage = QDateTime::currentDateTime();
// Get chat messages
- for (auto &message : mChatRoom->getHistory(mLastEntriesStep))
+ for (auto &message : mChatRoom->getHistory(mLastEntriesStep)) {
prepareEntries << EntrySorterHelper(message->getTime() ,MessageEntry, message);
+ if( !message->isRead()) {
+ lastUnreadMessage = min(lastUnreadMessage, QDateTime::fromMSecsSinceEpoch(message->getTime() * 1000));
+ }
+ }
// Get events
for(auto &eventLog : mChatRoom->getHistoryEvents(mLastEntriesStep))
prepareEntries << EntrySorterHelper(eventLog->getCreationTime() , NoticeEntry, eventLog);
@@ -852,6 +875,12 @@ void ChatRoomModel::initEntries(){
}
EntrySorterHelper::getLimitedSelection(&entries, prepareEntries, mLastEntriesStep, this);
+ if( mChatRoom->getUnreadMessagesCount() > 0) {
+ mUnreadMessageNotice.first = false;
+ mUnreadMessageNotice.second = ChatNoticeModel::create(ChatNoticeModel::NoticeType::NoticeUnreadMessages, lastUnreadMessage, QString::number(mChatRoom->getUnreadMessagesCount()));
+ entries.push_front(mUnreadMessageNotice.second);
+ }
+
mIsInitialized = true;
if(entries.size() >0){
beginResetModel();
@@ -914,7 +943,7 @@ int ChatRoomModel::loadMoreEntries(){
bool haveEntry = false;
while(!haveEntry && itEntries != mEntries.end()){
auto entry = dynamic_cast(itEntries->get());
- haveEntry = (entry && entry->getEventLog() == eventLog);
+ haveEntry = (entry && entry->getEventLog() && entry->getEventLog() == eventLog);
++itEntries;
}
if(!haveEntry)
@@ -1057,6 +1086,12 @@ void ChatRoomModel::insertNotices (const QList &call, linphone::Call::State state) {
diff --git a/linphone-app/src/components/chat-room/ChatRoomModel.hpp b/linphone-app/src/components/chat-room/ChatRoomModel.hpp
index 2e19836f8..77bab8021 100644
--- a/linphone-app/src/components/chat-room/ChatRoomModel.hpp
+++ b/linphone-app/src/components/chat-room/ChatRoomModel.hpp
@@ -134,7 +134,7 @@ public:
Q_PROPERTY(bool isMeAdmin READ isMeAdmin NOTIFY isMeAdminChanged)
Q_PROPERTY(bool canHandleParticipants READ canHandleParticipants CONSTANT)
- //Q_PROPERTY(bool isComposing MEMBER mIsRemoteComposing NOTIFY isRemoteComposingChanged)
+ Q_PROPERTY(bool isComposing READ getIsRemoteComposing NOTIFY isRemoteComposingChanged)
Q_PROPERTY(QList composers READ getComposers NOTIFY isRemoteComposingChanged)
Q_PROPERTY(bool hasBeenLeft READ hasBeenLeft NOTIFY hasBeenLeftChanged)
@@ -148,6 +148,7 @@ public:
Q_PROPERTY(long ephemeralLifetime READ getEphemeralLifetime WRITE setEphemeralLifetime NOTIFY ephemeralLifetimeChanged)
Q_PROPERTY(bool ephemeralEnabled READ isEphemeralEnabled WRITE setEphemeralEnabled NOTIFY ephemeralEnabledChanged)
Q_PROPERTY(bool canBeEphemeral READ canBeEphemeral NOTIFY canBeEphemeralChanged)
+ Q_PROPERTY(bool markAsReadEnabled READ markAsReadEnabled WRITE enableMarkAsRead NOTIFY markAsReadEnabledChanged)
Q_PROPERTY(ParticipantListModel* participants READ getParticipants CONSTANT)
@@ -187,6 +188,7 @@ public:
long getEphemeralLifetime() const;
bool canBeEphemeral();
bool haveEncryption() const;
+ bool markAsReadEnabled() const;
Q_INVOKABLE bool isSecure() const;
int getSecurityLevel() const;
bool isGroupEnabled() const;
@@ -211,6 +213,7 @@ public:
void addMissedCallsCount(std::shared_ptr call);
void setEphemeralEnabled(bool enabled);
void setEphemeralLifetime(long lifetime);
+ void enableMarkAsRead(const bool& enable);
void setReply(ChatMessageModel * model);
ChatMessageModel * getReply()const;
@@ -237,6 +240,7 @@ public:
bool mDeleteChatRoom = false; // Use as workaround because of core->deleteChatRoom() that call destructor without takking account of count ref : call it in ChatRoomModel destructor
int mLastEntriesStep = 50; // Retrieve a part of the history to avoid too much processing
+ bool mMarkAsReadEnabled = true;
void insertCall (const std::shared_ptr &callLog);
@@ -312,6 +316,7 @@ signals:
void ephemeralEnabledChanged();
void ephemeralLifetimeChanged();
void canBeEphemeralChanged();
+ void markAsReadEnabledChanged();
void chatRoomDeleted();// Must be connected with DirectConnection mode
void replyChanged();
@@ -337,7 +342,7 @@ private:
//void handleMessageReceived (const std::shared_ptr &message);
//bool mIsRemoteComposing = false;
-
+ QPair > mUnreadMessageNotice;
QList > mEntries;
std::shared_ptr mParticipantListModel;
std::shared_ptr mCoreHandlers;
diff --git a/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp b/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp
index 504488ae0..f20894b87 100644
--- a/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp
+++ b/linphone-app/src/components/chat-room/ChatRoomProxyModel.cpp
@@ -76,6 +76,7 @@ private:
ChatRoomProxyModel::ChatRoomProxyModel (QObject *parent) : QSortFilterProxyModel(parent) {
setSourceModel(new ChatRoomModelFilter(this));
+ mMarkAsReadEnabled = true;
//mIsSecure = false;
App *app = App::getInstance();
@@ -240,6 +241,14 @@ void ChatRoomProxyModel::setFullLocalAddress (const QString &localAddress) {
//reload();
}
+bool ChatRoomProxyModel::markAsReadEnabled() const{
+ return mChatRoomModel->markAsReadEnabled();
+}
+
+void ChatRoomProxyModel::enableMarkAsRead(const bool& enable){
+ mChatRoomModel->enableMarkAsRead(enable);
+}
+
QList ChatRoomProxyModel::getComposers() const{
return (mChatRoomModel?mChatRoomModel->getComposers():QList());
}
@@ -266,6 +275,7 @@ void ChatRoomProxyModel::reload (ChatRoomModel *chatRoomModel) {
QObject::disconnect(ChatRoomModel, &ChatRoomModel::isRemoteComposingChanged, this, &ChatRoomProxyModel::handleIsRemoteComposingChanged);
QObject::disconnect(ChatRoomModel, &ChatRoomModel::messageReceived, this, &ChatRoomProxyModel::handleMessageReceived);
QObject::disconnect(ChatRoomModel, &ChatRoomModel::messageSent, this, &ChatRoomProxyModel::handleMessageSent);
+ QObject::disconnect(ChatRoomModel, &ChatRoomModel::markAsReadEnabledChanged, this, &ChatRoomProxyModel::markAsReadEnabledChanged);
}
@@ -276,7 +286,8 @@ void ChatRoomProxyModel::reload (ChatRoomModel *chatRoomModel) {
ChatRoomModel *ChatRoomModel = mChatRoomModel.get();
QObject::connect(ChatRoomModel, &ChatRoomModel::isRemoteComposingChanged, this, &ChatRoomProxyModel::handleIsRemoteComposingChanged);
QObject::connect(ChatRoomModel, &ChatRoomModel::messageReceived, this, &ChatRoomProxyModel::handleMessageReceived);
- QObject::connect(ChatRoomModel, &ChatRoomModel::messageSent, this, &ChatRoomProxyModel::handleMessageSent);
+ QObject::connect(ChatRoomModel, &ChatRoomModel::messageSent, this, &ChatRoomProxyModel::handleMessageSent);
+ QObject::connect(ChatRoomModel, &ChatRoomModel::markAsReadEnabledChanged, this, &ChatRoomProxyModel::markAsReadEnabledChanged);
}
static_cast(sourceModel())->setSourceModel(mChatRoomModel.get());
@@ -324,7 +335,7 @@ static inline QWindow *getParentWindow (QObject *object) {
}
void ChatRoomProxyModel::handleIsActiveChanged (QWindow *window) {
- if (mChatRoomModel && window->isActive() && getParentWindow(this) == window) {
+ if (markAsReadEnabled() && mChatRoomModel && window->isActive() && getParentWindow(this) == window) {
auto timeline = CoreManager::getInstance()->getTimelineListModel()->getTimeline(mChatRoomModel->getChatRoom(), false);
if(timeline && timeline->mSelected){
mChatRoomModel->resetMessageCount();
diff --git a/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp b/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp
index 41d1d8817..7f8ba3020 100644
--- a/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp
+++ b/linphone-app/src/components/chat-room/ChatRoomProxyModel.hpp
@@ -47,6 +47,7 @@ class ChatRoomProxyModel : public QSortFilterProxyModel {
Q_PROPERTY(QString cachedText READ getCachedText)
Q_PROPERTY(QString filterText MEMBER mFilterText WRITE setFilterText NOTIFY filterTextChanged)
+ Q_PROPERTY(bool markAsReadEnabled READ markAsReadEnabled WRITE enableMarkAsRead NOTIFY markAsReadEnabledChanged)// Focus is at end of the list. Used to reset message count if not at end
public:
ChatRoomProxyModel (QObject *parent = Q_NULLPTR);
@@ -78,6 +79,7 @@ signals:
void fullPeerAddressChanged (const QString &fullPeerAddress);
void fullLocalAddressChanged (const QString &fullLocalAddress);
bool isRemoteComposingChanged ();
+ void markAsReadEnabledChanged();
//bool isSecureChanged(bool secure);
void chatRoomModelChanged();
@@ -104,6 +106,9 @@ private:
QString getFullLocalAddress () const;
void setFullLocalAddress (const QString &localAddress);
+ bool markAsReadEnabled() const;
+ void enableMarkAsRead(const bool& enable);
+
//bool isSecure () const;
//void setIsSecure (const int &secure);
@@ -129,6 +134,7 @@ private:
QString mFullPeerAddress;
QString mFullLocalAddress;
static QString gCachedText;
+ bool mMarkAsReadEnabled;
QString mFilterText;
diff --git a/linphone-app/ui/modules/Common/View/ScrollableListView.qml b/linphone-app/ui/modules/Common/View/ScrollableListView.qml
index 208a9291e..8e7918697 100644
--- a/linphone-app/ui/modules/Common/View/ScrollableListView.qml
+++ b/linphone-app/ui/modules/Common/View/ScrollableListView.qml
@@ -6,28 +6,51 @@ import Common 1.0
// =============================================================================
ListView {
- id: view
-
- // ---------------------------------------------------------------------------
-
- ScrollBar.vertical: ForceScrollBar {
- id: vScrollBar
-
- onPressedChanged: pressed ? view.movementStarted() : view.movementEnded()
- // ScrollBar.AsNeeded doesn't work. Do it ourself.
- policy: (view.contentHeight > view.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff)
- }
- // ---------------------------------------------------------------------------
-
- boundsBehavior: Flickable.StopAtBounds
- clip: true
- contentWidth: width - (vScrollBar.visible?vScrollBar.width:0)
- spacing: 0
- synchronousDrag: true
- cacheBuffer: height
- // ---------------------------------------------------------------------------
-
- // TODO: Find a solution at this bug =>
- // https://bugreports.qt.io/browse/QTBUG-31573
- // https://bugreports.qt.io/browse/QTBUG-49989
+ id: view
+
+ function getVisibleIndex(checkMax) {
+ var center_x = view.x + view.width / 2
+ var index = -1
+ var yCheck = 0
+ var direction = checkMax ? -1 : 1
+ var yStart = view.y + view.contentY + (checkMax ? view.height : 0)
+ var yStep = 5
+ while(index<0 && yCheck < view.height){
+ index = indexAt( center_x, yStart + yCheck * direction)
+ yCheck += yStep
+ }
+ return index
+ }
+ function getVisibleIndexRange() {
+ return [getVisibleIndex(0), getVisibleIndex(1)]
+ }
+ function isIndexVisible(index){
+ return getVisibleIndex(0) <= index && index <= getVisibleIndex(1)
+ }
+ function isIndexAfter(index){
+ return getVisibleIndex(1) < index
+ }
+
+ // ---------------------------------------------------------------------------
+
+ ScrollBar.vertical: ForceScrollBar {
+ id: vScrollBar
+
+ onPressedChanged: pressed ? view.movementStarted() : view.movementEnded()
+ // ScrollBar.AsNeeded doesn't work. Do it ourself.
+ policy: (view.contentHeight > view.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff)
+ }
+ // ---------------------------------------------------------------------------
+
+ boundsBehavior: Flickable.StopAtBounds
+ clip: true
+ contentWidth: width - (vScrollBar.visible?vScrollBar.width:0)
+ spacing: 0
+ synchronousDrag: true
+ cacheBuffer: height
+ // ---------------------------------------------------------------------------
+
+ // TODO: Find a solution at this bug =>
+ // https://bugreports.qt.io/browse/QTBUG-31573
+ // https://bugreports.qt.io/browse/QTBUG-49989
}
diff --git a/linphone-app/ui/modules/Linphone/Chat/Chat.qml b/linphone-app/ui/modules/Linphone/Chat/Chat.qml
index d3a2fe6c5..1010450a4 100644
--- a/linphone-app/ui/modules/Linphone/Chat/Chat.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/Chat.qml
@@ -296,13 +296,19 @@ Rectangle {
}
}
footer: Item{
+ implicitHeight: composersItem.implicitHeight
+ width: parent.width
Text {
- property var composers : container.proxyModel.composers
+ id: composersItem
+ property var composers : container.proxyModel.chatRoomModel.composers
+ onComposersChanged: console.log(composers)
+ onVisibleChanged: console.log(visible)
color: ChatStyle.composingText.color
font.pointSize: ChatStyle.composingText.pointSize
height: visible ? undefined : 0
leftPadding: ChatStyle.composingText.leftPadding
- visible: composers.length > 0 && (!proxyModel.chatRoomModel.haveEncryption && SettingsModel.standardChatEnabled || proxyModel.chatRoomModel.haveEncryption && SettingsModel.secureChatEnabled)
+ visible: composers.length > 0 && ( (!proxyModel.chatRoomModel.haveEncryption && SettingsModel.standardChatEnabled)
+ || (proxyModel.chatRoomModel.haveEncryption && SettingsModel.secureChatEnabled) )
wrapMode: Text.Wrap
//: '%1 is typing...' indicate that someone is composing in chat
text:(composers.length==0?'': qsTr('chatTyping','',composers.length).arg(container.proxyModel.getDisplayNameComposers()))
@@ -315,7 +321,7 @@ Rectangle {
}
Rectangle{
id: messageBlock
- height: 32
+ height: opacity > 0 ? 32 : 0
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
@@ -375,6 +381,31 @@ Rectangle {
}
]
}
+
+ ActionButton{
+ anchors.bottom: messageBlock.top
+ anchors.bottomMargin: 10
+ anchors.right: parent.right
+ anchors.rightMargin: 40
+ visible: chat.isIndexAfter(chat.count-1)
+ onVisibleChanged: container.proxyModel.markAsReadEnabled = !visible
+
+ isCustom: true
+ backgroundRadius: width/2
+ colorSet: ChatStyle.gotToBottom
+ onClicked: {
+ chat.bindToEnd = true
+ }
+ MessageCounter{
+ anchors.left: parent.right
+ anchors.bottom: parent.top
+ anchors.bottomMargin: -5
+ anchors.leftMargin: -5
+ count: container.proxyModel.chatRoomModel.unreadMessagesCount
+ }
+ }
+
+
}
// -------------------------------------------------------------------------
diff --git a/linphone-app/ui/modules/Linphone/Chat/Notice.qml b/linphone-app/ui/modules/Linphone/Chat/Notice.qml
index 49f9d3ccb..a54230410 100644
--- a/linphone-app/ui/modules/Linphone/Chat/Notice.qml
+++ b/linphone-app/ui/modules/Linphone/Chat/Notice.qml
@@ -15,6 +15,11 @@ RowLayout{
id: mainLayout
property string _type: {
var status = $chatEntry.eventLogType
+ var type = $chatEntry.status
+
+ if(type == ChatNoticeModel.NoticeUnreadMessages)
+ //: '%1 unread messages' : Little message to show on an event where unread messages begin.
+ return qsTr('unreadMessageNotice', '', $chatEntry.name)
if (status == LinphoneEnums.EventLogTypeConferenceCreated) {
//: 'You have joined the group' : Little message to show on the event when the user join the chat group.
diff --git a/linphone-app/ui/modules/Linphone/Styles/Chat/ChatStyle.qml b/linphone-app/ui/modules/Linphone/Styles/Chat/ChatStyle.qml
index c0a53d115..92eae750b 100644
--- a/linphone-app/ui/modules/Linphone/Styles/Chat/ChatStyle.qml
+++ b/linphone-app/ui/modules/Linphone/Styles/Chat/ChatStyle.qml
@@ -26,6 +26,18 @@ QtObject {
}
}
+ property QtObject gotToBottom: QtObject{
+ property string name: 'goToBottom'
+ property string icon: 'move_to_bottom_custom'
+ property int iconSize: 30
+ property color backgroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_b_n', icon, 's_n_b_bg').color
+ property color backgroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_b_h', icon, 's_h_b_bg').color
+ property color backgroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_b_p', icon, 's_p_b_bg').color
+ property color foregroundNormalColor : ColorsList.addImageColor(sectionName+'_'+name+'_f_n', icon, 's_n_b_fg').color
+ property color foregroundHoveredColor : ColorsList.addImageColor(sectionName+'_'+name+'_f_h', icon, 's_h_b_fg').color
+ property color foregroundPressedColor : ColorsList.addImageColor(sectionName+'_'+name+'_f_p', icon, 's_p_b_fg').color
+ }
+
property QtObject sendArea: QtObject {
property int height: 80
diff --git a/linphone-sdk b/linphone-sdk
index 3d422c64a..5800f6e48 160000
--- a/linphone-sdk
+++ b/linphone-sdk
@@ -1 +1 @@
-Subproject commit 3d422c64a3a10289fe6dda31ccb0af17b41cfffa
+Subproject commit 5800f6e489b250c5ffccaa90c8771a10a9edad59