First working prototype of history requesting, dates in messages, some screen scrolling handling

This commit is contained in:
Blue 2019-05-15 20:36:37 +03:00
parent d09fef5a34
commit da3151391b
19 changed files with 422 additions and 136 deletions

View file

@ -8,6 +8,10 @@ set(CMAKE_AUTOUIC ON)
# Find the QtWidgets library
find_package(Qt5Widgets CONFIG REQUIRED)
find_package(Qt5Qml CONFIG REQUIRED)
find_package(Qt5QuickCompiler)
find_package(Qt5Quick CONFIG REQUIRED)
find_package(Qt5QuickWidgets CONFIG REQUIRED)
set(squawkUI_SRC
squawk.cpp
@ -28,6 +32,9 @@ add_library(squawkUI ${squawkUI_SRC})
# Use the Widgets module from Qt 5.
target_link_libraries(squawkUI Qt5::Widgets)
target_link_libraries(squawkUI Qt5::Quick)
target_link_libraries(squawkUI Qt5::Qml)
target_link_libraries(squawkUI Qt5::QuickWidgets)
# Install the executable
install(TARGETS squawkUI DESTINATION lib)

View file

@ -20,6 +20,7 @@
#include "ui_conversation.h"
#include <QDebug>
#include <QScrollBar>
#include <QTimer>
Conversation::Conversation(Models::Contact* p_contact, QWidget* parent):
QWidget(parent),
@ -30,7 +31,9 @@ Conversation::Conversation(Models::Contact* p_contact, QWidget* parent):
activePalResource(),
thread(),
scroll(down),
manualSliderChange(false)
manualSliderChange(false),
requestingHistory(false),
everShown(false)
{
m_ui->setupUi(this);
m_ui->splitter->setSizes({300, 0});
@ -116,6 +119,7 @@ void Conversation::addMessage(const Shared::Message& data)
{
int pos = m_ui->scrollArea->verticalScrollBar()->sliderPosition();
int max = m_ui->scrollArea->verticalScrollBar()->maximum();
MessageLine::Position place = line->message(data);
if (place == MessageLine::invalid) {
return;
@ -183,6 +187,7 @@ void Conversation::onEnterPressed()
msg.setBody(body);
msg.setOutgoing(true);
msg.generateRandomId();
msg.setCurrentTime();
addMessage(msg);
emit sendMessage(msg);
}
@ -195,6 +200,18 @@ void Conversation::onMessagesResize(int amount)
case down:
m_ui->scrollArea->verticalScrollBar()->setValue(m_ui->scrollArea->verticalScrollBar()->maximum());
break;
case keep: {
int max = m_ui->scrollArea->verticalScrollBar()->maximum();
int value = m_ui->scrollArea->verticalScrollBar()->value() + amount;
m_ui->scrollArea->verticalScrollBar()->setValue(value);
if (value == max) {
scroll = down;
} else {
scroll = nothing;
}
}
break;
default:
break;
}
@ -207,7 +224,35 @@ void Conversation::onSliderValueChanged(int value)
if (value == m_ui->scrollArea->verticalScrollBar()->maximum()) {
scroll = down;
} else {
if (!requestingHistory && value == 0) {
m_ui->historyStatus->setPixmap(QIcon::fromTheme("view-refresh").pixmap(25));
requestingHistory = true;
emit requestArchive(line->firstMessageId());
}
scroll = nothing;
}
}
}
void Conversation::responseArchive(const std::list<Shared::Message> list)
{
requestingHistory = false;
scroll = keep;
m_ui->historyStatus->clear();
for (std::list<Shared::Message>::const_iterator itr = list.begin(), end = list.end(); itr != end; ++itr) {
addMessage(*itr);
}
}
void Conversation::showEvent(QShowEvent* event)
{
if (!everShown) {
everShown = true;
m_ui->historyStatus->setPixmap(QIcon::fromTheme("view-refresh").pixmap(25));
requestingHistory = true;
emit requestArchive(line->firstMessageId());
}
QWidget::showEvent(event);
}

View file

@ -56,9 +56,12 @@ public:
void addMessage(const Shared::Message& data);
void setPalResource(const QString& res);
void responseArchive(const std::list<Shared::Message> list);
void showEvent(QShowEvent * event) override;
signals:
void sendMessage(const Shared::Message& message);
void requestArchive(const QString& before);
protected:
void setState(Shared::Availability state);
@ -85,6 +88,8 @@ private:
QString thread;
Scroll scroll;
bool manualSliderChange;
bool requestingHistory;
bool everShown;
};
#endif // CONVERSATION_H

View file

@ -105,6 +105,13 @@
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="historyStatus">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="avatar">
<property name="text">
@ -134,7 +141,7 @@
<x>0</x>
<y>0</y>
<width>572</width>
<height>162</height>
<height>95</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">

