import QtQuick 2.13 import QtQuick.Controls 2.13 import QtQuick.Layouts 1.13 import Qt.labs.platform 1.1 import utils 1.0 import StatusQ.Popups 0.1 import shared.popups 1.0 import shared.controls.chat.menuItems 1.0 import AppLayouts.Communities.popups 1.0 StatusMenu { id: root property string currentFleet: "" property bool isCommunityChat: false property bool amIChatAdmin: false property string chatId: "" property string chatName: "" property string chatDescription: "" property string chatEmoji: "" property string chatColor: "" property string chatIcon: "" property int chatType: -1 property bool chatMuted: false property int channelPosition: -1 property string chatCategoryId: "" property var emojiPopup property bool showDebugOptions: false signal displayProfilePopup(string publicKey) signal requestAllHistoricMessages(string chatId) signal unmuteChat(string chatId) signal muteChat(string chatId, int interval) signal markAllMessagesRead(string chatId) signal clearChatHistory(string chatId) signal downloadMessages(string file) signal deleteCommunityChat(string chatId) signal leaveChat(string chatId) signal updateGroupChatDetails(string chatId, string groupName, string groupColor, string groupImage) signal createCommunityChannel(string chatId, string newName, string newDescription, string newEmoji, string newColor) signal editCommunityChannel(string chatId, string newName, string newDescription, string newEmoji, string newColor, string newCategory) signal requestMoreMessages(string chatId) signal addRemoveGroupMember() width: root.amIChatAdmin && (root.chatType === Constants.chatType.privateGroupChat) ? 207 : implicitWidth ViewProfileMenuItem { enabled: root.chatType === Constants.chatType.oneToOne onTriggered: root.displayProfilePopup(root.chatId) } StatusAction { text: root.amIChatAdmin ? qsTr("Add / remove from group") : qsTr("Add to group") icon.name: "add-to-dm" enabled: (root.chatType === Constants.chatType.privateGroupChat) onTriggered: { root.addRemoveGroupMember() } } StatusAction { text: qsTr("Copy channel link") icon.name: "copy" enabled: root.isCommunityChat onTriggered: { const link = Utils.getCommunityChannelShareLinkWithChatId(root.chatId) Utils.copyToClipboard(link) } } StatusMenuSeparator { visible: root.chatType === Constants.chatType.oneToOne || root.chatType === Constants.chatType.privateGroupChat || root.isCommunityChat } StatusAction { objectName: "editNameAndImageMenuItem" text: qsTr("Edit name and image") icon.name: "edit_pencil" enabled: root.chatType === Constants.chatType.privateGroupChat onTriggered: { Global.openPopup(renameGroupPopupComponent, { activeGroupName: root.chatName, activeGroupColor: root.chatColor, activeGroupImageData: root.chatIcon }); } } Component { id: renameGroupPopupComponent RenameGroupPopup { onUpdateGroupChatDetails: { root.updateGroupChatDetails(root.chatId, groupName, groupColor, groupImage) close() } } } MuteChatMenuItem { enabled: !root.chatMuted isCommunityChat: root.isCommunityChat onMuteTriggered: { root.muteChat(root.chatId, interval) } } StatusAction { enabled: root.chatMuted text: root.isCommunityChat ? qsTr("Unmute Channel") : qsTr("Unmute Chat") icon.name: "notification" onTriggered: { root.unmuteChat(root.chatId) } } StatusAction { objectName: "chatMarkAsReadMenuItem" text: qsTr("Mark as Read") icon.name: "checkmark-circle" onTriggered: { root.markAllMessagesRead(root.chatId) } } StatusAction { objectName: "chatFetchMessagesMenuItem" text: qsTr("Fetch messages") icon.name: "download" enabled: root.showDebugOptions onTriggered: { root.requestMoreMessages(root.chatId) } } StatusAction { objectName: "editChannelMenuItem" text: qsTr("Edit Channel") icon.name: "edit" enabled: root.isCommunityChat && root.amIChatAdmin onTriggered: { Global.openPopup(editChannelPopup, { isEdit: true, channelName: root.chatName, channelDescription: root.chatDescription, channelEmoji: root.chatEmoji, channelColor: root.chatColor, categoryId: root.chatCategoryId }); } } Component { id: editChannelPopup CreateChannelPopup { anchors.centerIn: parent isEdit: true isDeleteable: root.isCommunityChat emojiPopup: root.emojiPopup onCreateCommunityChannel: { root.createCommunityChannel(root.chatId, chName, chDescription, chEmoji, chColor); } onEditCommunityChannel: { root.editCommunityChannel(root.chatId, chName, chDescription, chEmoji, chColor, chCategoryId); } onDeleteCommunityChannel: { Global.openPopup(deleteChatConfirmationDialogComponent) close() } onClosed: { destroy() } } } StatusAction { text: qsTr("Download") enabled: localAccountSensitiveSettings.downloadChannelMessagesEnabled icon.name: "download" onTriggered: downloadDialog.open() } StatusMenuSeparator { visible: clearHistoryMenuItem.enabled || deleteOrLeaveMenuItem.enabled } StatusAction { id: clearHistoryMenuItem objectName: "clearHistoryMenuItem" text: qsTr("Clear History") icon.name: "close-circle" type: deleteOrLeaveMenuItem.enabled ? StatusAction.Type.Normal : StatusAction.Type.Danger onTriggered: { Global.openPopup(clearChatConfirmationDialogComponent); } } StatusAction { id: deleteOrLeaveMenuItem objectName: "deleteOrLeaveMenuItem" text: { if (root.isCommunityChat) { return qsTr("Delete Channel") } if (root.chatType === Constants.chatType.privateGroupChat) { return qsTr("Leave group") } return root.chatType === Constants.chatType.oneToOne ? qsTr("Close Chat") : qsTr("Leave Chat") } icon.name: root.chatType === Constants.chatType.oneToOne || root.isCommunityChat ? "delete" : "arrow-left" icon.width: root.chatType === Constants.chatType.oneToOne || root.isCommunityChat ? 18 : 14 type: StatusAction.Type.Danger onTriggered: { if (root.chatType === Constants.chatType.privateGroupChat) { Global.openPopup(leaveGroupConfirmationDialogComponent); } else { Global.openPopup(deleteChatConfirmationDialogComponent); } } enabled: !root.isCommunityChat || root.amIChatAdmin } FileDialog { id: downloadDialog acceptLabel: qsTr("Save") fileMode: FileDialog.SaveFile title: qsTr("Download messages") currentFile: StandardPaths.writableLocation(StandardPaths.DocumentsLocation) + "/messages.json" defaultSuffix: "json" onAccepted: { root.downloadMessages(downloadDialog.currentFile) } } Component { id: clearChatConfirmationDialogComponent ConfirmationDialog { confirmButtonObjectName: "clearChatConfirmationDialogClearButton" headerSettings.title: qsTr("Clear chat history") confirmationText: qsTr("Are you sure you want to clear chat history for %1?").arg(root.chatName) confirmButtonLabel: qsTr("Clear") showCancelButton: true cancelBtnType: "normal" onClosed: { destroy() } onCancelButtonClicked: { close() } onConfirmButtonClicked: { root.clearChatHistory(root.chatId) close() } } } Component { id: leaveGroupConfirmationDialogComponent ConfirmationDialog { confirmButtonObjectName: "leaveGroupConfirmationDialogLeaveButton" headerSettings.title: qsTr("Leave group") confirmationText: qsTr("Are you sure you want to leave group chat %1?").arg(root.chatName) confirmButtonLabel: qsTr("Leave") showCancelButton: true cancelBtnType: "normal" onClosed: { destroy() } onCancelButtonClicked: { close() } onConfirmButtonClicked: { root.leaveChat(root.chatId) close() } } } Component { id: deleteChatConfirmationDialogComponent ConfirmationDialog { confirmButtonObjectName: "deleteChatConfirmationDialogDeleteButton" headerSettings.title: root.isCommunityChat ? qsTr("Delete #%1").arg(root.chatName) : root.chatType === Constants.chatType.oneToOne ? qsTr("Close chat") : qsTr("Leave chat") confirmButtonLabel: root.isCommunityChat ? qsTr("Delete") : headerSettings.title confirmationText: root.isCommunityChat ? qsTr("Are you sure you want to delete #%1 channel?").arg(root.chatName) : root.chatType === Constants.chatType.oneToOne ? qsTr("Are you sure you want to close this chat?"): qsTr("Are you sure you want to leave this chat?") showCancelButton: true cancelBtnType: "normal" onClosed: { destroy() } onCancelButtonClicked: { close() } onConfirmButtonClicked: { if(root.isCommunityChat) root.deleteCommunityChat(root.chatId) else root.leaveChat(root.chatId) close() } } } }