Improve images in the chatbar

- Don't show the hide button
- Shrink them to better fit
- Allow a little more maxh height in the chatbar for attachments
- Make sure that the button states work properly when adding and removing images
This commit is contained in:
James Graham
2026-02-08 14:25:54 +00:00
parent f02366ee48
commit 60cf12524f
7 changed files with 71 additions and 26 deletions

View File

@@ -75,7 +75,7 @@ QQC2.Control {
QQC2.ScrollView { QQC2.ScrollView {
id: chatScrollView id: chatScrollView
Layout.fillWidth: true Layout.fillWidth: true
Layout.maximumHeight: Kirigami.Units.gridUnit * 8 Layout.maximumHeight: Kirigami.Units.gridUnit * (root.model.hasAttachment ? 12 : 8)
contentWidth: availableWidth contentWidth: availableWidth
clip: true clip: true

View File

@@ -58,6 +58,7 @@ RowLayout {
readonly property ChatButtonHelper chatButtonHelper: ChatButtonHelper { readonly property ChatButtonHelper chatButtonHelper: ChatButtonHelper {
textItem: root.contentModel.focusedTextItem textItem: root.contentModel.focusedTextItem
inQuote: root.contentModel.focusType == LibNeoChat.MessageComponentType.Quote inQuote: root.contentModel.focusType == LibNeoChat.MessageComponentType.Quote
hasAttachment: root.contentModel.hasAttachment
} }
signal clicked signal clicked

View File

@@ -5,11 +5,8 @@
#include <Kirigami/Platform/PlatformTheme> #include <Kirigami/Platform/PlatformTheme>
#include "chatbarcache.h"
#include "chattextitemhelper.h" #include "chattextitemhelper.h"
#include "enums/chatbartype.h"
#include "enums/richformat.h" #include "enums/richformat.h"
#include "neochatroom.h"
ChatButtonHelper::ChatButtonHelper(QObject *parent) ChatButtonHelper::ChatButtonHelper(QObject *parent)
: QObject(parent) : QObject(parent)
@@ -34,12 +31,6 @@ void ChatButtonHelper::setTextItem(ChatTextItemHelper *textItem)
m_textItem = textItem; m_textItem = textItem;
if (m_textItem) { if (m_textItem) {
connect(m_textItem, &ChatTextItemHelper::roomChanged, this, [this]() {
if (m_textItem->room() && m_textItem->type() != ChatBarType::None) {
const auto cache = m_textItem->room()->cacheForType(m_textItem->type());
connect(cache, &ChatBarCache::attachmentPathChanged, this, &ChatButtonHelper::richFormatEnabledChanged);
}
});
connect(m_textItem, &ChatTextItemHelper::textFormatChanged, this, &ChatButtonHelper::richFormatEnabledChanged); connect(m_textItem, &ChatTextItemHelper::textFormatChanged, this, &ChatButtonHelper::richFormatEnabledChanged);
connect(m_textItem, &ChatTextItemHelper::textFormatChanged, this, &ChatButtonHelper::styleChanged); connect(m_textItem, &ChatTextItemHelper::textFormatChanged, this, &ChatButtonHelper::styleChanged);
connect(m_textItem, &ChatTextItemHelper::charFormatChanged, this, &ChatButtonHelper::charFormatChanged); connect(m_textItem, &ChatTextItemHelper::charFormatChanged, this, &ChatButtonHelper::charFormatChanged);
@@ -68,6 +59,21 @@ void ChatButtonHelper::setInQuote(bool inQuote)
Q_EMIT styleChanged(); Q_EMIT styleChanged();
} }
bool ChatButtonHelper::hasAttachment() const
{
return m_hasAttachment;
}
void ChatButtonHelper::setHasAttachment(bool hasAttachment)
{
if (hasAttachment == m_hasAttachment) {
return;
}
m_hasAttachment = hasAttachment;
Q_EMIT hasAttachmentChanged();
Q_EMIT richFormatEnabledChanged();
}
bool ChatButtonHelper::richFormatEnabled() const bool ChatButtonHelper::richFormatEnabled() const
{ {
if (!m_textItem) { if (!m_textItem) {
@@ -86,16 +92,9 @@ bool ChatButtonHelper::richFormatEnabled() const
bool ChatButtonHelper::styleFormatEnabled() const bool ChatButtonHelper::styleFormatEnabled() const
{ {
if (!m_textItem) { if (!m_textItem || m_hasAttachment) {
return false; return false;
} }
const auto room = m_textItem->room();
if (!room) {
return false;
}
if (const auto cache = room->cacheForType(m_textItem->type())) {
return cache->attachmentPath().isEmpty();
}
return true; return true;
} }

View File

@@ -28,6 +28,11 @@ class ChatButtonHelper : public QObject
*/ */
Q_PROPERTY(bool inQuote READ inQuote WRITE setInQuote NOTIFY inQuoteChanged) Q_PROPERTY(bool inQuote READ inQuote WRITE setInQuote NOTIFY inQuoteChanged)
/**
* @brief Whether the model has an attachment..
*/
Q_PROPERTY(bool hasAttachment READ hasAttachment WRITE setHasAttachment NOTIFY hasAttachmentChanged)
/** /**
* @brief Whether rich formating is enabled at the current cursor location. * @brief Whether rich formating is enabled at the current cursor location.
*/ */
@@ -102,6 +107,9 @@ public:
bool inQuote() const; bool inQuote() const;
void setInQuote(bool inQuote); void setInQuote(bool inQuote);
bool hasAttachment() const;
void setHasAttachment(bool hasAttachment);
bool richFormatEnabled() const; bool richFormatEnabled() const;
bool styleFormatEnabled() const; bool styleFormatEnabled() const;
bool bold() const; bool bold() const;
@@ -149,6 +157,7 @@ public:
Q_SIGNALS: Q_SIGNALS:
void textItemChanged(); void textItemChanged();
void inQuoteChanged(); void inQuoteChanged();
void hasAttachmentChanged();
void richFormatEnabledChanged(); void richFormatEnabledChanged();
void charFormatChanged(); void charFormatChanged();
void styleChanged(); void styleChanged();
@@ -157,6 +166,7 @@ Q_SIGNALS:
private: private:
QPointer<ChatTextItemHelper> m_textItem; QPointer<ChatTextItemHelper> m_textItem;
bool m_inQuote = false; bool m_inQuote = false;
bool m_hasAttachment = false;
void selectLinkText(QTextCursor &cursor) const; void selectLinkText(QTextCursor &cursor) const;
}; };

View File

@@ -58,7 +58,9 @@ DelegateChooser {
DelegateChoice { DelegateChoice {
roleValue: MessageComponentType.Image roleValue: MessageComponentType.Image
delegate: ImageComponent {} delegate: ImageComponent {
rightAnchorMargin: root.rightAnchorMargin
}
} }
DelegateChoice { DelegateChoice {

View File

@@ -7,6 +7,7 @@ pragma ComponentBehavior: Bound
import QtCore import QtCore
import QtQuick import QtQuick
import QtQuick.Controls as QQC2 import QtQuick.Controls as QQC2
import QtQuick.Layouts
import org.kde.kirigami as Kirigami import org.kde.kirigami as Kirigami
@@ -38,19 +39,33 @@ Item {
*/ */
required property var fileTransferInfo required property var fileTransferInfo
/**
* @brief Whether the component should be editable.
*/
required property bool editable
/** /**
* The maximum height of the image. Can be left undefined most of the times. Passed to MediaSizeHelper::contentMaxHeight. * The maximum height of the image. Can be left undefined most of the times. Passed to MediaSizeHelper::contentMaxHeight.
*/ */
property var contentMaxHeight: undefined property var contentMaxHeight: editable ? Kirigami.Units.gridUnit * 8 : undefined
/**
* @brief Extra margin required when anchoring an item on the right.
*
* Normally used for scrollbars.
*/
property int rightAnchorMargin: 0
Layout.fillWidth: true
implicitWidth: mediaSizeHelper.currentSize.width implicitWidth: mediaSizeHelper.currentSize.width
implicitHeight: mediaSizeHelper.currentSize.height implicitHeight: mediaSizeHelper.currentSize.height
QQC2.Button { QQC2.Button {
anchors.right: parent.right anchors.top: root.top
anchors.top: parent.top anchors.topMargin: Kirigami.Units.smallSpacing
anchors.margins: Kirigami.Units.smallSpacing anchors.right: root.right
visible: !_private.hideImage anchors.rightMargin: root.rightAnchorMargin + Kirigami.Units.smallSpacing
visible: !_private.hideImage && !root.editable
icon.name: "view-hidden" icon.name: "view-hidden"
text: i18nc("@action:button", "Hide Image") text: i18nc("@action:button", "Hide Image")
display: QQC2.Button.IconOnly display: QQC2.Button.IconOnly
@@ -64,6 +79,21 @@ Item {
QQC2.ToolTip.visible: hovered QQC2.ToolTip.visible: hovered
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
} }
QQC2.Button {
id: cancelButton
anchors.top: root.top
anchors.topMargin: Kirigami.Units.smallSpacing
anchors.right: root.right
anchors.rightMargin: root.rightAnchorMargin + Kirigami.Units.smallSpacing
visible: root.editable
display: QQC2.AbstractButton.IconOnly
text: i18nc("@action:button", "Remove attachment")
icon.name: "dialog-close"
onClicked: root.Message.contentModel?.removeAttachment()
QQC2.ToolTip.text: text
QQC2.ToolTip.visible: hovered
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
}
Loader { Loader {
id: imageLoader id: imageLoader
@@ -149,8 +179,10 @@ Item {
if (root.componentAttributes.animated) { if (root.componentAttributes.animated) {
_private.imageItem.paused = true; _private.imageItem.paused = true;
} }
root.Message.timeline.interactive = false; if (root.Message.timeline) {
if (!root.componentAttributes.isSticker) { root.Message.timeline.interactive = false;
}
if (!root.componentAttributes.isSticker && !root.editable) {
RoomManager.maximizeMedia(root.eventId); RoomManager.maximizeMedia(root.eventId);
} }
} }

View File

@@ -498,6 +498,7 @@ void ChatBarMessageContentModel::removeAttachment()
mediaRow = 1; mediaRow = 1;
} }
removeComponent(mediaRow); removeComponent(mediaRow);
refocusCurrentComponent();
if (m_room) { if (m_room) {
m_room->cacheForType(m_type)->setAttachmentPath({}); m_room->cacheForType(m_type)->setAttachmentPath({});
} }