View file

@ -76,6 +76,12 @@ MessageLine::Position MessageLine::message(const Shared::Message& msg)
QLabel* body = new QLabel(msg.getBody());
QLabel* sender = new QLabel();
QLabel* time = new QLabel(msg.getTime().toLocalTime().toString());
QFont dFont = time->font();
dFont.setItalic(true);
dFont.setPointSize(dFont.pointSize() - 2);
time->setFont(dFont);
time->setForegroundRole(QPalette::ToolTipText);
QFont f;
f.setBold(true);
sender->setFont(f);
@ -84,10 +90,12 @@ MessageLine::Position MessageLine::message(const Shared::Message& msg)
vBox->addWidget(sender);
vBox->addWidget(body);
vBox->addWidget(time);
if (msg.getOutgoing()) {
body->setAlignment(Qt::AlignRight);
//body->setAlignment(Qt::AlignRight);
sender->setAlignment(Qt::AlignRight);
time->setAlignment(Qt::AlignRight);
sender->setText(myName);
hBox->addStretch();
hBox->addWidget(message);
@ -132,3 +140,13 @@ void MessageLine::resizeEvent(QResizeEvent* event)
QWidget::resizeEvent(event);
emit resize(event->size().height() - event->oldSize().height());
}
QString MessageLine::firstMessageId() const
{
if (messageOrder.size() == 0) {
return "";
} else {
return messageOrder.begin()->second->getId();
}
}

View file

@ -25,6 +25,7 @@
#include <QLabel>
#include <QResizeEvent>
#include "../global.h"
#include <QtQuickWidgets/QQuickWidget>
class MessageLine : public QWidget
{
@ -42,6 +43,9 @@ public:
Position message(const Shared::Message& msg);
void setMyName(const QString& name);
void setPalName(const QString& jid, const QString& name);
QString firstMessageId() const;
void showBusyIndicator();
void hideBusyIndicator();
signals:
void resize(int amount);
@ -67,6 +71,7 @@ private:
QString myName;
std::map<QString, QString> palNames;
std::deque<QHBoxLayout*> views;
QQuickWidget busy;
};
#endif // MESSAGELINE_H

View file

@ -189,6 +189,7 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
conv->setAttribute(Qt::WA_DeleteOnClose);
connect(conv, SIGNAL(destroyed(QObject*)), this, SLOT(onConversationClosed(QObject*)));
connect(conv, SIGNAL(sendMessage(const Shared::Message&)), this, SLOT(onConversationMessage(const Shared::Message&)));
connect(conv, SIGNAL(requestArchive(const QString&)), this, SLOT(onConversationRequestArchive(const QString&)));
conversations.insert(std::make_pair(id, conv));
rosterModel.dropMessages(account, jid);
@ -198,7 +199,6 @@ void Squawk::onRosterItemDoubleClicked(const QModelIndex& item)
if (res.size() > 0) {
itr->second->setPalResource(res);
}
requestArchive(account, jid);
}
}
}
@ -234,3 +234,19 @@ void Squawk::onConversationMessage(const Shared::Message& msg)
emit sendMessage(conv->getAccount(), msg);
}
void Squawk::onConversationRequestArchive(const QString& before)
{
Conversation* conv = static_cast<Conversation*>(sender());
requestArchive(conv->getAccount(), conv->getJid(), 20, before); //TODO amount as a settings value
}
void Squawk::responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list)
{
Models::Roster::ElId id(account, jid);
Conversations::const_iterator itr = conversations.find(id);
if (itr != conversations.end()) {
itr->second->responseArchive(list);
}
}

View file

@ -6,6 +6,7 @@
#include <QCloseEvent>
#include <deque>
#include <map>
#include <list>
#include "accounts.h"
#include "conversation.h"
@ -31,7 +32,7 @@ signals:
void disconnectAccount(const QString&);
void changeState(int state);
void sendMessage(const QString& account, const Shared::Message& data);
void requestArchive(const QString& account, const QString& jid);
void requestArchive(const QString& account, const QString& jid, int count, const QString& before);
public slots:
void newAccount(const QMap<QString, QVariant>& account);
@ -47,6 +48,7 @@ public slots:
void removePresence(const QString& account, const QString& jid, const QString& name);
void stateChanged(int state);
void accountMessage(const QString& account, const Shared::Message& data);
void responseArchive(const QString& account, const QString& jid, const std::list<Shared::Message>& list);
private:
typedef std::map<Models::Roster::ElId, Conversation*> Conversations;
@ -66,6 +68,7 @@ private slots:
void onComboboxActivated(int index);
void onRosterItemDoubleClicked(const QModelIndex& item);
void onConversationMessage(const Shared::Message& msg);
void onConversationRequestArchive(const QString& before);
};