mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-04-27 10:08:41 +00:00
- Chat room loading optimization.
- Fix loading more chat entries when going to beginning. - Fix right padding text in chat messages. - Fix black screen videos.
This commit is contained in:
parent
3be835d378
commit
3aab79261e
24 changed files with 229 additions and 180 deletions
|
|
@ -54,22 +54,41 @@ Camera::Camera (QQuickItem *parent) : QQuickFramebufferObject(parent) {
|
||||||
mRefreshTimer->start();
|
mRefreshTimer->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SafeFramebuffer : public QQuickFramebufferObject::Renderer{
|
||||||
|
public:
|
||||||
|
SafeFramebuffer(){}
|
||||||
|
QOpenGLFramebufferObject *createFramebufferObject (const QSize &size) override{
|
||||||
|
return new QOpenGLFramebufferObject(size);
|
||||||
|
}
|
||||||
|
void render () override{}
|
||||||
|
void synchronize (QQuickFramebufferObject *item) override{}
|
||||||
|
};
|
||||||
|
|
||||||
QQuickFramebufferObject::Renderer *Camera::createRenderer () const {
|
QQuickFramebufferObject::Renderer *Camera::createRenderer () const {
|
||||||
QQuickFramebufferObject::Renderer * renderer = NULL;
|
QQuickFramebufferObject::Renderer * renderer = NULL;
|
||||||
if(mIsPreview){
|
if(mIsPreview){
|
||||||
CoreManager::getInstance()->getCore()->setNativePreviewWindowId(NULL);// Reset
|
CoreManager::getInstance()->getCore()->setNativePreviewWindowId(NULL);// Reset
|
||||||
renderer=(QQuickFramebufferObject::Renderer *)CoreManager::getInstance()->getCore()->getNativePreviewWindowId();
|
renderer=(QQuickFramebufferObject::Renderer *)CoreManager::getInstance()->getCore()->getNativePreviewWindowId();
|
||||||
return renderer;
|
CoreManager::getInstance()->getCore()->setNativePreviewWindowId(renderer);
|
||||||
}else{
|
}else{
|
||||||
auto call = mCallModel->getCall();
|
auto call = mCallModel->getCall();
|
||||||
if(call){
|
if(call){
|
||||||
call->setNativeVideoWindowId(NULL);// Reset
|
call->setNativeVideoWindowId(NULL);// Reset
|
||||||
return (QQuickFramebufferObject::Renderer *) call->getNativeVideoWindowId();
|
renderer = (QQuickFramebufferObject::Renderer *) call->getNativeVideoWindowId();
|
||||||
|
call->setNativeVideoWindowId(renderer);
|
||||||
}else{
|
}else{
|
||||||
CoreManager::getInstance()->getCore()->setNativeVideoWindowId(NULL);
|
CoreManager::getInstance()->getCore()->setNativeVideoWindowId(NULL);
|
||||||
return (QQuickFramebufferObject::Renderer *) CoreManager::getInstance()->getCore()->getNativeVideoWindowId();
|
renderer = (QQuickFramebufferObject::Renderer *) CoreManager::getInstance()->getCore()->getNativeVideoWindowId();
|
||||||
|
CoreManager::getInstance()->getCore()->setNativeVideoWindowId(renderer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(renderer)
|
||||||
|
return renderer;
|
||||||
|
else{
|
||||||
|
qWarning() << "Camera stream couldn't start for Rendering";
|
||||||
|
return new SafeFramebuffer();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -88,6 +88,7 @@ QQuickFramebufferObject::Renderer *CameraPreview::createRenderer () const {
|
||||||
QQuickFramebufferObject::Renderer * renderer;
|
QQuickFramebufferObject::Renderer * renderer;
|
||||||
CoreManager::getInstance()->getCore()->setNativePreviewWindowId(NULL);// Reset
|
CoreManager::getInstance()->getCore()->setNativePreviewWindowId(NULL);// Reset
|
||||||
renderer=(QQuickFramebufferObject::Renderer *)CoreManager::getInstance()->getCore()->getNativePreviewWindowId();
|
renderer=(QQuickFramebufferObject::Renderer *)CoreManager::getInstance()->getCore()->getNativePreviewWindowId();
|
||||||
|
CoreManager::getInstance()->getCore()->setNativePreviewWindowId(renderer);
|
||||||
if(renderer)
|
if(renderer)
|
||||||
return renderer;
|
return renderer;
|
||||||
else{
|
else{
|
||||||
|
|
|
||||||
|
|
@ -525,6 +525,9 @@ bool ChatRoomModel::getIsRemoteComposing () const {
|
||||||
return mComposers.size() > 0;
|
return mComposers.size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ChatRoomModel::isEntriesLoading() const{
|
||||||
|
return mEntriesLoading;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<linphone::ChatRoom> ChatRoomModel::getChatRoom(){
|
std::shared_ptr<linphone::ChatRoom> ChatRoomModel::getChatRoom(){
|
||||||
return mChatRoom;
|
return mChatRoom;
|
||||||
|
|
@ -885,6 +888,7 @@ void ChatRoomModel::updateNewMessageNotice(const int& count){
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatRoomModel::initEntries(){
|
void ChatRoomModel::initEntries(){
|
||||||
|
qDebug() << "Internal Entries : Init";
|
||||||
// On call : reinitialize all entries. This allow to free up memory
|
// On call : reinitialize all entries. This allow to free up memory
|
||||||
QList<std::shared_ptr<ChatEvent> > entries;
|
QList<std::shared_ptr<ChatEvent> > entries;
|
||||||
QList<EntrySorterHelper> prepareEntries;
|
QList<EntrySorterHelper> prepareEntries;
|
||||||
|
|
@ -909,7 +913,7 @@ void ChatRoomModel::initEntries(){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EntrySorterHelper::getLimitedSelection(&entries, prepareEntries, mLastEntriesStep, this);
|
EntrySorterHelper::getLimitedSelection(&entries, prepareEntries, mLastEntriesStep, this);
|
||||||
|
qDebug() << "Internal Entries : Built";
|
||||||
mIsInitialized = true;
|
mIsInitialized = true;
|
||||||
if(entries.size() >0){
|
if(entries.size() >0){
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
|
|
@ -917,78 +921,95 @@ void ChatRoomModel::initEntries(){
|
||||||
updateNewMessageNotice(mChatRoom->getUnreadMessagesCount());
|
updateNewMessageNotice(mChatRoom->getUnreadMessagesCount());
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
qDebug() << "Internal Entries : End";
|
||||||
|
}
|
||||||
|
void ChatRoomModel::setEntriesLoading(const bool& loading){
|
||||||
|
if( mEntriesLoading != loading){
|
||||||
|
mEntriesLoading = loading;
|
||||||
|
emit entriesLoadingChanged(mEntriesLoading);
|
||||||
|
qApp->processEvents();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int ChatRoomModel::loadMoreEntries(){
|
int ChatRoomModel::loadMoreEntries(){
|
||||||
QList<std::shared_ptr<ChatEvent> > entries;
|
setEntriesLoading(true);
|
||||||
QList<EntrySorterHelper> prepareEntries;
|
int currentRowCount = rowCount();
|
||||||
// Get current event count for each type
|
int newEntries = 0;
|
||||||
QVector<int> entriesCounts;
|
do{
|
||||||
entriesCounts.resize(3);
|
QList<std::shared_ptr<ChatEvent> > entries;
|
||||||
for(auto itEntries = mEntries.begin() ; itEntries != mEntries.end() ; ++itEntries){
|
QList<EntrySorterHelper> prepareEntries;
|
||||||
if( (*itEntries)->mType == MessageEntry)
|
// Get current event count for each type
|
||||||
++entriesCounts[0];
|
QVector<int> entriesCounts;
|
||||||
else if( (*itEntries)->mType == CallEntry){
|
entriesCounts.resize(3);
|
||||||
if(dynamic_cast<ChatCallModel*>((*itEntries).get())->mIsStart)
|
for(auto itEntries = mEntries.begin() ; itEntries != mEntries.end() ; ++itEntries){
|
||||||
++entriesCounts[1];
|
if( (*itEntries)->mType == MessageEntry)
|
||||||
} else
|
++entriesCounts[0];
|
||||||
++entriesCounts[2];
|
else if( (*itEntries)->mType == CallEntry){
|
||||||
}
|
if(dynamic_cast<ChatCallModel*>((*itEntries).get())->mIsStart)
|
||||||
|
++entriesCounts[1];
|
||||||
|
} else
|
||||||
|
++entriesCounts[2];
|
||||||
|
}
|
||||||
|
|
||||||
// Messages
|
// Messages
|
||||||
for (auto &message : mChatRoom->getHistoryRange(entriesCounts[0], entriesCounts[0]+mLastEntriesStep)){
|
for (auto &message : mChatRoom->getHistoryRange(entriesCounts[0], entriesCounts[0]+mLastEntriesStep)){
|
||||||
auto itEntries = mEntries.begin();
|
auto itEntries = mEntries.begin();
|
||||||
bool haveEntry = false;
|
bool haveEntry = false;
|
||||||
while(!haveEntry && itEntries != mEntries.end()){
|
while(!haveEntry && itEntries != mEntries.end()){
|
||||||
auto entry = dynamic_cast<ChatMessageModel*>(itEntries->get());
|
auto entry = dynamic_cast<ChatMessageModel*>(itEntries->get());
|
||||||
haveEntry = (entry && entry->getChatMessage() == message);
|
haveEntry = (entry && entry->getChatMessage() == message);
|
||||||
++itEntries;
|
++itEntries;
|
||||||
|
}
|
||||||
|
if(!haveEntry)
|
||||||
|
prepareEntries << EntrySorterHelper(message->getTime() ,MessageEntry, message);
|
||||||
}
|
}
|
||||||
if(!haveEntry)
|
|
||||||
prepareEntries << EntrySorterHelper(message->getTime() ,MessageEntry, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calls
|
// Calls
|
||||||
bool secureChatEnabled = CoreManager::getInstance()->getSettingsModel()->getSecureChatEnabled();
|
bool secureChatEnabled = CoreManager::getInstance()->getSettingsModel()->getSecureChatEnabled();
|
||||||
bool standardChatEnabled = CoreManager::getInstance()->getSettingsModel()->getStandardChatEnabled();
|
bool standardChatEnabled = CoreManager::getInstance()->getSettingsModel()->getStandardChatEnabled();
|
||||||
|
|
||||||
if( isOneToOne() && (secureChatEnabled && !standardChatEnabled && isSecure()
|
if( isOneToOne() && (secureChatEnabled && !standardChatEnabled && isSecure()
|
||||||
|| standardChatEnabled && !isSecure()) ) {
|
|| standardChatEnabled && !isSecure()) ) {
|
||||||
auto callHistory = CallsListModel::getCallHistory(getParticipantAddress(), Utils::coreStringToAppString(mChatRoom->getLocalAddress()->asStringUriOnly()));
|
auto callHistory = CallsListModel::getCallHistory(getParticipantAddress(), Utils::coreStringToAppString(mChatRoom->getLocalAddress()->asStringUriOnly()));
|
||||||
int count = 0;
|
int count = 0;
|
||||||
auto itCallHistory = callHistory.begin();
|
auto itCallHistory = callHistory.begin();
|
||||||
while(count < entriesCounts[1] && itCallHistory != callHistory.end()){
|
while(count < entriesCounts[1] && itCallHistory != callHistory.end()){
|
||||||
++itCallHistory;
|
++itCallHistory;
|
||||||
++count;
|
++count;
|
||||||
|
}
|
||||||
|
count = 0;
|
||||||
|
while( count < mLastEntriesStep && itCallHistory != callHistory.end()){
|
||||||
|
prepareEntries << EntrySorterHelper((*itCallHistory)->getStartDate(), CallEntry, *itCallHistory);
|
||||||
|
++itCallHistory;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
count = 0;
|
// Notices
|
||||||
while( count < mLastEntriesStep && itCallHistory != callHistory.end()){
|
for (auto &eventLog : mChatRoom->getHistoryRangeEvents(entriesCounts[2], entriesCounts[2]+mLastEntriesStep)){
|
||||||
prepareEntries << EntrySorterHelper((*itCallHistory)->getStartDate(), CallEntry, *itCallHistory);
|
auto itEntries = mEntries.begin();
|
||||||
++itCallHistory;
|
bool haveEntry = false;
|
||||||
|
while(!haveEntry && itEntries != mEntries.end()){
|
||||||
|
auto entry = dynamic_cast<ChatNoticeModel*>(itEntries->get());
|
||||||
|
haveEntry = (entry && entry->getEventLog() && entry->getEventLog() == eventLog);
|
||||||
|
++itEntries;
|
||||||
|
}
|
||||||
|
if(!haveEntry)
|
||||||
|
prepareEntries << EntrySorterHelper(eventLog->getCreationTime() , NoticeEntry, eventLog);
|
||||||
}
|
}
|
||||||
}
|
EntrySorterHelper::getLimitedSelection(&entries, prepareEntries, mLastEntriesStep, this);
|
||||||
// Notices
|
if(entries.size() >0){
|
||||||
for (auto &eventLog : mChatRoom->getHistoryRangeEvents(entriesCounts[2], entriesCounts[2]+mLastEntriesStep)){
|
beginInsertRows(QModelIndex(), 0, entries.size()-1);
|
||||||
auto itEntries = mEntries.begin();
|
for(auto entry : entries)
|
||||||
bool haveEntry = false;
|
mEntries.prepend(entry);
|
||||||
while(!haveEntry && itEntries != mEntries.end()){
|
endInsertRows();
|
||||||
auto entry = dynamic_cast<ChatNoticeModel*>(itEntries->get());
|
//emit layoutChanged();
|
||||||
haveEntry = (entry && entry->getEventLog() && entry->getEventLog() == eventLog);
|
updateLastUpdateTime();
|
||||||
++itEntries;
|
|
||||||
}
|
}
|
||||||
if(!haveEntry)
|
newEntries = entries.size();
|
||||||
prepareEntries << EntrySorterHelper(eventLog->getCreationTime() , NoticeEntry, eventLog);
|
}while( newEntries>0 && currentRowCount == rowCount());
|
||||||
}
|
currentRowCount = rowCount() - currentRowCount + 1;
|
||||||
EntrySorterHelper::getLimitedSelection(&entries, prepareEntries, mLastEntriesStep, this);
|
setEntriesLoading(false);
|
||||||
if(entries.size() >0){
|
emit moreEntriesLoaded(currentRowCount);
|
||||||
beginInsertRows(QModelIndex(), 0, entries.size()-1);
|
return currentRowCount;
|
||||||
for(auto entry : entries)
|
|
||||||
mEntries.prepend(entry);
|
|
||||||
endInsertRows();
|
|
||||||
emit layoutChanged();
|
|
||||||
updateLastUpdateTime();
|
|
||||||
}
|
|
||||||
return entries.size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,8 @@ public:
|
||||||
|
|
||||||
Q_PROPERTY(ChatMessageModel * reply READ getReply WRITE setReply NOTIFY replyChanged)
|
Q_PROPERTY(ChatMessageModel * reply READ getReply WRITE setReply NOTIFY replyChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(bool entriesLoading READ isEntriesLoading WRITE setEntriesLoading NOTIFY entriesLoadingChanged)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//ChatRoomModel (const QString &peerAddress, const QString &localAddress, const bool& isSecure);
|
//ChatRoomModel (const QString &peerAddress, const QString &localAddress, const bool& isSecure);
|
||||||
|
|
@ -199,6 +201,7 @@ public:
|
||||||
bool isCurrentProxy() const; // Return true if this chat room is Me() is the current proxy
|
bool isCurrentProxy() const; // Return true if this chat room is Me() is the current proxy
|
||||||
bool canHandleParticipants() const;
|
bool canHandleParticipants() const;
|
||||||
bool getIsRemoteComposing () const;
|
bool getIsRemoteComposing () const;
|
||||||
|
bool isEntriesLoading() const;
|
||||||
ParticipantListModel* getParticipants() const;
|
ParticipantListModel* getParticipants() const;
|
||||||
std::shared_ptr<linphone::ChatRoom> getChatRoom();
|
std::shared_ptr<linphone::ChatRoom> getChatRoom();
|
||||||
QList<QString> getComposers();
|
QList<QString> getComposers();
|
||||||
|
|
@ -208,6 +211,7 @@ public:
|
||||||
void setSubject(QString& subject);
|
void setSubject(QString& subject);
|
||||||
void setLastUpdateTime(const QDateTime& lastUpdateDate);
|
void setLastUpdateTime(const QDateTime& lastUpdateDate);
|
||||||
void updateLastUpdateTime();
|
void updateLastUpdateTime();
|
||||||
|
void setEntriesLoading(const bool& loading);
|
||||||
|
|
||||||
void setUnreadMessagesCount(const int& count);
|
void setUnreadMessagesCount(const int& count);
|
||||||
void setMissedCallsCount(const int& count);
|
void setMissedCallsCount(const int& count);
|
||||||
|
|
@ -243,6 +247,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
|
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
|
int mLastEntriesStep = 50; // Retrieve a part of the history to avoid too much processing
|
||||||
bool mMarkAsReadEnabled = true;
|
bool mMarkAsReadEnabled = true;
|
||||||
|
bool mEntriesLoading = false;
|
||||||
|
|
||||||
|
|
||||||
void insertCall (const std::shared_ptr<linphone::CallLog> &callLog);
|
void insertCall (const std::shared_ptr<linphone::CallLog> &callLog);
|
||||||
|
|
@ -289,6 +294,8 @@ public slots:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
bool isRemoteComposingChanged ();
|
bool isRemoteComposingChanged ();
|
||||||
|
void entriesLoadingChanged(const bool& loading);
|
||||||
|
void moreEntriesLoaded(const int& count);
|
||||||
|
|
||||||
void allEntriesRemoved (std::shared_ptr<ChatRoomModel> model);
|
void allEntriesRemoved (std::shared_ptr<ChatRoomModel> model);
|
||||||
void lastEntryRemoved ();
|
void lastEntryRemoved ();
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <QQuickWindow>
|
#include <QQuickWindow>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
#include "app/App.hpp"
|
#include "app/App.hpp"
|
||||||
#include "components/core/CoreManager.hpp"
|
#include "components/core/CoreManager.hpp"
|
||||||
|
|
@ -140,16 +141,16 @@ void ChatRoomProxyModel::compose (const QString& text) {
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
void ChatRoomProxyModel::loadMoreEntries () {
|
void ChatRoomProxyModel::loadMoreEntriesAsync(){
|
||||||
|
QTimer::singleShot(10, this, &ChatRoomProxyModel::loadMoreEntries);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatRoomProxyModel::onMoreEntriesLoaded(const int& count){
|
||||||
|
emit moreEntriesLoaded(count);
|
||||||
|
}
|
||||||
|
void ChatRoomProxyModel::loadMoreEntries() {
|
||||||
if(mChatRoomModel ) {
|
if(mChatRoomModel ) {
|
||||||
int currentRowCount = rowCount();
|
mChatRoomModel->loadMoreEntries();
|
||||||
int newEntries = 0;
|
|
||||||
do{
|
|
||||||
newEntries = mChatRoomModel->loadMoreEntries();
|
|
||||||
invalidate();
|
|
||||||
}while( newEntries>0 && currentRowCount == rowCount());
|
|
||||||
currentRowCount = rowCount() - currentRowCount + 1;
|
|
||||||
emit moreEntriesLoaded(currentRowCount);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -228,7 +229,6 @@ QString ChatRoomProxyModel::getFullPeerAddress () const {
|
||||||
void ChatRoomProxyModel::setFullPeerAddress (const QString &peerAddress) {
|
void ChatRoomProxyModel::setFullPeerAddress (const QString &peerAddress) {
|
||||||
mFullPeerAddress = peerAddress;
|
mFullPeerAddress = peerAddress;
|
||||||
emit fullPeerAddressChanged(mFullPeerAddress);
|
emit fullPeerAddressChanged(mFullPeerAddress);
|
||||||
//reload();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ChatRoomProxyModel::getFullLocalAddress () const {
|
QString ChatRoomProxyModel::getFullLocalAddress () const {
|
||||||
|
|
@ -238,7 +238,6 @@ QString ChatRoomProxyModel::getFullLocalAddress () const {
|
||||||
void ChatRoomProxyModel::setFullLocalAddress (const QString &localAddress) {
|
void ChatRoomProxyModel::setFullLocalAddress (const QString &localAddress) {
|
||||||
mFullLocalAddress = localAddress;
|
mFullLocalAddress = localAddress;
|
||||||
emit fullLocalAddressChanged(mFullLocalAddress);
|
emit fullLocalAddressChanged(mFullLocalAddress);
|
||||||
//reload();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChatRoomProxyModel::markAsReadEnabled() const{
|
bool ChatRoomProxyModel::markAsReadEnabled() const{
|
||||||
|
|
@ -277,6 +276,7 @@ void ChatRoomProxyModel::reload (ChatRoomModel *chatRoomModel) {
|
||||||
QObject::disconnect(ChatRoomModel, &ChatRoomModel::messageReceived, this, &ChatRoomProxyModel::handleMessageReceived);
|
QObject::disconnect(ChatRoomModel, &ChatRoomModel::messageReceived, this, &ChatRoomProxyModel::handleMessageReceived);
|
||||||
QObject::disconnect(ChatRoomModel, &ChatRoomModel::messageSent, this, &ChatRoomProxyModel::handleMessageSent);
|
QObject::disconnect(ChatRoomModel, &ChatRoomModel::messageSent, this, &ChatRoomProxyModel::handleMessageSent);
|
||||||
QObject::disconnect(ChatRoomModel, &ChatRoomModel::markAsReadEnabledChanged, this, &ChatRoomProxyModel::markAsReadEnabledChanged);
|
QObject::disconnect(ChatRoomModel, &ChatRoomModel::markAsReadEnabledChanged, this, &ChatRoomProxyModel::markAsReadEnabledChanged);
|
||||||
|
QObject::disconnect(ChatRoomModel, &ChatRoomModel::moreEntriesLoaded, this, &ChatRoomProxyModel::onMoreEntriesLoaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -289,6 +289,7 @@ void ChatRoomProxyModel::reload (ChatRoomModel *chatRoomModel) {
|
||||||
QObject::connect(ChatRoomModel, &ChatRoomModel::messageReceived, this, &ChatRoomProxyModel::handleMessageReceived);
|
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);
|
QObject::connect(ChatRoomModel, &ChatRoomModel::markAsReadEnabledChanged, this, &ChatRoomProxyModel::markAsReadEnabledChanged);
|
||||||
|
QObject::connect(ChatRoomModel, &ChatRoomModel::moreEntriesLoaded, this, &ChatRoomProxyModel::onMoreEntriesLoaded);
|
||||||
}
|
}
|
||||||
|
|
||||||
static_cast<ChatRoomModelFilter *>(sourceModel())->setSourceModel(mChatRoomModel.get());
|
static_cast<ChatRoomModelFilter *>(sourceModel())->setSourceModel(mChatRoomModel.get());
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,8 @@ public:
|
||||||
Q_INVOKABLE QString getDisplayNameComposers()const;
|
Q_INVOKABLE QString getDisplayNameComposers()const;
|
||||||
Q_INVOKABLE QVariant getAt(int row);
|
Q_INVOKABLE QVariant getAt(int row);
|
||||||
|
|
||||||
|
|
||||||
|
Q_INVOKABLE void loadMoreEntriesAsync ();
|
||||||
Q_INVOKABLE void loadMoreEntries ();
|
Q_INVOKABLE void loadMoreEntries ();
|
||||||
Q_INVOKABLE void setEntryTypeFilter (int type);
|
Q_INVOKABLE void setEntryTypeFilter (int type);
|
||||||
|
|
||||||
|
|
@ -73,6 +75,9 @@ public:
|
||||||
|
|
||||||
Q_INVOKABLE void setFilterText(const QString& text);
|
Q_INVOKABLE void setFilterText(const QString& text);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void onMoreEntriesLoaded(const int& count);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void peerAddressChanged (const QString &peerAddress);
|
void peerAddressChanged (const QString &peerAddress);
|
||||||
void localAddressChanged (const QString &localAddress);
|
void localAddressChanged (const QString &localAddress);
|
||||||
|
|
|
||||||
|
|
@ -102,10 +102,7 @@ void TimelineModel::setSelected(const bool& selected){
|
||||||
mChatRoomModel->initEntries();
|
mChatRoomModel->initEntries();
|
||||||
}
|
}
|
||||||
emit selectedChanged(mSelected);
|
emit selectedChanged(mSelected);
|
||||||
}else if(selected)// Warning, Setting to true is only when we want to force a selection. It's why we send a signal only in this case. We want avoid to change the counter on timelines that are already unselected.
|
}
|
||||||
// This only work because we want at least only one timeline selected
|
|
||||||
emit selectedChanged(mSelected);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimelineModel::updateUnreadCount(){
|
void TimelineModel::updateUnreadCount(){
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ BusyIndicator {
|
||||||
RotationAnimator {
|
RotationAnimator {
|
||||||
duration: BusyIndicatorStyle.duration
|
duration: BusyIndicatorStyle.duration
|
||||||
loops: Animation.Infinite
|
loops: Animation.Infinite
|
||||||
running: busyIndicator.visible && busyIndicator.running
|
running: true
|
||||||
target: item
|
target: item
|
||||||
|
|
||||||
from: 0
|
from: 0
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,7 @@ Item {
|
||||||
property bool colorOverwriteEnabled : false
|
property bool colorOverwriteEnabled : false
|
||||||
mipmap: SettingsModel.mipmapEnabled
|
mipmap: SettingsModel.mipmapEnabled
|
||||||
cache: Images.areReadOnlyImages
|
cache: Images.areReadOnlyImages
|
||||||
|
asynchronous: true
|
||||||
|
|
||||||
//anchors.centerIn: parent
|
//anchors.centerIn: parent
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,8 @@ ListView {
|
||||||
policy: (view.contentHeight > view.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff)
|
policy: (view.contentHeight > view.height ? ScrollBar.AlwaysOn : ScrollBar.AlwaysOff)
|
||||||
}
|
}
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
boundsMovement: Flickable.StopAtBounds
|
||||||
boundsBehavior: Flickable.StopAtBounds
|
boundsBehavior: Flickable.DragOverBounds
|
||||||
clip: true
|
clip: true
|
||||||
contentWidth: width - (vScrollBar.visible?vScrollBar.width:0)
|
contentWidth: width - (vScrollBar.visible?vScrollBar.width:0)
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
|
|
||||||
|
|
@ -31,53 +31,53 @@
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
function initView () {
|
function initView () {
|
||||||
chat.tryToLoadMoreEntries = false
|
chat.bindToEnd = true
|
||||||
chat.bindToEnd = true
|
chat.positionViewAtEnd()
|
||||||
|
if(chat.atYBeginning && !chat.loadingEntries){//Check if we are at beginning
|
||||||
|
chat.displaying = true
|
||||||
|
container.proxyModel.loadMoreEntriesAsync()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getComponentFromEntry (chatEntry) {
|
function getComponentFromEntry (chatEntry) {
|
||||||
|
|
||||||
if (chatEntry.type === Linphone.ChatRoomModel.CallEntry) {
|
if (chatEntry.type === Linphone.ChatRoomModel.CallEntry) {
|
||||||
return 'Event.qml'
|
return 'Event.qml'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chatEntry.type === Linphone.ChatRoomModel.NoticeEntry) {
|
if (chatEntry.type === Linphone.ChatRoomModel.NoticeEntry) {
|
||||||
return 'Notice.qml'
|
return 'Notice.qml'
|
||||||
}
|
}
|
||||||
|
|
||||||
return chatEntry.isOutgoing ? 'OutgoingMessage.qml' : 'IncomingMessage.qml'
|
return chatEntry.isOutgoing ? 'OutgoingMessage.qml' : 'IncomingMessage.qml'
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleFilesDropped (files) {
|
function handleFilesDropped (files) {
|
||||||
chat.bindToEnd = true
|
chat.bindToEnd = true
|
||||||
files.forEach(container.proxyModel.sendFileMessage)
|
files.forEach(container.proxyModel.sendFileMessage)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMoreEntriesLoaded (n) {
|
function handleMoreEntriesLoaded (n) {
|
||||||
chat.positionViewAtIndex(n - 1, QtQuick.ListView.Beginning)
|
chat.positionViewAtIndex(n - 1, QtQuick.ListView.Beginning)
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMovementEnded () {
|
function handleMovementEnded () {
|
||||||
if (chat.atYEnd) {
|
if (chat.atYEnd) {
|
||||||
chat.bindToEnd = true
|
chat.bindToEnd = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMovementStarted () {
|
function handleMovementStarted () {
|
||||||
chat.bindToEnd = false
|
chat.bindToEnd = false
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTextChanged (text) {
|
function handleTextChanged (text) {
|
||||||
container.proxyModel.compose(text)
|
container.proxyModel.compose(text)
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendMessage (text) {
|
function sendMessage (text) {
|
||||||
textArea.text = ''
|
textArea.text = ''
|
||||||
chat.bindToEnd = true
|
chat.bindToEnd = true
|
||||||
if(container.proxyModel)
|
if(container.proxyModel)
|
||||||
container.proxyModel.sendMessage(text)
|
container.proxyModel.sendMessage(text)
|
||||||
/*
|
|
||||||
else{// Create a chat room
|
|
||||||
CallsListModel.createChat()
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,61 +39,42 @@ Rectangle {
|
||||||
id: chat
|
id: chat
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
property bool bindToEnd: false
|
property bool bindToEnd: false
|
||||||
property bool tryToLoadMoreEntries: true
|
property bool displaying: false
|
||||||
//property var sipAddressObserver: SipAddressesModel.getSipAddressObserver(proxyModel.fullPeerAddress, proxyModel.fullLocalAddress)
|
property int loaderCount: 0
|
||||||
|
property int readyItems : 0
|
||||||
|
property bool loadingLoader: (readyItems != loaderCount)
|
||||||
|
property bool loadingEntries: container.proxyModel.chatRoomModel.entriesLoading || displaying
|
||||||
|
property bool tryToLoadMoreEntries: loadingEntries || loadingLoader
|
||||||
|
property bool isMoving : false // replace moving read-only property to allow using movement signals.
|
||||||
|
|
||||||
|
onLoadingEntriesChanged: {
|
||||||
|
if( loadingEntries && !displaying)
|
||||||
|
displaying = true
|
||||||
|
}
|
||||||
|
//property var sipAddressObserver: SipAddressesModel.getSipAddressObserver(proxyModel.fullPeerAddress, proxyModel.fullLocalAddress)
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
highlightFollowsCurrentItem: false
|
highlightFollowsCurrentItem: false
|
||||||
|
// Use moving event => this is a user action.
|
||||||
|
onIsMovingChanged:{
|
||||||
|
if(!chat.isMoving && chat.atYBeginning && !chat.loadingEntries){// Moving has stopped. Check if we are at beginning
|
||||||
|
chat.displaying = true
|
||||||
|
container.proxyModel.loadMoreEntriesAsync()
|
||||||
|
}
|
||||||
|
}
|
||||||
section {
|
section {
|
||||||
criteria: ViewSection.FullString
|
criteria: ViewSection.FullString
|
||||||
delegate: sectionHeading
|
delegate: sectionHeading
|
||||||
property: '$sectionDate'
|
property: '$sectionDate'
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer {
|
|
||||||
id: loadMoreEntriesDelayer
|
|
||||||
interval: 1
|
|
||||||
repeat: false
|
|
||||||
running: false
|
|
||||||
|
|
||||||
onTriggered: {
|
|
||||||
chat.positionViewAtBeginning()
|
|
||||||
container.proxyModel.loadMoreEntries()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Timer {
|
|
||||||
// Delay each search by 100ms
|
|
||||||
id: endOfLoadMoreEntriesDelayer
|
|
||||||
interval: 100
|
|
||||||
repeat: false
|
|
||||||
running: false
|
|
||||||
|
|
||||||
onTriggered: {
|
|
||||||
if(chat.atYBeginning){// We are still at the beginning. Try to continue searching
|
|
||||||
loadMoreEntriesDelayer.start()
|
|
||||||
}else// We are not at the begining. New search can be done by moving to the top.
|
|
||||||
chat.tryToLoadMoreEntries = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
Component.onCompleted: Logic.initView()
|
Component.onCompleted: Logic.initView()
|
||||||
|
onMovementStarted: {Logic.handleMovementStarted(); chat.isMoving = true}
|
||||||
onContentYChanged: {
|
onMovementEnded: {Logic.handleMovementEnded(); chat.isMoving = false}
|
||||||
if (chat.atYBeginning && !chat.tryToLoadMoreEntries) {
|
|
||||||
chat.tryToLoadMoreEntries = true// Show busy indicator
|
|
||||||
loadMoreEntriesDelayer.start()// Let GUI time to the busy indicator to be shown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
onMovementEnded: Logic.handleMovementEnded()
|
|
||||||
onMovementStarted: Logic.handleMovementStarted()
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------
|
// -----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
@ -104,12 +85,10 @@ Rectangle {
|
||||||
// the position is set at end and it can be possible to load
|
// the position is set at end and it can be possible to load
|
||||||
// more entries.
|
// more entries.
|
||||||
onEntryTypeFilterChanged: Logic.initView()
|
onEntryTypeFilterChanged: Logic.initView()
|
||||||
|
|
||||||
onMoreEntriesLoaded: {
|
onMoreEntriesLoaded: {
|
||||||
Logic.handleMoreEntriesLoaded(n)
|
Logic.handleMoreEntriesLoaded(n)// move view to n - 1 item
|
||||||
if(n>1)// New entries : delay the end
|
chat.displaying = false
|
||||||
endOfLoadMoreEntriesDelayer.start()
|
|
||||||
else// No new entries, we can stop without waiting
|
|
||||||
chat.tryToLoadMoreEntries = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -258,8 +237,18 @@ Rectangle {
|
||||||
// Display content.
|
// Display content.
|
||||||
Loader {
|
Loader {
|
||||||
id: loader
|
id: loader
|
||||||
|
height: (item !== null && typeof(item)!== 'undefined')? item.height: 0
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
source: Logic.getComponentFromEntry($chatEntry)
|
source: Logic.getComponentFromEntry($chatEntry)
|
||||||
|
property int count: 0
|
||||||
|
asynchronous: chat.count - count > 100
|
||||||
|
onStatusChanged: if( status == Loader.Ready) ++chat.readyItems
|
||||||
|
Component.onCompleted: count = ++chat.loaderCount
|
||||||
|
Component.onDestruction: {
|
||||||
|
--chat.loaderCount
|
||||||
|
if( status == Loader.Ready)
|
||||||
|
--chat.readyItems
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Connections{
|
Connections{
|
||||||
target: loader.item
|
target: loader.item
|
||||||
|
|
@ -300,16 +289,17 @@ Rectangle {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
Text {
|
Text {
|
||||||
id: composersItem
|
id: composersItem
|
||||||
property var composers : container.proxyModel.chatRoomModel && container.proxyModel.chatRoomModel.composers
|
property var composers : container.proxyModel.chatRoomModel ? container.proxyModel.chatRoomModel.composers : undefined
|
||||||
|
property int count : composers && composers.length ? composers.length : 0
|
||||||
color: ChatStyle.composingText.color
|
color: ChatStyle.composingText.color
|
||||||
font.pointSize: ChatStyle.composingText.pointSize
|
font.pointSize: ChatStyle.composingText.pointSize
|
||||||
height: visible ? undefined : 0
|
height: visible ? undefined : 0
|
||||||
leftPadding: ChatStyle.composingText.leftPadding
|
leftPadding: ChatStyle.composingText.leftPadding
|
||||||
visible: composers && composers.length > 0 && ( (!proxyModel.chatRoomModel.haveEncryption && SettingsModel.standardChatEnabled)
|
visible: count > 0 && ( (!proxyModel.chatRoomModel.haveEncryption && SettingsModel.standardChatEnabled)
|
||||||
|| (proxyModel.chatRoomModel.haveEncryption && SettingsModel.secureChatEnabled) )
|
|| (proxyModel.chatRoomModel.haveEncryption && SettingsModel.secureChatEnabled) )
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
//: '%1 is typing...' indicate that someone is composing in chat
|
//: '%1 is typing...' indicate that someone is composing in chat
|
||||||
text:(!composers || composers.length==0?'': qsTr('chatTyping','',composers.length).arg(container.proxyModel.getDisplayNameComposers()))
|
text:(count==0?'': qsTr('chatTyping','',count).arg(container.proxyModel.getDisplayNameComposers()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ TextEdit {
|
||||||
property string lastTextSelected : ''
|
property string lastTextSelected : ''
|
||||||
property font customFont : SettingsModel.textMessageFont
|
property font customFont : SettingsModel.textMessageFont
|
||||||
property int fitHeight: visible ? contentHeight + padding : 0
|
property int fitHeight: visible ? contentHeight + padding : 0
|
||||||
property int fitWidth: visible ? implicitWidth + padding*2 : 0
|
property int fitWidth: visible ? implicitWidth + 2: 0 // add 2 because there is a bug on border that lead to not fit text exactly
|
||||||
|
|
||||||
signal rightClicked()
|
signal rightClicked()
|
||||||
|
|
||||||
|
|
@ -36,10 +36,12 @@ TextEdit {
|
||||||
visible: contentModel && contentModel.isText()
|
visible: contentModel && contentModel.isText()
|
||||||
clip: true
|
clip: true
|
||||||
padding: ChatStyle.entry.message.padding
|
padding: ChatStyle.entry.message.padding
|
||||||
|
textMargin: 0
|
||||||
readOnly: true
|
readOnly: true
|
||||||
selectByMouse: true
|
selectByMouse: true
|
||||||
font.family: customFont.family
|
font.family: customFont.family
|
||||||
font.pointSize: Units.dp * customFont.pointSize
|
font.pointSize: Units.dp * customFont.pointSize
|
||||||
|
|
||||||
text: visible ? Utils.encodeTextToQmlRichFormat(contentModel.text, {
|
text: visible ? Utils.encodeTextToQmlRichFormat(contentModel.text, {
|
||||||
imagesHeight: ChatStyle.entry.message.images.height,
|
imagesHeight: ChatStyle.entry.message.images.height,
|
||||||
imagesWidth: ChatStyle.entry.message.images.width
|
imagesWidth: ChatStyle.entry.message.images.width
|
||||||
|
|
@ -51,7 +53,7 @@ TextEdit {
|
||||||
textFormat: Text.RichText // To supports links and imgs.
|
textFormat: Text.RichText // To supports links and imgs.
|
||||||
wrapMode: TextEdit.Wrap
|
wrapMode: TextEdit.Wrap
|
||||||
|
|
||||||
onCursorRectangleChanged: if(!readOnly) Logic.ensureVisible(cursorRectangle)
|
//onCursorRectangleChanged: if(!readOnly) Logic.ensureVisible(cursorRectangle)
|
||||||
onLinkActivated: Qt.openUrlExternally(link)
|
onLinkActivated: Qt.openUrlExternally(link)
|
||||||
onSelectedTextChanged:{
|
onSelectedTextChanged:{
|
||||||
if(selectedText != '') lastTextSelected = selectedText
|
if(selectedText != '') lastTextSelected = selectedText
|
||||||
|
|
|
||||||
|
|
@ -93,8 +93,7 @@ DialogPlus {
|
||||||
updateSelectionModels: false
|
updateSelectionModels: false
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
model: TimelineProxyModel{}
|
model: TimelineProxyModel{}
|
||||||
onEntrySelected:{
|
onEntryClicked:{
|
||||||
console.log(entry)
|
|
||||||
if( entry ) {
|
if( entry ) {
|
||||||
mainItem.chatRoomSelectedCallback(entry.chatRoomModel)
|
mainItem.chatRoomSelectedCallback(entry.chatRoomModel)
|
||||||
exit(1)
|
exit(1)
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ function loadMoreEntries () {
|
||||||
if (history.atYBeginning && !history.tryToLoadMoreEntries) {
|
if (history.atYBeginning && !history.tryToLoadMoreEntries) {
|
||||||
history.tryToLoadMoreEntries = true
|
history.tryToLoadMoreEntries = true
|
||||||
history.positionViewAtBeginning()
|
history.positionViewAtBeginning()
|
||||||
container.proxyModel.loadMoreEntries()
|
container.proxyModel.loadMoreEntriesAsync()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ Rectangle {
|
||||||
|
|
||||||
Component.onCompleted: Logic.initView()
|
Component.onCompleted: Logic.initView()
|
||||||
|
|
||||||
onContentYChanged: Logic.loadMoreEntries()
|
onContentYChanged: Logic.loadMoreEntriesAsync()
|
||||||
onMovementEnded: Logic.handleMovementEnded()
|
onMovementEnded: Logic.handleMovementEnded()
|
||||||
onMovementStarted: Logic.handleMovementStarted()
|
onMovementStarted: Logic.handleMovementStarted()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,7 @@ Notification {
|
||||||
onClicked: notification._close(function () {
|
onClicked: notification._close(function () {
|
||||||
AccountSettingsModel.setDefaultProxyConfigFromSipAddress(notification.localAddress)
|
AccountSettingsModel.setDefaultProxyConfigFromSipAddress(notification.localAddress)
|
||||||
notification.timelineModel.selected = true
|
notification.timelineModel.selected = true
|
||||||
|
console.log("Load conversation from notification")
|
||||||
notification.notificationData.window.setView('Conversation', {
|
notification.notificationData.window.setView('Conversation', {
|
||||||
chatRoomModel:notification.timelineModel.getChatRoomModel()
|
chatRoomModel:notification.timelineModel.getChatRoomModel()
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -164,7 +164,7 @@ QtObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
property QtObject message: QtObject {
|
property QtObject message: QtObject {
|
||||||
property int padding: 8
|
property int padding: 10
|
||||||
property int radius: 4
|
property int radius: 4
|
||||||
|
|
||||||
property QtObject extraContent: QtObject {
|
property QtObject extraContent: QtObject {
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ Rectangle {
|
||||||
|
|
||||||
//signal entrySelected (string entry)
|
//signal entrySelected (string entry)
|
||||||
signal entrySelected (TimelineModel entry)
|
signal entrySelected (TimelineModel entry)
|
||||||
|
signal entryClicked(TimelineModel entry)
|
||||||
signal showHistoryRequest()
|
signal showHistoryRequest()
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
@ -329,8 +330,8 @@ Rectangle {
|
||||||
preventStealing: false
|
preventStealing: false
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if(mouse.button == Qt.LeftButton){
|
if(mouse.button == Qt.LeftButton){
|
||||||
if(modelData.selected || !view.updateSelectionModels)// Update selection
|
//if(modelData.selected || !view.updateSelectionModels)// Update selection
|
||||||
timeline.entrySelected(modelData)
|
timeline.entryClicked(modelData)
|
||||||
if(view){
|
if(view){
|
||||||
if(view.updateSelectionModels)
|
if(view.updateSelectionModels)
|
||||||
modelData.selected = true
|
modelData.selected = true
|
||||||
|
|
|
||||||
|
|
@ -216,8 +216,6 @@ Window {
|
||||||
fullPeerAddress: window.call.fullPeerAddress
|
fullPeerAddress: window.call.fullPeerAddress
|
||||||
fullLocalAddress: window.call.fullLocalAddress
|
fullLocalAddress: window.call.fullLocalAddress
|
||||||
localAddress: window.call.localAddress
|
localAddress: window.call.localAddress
|
||||||
|
|
||||||
onChatRoomModelChanged: if(chatRoomModel) chatRoomModel.initEntries()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
|
|
||||||
|
|
@ -240,6 +240,7 @@ ColumnLayout {
|
||||||
sipAddresses: _contact ? _contact.vcard.sipAddresses : [ contactEdit.sipAddress ]
|
sipAddresses: _contact ? _contact.vcard.sipAddresses : [ contactEdit.sipAddress ]
|
||||||
|
|
||||||
function vewConversation(chatRoomModel){
|
function vewConversation(chatRoomModel){
|
||||||
|
console.log("Load conversation from contact edit")
|
||||||
window.setView('Conversation', {
|
window.setView('Conversation', {
|
||||||
chatRoomModel:chatRoomModel
|
chatRoomModel:chatRoomModel
|
||||||
}, function(){
|
}, function(){
|
||||||
|
|
|
||||||
|
|
@ -204,6 +204,7 @@ ColumnLayout {
|
||||||
Connections{
|
Connections{
|
||||||
target: lastChatRoom
|
target: lastChatRoom
|
||||||
onStateChanged: if(state === 1) {
|
onStateChanged: if(state === 1) {
|
||||||
|
console.log("Load conversation from contacts")
|
||||||
window.setView('Conversation', {
|
window.setView('Conversation', {
|
||||||
chatRoomModel: lastChatRoom
|
chatRoomModel: lastChatRoom
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -455,7 +455,7 @@ ColumnLayout {
|
||||||
anchors.leftMargin: 50
|
anchors.leftMargin: 50
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
//anchors.horizontalCenter: parent.horizontalCenter
|
//anchors.horizontalCenter: parent.horizontalCenter
|
||||||
visible: chatArea.tryingToLoadMoreEntries
|
running: chatArea.tryingToLoadMoreEntries
|
||||||
}
|
}
|
||||||
|
|
||||||
// -------------------------------------------------------------------------
|
// -------------------------------------------------------------------------
|
||||||
|
|
@ -527,7 +527,6 @@ ColumnLayout {
|
||||||
id:chatArea
|
id:chatArea
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
proxyModel: ChatRoomProxyModel {
|
proxyModel: ChatRoomProxyModel {
|
||||||
id: chatRoomProxyModel
|
id: chatRoomProxyModel
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -319,10 +319,12 @@ ApplicationWindow {
|
||||||
|
|
||||||
onEntrySelected:{
|
onEntrySelected:{
|
||||||
if( entry ) {
|
if( entry ) {
|
||||||
window.setView('Conversation', {
|
if( entry.selected){
|
||||||
chatRoomModel:entry.chatRoomModel
|
console.log("Load conversation from entry selected on timeline")
|
||||||
|
window.setView('Conversation', {
|
||||||
|
chatRoomModel:entry.chatRoomModel
|
||||||
})
|
})
|
||||||
|
}
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
window.setView('Home', {})
|
window.setView('Home', {})
|
||||||
|
|
@ -364,11 +366,14 @@ ApplicationWindow {
|
||||||
Connections {
|
Connections {
|
||||||
target: UrlHandlers
|
target: UrlHandlers
|
||||||
|
|
||||||
onSip: window.setView('Conversation', {
|
onSip: {
|
||||||
|
console.log("Change conversation from url handler")
|
||||||
|
window.setView('Conversation', {
|
||||||
peerAddress: sipAddress,
|
peerAddress: sipAddress,
|
||||||
localAddress: AccountSettingsModel.sipAddress,
|
localAddress: AccountSettingsModel.sipAddress,
|
||||||
fullPeerAddress: sipAddress,
|
fullPeerAddress: sipAddress,
|
||||||
fullLocalAddress: AccountSettingsModel.fullSipAddress
|
fullLocalAddress: AccountSettingsModel.fullSipAddress
|
||||||
})
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue