diff --git a/libnymea-app-core/jsonrpc/jsonrpcclient.cpp b/libnymea-app-core/jsonrpc/jsonrpcclient.cpp index eddce39f..69656d5d 100644 --- a/libnymea-app-core/jsonrpc/jsonrpcclient.cpp +++ b/libnymea-app-core/jsonrpc/jsonrpcclient.cpp @@ -303,7 +303,7 @@ void JsonRpcClient::sendRequest(const QVariantMap &request) { QVariantMap newRequest = request; newRequest.insert("token", m_token); - qDebug() << "Sending request" << qUtf8Printable(QJsonDocument::fromVariant(newRequest).toJson()); +// qDebug() << "Sending request" << qUtf8Printable(QJsonDocument::fromVariant(newRequest).toJson()); m_connection->sendData(QJsonDocument::fromVariant(newRequest).toJson(QJsonDocument::Compact) + "\n"); } @@ -340,7 +340,7 @@ void JsonRpcClient::dataReceived(const QByteArray &data) // qWarning() << "Could not parse json data from nymea" << m_receiveBuffer.left(splitIndex) << error.errorString(); return; } - qDebug() << "received response" << qUtf8Printable(jsonDoc.toJson(QJsonDocument::Indented)); +// qDebug() << "received response" << qUtf8Printable(jsonDoc.toJson(QJsonDocument::Indented)); m_receiveBuffer = m_receiveBuffer.right(m_receiveBuffer.length() - splitIndex - 1); if (!m_receiveBuffer.isEmpty()) { staticMetaObject.invokeMethod(this, "dataReceived", Qt::QueuedConnection, Q_ARG(QByteArray, QByteArray())); diff --git a/libnymea-app-core/models/logsmodel.cpp b/libnymea-app-core/models/logsmodel.cpp index 3e08301c..d7ec31ef 100644 --- a/libnymea-app-core/models/logsmodel.cpp +++ b/libnymea-app-core/models/logsmodel.cpp @@ -213,7 +213,7 @@ void LogsModel::fetchEarlier(int hours) void LogsModel::logsReply(const QVariantMap &data) { - qDebug() << "logs reply";// << data; +// qDebug() << "logs reply" << data; beginResetModel(); qDeleteAll(m_list); m_list.clear(); @@ -242,7 +242,7 @@ void LogsModel::logsReply(const QVariantMap &data) void LogsModel::fetchEarlierReply(const QVariantMap &data) { - qDebug() << "logs reply";// << data; +// qDebug() << "logs reply" << data; QList logEntries = data.value("params").toMap().value("logEntries").toList(); QList newEntries; diff --git a/libnymea-app-core/models/logsmodel.h b/libnymea-app-core/models/logsmodel.h index 1d8b26f1..ee731d5a 100644 --- a/libnymea-app-core/models/logsmodel.h +++ b/libnymea-app-core/models/logsmodel.h @@ -19,6 +19,7 @@ class LogsModel : public QAbstractListModel Q_PROPERTY(QStringList typeIds READ typeIds WRITE setTypeIds NOTIFY typeIdsChanged) Q_PROPERTY(QDateTime startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged) Q_PROPERTY(QDateTime endTime READ endTime WRITE setEndTime NOTIFY endTimeChanged) +// Q_PROPERTY(int paginationCount READ paginationCount WRITE setPaginationCount NOTIFY paginationCountChanged) Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged) @@ -56,6 +57,9 @@ public: QDateTime endTime() const; void setEndTime(const QDateTime &endTime); +// int paginationCount() const; +// void setPaginationCount(int paginationCount); + Q_INVOKABLE LogEntry* get(int index) const; Q_INVOKABLE void notificationReceived(const QVariantMap &data); @@ -69,6 +73,7 @@ signals: void typeIdsChanged(); void startTimeChanged(); void endTimeChanged(); +// void paginationCountChanged(); public slots: virtual void update(); diff --git a/libnymea-app-core/models/logsmodelng.cpp b/libnymea-app-core/models/logsmodelng.cpp index ec8b3891..5e0f89cc 100644 --- a/libnymea-app-core/models/logsmodelng.cpp +++ b/libnymea-app-core/models/logsmodelng.cpp @@ -5,22 +5,24 @@ #include "engine.h" #include "types/logentry.h" +#include "logmanager.h" LogsModelNg::LogsModelNg(QObject *parent) : QAbstractListModel(parent) { } -JsonRpcClient *LogsModelNg::jsonRpcClient() const +Engine *LogsModelNg::engine() const { - return m_jsonRpcClient; + return m_engine; } -void LogsModelNg::setJsonRpcClient(JsonRpcClient *jsonRpcClient) +void LogsModelNg::setEngine(Engine *engine) { - if (m_jsonRpcClient != jsonRpcClient) { - m_jsonRpcClient = jsonRpcClient; - emit jsonRpcClientChanged(); + if (m_engine != engine) { + m_engine = engine; + connect(engine->logManager(), &LogManager::logEntryReceived, this, &LogsModelNg::newLogEntryReceived); + emit engineChanged(); } } @@ -92,16 +94,16 @@ void LogsModelNg::setDeviceId(const QString &deviceId) } } -QString LogsModelNg::typeId() const +QStringList LogsModelNg::typeIds() const { - return m_typeId; + return m_typeIds; } -void LogsModelNg::setTypeId(const QString &typeId) +void LogsModelNg::setTypeIds(const QStringList &typeIds) { - if (m_typeId != typeId) { - m_typeId = typeId; - emit typeIdChanged(); + if (m_typeIds != typeIds) { + m_typeIds = typeIds; + emit typeIdsChanged(); } } @@ -115,7 +117,6 @@ void LogsModelNg::setStartTime(const QDateTime &startTime) if (m_startTime != startTime) { m_startTime = startTime; emit startTimeChanged(); - update(); } } @@ -129,13 +130,57 @@ void LogsModelNg::setEndTime(const QDateTime &endTime) if (m_endTime != endTime) { m_endTime = endTime; emit endTimeChanged(); - update(); } } -void LogsModelNg::update() +void LogsModelNg::logsReply(const QVariantMap &data) { - if (!m_jsonRpcClient) { + qDebug() << "logs reply" << data; + + m_busy = false; + emit busyChanged(); + + int offset = data.value("params").toMap().value("offset").toInt(); + int count = data.value("params").toMap().value("count").toInt(); + + QList newBlock; + QList logEntries = data.value("params").toMap().value("logEntries").toList(); + foreach (const QVariant &logEntryVariant, logEntries) { + QVariantMap entryMap = logEntryVariant.toMap(); + QDateTime timeStamp = QDateTime::fromMSecsSinceEpoch(entryMap.value("timestamp").toLongLong()); + QString deviceId = entryMap.value("deviceId").toString(); + QString typeId = entryMap.value("typeId").toString(); + QMetaEnum sourceEnum = QMetaEnum::fromType(); + LogEntry::LoggingSource loggingSource = static_cast(sourceEnum.keyToValue(entryMap.value("source").toByteArray())); + QMetaEnum loggingEventTypeEnum = QMetaEnum::fromType(); + LogEntry::LoggingEventType loggingEventType = static_cast(loggingEventTypeEnum.keyToValue(entryMap.value("eventType").toByteArray())); + QVariant value = loggingEventType == LogEntry::LoggingEventTypeActiveChange ? entryMap.value("active").toBool() : entryMap.value("value"); + LogEntry *entry = new LogEntry(timeStamp, value, deviceId, typeId, loggingSource, loggingEventType, this); + newBlock.append(entry); + } + + if (count < m_blockSize) { + m_canFetchMore = false; + } + + if (newBlock.isEmpty()) { + return; + } + + beginInsertRows(QModelIndex(), offset, offset + newBlock.count() - 1); + for (int i = 0; i < newBlock.count(); i++) { + m_list.insert(offset + i, newBlock.at(i)); + } + endInsertRows(); + emit countChanged(); +} + +void LogsModelNg::fetchMore(const QModelIndex &parent) +{ + Q_UNUSED(parent) + qDebug() << "fetchMore called"; + + if (!m_engine->jsonRpcClient()) { qWarning() << "Cannot update. JsonRpcClient not set"; return; } @@ -143,66 +188,11 @@ void LogsModelNg::update() return; } - if (m_startTime.isNull() || m_endTime.isNull()) { - // Need both, startTime and endTime set + if ((!m_startTime.isNull() && m_endTime.isNull()) || (m_startTime.isNull() && !m_endTime.isNull())) { + // Need neither or both, startTime and endTime set return; } - m_currentFetchStartTime = QDateTime(); - m_currentFetchEndTime = QDateTime(); - bool haveData = false; - for(int i = 0; i < m_fetchedPeriods.length(); i++) { - if (m_fetchedPeriods.at(i).first < m_startTime) { - if (m_fetchedPeriods.at(i).second == true) { - haveData = true; - continue; - } - if (m_fetchedPeriods.at(i).second == false) { - haveData = false; - continue; - } - } - if (m_fetchedPeriods.at(i).first == m_startTime) { - if (m_fetchedPeriods.at(i).second == true) { - haveData = true; - continue; - } - if (m_fetchedPeriods.at(i).second == false) { - m_currentFetchStartTime = m_startTime; - continue; - } - } - if (m_fetchedPeriods.at(i).first > m_startTime) { - if (m_fetchedPeriods.at(i).second == true) { - if (m_currentFetchStartTime.isNull()) { - m_currentFetchStartTime = m_startTime; - } - m_currentFetchEndTime = m_fetchedPeriods.at(i).first; - break; - } - if (m_fetchedPeriods.at(i).second == false) { - if (m_currentFetchStartTime.isNull()) { - haveData = false; - m_currentFetchStartTime = m_fetchedPeriods.at(i).first; - } - continue; - } - } - } - if (haveData) { - qDebug() << "all the data is fetched"; - m_busy = false; - emit busyChanged(); - return; - } - if (m_currentFetchStartTime.isNull()) { - m_currentFetchStartTime = m_startTime; - } - if (m_currentFetchEndTime.isNull()) { - m_currentFetchEndTime = m_endTime; - } - qDebug() << "Fetching from" << m_currentFetchStartTime << "to" << m_currentFetchEndTime; - m_busy = true; emit busyChanged(); @@ -212,103 +202,65 @@ void LogsModelNg::update() deviceIds.append(m_deviceId); params.insert("deviceIds", deviceIds); } - if (!m_typeId.isEmpty()) { + if (!m_typeIds.isEmpty()) { QVariantList typeIds; - typeIds.append(m_typeId); + foreach (const QString &typeId, m_typeIds) { + typeIds.append(typeId); + } params.insert("typeIds", typeIds); } - QVariantList timeFilters; - QVariantMap timeFilter; - timeFilter.insert("startDate", m_currentFetchStartTime.toSecsSinceEpoch()); - timeFilter.insert("endDate", m_currentFetchEndTime.toSecsSinceEpoch()); - timeFilters.append(timeFilter); - params.insert("timeFilters", timeFilters); - m_jsonRpcClient->sendCommand("Logging.GetLogEntries", params, this, "logsReply"); + if (!m_startTime.isNull() && !m_endTime.isNull()) { + QVariantList timeFilters; + QVariantMap timeFilter; + timeFilter.insert("startDate", m_currentFetchStartTime.toSecsSinceEpoch()); + timeFilter.insert("endDate", m_currentFetchEndTime.toSecsSinceEpoch()); + timeFilters.append(timeFilter); + params.insert("timeFilters", timeFilters); + } + + params.insert("limit", m_blockSize); + params.insert("offset", m_list.count()); + + m_engine->jsonRpcClient()->sendCommand("Logging.GetLogEntries", params, this, "logsReply"); + qDebug() << "GetLogEntries called"; } -void LogsModelNg::logsReply(const QVariantMap &data) +bool LogsModelNg::canFetchMore(const QModelIndex &parent) const { - qDebug() << "logs reply";// << data; - - // First update the fetched periods information - int insertIndex = -1; - bool noNeedToInsert = false; - for (int i = 0; i < m_fetchedPeriods.count(); i++) { - if (m_fetchedPeriods.at(i).first < m_currentFetchStartTime) { - // skip it - insertIndex = i+1; - continue; - } - if (m_fetchedPeriods.at(i).first == m_currentFetchStartTime) { - if (m_fetchedPeriods.at(i).second == false) { - // Have an end marker where we start inserting. We can drop the existing end marker and just update the end marker - if (m_fetchedPeriods.count() > i+1) { - if (m_fetchedPeriods.at(i+1).first < m_currentFetchEndTime) { - qWarning() << "Overlap detected!"; - } else if (m_fetchedPeriods.at(i+1).first == m_currentFetchEndTime) { - if (m_fetchedPeriods.at(i+1).second == true) { - m_fetchedPeriods.removeAt(i+1); - } - } - } - m_fetchedPeriods.removeAt(i); - noNeedToInsert = true; - break; - } - } - if (m_fetchedPeriods.at(i).first > m_currentFetchStartTime) { - break; - } - } - - if (!noNeedToInsert) { - if (insertIndex == -1) { - insertIndex = 0; - } - m_fetchedPeriods.insert(insertIndex, qMakePair(m_currentFetchStartTime, true)); - m_fetchedPeriods.insert(insertIndex+1, qMakePair(m_currentFetchEndTime, false)); - } - qDebug() << "new fetched periods:" << m_fetchedPeriods << "insertIndex:" << insertIndex; - m_busy = false; - emit busyChanged(); - - - QList newBlock; - QList logEntries = data.value("params").toMap().value("logEntries").toList(); - foreach (const QVariant &logEntryVariant, logEntries) { - QVariantMap entryMap = logEntryVariant.toMap(); - QDateTime timeStamp = QDateTime::fromMSecsSinceEpoch(entryMap.value("timestamp").toLongLong()); - QString deviceId = entryMap.value("deviceId").toString(); - QString typeId = entryMap.value("typeId").toString(); - QMetaEnum sourceEnum = QMetaEnum::fromType(); - LogEntry::LoggingSource loggingSource = (LogEntry::LoggingSource)sourceEnum.keyToValue(entryMap.value("source").toByteArray()); - QMetaEnum loggingEventTypeEnum = QMetaEnum::fromType(); - LogEntry::LoggingEventType loggingEventType = (LogEntry::LoggingEventType)loggingEventTypeEnum.keyToValue(entryMap.value("eventType").toByteArray()); - QVariant value = loggingEventType == LogEntry::LoggingEventTypeActiveChange ? entryMap.value("active").toBool() : entryMap.value("value"); - LogEntry *entry = new LogEntry(timeStamp, value, deviceId, typeId, loggingSource, loggingEventType, this); - newBlock.append(entry); - } - - // Now let's find where to insert stuff in the model - if (!newBlock.isEmpty()) { - int indexToInsert = 0; - for (int i = 0; i < m_list.count(); i++) { - LogEntry *entry = m_list.at(i); - if (entry->timestamp() < newBlock.first()->timestamp()) { - continue; - } - indexToInsert = i; - break; - } - - beginInsertRows(QModelIndex(), indexToInsert, indexToInsert + newBlock.count() - 1); - for (int i = 0; i < newBlock.count(); i++) { - m_list.insert(indexToInsert + i, newBlock.at(i)); - } - endInsertRows(); - emit countChanged(); - } - - update(); + Q_UNUSED(parent) + qDebug() << "canFetchMore" << m_canFetchMore; + return m_canFetchMore; } +void LogsModelNg::newLogEntryReceived(const QVariantMap &data) +{ + if (!m_live) { + return; + } + + QVariantMap entryMap = data; + QString deviceId = entryMap.value("deviceId").toString(); + if (!m_deviceId.isNull() && deviceId != m_deviceId) { + return; + } + + QString typeId = entryMap.value("typeId").toString(); + if (!m_typeIds.isEmpty() && !m_typeIds.contains(typeId)) { + return; + } + + beginInsertRows(QModelIndex(), 0, 0); + QDateTime timeStamp = QDateTime::fromMSecsSinceEpoch(entryMap.value("timestamp").toLongLong()); + QMetaEnum sourceEnum = QMetaEnum::fromType(); + LogEntry::LoggingSource loggingSource = static_cast(sourceEnum.keyToValue(entryMap.value("source").toByteArray())); + QMetaEnum loggingEventTypeEnum = QMetaEnum::fromType(); + LogEntry::LoggingEventType loggingEventType = static_cast(loggingEventTypeEnum.keyToValue(entryMap.value("eventType").toByteArray())); + QVariant value = loggingEventType == LogEntry::LoggingEventTypeActiveChange ? entryMap.value("active").toBool() : entryMap.value("value"); + LogEntry *entry = new LogEntry(timeStamp, value, deviceId, typeId, loggingSource, loggingEventType, this); + m_list.prepend(entry); + endInsertRows(); + emit countChanged(); + +} + + diff --git a/libnymea-app-core/models/logsmodelng.h b/libnymea-app-core/models/logsmodelng.h index eb89632a..8881fb1d 100644 --- a/libnymea-app-core/models/logsmodelng.h +++ b/libnymea-app-core/models/logsmodelng.h @@ -6,16 +6,17 @@ #include class LogEntry; -class JsonRpcClient; +class Engine; class LogsModelNg : public QAbstractListModel { Q_OBJECT - Q_PROPERTY(JsonRpcClient* jsonRpcClient READ jsonRpcClient WRITE setJsonRpcClient NOTIFY jsonRpcClientChanged) + Q_PROPERTY(Engine* engine READ engine WRITE setEngine NOTIFY engineChanged) Q_PROPERTY(bool busy READ busy NOTIFY busyChanged) + Q_PROPERTY(bool live READ live WRITE setLive NOTIFY liveChanged) Q_PROPERTY(int count READ rowCount NOTIFY countChanged) Q_PROPERTY(QString deviceId READ deviceId WRITE setDeviceId NOTIFY deviceIdChanged) - Q_PROPERTY(QString typeId READ typeId WRITE setTypeId NOTIFY typeIdChanged) + Q_PROPERTY(QStringList typeIds READ typeIds WRITE setTypeIds NOTIFY typeIdsChanged) Q_PROPERTY(QDateTime startTime READ startTime WRITE setStartTime NOTIFY startTimeChanged) Q_PROPERTY(QDateTime endTime READ endTime WRITE setEndTime NOTIFY endTimeChanged) @@ -31,8 +32,8 @@ public: explicit LogsModelNg(QObject *parent = nullptr); - JsonRpcClient *jsonRpcClient() const; - void setJsonRpcClient(JsonRpcClient* jsonRpcClient); + Engine *engine() const; + void setEngine(Engine* jsonRpcClient); int rowCount(const QModelIndex &parent = QModelIndex()) const override; QVariant data(const QModelIndex &index, int role) const override; @@ -46,8 +47,8 @@ public: QString deviceId() const; void setDeviceId(const QString &deviceId); - QString typeId() const; - void setTypeId(const QString &typeId); + QStringList typeIds() const; + void setTypeIds(const QStringList &typeId); QDateTime startTime() const; void setStartTime(const QDateTime &startTime); @@ -55,34 +56,40 @@ public: QDateTime endTime() const; void setEndTime(const QDateTime &endTime); +protected: + virtual void fetchMore(const QModelIndex &parent = QModelIndex()) override; + virtual bool canFetchMore(const QModelIndex &parent = QModelIndex()) const override; signals: void busyChanged(); void liveChanged(); void deviceIdChanged(); - void typeIdChanged(); + void typeIdsChanged(); void countChanged(); void startTimeChanged(); void endTimeChanged(); - void jsonRpcClientChanged(); + void engineChanged(); + +private slots: + void newLogEntryReceived(const QVariantMap &data); + void logsReply(const QVariantMap &data); private: QList m_list; - JsonRpcClient *m_jsonRpcClient = nullptr; + Engine *m_engine = nullptr; bool m_busy = false; bool m_live = false; QString m_deviceId; - QString m_typeId; + QStringList m_typeIds; QDateTime m_startTime; QDateTime m_endTime; QDateTime m_currentFetchStartTime; QDateTime m_currentFetchEndTime; + int m_blockSize = 100; + bool m_canFetchMore = true; QList > m_fetchedPeriods; - - void update(); - Q_INVOKABLE void logsReply(const QVariantMap &data); }; diff --git a/nymea-app/ui/customviews/GenericTypeLogView.qml b/nymea-app/ui/customviews/GenericTypeLogView.qml index dc136765..954ecc0a 100644 --- a/nymea-app/ui/customviews/GenericTypeLogView.qml +++ b/nymea-app/ui/customviews/GenericTypeLogView.qml @@ -6,8 +6,6 @@ import "../components" Item { id: root - // %1 will be replaced with count - property string text signal addRuleClicked(var value) @@ -15,122 +13,74 @@ Item { property alias delegate: listView.delegate - property bool autoscroll: true - - ColumnLayout { + ListView { + id: listView anchors.fill: parent + model: logsModel + clip: true - Label { - id: titleLabel - Layout.fillWidth: true - Layout.margins: app.margins - wrapMode: Text.WordWrap - text: root.text.arg(logsModel.count).arg((logsModel.endTime.getTime() - logsModel.startTime.getTime())/ 1000 / 60 / 60 /24) - } + ScrollBar.vertical: ScrollBar {} - ThinDivider {} - - RulesFilterModel { - id: rulesFilterModel - rules: engine.ruleManager.rules - filterDeviceId: root.logsModel.deviceId - } - - ListView { - id: listView - Layout.fillWidth: true - Layout.fillHeight: true - model: logsModel - clip: true - onCountChanged: { - if (root.autoscroll) { - positionViewAtEnd() - } - } - - onContentYChanged: { + onContentYChanged: { + if (!engine.jsonRpcClient.ensureServerVersion("1.10")) { if (!logsModel.busy && contentY - originY < 5 * height) { logsModel.fetchEarlier(24) } } + } - delegate: SwipeDelegate { - id: logEntryDelegate - width: parent.width - implicitHeight: app.delegateHeight - property var device: engine.deviceManager.devices.getDevice(model.deviceId) - property var deviceClass: engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) - contentItem: RowLayout { - ColorIcon { - Layout.preferredHeight: app.iconSize - Layout.preferredWidth: height - name: "../images/event.svg" - color: app.accentColor - } - - ColumnLayout { - Label { - id: timeStampLabel - Layout.fillWidth: true - text: Qt.formatDateTime(model.timestamp,"dd.MM.yy - hh:mm:ss") - } - Label { - Layout.fillWidth: true - text: "%1: %2".arg(deviceClass.eventTypes.getEventType(model.typeId).displayName).arg(model.value.trim()) - elide: Text.ElideRight - font.pixelSize: app.smallFont - } - } -// ColorIcon { -// Layout.preferredWidth: app.iconSize -// Layout.preferredHeight: width -// name: "../images/magic.svg" -// color: { -// for (var i = 0; i < rulesFilterModel.count; i++) { -// var rule = rulesFilterModel.get(i); -// for (var j = 0; j < rule.eventDescriptors.count; j++) { -// var eventDescriptor = rule.eventDescriptors.get(j); -// if (eventDescriptor.eventTypeId === root.logsModel.typeId) { -// var matching = true; -// for (var k = 0; k < eventDescriptor.paramDescriptors.count; k++) { -// var paramDescriptor = eventDescriptor.paramDescriptors.get(k); -// if (paramDescriptor.value === model.value) { -// return app.accentColor; -// } -// } -// } -// } -// } -// return keyColor; -// } - -// } + delegate: SwipeDelegate { + id: logEntryDelegate + width: parent.width + implicitHeight: app.delegateHeight + property var device: engine.deviceManager.devices.getDevice(model.deviceId) + property var deviceClass: engine.deviceManager.deviceClasses.getDeviceClass(device.deviceClassId) + contentItem: RowLayout { + ColorIcon { + Layout.preferredHeight: app.iconSize + Layout.preferredWidth: height + name: "../images/event.svg" + color: app.accentColor } - swipe.right: MouseArea { - height: logEntryDelegate.height - width: height - anchors.right: parent.right - ColorIcon { - anchors.fill: parent - anchors.margins: app.margins - name: "../images/magic.svg" + + ColumnLayout { + Label { + id: timeStampLabel + Layout.fillWidth: true + text: Qt.formatDateTime(model.timestamp,"dd.MM.yy - hh:mm:ss") } - onClicked: root.addRuleClicked(model.value) - } - onClicked: { - if (swipe.complete) { - swipe.close() - } else { - swipe.open(SwipeDelegate.Right) + Label { + Layout.fillWidth: true + text: "%1: %2".arg(deviceClass.eventTypes.getEventType(model.typeId).displayName).arg(model.value.trim()) + elide: Text.ElideRight + font.pixelSize: app.smallFont } } } - - BusyIndicator { - anchors.centerIn: parent - visible: root.logsModel.busy - running: visible + swipe.right: MouseArea { + height: logEntryDelegate.height + width: height + anchors.right: parent.right + ColorIcon { + anchors.fill: parent + anchors.margins: app.margins + name: "../images/magic.svg" + } + onClicked: root.addRuleClicked(model.value) } + onClicked: { + if (swipe.complete) { + swipe.close() + } else { + swipe.open(SwipeDelegate.Right) + } + } + } + + BusyIndicator { + anchors.centerIn: parent + visible: root.logsModel.busy + running: visible } } } diff --git a/nymea-app/ui/delegates/ActionDelegate.qml b/nymea-app/ui/delegates/ActionDelegate.qml index de099023..7da1f75f 100644 --- a/nymea-app/ui/delegates/ActionDelegate.qml +++ b/nymea-app/ui/delegates/ActionDelegate.qml @@ -304,6 +304,7 @@ ItemDelegate { property var value: null text: root.actionType.displayName onClicked: { + print("ActionDelegate: Button clicked") var params = []; print("fooo", root.actionType.paramTypes.count) for (var i = 0; i < root.actionType.paramTypes.count; i++) { diff --git a/nymea-app/ui/devicepages/ButtonDevicePage.qml b/nymea-app/ui/devicepages/ButtonDevicePage.qml index 7a8ee002..08e9184f 100644 --- a/nymea-app/ui/devicepages/ButtonDevicePage.qml +++ b/nymea-app/ui/devicepages/ButtonDevicePage.qml @@ -5,15 +5,29 @@ import Nymea 1.0 import "../components" import "../customviews" -GenericDevicePage { +DevicePageBase { id: root - GenericTypeLogView { anchors.fill: parent - text: qsTr("This button has been pressed %1 times in the last %2 days.") - logsModel: LogsModel { + logsModel: engine.jsonRpcClient.ensureServerVersion("1.10") ? logsModelNg : logsModel + LogsModelNg { + id: logsModelNg + engine: _engine + deviceId: root.device.id + live: true + typeIds: { + var ret = []; + ret.push(root.deviceClass.eventTypes.findByName("pressed").id) + if (root.deviceClass.eventTypes.findByName("longPressed")) { + ret.push(root.deviceClass.eventTypes.findByName("longPressed").id) + } + return ret; + } + } + LogsModel { + id: logsModel engine: _engine deviceId: root.device.id live: true diff --git a/nymea-app/ui/devicepages/FingerprintReaderDevicePage.qml b/nymea-app/ui/devicepages/FingerprintReaderDevicePage.qml index 4c395fbe..d3d51c5f 100644 --- a/nymea-app/ui/devicepages/FingerprintReaderDevicePage.qml +++ b/nymea-app/ui/devicepages/FingerprintReaderDevicePage.qml @@ -26,14 +26,28 @@ DevicePageBase { } } -// ThinDivider {} + ThinDivider {} + + Label { + Layout.fillWidth: true + Layout.margins: app.margins + text: qsTr("Access log:") + } GenericTypeLogView { Layout.fillHeight: true Layout.fillWidth: true - text: qsTr("%1 fingerprints recognized on this device in the last %2 days.") - logsModel: LogsModel { + logsModel: engine.jsonRpcClient.ensureServerVersion("1.10") ? logsModelNg : logsModel + LogsModelNg { + id: logsModelNg + deviceId: root.device.id + engine: _engine + live: true + typeIds: [root.accessGrantedEventType.id, root.accessDeniedEventType.id]; + } + LogsModel { + id: logsModel deviceId: root.device.id engine: _engine live: true diff --git a/nymea-app/ui/devicepages/InputTriggerDevicePage.qml b/nymea-app/ui/devicepages/InputTriggerDevicePage.qml index 0c011755..bc331295 100644 --- a/nymea-app/ui/devicepages/InputTriggerDevicePage.qml +++ b/nymea-app/ui/devicepages/InputTriggerDevicePage.qml @@ -5,14 +5,22 @@ import Nymea 1.0 import "../components" import "../customviews" -GenericDevicePage { +DevicePageBase { id: root GenericTypeLogView { anchors.fill: parent - text: qsTr("This event has appeared %1 times in the last %2 days.") - logsModel: LogsModel { + logsModel: engine.jsonRpcClient.ensureServerVersion("1.10") ? logsModelNg : logsModel + LogsModelNg { + id: logsModelNg + engine: _engine + deviceId: root.device.id + live: true + typeIds: [root.deviceClass.eventTypes.findByName("triggered").id]; + } + LogsModel { + id: logsModel engine: _engine deviceId: root.device.id live: true diff --git a/nymea-app/ui/devicepages/NotificationsDevicePage.qml b/nymea-app/ui/devicepages/NotificationsDevicePage.qml index 5ac06f94..4f7cd7e8 100644 --- a/nymea-app/ui/devicepages/NotificationsDevicePage.qml +++ b/nymea-app/ui/devicepages/NotificationsDevicePage.qml @@ -71,18 +71,33 @@ DevicePageBase { ThinDivider {} + Label { + Layout.fillWidth: true + Layout.margins: app.margins + wrapMode: Text.WordWrap + text: qsTr("Sent notifications:") + } + + GenericTypeLogView { Layout.fillHeight: true Layout.fillWidth: true - text: qsTr("%1 notifications sent to this device in the last %2 days.") - logsModel: LogsModel { + logsModel: engine.jsonRpcClient.ensureServerVersion("1.10") ? logsModelNg : logsModel + LogsModelNg { + id: logsModelNg + deviceId: root.device.id + engine: _engine + typeIds: [root.deviceClass.actionTypes.findByName("notify").id]; + } + + LogsModel { + id: logsModel deviceId: root.device.id live: true engine: _engine Component.onCompleted: update() typeIds: [root.deviceClass.actionTypes.findByName("notify").id]; - } delegate: MeaListItemDelegate { diff --git a/nymea-app/ui/devicepages/StateLogPage.qml b/nymea-app/ui/devicepages/StateLogPage.qml index a5c3e02e..393361f7 100644 --- a/nymea-app/ui/devicepages/StateLogPage.qml +++ b/nymea-app/ui/devicepages/StateLogPage.qml @@ -37,17 +37,13 @@ Page { typeIds: [root.stateType.id] } -// LogsModelNg { -// id: logsModelNg -// deviceId: root.device.id -// typeId: root.stateType.id -// startTime: { -// var date = new Date(); -// date.setHours(new Date().getHours() - 24) -// return date; -// } -// endTime: new Date(); -// } + LogsModelNg { + id: logsModelNg + engine: _engine + deviceId: root.device.id + typeIds: [root.stateType.id] + live: true + } ColumnLayout { anchors.fill: parent @@ -75,9 +71,8 @@ Page { id: logView width: swipeView.width height: swipeView.height - text: qsTr("%1, %2 has changed %3 times in the last %4 days").arg(device.name).arg(stateType.displayName) - logsModel: logsModel + logsModel: engine.jsonRpcClient.ensureServerVersion("1.10") ? logsModelNg : logsModel onAddRuleClicked: { var rule = engine.ruleManager.createNewRule(); diff --git a/nymea-app/ui/system/LogViewerPage.qml b/nymea-app/ui/system/LogViewerPage.qml index 8ede8b8b..52d06372 100644 --- a/nymea-app/ui/system/LogViewerPage.qml +++ b/nymea-app/ui/system/LogViewerPage.qml @@ -33,7 +33,6 @@ Page { } endTime: new Date() live: true - Component.onCompleted: update() onCountChanged: { if (root.autoScroll) { listView.positionViewAtEnd() @@ -41,6 +40,12 @@ Page { } } + LogsModelNg { + id: logsModelNg + engine: _engine + live: true + } + BusyIndicator { anchors.centerIn: listView visible: logsModel.busy @@ -48,11 +53,13 @@ Page { ListView { id: listView - model: logsModel + model: engine.jsonRpcClient.ensureServerVersion("1.10") ? logsModelNg : logsModel anchors.fill: parent clip: true headerPositioning: ListView.OverlayHeader + Component.onCompleted: model.update() + onDraggingChanged: { if (dragging) { root.autoScroll = false; @@ -62,8 +69,10 @@ Page { ScrollBar.vertical: ScrollBar {} onContentYChanged: { - if (!logsModel.busy && contentY - originY < 5 * height) { - logsModel.fetchEarlier(1) + if (!engine.jsonRpcClient.ensureServerVersion("1.10")) { + if (!logsModel.busy && contentY - originY < 5 * height) { + logsModel.fetchEarlier(1) + } } }