diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 967369501..af38740c8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -242,6 +242,7 @@ ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE qml/EditMenu.qml qml/MessageDelegateContextMenu.qml qml/FileDelegateContextMenu.qml + qml/FileDelegateContextMenuMobile.qml qml/MessageSourceSheet.qml qml/ConfirmEncryptionDialog.qml qml/RoomSearchPage.qml diff --git a/src/qml/FileDelegateContextMenuMobile.qml b/src/qml/FileDelegateContextMenuMobile.qml new file mode 100644 index 000000000..9e5c3093b --- /dev/null +++ b/src/qml/FileDelegateContextMenuMobile.qml @@ -0,0 +1,116 @@ +// SPDX-FileCopyrightText: 2019 Black Hat +// SPDX-License-Identifier: GPL-3.0-only + +import QtQuick +import QtQuick.Controls as QQC2 +import Qt.labs.platform + +import org.kde.kirigami as Kirigami + +import org.kde.neochat + +/** + * @brief The menu for media messages. + * + * This component just overloads the actions and nested actions of the base menu + * to what is required for a media item. + * + * @sa DelegateContextMenu + */ +DelegateContextMenu { + id: root + + /** + * @brief The MIME type of the media. + */ + property string mimeType + + /** + * @brief Progress info when downloading files. + * + * @sa Quotient::FileTransferInfo + */ + required property var progressInfo + + // Web search isn't useful for images + enableWebSearch: false + + /** + * @brief The main list of menu item actions. + * + * Each action will be instantiated as a single line in the menu. + */ + property list actions: [ + Kirigami.Action { + text: i18n("Open Externally") + icon.name: "document-open" + onTriggered: { + currentRoom.openEventMediaExternally(root.eventId); + } + }, + Kirigami.Action { + text: i18n("Save As") + icon.name: "document-save" + onTriggered: { + var dialog = saveAsDialog.createObject(QQC2.Overlay.overlay); + dialog.open(); + dialog.currentFile = dialog.folder + "/" + currentRoom.fileNameToDownload(eventId); + } + }, + DelegateContextMenu.ReplyMessageAction {}, + Kirigami.Action { + text: i18n("Copy") + icon.name: "edit-copy" + onTriggered: { + currentRoom.copyEventMedia(root.eventId); + } + }, + Kirigami.Action { + visible: author.id === currentRoom.localMember.id || currentRoom.canSendState("redact") + text: i18n("Remove") + icon.name: "edit-delete-remove" + icon.color: "red" + onTriggered: { + let dialog = applicationWindow().pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'ReasonDialog'), { + title: i18nc("@title:dialog", "Remove Message"), + placeholder: i18nc("@info:placeholder", "Reason for removing this message"), + actionText: i18nc("@action:button 'Remove' as in 'Remove this message'", "Remove"), + icon: "delete" + }, { + title: i18nc("@title:dialog", "Remove Message"), + width: Kirigami.Units.gridUnit * 25 + }); + dialog.accepted.connect(reason => { + currentRoom.redactEvent(root.eventId, reason); + }); + } + }, + DelegateContextMenu.ReportMessageAction {}, + DelegateContextMenu.ShowUserAction {}, + DelegateContextMenu.ViewSourceAction {} + ] + + /** + * @brief The list of menu item actions that have sub-actions. + * + * Each action will be instantiated as a single line that opens a sub menu. + */ + property list nestedActions: [ + ] + + Component { + id: saveAsDialog + FileDialog { + fileMode: FileDialog.SaveFile + folder: NeoChatConfig.lastSaveDirectory.length > 0 ? NeoChatConfig.lastSaveDirectory : StandardPaths.writableLocation(StandardPaths.DownloadLocation) + onAccepted: { + if (!currentFile) { + return; + } + NeoChatConfig.lastSaveDirectory = folder; + NeoChatConfig.save(); + currentRoom.downloadFile(eventId, currentFile); + } + } + } +} diff --git a/src/qml/RoomPage.qml b/src/qml/RoomPage.qml index 16bf96010..2d3b4a4e5 100644 --- a/src/qml/RoomPage.qml +++ b/src/qml/RoomPage.qml @@ -281,15 +281,27 @@ Kirigami.Page { } function onShowFileMenu(eventId, author, messageComponentType, plainText, mimeType, progressInfo, isThread) { - const contextMenu = fileDelegateContextMenu.createObject(root, { - author: author, - eventId: eventId, - plainText: plainText, - mimeType: mimeType, - progressInfo: progressInfo, - isThread: isThread - }); - contextMenu.open(); + if (Kirigami.Settings.isMobile) { + const contextMenu = fileDelegateContextMenuMobile.createObject(root, { + author: author, + eventId: eventId, + plainText: plainText, + mimeType: mimeType, + progressInfo: progressInfo, + isThread: isThread + }); + contextMenu.open(); + } else { + const contextMenu = fileDelegateContextMenu.createObject(root, { + author: author, + eventId: eventId, + plainText: plainText, + mimeType: mimeType, + progressInfo: progressInfo, + isThread: isThread + }); + contextMenu.open(); + } } function onShowMaximizedMedia(index) { @@ -327,6 +339,13 @@ Kirigami.Page { } } + Component { + id: fileDelegateContextMenuMobile + FileDelegateContextMenuMobile { + connection: root.connection + } + } + Component { id: maximizeComponent NeochatMaximizeComponent {