Files
harbour-hermes/qml/pages/SessionsPage.qml
T
kaneda 9c6a1242f7 feat: v0.1.0 — client Sailfish per hermes-webui con voce
- ApiClient HTTP/SSE: login, sessioni, chat/start, stream SSE, transcribe, tts
- ChatModel: streaming live + risincronizzazione dallo stato del server
- CookieJar persistente (0600, mai la password); Settings
- Recorder OGG/Opus (fallback WAV/PCM, retry); Player TTS (QMediaPlayer)
- UI Silica: splash, login, sessioni, chat (dettatura + read-aloud), settings, cover
- Sailjail Internet;Audio;Microphone; icone; spec RPM; docs PROTOCOL/BUILD
- tests/core_test: unit parser SSE + integrazione live (probe :8899)
2026-09-12 07:11:20 +02:00

116 lines
3.4 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: api.refreshSessions()
}
MenuItem {
text: qsTr("Settings")
onClicked: pageStack.push(Qt.resolvedUrl("SettingsPage.qml"))
}
MenuItem {
text: qsTr("Sign out")
onClicked: api.logout()
}
}
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).length > 0 ? model.title : model.session_id
}
Label {
width: parent.width
font.pixelSize: Theme.fontSizeExtraSmall
color: Theme.secondaryColor
text: page.describe(model)
}
}
onClicked: page.openSession(model.session_id)
}
ViewPlaceholder {
enabled: api.sessions.length === 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 openSession(id) {
expectNewSession = false
pageStack.push(Qt.resolvedUrl("ChatPage.qml"), { sessionId: id })
}
function createSession() {
expectNewSession = true
chat.newSession()
}
function describe(m) {
var n = m.message_count ? m.message_count : 0
var d = new Date((m.updated_at ? m.updated_at : 0) * 1000)
return n + qsTr(" messages") + " · " + Qt.formatDateTime(d, "dd/MM HH:mm")
}
}