From 7afce01a2339c61456d39db09e1597c0681ee885 Mon Sep 17 00:00:00 2001 From: James Graham Date: Sat, 7 Feb 2026 15:50:18 +0000 Subject: [PATCH] Fold extra send icons when thin for mobile --- src/chatbar/ChatBarCore.qml | 1 + src/chatbar/RichEditBar.qml | 10 --- src/chatbar/SendBar.qml | 167 ++++++++++++++++++++++++------------ 3 files changed, 113 insertions(+), 65 deletions(-) diff --git a/src/chatbar/ChatBarCore.qml b/src/chatbar/ChatBarCore.qml index 4f9ad0078..a15af0195 100644 --- a/src/chatbar/ChatBarCore.qml +++ b/src/chatbar/ChatBarCore.qml @@ -110,6 +110,7 @@ QQC2.Control { SendBar { room: root.room contentModel: root.model + maxAvailableWidth: root.maxAvailableWidth } } } diff --git a/src/chatbar/RichEditBar.qml b/src/chatbar/RichEditBar.qml index 7df50b391..fec932c04 100644 --- a/src/chatbar/RichEditBar.qml +++ b/src/chatbar/RichEditBar.qml @@ -414,14 +414,4 @@ RowLayout { } } } - - Component { - id: locationChooser - LocationChooser {} - } - - Component { - id: newPollDialog - NewPollDialog {} - } } diff --git a/src/chatbar/SendBar.qml b/src/chatbar/SendBar.qml index 78b509273..38c8c5a68 100644 --- a/src/chatbar/SendBar.qml +++ b/src/chatbar/SendBar.qml @@ -11,6 +11,8 @@ import org.kde.kirigami as Kirigami import org.kde.neochat.libneochat as LibNeoChat import org.kde.neochat.messagecontent as MessageContent +pragma ComponentBehavior: Bound + RowLayout { id: root @@ -23,60 +25,128 @@ RowLayout { required property MessageContent.ChatBarMessageContentModel contentModel + required property real maxAvailableWidth + + readonly property real overflowWidth: Kirigami.Units.gridUnit * 30 + + function openLocationChooser(): void { + Qt.createComponent('org.kde.neochat.chatbar', 'LocationChooser').createObject(QQC2.ApplicationWindow.overlay, { + room: root.room + }).open(); + } + + function openNewPollDialog(): void { + Qt.createComponent('org.kde.neochat.chatbar', 'NewPollDialog').createObject(QQC2.Overlay.overlay, { + room: root.room + }).open(); + } + + function addAttachment(): void { + if (!root.contentModel.hasRichFormatting) { + if (LibNeoChat.Clipboard.hasImage) { + attachDialog(); + } else { + fileDialog(); + } + return; + } + + let warningDialog = Qt.createComponent('org.kde.kirigami', 'PromptDialog').createObject(QQC2.Overlay.overlay, { + dialogType: Kirigami.PromptDialog.Warning, + title: attachmentButton.text, + subtitle: i18nc("@Warning: that any rich text in the chat bar will be switched for the plain text equivalent.", "Attachments can only have plain text captions, all rich formatting will be removed"), + standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel + }); + warningDialog.onAccepted.connect(() => { + if (LibNeoChat.Clipboard.hasImage) { + attachmentButton.attachDialog(); + } else { + attachmentButton.fileDialog(); + } + }); + warningDialog.open(); + } + + function attachDialog(): void { + let dialog = Qt.createComponent('org.kde.neochat.chatbar', 'AttachDialog').createObject(QQC2.Overlay.overlay) as AttachDialog; + dialog.anchors.centerIn = QQC2.Overlay.overlay; + dialog.chosen.connect(path => root.contentModel.addAttachment(path)); + dialog.open(); + } + + function fileDialog(): void { + let dialog = Qt.createComponent('org.kde.neochat.libneochat', 'OpenFileDialog').createObject(QQC2.Overlay.overlay, { + parentWindow: Window.window, + currentFolder: StandardPaths.standardLocations(StandardPaths.HomeLocation)[0] + }); + dialog.chosen.connect(path => root.contentModel.addAttachment(path)); + dialog.open(); + } + Kirigami.Separator { Layout.fillHeight: true } QQC2.ToolButton { - id: attachmentButton + id: compressedExtraSendButton + property QQC2.Menu overflowMenu - property bool isBusy: root.room && root.room.hasFileUploading - - visible: !root.contentModel.hasAttachment && (root.contentModel?.type ?? true) === LibNeoChat.ChatBarType.Room - icon.name: "mail-attachment" - text: i18nc("@action:button", "Attach an image or file") + visible: root.maxAvailableWidth < root.overflowWidth && (root.contentModel?.type ?? true) === LibNeoChat.ChatBarType.Room + icon.name: "overflow-menu" + enabled: root.chatButtonHelper.richFormatEnabled + text: i18nc("@action:button", "Format Text") display: QQC2.AbstractButton.IconOnly - + checkable: true onClicked: { - if (!root.contentModel.hasRichFormatting) { - if (LibNeoChat.Clipboard.hasImage) { - attachDialog(); - } else { - fileDialog(); + if (!checked) { + if (overflowMenu) { + overflowMenu.close(); } return; } - let warningDialog = Qt.createComponent('org.kde.kirigami', 'PromptDialog').createObject(QQC2.Overlay.overlay, { - dialogType: Kirigami.PromptDialog.Warning, - title: attachmentButton.text, - subtitle: i18nc("@Warning: that any rich text in the chat bar will be switched for the plain text equivalent.", "Attachments can only have plain text captions, all rich formatting will be removed"), - standardButtons: Kirigami.Dialog.Ok | Kirigami.Dialog.Cancel + overflowMenu = compressedExtraSendMenu.createObject(compressedExtraSendButton) + overflowMenu.onClosed.connect(() => { + overflowMenu = null; }); - warningDialog.onAccepted.connect(() => { - if (LibNeoChat.Clipboard.hasImage) { - attachmentButton.attachDialog(); - } else { - attachmentButton.fileDialog(); + overflowMenu.open(); + } + + Component { + id: compressedExtraSendMenu + QQC2.Menu { + y: -implicitHeight + + QQC2.MenuItem { + visible: !root.contentModel.hasAttachment + icon.name: "mail-attachment" + text: i18nc("@action:button", "Attach an image or file") + onTriggered: root.addAttachment() } - }); - warningDialog.open(); + QQC2.MenuItem { + icon.name: "globe" + text: i18nc("@action:button", "Send a Location") + onTriggered: root.openLocationChooser() + } + QQC2.MenuItem { + icon.name: "amarok_playcount" + text: i18nc("@action:button", "Create a Poll") + onTriggered: root.openNewPollDialog(); + } + } } - function attachDialog(): void { - let dialog = Qt.createComponent('org.kde.neochat.chatbar', 'AttachDialog').createObject(QQC2.Overlay.overlay) as AttachDialog; - dialog.anchors.centerIn = QQC2.Overlay.overlay; - dialog.chosen.connect(path => root.contentModel.addAttachment(path)); - dialog.open(); - } + QQC2.ToolTip.text: text + QQC2.ToolTip.visible: hovered + QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay + } + QQC2.ToolButton { + id: attachmentButton + visible: !root.contentModel.hasAttachment && (root.contentModel?.type ?? true) === LibNeoChat.ChatBarType.Room && root.maxAvailableWidth >= root.overflowWidth + icon.name: "mail-attachment" + text: i18nc("@action:button", "Attach an image or file") + display: QQC2.AbstractButton.IconOnly - function fileDialog(): void { - let dialog = Qt.createComponent('org.kde.neochat.libneochat', 'OpenFileDialog').createObject(QQC2.Overlay.overlay, { - parentWindow: Window.window, - currentFolder: StandardPaths.standardLocations(StandardPaths.HomeLocation)[0] - }); - dialog.chosen.connect(path => root.contentModel.addAttachment(path)); - dialog.open(); - } + onClicked: root.addAttachment() QQC2.ToolTip.visible: hovered QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay @@ -84,43 +154,30 @@ RowLayout { } QQC2.ToolButton { id: mapButton - visible: (root.contentModel?.type ?? true) === LibNeoChat.ChatBarType.Room + visible: (root.contentModel?.type ?? true) === LibNeoChat.ChatBarType.Room && root.maxAvailableWidth >= root.overflowWidth icon.name: "globe" - property bool isBusy: false text: i18nc("@action:button", "Send a Location") display: QQC2.AbstractButton.IconOnly - onClicked: { - locationChooser.createObject(QQC2.ApplicationWindow.overlay, { - room: root.room - }).open(); - } + onClicked: root.openLocationChooser(); QQC2.ToolTip.visible: hovered QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay QQC2.ToolTip.text: text } QQC2.ToolButton { id: pollButton - visible: (root.contentModel?.type ?? true) === LibNeoChat.ChatBarType.Room + visible: (root.contentModel?.type ?? true) === LibNeoChat.ChatBarType.Room && root.maxAvailableWidth >= root.overflowWidth icon.name: "amarok_playcount" - property bool isBusy: false text: i18nc("@action:button", "Create a Poll") display: QQC2.AbstractButton.IconOnly - onClicked: { - newPollDialog.createObject(QQC2.Overlay.overlay, { - room: root.room - }).open(); - } + onClicked: root.openNewPollDialog(); QQC2.ToolTip.visible: hovered QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay QQC2.ToolTip.text: text } QQC2.ToolButton { id: sendButton - - property bool isBusy: false - icon.name: "document-send" text: i18nc("@action:button", "Send message") display: QQC2.AbstractButton.IconOnly