mirror of
https://github.com/nomic-ai/gpt4all
synced 2024-11-18 03:25:46 +00:00
The GUI should come up immediately and not wait on deserializing from disk.
This commit is contained in:
parent
eb7b61a76d
commit
ab13148430
@ -7,6 +7,21 @@
|
|||||||
#define CHAT_FORMAT_MAGIC 0xF5D553CC
|
#define CHAT_FORMAT_MAGIC 0xF5D553CC
|
||||||
#define CHAT_FORMAT_VERSION 100
|
#define CHAT_FORMAT_VERSION 100
|
||||||
|
|
||||||
|
ChatListModel::ChatListModel(QObject *parent)
|
||||||
|
: QAbstractListModel(parent)
|
||||||
|
, m_newChat(nullptr)
|
||||||
|
, m_dummyChat(nullptr)
|
||||||
|
, m_currentChat(nullptr)
|
||||||
|
, m_shouldSaveChats(false)
|
||||||
|
{
|
||||||
|
addDummyChat();
|
||||||
|
|
||||||
|
ChatsRestoreThread *thread = new ChatsRestoreThread;
|
||||||
|
connect(thread, &ChatsRestoreThread::chatsRestored, this, &ChatListModel::restoreChats);
|
||||||
|
connect(thread, &ChatsRestoreThread::finished, thread, &QObject::deleteLater);
|
||||||
|
thread->start();
|
||||||
|
}
|
||||||
|
|
||||||
bool ChatListModel::shouldSaveChats() const
|
bool ChatListModel::shouldSaveChats() const
|
||||||
{
|
{
|
||||||
return m_shouldSaveChats;
|
return m_shouldSaveChats;
|
||||||
@ -36,6 +51,8 @@ void ChatListModel::saveChats() const
|
|||||||
if (!m_shouldSaveChats)
|
if (!m_shouldSaveChats)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
QElapsedTimer timer;
|
||||||
|
timer.start();
|
||||||
const QString savePath = Download::globalInstance()->downloadLocalModelsPath();
|
const QString savePath = Download::globalInstance()->downloadLocalModelsPath();
|
||||||
for (Chat *chat : m_chats) {
|
for (Chat *chat : m_chats) {
|
||||||
QString fileName = "gpt4all-" + chat->id() + ".chat";
|
QString fileName = "gpt4all-" + chat->id() + ".chat";
|
||||||
@ -58,11 +75,15 @@ void ChatListModel::saveChats() const
|
|||||||
}
|
}
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
|
qint64 elapsedTime = timer.elapsed();
|
||||||
|
qDebug() << "serializing chats took:" << elapsedTime << "ms";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatListModel::restoreChats()
|
void ChatsRestoreThread::run()
|
||||||
{
|
{
|
||||||
beginResetModel();
|
QElapsedTimer timer;
|
||||||
|
timer.start();
|
||||||
|
QList<Chat*> chats;
|
||||||
{
|
{
|
||||||
// Look for any files in the original spot which was the settings config directory
|
// Look for any files in the original spot which was the settings config directory
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
@ -80,13 +101,13 @@ void ChatListModel::restoreChats()
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
QDataStream in(&file);
|
QDataStream in(&file);
|
||||||
Chat *chat = new Chat(this);
|
Chat *chat = new Chat;
|
||||||
|
chat->moveToThread(qApp->thread());
|
||||||
if (!chat->deserialize(in)) {
|
if (!chat->deserialize(in)) {
|
||||||
qWarning() << "ERROR: Couldn't deserialize chat from file:" << file.fileName();
|
qWarning() << "ERROR: Couldn't deserialize chat from file:" << file.fileName();
|
||||||
file.remove();
|
file.remove();
|
||||||
} else {
|
} else {
|
||||||
connect(chat, &Chat::nameChanged, this, &ChatListModel::nameChanged);
|
chats.append(chat);
|
||||||
m_chats.append(chat);
|
|
||||||
}
|
}
|
||||||
qDebug() << "deserializing chat" << f;
|
qDebug() << "deserializing chat" << f;
|
||||||
file.remove(); // No longer storing in this directory
|
file.remove(); // No longer storing in this directory
|
||||||
@ -126,20 +147,51 @@ void ChatListModel::restoreChats()
|
|||||||
if (version <= 100)
|
if (version <= 100)
|
||||||
in.setVersion(QDataStream::Qt_6_5);
|
in.setVersion(QDataStream::Qt_6_5);
|
||||||
|
|
||||||
Chat *chat = new Chat(this);
|
Chat *chat = new Chat;
|
||||||
|
chat->moveToThread(qApp->thread());
|
||||||
if (!chat->deserialize(in)) {
|
if (!chat->deserialize(in)) {
|
||||||
qWarning() << "ERROR: Couldn't deserialize chat from file:" << file.fileName();
|
qWarning() << "ERROR: Couldn't deserialize chat from file:" << file.fileName();
|
||||||
file.remove();
|
file.remove();
|
||||||
} else {
|
} else {
|
||||||
connect(chat, &Chat::nameChanged, this, &ChatListModel::nameChanged);
|
chats.append(chat);
|
||||||
m_chats.append(chat);
|
|
||||||
}
|
}
|
||||||
qDebug() << "deserializing chat" << f;
|
qDebug() << "deserializing chat" << f;
|
||||||
file.close();
|
file.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::sort(m_chats.begin(), m_chats.end(), [](const Chat* a, const Chat* b) {
|
std::sort(chats.begin(), chats.end(), [](const Chat* a, const Chat* b) {
|
||||||
return a->creationDate() > b->creationDate();
|
return a->creationDate() > b->creationDate();
|
||||||
});
|
});
|
||||||
|
qint64 elapsedTime = timer.elapsed();
|
||||||
|
qDebug() << "deserializing chats took:" << elapsedTime << "ms";
|
||||||
|
|
||||||
|
emit chatsRestored(chats);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChatListModel::restoreChats(const QList<Chat*> &chats)
|
||||||
|
{
|
||||||
|
for (Chat* chat : chats) {
|
||||||
|
chat->setParent(this);
|
||||||
|
connect(chat, &Chat::nameChanged, this, &ChatListModel::nameChanged);
|
||||||
|
}
|
||||||
|
|
||||||
|
beginResetModel();
|
||||||
|
|
||||||
|
// Setup the new chats
|
||||||
|
m_chats = chats;
|
||||||
|
|
||||||
|
if (!m_chats.isEmpty()) {
|
||||||
|
Chat *firstChat = m_chats.first();
|
||||||
|
if (firstChat->chatModel()->count() < 2)
|
||||||
|
setNewChat(firstChat);
|
||||||
|
else
|
||||||
|
setCurrentChat(firstChat);
|
||||||
|
} else
|
||||||
|
addChat();
|
||||||
|
|
||||||
|
// Clean up the dummy
|
||||||
|
delete m_dummyChat;
|
||||||
|
m_dummyChat = nullptr;
|
||||||
|
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,16 @@
|
|||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
#include "chat.h"
|
#include "chat.h"
|
||||||
|
|
||||||
|
class ChatsRestoreThread : public QThread
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
void run() override;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void chatsRestored(QList<Chat*> chats);
|
||||||
|
};
|
||||||
|
|
||||||
class ChatListModel : public QAbstractListModel
|
class ChatListModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -12,13 +22,7 @@ class ChatListModel : public QAbstractListModel
|
|||||||
Q_PROPERTY(bool shouldSaveChats READ shouldSaveChats WRITE setShouldSaveChats NOTIFY shouldSaveChatsChanged)
|
Q_PROPERTY(bool shouldSaveChats READ shouldSaveChats WRITE setShouldSaveChats NOTIFY shouldSaveChatsChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ChatListModel(QObject *parent = nullptr)
|
explicit ChatListModel(QObject *parent = nullptr);
|
||||||
: QAbstractListModel(parent)
|
|
||||||
, m_currentChat(nullptr)
|
|
||||||
, m_newChat(nullptr)
|
|
||||||
, m_shouldSaveChats(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
enum Roles {
|
enum Roles {
|
||||||
IdRole = Qt::UserRole + 1,
|
IdRole = Qt::UserRole + 1,
|
||||||
@ -61,7 +65,7 @@ public:
|
|||||||
Q_INVOKABLE void addChat()
|
Q_INVOKABLE void addChat()
|
||||||
{
|
{
|
||||||
// Don't add a new chat if we already have one
|
// Don't add a new chat if we already have one
|
||||||
if (m_newChat)
|
if (m_newChat || m_dummyChat)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Create a new chat pointer and connect it to determine when it is populated
|
// Create a new chat pointer and connect it to determine when it is populated
|
||||||
@ -78,6 +82,18 @@ public:
|
|||||||
setCurrentChat(m_newChat);
|
setCurrentChat(m_newChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Q_INVOKABLE void addDummyChat()
|
||||||
|
{
|
||||||
|
// Create a new dummy chat pointer and don't connect it
|
||||||
|
m_dummyChat = new Chat(this);
|
||||||
|
beginInsertRows(QModelIndex(), 0, 0);
|
||||||
|
m_chats.prepend(m_dummyChat);
|
||||||
|
endInsertRows();
|
||||||
|
emit countChanged();
|
||||||
|
m_currentChat = m_dummyChat;
|
||||||
|
emit currentChatChanged();
|
||||||
|
}
|
||||||
|
|
||||||
void setNewChat(Chat* chat)
|
void setNewChat(Chat* chat)
|
||||||
{
|
{
|
||||||
// Don't add a new chat if we already have one
|
// Don't add a new chat if we already have one
|
||||||
@ -101,7 +117,6 @@ public:
|
|||||||
|
|
||||||
removeChatFile(chat);
|
removeChatFile(chat);
|
||||||
|
|
||||||
emit disconnectChat(chat);
|
|
||||||
if (chat == m_newChat) {
|
if (chat == m_newChat) {
|
||||||
m_newChat->disconnect(this);
|
m_newChat->disconnect(this);
|
||||||
m_newChat = nullptr;
|
m_newChat = nullptr;
|
||||||
@ -140,13 +155,9 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_currentChat) {
|
if (m_currentChat && m_currentChat->isModelLoaded())
|
||||||
if (m_currentChat->isModelLoaded())
|
|
||||||
m_currentChat->unloadModel();
|
m_currentChat->unloadModel();
|
||||||
emit disconnect(m_currentChat);
|
|
||||||
}
|
|
||||||
|
|
||||||
emit connectChat(chat);
|
|
||||||
m_currentChat = chat;
|
m_currentChat = chat;
|
||||||
if (!m_currentChat->isModelLoaded())
|
if (!m_currentChat->isModelLoaded())
|
||||||
m_currentChat->reloadModel();
|
m_currentChat->reloadModel();
|
||||||
@ -163,12 +174,10 @@ public:
|
|||||||
|
|
||||||
void removeChatFile(Chat *chat) const;
|
void removeChatFile(Chat *chat) const;
|
||||||
void saveChats() const;
|
void saveChats() const;
|
||||||
void restoreChats();
|
void restoreChats(const QList<Chat*> &chats);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void countChanged();
|
void countChanged();
|
||||||
void connectChat(Chat*);
|
|
||||||
void disconnectChat(Chat*);
|
|
||||||
void currentChatChanged();
|
void currentChatChanged();
|
||||||
void shouldSaveChatsChanged();
|
void shouldSaveChatsChanged();
|
||||||
|
|
||||||
@ -206,6 +215,7 @@ private Q_SLOTS:
|
|||||||
private:
|
private:
|
||||||
bool m_shouldSaveChats;
|
bool m_shouldSaveChats;
|
||||||
Chat* m_newChat;
|
Chat* m_newChat;
|
||||||
|
Chat* m_dummyChat;
|
||||||
Chat* m_currentChat;
|
Chat* m_currentChat;
|
||||||
QList<Chat*> m_chats;
|
QList<Chat*> m_chats;
|
||||||
};
|
};
|
||||||
|
10
llm.cpp
10
llm.cpp
@ -24,16 +24,6 @@ LLM::LLM()
|
|||||||
{
|
{
|
||||||
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
|
connect(QCoreApplication::instance(), &QCoreApplication::aboutToQuit,
|
||||||
this, &LLM::aboutToQuit);
|
this, &LLM::aboutToQuit);
|
||||||
|
|
||||||
m_chatListModel->restoreChats();
|
|
||||||
if (m_chatListModel->count()) {
|
|
||||||
Chat *firstChat = m_chatListModel->get(0);
|
|
||||||
if (firstChat->chatModel()->count() < 2)
|
|
||||||
m_chatListModel->setNewChat(firstChat);
|
|
||||||
else
|
|
||||||
m_chatListModel->setCurrentChat(firstChat);
|
|
||||||
} else
|
|
||||||
m_chatListModel->addChat();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LLM::checkForUpdates() const
|
bool LLM::checkForUpdates() const
|
||||||
|
Loading…
Reference in New Issue
Block a user