From 9cc361c40a33e227ee5a3058c6edc59be2abd1b2 Mon Sep 17 00:00:00 2001 From: Alexandra Betouni <31625338+alexandraB99@users.noreply.github.com> Date: Fri, 1 Oct 2021 18:58:36 +0300 Subject: [PATCH] refactor(desktop/chat) Moving chat to new architecture Closes #3710 --- ui/app/AppLayouts/Browser/BrowserLayout.qml | 3 +- .../Browser/popups/BrowserSettingsMenu.qml | 4 +- .../Browser/popups/FavoriteMenu.qml | 3 +- .../ChatComponents/ActivityChannelBadge.qml | 103 ---------- .../ChatComponents/ChatCommandButton.qml | 70 ------- .../ChatComponents/ChatInputButton.qml | 62 ------ .../MessageComponents/MessageMouseArea.qml | 35 ---- .../SendTransactionButton.qml | 77 ------- .../MessageComponents/UserImage.qml | 55 ----- .../Chat/ChatColumn/MessageComponents/qmldir | 1 - ui/app/AppLayouts/Chat/ChatColumn/qmldir | 8 - .../AppLayouts/Chat/ChatColumn/samples/qmldir | 3 - ui/app/AppLayouts/Chat/ChatLayout.qml | 44 ++-- .../MembershipRequestsButton.qml | 70 ------- ui/app/AppLayouts/Chat/ContactsColumn/qmldir | 2 - .../Chat/components/ChannelIcon.qml | 73 ------- ui/app/AppLayouts/Chat/components/qmldir | 13 -- .../Chat/{components => controls}/Contact.qml | 0 .../DateGroup.qml | 5 +- .../EmojiReaction.qml | 5 +- .../MessageBorder.qml | 4 +- .../Chat/controls/MessageMouseArea.qml | 51 +++++ .../RectangleCorner.qml | 1 + .../MessageComponents => controls}/Retry.qml | 12 +- .../Chat/controls/SendTransactionButton.qml | 72 +++++++ .../SentMessage.qml | 2 +- .../StateBubble.qml | 10 +- .../SuggestedChannel.qml | 5 +- .../User.qml => controls/UserDelegate.qml} | 27 +-- ui/app/AppLayouts/Chat/controls/UserImage.qml | 60 ++++++ .../UsernameLabel.qml | 27 ++- .../controls/activityCenter/ChannelBadge.qml | 57 ++++++ .../activityCenter/CommunityBadge.qml | 119 +++++++++++ .../activityCenter/ReplyComponent.qml | 45 +++++ .../communities}/MembershipRadioButton.qml | 0 .../messages/FetchMoreMessagesButton.qml | 79 ++++++++ .../Chat/controls/messages/GapComponent.qml | 52 +++++ .../Chat/{data => helpers}/channelList.js | 0 .../Chat/{components => helpers}/emojiList.js | 0 .../AcceptRejectOptionsButtonsPanel.qml} | 0 .../ActivityCenterPopupTopBarPanel.qml} | 51 +++-- .../Chat/panels/ActivityChannelBadgePanel.qml | 90 +++++++++ .../AudioPlayerPanel.qml} | 4 +- .../BadgeContentPanel.qml} | 0 .../ChatButtonsPanel.qml} | 13 +- .../ChatReplyPanel.qml} | 52 +++-- .../ChatRequestMessagePanel.qml} | 11 +- .../ClosedEmptyPanel.qml} | 7 - .../ContactListPanel.qml} | 2 + .../ContactRequestPanel.qml} | 13 +- .../EmojiReactionsPanel.qml} | 58 +----- .../EmptyChatPanel.qml} | 13 +- .../EmptyViewPanel.qml} | 14 +- .../FetchMoreMessagesMenuPanel.qml} | 3 + .../InvitationBubblePanel.qml} | 10 +- .../MessageContextMenuPanel.qml} | 7 +- .../StatusUpdatePanel.qml} | 65 +++++- .../SuggestedChannelsPanel.qml} | 19 +- .../SuggestionBoxPanel.qml} | 2 +- .../SuggestionFilterPanel.qml} | 1 - .../TransactionBubblePanel.qml} | 37 +++- .../UserList.qml => panels/UserListPanel.qml} | 14 +- .../BackUpCommuntyBannerPanel.qml} | 8 +- ...mmunityProfilePopupInviteFriendsPanel.qml} | 9 +- ...CommunityProfilePopupMembersListPanel.qml} | 7 +- .../CommunityProfilePopupOverviewPanel.qml} | 0 .../communities/CommunityUserListPanel.qml} | 19 +- .../CommunityWelcomeBannerPanel.qml} | 7 +- .../ActivityCenterPopup.qml} | 46 ++++- .../ChatCommandModal.qml | 13 +- .../ChooseBrowserPopup.qml | 0 .../ContactRequestsPopup.qml | 12 +- .../{components => popups}/GroupChatPopup.qml | 5 +- .../{components => popups}/GroupInfoPopup.qml | 4 +- .../{components => popups}/NicknamePopup.qml | 0 .../PinnedMessagesPopup.qml | 54 ++++- .../PrivateChatPopup.qml | 0 .../{components => popups}/ProfilePopup.qml | 0 .../PublicChatPopup.qml | 9 +- .../RenameGroupPopup.qml | 0 .../SelectAccountModal.qml | 8 +- .../SignTransactionModal.qml | 13 +- .../AccessExistingCommunityPopup.qml | 10 +- .../community}/CommunitiesPopup.qml | 2 +- .../community}/CommunityDetailPopup.qml | 2 +- .../community}/CommunityProfilePopup.qml | 8 +- .../community}/CreateCategoryPopup.qml | 4 +- .../community}/CreateChannelPopup.qml | 0 .../community}/CreateCommunityPopup.qml | 6 +- .../InviteFriendsToCommunityPopup.qml | 8 +- .../community}/MembershipRequestsPopup.qml | 2 +- .../community}/MembershipRequirementPopup.qml | 0 .../community}/TransferOwnershipPopup.qml | 4 +- ui/app/AppLayouts/Chat/qmldir | 4 - .../Chat/{data => stores}/EmojiReactions.qml | 0 .../samples => stores}/MessagesData.qml | 0 ui/app/AppLayouts/Chat/stores/RootStore.qml | 53 +++++ .../samples => stores}/StickerData.qml | 0 .../samples => stores}/StickerPackData.qml | 0 .../AcceptTransactionView.qml} | 11 +- .../ActivityCenterGroupRequest.qml | 24 ++- .../ActivityCenterMessageComponentView.qml} | 120 +++++++++-- .../ChannelIdentifierView.qml} | 4 +- .../ChatColumnView.qml} | 60 +++--- .../ChatContextMenuView.qml} | 1 - .../ChatMessagesView.qml} | 68 +++++-- .../ChatText.qml => views/ChatTextView.qml} | 11 +- .../ChatTime.qml => views/ChatTimeView.qml} | 10 +- .../CommunityColumnView.qml} | 17 +- .../CompactMessageView.qml} | 177 +++++++++++++---- .../ContactsColumnView.qml} | 18 +- .../LinksMessageView.qml} | 12 +- .../Message.qml => views/MessageView.qml} | 118 ++++++----- .../NormalMessageView.qml} | 136 ++++++++++--- ui/app/AppLayouts/Profile/ProfileLayout.qml | 4 +- .../Profile/Sections/Contacts/ContactList.qml | 88 ++++++++ .../Profile/panels/ContactsListPanel.qml | 2 +- .../Profile/views/AppearanceView.qml | 21 +- .../AppLayouts/Profile/views/EnsListView.qml | 33 ++- ui/app/AppLayouts/Profile/views/EnsView.qml | 2 + ui/app/AppLayouts/Timeline/TimelineLayout.qml | 52 ++++- ui/app/AppLayouts/stores/MessageStore.qml | 188 ++++++++++++++++++ ui/app/AppLayouts/stores/RootStore.qml | 9 + ui/app/AppMain.qml | 15 +- ui/imports/utils/Utils.qml | 11 + .../LoadingAnimation.qml | 3 +- ui/shared/panels/NotificationWindow.qml | 2 - ui/shared/status/StatusChatInput.qml | 5 +- ui/shared/status/StatusSticker.qml | 2 +- ui/shared/status/StatusStickerMarket.qml | 3 +- .../status/StatusStickerPackClickPopup.qml | 3 +- ui/shared/status/StatusStickersPopup.qml | 3 +- ui/shared/views/ExistingContacts.qml | 3 +- ui/shared/views/SearchResults.qml | 5 +- 134 files changed, 2139 insertions(+), 1164 deletions(-) delete mode 100644 ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityChannelBadge.qml delete mode 100644 ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandButton.qml delete mode 100644 ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatInputButton.qml delete mode 100644 ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/MessageMouseArea.qml delete mode 100644 ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SendTransactionButton.qml delete mode 100644 ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/UserImage.qml delete mode 100644 ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/qmldir delete mode 100644 ui/app/AppLayouts/Chat/ChatColumn/qmldir delete mode 100644 ui/app/AppLayouts/Chat/ChatColumn/samples/qmldir delete mode 100644 ui/app/AppLayouts/Chat/CommunityComponents/MembershipRequestsButton.qml delete mode 100644 ui/app/AppLayouts/Chat/ContactsColumn/qmldir delete mode 100644 ui/app/AppLayouts/Chat/components/ChannelIcon.qml delete mode 100644 ui/app/AppLayouts/Chat/components/qmldir rename ui/app/AppLayouts/Chat/{components => controls}/Contact.qml (100%) rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents => controls}/DateGroup.qml (97%) rename ui/app/AppLayouts/Chat/{components => controls}/EmojiReaction.qml (87%) rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents => controls}/MessageBorder.qml (98%) create mode 100644 ui/app/AppLayouts/Chat/controls/MessageMouseArea.qml rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents => controls}/RectangleCorner.qml (91%) rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents => controls}/Retry.qml (63%) create mode 100644 ui/app/AppLayouts/Chat/controls/SendTransactionButton.qml rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents => controls}/SentMessage.qml (81%) rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents/TransactionComponents => controls}/StateBubble.qml (94%) rename ui/app/AppLayouts/Chat/{components => controls}/SuggestedChannel.qml (90%) rename ui/app/AppLayouts/Chat/{ChatColumn/User.qml => controls/UserDelegate.qml} (90%) create mode 100644 ui/app/AppLayouts/Chat/controls/UserImage.qml rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents => controls}/UsernameLabel.qml (62%) create mode 100644 ui/app/AppLayouts/Chat/controls/activityCenter/ChannelBadge.qml create mode 100644 ui/app/AppLayouts/Chat/controls/activityCenter/CommunityBadge.qml create mode 100644 ui/app/AppLayouts/Chat/controls/activityCenter/ReplyComponent.qml rename ui/app/AppLayouts/Chat/{CommunityComponents => controls/communities}/MembershipRadioButton.qml (100%) create mode 100644 ui/app/AppLayouts/Chat/controls/messages/FetchMoreMessagesButton.qml create mode 100644 ui/app/AppLayouts/Chat/controls/messages/GapComponent.qml rename ui/app/AppLayouts/Chat/{data => helpers}/channelList.js (100%) rename ui/app/AppLayouts/Chat/{components => helpers}/emojiList.js (100%) rename ui/app/AppLayouts/Chat/{components/AcceptRejectOptionsButtons.qml => panels/AcceptRejectOptionsButtonsPanel.qml} (100%) rename ui/app/AppLayouts/Chat/{ChatColumn/ChatComponents/ActivityCenterTopBar.qml => panels/ActivityCenterPopupTopBarPanel.qml} (75%) create mode 100644 ui/app/AppLayouts/Chat/panels/ActivityChannelBadgePanel.qml rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents/AudioPlayer.qml => panels/AudioPlayerPanel.qml} (97%) rename ui/app/AppLayouts/Chat/{components/BadgeContent.qml => panels/BadgeContentPanel.qml} (100%) rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents/ChatButtons.qml => panels/ChatButtonsPanel.qml} (93%) rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents/ChatReply.qml => panels/ChatReplyPanel.qml} (81%) rename ui/app/AppLayouts/Chat/{ChatColumn/ChatComponents/ChatRequestMessage.qml => panels/ChatRequestMessagePanel.qml} (87%) rename ui/app/AppLayouts/Chat/{ContactsColumn/ClosedEmptyView.qml => panels/ClosedEmptyPanel.qml} (85%) rename ui/app/AppLayouts/Chat/{components/ContactList.qml => panels/ContactListPanel.qml} (98%) rename ui/app/AppLayouts/Chat/{components/ContactRequest.qml => panels/ContactRequestPanel.qml} (81%) rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents/EmojiReactions.qml => panels/EmojiReactionsPanel.qml} (79%) rename ui/app/AppLayouts/Chat/{ChatColumn/EmptyChat.qml => panels/EmptyChatPanel.qml} (89%) rename ui/app/AppLayouts/Chat/{ContactsColumn/EmptyView.qml => panels/EmptyViewPanel.qml} (95%) rename ui/app/AppLayouts/Chat/{components/FetchMoreMessages.qml => panels/FetchMoreMessagesMenuPanel.qml} (99%) rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents/InvitationBubble.qml => panels/InvitationBubblePanel.qml} (98%) rename ui/app/AppLayouts/Chat/{components/MessageContextMenu.qml => panels/MessageContextMenuPanel.qml} (98%) rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents/StatusUpdate.qml => panels/StatusUpdatePanel.qml} (69%) rename ui/app/AppLayouts/Chat/{components/SuggestedChannels.qml => panels/SuggestedChannelsPanel.qml} (74%) rename ui/app/AppLayouts/Chat/{ChatColumn/SuggestionBox.qml => panels/SuggestionBoxPanel.qml} (99%) rename ui/app/AppLayouts/Chat/{ChatColumn/SuggestionFilter.qml => panels/SuggestionFilterPanel.qml} (99%) rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents/TransactionBubble.qml => panels/TransactionBubblePanel.qml} (85%) rename ui/app/AppLayouts/Chat/{ChatColumn/UserList.qml => panels/UserListPanel.qml} (87%) rename ui/app/AppLayouts/Chat/{CommunityComponents/BackUpCommuntyBanner.qml => panels/communities/BackUpCommuntyBannerPanel.qml} (94%) rename ui/app/AppLayouts/Chat/{CommunityComponents/CommunityProfilePopupInviteFriendsView.qml => panels/communities/CommunityProfilePopupInviteFriendsPanel.qml} (93%) rename ui/app/AppLayouts/Chat/{CommunityComponents/CommunityProfilePopupMembersList.qml => panels/communities/CommunityProfilePopupMembersListPanel.qml} (98%) rename ui/app/AppLayouts/Chat/{CommunityComponents/CommunityProfilePopupOverview.qml => panels/communities/CommunityProfilePopupOverviewPanel.qml} (100%) rename ui/app/AppLayouts/Chat/{CommunityComponents/CommunityUserList.qml => panels/communities/CommunityUserListPanel.qml} (87%) rename ui/app/AppLayouts/Chat/{CommunityComponents/CommunityWelcomeBanner.qml => panels/communities/CommunityWelcomeBannerPanel.qml} (96%) rename ui/app/AppLayouts/Chat/{ChatColumn/ActivityCenter.qml => popups/ActivityCenterPopup.qml} (80%) rename ui/app/AppLayouts/Chat/{ChatColumn/ChatComponents => popups}/ChatCommandModal.qml (96%) rename ui/app/AppLayouts/Chat/{components => popups}/ChooseBrowserPopup.qml (100%) rename ui/app/AppLayouts/Chat/{components => popups}/ContactRequestsPopup.qml (91%) rename ui/app/AppLayouts/Chat/{components => popups}/GroupChatPopup.qml (98%) rename ui/app/AppLayouts/Chat/{components => popups}/GroupInfoPopup.qml (99%) rename ui/app/AppLayouts/Chat/{components => popups}/NicknamePopup.qml (100%) rename ui/app/AppLayouts/Chat/{components => popups}/PinnedMessagesPopup.qml (71%) rename ui/app/AppLayouts/Chat/{components => popups}/PrivateChatPopup.qml (100%) rename ui/app/AppLayouts/Chat/{components => popups}/ProfilePopup.qml (100%) rename ui/app/AppLayouts/Chat/{components => popups}/PublicChatPopup.qml (93%) rename ui/app/AppLayouts/Chat/{components => popups}/RenameGroupPopup.qml (100%) rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents/TransactionComponents => popups}/SelectAccountModal.qml (89%) rename ui/app/AppLayouts/Chat/{ChatColumn/ChatComponents => popups}/SignTransactionModal.qml (98%) rename ui/app/AppLayouts/Chat/{CommunityComponents => popups/community}/AccessExistingCommunityPopup.qml (93%) rename ui/app/AppLayouts/Chat/{CommunityComponents => popups/community}/CommunitiesPopup.qml (99%) rename ui/app/AppLayouts/Chat/{CommunityComponents => popups/community}/CommunityDetailPopup.qml (99%) rename ui/app/AppLayouts/Chat/{CommunityComponents => popups/community}/CommunityProfilePopup.qml (96%) rename ui/app/AppLayouts/Chat/{CommunityComponents => popups/community}/CreateCategoryPopup.qml (99%) rename ui/app/AppLayouts/Chat/{CommunityComponents => popups/community}/CreateChannelPopup.qml (100%) rename ui/app/AppLayouts/Chat/{CommunityComponents => popups/community}/CreateCommunityPopup.qml (99%) rename ui/app/AppLayouts/Chat/{CommunityComponents => popups/community}/InviteFriendsToCommunityPopup.qml (92%) rename ui/app/AppLayouts/Chat/{CommunityComponents => popups/community}/MembershipRequestsPopup.qml (99%) rename ui/app/AppLayouts/Chat/{CommunityComponents => popups/community}/MembershipRequirementPopup.qml (100%) rename ui/app/AppLayouts/Chat/{CommunityComponents => popups/community}/TransferOwnershipPopup.qml (97%) delete mode 100644 ui/app/AppLayouts/Chat/qmldir rename ui/app/AppLayouts/Chat/{data => stores}/EmojiReactions.qml (100%) rename ui/app/AppLayouts/Chat/{ChatColumn/samples => stores}/MessagesData.qml (100%) create mode 100644 ui/app/AppLayouts/Chat/stores/RootStore.qml rename ui/app/AppLayouts/Chat/{ChatColumn/samples => stores}/StickerData.qml (100%) rename ui/app/AppLayouts/Chat/{ChatColumn/samples => stores}/StickerPackData.qml (100%) rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents/TransactionComponents/AcceptTransaction.qml => views/AcceptTransactionView.qml} (94%) rename ui/app/AppLayouts/Chat/{ChatColumn/ChatComponents => views}/ActivityCenterGroupRequest.qml (94%) rename ui/app/AppLayouts/Chat/{ChatColumn/ChatComponents/ActivityCenterMessageComponent.qml => views/ActivityCenterMessageComponentView.qml} (56%) rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents/ChannelIdentifier.qml => views/ChannelIdentifierView.qml} (98%) rename ui/app/AppLayouts/Chat/{ChatColumn.qml => views/ChatColumnView.qml} (96%) rename ui/app/AppLayouts/Chat/{components/ChatContextMenu.qml => views/ChatContextMenuView.qml} (99%) rename ui/app/AppLayouts/Chat/{ChatColumn/ChatMessages.qml => views/ChatMessagesView.qml} (81%) rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents/ChatText.qml => views/ChatTextView.qml} (96%) rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents/ChatTime.qml => views/ChatTimeView.qml} (71%) rename ui/app/AppLayouts/Chat/{CommunityColumn.qml => views/CommunityColumnView.qml} (97%) rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents/CompactMessage.qml => views/CompactMessageView.qml} (75%) rename ui/app/AppLayouts/Chat/{ContactsColumn.qml => views/ContactsColumnView.qml} (96%) rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents/LinksMessage.qml => views/LinksMessageView.qml} (98%) rename ui/app/AppLayouts/Chat/{ChatColumn/Message.qml => views/MessageView.qml} (92%) rename ui/app/AppLayouts/Chat/{ChatColumn/MessageComponents/NormalMessage.qml => views/NormalMessageView.qml} (65%) create mode 100644 ui/app/AppLayouts/Profile/Sections/Contacts/ContactList.qml create mode 100644 ui/app/AppLayouts/stores/MessageStore.qml create mode 100644 ui/app/AppLayouts/stores/RootStore.qml rename ui/{app/AppLayouts/Chat/components => shared}/LoadingAnimation.qml (84%) diff --git a/ui/app/AppLayouts/Browser/BrowserLayout.qml b/ui/app/AppLayouts/Browser/BrowserLayout.qml index 1ee246e24d..f140bfc891 100644 --- a/ui/app/AppLayouts/Browser/BrowserLayout.qml +++ b/ui/app/AppLayouts/Browser/BrowserLayout.qml @@ -12,12 +12,13 @@ import utils 1.0 import "../../../shared" import "../../../shared/controls" import "../../../shared/status" -import "../Chat/ChatColumn/ChatComponents" + import "popups" import "controls" import "views" import "panels" import "stores" +import "../Chat/popups" // Code based on https://code.qt.io/cgit/qt/qtwebengine.git/tree/examples/webengine/quicknanobrowser/BrowserWindow.qml?h=5.15 // Licensed under BSD diff --git a/ui/app/AppLayouts/Browser/popups/BrowserSettingsMenu.qml b/ui/app/AppLayouts/Browser/popups/BrowserSettingsMenu.qml index 39640277a8..a7d74be3c7 100644 --- a/ui/app/AppLayouts/Browser/popups/BrowserSettingsMenu.qml +++ b/ui/app/AppLayouts/Browser/popups/BrowserSettingsMenu.qml @@ -2,11 +2,13 @@ import QtQuick 2.13 import QtQuick.Controls 2.3 import QtWebEngine 1.9 import utils 1.0 + import "../../../../shared" import "../../../../shared/popups" import "../../../../shared/panels" import "../../../../shared/status" -import "../../Chat/ChatColumn/ChatComponents" + +import "../../Chat/popups" // TODO: replace with StatusPopupMenu PopupMenu { diff --git a/ui/app/AppLayouts/Browser/popups/FavoriteMenu.qml b/ui/app/AppLayouts/Browser/popups/FavoriteMenu.qml index be041303ff..56832545e4 100644 --- a/ui/app/AppLayouts/Browser/popups/FavoriteMenu.qml +++ b/ui/app/AppLayouts/Browser/popups/FavoriteMenu.qml @@ -8,7 +8,8 @@ import "../../../../shared/status" import "../stores" import utils 1.0 -import "../../Chat/ChatColumn/ChatComponents" + +import "../../Chat/popups" // TODO: replace with StatusPopupMenu PopupMenu { diff --git a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityChannelBadge.qml b/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityChannelBadge.qml deleted file mode 100644 index 9322c0b533..0000000000 --- a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityChannelBadge.qml +++ /dev/null @@ -1,103 +0,0 @@ -import QtQuick 2.13 -import QtGraphicalEffects 1.13 - -import utils 1.0 -import "../../../../../shared" -import "../../../../../shared/panels" -import "../../../../../shared/controls" -import "../../../../../shared/status" -import ".." -import "../../components" - -Rectangle { - property string chatId: "" - property string name: "channelName" - property string identicon - property string responseTo - property string communityId - property int notificationType - property int chatType: chatsModel.channelView.chats.getChannelType(chatId) - property int realChatType: { - if (chatType === Constants.chatTypeCommunity) { - // TODO add a check for private community chats once it is created - return Constants.chatTypePublic - } - return chatType - } - - property string profileImage: realChatType === Constants.chatTypeOneToOne ? appMain.getProfileImage(chatId) || "" : "" - - id: wrapper - height: visible ? 24 : 0 - width: childrenRect.width + 12 - color: Style.current.transparent - border.color: Style.current.borderSecondary - border.width: 1 - radius: 11 - - Loader { - active: true - height: parent.height - anchors.left: parent.left - anchors.leftMargin: 4 - sourceComponent: { - switch (model.notificationType) { - case Constants.activityCenterNotificationTypeMention: return communityOrChannelContentComponent - case Constants.activityCenterNotificationTypeReply: return replyComponent - default: return communityOrChannelContentComponent - } - } - } - - Component { - id: replyComponent - - Item { - property int replyMessageIndex: chatsModel.messageView.getMessageIndex(chatId, responseTo) - property string repliedMessageContent: replyMessageIndex > -1 ? chatsModel.messageView.getMessageData(chatId, replyMessageIndex, "message") : ""; - - - onReplyMessageIndexChanged: { - wrapper.visible = replyMessageIndex > -1 - } - - width: childrenRect.width - height: parent.height - SVGImage { - id: replyIcon - width: 16 - height: 16 - source: Style.svg("reply-small-arrow") - anchors.left: parent.left - anchors.verticalCenter:parent.verticalCenter - } - - StyledTextEdit { - text: Utils.getReplyMessageStyle(Emoji.parse(Utils.linkifyAndXSS(repliedMessageContent), Emoji.size.small), false, appSettings.useCompactMode) - textFormat: Text.RichText - height: 18 - width: implicitWidth > 300 ? 300 : implicitWidth - clip: true - anchors.left: replyIcon.right - anchors.leftMargin: 4 - color: Style.current.secondaryText - font.weight: Font.Medium - font.pixelSize: 13 - anchors.verticalCenter: parent.verticalCenter - selectByMouse: true - readOnly: true - } - } - } - - Component { - id: communityOrChannelContentComponent - - BadgeContent { - chatId: wrapper.chatId - name: wrapper.name - identicon: wrapper.identicon - communityId: wrapper.communityId - } - } -} diff --git a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandButton.qml b/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandButton.qml deleted file mode 100644 index db2844fe6b..0000000000 --- a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandButton.qml +++ /dev/null @@ -1,70 +0,0 @@ -import QtQuick 2.13 -import QtQuick.Controls 2.13 -import QtGraphicalEffects 1.13 - -import utils 1.0 -import "../../../../../shared" -import "../../../../../shared/panels" - -Rectangle { - property color iconColor - property string text: "My command" - property url iconSource: Style.svg("send") - property bool rotatedImage: false - property var onClicked: function () {} - - id: root - width: 168 - height: 95 - radius: 16 - color: Utils.setColorAlpha(iconColor, 0.2) - - Rectangle { - id: iconBox - radius: 50 - color: iconColor - anchors.top: parent.top - anchors.topMargin: Style.current.smallPadding - anchors.left: parent.left - anchors.leftMargin: Style.current.smallPadding - height: iconImage.height + Style.current.smallPadding * 2 - width: this.height - - SVGImage { - id: iconImage - source: Style.svg("send") - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - width: 16 - fillMode: Image.PreserveAspectFit - rotation: rotatedImage ? 180 : 0 - antialiasing: true - } - - ColorOverlay { - anchors.fill: iconImage - source: iconImage - color: Style.current.white - rotation: rotatedImage ? 180 : 0 - antialiasing: true - } - } - - StyledText { - text: root.text - anchors.left: parent.left - anchors.leftMargin: Style.current.smallPadding - anchors.bottom: parent.bottom - anchors.bottomMargin: Style.current.smallPadding - font.weight: Font.Medium - font.pixelSize: 13 - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: { - root.onClicked() - } - } -} diff --git a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatInputButton.qml b/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatInputButton.qml deleted file mode 100644 index 2a627a52d2..0000000000 --- a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatInputButton.qml +++ /dev/null @@ -1,62 +0,0 @@ -import QtQuick 2.13 -import QtQuick.Controls 2.13 -import QtGraphicalEffects 1.13 - -import utils 1.0 -import "../../../../../shared" -import "../../../../../shared/panels" - -Rectangle { - property url source: Style.svg("emojiBtn") - property bool hovered: false - property bool opened: false - property var close: function () {} - property var open: function () {} - - id: root - width: this.visible ? buttonIcon.width + 4 + chatButtonsContainer.iconPadding * 2 : 0 - height: this.visible ? buttonIcon.height + chatButtonsContainer.iconPadding * 2 : 0 - radius: Style.current.radius - color: hovered ? Style.current.secondaryBackground : Style.current.transparent - anchors.verticalCenter: parent.verticalCenter - - SVGImage { - id: buttonIcon - visible: txtData.length === 0 - source: root.source - width: 20 - height: 20 - anchors.verticalCenter: parent.verticalCenter - anchors.horizontalCenter: parent.horizontalCenter - } - ColorOverlay { - anchors.fill: buttonIcon - source: buttonIcon - color: root.hovered || root.opened ? Style.current.blue : Style.current.darkGrey - } - - MouseArea { - cursorShape: Qt.PointingHandCursor - anchors.fill: parent - hoverEnabled: true - onEntered: { - root.hovered = true - } - onExited: { - root.hovered = false - } - onClicked: { - if (root.opened) { - root.close() - } else { - root.open() - } - } - } -} - -/*##^## -Designer { - D{i:0;formeditorZoom:1.5} -} -##^##*/ diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/MessageMouseArea.qml b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/MessageMouseArea.qml deleted file mode 100644 index 5fae11cbc0..0000000000 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/MessageMouseArea.qml +++ /dev/null @@ -1,35 +0,0 @@ -import QtQuick 2.13 -import "../../../../../shared" - -import utils 1.0 - -MouseArea { - enabled: !placeholderMessage - cursorShape: chatText.hoveredLink ? Qt.PointingHandCursor : undefined - acceptedButtons: Qt.LeftButton | Qt.RightButton - z: 50 - onClicked: { - if (activityCenterMessage) { - return clickMessage(false, isSticker, false) - } - if(mouse.button === Qt.RightButton) { - // Set parent, X & Y positions for the messageContextMenu - messageContextMenu.parent = root - messageContextMenu.setXPosition = function() { return (mouse.x)} - messageContextMenu.setYPosition = function() { return (mouse.y)} - clickMessage(false, isSticker, false) - if (typeof isMessageActive !== "undefined") { - setMessageActive(messageId, true) - } - return; - } - if (mouse.button === Qt.LeftButton && isSticker && stickersLoaded) { - if (isHovered) { - isHovered = false - } - - openPopup(statusStickerPackClickPopup, {packId: stickerPackId} ) - return; - } - } -} diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SendTransactionButton.qml b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SendTransactionButton.qml deleted file mode 100644 index 2bfe830a99..0000000000 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SendTransactionButton.qml +++ /dev/null @@ -1,77 +0,0 @@ -import QtQuick 2.3 -import "../../../../../../shared" -import "../../../../../../shared/controls" -import "../../../../../../shared/panels" - -import utils 1.0 -import "../../ChatComponents" - -Item { - id: root - width: parent.width - height: childrenRect.height + Style.current.halfPadding - - Separator { - id: separator - } - - StyledText { - id: signText - color: Style.current.blue - //% "Sign and send" - text: qsTrId("sign-and-send") - horizontalAlignment: Text.AlignHCenter - wrapMode: Text.WordWrap - font.weight: Font.Medium - anchors.right: parent.right - anchors.left: parent.left - topPadding: Style.current.halfPadding - anchors.top: separator.bottom - font.pixelSize: 15 - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: { - walletModel.accountsView.setFocusedAccountByAddress(commandParametersObject.fromAddress) - var acc = walletModel.accountsView.focusedAccount - openPopup(signTxComponent, {selectedAccount: { - name: acc.name, - address: commandParametersObject.fromAddress, - iconColor: acc.iconColor, - assets: acc.assets - }}) - } - } - } - - Component { - id: signTxComponent - SignTransactionModal { - onOpened: { - walletModel.gasView.getGasPrice() - } - onClosed: { - destroy(); - } - selectedRecipient: { - return { - address: commandParametersObject.address, - identicon: chatsModel.channelView.activeChannel.identicon, - name: chatsModel.channelView.activeChannel.name, - type: RecipientSelector.Type.Contact - } - } - selectedAsset: token - selectedAmount: tokenAmount - selectedFiatAmount: fiatValue - } - } -} - -/*##^## -Designer { - D{i:0;formeditorColor:"#ffffff";formeditorZoom:1.25} -} -##^##*/ - diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/UserImage.qml b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/UserImage.qml deleted file mode 100644 index 7fabcf52c5..0000000000 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/UserImage.qml +++ /dev/null @@ -1,55 +0,0 @@ -import QtQuick 2.3 -import "../../../../../shared" -import "../../../../../shared/panels" - -import utils 1.0 - -Loader { - property int imageHeight: 36 - property int imageWidth: 36 - property string identiconImageSource: identicon - property string profileImage: profileImageSource - property bool isReplyImage: false - - id: root - active: isMessage - height: active ? item.height : 0 - - sourceComponent: Component { - Item { - id: chatImage - width: identiconImage.width - height: identiconImage.height - - RoundedImage { - id: identiconImage - width: root.imageWidth - height: root.imageHeight - border.width: 1 - border.color: Style.current.border - source: { - if (root.profileImage) { - return root.profileImage - } - identiconImage.showLoadingIndicator = false - return !isCurrentUser || isReplyImage ? root.identiconImageSource : profileModel.profile.identicon - } - smooth: false - antialiasing: true - - MouseArea { - cursorShape: Qt.PointingHandCursor - acceptedButtons: Qt.LeftButton | Qt.RightButton - anchors.fill: parent - onClicked: { - // Set parent, X & Y positions for the messageContextMenu - messageContextMenu.parent = root - messageContextMenu.setXPosition = function() { return root.width + 4} - messageContextMenu.setYPosition = function() { return root.height/2 + 4} - clickMessage(true, false, false, null, false, false, isReplyImage) - } - } - } - } - } -} diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/qmldir b/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/qmldir deleted file mode 100644 index f17b4a3740..0000000000 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/qmldir +++ /dev/null @@ -1 +0,0 @@ -ChannelIdentifier 1.0 ChannelIdentifier.qml diff --git a/ui/app/AppLayouts/Chat/ChatColumn/qmldir b/ui/app/AppLayouts/Chat/ChatColumn/qmldir deleted file mode 100644 index 8fab2035fe..0000000000 --- a/ui/app/AppLayouts/Chat/ChatColumn/qmldir +++ /dev/null @@ -1,8 +0,0 @@ -TopBar 1.0 TopBar.qml -ChatMessages 1.0 ChatMessages.qml -ChatInput 1.0 ChatInput.qml -EmptyChat 1.0 EmptyChat.qml -ChatButtons 1.0 ChatButtons.qml -ReplyArea 1.0 ReplyArea.qml -Message 1.0 Message.qml -CompactMessage 1.0 CompactMessage.qml diff --git a/ui/app/AppLayouts/Chat/ChatColumn/samples/qmldir b/ui/app/AppLayouts/Chat/ChatColumn/samples/qmldir deleted file mode 100644 index 1074e3c2c2..0000000000 --- a/ui/app/AppLayouts/Chat/ChatColumn/samples/qmldir +++ /dev/null @@ -1,3 +0,0 @@ -MessagesData 1.0 MessagesData.qml -StickerData 1.0 StickerData.qml -StickerPackData 1.0 StickerPackData.qml diff --git a/ui/app/AppLayouts/Chat/ChatLayout.qml b/ui/app/AppLayouts/Chat/ChatLayout.qml index 9810ccb35b..79542ee5a7 100644 --- a/ui/app/AppLayouts/Chat/ChatLayout.qml +++ b/ui/app/AppLayouts/Chat/ChatLayout.qml @@ -7,11 +7,14 @@ import "../../../shared" import "../../../shared/popups" import "../../../shared/panels" import "../../../shared/status" -import "." -import "./data" -import "components" -import "./ChatColumn" -import "./CommunityComponents" + +import "views" +import "panels" +import "panels/communities" +import "popups" +import "helpers" +import "controls" +import "stores" import StatusQ.Layout 0.1 import StatusQ.Popups 0.1 @@ -21,6 +24,10 @@ StatusAppThreePanelLayout { handle: SplitViewHandle { implicitWidth: 5 } + property var messageStore + property RootStore rootStore: RootStore { + messageStore: chatView.messageStore + } property alias chatColumn: chatColumn property bool stickersLoaded: false signal profileButtonClicked() @@ -157,8 +164,9 @@ StatusAppThreePanelLayout { sourceComponent: appSettings.communitiesEnabled && chatsModel.communities.activeCommunity.active ? communtiyColumnComponent : contactsColumnComponent } - centerPanel: ChatColumn { + centerPanel: ChatColumnView { id: chatColumn + rootStore: chatView.rootStore chatGroupsListViewCount: contactColumnLoader.item.chatGroupsListViewCount } @@ -168,17 +176,29 @@ StatusAppThreePanelLayout { Component { id: communityUserListComponent - CommunityUserList { currentTime: chatColumn.currentTime; messageContextMenu: quickActionMessageOptionsMenu } + CommunityUserListPanel { + currentTime: chatColumn.currentTime + messageContextMenu: quickActionMessageOptionsMenu + profilePubKey: profileModel.profile.pubKey + contactsList: profileModel.contacts.list + } } Component { id: userListComponent - UserList { currentTime: chatColumn.currentTime; userList: chatColumn.userList; messageContextMenu: quickActionMessageOptionsMenu} + UserListPanel { + currentTime: chatColumn.currentTime + userList: chatColumn.userList + messageContextMenu: quickActionMessageOptionsMenu + profilePubKey: profileModel.profile.pubKey + contactsList: profileModel.contacts.list + isOnline: chatsModel.isOnline + } } Component { id: contactsColumnComponent - ContactsColumn { + ContactsColumnView { onOpenProfileClicked: { chatView.profileButtonClicked(); } @@ -187,7 +207,7 @@ StatusAppThreePanelLayout { Component { id: communtiyColumnComponent - CommunityColumn { + CommunityColumnView { pinnedMessagesPopupComponent: chatColumn.pinnedMessagesPopupComponent } } @@ -223,9 +243,9 @@ StatusAppThreePanelLayout { } } - MessageContextMenu { + MessageContextMenuPanel { id: quickActionMessageOptionsMenu - reactionModel: EmojiReactions { } + reactionModel: chatColumn.rootStore.emojiReactionsModel } } diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/MembershipRequestsButton.qml b/ui/app/AppLayouts/Chat/CommunityComponents/MembershipRequestsButton.qml deleted file mode 100644 index 8642dab435..0000000000 --- a/ui/app/AppLayouts/Chat/CommunityComponents/MembershipRequestsButton.qml +++ /dev/null @@ -1,70 +0,0 @@ -import QtQuick 2.13 -import QtQuick.Controls 2.13 -import QtQuick.Layouts 1.13 -import QtGraphicalEffects 1.13 -import "../../../../shared" -import "../../../../shared/panels" - -import utils 1.0 -import "../components" -import "./" - -Rectangle { - property int nbRequests: chatsModel.communities.activeCommunity.communityMembershipRequests.nbRequests - - id: membershipRequestsBtn - visible: nbRequests > 0 - width: parent.width - height: visible ? 52 : 0 - color: Style.current.secondaryBackground - - StyledText { - //% "Membership requests" - text: qsTrId("membership-requests") - font.pixelSize: 15 - anchors.left: parent.left - anchors.leftMargin: Style.current.padding - anchors.verticalCenter: parent.verticalCenter - } - - Rectangle { - id: badge - anchors.right: caret.left - anchors.rightMargin: Style.current.padding - anchors.verticalCenter: parent.verticalCenter - color: Style.current.blue - width: 22 - height: 22 - radius: width / 2 - Text { - font.pixelSize: 12 - color: Style.current.white - anchors.centerIn: parent - text: membershipRequestsBtn.nbRequests.toString() - } - } - - SVGImage { - id: caret - source: Style.svg("caret") - fillMode: Image.PreserveAspectFit - rotation: -90 - anchors.right: parent.right - anchors.rightMargin: Style.current.padding - anchors.verticalCenter: parent.verticalCenter - width: 13 - height: 7 - - ColorOverlay { - anchors.fill: parent - source: parent - color: Style.current.darkGrey - } - } - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: membershipRequestPopup.open() - } -} diff --git a/ui/app/AppLayouts/Chat/ContactsColumn/qmldir b/ui/app/AppLayouts/Chat/ContactsColumn/qmldir deleted file mode 100644 index 1d1bd0bf6e..0000000000 --- a/ui/app/AppLayouts/Chat/ContactsColumn/qmldir +++ /dev/null @@ -1,2 +0,0 @@ -EmptyView 1.0 EmptyView.qml -ClosedEmptyView 1.0 ClosedEmptyView.qml diff --git a/ui/app/AppLayouts/Chat/components/ChannelIcon.qml b/ui/app/AppLayouts/Chat/components/ChannelIcon.qml deleted file mode 100644 index 0bdb2d90bb..0000000000 --- a/ui/app/AppLayouts/Chat/components/ChannelIcon.qml +++ /dev/null @@ -1,73 +0,0 @@ -import QtQuick 2.13 -import QtQuick.Controls 2.13 -import QtQuick.Layouts 1.13 - -import utils 1.0 -import "../../../../shared" -import "../../../../shared/panels" - -Item { - property string channelName - property int channelType - property string channelIdenticon - readonly property int defaultFontSize: 21 - property int fontSize: defaultFontSize - id: contactImage - width: 36 - height: 36 - - Loader { - sourceComponent: channelType == Constants.chatTypeOneToOne ? imageIdenticon : letterIdenticon - anchors.fill: parent - } - - Component { - id: letterIdenticon - Rectangle { - width: contactImage.width - height: contactImage.height - radius: 50 - color: { - const color = chatsModel.channelView.getChannelColor(channelName) - if (!color) { - return Style.current.transparent - } - return color - } - - StyledText { - text: { - if (channelType == Constants.chatTypeOneToOne) { - return channelName - } else { - return (channelName.charAt(0) == "#" ? channelName.charAt(1) : channelName.charAt(0)).toUpperCase() - } - } - opacity: 0.7 - font.weight: Font.Bold - font.pixelSize: fontSize - color: "white" - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - } - } - } - - Component { - id: imageIdenticon - Rectangle { - width: contactImage.width ? contactImage.width : 40 - height: contactImage.height ? contactImage.height : 40 - radius: 50 - border.color: Style.current.border - border.width: 1 - color: Style.current.background - SVGImage { - width: contactImage.width ? contactImage.width : 40 - height: contactImage.height ? contactImage.height : 40 - fillMode: Image.PreserveAspectFit - source: channelIdenticon - } - } - } -} diff --git a/ui/app/AppLayouts/Chat/components/qmldir b/ui/app/AppLayouts/Chat/components/qmldir deleted file mode 100644 index 19f3dadba8..0000000000 --- a/ui/app/AppLayouts/Chat/components/qmldir +++ /dev/null @@ -1,13 +0,0 @@ -SuggestedChannel 1.0 SuggestedChannel.qml -PublicChatPopup 1.0 PublicChatPopup.qml -PrivateChatPopup 1.0 PrivateChatPopup.qml -GroupInfoPopup 1.0 GroupInfoPopup.qml -ProfilePropup 1.0 ProfilePopup.qml -ChannelIcon 1.0 ChannelIcon.qml -RenameGroupPopup 1.0 RenameGroupPopup.qml -GroupChatPopup 1.0 GroupChatPopup.qml -StickerButton 1.0 StickerButton.qml -StickerMarket 1.0 StickerMarket.qml -StickersPopup 1.0 StickersPopup.qml -StickerPackIconWithIndicator 1.0 StickerPackIconWithIndicator.qml -SuggestedChannels 1.0 SuggestedChannels.qml diff --git a/ui/app/AppLayouts/Chat/components/Contact.qml b/ui/app/AppLayouts/Chat/controls/Contact.qml similarity index 100% rename from ui/app/AppLayouts/Chat/components/Contact.qml rename to ui/app/AppLayouts/Chat/controls/Contact.qml diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/DateGroup.qml b/ui/app/AppLayouts/Chat/controls/DateGroup.qml similarity index 97% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/DateGroup.qml rename to ui/app/AppLayouts/Chat/controls/DateGroup.qml index e76580bb7d..4a27ed81fc 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/DateGroup.qml +++ b/ui/app/AppLayouts/Chat/controls/DateGroup.qml @@ -1,6 +1,7 @@ import QtQuick 2.3 -import "../../../../../shared" -import "../../../../../shared/panels" + +import "../../../../shared" +import "../../../../shared/panels" import utils 1.0 diff --git a/ui/app/AppLayouts/Chat/components/EmojiReaction.qml b/ui/app/AppLayouts/Chat/controls/EmojiReaction.qml similarity index 87% rename from ui/app/AppLayouts/Chat/components/EmojiReaction.qml rename to ui/app/AppLayouts/Chat/controls/EmojiReaction.qml index 279a705a5b..3b6e0a549e 100644 --- a/ui/app/AppLayouts/Chat/components/EmojiReaction.qml +++ b/ui/app/AppLayouts/Chat/controls/EmojiReaction.qml @@ -6,10 +6,10 @@ import "../../../../shared/panels" Rectangle { property alias source: reactionImage.source - property var closeModal: function () {} property int emojiId property bool reactedByUser: false property bool isHovered: false + signal closeModal() id: root width: reactionImage.width + Style.current.halfPadding @@ -34,8 +34,7 @@ Rectangle { onEntered: root.isHovered = true onExited: root.isHovered = false onClicked: { - chatsModel.toggleReaction(SelectedMessage.messageId, emojiId) - root.closeModal() + root.closeModal(); } } } diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/MessageBorder.qml b/ui/app/AppLayouts/Chat/controls/MessageBorder.qml similarity index 98% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/MessageBorder.qml rename to ui/app/AppLayouts/Chat/controls/MessageBorder.qml index e5e30d540b..c52f659232 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/MessageBorder.qml +++ b/ui/app/AppLayouts/Chat/controls/MessageBorder.qml @@ -4,7 +4,7 @@ import QtQuick.Layouts 1.13 import "./" as MessageComponents import utils 1.0 -import "../../../../../shared" +import "../../../../shared" Item { id: root @@ -93,4 +93,4 @@ Item { height: root.height } } -} \ No newline at end of file +} diff --git a/ui/app/AppLayouts/Chat/controls/MessageMouseArea.qml b/ui/app/AppLayouts/Chat/controls/MessageMouseArea.qml new file mode 100644 index 0000000000..293e9e734b --- /dev/null +++ b/ui/app/AppLayouts/Chat/controls/MessageMouseArea.qml @@ -0,0 +1,51 @@ +import QtQuick 2.13 +import "../../../../shared" + +import utils 1.0 + +MouseArea { + z: 50 + enabled: !placeholderMessage + + property bool isHovered: false + property bool isSticker: false + property bool placeholderMessage: false + property bool isActivityCenterMessage: false + property var isMessageActive + property var messageContextMenu + signal setMessageActive(string messageId, bool active) + signal clickMessage(bool isProfileClick, bool isSticker, bool isImage) + + cursorShape: !enabled ? Qt.PointingHandCursor : undefined + + acceptedButtons: Qt.LeftButton | Qt.RightButton + + onClicked: { + if (isActivityCenterMessage) { + return clickMessage(false, isSticker, false) + } + if (mouse.button === Qt.RightButton) { + if (!!messageContextMenu) { + // Set parent, X & Y positions for the messageContextMenu + //TODO remove dynamic scoping + messageContextMenu.parent = root + messageContextMenu.setXPosition = function() { return (mouse.x)}; + messageContextMenu.setYPosition = function() { return (mouse.y)}; + } + clickMessage(false, isSticker, false) + if (typeof isMessageActive !== "undefined") { + setMessageActive(messageId, true) + } + return; + } + //TODO remove dynamic scoping + if (mouse.button === Qt.LeftButton && isSticker && stickersLoaded) { + if (isHovered) { + isHovered = false; + } + //TODO remove dynamic scoping + openPopup(statusStickerPackClickPopup, {packId: stickerPackId} ) + return; + } + } +} diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/RectangleCorner.qml b/ui/app/AppLayouts/Chat/controls/RectangleCorner.qml similarity index 91% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/RectangleCorner.qml rename to ui/app/AppLayouts/Chat/controls/RectangleCorner.qml index b90ed6b88b..984bab17c0 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/RectangleCorner.qml +++ b/ui/app/AppLayouts/Chat/controls/RectangleCorner.qml @@ -5,6 +5,7 @@ Rectangle { color: parent.color width: 18 height: 18 + property bool isCurrentUser: false anchors.bottom: parent.bottom anchors.bottomMargin: 0 anchors.left: !isCurrentUser ? parent.left : undefined diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/Retry.qml b/ui/app/AppLayouts/Chat/controls/Retry.qml similarity index 63% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/Retry.qml rename to ui/app/AppLayouts/Chat/controls/Retry.qml index 5461b4081a..dd7f5ef6c0 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/Retry.qml +++ b/ui/app/AppLayouts/Chat/controls/Retry.qml @@ -1,7 +1,7 @@ - import QtQuick 2.3 -import "../../../../../shared" -import "../../../../../shared/panels" + +import "../../../../shared" +import "../../../../shared/panels" import utils 1.0 @@ -12,11 +12,15 @@ StyledText { text: qsTrId("resend-message") font.pixelSize: Style.current.tertiaryTextFontSize visible: isCurrentUser && (timeout || isExpired) + property bool isCurrentUser: false + property bool isExpired: false + property bool timeout: false + signal clicked() MouseArea { cursorShape: Qt.PointingHandCursor anchors.fill: parent onClicked: { - chatsModel.messageView.resendMessage(chatId, messageId) + retryLbl.clicked(); } } } diff --git a/ui/app/AppLayouts/Chat/controls/SendTransactionButton.qml b/ui/app/AppLayouts/Chat/controls/SendTransactionButton.qml new file mode 100644 index 0000000000..8a3db81aa9 --- /dev/null +++ b/ui/app/AppLayouts/Chat/controls/SendTransactionButton.qml @@ -0,0 +1,72 @@ +import QtQuick 2.3 + +import utils 1.0 +import "../../../../shared" +import "../../../../shared/panels" +import "../popups" + +Item { + id: root + width: parent.width + height: childrenRect.height + Style.current.halfPadding + + property var acc + property string fromAddress + property var selectedRecipient + property var selectedAsset + property string selectedAmount + property string selectedFiatAmount + + signal signModalOpened() + signal sendTransaction(string address) + + Separator { + id: separator + } + + StyledText { + id: signText + color: Style.current.blue + //% "Sign and send" + text: qsTrId("sign-and-send") + horizontalAlignment: Text.AlignHCenter + wrapMode: Text.WordWrap + font.weight: Font.Medium + anchors.right: parent.right + anchors.left: parent.left + topPadding: Style.current.halfPadding + anchors.top: separator.bottom + font.pixelSize: 15 + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: { + root.clicked(root.fromAddress); + //TODO remove dynamic scoping + openPopup(signTxComponent, {selectedAccount: { + name: root.acc.name, + address: root.fromAddress, + iconColor: root.acc.iconColor, + assets: root.acc.assets + }}) + } + } + } + + Component { + id: signTxComponent + SignTransactionModal { + selectedAsset: root.selectedAsset + selectedAmount: root.selectedAmount + selectedRecipient: root.selectedRecipient + selectedFiatAmount: root.selectedFiatAmount + onOpened: { + root.signModalOpened(); + } + onClosed: { + destroy(); + } + } + } +} diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/SentMessage.qml b/ui/app/AppLayouts/Chat/controls/SentMessage.qml similarity index 81% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/SentMessage.qml rename to ui/app/AppLayouts/Chat/controls/SentMessage.qml index 526f26a056..ec5270ab3c 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/SentMessage.qml +++ b/ui/app/AppLayouts/Chat/controls/SentMessage.qml @@ -1,5 +1,5 @@ import QtQuick 2.3 -import "../../../../../shared/panels" +import "../../../../shared/panels" import utils 1.0 diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/StateBubble.qml b/ui/app/AppLayouts/Chat/controls/StateBubble.qml similarity index 94% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/StateBubble.qml rename to ui/app/AppLayouts/Chat/controls/StateBubble.qml index df3a6275ea..1a2fa26534 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/StateBubble.qml +++ b/ui/app/AppLayouts/Chat/controls/StateBubble.qml @@ -1,7 +1,7 @@ import QtQuick 2.3 import QtGraphicalEffects 1.13 -import "../../../../../../shared" -import "../../../../../../shared/panels" +import "../../../../shared" +import "../../../../shared/panels" import utils 1.0 @@ -89,9 +89,3 @@ Rectangle { font.pixelSize: 13 } } - -/*##^## -Designer { - D{i:0;formeditorColor:"#808080";formeditorZoom:2} -} -##^##*/ diff --git a/ui/app/AppLayouts/Chat/components/SuggestedChannel.qml b/ui/app/AppLayouts/Chat/controls/SuggestedChannel.qml similarity index 90% rename from ui/app/AppLayouts/Chat/components/SuggestedChannel.qml rename to ui/app/AppLayouts/Chat/controls/SuggestedChannel.qml index ead2ace231..4d74542bde 100644 --- a/ui/app/AppLayouts/Chat/components/SuggestedChannel.qml +++ b/ui/app/AppLayouts/Chat/controls/SuggestedChannel.qml @@ -5,8 +5,9 @@ import "../../../../shared" import "../../../../shared/panels" Rectangle { + id: root property string channel: "status" - + signal clicked(string channel) border.width: 1 radius: 8 width: children[0].width + 10 @@ -30,7 +31,7 @@ Rectangle { MouseArea { anchors.fill: parent onClicked: { - chatsModel.channelView.joinPublicChat(channel); + root.clicked(channel); } cursorShape: Qt.PointingHandCursor } diff --git a/ui/app/AppLayouts/Chat/ChatColumn/User.qml b/ui/app/AppLayouts/Chat/controls/UserDelegate.qml similarity index 90% rename from ui/app/AppLayouts/Chat/ChatColumn/User.qml rename to ui/app/AppLayouts/Chat/controls/UserDelegate.qml index 93e4075138..93c029de6a 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/User.qml +++ b/ui/app/AppLayouts/Chat/controls/UserDelegate.qml @@ -5,7 +5,6 @@ import "../../../../shared/panels" import "../../../../shared/status" import utils 1.0 -import "../components" import StatusQ.Components 0.1 import StatusQ.Core.Theme 0.1 @@ -13,27 +12,30 @@ import StatusQ.Core.Theme 0.1 Item { id: wrapper anchors.right: parent.right - anchors.top: applicationWindow.top anchors.left: parent.left height: rectangle.height + 4 property string publicKey: "" + property string profilePubKey + property var contactsList property string name: "channelName" property string lastSeen: "" property string identicon property int statusType: -1 property bool hovered: false property bool enableMouseArea: true - property bool isOnline: chatsModel.isOnline + property bool isOnline: false property var currentTime + property var messageContextMenu property color color: { if (wrapper.hovered) { return Style.current.menuBackgroundHover } - return Style.current.transparent + return Style.current.transparent } + //TODO remove dynamic scoping property string profileImage: appMain.getProfileImage(publicKey) || "" - property bool isCurrentUser: publicKey === profileModel.profile.pubKey + property bool isCurrentUser: (publicKey === profilePubKey) Rectangle { id: rectangle @@ -42,7 +44,8 @@ Item { radius: 8 color: wrapper.color Connections { - target: profileModel.contacts.list + enabled: !!wrapper.contactsList + target: wrapper.contactsList onContactChanged: { if (pubkey === wrapper.publicKey) { wrapper.profileImage = appMain.getProfileImage(wrapper.publicKey) @@ -120,9 +123,10 @@ Item { } onClicked: { if (mouse.button === Qt.LeftButton) { + //TODO remove dynamic scoping openProfilePopup(wrapper.name, wrapper.publicKey, (wrapper.profileImage || wrapper.identicon), "", appMain.getUserNickname(wrapper.publicKey)); } - else if (mouse.button === Qt.RightButton) { + else if (mouse.button === Qt.RightButton && !!messageContextMenu) { // Set parent, X & Y positions for the messageContextMenu messageContextMenu.parent = rectangle messageContextMenu.setXPosition = function() { return 0} @@ -132,14 +136,5 @@ Item { } } } - } } - - - -/*##^## -Designer { - D{i:0;formeditorColor:"#ffffff";height:64;width:640} -} -##^##*/ diff --git a/ui/app/AppLayouts/Chat/controls/UserImage.qml b/ui/app/AppLayouts/Chat/controls/UserImage.qml new file mode 100644 index 0000000000..09271e9f67 --- /dev/null +++ b/ui/app/AppLayouts/Chat/controls/UserImage.qml @@ -0,0 +1,60 @@ +import QtQuick 2.3 +import "../../../../shared" +import "../../../../shared/panels" + +import utils 1.0 + +Loader { + id: root + active: isMessage + height: active ? item.height : 0 + property int imageHeight: 36 + property int imageWidth: 36 +// property string profileImage: "" +// property string identiconImageSource: "" + property bool isReplyImage: false +// property var messageContextMenu +// property bool isCurrentUser: false +// property bool isMessage: false + signal clickMessage(bool isProfileClick, bool isSticker, bool isImage, var image, bool emojiOnly, bool hideEmojiPicker, bool isReply) + + sourceComponent: Component { + Item { + id: chatImage + width: identiconImage.width + height: identiconImage.height + + RoundedImage { + id: identiconImage + width: root.imageWidth + height: root.imageHeight + border.width: 1 + border.color: Style.current.border + source: { + if (profileImageSource) { + return profileImageSource + } + identiconImage.showLoadingIndicator = false + return !isCurrentUser || isReplyImage ? identicon : profileModel.profile.identicon + } + smooth: false + antialiasing: true + + MouseArea { + cursorShape: Qt.PointingHandCursor + acceptedButtons: Qt.LeftButton | Qt.RightButton + anchors.fill: parent + onClicked: { + if (!!messageContextMenu) { + // Set parent, X & Y positions for the messageContextMenu + messageContextMenu.parent = root + messageContextMenu.setXPosition = function() { return root.width + 4} + messageContextMenu.setYPosition = function() { return root.height/2 + 4} + } + root.clickMessage(true, false, false, null, false, false, isReplyImage) + } + } + } + } + } +} diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/UsernameLabel.qml b/ui/app/AppLayouts/Chat/controls/UsernameLabel.qml similarity index 62% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/UsernameLabel.qml rename to ui/app/AppLayouts/Chat/controls/UsernameLabel.qml index 9bd8d8f623..77c45d773a 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/UsernameLabel.qml +++ b/ui/app/AppLayouts/Chat/controls/UsernameLabel.qml @@ -1,7 +1,7 @@ import QtQuick 2.3 -import "../../../../../shared" -import "../../../../../shared/controls" -import "../../../../../shared/panels" +import "../../../../shared" +import "../../../../shared/controls" +import "../../../../shared/panels" import utils 1.0 @@ -11,7 +11,14 @@ Item { height: childrenRect.height width: chatName.width + (ensOrAlias.visible ? ensOrAlias.width + ensOrAlias.anchors.leftMargin : 0) property alias label: chatName - visible: isMessage && authorCurrentMsg != authorPrevMsg +// property var messageContextMenu +// property bool isCurrentUser: false +// property string userName: "" +// property string localName: "" +// property string displayUserName: "" + signal clickMessage(bool isProfileClick) + //TODO remove dynamic scoping + //visible: isMessage && authorCurrentMsg != authorPrevMsg StyledTextEdit { id: chatName @@ -35,11 +42,13 @@ Item { root.isHovered = false } onClicked: { - // Set parent, X & Y positions for the messageContextMenu - messageContextMenu.parent = root - messageContextMenu.setXPosition = function() { return 0} - messageContextMenu.setYPosition = function() { return root.height + 4} - clickMessage(true) + if (!!messageContextMenu) { + // Set parent, X & Y positions for the messageContextMenu + messageContextMenu.parent = root + messageContextMenu.setXPosition = function() { return 0} + messageContextMenu.setYPosition = function() { return root.height + 4} + } + root.clickMessage(true); } } } diff --git a/ui/app/AppLayouts/Chat/controls/activityCenter/ChannelBadge.qml b/ui/app/AppLayouts/Chat/controls/activityCenter/ChannelBadge.qml new file mode 100644 index 0000000000..04dcaa0722 --- /dev/null +++ b/ui/app/AppLayouts/Chat/controls/activityCenter/ChannelBadge.qml @@ -0,0 +1,57 @@ +import QtQuick 2.3 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.3 +import Qt.labs.platform 1.1 + +import utils 1.0 +import "../../../../../shared" +import "../../../../../shared/panels" +import "../../../../../shared/status" + +Item { + id: channelBadge + + property int realChatType: -1 + property string name: "channelName" + property color textColor + property string chatId: "" + property string profileImage: "" + property string identicon + + SVGImage { + id: channelIcon + width: 16 + height: 16 + fillMode: Image.PreserveAspectFit + source: Style.svg("channel-icon-" + (realChatType === Constants.chatTypePublic ? "public-chat" : "group")) + anchors.left: parent.left + anchors.verticalCenter:parent.verticalCenter + } + + StatusIdenticon { + id: contactImage + height: 16 + width: 16 + chatId: chatId + chatName: name + chatType: realChatType + identicon: profileImage || identicon + anchors.left: channelIcon.right + anchors.leftMargin: 4 + anchors.verticalCenter: parent.verticalCenter + letterSize: 11 + } + + StyledText { + id: contactInfo + text: realChatType !== Constants.chatTypePublic ? + Emoji.parse(Utils.removeStatusEns(Utils.filterXSS(name))) : + "#" + Utils.filterXSS(name) + anchors.left: contactImage.right + anchors.leftMargin: 4 + color: textColor + font.weight: Font.Medium + font.pixelSize: 13 + anchors.verticalCenter: parent.verticalCenter + } +} diff --git a/ui/app/AppLayouts/Chat/controls/activityCenter/CommunityBadge.qml b/ui/app/AppLayouts/Chat/controls/activityCenter/CommunityBadge.qml new file mode 100644 index 0000000000..e8bac5a9ce --- /dev/null +++ b/ui/app/AppLayouts/Chat/controls/activityCenter/CommunityBadge.qml @@ -0,0 +1,119 @@ +import QtQuick 2.3 +import QtGraphicalEffects 1.13 +import StatusQ.Components 0.1 + +import utils 1.0 + +import "../../../../../shared" +import "../../../../../shared/panels" +import "../../../../../shared/status" +import "../../../../../shared/controls" + +Item { + id: communityBadge + + property string image: "" + property string iconColor: "" + property bool useLetterIdenticon: !image + property string communityName: "" + property string channelName: "" + property string communityId: "" + property string name: "channelName" + property color textColor + + signal communityNameClicked() + signal channelNameClicked() + + SVGImage { + id: communityIcon + visible: !hideSecondIcon + width: 16 + height: 16 + source: Style.svg("communities") + anchors.left: parent.left + anchors.verticalCenter:parent.verticalCenter + + ColorOverlay { + anchors.fill: parent + source: parent + color: textColor + } + } + + Loader { + id: communityImageLoader + active: true + anchors.left: communityIcon.visible ? communityIcon.right : parent.left + anchors.leftMargin: 2 + anchors.verticalCenter: parent.verticalCenter + sourceComponent: communityBadge.useLetterIdenticon ? letterIdenticon :imageIcon + } + + Component { + id: imageIcon + RoundedImage { + source: communityBadge.image + noMouseArea: true + noHover: true + width: 16 + height: 16 + } + } + + Component { + id: letterIdenticon + StatusLetterIdenticon { + width: 16 + height: 16 + letterSize: 12 + name: communityBadge.communityName + color: communityBadge.iconColor + } + } + + StyledTextEdit { + id: communityName + text: Utils.getLinkStyle(communityBadge.communityName, hoveredLink) + height: 18 + readOnly: true + textFormat: Text.RichText + width: implicitWidth > 300 ? 300 : implicitWidth + clip: true + anchors.left: communityImageLoader.right + anchors.leftMargin: 4 + color: textColor + font.pixelSize: 13 + anchors.verticalCenter: parent.verticalCenter + onLinkActivated: communityNameClicked() + } + + SVGImage { + id: caretImage + source: Style.svg("show-category") + width: 16 + height: 16 + anchors.left: communityName.right + anchors.verticalCenter: parent.verticalCenter + + ColorOverlay { + anchors.fill: parent + source: parent + color: textColor + } + } + + StyledTextEdit { + id: channelName + text: Utils.getLinkStyle(communityBadge.channelName || name, hoveredLink) + height: 18 + readOnly: true + textFormat: Text.RichText + width: implicitWidth > 300 ? 300 : implicitWidth + clip: true + anchors.left: caretImage.right + color: textColor + font.pixelSize: 13 + anchors.verticalCenter: parent.verticalCenter + onLinkActivated: channelNameClicked() + } +} diff --git a/ui/app/AppLayouts/Chat/controls/activityCenter/ReplyComponent.qml b/ui/app/AppLayouts/Chat/controls/activityCenter/ReplyComponent.qml new file mode 100644 index 0000000000..44571d852f --- /dev/null +++ b/ui/app/AppLayouts/Chat/controls/activityCenter/ReplyComponent.qml @@ -0,0 +1,45 @@ +import QtQuick 2.3 +import QtQuick.Controls 2.3 +import QtQuick.Layouts 1.3 +import Qt.labs.platform 1.1 + +import utils 1.0 + +import "../../../../../shared/panels" +import "../../../../../shared/controls" + +Item { + id: replyComponent + + property int replyMessageIndex: wrapper.replyMessageIndex + property string repliedMessageContent: wrapper.repliedMessageContent + + onReplyMessageIndexChanged: { + wrapper.visible = replyMessageIndex > -1 + } + + SVGImage { + id: replyIcon + width: 16 + height: 16 + source: Style.svg("reply-small-arrow") + anchors.left: parent.left + anchors.verticalCenter:parent.verticalCenter + } + + StyledTextEdit { + text: Utils.getReplyMessageStyle(Emoji.parse(Utils.linkifyAndXSS(repliedMessageContent), Emoji.size.small), false, appSettings.useCompactMode) + textFormat: Text.RichText + height: 18 + width: implicitWidth > 300 ? 300 : implicitWidth + clip: true + anchors.left: replyIcon.right + anchors.leftMargin: 4 + color: Style.current.secondaryText + font.weight: Font.Medium + font.pixelSize: 13 + anchors.verticalCenter: parent.verticalCenter + selectByMouse: true + readOnly: true + } +} diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/MembershipRadioButton.qml b/ui/app/AppLayouts/Chat/controls/communities/MembershipRadioButton.qml similarity index 100% rename from ui/app/AppLayouts/Chat/CommunityComponents/MembershipRadioButton.qml rename to ui/app/AppLayouts/Chat/controls/communities/MembershipRadioButton.qml diff --git a/ui/app/AppLayouts/Chat/controls/messages/FetchMoreMessagesButton.qml b/ui/app/AppLayouts/Chat/controls/messages/FetchMoreMessagesButton.qml new file mode 100644 index 0000000000..e9ed4d44ec --- /dev/null +++ b/ui/app/AppLayouts/Chat/controls/messages/FetchMoreMessagesButton.qml @@ -0,0 +1,79 @@ +import QtQuick 2.13 +import "../../../../../shared" +import "../../../../../shared/panels" +import "../../../../../shared/status/core" + +import utils 1.0 + +Item { + id: root + height: childrenRect.height + Style.current.smallPadding * 2 + anchors.left: parent.left + anchors.right: parent.right + property int nextMessageIndex + property string nextMsgTimestamp + signal clicked() + signal timerTriggered() + Timer { + id: timer + interval: 3000 + onTriggered: { + fetchLoaderIndicator.active = false; + fetchMoreButton.visible = true; + fetchDate.visible = true; + root.timerTriggered(); + } + } + + Separator { + id: sep1 + } + Loader { + id: fetchLoaderIndicator + anchors.top: sep1.bottom + anchors.topMargin: Style.current.padding + anchors.left: parent.left + anchors.right: parent.right + active: false + sourceComponent: StatusLoadingIndicator { + width: 12 + height: 12 + } + } + StyledText { + id: fetchMoreButton + font.weight: Font.Medium + font.pixelSize: Style.current.primaryTextFontSize + color: Style.current.blue + //% "↓ Fetch more messages" + text: qsTrId("load-more-messages") + horizontalAlignment: Text.AlignHCenter + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: sep1.bottom + anchors.topMargin: Style.current.smallPadding + MouseArea { + cursorShape: Qt.PointingHandCursor + anchors.fill: parent + onClicked: { + root.clicked(); + fetchLoaderIndicator.active = true; + fetchMoreButton.visible = false; + fetchDate.visible = false; + } + } + } + StyledText { + id: fetchDate + anchors.top: fetchMoreButton.bottom + anchors.topMargin: 3 + anchors.horizontalCenter: parent.horizontalCenter + horizontalAlignment: Text.AlignHCenter + color: Style.current.secondaryText + //% "before %1" + text: qsTrId("before--1").arg((nextMessageIndex > -1 ? new Date(nextMsgTimestamp * 1) : new Date()).toLocaleString(Qt.locale(globalSettings.locale))) + } + Separator { + anchors.top: fetchDate.bottom + anchors.topMargin: Style.current.smallPadding + } +} diff --git a/ui/app/AppLayouts/Chat/controls/messages/GapComponent.qml b/ui/app/AppLayouts/Chat/controls/messages/GapComponent.qml new file mode 100644 index 0000000000..97c29d498c --- /dev/null +++ b/ui/app/AppLayouts/Chat/controls/messages/GapComponent.qml @@ -0,0 +1,52 @@ +import QtQuick 2.13 +import "../../../../../shared" +import "../../../../../shared/panels" +import "../../../../../shared/status/core" + +import utils 1.0 + +Item { + id: root + height: childrenRect.height + Style.current.smallPadding * 2 + anchors.left: parent.left + anchors.right: parent.right + signal clicked() + Separator { + id: sep1 + } + StyledText { + id: fetchMoreButton + font.weight: Font.Medium + font.pixelSize: Style.current.primaryTextFontSize + color: Style.current.blue + //% "↓ " + //% "Fetch messages" + text: qsTrId("fetch-messages") + horizontalAlignment: Text.AlignHCenter + anchors.horizontalCenter: parent.horizontalCenter + anchors.top: sep1.bottom + anchors.topMargin: Style.current.smallPadding + MouseArea { + cursorShape: Qt.PointingHandCursor + anchors.fill: parent + onClicked: { + root.clicked(); + } + } + } + StyledText { + id: fetchDate + anchors.top: fetchMoreButton.bottom + anchors.topMargin: 3 + anchors.horizontalCenter: parent.horizontalCenter + horizontalAlignment: Text.AlignHCenter + color: Style.current.secondaryText + //% "before %1" + //% "Between %1 and %2" + text: qsTrId("between--1-and--2").arg(new Date(root.gapFrom*1000)).arg(new Date(root.gapTo*1000)) + } + Separator { + anchors.top: fetchDate.bottom + anchors.topMargin: Style.current.smallPadding + } +} diff --git a/ui/app/AppLayouts/Chat/data/channelList.js b/ui/app/AppLayouts/Chat/helpers/channelList.js similarity index 100% rename from ui/app/AppLayouts/Chat/data/channelList.js rename to ui/app/AppLayouts/Chat/helpers/channelList.js diff --git a/ui/app/AppLayouts/Chat/components/emojiList.js b/ui/app/AppLayouts/Chat/helpers/emojiList.js similarity index 100% rename from ui/app/AppLayouts/Chat/components/emojiList.js rename to ui/app/AppLayouts/Chat/helpers/emojiList.js diff --git a/ui/app/AppLayouts/Chat/components/AcceptRejectOptionsButtons.qml b/ui/app/AppLayouts/Chat/panels/AcceptRejectOptionsButtonsPanel.qml similarity index 100% rename from ui/app/AppLayouts/Chat/components/AcceptRejectOptionsButtons.qml rename to ui/app/AppLayouts/Chat/panels/AcceptRejectOptionsButtonsPanel.qml diff --git a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityCenterTopBar.qml b/ui/app/AppLayouts/Chat/panels/ActivityCenterPopupTopBarPanel.qml similarity index 75% rename from ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityCenterTopBar.qml rename to ui/app/AppLayouts/Chat/panels/ActivityCenterPopupTopBarPanel.qml index 48be559b98..76f0135533 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityCenterTopBar.qml +++ b/ui/app/AppLayouts/Chat/panels/ActivityCenterPopupTopBarPanel.qml @@ -2,16 +2,29 @@ import QtQuick 2.13 import QtQuick.Controls 2.13 import utils 1.0 -import "../../../../../shared" -import "../../../../../shared/popups" -import "../../../../../shared/panels" -import "../../../../../shared/status" +import "../../../../shared" +import "../../../../shared/popups" +import "../../../../shared/panels" +import "../../../../shared/status" import ".." Item { + id: root width: parent.width height: 64 + property bool allBtnHighlighted: false + property bool repliesBtnHighlighted: false + property bool mentionsBtnHighlighted: false + property alias repliesBtnEnabled: repliesbtn.enabled + property alias mentionsBtnEnabled: mentionsBtn.enabled + property alias errorText: errorText.text + signal allBtnClicked() + signal repliesBtnClicked() + signal mentionsBtnClicked() + signal preferencesClicked() + signal markAllReadClicked() + Row { id: filterButtons anchors.verticalCenter: parent.verticalCenter @@ -26,8 +39,10 @@ Item { text: qsTrId("all") type: "secondary" size: "small" - highlighted: activityCenter.currentFilter === ActivityCenter.Filter.All - onClicked: activityCenter.currentFilter = ActivityCenter.Filter.All + highlighted: root.allBtnHighlighted + onClicked: { + root.allBtnClicked(); + } } StatusButton { @@ -35,21 +50,23 @@ Item { //% "Mentions" text: qsTrId("mentions") type: "secondary" - enabled: hasMentions size: "small" - highlighted: activityCenter.currentFilter === ActivityCenter.Filter.Mentions - onClicked: activityCenter.currentFilter = ActivityCenter.Filter.Mentions + highlighted: root.mentionsBtnHighlighted + onClicked: { + root.mentionsBtnClicked(); + } } StatusButton { id: repliesbtn //% "Replies" text: qsTrId("replies") - enabled: hasReplies type: "secondary" size: "small" - highlighted: activityCenter.currentFilter === ActivityCenter.Filter.Replies - onClicked: activityCenter.currentFilter = ActivityCenter.Filter.Replies + highlighted: root.repliesBtnHighlighted + onClicked: { + root.repliesBtnClicked(); + } } // StatusButton { @@ -80,9 +97,7 @@ Item { icon.height: 24 width: 32 height: 32 - onClicked: { - errorText.text = chatsModel.activityNotificationList.markAllActivityCenterNotificationsRead() - } + onClicked: markAllReadClicked() StatusToolTip { visible: markAllReadBtn.hovered @@ -119,11 +134,7 @@ Item { //% "Notification settings" text: qsTrId("chat-notification-preferences") onTriggered: { - activityCenter.close() - appMain.changeAppSection(Constants.profile) - // TODO: replace with shared store constant - // Profile/RootStore.notifications_id - profileLayoutContainer.changeProfileSection(7) + root.preferencesClicked(); } } } diff --git a/ui/app/AppLayouts/Chat/panels/ActivityChannelBadgePanel.qml b/ui/app/AppLayouts/Chat/panels/ActivityChannelBadgePanel.qml new file mode 100644 index 0000000000..f396bb27fb --- /dev/null +++ b/ui/app/AppLayouts/Chat/panels/ActivityChannelBadgePanel.qml @@ -0,0 +1,90 @@ +import QtQuick 2.13 + +import utils 1.0 +import "../../../../shared" +import "../../../../shared/panels" +import "../../../../shared/controls" +import "../../../../shared/status" + +import "../controls/activityCenter" as ActivityCenter + +Rectangle { + id: wrapper + + property string name: "channelName" + property string identicon: "" + property string chatId: "" + property int realChatType: -1 + property string communityId + property string channelName: "" + property string communityName: "" + property string communityColor: "" + property string communityThumbnailImage: "" + property int replyMessageIndex: -1 + property string repliedMessageContent: "" + property int notificationType + property string profileImage: "" + + property color textColor: Style.current.textColor + + signal communityNameClicked() + signal channelNameClicked() + + height: visible ? 24 : 0 + width: childrenRect.width + 12 + color: Style.current.transparent + border.color: Style.current.borderSecondary + border.width: 1 + radius: 11 + + Loader { + active: true + height: parent.height + anchors.left: parent.left + anchors.leftMargin: 4 + sourceComponent: { + switch (wrapper.notificationType) { + case Constants.activityCenterNotificationTypeMention: return wrapper.communityId ? communityBadgeComponent : channelBadgeComponent + case Constants.activityCenterNotificationTypeReply: return replyComponent + default: return wrapper.communityId ? communityBadgeComponent : channelBadgeComponent + } + } + } + + ActivityCenter.ReplyComponent { + id: replyComponent + width: childrenRect.width + height: parent.height + replyMessageIndex: wrapper.replyMessageIndex + repliedMessageContent: wrapper.repliedMessageContent + } + + ActivityCenter.CommunityBadge { + id: communityBadgeComponent + width: childrenRect.width + height: parent.height + + textColor: wrapper.textColor + image: wrapper.communityThumbnailImage + iconColor: wrapper.communityColor + communityName: wrapper.communityName + channelName: wrapper.channelName + name: wrapper.name + + onCommunityNameClicked: communityNameClicked() + onChannelNameClicked: channelNameClicked() + } + + ActivityCenter.ChannelBadge { + id: channelBadgeComponent + width: childrenRect.width + height: parent.height + + realChatType: wrapper.realChatType + textColor: wrapper.textColor + name: wrapper.name + chatId: wrapper.chatId + profileImage: wrapper.profileImage + identicon: wrapper.identicon + } +} diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/AudioPlayer.qml b/ui/app/AppLayouts/Chat/panels/AudioPlayerPanel.qml similarity index 97% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/AudioPlayer.qml rename to ui/app/AppLayouts/Chat/panels/AudioPlayerPanel.qml index 9546487370..2001a280c8 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/AudioPlayer.qml +++ b/ui/app/AppLayouts/Chat/panels/AudioPlayerPanel.qml @@ -1,7 +1,7 @@ import QtQuick 2.3 import QtMultimedia 5.14 -import "../../../../../shared" -import "../../../../../shared/panels" +import "../../../../shared" +import "../../../../shared/panels" import utils 1.0 diff --git a/ui/app/AppLayouts/Chat/components/BadgeContent.qml b/ui/app/AppLayouts/Chat/panels/BadgeContentPanel.qml similarity index 100% rename from ui/app/AppLayouts/Chat/components/BadgeContent.qml rename to ui/app/AppLayouts/Chat/panels/BadgeContentPanel.qml diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatButtons.qml b/ui/app/AppLayouts/Chat/panels/ChatButtonsPanel.qml similarity index 93% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatButtons.qml rename to ui/app/AppLayouts/Chat/panels/ChatButtonsPanel.qml index c573051698..e0bff5217e 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatButtons.qml +++ b/ui/app/AppLayouts/Chat/panels/ChatButtonsPanel.qml @@ -1,19 +1,23 @@ import QtQuick 2.13 import QtGraphicalEffects 1.13 -import "../../../../../shared" -import "../../../../../shared/status" +import "../../../../shared" +import "../../../../shared/status" import utils 1.0 Rectangle { id: buttonsContainer property bool parentIsHovered: false - property bool showEdit: true - signal hoverChanged(bool hovered) property int containerMargin: 2 property int contentType: 2 property var messageContextMenu property bool showMoreButton: true + property bool activityCenterMessage + property string fromAuthor + property alias editBtnActive: editBtn.active + signal hoverChanged(bool hovered) + signal setMessageActive(string messageId, bool active) + signal clickMessage(bool isProfileClick, bool isSticker, bool isImage, var image, bool emojiOnly) visible: !activityCenterMessage && (buttonsContainer.parentIsHovered || isMessageActive) @@ -108,7 +112,6 @@ Rectangle { Loader { id: editBtn - active: isText && !isEdit && isCurrentUser && showEdit sourceComponent: StatusIconButton { id: btn icon.name: "edit-message" diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatReply.qml b/ui/app/AppLayouts/Chat/panels/ChatReplyPanel.qml similarity index 81% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatReply.qml rename to ui/app/AppLayouts/Chat/panels/ChatReplyPanel.qml index 0d3a47cd9d..8fe6f997e3 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatReply.qml +++ b/ui/app/AppLayouts/Chat/panels/ChatReplyPanel.qml @@ -1,32 +1,49 @@ import QtQuick 2.14 import QtQuick.Shapes 1.13 import QtGraphicalEffects 1.13 -import "../../../../../shared" -import "../../../../../shared/panels" -import "../../../../../shared/controls" -import "../../../../../shared/status" + +import "../../../../shared" +import "../../../../shared/panels" +import "../../../../shared/controls" +import "../../../../shared/status" +import "../controls" import utils 1.0 Loader { + id: root + + property int nameMargin: 6 +// property bool isCurrentUser: false property int textFieldWidth: item ? item.textField.width : 0 property int textFieldImplicitWidth: 0 property int authorWidth: item ? item.authorMetrics.width : 0 - +// property int repliedMessageType +// property string repliedMessageImage +// property string repliedMessageUserIdenticon +// property bool repliedMessageIsEdited +// property string repliedMessageUserImage +// property string repliedMessageAuthor +// property string repliedMessageContent property bool longReply: false property color elementsColor: isCurrentUser ? Style.current.chatReplyCurrentUser : Style.current.secondaryText property var container property int chatHorizontalPadding +// property string responseTo: "" + property var stickerData - property int nameMargin: 6 - - id: root - active: responseTo !== "" && replyMessageIndex > -1 && !activityCenterMessage +// signal scrollToBottom(bool isit, var container) + signal clickMessage(bool isProfileClick, bool isSticker, bool isImage, var image, bool emojiOnly, bool hideEmojiPicker, bool isReply) sourceComponent: Component { Item { property alias textField: lblReplyMessage property alias authorMetrics: txtAuthorMetrics + property var messageEdited: function(id, content) { + if (responseTo === id){ + lblReplyMessage.text = Utils.getReplyMessageStyle(Emoji.parse(Utils.linkifyAndXSS(content + Constants.editLabel), Emoji.size.small), isCurrentUser, appSettings.useCompactMode) + } + } id: chatReply // childrenRect.height shows a binding loop for some reason, so we use heights instead @@ -90,17 +107,12 @@ Loader { active: true anchors.left: replyCorner.right anchors.leftMargin: Style.current.halfPadding - identiconImageSource: repliedMessageUserIdenticon +// identiconImageSource: repliedMessageUserIdenticon isReplyImage: true - profileImage: repliedMessageUserImage - } - - Connections { - target: chatsModel.messageView - onMessageEdited: { - if (responseTo === editedMessageId){ - lblReplyMessage.text = Utils.getReplyMessageStyle(Emoji.parse(Utils.linkifyAndXSS(editedMessageContent + Constants.editLabel), Emoji.size.small), isCurrentUser, appSettings.useCompactMode) - } +// profileImage: repliedMessageUserImage +// isCurrentUser: isCurrentUser + onClickMessage: { + root.clickMessage(true, false, false, null, false, false, isReplyImage) } } @@ -141,7 +153,7 @@ Loader { id: stickerId imageHeight: 56 imageWidth: 56 - stickerData: chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "sticker") + stickerData: root.stickerData contentType: repliedMessageType onLoaded: { scrollToBottom(true, root.container) diff --git a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatRequestMessage.qml b/ui/app/AppLayouts/Chat/panels/ChatRequestMessagePanel.qml similarity index 87% rename from ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatRequestMessage.qml rename to ui/app/AppLayouts/Chat/panels/ChatRequestMessagePanel.qml index c98b2ce663..faf9495916 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatRequestMessage.qml +++ b/ui/app/AppLayouts/Chat/panels/ChatRequestMessagePanel.qml @@ -1,15 +1,16 @@ import QtQuick 2.13 import utils 1.0 -import "../../../../../shared" -import "../../../../../shared/panels" -import "../../../../../shared/status" +import "../../../../shared" +import "../../../../shared/panels" +import "../../../../shared/status" Item { - visible: chatsModel.channelView.activeChannel.chatType === Constants.chatTypeOneToOne && (!isContact /*|| !contactRequestReceived*/) width: parent.width height: childrenRect.height + signal addContactClicked() + Image { id: waveImg source: Style.png("wave") @@ -54,6 +55,6 @@ Item { anchors.top: contactText2.bottom anchors.topMargin: Style.current.smallPadding anchors.horizontalCenter: parent.horizontalCenter - onClicked: profileModel.contacts.addContact(activeChatId) + onClicked: addContactClicked() } } diff --git a/ui/app/AppLayouts/Chat/ContactsColumn/ClosedEmptyView.qml b/ui/app/AppLayouts/Chat/panels/ClosedEmptyPanel.qml similarity index 85% rename from ui/app/AppLayouts/Chat/ContactsColumn/ClosedEmptyView.qml rename to ui/app/AppLayouts/Chat/panels/ClosedEmptyPanel.qml index 4ec14175f8..81ffe42a75 100644 --- a/ui/app/AppLayouts/Chat/ContactsColumn/ClosedEmptyView.qml +++ b/ui/app/AppLayouts/Chat/panels/ClosedEmptyPanel.qml @@ -2,7 +2,6 @@ import QtQuick 2.13 import QtQuick.Controls 2.13 import QtQuick.Layouts 1.13 import QtGraphicalEffects 1.13 -import "../components" import "../../../../shared" import "../../../../shared/panels" @@ -28,9 +27,3 @@ Item { color: Style.current.darkGrey } } - -/*##^## -Designer { - D{i:0;autoSize:true;formeditorColor:"#ffffff";formeditorZoom:1.25;height:500;width:300} -} -##^##*/ diff --git a/ui/app/AppLayouts/Chat/components/ContactList.qml b/ui/app/AppLayouts/Chat/panels/ContactListPanel.qml similarity index 98% rename from ui/app/AppLayouts/Chat/components/ContactList.qml rename to ui/app/AppLayouts/Chat/panels/ContactListPanel.qml index 8f80b1cb29..7fa64bd675 100644 --- a/ui/app/AppLayouts/Chat/components/ContactList.qml +++ b/ui/app/AppLayouts/Chat/panels/ContactListPanel.qml @@ -4,6 +4,8 @@ import QtQuick.Controls 2.3 import utils 1.0 import "../../../../shared" +import "../controls" + ScrollView { property alias membersData: membersData property string searchString diff --git a/ui/app/AppLayouts/Chat/components/ContactRequest.qml b/ui/app/AppLayouts/Chat/panels/ContactRequestPanel.qml similarity index 81% rename from ui/app/AppLayouts/Chat/components/ContactRequest.qml rename to ui/app/AppLayouts/Chat/panels/ContactRequestPanel.qml index 1044cd6fd0..5e227f711a 100644 --- a/ui/app/AppLayouts/Chat/components/ContactRequest.qml +++ b/ui/app/AppLayouts/Chat/panels/ContactRequestPanel.qml @@ -14,6 +14,8 @@ Rectangle { property string localNickname property var profileClick: function() {} signal blockContactActionTriggered(name: string, address: string) + signal acceptClicked() + signal declineClicked() property bool isHovered: false id: container @@ -49,17 +51,14 @@ Rectangle { onHoveredChanged: container.isHovered = hovered } - AcceptRejectOptionsButtons { + AcceptRejectOptionsButtonsPanel { id: buttons anchors.right: parent.right anchors.rightMargin: Style.current.padding anchors.verticalCenter: parent.verticalCenter - onAcceptClicked: { - chatsModel.channelView.joinPrivateChat(container.address, "") - profileModel.contacts.addContact(container.address) - } - onDeclineClicked: profileModel.contacts.rejectContactRequest(container.address) - onProfileClicked: profileClick(true, name, address, identicon, "", localNickname) + onAcceptClicked: container.acceptClicked() + onDeclineClicked: container.declineClicked() + onProfileClicked: container.profileClick(true, name, address, identicon, "", localNickname) onBlockClicked: container.blockContactActionTriggered(name, address) } } diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/EmojiReactions.qml b/ui/app/AppLayouts/Chat/panels/EmojiReactionsPanel.qml similarity index 79% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/EmojiReactions.qml rename to ui/app/AppLayouts/Chat/panels/EmojiReactionsPanel.qml index 1cb6f813e6..44dc3261d9 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/EmojiReactions.qml +++ b/ui/app/AppLayouts/Chat/panels/EmojiReactionsPanel.qml @@ -1,10 +1,10 @@ import QtQuick 2.3 import QtQuick.Controls 2.13 import QtGraphicalEffects 1.13 -import "../../../../../shared" -import "../../../../../shared/panels" -import "../../../../../shared/status" +import "../../../../shared" +import "../../../../shared/panels" +import "../../../../shared/status" import utils 1.0 Item { @@ -13,48 +13,13 @@ Item { width: childrenRect.width property int imageMargin: 4 - signal hoverChanged(bool hovered) +// property bool isCurrentUser +// property var emojiReactionsModel +// property bool isMessageActive signal addEmojiClicked() - - function lastTwoItems(nodes) { - //% " and " - return nodes.join(qsTrId("-and-")); - } - - function showReactionAuthors(fromAccounts, emojiId) { - let tooltip - if (fromAccounts.length === 1) { - tooltip = fromAccounts[0] - } else if (fromAccounts.length === 2) { - tooltip = lastTwoItems(fromAccounts); - } else { - var leftNode = []; - var rightNode = []; - const maxReactions = 12 - let maximum = Math.min(maxReactions, fromAccounts.length) - - if (fromAccounts.length > maxReactions) { - leftNode = fromAccounts.slice(0, maxReactions); - rightNode = fromAccounts.slice(maxReactions, fromAccounts.length); - return (rightNode.length === 1) ? - lastTwoItems([leftNode.join(", "), rightNode[0]]) : - //% "%1 more" - lastTwoItems([leftNode.join(", "), qsTrId("-1-more").arg(rightNode.length)]); - } - - leftNode = fromAccounts.slice(0, maximum - 1); - rightNode = fromAccounts.slice(maximum - 1, fromAccounts.length); - tooltip = lastTwoItems([leftNode.join(", "), rightNode[0]]) - } - - //% " reacted with " - tooltip += qsTrId("-reacted-with-"); - let emojiHtml = Emoji.getEmojiFromId(emojiId); - if (emojiHtml) { - tooltip += emojiHtml; - } - return tooltip - } + signal hoverChanged(bool hovered) + signal toggleReaction(int emojiID) + signal setMessageActive(string messageId, bool active) Row { spacing: root.imageMargin @@ -172,8 +137,7 @@ Item { emojiContainer.isHovered = false } onClicked: { - chatsModel.toggleReaction(messageId, modelData.emojiId) - + toggleReaction(modelData.emojiId) } } } @@ -210,7 +174,7 @@ Item { onExited: addEmojiBtn.isHovered = false onClicked: { if (typeof isMessageActive !== "undefined") { - setMessageActive(messageId, true) + setMessageActive(messageId, true); } root.addEmojiClicked(); } diff --git a/ui/app/AppLayouts/Chat/ChatColumn/EmptyChat.qml b/ui/app/AppLayouts/Chat/panels/EmptyChatPanel.qml similarity index 89% rename from ui/app/AppLayouts/Chat/ChatColumn/EmptyChat.qml rename to ui/app/AppLayouts/Chat/panels/EmptyChatPanel.qml index a748827e3d..2e81c8a6d3 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/EmptyChat.qml +++ b/ui/app/AppLayouts/Chat/panels/EmptyChatPanel.qml @@ -6,13 +6,15 @@ import "../../../../shared/popups" import "../../../../shared/panels" import utils 1.0 -import "../components" Item { id: element Layout.fillHeight: true Layout.fillWidth: true + + signal shareChatKeyClicked() + Image { id: walkieTalkieImage anchors.horizontalCenter: parent.horizontalCenter @@ -44,9 +46,7 @@ Item { onExited: { parent.font.underline = false } - onClicked: { - openProfilePopup(profileModel.profile.username, profileModel.profile.pubKey, profileModel.profile.thumbnailImage); - } + onClicked: shareChatKeyClicked() } } @@ -101,8 +101,3 @@ Item { id: inviteFriendsPopup } } -/*##^## -Designer { - D{i:0;autoSize:true;formeditorColor:"#ffffff";formeditorZoom:2;height:480;width:640} -} -##^##*/ diff --git a/ui/app/AppLayouts/Chat/ContactsColumn/EmptyView.qml b/ui/app/AppLayouts/Chat/panels/EmptyViewPanel.qml similarity index 95% rename from ui/app/AppLayouts/Chat/ContactsColumn/EmptyView.qml rename to ui/app/AppLayouts/Chat/panels/EmptyViewPanel.qml index d5cc588ee3..b99415849e 100644 --- a/ui/app/AppLayouts/Chat/ContactsColumn/EmptyView.qml +++ b/ui/app/AppLayouts/Chat/panels/EmptyViewPanel.qml @@ -2,8 +2,7 @@ import QtQuick 2.13 import QtQuick.Controls 2.13 import QtQuick.Layouts 1.13 import QtGraphicalEffects 1.13 -import "../components" -import "../data/channelList.js" as ChannelJSON +import "../helpers/channelList.js" as ChannelJSON import "../../../../shared" import "../../../../shared/popups" import "../../../../shared/panels" @@ -16,6 +15,8 @@ Rectangle { Layout.fillHeight: true Layout.fillWidth: true + signal suggestedMessageClicked(string channel) + height: suggestionContainer.height + inviteFriendsContainer.height + Style.current.padding * 2 border.color: Style.current.secondaryMenuBorder radius: 16 @@ -138,15 +139,10 @@ Rectangle { anchors.topMargin: Style.current.smallPadding width: parent.width - SuggestedChannels { + SuggestedChannelsPanel { id: sectionRepeater + onSuggestedMessageClicked: emptyView.suggestedMessageClicked(channel) } } } } - -/*##^## -Designer { - D{i:0;autoSize:true;formeditorColor:"#ffffff";formeditorZoom:1.25;height:500;width:300} -} -##^##*/ diff --git a/ui/app/AppLayouts/Chat/components/FetchMoreMessages.qml b/ui/app/AppLayouts/Chat/panels/FetchMoreMessagesMenuPanel.qml similarity index 99% rename from ui/app/AppLayouts/Chat/components/FetchMoreMessages.qml rename to ui/app/AppLayouts/Chat/panels/FetchMoreMessagesMenuPanel.qml index 222acc457f..0ba3d8189a 100644 --- a/ui/app/AppLayouts/Chat/components/FetchMoreMessages.qml +++ b/ui/app/AppLayouts/Chat/panels/FetchMoreMessagesMenuPanel.qml @@ -1,6 +1,7 @@ import QtQuick 2.13 import QtQuick.Controls 2.13 import QtQuick.Layouts 1.13 + import "../../../../shared" import "../../../../shared/popups" import "../../../../shared/status" @@ -8,6 +9,8 @@ import "../../../../shared/status" import utils 1.0 // TODO: replace with StatusPopupmenu +//Todo Unsed? + PopupMenu { //% "Fetch Messages" title: qsTrId("fetch-messages") diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/InvitationBubble.qml b/ui/app/AppLayouts/Chat/panels/InvitationBubblePanel.qml similarity index 98% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/InvitationBubble.qml rename to ui/app/AppLayouts/Chat/panels/InvitationBubblePanel.qml index ed13caea0a..952ed9d427 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/InvitationBubble.qml +++ b/ui/app/AppLayouts/Chat/panels/InvitationBubblePanel.qml @@ -1,12 +1,12 @@ import QtQuick 2.3 import QtQuick.Dialogs 1.3 -import "../../../../../shared" -import "../../../../../shared/popups" -import "../../../../../shared/panels" -import "../../../../../shared/status" + +import "../../../../shared" +import "../../../../shared/popups" +import "../../../../shared/panels" +import "../../../../shared/status" import utils 1.0 -import "./TransactionComponents" Item { property string communityId diff --git a/ui/app/AppLayouts/Chat/components/MessageContextMenu.qml b/ui/app/AppLayouts/Chat/panels/MessageContextMenuPanel.qml similarity index 98% rename from ui/app/AppLayouts/Chat/components/MessageContextMenu.qml rename to ui/app/AppLayouts/Chat/panels/MessageContextMenuPanel.qml index 5a55f2211c..4d4662e8b9 100644 --- a/ui/app/AppLayouts/Chat/components/MessageContextMenu.qml +++ b/ui/app/AppLayouts/Chat/panels/MessageContextMenuPanel.qml @@ -12,7 +12,7 @@ import "../../../../shared" import "../../../../shared/popups" import "../../../../shared/panels" import "../../../../shared/status" -import "./" +import "../controls" StatusPopupMenu { id: messageContextMenu @@ -92,12 +92,13 @@ StatusPopupMenu { bottomPadding: messageContextMenu.emojiOnly ? 0 : Style.current.padding Repeater { - model: reactionModel + model: messageContextMenu.reactionModel delegate: EmojiReaction { source: Style.svg(filename) emojiId: model.emojiId reactedByUser: !!messageContextMenu.emojiReactionsReactedByUser[model.emojiId] - closeModal: function () { + onCloseModal: { + chatsModel.toggleReaction(SelectedMessage.messageId, emojiId) messageContextMenu.close() } } diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/StatusUpdate.qml b/ui/app/AppLayouts/Chat/panels/StatusUpdatePanel.qml similarity index 69% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/StatusUpdate.qml rename to ui/app/AppLayouts/Chat/panels/StatusUpdatePanel.qml index 58f3e45838..4cdd86f17f 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/StatusUpdate.qml +++ b/ui/app/AppLayouts/Chat/panels/StatusUpdatePanel.qml @@ -1,20 +1,39 @@ import QtQuick 2.3 import QtGraphicalEffects 1.13 -import "../../../../../shared" -import "../../../../../shared/panels" +import "../../../../shared" +import "../../../../shared/panels" +import "../../../../shared/status" import utils 1.0 -import "../../../../../shared/status" + +import "../controls" +//TODO remove this or make view +import "../views" MouseArea { id: root - property var clickMessage: function () {} property bool hovered: containsMouse property var container property int statusAgeEpoch: 0 property var messageContextMenu +// property var emojiReactionsModel +// property string timestamp: "" +// property bool isCurrentUser: false +// property bool isMessageActive: false +// property string userName: "" +// property string localName: "" +// property string displayUserName: "" +// property bool isImage: false +// property bool isMessage: false +// property string profileImageSource: "" +// property string userIdenticon: "" + signal userNameClicked(bool isProfileClick) + signal setMessageActive(string messageId, bool active) + signal emojiBtnClicked(bool isProfileClick, bool isSticker, bool isImage, var image, bool emojiOnly) + signal clickMessage(bool isProfileClick, bool isSticker, bool isImage, var image, bool emojiOnly, bool hideEmojiPicker, bool isReply) + anchors.top: parent.top anchors.topMargin: 0 height: (isImage ? chatImageContent.height : chatText.height) + chatName.height + 2* Style.current.padding + (emojiReactionsModel.length ? 20 : 0) @@ -23,6 +42,7 @@ MouseArea { cursorShape: Qt.PointingHandCursor propagateComposedEvents: true + signal chatImageClicked(string image) signal addEmoji(bool isProfileClick, bool isSticker, bool isImage , var image, bool emojiOnly, bool hideEmojiPicker) onClicked: { @@ -42,19 +62,34 @@ MouseArea { anchors.leftMargin: Style.current.padding anchors.top: parent.top anchors.topMargin: Style.current.halfPadding +// messageContextMenu: root.messageContextMenu +// profileImage: root.profileImageSource +// isMessage: root.isMessage +// identiconImageSource: root.userIdenticon + onClickMessage: { + root.clickMessage(true, false, false, null, false, false, isReplyImage) + } } UsernameLabel { id: chatName + z: 51 visible: chatImage.visible anchors.leftMargin: Style.current.halfPadding anchors.top: chatImage.top anchors.left: chatImage.right label.font.pixelSize: Style.current.primaryTextFontSize - z: 51 +// messageContextMenu: root.messageContextMenu +// isCurrentUser: root.isCurrentUser +// userName: root.userName +// localName: root.localName +// displayUserName: root.displayUserName + onClickMessage: { + root.userNameClicked(true); + } } - ChatTime { + ChatTimeView { id: chatTime // statusAgeEpoch is used to trigger Qt property update // since the returned string will be the same in 99% cases, this should not trigger ChatTime re-rendering @@ -63,9 +98,10 @@ MouseArea { anchors.verticalCenter: chatName.verticalCenter anchors.left: chatName.right anchors.leftMargin: Style.current.halfPadding + timestamp: root.timestamp } - ChatText { + ChatTextView { id: chatText anchors.top: chatName.visible ? chatName.bottom : chatImage.top anchors.topMargin: chatName.visible ? 6 : 0 @@ -87,8 +123,10 @@ MouseArea { StatusChatImage { imageSource: image imageWidth: 200 - onClicked: imageClick(image) container: root.container + onClicked: { + root.chatImageClicked(image); + } } } } @@ -111,7 +149,7 @@ MouseArea { messageContextMenu.parent = emojiBtn messageContextMenu.setXPosition = function() { return -messageContextMenu.width + emojiBtn.width} messageContextMenu.setYPosition = function() { return -messageContextMenu.height - 4} - root.clickMessage(false, false, false, null, true) + root.emojiBtnClicked(false, false, false, null, true) } } @@ -137,7 +175,9 @@ MouseArea { Component { id: emojiReactionsComponent - EmojiReactions { + EmojiReactionsPanel { +// isMessageActive: root.isMessageActive +// emojiReactionsModel: root.emojiReactionsModel onAddEmojiClicked: { root.addEmoji(false, false, false, null, true, false); // Set parent, X & Y positions for the messageContextMenu @@ -145,6 +185,11 @@ MouseArea { messageContextMenu.setXPosition = function() { return (messageContextMenu.parent.x + 4)} messageContextMenu.setYPosition = function() { return (-messageContextMenu.height - 4)} } + onToggleReaction: chatsModel.toggleReaction(messageId, emojiID) + +// onSetMessageActive: { +// root.setMessageActive(messageId, active);; +// } } } diff --git a/ui/app/AppLayouts/Chat/components/SuggestedChannels.qml b/ui/app/AppLayouts/Chat/panels/SuggestedChannelsPanel.qml similarity index 74% rename from ui/app/AppLayouts/Chat/components/SuggestedChannels.qml rename to ui/app/AppLayouts/Chat/panels/SuggestedChannelsPanel.qml index 6eb39bf6a8..d599bbb703 100644 --- a/ui/app/AppLayouts/Chat/components/SuggestedChannels.qml +++ b/ui/app/AppLayouts/Chat/panels/SuggestedChannelsPanel.qml @@ -5,12 +5,14 @@ import QtQuick.Layouts 1.13 import utils 1.0 import "../../../../shared" import "../../../../shared/panels" -import "../data/channelList.js" as ChannelJSON -import "./" + +import "../helpers/channelList.js" as ChannelJSON +import "../controls" Repeater { id: sectionRepeater model: ChannelJSON.categories + signal suggestedMessageClicked(string channel) Item { anchors.top: index === 0 ? parent.top : parent.children[index - 1].bottom anchors.topMargin: index === 0 ? 0 : Style.current.padding @@ -32,14 +34,13 @@ Repeater { spacing: 10 Repeater { model: modelData.channels - SuggestedChannel { channel: modelData } + SuggestedChannel { + channel: modelData + onClicked: { + suggestedMessageClicked(channel); + } + } } } - } } -/*##^## -Designer { - D{i:0;autoSize:true;height:480;width:640} -} -##^##*/ diff --git a/ui/app/AppLayouts/Chat/ChatColumn/SuggestionBox.qml b/ui/app/AppLayouts/Chat/panels/SuggestionBoxPanel.qml similarity index 99% rename from ui/app/AppLayouts/Chat/ChatColumn/SuggestionBox.qml rename to ui/app/AppLayouts/Chat/panels/SuggestionBoxPanel.qml index f6824c422a..3f5cfe93d2 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/SuggestionBox.qml +++ b/ui/app/AppLayouts/Chat/panels/SuggestionBoxPanel.qml @@ -104,7 +104,7 @@ Rectangle { color: "#22000000" } - SuggestionFilter { + SuggestionFilterPanel { id: filterItem sourceModel: container.model cursorPosition: container.cursorPosition diff --git a/ui/app/AppLayouts/Chat/ChatColumn/SuggestionFilter.qml b/ui/app/AppLayouts/Chat/panels/SuggestionFilterPanel.qml similarity index 99% rename from ui/app/AppLayouts/Chat/ChatColumn/SuggestionFilter.qml rename to ui/app/AppLayouts/Chat/panels/SuggestionFilterPanel.qml index 07e4869d9f..e0d4abcd23 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/SuggestionFilter.qml +++ b/ui/app/AppLayouts/Chat/panels/SuggestionFilterPanel.qml @@ -1,6 +1,5 @@ import QtQuick 2.13 - Item { id: component property alias model: filterModel diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionBubble.qml b/ui/app/AppLayouts/Chat/panels/TransactionBubblePanel.qml similarity index 85% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionBubble.qml rename to ui/app/AppLayouts/Chat/panels/TransactionBubblePanel.qml index 79c4b711ca..f3f176cbdb 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionBubble.qml +++ b/ui/app/AppLayouts/Chat/panels/TransactionBubblePanel.qml @@ -1,9 +1,11 @@ import QtQuick 2.3 -import "../../../../../shared" -import "../../../../../shared/panels" - import utils 1.0 -import "./TransactionComponents" +import "../../../../shared" +import "../../../../shared/panels" + +import "../controls" +//TODO remove or make view +import "../views" Item { property var commandParametersObject: { @@ -25,7 +27,11 @@ Item { } } } - + property var focusedAccount + property string activeChannelName + property string activeChannelIdenticon + signal getGasPrice() + signal sendTransactionClicked(string fromAddress) property var token: JSON.parse(commandParametersObject.contract) // TODO: handle {} property string tokenAmount: commandParametersObject.value property string tokenSymbol: token.symbol || "" @@ -176,7 +182,7 @@ Item { Component { id: acceptTransactionComponent - AcceptTransaction { + AcceptTransactionView { state: root.state } } @@ -186,6 +192,25 @@ Item { SendTransactionButton { // outgoing: root.outgoing + acc: root.focusedAccount + selectedAsset: token + selectedAmount: tokenAmount + selectedFiatAmount: fiatValue + fromAddress: commandParametersObject.fromAddress + selectedRecipient: { + return { + address: commandParametersObject.address, + identicon: root.activeChannelIdenticon, + name: root.activeChannelName, + type: RecipientSelector.Type.Contact + } + } + onSignModalOpened: { + root.getGasPrice(); + } + onSendTransaction: { + root.sendTransactionClicked(address); + } } } diff --git a/ui/app/AppLayouts/Chat/ChatColumn/UserList.qml b/ui/app/AppLayouts/Chat/panels/UserListPanel.qml similarity index 87% rename from ui/app/AppLayouts/Chat/ChatColumn/UserList.qml rename to ui/app/AppLayouts/Chat/panels/UserListPanel.qml index 578b000f42..480e41235e 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/UserList.qml +++ b/ui/app/AppLayouts/Chat/panels/UserListPanel.qml @@ -10,17 +10,18 @@ import "../../../../shared" import "../../../../shared/panels" import "../../../../shared/status" +import "../controls" + import utils 1.0 -import "../components" -import "./samples/" -import "./MessageComponents" -import "../ContactsColumn" Item { id: root anchors.fill: parent property var userList property var currentTime + property bool isOnline + property var contactsList + property string profilePubKey property var messageContextMenu StyledText { @@ -63,12 +64,15 @@ Item { } ] model: root.userList - delegate: User { + delegate: UserDelegate { publicKey: model.publicKey name: model.userName identicon: model.identicon lastSeen: model.lastSeen / 1000 currentTime: root.currentTime + isOnline: root.isOnline + contactsList: root.contactsList + profilePubKey: root.profilePubKey } } } diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/BackUpCommuntyBanner.qml b/ui/app/AppLayouts/Chat/panels/communities/BackUpCommuntyBannerPanel.qml similarity index 94% rename from ui/app/AppLayouts/Chat/CommunityComponents/BackUpCommuntyBanner.qml rename to ui/app/AppLayouts/Chat/panels/communities/BackUpCommuntyBannerPanel.qml index 45fe315e33..7116feeeb8 100644 --- a/ui/app/AppLayouts/Chat/CommunityComponents/BackUpCommuntyBanner.qml +++ b/ui/app/AppLayouts/Chat/panels/communities/BackUpCommuntyBannerPanel.qml @@ -1,11 +1,11 @@ import QtQuick 2.13 import QtGraphicalEffects 1.13 -import "../../../../shared" -import "../../../../shared/panels" -import "../../../../shared/status" +import "../../../../../shared" +import "../../../../../shared/panels" +import "../../../../../shared/status" import utils 1.0 -import "." +import "../../popups/community" Rectangle { id: root diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopupInviteFriendsView.qml b/ui/app/AppLayouts/Chat/panels/communities/CommunityProfilePopupInviteFriendsPanel.qml similarity index 93% rename from ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopupInviteFriendsView.qml rename to ui/app/AppLayouts/Chat/panels/communities/CommunityProfilePopupInviteFriendsPanel.qml index 707ab286c8..658ef9e6f2 100644 --- a/ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopupInviteFriendsView.qml +++ b/ui/app/AppLayouts/Chat/panels/communities/CommunityProfilePopupInviteFriendsPanel.qml @@ -5,11 +5,10 @@ import QtQuick.Layouts 1.13 import QtGraphicalEffects 1.13 import utils 1.0 -import "../../../../shared" -import "../../../../shared/controls" -import "../../../../shared/panels" -import "../../../../shared/status" - +import "../../../../../shared" +import "../../../../../shared/controls" +import "../../../../../shared/panels" +import "../../../../../shared/status" import StatusQ.Components 0.1 import StatusQ.Popups 0.1 diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopupMembersList.qml b/ui/app/AppLayouts/Chat/panels/communities/CommunityProfilePopupMembersListPanel.qml similarity index 98% rename from ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopupMembersList.qml rename to ui/app/AppLayouts/Chat/panels/communities/CommunityProfilePopupMembersListPanel.qml index 084d20a1af..89f3a6e713 100644 --- a/ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopupMembersList.qml +++ b/ui/app/AppLayouts/Chat/panels/communities/CommunityProfilePopupMembersListPanel.qml @@ -8,10 +8,11 @@ import StatusQ.Components 0.1 import StatusQ.Controls 0.1 import StatusQ.Popups 0.1 - import utils 1.0 -import "../../../../shared" -import "../components" +import "../../../../../shared" + +import "../../popups" +import "../../popups/community" Item { id: root diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopupOverview.qml b/ui/app/AppLayouts/Chat/panels/communities/CommunityProfilePopupOverviewPanel.qml similarity index 100% rename from ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopupOverview.qml rename to ui/app/AppLayouts/Chat/panels/communities/CommunityProfilePopupOverviewPanel.qml diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/CommunityUserList.qml b/ui/app/AppLayouts/Chat/panels/communities/CommunityUserListPanel.qml similarity index 87% rename from ui/app/AppLayouts/Chat/CommunityComponents/CommunityUserList.qml rename to ui/app/AppLayouts/Chat/panels/communities/CommunityUserListPanel.qml index d866cd9d8a..9b3b74b127 100644 --- a/ui/app/AppLayouts/Chat/CommunityComponents/CommunityUserList.qml +++ b/ui/app/AppLayouts/Chat/panels/communities/CommunityUserListPanel.qml @@ -6,15 +6,13 @@ import QtQuick.Layouts 1.13 import QtQml.Models 2.13 import QtGraphicalEffects 1.13 import QtQuick.Dialogs 1.3 -import "../../../../shared" -import "../../../../shared/panels" -import "../../../../shared/status" +import "../../../../../shared" +import "../../../../../shared/panels" +import "../../../../../shared/status" import utils 1.0 -import "../components" -import "../ChatColumn/MessageComponents" -import "../ChatColumn/" -import "../ContactsColumn" + +import "../../controls" import StatusQ.Core.Theme 0.1 @@ -23,6 +21,8 @@ Item { anchors.fill: parent property var userList property var currentTime + property var contactsList + property string profilePubKey property var messageContextMenu property QtObject community: chatsModel.communities.activeCommunity @@ -84,7 +84,7 @@ Item { } ] model: community.members - delegate: User { + delegate: UserDelegate { publicKey: model.pubKey name: model.userName identicon: model.identicon @@ -92,6 +92,9 @@ Item { statusType: model.statusType currentTime: root.currentTime isOnline: model.online + contactsList: root.contactsList + profilePubKey: root.profilePubKey + messageContextMenu: root.messageContextMenu } } } diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/CommunityWelcomeBanner.qml b/ui/app/AppLayouts/Chat/panels/communities/CommunityWelcomeBannerPanel.qml similarity index 96% rename from ui/app/AppLayouts/Chat/CommunityComponents/CommunityWelcomeBanner.qml rename to ui/app/AppLayouts/Chat/panels/communities/CommunityWelcomeBannerPanel.qml index ff5199dad6..4a6a775997 100644 --- a/ui/app/AppLayouts/Chat/CommunityComponents/CommunityWelcomeBanner.qml +++ b/ui/app/AppLayouts/Chat/panels/communities/CommunityWelcomeBannerPanel.qml @@ -1,9 +1,10 @@ import QtQuick 2.13 import QtQuick.Controls 2.13 import QtGraphicalEffects 1.13 -import "../../../../shared" -import "../../../../shared/panels" -import "../../../../shared/status" + +import "../../../../../shared" +import "../../../../../shared/panels" +import "../../../../../shared/status" import utils 1.0 import "." diff --git a/ui/app/AppLayouts/Chat/ChatColumn/ActivityCenter.qml b/ui/app/AppLayouts/Chat/popups/ActivityCenterPopup.qml similarity index 80% rename from ui/app/AppLayouts/Chat/ChatColumn/ActivityCenter.qml rename to ui/app/AppLayouts/Chat/popups/ActivityCenterPopup.qml index b1aefe4120..13b6f3b59f 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/ActivityCenter.qml +++ b/ui/app/AppLayouts/Chat/popups/ActivityCenterPopup.qml @@ -4,11 +4,10 @@ import QtQml.Models 2.13 import QtGraphicalEffects 1.13 import "../../../../shared" import "../../../../shared/status" +import "../views" +import "../panels" import utils 1.0 -import "./ChatComponents" -import "../components" -import "./MessageComponents" Popup { enum Filter { @@ -17,12 +16,13 @@ Popup { Replies, ContactRequests } - property int currentFilter: ActivityCenter.Filter.All + property int currentFilter: ActivityCenterPopup.Filter.All property bool hasMentions: false property bool hasReplies: false // property bool hasContactRequests: false property bool hideReadNotifications: false + property var store id: activityCenter modal: false @@ -56,8 +56,32 @@ Popup { } padding: 0 - ActivityCenterTopBar { + ActivityCenterPopupTopBarPanel { id: activityCenterTopBar + repliesBtnEnabled: hasReplies + mentionsBtnEnabled: hasMentions + allBtnHighlighted: activityCenter.currentFilter === ActivityCenterPopup.Filter.All + mentionsBtnHighlighted: activityCenter.currentFilter === ActivityCenterPopup.Filter.Mentions + repliesBtnHighlighted: activityCenter.currentFilter === ActivityCenterPopup.Filter.Replies + onAllBtnClicked: { + activityCenter.currentFilter = ActivityCenterPopup.Filter.All; + } + onRepliesBtnClicked: { + activityCenter.currentFilter = ActivityCenterPopup.Filter.Replies; + } + onMentionsBtnClicked: { + activityCenter.currentFilter = ActivityCenterPopup.Filter.Mentions; + } + onPreferencesClicked: { + activityCenter.close() + appMain.changeAppSection(Constants.profile) + // TODO: replace with shared store constant + // Profile/RootStore.notifications_id + profileLayoutContainer.changeProfileSection(7) + } + onMarkAllReadClicked: { + errorText = chatsModel.activityNotificationList.markAllActivityCenterNotificationsRead() + } } ScrollView { @@ -158,7 +182,9 @@ Popup { return -1; } property string previousNotificationTimestamp: notificationDelegate.idx === 0 ? "" : chatsModel.activityNotificationList.getNotificationData(previousNotificationIndex, "timestamp") - + onPreviousNotificationTimestampChanged: { + activityCenter.store.messageStore.prevMsgTimestamp = previousNotificationTimestamp; + } id: notifLoader anchors.top: parent.top @@ -178,13 +204,17 @@ Popup { Component { id: messageNotificationComponent - ActivityCenterMessageComponent {} + ActivityCenterMessageComponentView { + store: activityCenter.store + } } Component { id: groupRequestNotificationComponent - ActivityCenterGroupRequest {} + ActivityCenterGroupRequest { + timestamp: activityCenter.store.messageStore.timestamp + } } } } diff --git a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandModal.qml b/ui/app/AppLayouts/Chat/popups/ChatCommandModal.qml similarity index 96% rename from ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandModal.qml rename to ui/app/AppLayouts/Chat/popups/ChatCommandModal.qml index 0a67e173fc..ff81468ff1 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ChatCommandModal.qml +++ b/ui/app/AppLayouts/Chat/popups/ChatCommandModal.qml @@ -4,13 +4,12 @@ import QtQuick.Layouts 1.13 import QtQuick.Dialogs 1.3 import utils 1.0 -import "../../../../../shared" -import "../../../../../shared/panels" -import "../../../../../shared/controls" -import "../../../../../shared/popups" -import "../../../../../shared/views" -import "../../../../../shared/status" - +import "../../../../shared" +import "../../../../shared/panels" +import "../../../../shared/controls" +import "../../../../shared/popups" +import "../../../../shared/views" +import "../../../../shared/status" // TODO: replace with StatusModal ModalPopup { property string commandTitle: "Send" diff --git a/ui/app/AppLayouts/Chat/components/ChooseBrowserPopup.qml b/ui/app/AppLayouts/Chat/popups/ChooseBrowserPopup.qml similarity index 100% rename from ui/app/AppLayouts/Chat/components/ChooseBrowserPopup.qml rename to ui/app/AppLayouts/Chat/popups/ChooseBrowserPopup.qml diff --git a/ui/app/AppLayouts/Chat/components/ContactRequestsPopup.qml b/ui/app/AppLayouts/Chat/popups/ContactRequestsPopup.qml similarity index 91% rename from ui/app/AppLayouts/Chat/components/ContactRequestsPopup.qml rename to ui/app/AppLayouts/Chat/popups/ContactRequestsPopup.qml index 77dcf1850c..632cfdce84 100644 --- a/ui/app/AppLayouts/Chat/components/ContactRequestsPopup.qml +++ b/ui/app/AppLayouts/Chat/popups/ContactRequestsPopup.qml @@ -8,6 +8,9 @@ import "../../../../shared" import "../../../../shared/status" import "../../../../shared/popups" +import "../../Profile/Sections/Contacts" +import "../panels" + // TODO: Replace with StatusModal ModalPopup { id: popup @@ -31,7 +34,7 @@ ModalPopup { model: profileModel.contacts.contactRequests clip: true - delegate: ContactRequest { + delegate: ContactRequestPanel { name: Utils.removeStatusEns(model.name) address: model.address localNickname: model.localNickname @@ -45,6 +48,13 @@ ModalPopup { blockContactConfirmationDialog.contactAddress = address blockContactConfirmationDialog.open() } + onAcceptClicked: { + chatsModel.channelView.joinPrivateChat(model.address, "") + profileModel.contacts.addContact(model.address) + } + onDeclineClicked: { + profileModel.contacts.rejectContactRequest(model.address) + } } } diff --git a/ui/app/AppLayouts/Chat/components/GroupChatPopup.qml b/ui/app/AppLayouts/Chat/popups/GroupChatPopup.qml similarity index 98% rename from ui/app/AppLayouts/Chat/components/GroupChatPopup.qml rename to ui/app/AppLayouts/Chat/popups/GroupChatPopup.qml index c3e4dcbd5d..68f4eccd11 100644 --- a/ui/app/AppLayouts/Chat/components/GroupChatPopup.qml +++ b/ui/app/AppLayouts/Chat/popups/GroupChatPopup.qml @@ -10,7 +10,8 @@ import "../../../../shared/popups" import "../../../../shared/panels" import "../../../../shared/views" import "../../../../shared/status" -import "./" +import "../panels" +import "../controls" // TODO: replace with StatusModal ModalPopup { @@ -129,7 +130,7 @@ ModalPopup { anchors.horizontalCenter: parent.horizontalCenter } - ContactList { + ContactListPanel { id: contactList searchString: searchBox.text.toLowerCase() selectMode: selectChatMembers && memberCount < maxMembers diff --git a/ui/app/AppLayouts/Chat/components/GroupInfoPopup.qml b/ui/app/AppLayouts/Chat/popups/GroupInfoPopup.qml similarity index 99% rename from ui/app/AppLayouts/Chat/components/GroupInfoPopup.qml rename to ui/app/AppLayouts/Chat/popups/GroupInfoPopup.qml index 69ff0fccf4..cb8296ecac 100644 --- a/ui/app/AppLayouts/Chat/components/GroupInfoPopup.qml +++ b/ui/app/AppLayouts/Chat/popups/GroupInfoPopup.qml @@ -12,7 +12,7 @@ import "../../../../shared/popups" import "../../../../shared/panels" import "../../../../shared/controls" import "../../../../shared/status" -import "./" +import "../panels" // TODO: replace with StatusModal ModalPopup { @@ -185,7 +185,7 @@ ModalPopup { anchors.horizontalCenter: parent.horizontalCenter } - ContactList { + ContactListPanel { id: contactList visible: addMembers && contactList.membersData.count > 0 anchors.fill: parent diff --git a/ui/app/AppLayouts/Chat/components/NicknamePopup.qml b/ui/app/AppLayouts/Chat/popups/NicknamePopup.qml similarity index 100% rename from ui/app/AppLayouts/Chat/components/NicknamePopup.qml rename to ui/app/AppLayouts/Chat/popups/NicknamePopup.qml diff --git a/ui/app/AppLayouts/Chat/components/PinnedMessagesPopup.qml b/ui/app/AppLayouts/Chat/popups/PinnedMessagesPopup.qml similarity index 71% rename from ui/app/AppLayouts/Chat/components/PinnedMessagesPopup.qml rename to ui/app/AppLayouts/Chat/popups/PinnedMessagesPopup.qml index 2f1d336fb6..bb36f1b91f 100644 --- a/ui/app/AppLayouts/Chat/components/PinnedMessagesPopup.qml +++ b/ui/app/AppLayouts/Chat/popups/PinnedMessagesPopup.qml @@ -6,11 +6,16 @@ import "../../../../shared" import "../../../../shared/popups" import "../../../../shared/panels" import "../../../../shared/status" -import "../data" -import "../ChatColumn" + +import "../controls" +import "../panels" +//TODO remove or make view? +import "../views" // TODO: replace with StatusMOdal ModalPopup { + property var rootStore + property var messageStore property bool userCanPin: { switch (chatsModel.channelView.activeChannel.chatType) { case Constants.chatTypePublic: return false @@ -107,12 +112,16 @@ ModalPopup { } delegate: Item { + id: messageDelegate property var listView: ListView.view width: parent.width height: messageItem.height - Message { + MessageView { id: messageItem + rootStore: popup.rootStore + messageStore: popup.messageStore + /////////////TODO Remove fromAuthor: model.fromAuthor chatId: model.chatId userName: model.userName @@ -141,12 +150,45 @@ ModalPopup { activityCenterMessage: false isEdited: model.isEdited showEdit: false - messageContextMenu: MessageContextMenu { + messageContextMenu: msgContextMenu + Component.onCompleted: { + messageStore.fromAuthor = model.fromAuthor; + messageStore.chatId = model.chatId; + messageStore.userName = model.userName; + messageStore.alias = model.alias; + messageStore.localName = model.localName; + messageStore.message = model.message; + messageStore.plainText = model.plainText; + messageStore.identicon = model.identicon; + messageStore.isCurrentUser = model.isCurrentUser; + messageStore.timestamp = model.timestamp; + messageStore.sticker = model.sticker; + messageStore.contentType = model.contentType; + messageStore.outgoingStatus = model.outgoingStatus; + messageStore.responseTo = model.responseTo; + messageStore.imageClick = imagePopup.openPopup.bind(imagePopup); + messageStore.messageId = model.messageId; + messageStore.emojiReactions = model.emojiReactions; + messageStore.linkUrls = model.linkUrls; + messageStore.communityId = model.communityId; + messageStore.hasMention = model.hasMention; + messageStore.stickerPackId = model.stickerPackId; + messageStore.timeout = model.timeout; + messageStore.pinnedMessage = true; + messageStore.pinnedBy = model.pinnedBy; + messageStore.forceHoverHandler = !messageToPin; + messageStore.activityCenterMessage = false; + messageStore.isEdited = model.isEdited; + messageStore.showEdit = false; + messageStore.messageContextMenu = msgContextMenu; + } + MessageContextMenuPanel { + id: msgContextMenu pinnedPopup: true pinnedMessage: true - reactionModel: EmojiReactions {} + reactionModel: popup.rootStore.emojiReactionsModel onShouldCloseParentPopup: { - listView.closePopup() + messageDelegate.listView.closePopup(); } } } diff --git a/ui/app/AppLayouts/Chat/components/PrivateChatPopup.qml b/ui/app/AppLayouts/Chat/popups/PrivateChatPopup.qml similarity index 100% rename from ui/app/AppLayouts/Chat/components/PrivateChatPopup.qml rename to ui/app/AppLayouts/Chat/popups/PrivateChatPopup.qml diff --git a/ui/app/AppLayouts/Chat/components/ProfilePopup.qml b/ui/app/AppLayouts/Chat/popups/ProfilePopup.qml similarity index 100% rename from ui/app/AppLayouts/Chat/components/ProfilePopup.qml rename to ui/app/AppLayouts/Chat/popups/ProfilePopup.qml diff --git a/ui/app/AppLayouts/Chat/components/PublicChatPopup.qml b/ui/app/AppLayouts/Chat/popups/PublicChatPopup.qml similarity index 93% rename from ui/app/AppLayouts/Chat/components/PublicChatPopup.qml rename to ui/app/AppLayouts/Chat/popups/PublicChatPopup.qml index 05c00f8fa3..166de10535 100644 --- a/ui/app/AppLayouts/Chat/components/PublicChatPopup.qml +++ b/ui/app/AppLayouts/Chat/popups/PublicChatPopup.qml @@ -8,8 +8,8 @@ import "../../../../shared/controls" import "../../../../shared/popups" import "../../../../shared/panels" import "../../../../shared/status" -import "../data/channelList.js" as ChannelJSON -import "./" +import "../helpers/channelList.js" as ChannelJSON +import "../panels" // TODO: replace with StatusModal ModalPopup { @@ -96,9 +96,12 @@ ModalPopup { return totalHeight + Style.current.padding } - SuggestedChannels { + SuggestedChannelsPanel { id: sectionRepeater width: parent.width + onSuggestedMessageClicked: { + chatsModel.channelView.joinPublicChat(channel); + } } } diff --git a/ui/app/AppLayouts/Chat/components/RenameGroupPopup.qml b/ui/app/AppLayouts/Chat/popups/RenameGroupPopup.qml similarity index 100% rename from ui/app/AppLayouts/Chat/components/RenameGroupPopup.qml rename to ui/app/AppLayouts/Chat/popups/RenameGroupPopup.qml diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SelectAccountModal.qml b/ui/app/AppLayouts/Chat/popups/SelectAccountModal.qml similarity index 89% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SelectAccountModal.qml rename to ui/app/AppLayouts/Chat/popups/SelectAccountModal.qml index ac58b45584..731befc1aa 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/SelectAccountModal.qml +++ b/ui/app/AppLayouts/Chat/popups/SelectAccountModal.qml @@ -4,10 +4,10 @@ import QtQuick.Layouts 1.13 import QtQuick.Dialogs 1.3 import utils 1.0 -import "../../../../../../shared" -import "../../../../../../shared/controls" -import "../../../../../../shared/popups" -import "../../../../../../shared/status" +import "../../../../shared" +import "../../../../shared/controls" +import "../../../../shared/popups" +import "../../../../shared/status" // TODO: replace with StatusModal ModalPopup { diff --git a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/SignTransactionModal.qml b/ui/app/AppLayouts/Chat/popups/SignTransactionModal.qml similarity index 98% rename from ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/SignTransactionModal.qml rename to ui/app/AppLayouts/Chat/popups/SignTransactionModal.qml index dff9a6bfa1..b74c38a57a 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/SignTransactionModal.qml +++ b/ui/app/AppLayouts/Chat/popups/SignTransactionModal.qml @@ -4,12 +4,13 @@ import QtQuick.Layouts 1.13 import QtQuick.Dialogs 1.3 import utils 1.0 -import "../../../../../shared" -import "../../../../../shared/status" -import "../../../../../shared/panels" -import "../../../../../shared/controls" -import "../../../../../shared/views" -import "../../../../../shared/popups" +import "../../../../shared" +import "../../../../shared/status" +import "../../../../shared/panels" +import "../../../../shared/controls" +import "../../../../shared/views" +import "../../../../shared/popups" +import "../../Wallet/" // TODO: replace with StatusModal ModalPopup { diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/AccessExistingCommunityPopup.qml b/ui/app/AppLayouts/Chat/popups/community/AccessExistingCommunityPopup.qml similarity index 93% rename from ui/app/AppLayouts/Chat/CommunityComponents/AccessExistingCommunityPopup.qml rename to ui/app/AppLayouts/Chat/popups/community/AccessExistingCommunityPopup.qml index 48dccffa3a..984a0cd631 100644 --- a/ui/app/AppLayouts/Chat/CommunityComponents/AccessExistingCommunityPopup.qml +++ b/ui/app/AppLayouts/Chat/popups/community/AccessExistingCommunityPopup.qml @@ -4,11 +4,11 @@ import QtGraphicalEffects 1.13 import QtQuick.Dialogs 1.3 import utils 1.0 -import "../../../../shared" -import "../../../../shared/popups" -import "../../../../shared/controls" -import "../../../../shared/panels" -import "../../../../shared/status" +import "../../../../../shared" +import "../../../../../shared/popups" +import "../../../../../shared/controls" +import "../../../../../shared/panels" +import "../../../../../shared/status" // TODO: replace with StatusModal ModalPopup { diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/CommunitiesPopup.qml b/ui/app/AppLayouts/Chat/popups/community/CommunitiesPopup.qml similarity index 99% rename from ui/app/AppLayouts/Chat/CommunityComponents/CommunitiesPopup.qml rename to ui/app/AppLayouts/Chat/popups/community/CommunitiesPopup.qml index 83be6213dd..3ff77aeba2 100644 --- a/ui/app/AppLayouts/Chat/CommunityComponents/CommunitiesPopup.qml +++ b/ui/app/AppLayouts/Chat/popups/community/CommunitiesPopup.qml @@ -10,7 +10,7 @@ import StatusQ.Popups 0.1 import utils 1.0 -import "../../../../shared" +import "../../../../../shared" StatusModal { id: popup diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/CommunityDetailPopup.qml b/ui/app/AppLayouts/Chat/popups/community/CommunityDetailPopup.qml similarity index 99% rename from ui/app/AppLayouts/Chat/CommunityComponents/CommunityDetailPopup.qml rename to ui/app/AppLayouts/Chat/popups/community/CommunityDetailPopup.qml index 03d6594c50..cc36a61fb8 100644 --- a/ui/app/AppLayouts/Chat/CommunityComponents/CommunityDetailPopup.qml +++ b/ui/app/AppLayouts/Chat/popups/community/CommunityDetailPopup.qml @@ -10,7 +10,7 @@ import StatusQ.Popups 0.1 import utils 1.0 -import "../../../../shared" +import "../../../../../shared" StatusModal { property QtObject community: chatsModel.communities.observedCommunity diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopup.qml b/ui/app/AppLayouts/Chat/popups/community/CommunityProfilePopup.qml similarity index 96% rename from ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopup.qml rename to ui/app/AppLayouts/Chat/popups/community/CommunityProfilePopup.qml index 3cce88cdd3..abb3aab866 100644 --- a/ui/app/AppLayouts/Chat/CommunityComponents/CommunityProfilePopup.qml +++ b/ui/app/AppLayouts/Chat/popups/community/CommunityProfilePopup.qml @@ -7,6 +7,8 @@ import StatusQ.Popups 0.1 import utils 1.0 +import "../../panels/communities" + StatusModal { property var community @@ -38,7 +40,7 @@ StatusModal { Component { id: profileOverview - CommunityProfilePopupOverview { + CommunityProfilePopupOverviewPanel { width: stack.width headerTitle: popup.community.name @@ -84,7 +86,7 @@ StatusModal { Component { id: membersList - CommunityProfilePopupMembersList { + CommunityProfilePopupMembersListPanel { width: stack.width //% "Members" headerTitle: qsTrId("members-label") @@ -96,7 +98,7 @@ StatusModal { Component { id: inviteFriendsView - CommunityProfilePopupInviteFriendsView { + CommunityProfilePopupInviteFriendsPanel { width: stack.width //% "Invite friends" headerTitle: qsTrId("invite-friends") diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/CreateCategoryPopup.qml b/ui/app/AppLayouts/Chat/popups/community/CreateCategoryPopup.qml similarity index 99% rename from ui/app/AppLayouts/Chat/CommunityComponents/CreateCategoryPopup.qml rename to ui/app/AppLayouts/Chat/popups/community/CreateCategoryPopup.qml index bfa113a595..8ae285b6a8 100644 --- a/ui/app/AppLayouts/Chat/CommunityComponents/CreateCategoryPopup.qml +++ b/ui/app/AppLayouts/Chat/popups/community/CreateCategoryPopup.qml @@ -3,8 +3,8 @@ import QtQuick.Controls 2.3 import QtQuick.Dialogs 1.3 import utils 1.0 -import "../../../../shared" -import "../../../../shared/popups" +import "../../../../../shared" +import "../../../../../shared/popups" import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/CreateChannelPopup.qml b/ui/app/AppLayouts/Chat/popups/community/CreateChannelPopup.qml similarity index 100% rename from ui/app/AppLayouts/Chat/CommunityComponents/CreateChannelPopup.qml rename to ui/app/AppLayouts/Chat/popups/community/CreateChannelPopup.qml diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/CreateCommunityPopup.qml b/ui/app/AppLayouts/Chat/popups/community/CreateCommunityPopup.qml similarity index 99% rename from ui/app/AppLayouts/Chat/CommunityComponents/CreateCommunityPopup.qml rename to ui/app/AppLayouts/Chat/popups/community/CreateCommunityPopup.qml index 0a1c82c583..5e4a2e5d0c 100644 --- a/ui/app/AppLayouts/Chat/CommunityComponents/CreateCommunityPopup.qml +++ b/ui/app/AppLayouts/Chat/popups/community/CreateCommunityPopup.qml @@ -4,9 +4,9 @@ import QtGraphicalEffects 1.13 import QtQuick.Dialogs 1.3 import utils 1.0 -import "../../../../shared" -import "../../../../shared/panels" -import "../../../../shared/popups" +import "../../../../../shared" +import "../../../../../shared/panels" +import "../../../../../shared/popups" import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/InviteFriendsToCommunityPopup.qml b/ui/app/AppLayouts/Chat/popups/community/InviteFriendsToCommunityPopup.qml similarity index 92% rename from ui/app/AppLayouts/Chat/CommunityComponents/InviteFriendsToCommunityPopup.qml rename to ui/app/AppLayouts/Chat/popups/community/InviteFriendsToCommunityPopup.qml index 75fe911da5..ee57aff9fc 100644 --- a/ui/app/AppLayouts/Chat/CommunityComponents/InviteFriendsToCommunityPopup.qml +++ b/ui/app/AppLayouts/Chat/popups/community/InviteFriendsToCommunityPopup.qml @@ -9,8 +9,10 @@ import StatusQ.Popups 0.1 import utils 1.0 -import "../../../../shared" -import "../components" +import "../../../../../shared" + +import "../../views" +import "../../panels/communities" StatusModal { id: popup @@ -32,7 +34,7 @@ StatusModal { //% "Invite friends" header.title: qsTrId("invite-friends") - contentItem: CommunityProfilePopupInviteFriendsView { + contentItem: CommunityProfilePopupInviteFriendsPanel { id: contactFieldAndList contactListSearch.onUserClicked: { if (isContact) { diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/MembershipRequestsPopup.qml b/ui/app/AppLayouts/Chat/popups/community/MembershipRequestsPopup.qml similarity index 99% rename from ui/app/AppLayouts/Chat/CommunityComponents/MembershipRequestsPopup.qml rename to ui/app/AppLayouts/Chat/popups/community/MembershipRequestsPopup.qml index e1ed2f663a..e5e11a0ce6 100644 --- a/ui/app/AppLayouts/Chat/CommunityComponents/MembershipRequestsPopup.qml +++ b/ui/app/AppLayouts/Chat/popups/community/MembershipRequestsPopup.qml @@ -9,7 +9,7 @@ import StatusQ.Popups 0.1 import utils 1.0 -import "../../../../shared" +import "../../../../../shared" StatusModal { id: popup diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/MembershipRequirementPopup.qml b/ui/app/AppLayouts/Chat/popups/community/MembershipRequirementPopup.qml similarity index 100% rename from ui/app/AppLayouts/Chat/CommunityComponents/MembershipRequirementPopup.qml rename to ui/app/AppLayouts/Chat/popups/community/MembershipRequirementPopup.qml diff --git a/ui/app/AppLayouts/Chat/CommunityComponents/TransferOwnershipPopup.qml b/ui/app/AppLayouts/Chat/popups/community/TransferOwnershipPopup.qml similarity index 97% rename from ui/app/AppLayouts/Chat/CommunityComponents/TransferOwnershipPopup.qml rename to ui/app/AppLayouts/Chat/popups/community/TransferOwnershipPopup.qml index ddef1f90a4..f645110831 100644 --- a/ui/app/AppLayouts/Chat/CommunityComponents/TransferOwnershipPopup.qml +++ b/ui/app/AppLayouts/Chat/popups/community/TransferOwnershipPopup.qml @@ -8,8 +8,8 @@ import StatusQ.Popups 0.1 import utils 1.0 -import "../../../../shared" -import "../../../../shared/controls" +import "../../../../../shared" +import "../../../../../shared/controls" StatusModal { id: popup diff --git a/ui/app/AppLayouts/Chat/qmldir b/ui/app/AppLayouts/Chat/qmldir deleted file mode 100644 index aae7d508e4..0000000000 --- a/ui/app/AppLayouts/Chat/qmldir +++ /dev/null @@ -1,4 +0,0 @@ -ContactsColumn 1.0 ContactsColumn.qml -ChatColumn 1.0 ChatColumn.qml -SuggestionBox 1.0 SuggestionBox.qml -SuggestionFilter 1.0 SuggestionFilter.qml diff --git a/ui/app/AppLayouts/Chat/data/EmojiReactions.qml b/ui/app/AppLayouts/Chat/stores/EmojiReactions.qml similarity index 100% rename from ui/app/AppLayouts/Chat/data/EmojiReactions.qml rename to ui/app/AppLayouts/Chat/stores/EmojiReactions.qml diff --git a/ui/app/AppLayouts/Chat/ChatColumn/samples/MessagesData.qml b/ui/app/AppLayouts/Chat/stores/MessagesData.qml similarity index 100% rename from ui/app/AppLayouts/Chat/ChatColumn/samples/MessagesData.qml rename to ui/app/AppLayouts/Chat/stores/MessagesData.qml diff --git a/ui/app/AppLayouts/Chat/stores/RootStore.qml b/ui/app/AppLayouts/Chat/stores/RootStore.qml new file mode 100644 index 0000000000..f5daa78945 --- /dev/null +++ b/ui/app/AppLayouts/Chat/stores/RootStore.qml @@ -0,0 +1,53 @@ +import QtQuick 2.13 + +import utils 1.0 + +QtObject { + id: root + property var messageStore + property EmojiReactions emojiReactionsModel: EmojiReactions { } + + property var chatsModelInst: chatsModel + property var walletModelInst: walletModel + property var profileModelInst: profileModel + + function lastTwoItems(nodes) { + //% " and " + return nodes.join(qsTrId("-and-")); + } + + function showReactionAuthors(fromAccounts, emojiId) { + let tooltip + if (fromAccounts.length === 1) { + tooltip = fromAccounts[0] + } else if (fromAccounts.length === 2) { + tooltip = lastTwoItems(fromAccounts); + } else { + var leftNode = []; + var rightNode = []; + const maxReactions = 12 + let maximum = Math.min(maxReactions, fromAccounts.length) + + if (fromAccounts.length > maxReactions) { + leftNode = fromAccounts.slice(0, maxReactions); + rightNode = fromAccounts.slice(maxReactions, fromAccounts.length); + return (rightNode.length === 1) ? + lastTwoItems([leftNode.join(", "), rightNode[0]]) : + //% "%1 more" + lastTwoItems([leftNode.join(", "), qsTrId("-1-more").arg(rightNode.length)]); + } + + leftNode = fromAccounts.slice(0, maximum - 1); + rightNode = fromAccounts.slice(maximum - 1, fromAccounts.length); + tooltip = lastTwoItems([leftNode.join(", "), rightNode[0]]) + } + + //% " reacted with " + tooltip += qsTrId("-reacted-with-"); + let emojiHtml = Emoji.getEmojiFromId(emojiId); + if (emojiHtml) { + tooltip += emojiHtml; + } + return tooltip + } +} diff --git a/ui/app/AppLayouts/Chat/ChatColumn/samples/StickerData.qml b/ui/app/AppLayouts/Chat/stores/StickerData.qml similarity index 100% rename from ui/app/AppLayouts/Chat/ChatColumn/samples/StickerData.qml rename to ui/app/AppLayouts/Chat/stores/StickerData.qml diff --git a/ui/app/AppLayouts/Chat/ChatColumn/samples/StickerPackData.qml b/ui/app/AppLayouts/Chat/stores/StickerPackData.qml similarity index 100% rename from ui/app/AppLayouts/Chat/ChatColumn/samples/StickerPackData.qml rename to ui/app/AppLayouts/Chat/stores/StickerPackData.qml diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/AcceptTransaction.qml b/ui/app/AppLayouts/Chat/views/AcceptTransactionView.qml similarity index 94% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/AcceptTransaction.qml rename to ui/app/AppLayouts/Chat/views/AcceptTransactionView.qml index ee358cdc40..ec8765698e 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/TransactionComponents/AcceptTransaction.qml +++ b/ui/app/AppLayouts/Chat/views/AcceptTransactionView.qml @@ -1,9 +1,10 @@ import QtQuick 2.3 -import "../../ChatComponents" -import "../../../../../../shared" -import "../../../../../../shared/popups" -import "../../../../../../shared/panels" -import "../../../../../../shared/controls" +import "../../../../shared" +import "../../../../shared/popups" +import "../../../../shared/panels" +import "../../../../shared/controls" + +import "../popups" import utils 1.0 diff --git a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityCenterGroupRequest.qml b/ui/app/AppLayouts/Chat/views/ActivityCenterGroupRequest.qml similarity index 94% rename from ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityCenterGroupRequest.qml rename to ui/app/AppLayouts/Chat/views/ActivityCenterGroupRequest.qml index b39b204ccd..dd80e6f11b 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityCenterGroupRequest.qml +++ b/ui/app/AppLayouts/Chat/views/ActivityCenterGroupRequest.qml @@ -2,19 +2,20 @@ import QtQuick 2.13 import QtGraphicalEffects 1.13 import utils 1.0 -import "../../../../../shared" -import "../../../../../shared/status" -import "../../../../../shared/popups" -import "../../../../../shared/controls" -import "../../../../../shared/panels" -import "../MessageComponents" -import "../../components" -import ".." +import "../../../../shared" +import "../../../../shared/status" +import "../../../../shared/popups" +import "../../../../shared/controls" +import "../../../../shared/panels" + +import "../controls" +import "../panels" Item { + id: root width: parent.width height: childrenRect.height + dateGroupLbl.anchors.topMargin - + property string timestamp: "" DateGroup { id: dateGroupLbl previousMessageIndex: previousNotificationIndex @@ -91,13 +92,14 @@ Item { font.weight: Font.Medium } - ChatTime { + ChatTimeView { anchors.verticalCenter: chatName.verticalCenter anchors.left: chatName.right anchors.leftMargin: 4 font.pixelSize: 10 visible: true color: Style.current.secondaryText + timestamp: root.timestamp } } @@ -147,7 +149,7 @@ Item { } } - AcceptRejectOptionsButtons { + AcceptRejectOptionsButtonsPanel { id: buttons anchors.right: parent.right anchors.rightMargin: Style.current.halfPadding diff --git a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityCenterMessageComponent.qml b/ui/app/AppLayouts/Chat/views/ActivityCenterMessageComponentView.qml similarity index 56% rename from ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityCenterMessageComponent.qml rename to ui/app/AppLayouts/Chat/views/ActivityCenterMessageComponentView.qml index bd1151e28f..49cbaa46af 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/ChatComponents/ActivityCenterMessageComponent.qml +++ b/ui/app/AppLayouts/Chat/views/ActivityCenterMessageComponentView.qml @@ -1,31 +1,33 @@ import QtQuick 2.13 import utils 1.0 -import "../../../../../shared" -import "../../../../../shared/status" -import "../../../../../shared/popups" -import "../../components" -import ".." +import "../../../../shared" +import "../../../../shared/status" +import "../../../../shared/popups" +import "../controls" +import "../panels" Item { id: root + property int communityIndex: chatsModel.communities.joinedCommunities.getCommunityIndex(model.message.communityId) + visible: { if (hideReadNotifications && model.read) { return false } - return activityCenter.currentFilter === ActivityCenter.Filter.All || - (model.notificationType === Constants.activityCenterNotificationTypeMention && activityCenter.currentFilter === ActivityCenter.Filter.Mentions) || - (model.notificationType === Constants.activityCenterNotificationTypeOneToOne && activityCenter.currentFilter === ActivityCenter.Filter.ContactRequests) || - (model.notificationType === Constants.activityCenterNotificationTypeReply && activityCenter.currentFilter === ActivityCenter.Filter.Replies) + return activityCenter.currentFilter === ActivityCenterPopup.Filter.All || + (model.notificationType === Constants.activityCenterNotificationTypeMention && activityCenter.currentFilter === ActivityCenterPopup.Filter.Mentions) || + (model.notificationType === Constants.activityCenterNotificationTypeOneToOne && activityCenter.currentFilter === ActivityCenterPopup.Filter.ContactRequests) || + (model.notificationType === Constants.activityCenterNotificationTypeReply && activityCenter.currentFilter === ActivityCenterPopup.Filter.Replies) } width: parent.width // Setting a height of 0 breaks the layout for when it comes back visible // The Item never goes back to actually have a height or width height: visible ? messageNotificationContent.height : 0.01 - + property var store function openProfile() { const pk = model.author const userProfileImage = appMain.getProfileImage(pk) @@ -59,7 +61,7 @@ Item { Component { id: acceptRejectComponent - AcceptRejectOptionsButtons { + AcceptRejectOptionsButtonsPanel { id: buttons onAcceptClicked: { const setActiveChannel = chatsModel.channelView.setActiveChannel @@ -95,9 +97,12 @@ Item { width: parent.width height: childrenRect.height - Message { + MessageView { id: notificationMessage anchors.right: undefined + rootStore: root.store + messageStore: root.store.messageStore + //TODO Remove fromAuthor: model.message.fromAuthor chatId: model.message.chatId userName: model.message.userName @@ -141,6 +146,50 @@ Item { prevMessageIndex: previousNotificationIndex prevMsgTimestamp: previousNotificationTimestamp + Component.onCompleted: { + messageStore.activityCenterMessage = true; + messageStore.fromAuthor = model.message.fromAuthor; + messageStore.chatId = model.message.chatId; + messageStore.userName = model.message.userName; + messageStore.alias = model.message.alias; + messageStore.localName = model.message.localName; + messageStore.message = model.message.message; + messageStore.plainText = model.message.plainText; + messageStore.identicon = model.message.identicon; + messageStore.isCurrentUser = model.message.isCurrentUser; + messageStore.timestamp = model.message.timestamp; + messageStore.sticker = model.message.sticker; + messageStore.contentType = model.message.contentType; + messageStore.outgoingStatus = model.message.outgoingStatus; + messageStore.responseTo = model.message.responseTo; + messageStore.imageClick = imagePopup.openPopup.bind(imagePopup); + messageStore.messageId = model.message.messageId; + messageStore.linkUrls = model.message.linkUrls; + messageStore.communityId = model.message.communityId; + messageStore.hasMention = model.message.hasMention; + messageStore.stickerPackId = model.message.stickerPackId; + messageStore.pinnedBy = model.message.pinnedBy; + messageStore.pinnedMessage = model.message.isPinned; + messageStore.read = model.read; + messageStore.prevMessageIndex = previousNotificationIndex; + messageStore.prevMsgTimestamp = previousNotificationTimestamp; + messageStore.clickMessage = function (isProfileClick) { + if (isProfileClick) { + const pk = model.message.fromAuthor + const userProfileImage = appMain.getProfileImage(pk) + return openProfilePopup(chatsModel.userNameOrAlias(pk), pk, userProfileImage || utilsModel.generateIdenticon(pk)) + } + + activityCenter.close() + + if (model.message.communityId) { + chatsModel.communities.setActiveCommunity(model.message.communityId) + } + + chatsModel.channelView.setActiveChannel(model.message.chatId) + positionAtMessage(model.message.messageId) + } + } } Rectangle { @@ -169,17 +218,50 @@ Item { } } - ActivityChannelBadge { + ActivityChannelBadgePanel { id: badge - visible: model.notificationType !== Constants.activityCenterNotificationTypeOneToOne - name: model.name - chatId: model.chatId - notificationType: model.notificationType - responseTo: model.message.responseTo - communityId: model.message.communityId anchors.top: notificationMessage.bottom anchors.left: parent.left anchors.leftMargin: 61 // TODO find a way to align with the text of the message + visible: model.notificationType !== Constants.activityCenterNotificationTypeOneToOne + + name: model.name + chatId: model.chatId + notificationType: model.notificationType + communityId: model.message.communityId + replyMessageIndex: chatsModel.messageView.getMessageIndex(chatId, responseTo) + repliedMessageContent: replyMessageIndex > -1 ? chatsModel.messageView.getMessageData(chatId, replyMessageIndex, "message") : "" + realChatType: { + var chatType = chatsModel.channelView.chats.getChannelType(model.chatId) + if (chatType === Constants.chatTypeCommunity) { + // TODO add a check for private community chats once it is created + return Constants.chatTypePublic + } + return chatType + } + profileImage: realChatType === Constants.chatTypeOneToOne ? appMain.getProfileImage(chatId) || "" : "" + channelName: chatsModel.getChannelNameById(badge.chatId) + communityName: root.communityIndex > -1 ? chatsModel.communities.joinedCommunities.rowData(root.communityIndex, "name") : "" + communityThumbnailImage: root.communityIndex > -1 ? chatsModel.communities.joinedCommunities.rowData(root.communityIndex, "thumbnailImage") : "" + communityColor: !image && root.communityIndex > -1 ? chatsModel.communities.joinedCommunities.rowData(root.communityIndex, "communityColor"): "" + + onCommunityNameClicked: { + chatsModel.communities.setActiveCommunity(badge.communityId) + } + onChannelNameClicked: { + chatsModel.communities.setActiveCommunity(badge.communityId) + chatsModel.setActiveChannel(badge.chatId) + } + + Connections { + enabled: badge.realChatType === Constants.chatTypeOneToOne + target: profileModel.contacts.list + onContactChanged: { + if (pubkey === badge.chatId) { + badge.profileImage = appMain.getProfileImage(badge.chatId) + } + } + } } } } diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChannelIdentifier.qml b/ui/app/AppLayouts/Chat/views/ChannelIdentifierView.qml similarity index 98% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChannelIdentifier.qml rename to ui/app/AppLayouts/Chat/views/ChannelIdentifierView.qml index 0d4abab560..13b94fd2c6 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChannelIdentifier.qml +++ b/ui/app/AppLayouts/Chat/views/ChannelIdentifierView.qml @@ -1,6 +1,6 @@ import QtQuick 2.14 -import "../../../../../shared" -import "../../../../../shared/panels" +import "../../../../shared" +import "../../../../shared/panels" import utils 1.0 diff --git a/ui/app/AppLayouts/Chat/ChatColumn.qml b/ui/app/AppLayouts/Chat/views/ChatColumnView.qml similarity index 96% rename from ui/app/AppLayouts/Chat/ChatColumn.qml rename to ui/app/AppLayouts/Chat/views/ChatColumnView.qml index e758e34ba4..1a8adb5124 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn.qml +++ b/ui/app/AppLayouts/Chat/views/ChatColumnView.qml @@ -8,23 +8,23 @@ import StatusQ.Core.Theme 0.1 import StatusQ.Components 0.1 import StatusQ.Controls 0.1 -import "../../../shared" -import "../../../shared/status" -import "../../../shared/controls" -import "../../../shared/popups" +import "../../../../shared" +import "../../../../shared/status" +import "../../../../shared/controls" +import "../../../../shared/popups" import utils 1.0 -import "./components" -import "./ChatColumn" -import "./ChatColumn/ChatComponents" -import "./data" - +import "../helpers" +import "../controls" +import "../popups" +import "../panels" +import "../../Wallet" Item { id: chatColumnLayout anchors.fill: parent - + property var rootStore property alias pinnedMessagesPopupComponent: pinnedMessagesPopupComponent property int chatGroupsListViewCount: 0 property bool isReply: false @@ -38,8 +38,6 @@ Item { property bool contactRequestReceived: profileModel.contacts.contactRequestReceived(activeChatId) property string currentNotificationChatId property string currentNotificationCommunityId - property string hoveredMessage - property string activeMessage property var currentTime: 0 property var idMap: ({}) property Timer timer: Timer { } @@ -54,22 +52,6 @@ Item { stackLayoutChatMessages.children[stackLayoutChatMessages.currentIndex].chatInput.hideExtendedArea() } - function setHovered(messageId, hovered) { - if (hovered) { - hoveredMessage = messageId - } else if (hoveredMessage === messageId) { - hoveredMessage = "" - } - } - - function setMessageActive(messageId, active) { - if (active) { - activeMessage = messageId - } else if (activeMessage === messageId) { - activeMessage = "" - } - } - function showReplyArea() { isReply = true; isImage = false; @@ -128,9 +110,9 @@ Item { } } - MessageContextMenu { + MessageContextMenuPanel { id: contextmenu - reactionModel: EmojiReactions { } + reactionModel: chatColumnLayout.rootStore.emojiReactionsModel } StackLayout { @@ -226,7 +208,7 @@ Item { onMembersButtonClicked: appSettings.expandUsersList = !appSettings.expandUsersList onNotificationButtonClicked: activityCenter.open() - popupMenu: ChatContextMenu { + popupMenu: ChatContextMenuView { onOpened: { chatItem = chatsModel.channelView.activeChannel } @@ -315,8 +297,9 @@ Item { Layout.preferredWidth: parent.width active: stackLayoutChatMessages.currentIndex === index - sourceComponent: ChatMessages { + sourceComponent: ChatMessagesView { id: chatMessages + store: chatColumnLayout.rootStore messageList: messages messageContextMenuInst: contextmenu Component.onCompleted: { @@ -431,14 +414,18 @@ Item { } } - ChatRequestMessage { + ChatRequestMessagePanel { Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom Layout.fillWidth: true Layout.bottomMargin: Style.current.bigPadding + visible: chatsModel.channelView.activeChannel.chatType === Constants.chatTypeOneToOne && (!isContact /*|| !contactRequestReceived*/) + onAddContactClicked: profileModel.contacts.addContact(activeChatId) } } - EmptyChat { } + EmptyChatPanel { + onShareChatKeyClicked: openProfilePopup(profileModel.profile.username, profileModel.profile.pubKey, profileModel.profile.thumbnailImage); + } Loader { id: txModalLoader @@ -535,10 +522,11 @@ Item { } } - ActivityCenter { + ActivityCenterPopup { id: activityCenter height: chatColumnLayout.height - (topBar.height * 2) // TODO get screen size y: topBar.height + store: chatColumnLayout.rootStore } Connections { @@ -568,6 +556,8 @@ Item { id: pinnedMessagesPopupComponent PinnedMessagesPopup { id: pinnedMessagesPopup + rootStore: chatColumnLayout.rootStore + messageStore: chatColumnLayout.rootStore.messageStore onClosed: destroy() } } diff --git a/ui/app/AppLayouts/Chat/components/ChatContextMenu.qml b/ui/app/AppLayouts/Chat/views/ChatContextMenuView.qml similarity index 99% rename from ui/app/AppLayouts/Chat/components/ChatContextMenu.qml rename to ui/app/AppLayouts/Chat/views/ChatContextMenuView.qml index d34625ddd6..4d71385e6d 100644 --- a/ui/app/AppLayouts/Chat/components/ChatContextMenu.qml +++ b/ui/app/AppLayouts/Chat/views/ChatContextMenuView.qml @@ -2,7 +2,6 @@ import QtQuick 2.13 import QtQuick.Controls 2.13 import QtQuick.Layouts 1.13 import Qt.labs.platform 1.1 -import "./" import "../../../../shared" import "../../../../shared/popups" diff --git a/ui/app/AppLayouts/Chat/ChatColumn/ChatMessages.qml b/ui/app/AppLayouts/Chat/views/ChatMessagesView.qml similarity index 81% rename from ui/app/AppLayouts/Chat/ChatColumn/ChatMessages.qml rename to ui/app/AppLayouts/Chat/views/ChatMessagesView.qml index 53f5574c6b..c95dbe4270 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/ChatMessages.qml +++ b/ui/app/AppLayouts/Chat/views/ChatMessagesView.qml @@ -10,17 +10,17 @@ import "../../../../shared/panels" import "../../../../shared/controls" import "../../../../shared/status" +import "../controls" +//TODO REMOVE +import "../stores" + import utils 1.0 -import "../components" -import "./samples/" -import "./MessageComponents" -import "../ContactsColumn" -import "../CommunityComponents" Item { id: root anchors.fill: parent + property var store property alias chatLogView: chatLogView property alias scrollToMessage: chatLogView.scrollToMessage @@ -291,8 +291,11 @@ Item { model: messages - delegate: Message { + delegate: MessageView { id: msgDelegate + rootStore: root.store + messageStore: root.store.messageStore + /////////////TODO Remove fromAuthor: model.fromAuthor chatId: model.chatId userName: model.userName @@ -324,12 +327,6 @@ Item { gapFrom: model.gapFrom gapTo: model.gapTo visible: !model.hide - Component.onCompleted: { - if ((root.countOnStartUp > 0) && (root.countOnStartUp - 1) < index) { - //new message, increment z order - z = index; - } - } messageContextMenu: root.messageContextMenuInst prevMessageIndex: { @@ -348,6 +345,53 @@ Item { } scrollToBottom: chatLogView.scrollToBottom timeout: model.timeout + Component.onCompleted: { + if ((root.countOnStartUp > 0) && (root.countOnStartUp - 1) < index) { + //new message, increment z order + z = index; + } + messageStore.fromAuthor = model.fromAuthor; + messageStore.chatId = model.chatId; + messageStore.userName = model.userName; + messageStore.alias = model.alias; + messageStore.localName = model.localName; + messageStore.message = model.message; + messageStore.plainText = model.plainText; + messageStore.identicon = model.identicon; + messageStore.isCurrentUser = model.isCurrentUser; + messageStore.timestamp = model.timestamp; + messageStore.sticker = model.sticker; + messageStore.contentType = model.contentType; + messageStore.replaces = model.replaces; + messageStore.isEdited = model.isEdited; + messageStore.outgoingStatus = model.outgoingStatus; + messageStore.responseTo = model.responseTo; + messageStore.authorCurrentMsg = msgDelegate.ListView.section; + // The previous message is actually the nextSection since we reversed the list order + messageStore.authorPrevMsg = msgDelegate.ListView.nextSection; + messageStore.imageClick = imagePopup.openPopup.bind(imagePopup); + messageStore.messageId = model.messageId; + messageStore.emojiReactions = model.emojiReactions; + messageStore.linkUrls = model.linkUrls; + messageStore.communityId = model.communityId; + messageStore.hasMention = model.hasMention; + messageStore.stickerPackId = model.stickerPackId; + messageStore.pinnedMessage = model.isPinned; + messageStore.pinnedBy = model.pinnedBy; + messageStore.gapFrom = model.gapFrom; + messageStore.gapTo = model.gapTo; + messageStore.messageContextMenu = root.messageContextMenuInst; + messageStore.prevMessageIndex = + // This is used in order to have access to the previous message and determine the timestamp + // we can't rely on the index because the sequence of messages is not ordered on the nim side + (msgDelegate.DelegateModel.itemsIndex < messageListDelegate.items.count - 1) ? + messageListDelegate.items.get(msgDelegate.DelegateModel.itemsIndex + 1).model.index + : -1; + messageStore.nextMessageIndex = (msgDelegate.DelegateModel.itemsIndex < 1) ? + -1 : messageListDelegate.items.get(msgDelegate.DelegateModel.itemsIndex - 1).model.index; + messageStore.scrollToBottom = chatLogView.scrollToBottom; + messageStore.timeout = model.timeout; + } } Component.onCompleted: { modelLoadingDelayTimer.start(); diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatText.qml b/ui/app/AppLayouts/Chat/views/ChatTextView.qml similarity index 96% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatText.qml rename to ui/app/AppLayouts/Chat/views/ChatTextView.qml index 61a5d07cf8..5fcfc07da9 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatText.qml +++ b/ui/app/AppLayouts/Chat/views/ChatTextView.qml @@ -1,14 +1,15 @@ import QtQuick 2.13 -import "../../../../../shared" -import "../../../../../shared/panels" -import "../../../../../shared/controls" - +import "../../../../shared" +import "../../../../shared/panels" +import "../../../../shared/controls" import utils 1.0 import QtGraphicalEffects 1.0 Item { id: root + property var store + property var messageStore property bool longChatText: true property bool veryLongChatText: chatsModel.plainText(message).length > (appSettings.useCompactMode ? Constants.limitLongChatTextCompactMode : Constants.limitLongChatText) @@ -16,7 +17,7 @@ Item { property alias textField: chatText signal linkActivated(url link) - + property alias hoveredLink: chatText.hoveredLink property bool linkHovered: chatText.hoveredLink !== "" z: 51 diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatTime.qml b/ui/app/AppLayouts/Chat/views/ChatTimeView.qml similarity index 71% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatTime.qml rename to ui/app/AppLayouts/Chat/views/ChatTimeView.qml index 5c8489dfd3..3a799e9a2d 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/ChatTime.qml +++ b/ui/app/AppLayouts/Chat/views/ChatTimeView.qml @@ -1,13 +1,13 @@ import QtQuick 2.14 -import "../../../../../shared" -import "../../../../../shared/panels" -import "../../../../../shared/status" - +import "../../../../shared" +import "../../../../shared/panels" +import "../../../../shared/status" import utils 1.0 StyledText { id: chatTime - visible: isMessage + property string timestamp + visible: chatTime.messageStore.isMessage color: Style.current.secondaryText text: Utils.formatTime(timestamp) font.pixelSize: Style.current.asideTextFontSize diff --git a/ui/app/AppLayouts/Chat/CommunityColumn.qml b/ui/app/AppLayouts/Chat/views/CommunityColumnView.qml similarity index 97% rename from ui/app/AppLayouts/Chat/CommunityColumn.qml rename to ui/app/AppLayouts/Chat/views/CommunityColumnView.qml index 992c40ad69..70db64d90a 100644 --- a/ui/app/AppLayouts/Chat/CommunityColumn.qml +++ b/ui/app/AppLayouts/Chat/views/CommunityColumnView.qml @@ -9,12 +9,11 @@ import StatusQ.Popups 0.1 import utils 1.0 -import "../../../shared" -import "../../../shared/popups" -import "../../../shared/status" -import "./components" -import "./CommunityComponents" - +import "../../../../shared" +import "../../../../shared/popups" +import "../../../../shared/status" +import "../popups/community" +import "../panels/communities" Item { id: root @@ -226,7 +225,7 @@ Item { } } - chatListPopupMenu: ChatContextMenu { + chatListPopupMenu: ChatContextMenuView { openHandler: function (id) { chatItem = chatsModel.channelView.getChatItemById(id) } @@ -241,7 +240,7 @@ Item { anchors.top: communityChatListAndCategories.bottom anchors.topMargin: active ? Style.current.padding : 0 sourceComponent: Component { - CommunityWelcomeBanner {} + CommunityWelcomeBannerPanel {} } } @@ -257,7 +256,7 @@ Item { width: parent.width height: backupBanner.height - BackUpCommuntyBanner { + BackUpCommuntyBannerPanel { id: backupBanner } MouseArea { diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/CompactMessage.qml b/ui/app/AppLayouts/Chat/views/CompactMessageView.qml similarity index 75% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/CompactMessage.qml rename to ui/app/AppLayouts/Chat/views/CompactMessageView.qml index 3fd8258115..45a2e01858 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/CompactMessage.qml +++ b/ui/app/AppLayouts/Chat/views/CompactMessageView.qml @@ -1,32 +1,42 @@ -import QtQuick 2.13 +import QtQuick 2.13 import QtGraphicalEffects 1.13 -import "../../../../../shared" -import "../../../../../shared/panels" -import "../../../../../shared/controls" -import "../../../../../shared/status" - +import "../../../../shared" +import "../../../../shared/panels" +import "../../../../shared/controls" +import "../../../../shared/status" import utils 1.0 +import "../panels" +import "../controls" + Item { id: root - property var clickMessage: function () {} + property var store + property var messageStore property int chatHorizontalPadding: Style.current.halfPadding property int chatVerticalPadding: 7 - property string linkUrls: "" + property string linkUrls: root.messageStore.linkUrls property int contentType: 2 property var container property bool isCurrentUser: false - property bool isHovered: typeof hoveredMessage !== "undefined" && hoveredMessage === messageId - property bool isMessageActive: typeof activeMessage !== "undefined" && activeMessage === messageId + property bool isHovered: typeof root.messageStore.hoveredMessage !== "undefined" && root.messageStore.hoveredMessage === messageId + property bool isMessageActive: typeof root.messageStore.activeMessage !== "undefined" && root.messageStore.activeMessage === messageId property bool headerRepeatCondition: (authorCurrentMsg !== authorPrevMsg || shouldRepeatHeader || dateGroupLbl.visible || chatReply.active) - property bool showMoreButton: switch (chatsModel.channelView.activeChannel.chatType) { - case Constants.chatTypeOneToOne: return true - case Constants.chatTypePrivateGroupChat: return chatsModel.channelView.activeChannel.isAdmin(profileModel.profile.pubKey) ? true : isCurrentUser - case Constants.chatTypePublic: return isCurrentUser - case Constants.chatTypeCommunity: return chatsModel.communities.activeCommunity.admin ? true : isCurrentUser - case Constants.chatTypeStatusUpdate: return false - default: return false - } + property bool showMoreButton: { + if (!!root.store) { + switch (root.store.chatsModelInst.channelView.activeChannel.chatType) { + case Constants.chatTypeOneToOne: return true + case Constants.chatTypePrivateGroupChat: return root.store.chatsModelInst.channelView.activeChannel.isAdmin(root.store.profileModelInst.profile.pubKey) ? true : isCurrentUser + case Constants.chatTypePublic: return isCurrentUser + case Constants.chatTypeCommunity: return root.store.chatsModelInst.communities.activeCommunity.admin ? true : isCurrentUser + case Constants.chatTypeStatusUpdate: return false + default: return false + } + } + else { + return false; + } + } property bool showEdit: true property var messageContextMenu signal addEmoji(bool isProfileClick, bool isSticker, bool isImage , var image, bool emojiOnly, bool hideEmojiPicker) @@ -52,18 +62,24 @@ Item { } } - ChatButtons { + ChatButtonsPanel { contentType: root.contentType parentIsHovered: !isEdit && root.isHovered - onHoverChanged: hovered && setHovered(messageId, hovered) + onHoverChanged: { + hovered && root.messageStore.setHovered(messageId, hovered) + } anchors.right: parent.right anchors.rightMargin: 20 anchors.top: messageContainer.top // This is not exactly like the design because the hover becomes messed up with the buttons on top of another Message anchors.topMargin: -Style.current.halfPadding - showEdit: root.showEdit messageContextMenu: root.messageContextMenu showMoreButton: root.showMoreButton + fromAuthor: fromAuthor + editBtnActive: isText && !isEdit && isCurrentUser && showEdit + onClickMessage: { + parent.parent.parent.clickMessage(isProfileClick, isSticker, isImage, image, emojiOnly); + } } Loader { @@ -72,7 +88,7 @@ Item { Connections { enabled: root.isMessageActive target: messageContextMenu - onClosed: setMessageActive(messageId, false) + onClosed: root.messageStore.setMessageActive(messageId, false) } } } @@ -188,7 +204,7 @@ Item { StyledText { //% "Pinned by %1" - text: qsTrId("pinned-by--1").arg(chatsModel.alias(pinnedBy)) + text: qsTrId("pinned-by--1").arg(root.store.chatsModelInst.alias(pinnedBy)) anchors.left: pinImage.right anchors.verticalCenter: parent.verticalCenter font.pixelSize: 13 @@ -197,18 +213,47 @@ Item { } } - ChatReply { + + Connections { + target: chatsModel.messageView + onMessageEdited: { + if(chatReply.item) + chatReply.item.messageEdited(editedMessageId, editedMessageContent) + } + } + + ChatReplyPanel { id: chatReply anchors.top: pinnedRectangleLoader.active ? pinnedRectangleLoader.bottom : parent.top anchors.topMargin: active ? 4 : 0 anchors.left: chatImage.left + anchors.right: parent.right + anchors.rightMargin: Style.current.padding + longReply: active && textFieldImplicitWidth > width container: root.container chatHorizontalPadding: root.chatHorizontalPadding - anchors.right: parent.right - anchors.rightMargin: Style.current.padding + stickerData: chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "sticker") + active: responseTo !== "" && replyMessageIndex > -1 && !activityCenterMessage +// To-Do move to store later? +// isCurrentUser: root.messageStore.isCurrentUser +// repliedMessageType: root.messageStore.repliedMessageType +// repliedMessageImage: root.messageStore.repliedMessageImage +// repliedMessageUserIdenticon: root.messageStore.repliedMessageUserIdenticon +// repliedMessageIsEdited: root.messageStore.repliedMessageIsEdited +// repliedMessageUserImage: root.messageStore.repliedMessageUserImage +// repliedMessageAuthor: root.messageStore.repliedMessageAuthor +// repliedMessageContent: root.messageStore.repliedMessageContent +// responseTo: root.messageStore.responseTo +// onScrollToBottom: { +// root.messageStore.scrollToBottom(isit, container); +// } + onClickMessage: { + parent.parent.parent.clickMessage(isProfileClick, isSticker, isImage, image, emojiOnly, hideEmojiPicker, isReply); + } } + UserImage { id: chatImage active: isMessage && headerRepeatCondition @@ -217,6 +262,14 @@ Item { anchors.top: chatReply.active ? chatReply.bottom : pinnedRectangleLoader.active ? pinnedRectangleLoader.bottom : parent.top anchors.topMargin: chatReply.active || pinnedRectangleLoader.active ? 4 : Style.current.smallPadding +// messageContextMenu: root.messageStore.messageContextMenu +// isCurrentUser: root.messageStore.isCurrentUser +// profileImage: root.messageStore.profileImageSource +// isMessage: root.messageStore.isMessage +// identiconImageSource: root.messageStore.identicon + onClickMessage: { + parent.parent.parent.parent.clickMessage(isProfileClick, isSticker, isImage, image, emojiOnly, hideEmojiPicker, isReply); + } } UsernameLabel { @@ -225,15 +278,24 @@ Item { anchors.leftMargin: root.chatHorizontalPadding anchors.top: chatImage.top anchors.left: chatImage.right +// messageContextMenu: root.messageStore.messageContextMenu +// isCurrentUser: root.messageStore.isCurrentUser +// localName: root.messageStore.localName +// userName: root.messageStore.userName +// displayUserName: root.messageStore.displayUserName + onClickMessage: { + parent.parent.parent.parent.clickMessage(true, false, false, null, false, false, false); + } } - ChatTime { + ChatTimeView { id: chatTime visible: !isEdit && headerRepeatCondition anchors.verticalCenter: chatName.verticalCenter anchors.left: chatName.right anchors.leftMargin: 4 color: Style.current.secondaryText + timestamp: timestamp } Loader { @@ -264,7 +326,7 @@ Item { index += 8 // " -1 && pubkey === repliedMessageAuthorPubkey) { - const imgReply = appMain.getProfileImage(repliedMessageAuthorPubkey, repliedMessageAuthorIsCurrentUser, false) - if (imgReply) { - repliedMessageUserImage = imgReply - } - } - } - } - - Connections { - target: chatsModel.messageView - onHideMessage: { - // This hack is used because message_list deleteMessage sometimes does not remove the messages (there might be an issue with the delegate model) - if(mId === messageId){ - root.visible = 0; - root.height = 0; - } - } - } - property var clickMessage: function(isProfileClick, isSticker = false, isImage = false, image = null, emojiOnly = false, hideEmojiPicker = false, isReply = false, isRightClickOnImage = false, imageSource = "") { if (placeholderMessage || activityCenterMessage) { return @@ -212,6 +183,50 @@ Item { messageContextMenu.y = messageContextMenu.setYPosition() } + + function showReactionAuthors(fromAccounts, emojiId) { + return store.showReactionAuthors(fromAccounts, emojiId) + } + + function startMessageFoundAnimation() { + messageLoader.item.startMessageFoundAnimation(); + } + ///////////////////////////////////////////// + + + property var rootStore + property var messageStore + + Connections { + enabled: (!placeholderMessage && !!root.rootStore) + target: !!root.rootStore ? root.rootStore.profileModelInst.contacts.list : null + onContactChanged: { + if (pubkey === fromAuthor) { + const img = appMain.getProfileImage(userPubKey, isCurrentUser, useLargeImage) + if (img) { + profileImageSource = img + } + } else if (replyMessageIndex > -1 && pubkey === repliedMessageAuthorPubkey) { + const imgReply = appMain.getProfileImage(repliedMessageAuthorPubkey, repliedMessageAuthorIsCurrentUser, false) + if (imgReply) { + repliedMessageUserImage = imgReply + } + } + } + } + + Connections { + enabled: !!root.rootStore + target: !!root.rootStore ? root.rootStore.chatsModelInst.messageView : null + onHideMessage: { + // This hack is used because message_list deleteMessage sometimes does not remove the messages (there might be an issue with the delegate model) + if(mId === messageId){ + root.visible = 0; + root.height = 0; + } + } + } + Loader { id: messageLoader width: parent.width @@ -356,7 +371,7 @@ Item { Component { id: channelIdentifierComponent - ChannelIdentifier { + ChannelIdentifierView { authorCurrentMsg: root.authorCurrentMsg profileImage: profileImageSource } @@ -395,8 +410,7 @@ Item { Component { id: messageComponent - NormalMessage { - clickMessage: root.clickMessage + NormalMessageView { linkUrls: root.linkUrls isCurrentUser: root.isCurrentUser contentType: root.contentType @@ -406,36 +420,44 @@ Item { Component { id: statusUpdateComponent - StatusUpdate { + StatusUpdatePanel { statusAgeEpoch: root.statusAgeEpoch - clickMessage: root.clickMessage container: root messageContextMenu: root.messageContextMenu onAddEmoji: { root.clickMessage(isProfileClick, isSticker, isImage , image, emojiOnly, hideEmojiPicker); } + onChatImageClicked: { + messageStore.imageClick(image); + } + onUserNameClicked: { + root.parent.clickMessage(isProfileClick); + } + onEmojiBtnClicked: { + root.parent.clickMessage(isProfileClick, isSticker, isImage, image, emojiOnly); + } + onClickMessage: { + root.parent.clickMessage(isProfileClick, isSticker, isImage, image, emojiOnly, hideEmojiPicker, isReply); + } + onSetMessageActive: { + root.messageStore.setMessageActive(messageId, active);; + } } } Component { id: compactMessageComponent - CompactMessage { - clickMessage: root.clickMessage + CompactMessageView { linkUrls: root.linkUrls isCurrentUser: root.isCurrentUser contentType: root.contentType showEdit: root.showEdit container: root messageContextMenu: root.messageContextMenu + messageStore: root.messageStore onAddEmoji: { root.clickMessage(isProfileClick, isSticker, isImage , image, emojiOnly, hideEmojiPicker); } } } } - -/*##^## -Designer { - D{i:0;formeditorColor:"#ffffff";formeditorZoom:1.75;height:80;width:800} -} -##^##*/ diff --git a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/NormalMessage.qml b/ui/app/AppLayouts/Chat/views/NormalMessageView.qml similarity index 65% rename from ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/NormalMessage.qml rename to ui/app/AppLayouts/Chat/views/NormalMessageView.qml index e76a444300..95d405a894 100644 --- a/ui/app/AppLayouts/Chat/ChatColumn/MessageComponents/NormalMessage.qml +++ b/ui/app/AppLayouts/Chat/views/NormalMessageView.qml @@ -1,23 +1,29 @@ import QtQuick 2.13 -import "../../../../../shared" -import "../../../../../shared/status" +import "../../../../shared" +import "../../../../shared/status" import utils 1.0 -Item { - property var clickMessage: function () {} - property string linkUrls: "" - property bool isCurrentUser: false - property int contentType: 2 - property var container - property bool headerRepeatCondition: (authorCurrentMsg != authorPrevMsg || shouldRepeatHeader || dateGroupLbl.visible) +import "../panels" +import "../views" +import "../controls" +Item { id: root anchors.top: parent.top anchors.topMargin: authorCurrentMsg !== authorPrevMsg ? Style.current.smallPadding : 0 height: childrenRect.height + this.anchors.topMargin + (dateGroupLbl.visible ? dateGroupLbl.height : 0) width: parent.width + property var store + property var messageStore + property string linkUrls: "" + property bool isCurrentUser: false + property int contentType: 2 + property var container + property bool headerRepeatCondition: (authorCurrentMsg !== authorPrevMsg + || shouldRepeatHeader || dateGroupLbl.visible) + DateGroup { id: dateGroupLbl previousMessageIndex: prevMessageIndex @@ -28,20 +34,34 @@ Item { UserImage { id: chatImage - active: chatsModel.channelView.activeChannel.chatType !== Constants.chatTypeOneToOne && isMessage && headerRepeatCondition && !root.isCurrentUser + active: root.store.chatsModelInst.channelView.activeChannel.chatType !== Constants.chatTypeOneToOne && isMessage && headerRepeatCondition && !root.isCurrentUser anchors.left: parent.left anchors.leftMargin: Style.current.padding anchors.top: dateGroupLbl.visible ? dateGroupLbl.bottom : parent.top anchors.topMargin: 20 +// isCurrentUser: root.messageStore.isCurrentUser +// profileImage: root.messageStore.profileImageSource +// isMessage: root.messageStore.isMessage +// identiconImageSource: root.messageStore.identicon + onClickMessage: { + root.parent.clickMessage(isProfileClick, isSticker, isImage, image, emojiOnly, hideEmojiPicker, isReply); + } } UsernameLabel { id: chatName - visible: chatsModel.channelView.activeChannel.chatType !== Constants.chatTypeOneToOne && isMessage && headerRepeatCondition && !root.isCurrentUser + visible: root.store.chatsModelInst.channelView.activeChannel.chatType !== Constants.chatTypeOneToOne && isMessage && headerRepeatCondition && !root.isCurrentUser anchors.leftMargin: 20 anchors.top: dateGroupLbl.visible ? dateGroupLbl.bottom : parent.top anchors.topMargin: 0 anchors.left: chatImage.right +// isCurrentUser: root.messageStore.isCurrentUser +// userName: root.messageStore.userName +// localName: root.messageStore.localName +// displayUserName: root.messageStore.displayUserName + onClickMessage: { + root.parent.clickMessage(true, false, false, null, false, false, false); + } } Rectangle { @@ -52,7 +72,7 @@ Item { property int chatVerticalPadding: isImage ? 4 : 6 property int chatHorizontalPadding: isImage ? 0 : 12 property bool longReply: chatReply.active && repliedMessageContent.length > maxMessageChars - property bool longChatText: chatsModel.plainText(message).split('\n').some(function (messagePart) { + property bool longChatText: root.store.chatsModelInst.plainText(root.messageStore.message).split('\n').some(function (messagePart) { return messagePart.length > maxMessageChars }) @@ -64,7 +84,7 @@ Item { if (isImage) { return "transparent" } - return root.isCurrentUser ? Style.current.primary : Style.current.secondaryBackground + return isCurrentUser ? Style.current.primary : Style.current.secondaryBackground } border.color: isSticker ? Style.current.border : Style.current.transparent border.width: 1 @@ -122,7 +142,7 @@ Item { anchors.topMargin: 0 visible: isMessage && contentType !== Constants.transactionType - ChatReply { + ChatReplyPanel { id: chatReply longReply: chatBox.longReply anchors.top: parent.top @@ -133,9 +153,36 @@ Item { anchors.rightMargin: chatBox.chatHorizontalPadding container: root.container chatHorizontalPadding: chatBox.chatHorizontalPadding + stickerData: chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "sticker") + active: responseTo !== "" && replyMessageIndex > -1 && !activityCenterMessage +// To-Do move to store later? +// isCurrentUser: root.messageStore.isCurrentUser +// repliedMessageType: root.messageStore.repliedMessageType +// repliedMessageImage: root.messageStore.repliedMessageImage +// repliedMessageUserIdenticon: root.messageStore.repliedMessageUserIdenticon +// repliedMessageIsEdited: root.messageStore.repliedMessageIsEdited +// repliedMessageUserImage: root.messageStore.repliedMessageUserImage +// repliedMessageAuthor: root.messageStore.repliedMessageAuthor +// repliedMessageContent: root.messageStore.repliedMessageContent +// responseTo: root.messageStore.responseTo +// onScrollToBottom: { +// root.messageStore.scrollToBottom(isit, container); +// } + onClickMessage: { + root.parent.clickMessage(isProfileClick, isSticker, isImage, image, emojiOnly, hideEmojiPicker, isReply); + } } - ChatText { + + Connections { + target: chatsModel.messageView + onMessageEdited: { + if(chatReply.item) + chatReply.item.messageEdited(editedMessageId, editedMessageContent) + } + } + + ChatTextView { id: chatText longChatText: chatBox.longChatText anchors.top: chatReply.bottom @@ -144,6 +191,7 @@ Item { anchors.leftMargin: chatBox.chatHorizontalPadding anchors.right: chatBox.longChatText ? parent.right : undefined anchors.rightMargin: chatBox.longChatText ? chatBox.chatHorizontalPadding : 0 + messageStore: root.store.messageStore textField.color: !root.isCurrentUser ? Style.current.textColor : Style.current.currentUserTextColor Connections { target: appSettings.useCompactMode ? null : chatBox @@ -153,15 +201,15 @@ Item { } onLinkActivated: { - if (activityCenterMessage) { - clickMessage(false, isSticker, false) + if (root.messageStore.activityCenterMessage) { + clickMessage(false, root.messageStore.isSticker, false) } } } Loader { id: chatImageContent - active: isImage && !!image + active: root.messageStore.isImage && !!image anchors.top: parent.top anchors.topMargin: Style.current.smallPadding anchors.left: parent.left @@ -187,14 +235,14 @@ Item { Loader { id: audioPlayerLoader - active: isAudio + active: root.messageStore.isAudio sourceComponent: audioPlayer anchors.verticalCenter: parent.verticalCenter } Component { id: audioPlayer - AudioPlayer { + AudioPlayerPanel { audioSource: audio } } @@ -207,19 +255,28 @@ Item { anchors.topMargin: chatBox.chatVerticalPadding color: Style.current.transparent contentType: root.contentType + stickerData: root.messageStore.sticker onLoaded: { - scrollToBottom(true, root.container) + root.messageStore.scrollToBottom(true, root.container) } } MessageMouseArea { anchors.fill: parent enabled: !chatText.linkHovered + isActivityCenterMessage: root.messageStore.activityCenterMessage + onClickMessage: { + root.parent.clickMessage(isProfileClick, root.messageStore.isSticker, root.messageStore.isImage) + } + onSetMessageActive: { + root.messageStore.setMessageActive(root.messageStore.messageId, active); + } } RectangleCorner { // TODO find a way to show the corner for stickers since they have a border - visible: isMessage + visible: root.messageStore.isMessage + isCurrentUser: root.isCurrentUser } } @@ -231,7 +288,17 @@ Item { anchors.right: isCurrentUser ? parent.right : undefined anchors.rightMargin: Style.current.padding sourceComponent: Component { - TransactionBubble {} + TransactionBubblePanel { + focusedAccount: root.store.walletModelInst.accountsView.focusedAccount + activeChannelName: root.store.chatsModelInst.channelView.activeChannel.name + activeChannelIdenticon: root.store.chatsModelInst.channelView.activeChannel.identicon + onGetGasPrice: { + root.store.walletModelInst.gasView.getGasPrice(); + } + onSendTransactionClicked: { + root.store.walletModelInst.accountsView.setFocusedAccountByAddress(fromAddress); + } + } } } @@ -249,19 +316,21 @@ Item { anchors.rightMargin: 6 } - ChatTime { + ChatTimeView { id: chatTime - visible: isMessage && !emojiReactionLoader.active + visible: root.messageStore.isMessage && !emojiReactionLoader.active anchors.top: isImage ? undefined : (linksLoader.active ? linksLoader.bottom : chatBox.bottom) anchors.topMargin: isImage ? 0 : 4 anchors.verticalCenter: isImage ? dateTimeBackground.verticalCenter : undefined anchors.right: isImage ? dateTimeBackground.right : (linksLoader.active ? linksLoader.right : chatBox.right) anchors.rightMargin: isImage ? 6 : (root.isCurrentUser ? 5 : Style.current.padding) + timestamp: root.messageStore.timestamp } SentMessage { id: sentMessage - visible: root.isCurrentUser && !timeout && !isExpired && isMessage && outgoingStatus === "sent" + visible: root.isCurrentUser && !root.messageStore.timeout && !root.messageStore.isExpired + && root.messageStore.isMessage && root.messageStore.outgoingStatus === "sent" anchors.verticalCenter: chatTime.verticalCenter anchors.right: chatTime.left anchors.rightMargin: 5 @@ -272,6 +341,10 @@ Item { anchors.verticalCenter: chatTime.verticalCenter anchors.right: chatTime.left anchors.rightMargin: 5 + isCurrentUser: root.isCurrentUser + onClicked: { + root.store.chatsModelInst.messageView.resendMessage(chatId, messageId) + } } Loader { @@ -286,7 +359,7 @@ Item { anchors.bottomMargin: Style.current.halfPadding sourceComponent: Component { - LinksMessage { + LinksMessageView { linkUrls: root.linkUrls container: root.container isCurrentUser: root.isCurrentUser @@ -307,6 +380,13 @@ Item { Component { id: emojiReactionsComponent - EmojiReactions {} + EmojiReactionsPanel { +// isMessageActive: root.store.messageStore.isMessageActive +// emojiReactionsModel: root.store.messageStore.emojiReactionsModel + onSetMessageActive: { + root.store.messageStore.setMessageActive(messageId, active);; + } + onToggleReaction: chatsModel.toggleReaction(messageId, emojiID) + } } } diff --git a/ui/app/AppLayouts/Profile/ProfileLayout.qml b/ui/app/AppLayouts/Profile/ProfileLayout.qml index 7ef65f3e85..ef78c1ebb5 100644 --- a/ui/app/AppLayouts/Profile/ProfileLayout.qml +++ b/ui/app/AppLayouts/Profile/ProfileLayout.qml @@ -16,7 +16,7 @@ StatusAppTwoPanelLayout { id: profileView property RootStore store: RootStore { } - + property var globalStore property int contentMaxWidth: 624 property int contentMinWidth: 450 property alias changeProfileSection: leftTab.changeProfileSection @@ -51,6 +51,7 @@ StatusAppTwoPanelLayout { EnsView { id: ensContainer store: profileView.store + messageStore: profileView.globalStore.messageStore } PrivacyView { @@ -59,6 +60,7 @@ StatusAppTwoPanelLayout { AppearanceView { store: profileView.store + globalStore: profileView.globalStore } SoundsView {} diff --git a/ui/app/AppLayouts/Profile/Sections/Contacts/ContactList.qml b/ui/app/AppLayouts/Profile/Sections/Contacts/ContactList.qml new file mode 100644 index 0000000000..31ccf262fe --- /dev/null +++ b/ui/app/AppLayouts/Profile/Sections/Contacts/ContactList.qml @@ -0,0 +1,88 @@ +import QtQuick 2.13 +import QtQuick.Controls 2.13 +import QtQuick.Layouts 1.13 +import "./samples/" + +import utils 1.0 +import "../../../../../shared" +import "../../../Chat/popups" +import "." + +ListView { + id: contactList + property var contacts: ContactsData {} + property string searchStr: "" + property string searchString: "" + property string lowerCaseSearchString: searchString.toLowerCase() + property string contactToRemove: "" + property bool hideBlocked: false + + property Component profilePopupComponent: ProfilePopup { + id: profilePopup + onClosed: destroy() + } + + width: parent.width + + model: contacts + + delegate: Contact { + name: Utils.removeStatusEns(model.name) + address: model.address + localNickname: model.localNickname + identicon: model.thumbnailImage || model.identicon + isContact: model.isContact + isBlocked: model.isBlocked + profileClick: function (showFooter, userName, fromAuthor, identicon, textParam, nickName) { + var popup = profilePopupComponent.createObject(contactList); + popup.openPopup(showFooter, userName, fromAuthor, identicon, textParam, nickName); + } + visible: { + if (hideBlocked && model.isBlocked) { + return false + } + + return searchString === "" || + model.name.toLowerCase().includes(lowerCaseSearchString) || + model.address.toLowerCase().includes(lowerCaseSearchString) + } + onBlockContactActionTriggered: { + blockContactConfirmationDialog.contactName = name + blockContactConfirmationDialog.contactAddress = address + blockContactConfirmationDialog.open() + } + onRemoveContactActionTriggered: { + removeContactConfirmationDialog.value = address + removeContactConfirmationDialog.open() + } + } + + // TODO: Make BlockContactConfirmationDialog a dynamic component on a future refactor + BlockContactConfirmationDialog { + id: blockContactConfirmationDialog + onBlockButtonClicked: { + profileModel.contacts.blockContact(blockContactConfirmationDialog.contactAddress) + blockContactConfirmationDialog.close() + } + } + + // TODO: Make ConfirmationDialog a dynamic component on a future refactor + ConfirmationDialog { + id: removeContactConfirmationDialog + //% "Remove contact" + header.title: qsTrId("remove-contact") + //% "Are you sure you want to remove this contact?" + confirmationText: qsTrId("are-you-sure-you-want-to-remove-this-contact-") + onConfirmButtonClicked: { + if (profileModel.contacts.isAdded(removeContactConfirmationDialog.value)) { + profileModel.contacts.removeContact(removeContactConfirmationDialog.value); + } + removeContactConfirmationDialog.close() + } + } +} +/*##^## +Designer { + D{i:0;autoSize:true;height:480;width:640} +} +##^##*/ diff --git a/ui/app/AppLayouts/Profile/panels/ContactsListPanel.qml b/ui/app/AppLayouts/Profile/panels/ContactsListPanel.qml index 24a90d6fe2..ad9c1215a7 100644 --- a/ui/app/AppLayouts/Profile/panels/ContactsListPanel.qml +++ b/ui/app/AppLayouts/Profile/panels/ContactsListPanel.qml @@ -4,7 +4,7 @@ import QtQuick.Layouts 1.13 import utils 1.0 import "../../../../shared" -import "../../Chat/components" +import "../../Chat/popups" import "." diff --git a/ui/app/AppLayouts/Profile/views/AppearanceView.qml b/ui/app/AppLayouts/Profile/views/AppearanceView.qml index 73e7aabb37..3a72a4e6f4 100644 --- a/ui/app/AppLayouts/Profile/views/AppearanceView.qml +++ b/ui/app/AppLayouts/Profile/views/AppearanceView.qml @@ -6,7 +6,9 @@ import QtQuick.Controls.Universal 2.12 import utils 1.0 import "../../../../shared" import "../../../../shared/status" -import "../../Chat/ChatColumn" + +//TODO remove import dependency +import "../../Chat/views" import StatusQ.Core 0.1 @@ -18,6 +20,8 @@ ScrollView { id: root contentHeight: appearanceContainer.height clip: true + property var store + property var globalStore enum Theme { Light, @@ -25,8 +29,6 @@ ScrollView { System } - property var store - function updateTheme(theme) { globalSettings.theme = theme Style.changeTheme(theme, systemPalette.isCurrentSystemThemeDark()) @@ -73,18 +75,29 @@ ScrollView { border.color: Style.current.border color: Style.current.transparent - Message { + MessageView { id: paceholderMessage anchors.top: parent.top anchors.topMargin: Style.current.padding*2 anchors.left: parent.left anchors.leftMargin: Style.current.smallPadding + rootStore: root.rootStore + messageStore: root.globalStore.messageStore + ///////////TODO Remove userName: "@vitalik" identicon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAb0lEQVR4Ae3UQQqAIBRF0Wj9ba9Bq6l5JBQqfn/ngDMH3YS3AAB/tO3H+XRG3b9bR/+gVoREI2RapVXpfd5+X5oXERKNkHS+rk3tOpWkeREh0QiZVu91ql2zNC8iJBoh0yqtSqt1slpCghICANDPBc0ESPh0bHkHAAAAAElFTkSuQmCC" //% "Blockchains will drop search costs, causing a kind of decomposition that allows you to have markets of entities that are horizontally segregated and vertically segregated." message: qsTrId("blockchains-will-drop-search-costs--causing-a-kind-of-decomposition-that-allows-you-to-have-markets-of-entities-that-are-horizontally-segregated-and-vertically-segregated-") contentType: Constants.messageType placeholderMessage: true + Component.onCompleted: { + messageStore.userName = "@vitalik"; + messageStore.identicon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAb0lEQVR4Ae3UQQqAIBRF0Wj9ba9Bq6l5JBQqfn/ngDMH3YS3AAB/tO3H+XRG3b9bR/+gVoREI2RapVXpfd5+X5oXERKNkHS+rk3tOpWkeREh0QiZVu91ql2zNC8iJBoh0yqtSqt1slpCghICANDPBc0ESPh0bHkHAAAAAElFTkSuQmCC"; + //% "Blockchains will drop search costs, causing a kind of decomposition that allows you to have markets of entities that are horizontally segregated and vertically segregated." + messageStore.message = qsTrId("blockchains-will-drop-search-costs--causing-a-kind-of-decomposition-that-allows-you-to-have-markets-of-entities-that-are-horizontally-segregated-and-vertically-segregated-"); + messageStore.contentType = Constants.messageType; + //messageStore.placeholderMessage = true; + } } } diff --git a/ui/app/AppLayouts/Profile/views/EnsListView.qml b/ui/app/AppLayouts/Profile/views/EnsListView.qml index 8dd472d2e2..535b78df6e 100644 --- a/ui/app/AppLayouts/Profile/views/EnsListView.qml +++ b/ui/app/AppLayouts/Profile/views/EnsListView.qml @@ -3,15 +3,18 @@ import QtQuick.Layouts 1.3 import QtQuick.Controls 2.14 import utils 1.0 -import "../../../../shared" -import "../../../../shared/panels" -import "../../../../shared/status" -import "../../Chat/ChatColumn/MessageComponents" import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 import "../popups" +import "../../../../shared" +import "../../../../shared/panels" +import "../../../../shared/status" + +//TODO remove these dependencies in imports +import "../../Chat/views" +import "../../Chat/controls" Item { id: root @@ -32,7 +35,9 @@ Item { property bool isText: true property var clickMessage: function(){} property string identicon: store.identicon + //property string identicon: profileModel.profile.identicon property int timestamp: 1577872140 + property var messageStore function shouldDisplayExampleMessage(){ return store.ens.rowCount() > 0 && store.ensPendingLen() !== store.ens.rowCount() && store.preferredUsername !== "" @@ -273,6 +278,13 @@ Item { anchors.leftMargin: Style.current.padding anchors.top: parent.top anchors.topMargin: 20 +// isCurrentUser: root.isCurrentUser +// profileImage: root.messageStore.profileImageSource +// isMessage: root.messageStore.isMessage +// identiconImageSource: root.messageStore.identicon + onClickMessage: { + root.parent.clickMessage(isProfileClick, isSticker, isImage, image, emojiOnly, hideEmojiPicker, isReply); + } } UsernameLabel { @@ -283,6 +295,13 @@ Item { anchors.top: parent.top anchors.topMargin: 0 anchors.left: chatImage.right +// isCurrentUser: root.messageStore.isCurrentUser +// userName: root.messageStore.userName +// localName: root.messageStore.localName +// displayUserName: root.messageStore.displayUserName + onClickMessage: { + root.parent.clickMessage(true, false, false, null, false, false, false); + } } Rectangle { @@ -297,7 +316,7 @@ Item { anchors.leftMargin: 8 anchors.top: chatImage.top - ChatText { + ChatTextView { id: chatText anchors.top: parent.top anchors.topMargin: chatBox.chatVerticalPadding @@ -305,18 +324,20 @@ Item { anchors.leftMargin: chatBox.chatHorizontalPadding width: parent.width anchors.right: parent.right + messageStore: root.messageStore } RectangleCorner {} } - ChatTime { + ChatTimeView { id: chatTime anchors.top: chatBox.bottom anchors.topMargin: 4 anchors.bottomMargin: Style.current.padding anchors.right: chatBox.right anchors.rightMargin: Style.current.padding + timestamp: root.timestamp } StatusBaseText { diff --git a/ui/app/AppLayouts/Profile/views/EnsView.qml b/ui/app/AppLayouts/Profile/views/EnsView.qml index 028153dc3d..1afb1bb980 100644 --- a/ui/app/AppLayouts/Profile/views/EnsView.qml +++ b/ui/app/AppLayouts/Profile/views/EnsView.qml @@ -22,6 +22,7 @@ Item { property bool showSearchScreen: false property string addedUsername: "" property string selectedUsername: "" + property var messageStore signal next(output: string) signal back() @@ -283,6 +284,7 @@ Item { id: list EnsListView { store: root.store + messageStore: ensContainer.messageStore onAddBtnClicked: next("search") onSelectEns: { root.store.ensDetails(username) diff --git a/ui/app/AppLayouts/Timeline/TimelineLayout.qml b/ui/app/AppLayouts/Timeline/TimelineLayout.qml index fb2874de47..f25c298fac 100644 --- a/ui/app/AppLayouts/Timeline/TimelineLayout.qml +++ b/ui/app/AppLayouts/Timeline/TimelineLayout.qml @@ -8,9 +8,11 @@ import utils 1.0 import "../../../shared" import "../../../shared/controls" import "../../../shared/status" -import "../Chat/ChatColumn" -import "../Chat/ChatColumn/MessageComponents" -import "../Chat/components" + +import "../Chat/views" +import "../Chat/panels" +import "../Chat/popups" +import "../Chat/stores" import "stores" import "panels" @@ -26,6 +28,8 @@ ScrollView { clip: true ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + property var rootStore + property var messageStore property var onActivated: function () { store.setActiveChannelToTimeline() statusUpdateInput.textInput.forceActiveFocus(Qt.MouseFocusReason) @@ -138,11 +142,13 @@ ScrollView { lessThan: [ function(left, right) { return left.clock > right.clock } ] - model: root.store.chatsModelInst.messageView.messageList // TODO: Replace with StatusQ component once it lives there. - delegate: Message { + delegate: MessageView { id: msgDelegate + rootStore: root.rootStore + messageStore: root.messageStore + /////////TODO Remove fromAuthor: model.fromAuthor chatId: model.chatId userName: model.userName @@ -175,7 +181,41 @@ ScrollView { return -1; } timeout: model.timeout - messageContextMenu: MessageContextMenu { + messageContextMenu: msgCntxtMenu + Component.onCompleted: { + messageStore.fromAuthor = model.fromAuthor; + messageStore.chatId = model.chatId; + messageStore.userName = model.userName; + messageStore.alias = model.alias; + messageStore.localName = model.localName; + messageStore.message = model.message; + messageStore.plainText = model.plainText; + messageStore.identicon = model.identicon; + messageStore.isCurrentUser = model.isCurrentUser; + messageStore.timestamp = model.timestamp; + messageStore.sticker = model.sticker; + messageStore.contentType = model.contentType; + messageStore.outgoingStatus = model.outgoingStatus; + messageStore.responseTo = model.responseTo; + messageStore.authorCurrentMsg = msgDelegate.ListView.section; + messageStore.authorPrevMsg = msgDelegate.ListView.previousSection; + messageStore.imageClick = imagePopup.openPopup.bind(imagePopup); + messageStore.messageId = model.messageId; + messageStore.emojiReactions = model.emojiReactions; + messageStore.isStatusUpdate = true; + messageStore.statusAgeEpoch = ageUpdateTimer.epoch; + // This is used in order to have access to the previous message and determine the timestamp + // we can't rely on the index because the sequence of messages is not ordered on the nim side + messageStore.prevMessageIndex = + // This is used in order to have access to the previous message and determine the timestamp + // we can't rely on the index because the sequence of messages is not ordered on the nim side + (msgDelegate.DelegateModel.itemsIndex > 0) ? + messageListDelegate.items.get(msgDelegate.DelegateModel.itemsIndex - 1).model.index : -1; + messageStore.timeout = model.timeout; + messageStore.messageContextMenu = msgCntxtMenu; + } + MessageContextMenuPanel { + id: msgCntxtMenu reactionModel: EmojiReactions { } } } diff --git a/ui/app/AppLayouts/stores/MessageStore.qml b/ui/app/AppLayouts/stores/MessageStore.qml new file mode 100644 index 0000000000..6690fefe71 --- /dev/null +++ b/ui/app/AppLayouts/stores/MessageStore.qml @@ -0,0 +1,188 @@ +import QtQuick 2.13 +import utils 1.0 + +QtObject { + id: root + property string hoveredMessage + property string activeMessage + property string fromAuthor: "0x0011223344556677889910" + property string userName: "Jotaro Kujo" + property string alias: "" + property string localName: "" + property string message: "That's right. We're friends... Of justice, that is." + property string plainText: "That's right. We're friends... Of justice, that is." + property string identicon: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQAQMAAAC6caSPAAAABlBMVEXMzMz////TjRV2AAAAAWJLR0QB/wIt3gAAACpJREFUGBntwYEAAAAAw6D7Uw/gCtUAAAAAAAAAAAAAAAAAAAAAAAAAgBNPsAABAjKCqQAAAABJRU5ErkJggg==" + property bool isCurrentUser: false + property string timestamp: "1234567" + property string sticker: "Qme8vJtyrEHxABcSVGPF95PtozDgUyfr1xGjePmFdZgk9v" + property int contentType: 1 // constants don't work in default props + property string chatId: "chatId" + property string outgoingStatus: "" + property string responseTo: "" + property string messageId: "" + property string emojiReactions: "" + property int prevMessageIndex: -1 + property int nextMessageIndex: -1 + property bool timeout: false + property bool hasMention: false + property string linkUrls: "" + property bool placeholderMessage: false + property bool activityCenterMessage: false + property bool pinnedMessage: false + property bool read: true + property string pinnedBy + property bool forceHoverHandler: false // Used to force the HoverHandler to be active (useful for messages in popups) + property string communityId: "" + property int stickerPackId: -1 + property int gapFrom: 0 + property int gapTo: 0 + property bool isEdit: false + property string replaces: "" + property bool isEdited: false + property bool showEdit: true + property var messageContextMenu + property bool isMessageActive: typeof root.activeMessage !== "undefined" && root.activeMessage === root.messageId + property string displayUserName: { + if (isCurrentUser) { + //% "You" + return qsTrId("You") + } + + if (localName !== "") { + return localName + } + + if (userName !== "") { + return Utils.removeStatusEns(userName) + } + return Utils.removeStatusEns(alias) + } + + property string authorCurrentMsg: "authorCurrentMsg" + property string authorPrevMsg: "authorPrevMsg" + + property string prevMsgTimestamp: chatsModel.messageView.messageList.getMessageData(prevMessageIndex, "timestamp") + property string nextMsgTimestamp: chatsModel.messageView.messageList.getMessageData(nextMessageIndex, "timestamp") + + property bool shouldRepeatHeader: ((parseInt(timestamp, 10) - parseInt(prevMsgTimestamp, 10)) / 60 / 1000) > Constants.repeatHeaderInterval + + property bool isEmoji: contentType === Constants.emojiType + property bool isImage: contentType === Constants.imageType + property bool isAudio: contentType === Constants.audioType + property bool isStatusMessage: contentType === Constants.systemMessagePrivateGroupType + property bool isSticker: contentType === Constants.stickerType + property bool isText: contentType === Constants.messageType || contentType === Constants.editType + property bool isMessage: isEmoji || isImage || isSticker || isText || isAudio + || contentType === Constants.communityInviteType || contentType === Constants.transactionType + + property bool isExpired: (outgoingStatus === "sending" && (Math.floor(timestamp) + 180000) < Date.now()) + property bool isStatusUpdate: false + property int statusAgeEpoch: 0 + + property int replyMessageIndex: chatsModel.messageView.messageList.getMessageIndex(responseTo); + property string repliedMessageAuthor: replyMessageIndex > -1 ? chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "userName") : ""; + property string repliedMessageAuthorPubkey: replyMessageIndex > -1 ? chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "publicKey") : ""; + property bool repliedMessageAuthorIsCurrentUser: replyMessageIndex > -1 ? repliedMessageAuthorPubkey === profileModel.profile.pubKey : ""; + property bool repliedMessageIsEdited: replyMessageIndex > -1 ? chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "isEdited") === "true" : false; + property string repliedMessageContent: replyMessageIndex > -1 ? chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "message") : ""; + property int repliedMessageType: replyMessageIndex > -1 ? parseInt(chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "contentType")) : 0; + property string repliedMessageImage: replyMessageIndex > -1 ? chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "image") : ""; + property string repliedMessageUserIdenticon: replyMessageIndex > -1 ? chatsModel.messageView.messageList.getMessageData(replyMessageIndex, "identicon") : ""; + property string repliedMessageUserImage: replyMessageIndex > -1 ? appMain.getProfileImage(repliedMessageAuthorPubkey, repliedMessageAuthorIsCurrentUser , false) || "" : ""; + + property var imageClick: function () {} + property var scrollToBottom: function () {} + property string userPubKey: { + if (contentType === Constants.chatIdentifier) { + return chatId + } + return fromAuthor + } + property bool useLargeImage: contentType === Constants.chatIdentifier + + property string profileImageSource: !placeholderMessage && appMain.getProfileImage(userPubKey, isCurrentUser, useLargeImage) || "" + + property var emojiReactionsModel: { + if (!emojiReactions) { + return [] + } + + try { + // group by id + var allReactions = Object.values(JSON.parse(emojiReactions)) + var byEmoji = {} + allReactions.forEach(function (reaction) { + if (!byEmoji[reaction.emojiId]) { + byEmoji[reaction.emojiId] = { + emojiId: reaction.emojiId, + fromAccounts: [], + count: 0, + currentUserReacted: false + } + } + byEmoji[reaction.emojiId].count++; + byEmoji[reaction.emojiId].fromAccounts.push(chatsModel.userNameOrAlias(reaction.from)); + if (!byEmoji[reaction.emojiId].currentUserReacted && reaction.from === profileModel.profile.pubKey) { + byEmoji[reaction.emojiId].currentUserReacted = true + } + + }) + return Object.values(byEmoji) + } catch (e) { + console.error('Error parsing emoji reactions', e) + return [] + } + } + property var clickMessage: function(isProfileClick, isSticker = false, isImage = false, image = null, emojiOnly = false, hideEmojiPicker = false, isReply = false, isRightClickOnImage = false, imageSource = "") { + if (placeholderMessage || activityCenterMessage) { + return + } + + if (!isProfileClick) { + SelectedMessage.set(messageId, fromAuthor); + } + + messageContextMenu.messageId = messageId + messageContextMenu.contentType = contentType + messageContextMenu.linkUrls = linkUrls; + messageContextMenu.isProfile = !!isProfileClick; + messageContextMenu.isCurrentUser = isCurrentUser + messageContextMenu.isText = isText + messageContextMenu.isSticker = isSticker; + messageContextMenu.emojiOnly = emojiOnly; + messageContextMenu.hideEmojiPicker = hideEmojiPicker; + messageContextMenu.pinnedMessage = pinnedMessage; + messageContextMenu.isCurrentUser = isCurrentUser; + messageContextMenu.isRightClickOnImage = isRightClickOnImage + messageContextMenu.imageSource = imageSource + messageContextMenu.onClickEdit = function() {isEdit = true} + + //TODO remove dynamic scoping + if (isReply) { + let nickname = appMain.getUserNickname(repliedMessageAuthor) + messageContextMenu.show(repliedMessageAuthor, repliedMessageAuthorPubkey, repliedMessageUserImage || repliedMessageUserIdenticon, plainText, nickname, emojiReactionsModel); + } else { + let nickname = appMain.getUserNickname(fromAuthor) + messageContextMenu.show(userName, fromAuthor, profileImageSource || identicon, plainText, nickname, emojiReactionsModel); + } + + messageContextMenu.x = messageContextMenu.setXPosition() + messageContextMenu.y = messageContextMenu.setYPosition() + } + + function setHovered(messageId, hovered) { + if (hovered) { + hoveredMessage = messageId; + } else if (hoveredMessage === messageId) { + hoveredMessage = ""; + } + } + + function setMessageActive(messageId, active) { + if (active) { + activeMessage = messageId; + } else if (activeMessage === messageId) { + activeMessage = ""; + } + } +} diff --git a/ui/app/AppLayouts/stores/RootStore.qml b/ui/app/AppLayouts/stores/RootStore.qml new file mode 100644 index 0000000000..3150290bc0 --- /dev/null +++ b/ui/app/AppLayouts/stores/RootStore.qml @@ -0,0 +1,9 @@ +import QtQuick 2.13 + +QtObject { + id: root + property var chatsModelInst: chatsModel + property var walletModelInst: walletModel + property var profileModelInst: profileModel + property MessageStore messageStore: MessageStore { } +} diff --git a/ui/app/AppMain.qml b/ui/app/AppMain.qml index 822c7e0453..54139aae24 100644 --- a/ui/app/AppMain.qml +++ b/ui/app/AppMain.qml @@ -12,8 +12,10 @@ import "./AppLayouts" import "./AppLayouts/Timeline" import "./AppLayouts/Wallet" import "./AppLayouts/WalletV2" -import "./AppLayouts/Chat/components" -import "./AppLayouts/Chat/CommunityComponents" +import "./AppLayouts/Chat/popups" +import "./AppLayouts/Chat/popups/community" +import "./AppLayouts/Profile/Sections" +import "./AppLayouts/stores" import Qt.labs.platform 1.1 import Qt.labs.settings 1.0 @@ -32,7 +34,7 @@ Item { property var newVersionJSON: JSON.parse(utilsModel.newVersion) property bool profilePopupOpened: false property bool networkGuarded: profileModel.network.current === Constants.networkMainnet || (profileModel.network.current === Constants.networkRopsten && appSettings.stickersEnsRopsten) - + property RootStore rootStore: RootStore { } signal settingsLoaded() signal openContactsPopup() @@ -417,6 +419,7 @@ Item { Layout.fillWidth: true Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillHeight: true + messageStore: appMain.rootStore.messageStore onProfileButtonClicked: { appMain.changeAppSection(Constants.profile); } @@ -452,7 +455,10 @@ Item { Loader { id: timelineLayoutContainer sourceComponent: Component { - TimelineLayout {} + TimelineLayout { + messageStore: appMain.rootStore.messageStore + rootStore: appMain.rootStore + } } onLoaded: timelineLayoutContainer.item.onActivated() active: false @@ -466,6 +472,7 @@ Item { Layout.fillWidth: true Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillHeight: true + globalStore: appMain.rootStore } NodeLayout { diff --git a/ui/imports/utils/Utils.qml b/ui/imports/utils/Utils.qml index 3f691048be..c9805d8fa3 100644 --- a/ui/imports/utils/Utils.qml +++ b/ui/imports/utils/Utils.qml @@ -115,6 +115,17 @@ QtObject { `` } + function getLinkStyle(link, hoveredLink) { + return `` + + `${link}` + } + function getAppSectionIndex(section) { let sectionId = -1 switch (section) { diff --git a/ui/app/AppLayouts/Chat/components/LoadingAnimation.qml b/ui/shared/LoadingAnimation.qml similarity index 84% rename from ui/app/AppLayouts/Chat/components/LoadingAnimation.qml rename to ui/shared/LoadingAnimation.qml index 913b494652..20ddf20d19 100644 --- a/ui/app/AppLayouts/Chat/components/LoadingAnimation.qml +++ b/ui/shared/LoadingAnimation.qml @@ -1,8 +1,7 @@ import QtQuick 2.13 import utils 1.0 -import "../../../../shared" -import "../../../../shared/panels" +import "../shared/panels" SVGImage { id: loadingImg diff --git a/ui/shared/panels/NotificationWindow.qml b/ui/shared/panels/NotificationWindow.qml index 263ae0ebf4..764e22c969 100644 --- a/ui/shared/panels/NotificationWindow.qml +++ b/ui/shared/panels/NotificationWindow.qml @@ -8,8 +8,6 @@ import QtGraphicalEffects 1.13 import utils 1.0 import "../status" import "../controls" -import "../" -import "../../app/AppLayouts/Chat/ContactsColumn" Item { id: root diff --git a/ui/shared/status/StatusChatInput.qml b/ui/shared/status/StatusChatInput.qml index c658f198c0..f169eadf92 100644 --- a/ui/shared/status/StatusChatInput.qml +++ b/ui/shared/status/StatusChatInput.qml @@ -9,8 +9,7 @@ import DotherSide 0.1 import utils 1.0 import "../../shared" import "../../shared/panels" -import "../../app/AppLayouts/Chat/ChatColumn/samples" -import "../../app/AppLayouts/Chat/ChatColumn" +import "../../app/AppLayouts/Chat/panels" import "./emojiList.js" as EmojiJSON @@ -604,7 +603,7 @@ Rectangle { id: emojiSuggestions } - SuggestionBox { + SuggestionBoxPanel { id: suggestionsBox model: { if (chatsModel.communities.activeCommunity.active) { diff --git a/ui/shared/status/StatusSticker.qml b/ui/shared/status/StatusSticker.qml index f811d2ef13..9df99a65b5 100644 --- a/ui/shared/status/StatusSticker.qml +++ b/ui/shared/status/StatusSticker.qml @@ -6,7 +6,7 @@ import utils 1.0 Loader { property color color property int contentType: -1 - property string stickerData: sticker + property string stickerData: "" property int imageHeight: 140 property int imageWidth: 140 signal loaded() diff --git a/ui/shared/status/StatusStickerMarket.qml b/ui/shared/status/StatusStickerMarket.qml index e26c4efd9c..fa7d3df7fc 100644 --- a/ui/shared/status/StatusStickerMarket.qml +++ b/ui/shared/status/StatusStickerMarket.qml @@ -8,7 +8,8 @@ import "../../shared" import "../../shared/popups" import "../../shared/panels" import "../../shared/status" -import "../../app/AppLayouts/Chat/ChatColumn/samples" +//TODO improve this! +import "../../app/AppLayouts/Chat/stores" Item { id: root diff --git a/ui/shared/status/StatusStickerPackClickPopup.qml b/ui/shared/status/StatusStickerPackClickPopup.qml index 476527bc45..dd1fb3b96d 100644 --- a/ui/shared/status/StatusStickerPackClickPopup.qml +++ b/ui/shared/status/StatusStickerPackClickPopup.qml @@ -7,7 +7,8 @@ import utils 1.0 import "../../shared" import "../../shared/status" import "../../shared/popups" -import "../../app/AppLayouts/Chat/ChatColumn/samples" +//TODO remove this! +import "../../app/AppLayouts/Chat/stores" // TODO: replace with StatusModal ModalPopup { diff --git a/ui/shared/status/StatusStickersPopup.qml b/ui/shared/status/StatusStickersPopup.qml index 63f3bb3663..7851b421ed 100644 --- a/ui/shared/status/StatusStickersPopup.qml +++ b/ui/shared/status/StatusStickersPopup.qml @@ -8,7 +8,8 @@ import "../../shared" import "../../shared/panels" import "../../shared/status/core" import "../../shared/status" -import "../../app/AppLayouts/Chat/ChatColumn/samples" +//TODO improve this! +import "../../app/AppLayouts/Chat/stores" Popup { id: root diff --git a/ui/shared/views/ExistingContacts.qml b/ui/shared/views/ExistingContacts.qml index 0318a5c7c0..871ada90f0 100644 --- a/ui/shared/views/ExistingContacts.qml +++ b/ui/shared/views/ExistingContacts.qml @@ -5,8 +5,7 @@ import QtQuick.Layouts 1.13 import utils 1.0 import "../status" // TODO move Contact into shared to get rid of that import -import "../../app/AppLayouts/Chat/components" -import "." +import "../../app/AppLayouts/Chat/controls" Item { id: root diff --git a/ui/shared/views/SearchResults.qml b/ui/shared/views/SearchResults.qml index ef4cffd8c9..9c88e72329 100644 --- a/ui/shared/views/SearchResults.qml +++ b/ui/shared/views/SearchResults.qml @@ -7,9 +7,8 @@ import "../" import "../status" import "../panels" // TODO move Contact into shared to get rid of that import -import "../../app/AppLayouts/Chat/components" -import "." - +import "../../app/AppLayouts/Chat/controls" +import "./" Item { id: root