#pragma once #include "session.hpp" #include #include #include #include #include #include #include namespace ZShell::llm { class LlmClient; class ChatStore : public QAbstractListModel { Q_OBJECT QML_ELEMENT QML_UNCREATABLE("Chat sessions are owned by the LlmClient singleton") public: explicit ChatStore(LlmClient* client, QObject* parent = nullptr); ~ChatStore() override; [[nodiscard]] int rowCount( const QModelIndex& parent = QModelIndex()) const override; [[nodiscard]] QVariant data( const QModelIndex& index, int role = Qt::DisplayRole) const override; [[nodiscard]] QHash roleNames() const override; [[nodiscard]] LlmClient* client() const { return m_client; } [[nodiscard]] int rowOf(const ChatSession* session) const; Q_INVOKABLE ZShell::llm::ChatSession* draft(); Q_INVOKABLE void remove(ZShell::llm::ChatSession* chat); Q_INVOKABLE void clear(); void commitDraft(ZShell::llm::ChatSession* session); void persist(ZShell::llm::ChatSession* session); void saveFlags(ZShell::llm::ChatSession* session); void loadMessagesInto(ZShell::llm::ChatSession* session); void requestClear(ZShell::llm::ChatSession* session); void applyPendingClear(ZShell::llm::ChatSession* session); void reposition(ZShell::llm::ChatSession* session); Q_SIGNALS: void sessionRemoved(ZShell::llm::ChatSession* session); private: void openDb(); void load(); [[nodiscard]] int sortedRow(const ChatSession* session) const; [[nodiscard]] static bool firstAfter( const ChatSession* a, const ChatSession* b); void insertRow(ChatSession* session); void moveRow(int from, int to); void removeRow(ChatSession* session); [[nodiscard]] bool saveSession(ChatSession* session); [[nodiscard]] bool writeSessionRow(ChatSession* session); [[nodiscard]] QSqlDatabase db() const; LlmClient* m_client; QList m_sessions; ChatSession* m_draft = nullptr; QString m_connectionName; QString m_dbPath; QSet m_pendingPersists; QSet m_pendingClears; bool m_loading = false; }; } // namespace ZShell::llm