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

334 lines
13 KiB
QML
Raw Normal View History

import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import QtQml.Models 2.2
import QtGraphicalEffects 1.0
import StatusQ.Controls 0.1
import StatusQ.Components 0.1
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import utils 1.0
import shared.status 1.0
Page {
id: root
anchors.fill: parent
Behavior on anchors.bottomMargin { NumberAnimation { duration: 30 }}
property ListModel contactsModel: ListModel { }
property var rootStore
property var emojiPopup: null
ListView {
id: contactsModelListView
anchors.left: parent.left
anchors.right: parent.right
model: root.rootStore.contactsModel
delegate: Item {
property string publicId: model.pubKey
property string name: model.name
property string icon: model.icon
property bool isIdenticon: model.isIdenticon
}
}
Connections {
target: rootStore
onOpenCreateChatChanged: {
if (root.rootStore.openCreateChat) {
for (var i = 0; i < contactsModelListView.count; i ++) {
var entry = contactsModelListView.itemAtIndex(i);
contactsModel.insert(contactsModel.count,
{"publicId": entry.publicId, "name": entry.name,
"icon": entry.icon, "isIdenticon": entry.isIdenticon});
}
} else {
tagSelector.namesModel.clear();
contactsModel.clear();
}
}
}
function createChat() {
if (tagSelector.namesModel.count === 1) {
var ensName = tagSelector.namesModel.get(0).name.includes(".eth") ? tagSelector.namesModel.get(0).name : "";
root.rootStore.chatCommunitySectionModule.createOneToOneChat("", tagSelector.namesModel.get(0).publicId, ensName);
} else {
var groupName = "";
var publicIds = [];
for (var i = 0; i < tagSelector.namesModel.count; i++) {
groupName += (tagSelector.namesModel.get(i).name + (i === tagSelector.namesModel.count - 1 ? "" : "&"));
publicIds.push(tagSelector.namesModel.get(i).publicId);
}
root.rootStore.chatCommunitySectionModule.createGroupChat("",groupName, JSON.stringify(publicIds));
}
chatInput.textInput.clear();
chatInput.textInput.textFormat = TextEdit.PlainText;
chatInput.textInput.textFormat = TextEdit.RichText;
}
visible: (opacity > 0.01)
onVisibleChanged: {
if (!visible) {
tagSelector.namesModel.clear();
}
}
opacity: (root.rootStore.openCreateChat) ? 1.0 : 0.0
Behavior on opacity { NumberAnimation {}}
background: Rectangle {
anchors.fill: parent
color: Theme.palette.statusAppLayout.rightPanelBackgroundColor
}
header: RowLayout {
id: headerRow
width: parent.width
height: tagSelector.height
anchors.top: parent.top
anchors.topMargin: 8
anchors.right: parent.right
anchors.rightMargin: 8
StatusTagSelector {
id: tagSelector
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
Layout.leftMargin: 17
implicitHeight: 44
toLabelText: qsTr("To: ")
warningText: qsTr("USER LIMIT REACHED")
//simulate model filtering, TODO this
//makes more sense to be provided by the backend
//figure how real implementation should look like
property ListModel sortedList: ListModel { }
onTextChanged: {
sortedList.clear();
if (text !== "") {
for (var i = 0; i < contactsModel.count; i++ ) {
var entry = contactsModel.get(i);
if (entry.name.toLowerCase().includes(text.toLowerCase())) {
sortedList.insert(sortedList.count, {"publicId": entry.publicId, "name": entry.name,
"icon": entry.icon, "isIdenticon": entry.isIdenticon});
userListView.model = sortedList;
}
}
} else {
userListView.model = contactsModel;
}
}
}
StatusButton {
id: confirmButton
implicitHeight: 44
enabled: (tagSelector.namesModel.count > 0)
text: "Confirm"
onClicked: {
root.rootStore.createChatInitMessage = chatInput.textInput.text;
root.rootStore.createChatFileUrls = chatInput.fileUrls;
root.createChat();
}
}
}
contentItem: Item {
anchors.fill: parent
anchors.topMargin: headerRow.height + 32
Item {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: chatInput.visible? chatInput.top : parent.bottom
visible: (contactsModel.count > 0)
Component.onCompleted: {
if (visible) {
tagSelector.textEdit.forceActiveFocus();
}
}
StatusBaseText {
id: contactsLabel
font.pixelSize: 15
anchors.left: parent.left
anchors.leftMargin: 8
color: Theme.palette.baseColor1
text: qsTr("Contacts")
}
Control {
width: 360
anchors {
top: contactsLabel.bottom
topMargin: Style.current.halfPadding
bottom: !statusPopupMenuBackgroundContent.visible ? parent.bottom : undefined
}
height: Style.current.padding + (!statusPopupMenuBackgroundContent.visible ? parent.height :
(((userListView.count * 64) > parent.height) ? parent.height : (userListView.count * 64)))
x: (statusPopupMenuBackgroundContent.visible && (tagSelector.namesModel.count > 0) &&
((tagSelector.textEdit.x + Style.current.bigPadding + statusPopupMenuBackgroundContent.width) < parent.width))
? (tagSelector.textEdit.x + Style.current.bigPadding) : 0
background: Rectangle {
id: statusPopupMenuBackgroundContent
anchors.fill: parent
visible: (tagSelector.sortedList.count > 0)
color: Theme.palette.statusPopupMenu.backgroundColor
radius: 8
layer.enabled: true
layer.effect: DropShadow {
width: statusPopupMenuBackgroundContent.width
height: statusPopupMenuBackgroundContent.height
x: statusPopupMenuBackgroundContent.x
visible: statusPopupMenuBackgroundContent.visible
source: statusPopupMenuBackgroundContent
horizontalOffset: 0
verticalOffset: 4
radius: 12
samples: 25
spread: 0.2
color: Theme.palette.dropShadow
}
}
contentItem: ListView {
id: userListView
anchors.fill: parent
anchors.topMargin: 8
anchors.bottomMargin: 8
clip: true
model: contactsModel
ScrollBar.vertical: ScrollBar {
policy: ScrollBar.AsNeeded
}
boundsBehavior: Flickable.StopAtBounds
delegate: Item {
id: wrapper
anchors.right: parent.right
anchors.left: parent.left
height: 64
property bool hovered: false
Rectangle {
id: rectangle
anchors.fill: parent
anchors.rightMargin: Style.current.halfPadding
anchors.leftMargin: Style.current.halfPadding
radius: Style.current.radius
visible: (tagSelector.sortedList.count > 0)
color: (wrapper.hovered) ? Theme.palette.baseColor2 : "transparent"
}
StatusSmartIdenticon {
id: contactImage
anchors.left: parent.left
anchors.leftMargin: Style.current.padding
anchors.verticalCenter: parent.verticalCenter
name: model.name
icon: StatusIconSettings {
width: 28
height: 28
letterSize: 15
}
image: StatusImageSettings {
width: 28
height: 28
source: model.icon
isIdenticon: model.isIdenticon
}
}
StatusBaseText {
id: contactInfo
text: model.name
anchors.right: parent.right
anchors.rightMargin: 8
anchors.left: contactImage.right
anchors.leftMargin: 16
anchors.verticalCenter: parent.verticalCenter
elide: Text.ElideRight
color: Theme.palette.directColor1
font.weight: Font.Medium
font.pixelSize: 15
}
MouseArea {
cursorShape: enabled ? Qt.PointingHandCursor : Qt.ArrowCursor
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent
hoverEnabled: true
onEntered: {
wrapper.hovered = true;
}
onExited: {
wrapper.hovered = false;
}
onClicked: {
tagSelector.insertTag(model.name, model.publicId);
}
}
}
}
}
}
StatusChatInput {
id: chatInput
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
visible: tagSelector.namesModel.count > 0
chatType: tagSelector.namesModel.count == 1? Constants.chatType.oneToOne : Constants.chatType.privateGroupChat
emojiPopup: root.emojiPopup
recentStickers: root.rootStore.stickersModuleInst.recent
stickerPackList: root.rootStore.stickersModuleInst.stickerPacks
onSendTransactionCommandButtonClicked: {
root.rootStore.createChatStartSendTransactionProcess = true;
root.createChat();
}
onReceiveTransactionCommandButtonClicked: {
root.rootStore.createChatStartReceiveTransactionProcess = true;
root.createChat();
}
onStickerSelected: {
root.rootStore.createChatStickerHashId = hashId;
root.rootStore.createChatStickerPackId = packId;
root.createChat();
}
onSendMessage: {
root.rootStore.createChatFileUrls = chatInput.fileUrls;
root.rootStore.createChatInitMessage = chatInput.textInput.text;
root.createChat();
}
}
StatusBaseText {
width: parent.width
height: contentHeight
anchors.centerIn: parent
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
visible: (contactsModel.count === 0)
wrapMode: Text.WordWrap
font.pixelSize: 15
color: Theme.palette.baseColor1
text: qsTr("You can only send direct messages to your Contacts.\n\n
Send a contact request to the person you would like to chat with, you will be able to
chat with them once they have accepted your contact request.")
Component.onCompleted: {
if (visible) {
tagSelector.enabled = false;
}
}
}
}
}