status-desktop/ui/app/AppLayouts/Chat/views/ChatContentView.qml

254 lines
9.7 KiB
QML
Raw Normal View History

import QtQuick 2.15
import QtQml 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1 as StatusQUtils
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import utils 1.0
import shared 1.0
import shared.popups 1.0
import shared.status 1.0
import shared.controls 1.0
import shared.views.chat 1.0
import "../helpers"
import "../controls"
import "../popups"
import "../panels"
import "../../Wallet"
import "../stores"
ColumnLayout {
id: root
objectName: "chatContentViewColumn"
spacing: 0
// Important:
// Each chat/channel has its own ChatContentModule
property var chatContentModule
property var chatSectionModule
property var rootStore
property var contactsStore
property bool isActiveChannel: false
property string chatId
property int chatType: Constants.chatType.unknown
readonly property alias chatMessagesLoader: chatMessagesLoader
property var emojiPopup
property var stickersPopup
property UsersStore usersStore: UsersStore {}
onChatContentModuleChanged: if (!!chatContentModule) {
root.usersStore.usersModule = root.chatContentModule.usersModule
}
signal openAppSearch()
signal openStickerPackPopup(string stickerPackId)
property Component sendTransactionNoEnsModal
property Component receiveTransactionModal
property Component sendTransactionWithEnsModal
property bool isBlocked: false
property bool isUserAllowedToSendMessage: root.rootStore.isUserAllowedToSendMessage
property string chatInputPlaceholder: root.rootStore.chatInputPlaceHolderText
property bool stickersLoaded: false
Loader {
Layout.fillWidth: true
active: root.isBlocked
visible: active
sourceComponent: StatusBanner {
type: StatusBanner.Type.Danger
statusText: qsTr("Blocked")
}
}
readonly property var messageStore: MessageStore {
messageModule: chatContentModule ? chatContentModule.messagesModule : null
chatSectionModule: root.rootStore.chatCommunitySectionModule
}
QtObject {
id: d
readonly property string blockedText: qsTr("This user has been blocked.")
function showReplyArea(messageId) {
let obj = messageStore.getMessageByIdAsJson(messageId)
if (!obj) {
return
}
if (inputAreaLoader.item) {
inputAreaLoader.item.chatInput.showReplyArea(messageId, obj.senderDisplayName, obj.messageText, obj.contentType, obj.messageImage, obj.albumMessageImages, obj.albumImagesCount, obj.sticker)
}
}
}
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
Loader {
id: chatMessagesLoader
Layout.fillWidth: true
Layout.fillHeight: true
sourceComponent: ChatMessagesView {
chatContentModule: root.chatContentModule
rootStore: root.rootStore
contactsStore: root.contactsStore
messageStore: root.messageStore
emojiPopup: root.emojiPopup
stickersPopup: root.stickersPopup
usersStore: root.usersStore
stickersLoaded: root.stickersLoaded
chatId: root.chatId
isOneToOne: root.chatType === Constants.chatType.oneToOne
isContactBlocked: root.isBlocked
isChatBlocked: root.isBlocked || !root.isUserAllowedToSendMessage
channelEmoji: !chatContentModule ? "" : (chatContentModule.chatDetails.emoji || "")
isActiveChannel: root.isActiveChannel
onShowReplyArea: (messageId, senderId) => {
d.showReplyArea(messageId)
}
onOpenStickerPackPopup: {
root.openStickerPackPopup(stickerPackId);
}
onEditModeChanged: {
if (!editModeOn && inputAreaLoader.item)
inputAreaLoader.item.chatInput.forceInputActiveFocus()
}
}
}
Loader {
id: inputAreaLoader
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.fillWidth: true
active: root.isActiveChannel
asynchronous: true
property string preservedText
Binding on preservedText {
when: inputAreaLoader.item != null
value: inputAreaLoader.item ? inputAreaLoader.item.chatInput.textInput.text : inputAreaLoader.preservedText
restoreMode: Binding.RestoreNone
delayed: true
}
// FIXME: `StatusChatInput` is way too heavy
// see: https://github.com/status-im/status-desktop/pull/10343#issuecomment-1515103756
sourceComponent: Item {
id: inputArea
implicitHeight: chatInput.implicitHeight
+ chatInput.anchors.topMargin
+ chatInput.anchors.bottomMargin
readonly property alias chatInput: chatInput
StatusChatInput {
id: chatInput
anchors.fill: parent
anchors.margins: Style.current.smallPadding
// We enable the component if the contact is blocked, because if we disable it, the `Unban` button
// becomes disabled. All the local components inside already disable themselves when blocked
enabled: root.isBlocked ||
(root.rootStore.sectionDetails.joined && !root.rootStore.sectionDetails.amIBanned &&
root.isUserAllowedToSendMessage)
store: root.rootStore
usersStore: root.usersStore
textInput.text: inputAreaLoader.preservedText
textInput.placeholderText: root.isBlocked ? d.blockedText : root.chatInputPlaceholder
emojiPopup: root.emojiPopup
stickersPopup: root.stickersPopup
isContactBlocked: root.isBlocked
isActiveChannel: root.isActiveChannel
anchors.bottom: parent.bottom
chatType: root.chatType
suggestions.suggestionFilter.addSystemSuggestions: chatType === Constants.chatType.communityChat
Binding on chatInputPlaceholder {
when: root.isBlocked
value: d.blockedText
}
Binding on chatInputPlaceholder {
when: !root.rootStore.sectionDetails.joined || root.rootStore.sectionDetails.amIBanned
value: qsTr("You need to join this community to send messages")
}
onSendTransactionCommandButtonClicked: {
if(!chatContentModule) {
console.debug("error on sending transaction command - chat content module is not set")
return
}
if (Utils.isEnsVerified(chatContentModule.getMyChatId())) {
Global.openPopup(root.sendTransactionWithEnsModal)
} else {
Global.openPopup(root.sendTransactionNoEnsModal)
}
}
onReceiveTransactionCommandButtonClicked: {
Global.openPopup(root.receiveTransactionModal)
}
onStickerSelected: {
root.rootStore.sendSticker(chatContentModule.getMyChatId(),
hashId,
chatInput.isReply ? chatInput.replyMessageId : "",
packId,
url)
}
onSendMessage: {
if (!chatContentModule) {
console.debug("error on sending message - chat content module is not set")
return
}
if(root.rootStore.sendMessage(chatContentModule.getMyChatId(),
event,
chatInput.getTextWithPublicKeys(),
chatInput.isReply? chatInput.replyMessageId : "",
chatInput.fileUrlsAndSources
))
{
Global.playSendMessageSound()
chatInput.textInput.clear();
chatInput.textInput.textFormat = TextEdit.PlainText;
chatInput.textInput.textFormat = TextEdit.RichText;
}
}
onUnblockChat: {
chatContentModule.unblockChat()
}
onKeyUpPress: messageStore.setEditModeOnLastMessage(root.rootStore.userProfileInst.pubKey)
Component.onCompleted: {
Qt.callLater(() => {
forceInputActiveFocus()
textInput.cursorPosition = textInput.length
})
}
}
}
}
}
}