mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-25 12:38:48 +03:00
Implement simple scroll state handling
This commit is contained in:
parent
691c854201
commit
d1fffd6617
4 changed files with 77 additions and 2 deletions
|
@ -2,6 +2,7 @@ import QtQuick 2.6
|
||||||
import QtQuick.Controls 2.5
|
import QtQuick.Controls 2.5
|
||||||
import QtQuick.Layouts 1.5
|
import QtQuick.Layouts 1.5
|
||||||
import QtGraphicalEffects 1.0
|
import QtGraphicalEffects 1.0
|
||||||
|
import QtQuick.Window 2.2
|
||||||
|
|
||||||
import com.github.nheko 1.0
|
import com.github.nheko 1.0
|
||||||
|
|
||||||
|
@ -28,14 +29,51 @@ Rectangle {
|
||||||
visible: timelineManager.timeline != null
|
visible: timelineManager.timeline != null
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
model: timelineManager.timeline
|
||||||
|
|
||||||
|
onModelChanged: {
|
||||||
|
if (model) {
|
||||||
|
currentIndex = model.currentIndex
|
||||||
|
if (model.currentIndex == count - 1) {
|
||||||
|
positionViewAtEnd()
|
||||||
|
} else {
|
||||||
|
positionViewAtIndex(model.currentIndex, ListView.End)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ScrollBar.vertical: ScrollBar {
|
ScrollBar.vertical: ScrollBar {
|
||||||
id: scrollbar
|
id: scrollbar
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
onPressedChanged: if (!pressed) chat.updatePosition()
|
||||||
}
|
}
|
||||||
|
|
||||||
model: timelineManager.timeline
|
property bool atBottom: false
|
||||||
|
onCountChanged: {
|
||||||
|
if (atBottom && Window.active) {
|
||||||
|
var newIndex = count - 1 // last index
|
||||||
|
positionViewAtEnd()
|
||||||
|
currentIndex = newIndex
|
||||||
|
model.currentIndex = newIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updatePosition() {
|
||||||
|
for (var y = chat.contentY + chat.height; y > chat.height; y -= 5) {
|
||||||
|
var i = chat.itemAt(100, y);
|
||||||
|
if (!i) continue;
|
||||||
|
if (!i.isFullyVisible()) continue;
|
||||||
|
chat.model.currentIndex = i.getIndex();
|
||||||
|
chat.currentIndex = i.getIndex()
|
||||||
|
atBottom = i.getIndex() == count - 1;
|
||||||
|
console.log("bottom:" + atBottom)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onMovementEnded: updatePosition()
|
||||||
|
|
||||||
spacing: 4
|
spacing: 4
|
||||||
delegate: RowLayout {
|
delegate: RowLayout {
|
||||||
anchors.leftMargin: 52
|
anchors.leftMargin: 52
|
||||||
|
@ -43,6 +81,13 @@ Rectangle {
|
||||||
anchors.right: parent.right
|
anchors.right: parent.right
|
||||||
anchors.rightMargin: scrollbar.width
|
anchors.rightMargin: scrollbar.width
|
||||||
|
|
||||||
|
function isFullyVisible() {
|
||||||
|
return (y - chat.contentY - 1) + height < chat.height
|
||||||
|
}
|
||||||
|
function getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: loader
|
id: loader
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
|
@ -625,3 +625,22 @@ TimelineModel::replyAction(QString id)
|
||||||
|
|
||||||
emit ChatPage::instance()->messageReply(related);
|
emit ChatPage::instance()->messageReply(related);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
TimelineModel::idToIndex(QString id) const
|
||||||
|
{
|
||||||
|
if (id.isEmpty())
|
||||||
|
return -1;
|
||||||
|
for (int i = 0; i < (int)eventOrder.size(); i++)
|
||||||
|
if (id == eventOrder[i])
|
||||||
|
return i;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
TimelineModel::indexToId(int index) const
|
||||||
|
{
|
||||||
|
if (index < 0 || index >= (int)eventOrder.size())
|
||||||
|
return "";
|
||||||
|
return eventOrder[index];
|
||||||
|
}
|
||||||
|
|
|
@ -81,6 +81,8 @@ struct DecryptionResult
|
||||||
class TimelineModel : public QAbstractListModel
|
class TimelineModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(
|
||||||
|
int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentIndexChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit TimelineModel(QString room_id, QObject *parent = 0);
|
explicit TimelineModel(QString room_id, QObject *parent = 0);
|
||||||
|
@ -112,6 +114,8 @@ public:
|
||||||
Q_INVOKABLE QString escapeEmoji(QString str) const;
|
Q_INVOKABLE QString escapeEmoji(QString str) const;
|
||||||
Q_INVOKABLE void viewRawMessage(QString id) const;
|
Q_INVOKABLE void viewRawMessage(QString id) const;
|
||||||
Q_INVOKABLE void replyAction(QString id);
|
Q_INVOKABLE void replyAction(QString id);
|
||||||
|
Q_INVOKABLE int idToIndex(QString id) const;
|
||||||
|
Q_INVOKABLE QString indexToId(int index) const;
|
||||||
|
|
||||||
void addEvents(const mtx::responses::Timeline &events);
|
void addEvents(const mtx::responses::Timeline &events);
|
||||||
template<class T>
|
template<class T>
|
||||||
|
@ -119,6 +123,12 @@ public:
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void fetchHistory();
|
void fetchHistory();
|
||||||
|
void setCurrentIndex(int index)
|
||||||
|
{
|
||||||
|
currentId = indexToId(index);
|
||||||
|
emit currentIndexChanged(index);
|
||||||
|
}
|
||||||
|
int currentIndex() const { return idToIndex(currentId); }
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
// Add old events at the top of the timeline.
|
// Add old events at the top of the timeline.
|
||||||
|
@ -129,6 +139,7 @@ signals:
|
||||||
void oldMessagesRetrieved(const mtx::responses::Messages &res);
|
void oldMessagesRetrieved(const mtx::responses::Messages &res);
|
||||||
void messageFailed(const std::string txn_id);
|
void messageFailed(const std::string txn_id);
|
||||||
void messageSent(const std::string txn_id, std::string event_id);
|
void messageSent(const std::string txn_id, std::string event_id);
|
||||||
|
void currentIndexChanged(int index);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DecryptionResult decryptEvent(
|
DecryptionResult decryptEvent(
|
||||||
|
@ -146,6 +157,7 @@ private:
|
||||||
bool paginationInProgress = false;
|
bool paginationInProgress = false;
|
||||||
|
|
||||||
QHash<QString, QColor> userColors;
|
QHash<QString, QColor> userColors;
|
||||||
|
QString currentId;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
|
|
@ -14,7 +14,6 @@ TimelineViewManager::TimelineViewManager(QWidget *parent)
|
||||||
0,
|
0,
|
||||||
"MtxEvent",
|
"MtxEvent",
|
||||||
"Can't instantiate enum!");
|
"Can't instantiate enum!");
|
||||||
|
|
||||||
view = new QQuickView();
|
view = new QQuickView();
|
||||||
container = QWidget::createWindowContainer(view, parent);
|
container = QWidget::createWindowContainer(view, parent);
|
||||||
container->setMinimumSize(200, 200);
|
container->setMinimumSize(200, 200);
|
||||||
|
|
Loading…
Reference in a new issue