Files
harbour-hermes/qml/pages/SessionsPage.qml
T
kaneda 479edb0f99 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
2026-09-12 08:47:28 +02:00

128 lines
3.5 KiB
QML

import QtQuick 2.0
import Sailfish.Silica 1.0
// Lista delle sessioni della Web UI di Hermes (sidebar).
Page {
id: page
// true solo quando e' questa pagina a chiedere una nuova sessione:
// serve a distinguere la creazione dall'apertura di una sessione esistente.
property bool expectNewSession: false
SilicaListView {
id: list
anchors.fill: parent
model: api.sessions
spacing: Theme.paddingSmall
header: PageHeader { title: qsTr("Sessions") }
PullDownMenu {
MenuItem {
text: qsTr("New session")
onClicked: page.createSession()
}
MenuItem {
text: qsTr("Refresh")
onClicked: page.refresh()
}
MenuItem {
text: qsTr("Settings")
onClicked: page.openSettings()
}
MenuItem {
text: qsTr("Sign out")
onClicked: page.signOut()
}
}
delegate: ListItem {
id: item
contentHeight: col.height + Theme.paddingMedium
Column {
id: col
x: Theme.horizontalPageMargin
width: parent.width - 2 * Theme.horizontalPageMargin
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.paddingSmall / 2
Label {
width: parent.width
truncationMode: TruncationMode.Fade
color: item.highlighted ? Theme.highlightColor : Theme.primaryColor
text: model.title ? model.title : model.session_id
}
Label {
width: parent.width
font.pixelSize: Theme.fontSizeExtraSmall
color: Theme.secondaryColor
text: page.describe(model.message_count, model.updated_at)
}
}
onClicked: page.openSession(model.session_id)
}
ViewPlaceholder {
enabled: api.sessionsCount === 0 && !api.busy
text: qsTr("No sessions")
hintText: qsTr("Pull down to create a new session")
}
VerticalScrollDecorator {}
}
BusyIndicator {
anchors.centerIn: parent
size: BusyIndicatorSize.Large
running: api.busy
}
Connections {
target: api
onLoggedInChanged: {
if (!api.loggedIn)
pageStack.replace(Qt.resolvedUrl("LoginPage.qml"))
}
onSessionOpened: {
if (page.expectNewSession) {
page.expectNewSession = false
pageStack.push(Qt.resolvedUrl("ChatPage.qml"),
{ sessionId: api.session.session_id })
}
}
}
Component.onCompleted: api.refreshSessions()
function refresh() {
api.refreshSessions()
}
function openSettings() {
pageStack.push(Qt.resolvedUrl("SettingsPage.qml"))
}
function signOut() {
api.logout()
}
function openSession(id) {
expectNewSession = false
pageStack.push(Qt.resolvedUrl("ChatPage.qml"), { sessionId: id })
}
function createSession() {
expectNewSession = true
chat.newSession()
}
function describe(n, u) {
var c = n ? n : 0
var d = new Date((u ? u : 0) * 1000)
return c + qsTr(" messages") + " · " + Qt.formatDateTime(d, "dd/MM HH:mm")
}
}