parent
debdd1fda7
commit
dda2b21a9a
@ -0,0 +1,88 @@
|
||||
#include <rtcom-eventlogger/eventlogger.h>
|
||||
#include <glib.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include "models/ChatMessage.h"
|
||||
|
||||
struct rtcom_query {
|
||||
RTComElQuery *query = NULL;
|
||||
RTComElIter *it = NULL;
|
||||
RTComEl *el = NULL;
|
||||
};
|
||||
|
||||
#define LOOKUP_INT(x) \
|
||||
g_value_get_int((const GValue*)g_hash_table_lookup(values, x))
|
||||
#define LOOKUP_BOOL(x) \
|
||||
g_value_get_boolean((const GValue*)g_hash_table_lookup(values, x))
|
||||
#define LOOKUP_STR(x) \
|
||||
g_value_get_string((const GValue*)g_hash_table_lookup(values, x))
|
||||
|
||||
rtcom_query* rtcomStartQuery(const int limit, const int offset, const RTComElQueryGroupBy group_by) {
|
||||
RTComElQuery *query = NULL;
|
||||
RTComElIter *it = NULL;
|
||||
RTComEl *el = NULL;
|
||||
|
||||
el = rtcom_el_new();
|
||||
query = rtcom_el_query_new(el);
|
||||
|
||||
if(group_by != RTCOM_EL_QUERY_GROUP_BY_NONE)
|
||||
rtcom_el_query_set_group_by(query, group_by);
|
||||
|
||||
rtcom_el_query_set_limit(query, limit);
|
||||
rtcom_el_query_set_offset(query, offset);
|
||||
|
||||
return new rtcom_query{query, it , el};
|
||||
}
|
||||
|
||||
QList<ChatMessage*> rtcomIterateResults(rtcom_query *query_struct) {
|
||||
QList<ChatMessage*> results;
|
||||
query_struct->it = rtcom_el_get_events(query_struct->el, query_struct->query);
|
||||
|
||||
if(query_struct->it && rtcom_el_iter_first(query_struct->it)) {
|
||||
do {
|
||||
GHashTable *values = NULL;
|
||||
values = rtcom_el_iter_get_value_map(
|
||||
query_struct->it,
|
||||
"id",
|
||||
"service",
|
||||
"group-uid",
|
||||
"local-uid",
|
||||
"remote-uid",
|
||||
"remote-name",
|
||||
"remote-ebook-uid",
|
||||
"content",
|
||||
"icon-name",
|
||||
"start-time",
|
||||
"event-count",
|
||||
"group-title",
|
||||
"event-type",
|
||||
"outgoing",
|
||||
"flags",
|
||||
NULL);
|
||||
|
||||
auto *item = new ChatMessage(
|
||||
LOOKUP_INT("id"),
|
||||
LOOKUP_STR("service"),
|
||||
LOOKUP_STR("group-uid"),
|
||||
LOOKUP_STR("local-uid"),
|
||||
LOOKUP_STR("remote-uid"),
|
||||
LOOKUP_STR("remote-name"),
|
||||
LOOKUP_STR("remote-ebook-uid"),
|
||||
LOOKUP_STR("content"),
|
||||
LOOKUP_STR("icon-name"),
|
||||
LOOKUP_INT("start-time"),
|
||||
LOOKUP_INT("event-count"),
|
||||
LOOKUP_STR("group-title"),
|
||||
LOOKUP_STR("event-type"),
|
||||
LOOKUP_BOOL("outgoing"),
|
||||
LOOKUP_INT("flags"));
|
||||
results << item;
|
||||
} while (rtcom_el_iter_next(query_struct->it));
|
||||
g_object_unref(query_struct->it);
|
||||
} else {
|
||||
qCritical() << "Failed to init iterator to start";
|
||||
}
|
||||
|
||||
g_object_unref(query_struct->query);
|
||||
return results;
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
#include <QObject>
|
||||
#include <QDebug>
|
||||
|
||||
#include "models/ChatOverviewModel.h"
|
||||
#include "models/ChatMessage.h"
|
||||
|
||||
ChatOverviewModel::ChatOverviewModel(QObject *parent)
|
||||
: QAbstractListModel(parent) {
|
||||
}
|
||||
|
||||
void ChatOverviewModel::appendOverviewItem(ChatMessage *message) {
|
||||
const int idx = rowCount();
|
||||
beginInsertRows(QModelIndex(), idx, rowCount());
|
||||
items << message;
|
||||
endInsertRows();
|
||||
}
|
||||
|
||||
int ChatOverviewModel::rowCount(const QModelIndex & parent) const {
|
||||
Q_UNUSED(parent);
|
||||
return items.count();
|
||||
}
|
||||
|
||||
QVariant ChatOverviewModel::data(const QModelIndex &index, int role) const {
|
||||
if (index.row() < 0 || index.row() >= items.count())
|
||||
return QVariant();
|
||||
|
||||
const ChatMessage *message = items[index.row()];
|
||||
if (role == RemoteUIDRole)
|
||||
return message->remote_uid();
|
||||
else if (role == GroupUIDRole)
|
||||
return message->group_uid();
|
||||
else if (role == LocalUIDRole)
|
||||
return message->local_uid();
|
||||
else if (role == RemoteNameRole)
|
||||
return message->remote_name();
|
||||
else if (role == DateRole)
|
||||
return message->datestr();
|
||||
else if (role == HourRole)
|
||||
return message->hourstr();
|
||||
else if (role == MessageRole)
|
||||
return message->text();
|
||||
else if (role == OutgoingRole)
|
||||
return message->outgoing();
|
||||
else if (role == IconNameRole)
|
||||
return message->icon_name();
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ChatOverviewModel::roleNames() const {
|
||||
QHash<int, QByteArray> roles;
|
||||
roles[GroupUIDRole] = "group_uid";
|
||||
roles[LocalUIDRole] = "local_uid";
|
||||
roles[RemoteUIDRole] = "remote_uid";
|
||||
roles[RemoteNameRole] = "remote_name";
|
||||
roles[DateRole] = "datestr";
|
||||
roles[HourRole] = "hourstr";
|
||||
roles[MessageRole] = "message";
|
||||
roles[OutgoingRole] = "outgoing";
|
||||
roles[IconNameRole] = "icon_name";
|
||||
return roles;
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
#ifndef CHATOVERVIEWMODEL_H
|
||||
#define CHATOVERVIEWMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QDateTime>
|
||||
#include <QStringList>
|
||||
|
||||
#include "models/ChatMessage.h"
|
||||
|
||||
class ChatOverviewModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
// Name, date, time, content, type?
|
||||
enum ChatOverviewModelRoles {
|
||||
RemoteUIDRole = Qt::UserRole + 1,
|
||||
GroupUIDRole,
|
||||
LocalUIDRole,
|
||||
RemoteNameRole,
|
||||
DateRole,
|
||||
HourRole,
|
||||
MessageRole,
|
||||
OutgoingRole,
|
||||
IconNameRole
|
||||
};
|
||||
|
||||
ChatOverviewModel(QObject *parent = nullptr);
|
||||
void appendOverviewItem(ChatMessage *item);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||
|
||||
QList<ChatMessage*> items;
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const;
|
||||
};
|
||||
|
||||
#endif
|
@ -0,0 +1,28 @@
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.0
|
||||
|
||||
|
||||
ListView {
|
||||
id: root
|
||||
model: chatModel
|
||||
|
||||
signal scrollToBottom()
|
||||
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
property var chatScroll: chatScroll
|
||||
property bool scrollable: root.childrenRect.height > parent.height
|
||||
property bool atBottom: (chatScroll.position + chatScroll.size) == 1
|
||||
property bool atTop: chatScroll.position <= 0.01
|
||||
property bool mayAutoScroll: atBottom && scrollable
|
||||
|
||||
onCountChanged: { // scroll to bottom
|
||||
if(chatListView.mayAutoScroll)
|
||||
scrollToBottom();
|
||||
}
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
id: chatScroll
|
||||
visible: false
|
||||
}
|
||||
}
|
@ -0,0 +1,102 @@
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.0
|
||||
|
||||
import "." as Components
|
||||
|
||||
Rectangle {
|
||||
id: chatRoot
|
||||
visible: true
|
||||
color: "grey"
|
||||
|
||||
property var chatList
|
||||
signal scrollToBottom()
|
||||
signal fetchHistory()
|
||||
|
||||
onScrollToBottom: scrollBottomTimer.start()
|
||||
|
||||
Components.ChatScrollToBottomButton {
|
||||
z: parent.z + 1
|
||||
visible: !chatList.atBottom
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: 60
|
||||
anchors.bottomMargin: 60
|
||||
onClicked: scrollBottomTimer.start();
|
||||
}
|
||||
|
||||
Item {
|
||||
visible: chatList.atTop && !chatModel.exhausted
|
||||
onVisibleChanged: {
|
||||
if(!chatModel.exhausted && chatList.atTop && visible && chatListView.count >= chatModel.limit)
|
||||
fetchHistory();
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
// debugBar
|
||||
z: parent.z + 1
|
||||
visible: ctx.isDebug
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: 60
|
||||
anchors.topMargin: 60
|
||||
property int pointSize: 16
|
||||
|
||||
Text {
|
||||
color: "lime"
|
||||
text: "Messages: " + chatList.count + " (limit: " + chatModel.limit + " offset: " + chatModel.offset + " exhausted: " + chatModel.exhausted + ")"
|
||||
font.pointSize: parent.pointSize
|
||||
}
|
||||
|
||||
Text {
|
||||
color: "lime"
|
||||
text: "mayAutoScroll: " + chatList.mayAutoScroll
|
||||
font.pointSize: parent.pointSize
|
||||
}
|
||||
|
||||
Text {
|
||||
color: "lime"
|
||||
text: "atBottom: " + chatList.atBottom
|
||||
font.pointSize: parent.pointSize
|
||||
}
|
||||
|
||||
Text {
|
||||
color: "lime"
|
||||
text: "atTop: " + chatList.atTop
|
||||
font.pointSize: parent.pointSize
|
||||
}
|
||||
|
||||
Text {
|
||||
color: "lime"
|
||||
text: "rootHeight: " + chatRoot.height
|
||||
font.pointSize: parent.pointSize
|
||||
}
|
||||
|
||||
Text {
|
||||
color: "lime"
|
||||
text: "chatList.cRect.height: " + chatList.childrenRect.height
|
||||
font.pointSize: parent.pointSize
|
||||
}
|
||||
|
||||
Text {
|
||||
color: "lime"
|
||||
text: "scrollPosition: " + chatList.chatScroll.position.toFixed(4)
|
||||
font.pointSize: parent.pointSize
|
||||
}
|
||||
|
||||
Text {
|
||||
color: "lime"
|
||||
text: "scaling: " + ctx.scaleFactor
|
||||
font.pointSize: parent.pointSize
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: scrollBottomTimer
|
||||
interval: 10
|
||||
repeat: false
|
||||
running: false
|
||||
onTriggered: chatList.positionViewAtEnd();
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 2.3
|
||||
import QtQuick.Layouts 1.0
|
||||
|
||||
Item {
|
||||
id: root
|
||||
width: 76
|
||||
height: 76
|
||||
|
||||
signal clicked();
|
||||
|
||||
Rectangle { // lies: it is a circle
|
||||
anchors.fill: parent
|
||||
color: "white"
|
||||
opacity: 0.3
|
||||
radius: width * 0.5
|
||||
}
|
||||
|
||||
Image {
|
||||
width: 48
|
||||
height: 48
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
source: "qrc:///rss_reader_move_down.png"
|
||||
smooth: true
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
root.clicked();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource prefix="/">
|
||||
<file alias="components/ChatScrollToBottomButton.qml">ChatScrollToBottomButton.qml</file>
|
||||
<file alias="components/ChatRoot.qml">ChatRoot.qml</file>
|
||||
<file alias="components/ChatListView.qml">ChatListView.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
Loading…
Reference in new issue