mirror of
https://github.com/Palm1r/QodeAssist.git
synced 2026-03-20 12:39:51 -04:00
fix: Remove image dublicate (#271)
This commit is contained in:
@ -20,8 +20,11 @@
|
||||
#include "ChatModel.hpp"
|
||||
#include <utils/aspects.h>
|
||||
#include <QDateTime>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QUrl>
|
||||
#include <QtQml>
|
||||
|
||||
#include "ChatAssistantSettings.hpp"
|
||||
@ -91,6 +94,19 @@ QVariant ChatModel::data(const QModelIndex &index, int role) const
|
||||
imageMap["fileName"] = image.fileName;
|
||||
imageMap["storedPath"] = image.storedPath;
|
||||
imageMap["mediaType"] = image.mediaType;
|
||||
|
||||
// Generate proper file URL for cross-platform compatibility
|
||||
if (!m_chatFilePath.isEmpty()) {
|
||||
QFileInfo fileInfo(m_chatFilePath);
|
||||
QString baseName = fileInfo.completeBaseName();
|
||||
QString dirPath = fileInfo.absolutePath();
|
||||
QString imagesFolder = QDir(dirPath).filePath(baseName + "_images");
|
||||
QString fullPath = QDir(imagesFolder).filePath(image.storedPath);
|
||||
imageMap["imageUrl"] = QUrl::fromLocalFile(fullPath).toString();
|
||||
} else {
|
||||
imageMap["imageUrl"] = QString();
|
||||
}
|
||||
|
||||
imagesList.append(imageMap);
|
||||
}
|
||||
return imagesList;
|
||||
@ -549,4 +565,14 @@ void ChatModel::updateFileEditStatus(const QString &editId, const QString &statu
|
||||
}
|
||||
}
|
||||
|
||||
void ChatModel::setChatFilePath(const QString &filePath)
|
||||
{
|
||||
m_chatFilePath = filePath;
|
||||
}
|
||||
|
||||
QString ChatModel::chatFilePath() const
|
||||
{
|
||||
return m_chatFilePath;
|
||||
}
|
||||
|
||||
} // namespace QodeAssist::Chat
|
||||
|
||||
@ -101,6 +101,9 @@ public:
|
||||
|
||||
void setLoadingFromHistory(bool loading);
|
||||
bool isLoadingFromHistory() const;
|
||||
|
||||
void setChatFilePath(const QString &filePath);
|
||||
QString chatFilePath() const;
|
||||
|
||||
signals:
|
||||
void tokensThresholdChanged();
|
||||
@ -116,6 +119,7 @@ private:
|
||||
|
||||
QVector<Message> m_messages;
|
||||
bool m_loadingFromHistory = false;
|
||||
QString m_chatFilePath;
|
||||
};
|
||||
|
||||
} // namespace QodeAssist::Chat
|
||||
|
||||
@ -601,6 +601,21 @@ void ChatRootView::showAddImageDialog()
|
||||
}
|
||||
}
|
||||
|
||||
QStringList ChatRootView::convertUrlsToLocalPaths(const QVariantList &urls) const
|
||||
{
|
||||
QStringList localPaths;
|
||||
for (const QVariant &urlVariant : urls) {
|
||||
QUrl url(urlVariant.toString());
|
||||
if (url.isLocalFile()) {
|
||||
QString localPath = url.toLocalFile();
|
||||
if (!localPath.isEmpty()) {
|
||||
localPaths.append(localPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
return localPaths;
|
||||
}
|
||||
|
||||
void ChatRootView::calculateMessageTokensCount(const QString &message)
|
||||
{
|
||||
m_messageTokensCount = Context::TokenUtils::estimateTokens(message);
|
||||
|
||||
@ -88,6 +88,7 @@ public:
|
||||
Q_INVOKABLE void showLinkFilesDialog();
|
||||
Q_INVOKABLE void addFilesToLinkList(const QStringList &filePaths);
|
||||
Q_INVOKABLE void removeFileFromLinkList(int index);
|
||||
Q_INVOKABLE QStringList convertUrlsToLocalPaths(const QVariantList &urls) const;
|
||||
Q_INVOKABLE void showAddImageDialog();
|
||||
Q_INVOKABLE bool isImageFile(const QString &filePath) const;
|
||||
Q_INVOKABLE void calculateMessageTokensCount(const QString &message);
|
||||
|
||||
@ -183,22 +183,7 @@ void ClientInterface::sendMessage(
|
||||
messages.append(apiMessage);
|
||||
}
|
||||
|
||||
if (!imageAttachments.isEmpty() && provider->supportImage() && !messages.isEmpty()) {
|
||||
for (int i = messages.size() - 1; i >= 0; --i) {
|
||||
if (messages[i].role == "user") {
|
||||
auto newImages = loadImagesFromStorage(imageAttachments);
|
||||
if (!newImages.isEmpty()) {
|
||||
if (messages[i].images.has_value()) {
|
||||
messages[i].images.value().append(newImages);
|
||||
} else {
|
||||
messages[i].images = newImages;
|
||||
}
|
||||
LOG_MESSAGE(QString("Added %1 new image(s) to message").arg(newImages.size()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (!imageFiles.isEmpty() && !provider->supportImage()) {
|
||||
if (!imageFiles.isEmpty() && !provider->supportImage()) {
|
||||
LOG_MESSAGE(QString("Provider %1 doesn't support images, %2 ignored")
|
||||
.arg(provider->name(), QString::number(imageFiles.size())));
|
||||
}
|
||||
@ -522,6 +507,7 @@ QVector<LLMCore::ImageAttachment> ClientInterface::loadImagesFromStorage(const Q
|
||||
void ClientInterface::setChatFilePath(const QString &filePath)
|
||||
{
|
||||
m_chatFilePath = filePath;
|
||||
m_chatModel->setChatFilePath(filePath);
|
||||
}
|
||||
|
||||
QString ClientInterface::chatFilePath() const
|
||||
|
||||
@ -61,12 +61,18 @@ ChatRootView {
|
||||
SplitDropZone {
|
||||
anchors.fill: parent
|
||||
|
||||
onFilesDroppedToAttach: (filePaths) => {
|
||||
root.addFilesToAttachList(filePaths)
|
||||
onFilesDroppedToAttach: (urlStrings) => {
|
||||
var localPaths = root.convertUrlsToLocalPaths(urlStrings)
|
||||
if (localPaths.length > 0) {
|
||||
root.addFilesToAttachList(localPaths)
|
||||
}
|
||||
}
|
||||
|
||||
onFilesDroppedToLink: (filePaths) => {
|
||||
root.addFilesToLinkList(filePaths)
|
||||
onFilesDroppedToLink: (urlStrings) => {
|
||||
var localPaths = root.convertUrlsToLocalPaths(urlStrings)
|
||||
if (localPaths.length > 0) {
|
||||
root.addFilesToLinkList(localPaths)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -263,12 +263,7 @@ Rectangle {
|
||||
Layout.maximumWidth: parent.parent.maxImageWidth
|
||||
Layout.maximumHeight: parent.parent.maxImageHeight
|
||||
|
||||
source: {
|
||||
if (!itemData.storedPath || !root.chatFilePath) return "";
|
||||
var fileInfo = chatFileInfo(root.chatFilePath);
|
||||
var imagesFolder = fileInfo.dir + "/" + fileInfo.baseName + "_images";
|
||||
return "file://" + imagesFolder + "/" + itemData.storedPath;
|
||||
}
|
||||
source: itemData.imageUrl ? itemData.imageUrl : ""
|
||||
|
||||
sourceSize.width: parent.parent.maxImageWidth
|
||||
sourceSize.height: parent.parent.maxImageHeight
|
||||
@ -303,14 +298,4 @@ Rectangle {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function chatFileInfo(filePath) {
|
||||
if (!filePath) return {dir: "", baseName: ""};
|
||||
var lastSlash = filePath.lastIndexOf("/");
|
||||
var dir = lastSlash >= 0 ? filePath.substring(0, lastSlash) : "";
|
||||
var fileName = lastSlash >= 0 ? filePath.substring(lastSlash + 1) : filePath;
|
||||
var lastDot = fileName.lastIndexOf(".");
|
||||
var baseName = lastDot >= 0 ? fileName.substring(0, lastDot) : fileName;
|
||||
return {dir: dir, baseName: baseName};
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,8 +23,8 @@ import QtQuick.Controls
|
||||
Item {
|
||||
id: root
|
||||
|
||||
signal filesDroppedToAttach(var filePaths)
|
||||
signal filesDroppedToLink(var filePaths)
|
||||
signal filesDroppedToAttach(var urlStrings) // Array of URL strings (file://...)
|
||||
signal filesDroppedToLink(var urlStrings) // Array of URL strings (file://...)
|
||||
|
||||
property string activeZone: ""
|
||||
|
||||
@ -216,21 +216,17 @@ Item {
|
||||
splitDropOverlay.visible = false
|
||||
root.activeZone = ""
|
||||
|
||||
if (drop.hasUrls) {
|
||||
var filePaths = []
|
||||
if (drop.hasUrls && drop.urls.length > 0) {
|
||||
// Convert URLs to array of strings for C++ processing
|
||||
var urlStrings = []
|
||||
for (var i = 0; i < drop.urls.length; i++) {
|
||||
var url = drop.urls[i].toString()
|
||||
if (url.startsWith("file://")) {
|
||||
filePaths.push(decodeURIComponent(url.replace(/^file:\/\//, '')))
|
||||
}
|
||||
urlStrings.push(drop.urls[i].toString())
|
||||
}
|
||||
|
||||
if (filePaths.length > 0) {
|
||||
if (targetZone === "right") {
|
||||
root.filesDroppedToLink(filePaths)
|
||||
} else {
|
||||
root.filesDroppedToAttach(filePaths)
|
||||
}
|
||||
|
||||
if (targetZone === "right") {
|
||||
root.filesDroppedToLink(urlStrings)
|
||||
} else {
|
||||
root.filesDroppedToAttach(urlStrings)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user