fix(sessions): lista vuota sul device — modello C++ con ruoli (v0.1.2)
Causa: su Qt 5.6 (kit Sailfish 5.1) una QVariantList di QVariantMap
usata come model non fa risolvere i campi nei delegate QML
(model.title/message_count/updated_at = undefined -> righe vuote), pur
con payload corretto dal server (verificato con cattura reale del 12/09).
- Nuovo src/sessionsmodel.{h,cpp}: QAbstractListModel con ruoli
session_id/title/message_count/updated_at; api.sessions ora e' il
modello, api.sessionsCount per lo stato "nessuna sessione"
- /api/sessions con sidebar_source=webui&exclude_hidden=1 (come la
sidebar del browser: solo sessioni WebUI, niente CLI/cron/nascoste)
- SessionsPage: describe(message_count, updated_at) con parametri espliciti
- PROTOCOL.md: payload sessions verificato + nota del pitfall Qt 5.6
This commit is contained in:
+16
-3
@@ -15,6 +15,7 @@ ApiClient::ApiClient(Settings *settings, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_settings(settings)
|
||||
, m_jar(new CookieJar(this))
|
||||
, m_sessionsModel(new SessionsModel(this))
|
||||
, m_loggedIn(false)
|
||||
, m_busy(false)
|
||||
, m_streaming(false)
|
||||
@@ -170,7 +171,7 @@ void ApiClient::logout()
|
||||
});
|
||||
m_jar->clear();
|
||||
setLoggedIn(false);
|
||||
m_sessions.clear();
|
||||
m_sessionsModel->setSessions(QVariantList());
|
||||
emit sessionsChanged();
|
||||
m_session.clear();
|
||||
emit sessionChanged();
|
||||
@@ -181,7 +182,14 @@ void ApiClient::logout()
|
||||
void ApiClient::refreshSessions()
|
||||
{
|
||||
setBusy(true);
|
||||
QNetworkReply *reply = m_nam.get(jsonRequest(QStringLiteral("/api/sessions")));
|
||||
// Stessi parametri della sidebar del WebUI: solo sessioni WebUI visibili
|
||||
// (senza parametri arriverebbero anche le CLI/cron e le nascoste).
|
||||
QUrl url = apiUrl(QStringLiteral("/api/sessions"));
|
||||
QUrlQuery q;
|
||||
q.addQueryItem(QStringLiteral("sidebar_source"), QStringLiteral("webui"));
|
||||
q.addQueryItem(QStringLiteral("exclude_hidden"), QStringLiteral("1"));
|
||||
url.setQuery(q);
|
||||
QNetworkReply *reply = m_nam.get(QNetworkRequest(url));
|
||||
connect(reply, &QNetworkReply::finished, this, [this, reply]() {
|
||||
reply->deleteLater();
|
||||
setBusy(false);
|
||||
@@ -192,11 +200,16 @@ void ApiClient::refreshSessions()
|
||||
}
|
||||
const QJsonObject obj = QJsonDocument::fromJson(body).object();
|
||||
const QJsonArray arr = obj.value(QStringLiteral("sessions")).toArray();
|
||||
m_sessions = arr.toVariantList();
|
||||
m_sessionsModel->setSessions(arr.toVariantList());
|
||||
emit sessionsChanged();
|
||||
});
|
||||
}
|
||||
|
||||
int ApiClient::sessionsCount() const
|
||||
{
|
||||
return m_sessionsModel->rowCount();
|
||||
}
|
||||
|
||||
void ApiClient::openSession(const QString &id)
|
||||
{
|
||||
setLastError(QString());
|
||||
|
||||
+6
-3
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "cookiejar.h"
|
||||
#include "settings.h"
|
||||
#include "sessionsmodel.h"
|
||||
#include "sseparser.h"
|
||||
|
||||
class QHttpMultiPart;
|
||||
@@ -36,7 +37,8 @@ class ApiClient : public QObject
|
||||
Q_PROPERTY(bool streaming READ streaming NOTIFY streamingChanged)
|
||||
Q_PROPERTY(bool transcribing READ transcribing NOTIFY transcribingChanged)
|
||||
Q_PROPERTY(QString lastError READ lastError NOTIFY lastErrorChanged)
|
||||
Q_PROPERTY(QVariantList sessions READ sessions NOTIFY sessionsChanged)
|
||||
Q_PROPERTY(SessionsModel *sessions READ sessions NOTIFY sessionsChanged)
|
||||
Q_PROPERTY(int sessionsCount READ sessionsCount NOTIFY sessionsChanged)
|
||||
Q_PROPERTY(QVariantMap session READ session NOTIFY sessionChanged)
|
||||
|
||||
public:
|
||||
@@ -47,7 +49,8 @@ public:
|
||||
bool streaming() const { return m_streaming; }
|
||||
bool transcribing() const { return m_transcribing; }
|
||||
QString lastError() const { return m_lastError; }
|
||||
QVariantList sessions() const { return m_sessions; }
|
||||
SessionsModel *sessions() const { return m_sessionsModel; }
|
||||
int sessionsCount() const;
|
||||
QVariantMap session() const { return m_session; }
|
||||
|
||||
// Avvio: verifica lo stato auth (cookie persistito o auth disabilitata).
|
||||
@@ -119,7 +122,7 @@ private:
|
||||
bool m_transcribing;
|
||||
QString m_lastError;
|
||||
|
||||
QVariantList m_sessions;
|
||||
SessionsModel *m_sessionsModel;
|
||||
QVariantMap m_session;
|
||||
|
||||
QString m_streamId;
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "sessionsmodel.h"
|
||||
|
||||
#include <QVariantMap>
|
||||
|
||||
SessionsModel::SessionsModel(QObject *parent)
|
||||
: QAbstractListModel(parent)
|
||||
{
|
||||
}
|
||||
|
||||
int SessionsModel::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
if (parent.isValid())
|
||||
return 0;
|
||||
return m_rows.size();
|
||||
}
|
||||
|
||||
QVariant SessionsModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (!index.isValid() || index.row() < 0 || index.row() >= m_rows.size())
|
||||
return QVariant();
|
||||
|
||||
const QVariantMap row = m_rows.at(index.row()).toMap();
|
||||
switch (role) {
|
||||
case SessionIdRole:
|
||||
return row.value(QStringLiteral("session_id"));
|
||||
case TitleRole:
|
||||
return row.value(QStringLiteral("title"));
|
||||
case MessageCountRole:
|
||||
return row.value(QStringLiteral("message_count"));
|
||||
case UpdatedAtRole:
|
||||
return row.value(QStringLiteral("updated_at"));
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> SessionsModel::roleNames() const
|
||||
{
|
||||
QHash<int, QByteArray> names;
|
||||
names[SessionIdRole] = "session_id";
|
||||
names[TitleRole] = "title";
|
||||
names[MessageCountRole] = "message_count";
|
||||
names[UpdatedAtRole] = "updated_at";
|
||||
return names;
|
||||
}
|
||||
|
||||
void SessionsModel::setSessions(const QVariantList &sessions)
|
||||
{
|
||||
beginResetModel();
|
||||
m_rows = sessions;
|
||||
endResetModel();
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#ifndef SESSIONSMODEL_H
|
||||
#define SESSIONSMODEL_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QVariantList>
|
||||
|
||||
// Modello delle sessioni per la lista QML.
|
||||
//
|
||||
// Perché non una QVariantList di mappe: sul kit Sailfish 5.1 (Qt 5.6) i campi
|
||||
// di una QVariantMap dentro una lista non si risolvono nei delegate
|
||||
// (model.campo = undefined -> righe vuote, pur con dati corretti dal server).
|
||||
// I ruoli di un QAbstractListModel sono il meccanismo supportato da sempre
|
||||
// (stesso principio dei ListModel usati con successo negli altri progetti).
|
||||
class SessionsModel : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Roles {
|
||||
SessionIdRole = Qt::UserRole + 1,
|
||||
TitleRole,
|
||||
MessageCountRole,
|
||||
UpdatedAtRole,
|
||||
};
|
||||
|
||||
explicit SessionsModel(QObject *parent = nullptr);
|
||||
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
// Sostituisce i dati (reset del modello: la lista QML si aggiorna).
|
||||
void setSessions(const QVariantList &sessions);
|
||||
|
||||
private:
|
||||
QVariantList m_rows;
|
||||
};
|
||||
|
||||
#endif // SESSIONSMODEL_H
|
||||
Reference in New Issue
Block a user