Files
z-bar-qt/Modules/Sidebar/Chat/SidebarView.qml
T

208 lines
4.3 KiB
QML

pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Layouts
import QtQuick.Controls
import Quickshell
import ZShell.Blobs
import ZShell.Config
import ZShell.Llm
import qs.Components
import qs.Modules.Sidebar.Chat.Content
import qs.Services
Item {
id: root
property int breakpoint: Math.round(Config.sidebar.sizes.width * 2) + Tokens.spacing.medium * 2 + Tokens.padding.medium * 3
property color blobColor: Colors.tPalette.m3surfaceContainerLow
readonly property int iconSize: Math.round(Tokens.font.icon.extraLarge.pointSize * (96 / 72)) + Tokens.padding.large * 2
property alias conversationModel: sidebar.model
property bool chatOpen: ChatState.chatSession !== null
readonly property bool isWide: root.width >= root.breakpoint
readonly property bool showList: isWide || !chatOpen
readonly property bool showContent: !isWide && chatOpen
function openConversation(conv: ChatSession, index: int): void {
}
BlobGroup {
id: blobGroup
color: root.blobColor
smoothing: Tokens.rounding.medium
}
BlobInvertedRect {
id: invertedRect
anchors.fill: parent
borderBottom: Tokens.padding.small
borderLeft: sidebar.implicitWidth + sidebar.anchors.margins + Tokens.spacing.medium
borderRight: Tokens.padding.small
borderTop: Tokens.padding.small
group: blobGroup
opacity: root.blobColor.a
radius: Tokens.rounding.largeIncreased
}
ChatList {
id: sidebar
anchors.top: parent.top
anchors.left: parent.left
anchors.bottom: parent.bottom
anchors.margins: Tokens.padding.medium
implicitWidth: root.isWide || ChatState.narrowSidebarExpanded ? Config.sidebar.sizes.width : root.iconSize
highlight: true
slim: !root.isWide && !ChatState.narrowSidebarExpanded
z: 1
Behavior on implicitWidth {
Anim {
type: Anim.DefaultEffects
}
}
model: LlmClient.chats
onLoadChatRequest: (chat, index) => {
ChatState.currentIdx = index;
ChatState.chatSession = chat;
}
onDeleteChatRequest: chat => {
const wasCurrent = chat === ChatState.chatSession;
LlmClient.chats.remove(chat);
if (wasCurrent)
ChatState.openDraft();
}
onNewChatRequest: ChatState.openDraft()
onRequestExpand: {
ChatState.narrowSidebarExpanded = true;
}
}
CustomClippingRect {
anchors.fill: parent
anchors.leftMargin: invertedRect.borderLeft
anchors.topMargin: invertedRect.borderTop
anchors.bottomMargin: invertedRect.borderBottom
anchors.rightMargin: invertedRect.borderRight
radius: invertedRect.radius
children: [contentArea, dim]
}
CustomRect {
id: dim
anchors.fill: parent
color: Colors.palette.m3shadow
opacity: ChatState.narrowSidebarExpanded && !root.isWide ? 0.3 : 0
z: 1
Behavior on opacity {
Anim {
type: Anim.DefaultEffects
}
}
}
Item {
id: contentArea
property int leftMargin: sidebar.implicitWidth
z: 0
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
implicitWidth: root.width - leftMargin - sidebar.anchors.margins - Tokens.spacing.medium * 2
states: State {
name: "wide"
when: !root.isWide
PropertyChanges {
contentArea.leftMargin: root.iconSize
}
}
transitions: Transition {
to: "wide"
Anim {
type: Anim.DefaultEffects
property: "leftMargin"
}
}
ChatHost {
id: convHost
anchors.fill: parent
clip: true
onLoadingChanged: if (!loading)
root.chatOpen = true
}
MouseArea {
id: dimArea
anchors.fill: parent
preventStealing: true
enabled: !root.isWide && ChatState.narrowSidebarExpanded
cursorShape: undefined
onClicked: {
const x = mouseX;
const margin = root.width - contentArea.implicitWidth - contentArea.anchors.margins * 2;
if (x > invertedRect.borderLeft - margin) {
ChatState.narrowSidebarExpanded = false;
ChatState.fabExpanded = false;
}
}
HoverHandler {
cursorShape: dimArea.enabled ? Qt.ArrowCursor : undefined
enabled: dimArea.enabled
}
}
}
Binding {
target: ChatState
property: "windowIsWide"
value: root.showList
}
Binding {
target: ChatState
property: "isWide"
value: root.isWide
}
Binding {
target: ChatState
value: contentArea.leftMargin === root.iconSize
property: "settledSlim"
}
Binding {
target: ChatState
value: contentArea.leftMargin === sidebar.implicitWidth
property: "settledWide"
}
Component {
id: conversationView
ChatContent {}
}
}