better chat list view + anchor to bottom. sqlite db for chats + LIFO-ordered

This commit is contained in:
2026-08-23 16:37:11 +02:00
parent 37c6a9986e
commit aae3757daf
36 changed files with 2653 additions and 1459 deletions
@@ -8,26 +8,49 @@ import ZShell.Llm
import qs.Components
import qs.Services
RowLayout {
Item {
id: root
ChatList {
id: chatList
property int breakpoint: 700
property alias conversationModel: sidebar.model
property var currentConversation: null // whatever model item is "open"
Layout.fillHeight: true
Layout.fillWidth: true
Layout.maximumWidth: Config.sidebar.sizes.width
Layout.minimumWidth: Config.sidebar.sizes.width / 2
readonly property bool isWide: root.width >= root.breakpoint
property bool narrowShowsSidebar: true
function closeConversation() {
narrowShowsSidebar = true;
}
function openConversation(conv) {
currentConversation = conv;
narrowShowsSidebar = false; // in narrow mode, jump to the chat
}
ChatList {
id: sidebar
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: root.isWide ? undefined : parent.right
anchors.top: parent.top
implicitWidth: 20
list.currentIndex: -1
list.highlightFollowsCurrentItem: false
Behavior on anchors.right {
AnchorAnim {}
}
Behavior on implicitWidth {
Anim {}
}
list.highlight: CustomRect {
color: Colors.palette.m3primary
implicitHeight: chatList.list.currentItem?.implicitHeight ?? 0
implicitWidth: chatList.list.width
implicitHeight: sidebar.list.currentItem?.implicitHeight ?? 0
implicitWidth: sidebar.list.width
radius: Tokens.rounding.medium
x: chatList.list.currentItem?.chat.x ?? 0
y: chatList.list.currentItem?.y ?? 0
x: sidebar.list.currentItem?.chat.x ?? 0
y: sidebar.list.currentItem?.y ?? 0
Behavior on y {
Anim {
@@ -40,18 +63,29 @@ RowLayout {
values: Chat.chats.values
}
anchors.onRightChanged: {
if (anchors.right === undefined)
implicitWidth = 20;
}
onLoadChatRequest: (chat, index) => {
chatList.list.currentIndex = index;
chatContent.chatData = chat;
sidebar.list.currentIndex = index;
root.openConversation(chat);
}
}
ChatContent {
id: chatContent
CustomClippingWrapperRect {
anchors.bottom: parent.bottom
anchors.left: sidebar.right
anchors.right: parent.right
anchors.top: parent.top
child: conversationView
}
Layout.fillHeight: true
Layout.fillWidth: true
Layout.minimumWidth: Config.sidebar.sizes.width
Layout.preferredWidth: Math.round(Config.sidebar.sizes.width * 1.5)
ChatContent {
id: conversationView
anchors.fill: root
anchors.leftMargin: root.isWide ? Config.sidebar.sizes.width / 2 : 0
chatData: root.currentConversation
}
}