refactor(desktop/chat) Cleaning up panels

This commit is contained in:
Alexandra Betouni 2021-10-21 03:41:54 +03:00 committed by Iuri Matias
parent be7a56cc27
commit 22429689e3
31 changed files with 188 additions and 344 deletions

View File

@ -181,6 +181,7 @@ StatusAppThreePanelLayout {
messageContextMenu: quickActionMessageOptionsMenu messageContextMenu: quickActionMessageOptionsMenu
profilePubKey: profileModel.profile.pubKey profilePubKey: profileModel.profile.pubKey
contactsList: profileModel.contacts.list contactsList: profileModel.contacts.list
community: chatsModel.communities.activeCommunity
} }
} }
@ -208,6 +209,7 @@ StatusAppThreePanelLayout {
Component { Component {
id: communtiyColumnComponent id: communtiyColumnComponent
CommunityColumnView { CommunityColumnView {
rootStore: chatColumn.rootStore
pinnedMessagesPopupComponent: chatColumn.pinnedMessagesPopupComponent pinnedMessagesPopupComponent: chatColumn.pinnedMessagesPopupComponent
} }
} }
@ -243,8 +245,9 @@ StatusAppThreePanelLayout {
} }
} }
MessageContextMenuPanel { MessageContextMenuView {
id: quickActionMessageOptionsMenu id: quickActionMessageOptionsMenu
store: chatColumn.rootStore
reactionModel: chatColumn.rootStore.emojiReactionsModel reactionModel: chatColumn.rootStore.emojiReactionsModel
} }
} }

View File

@ -2,7 +2,7 @@ import QtQuick 2.13
import StatusQ.Components 0.1 import StatusQ.Components 0.1
import "../../../../../shared/panels" import "../../../../shared/panels"
import utils 1.0 import utils 1.0
@ -11,8 +11,8 @@ Item {
height: childrenRect.height + Style.current.smallPadding * 2 height: childrenRect.height + Style.current.smallPadding * 2
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
property int nextMessageIndex // property int nextMessageIndex
property string nextMsgTimestamp // property string nextMsgTimestamp
signal clicked() signal clicked()
signal timerTriggered() signal timerTriggered()
Timer { Timer {

View File

@ -1,7 +1,6 @@
import QtQuick 2.13 import QtQuick 2.13
import "../../../../../shared" import "../../../../shared"
import "../../../../../shared/panels" import "../../../../shared/panels"
import "../../../../../shared/status/core"
import utils 1.0 import utils 1.0

View File

@ -48,7 +48,8 @@ Item {
target: wrapper.contactsList target: wrapper.contactsList
onContactChanged: { onContactChanged: {
if (pubkey === wrapper.publicKey) { if (pubkey === wrapper.publicKey) {
wrapper.profileImage = appMain.getProfileImage(wrapper.publicKey) wrapper.profileImage = !!appMain.getProfileImage(wrapper.publicKey) ?
appMain.getProfileImage(wrapper.publicKey) : ""
} }
} }
} }

View File

@ -1,55 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtGraphicalEffects 1.13
import "../../../../shared"
import "../../../../shared/panels"
import "../../../../shared/status"
import utils 1.0
import "."
Item {
property string text
property string description
property var buttonGroup
property bool checked: false
property bool hideSeparator: false
signal radioCheckedChanged(bool checked)
id: root
width: parent.width
height: childrenRect.height
StatusRadioButtonRow {
id: radioBtn
text: root.text
buttonGroup: root.buttonGroup
checked: root.checked
onRadioCheckedChanged: {
root.radioCheckedChanged(checked)
}
}
StyledText {
id: radioDesc
text: root.description
anchors.top: radioBtn.bottom
anchors.topMargin: Style.current.halfPadding
anchors.left: parent.left
anchors.right: parent.right
anchors.rightMargin: 100
font.pixelSize: 13
color: Style.current.secondaryText
wrapMode: Text.WordWrap
}
Separator {
visible: !root.hideSeparator
anchors.top: radioDesc.bottom
anchors.topMargin: visible ? Style.current.halfPadding : 0
anchors.left: parent.left
anchors.leftMargin: -Style.current.halfPadding
anchors.right: parent.right
anchors.rightMargin: -Style.current.halfPadding
}
}

View File

@ -14,10 +14,18 @@ Loader {
id: root id: root
property int nameMargin: 6 property int nameMargin: 6
// property bool isCurrentUser: false
property int textFieldWidth: item ? item.textField.width : 0 property int textFieldWidth: item ? item.textField.width : 0
property int textFieldImplicitWidth: 0 property int textFieldImplicitWidth: 0
property int authorWidth: item ? item.authorMetrics.width : 0 property int authorWidth: item ? item.authorMetrics.width : 0
property bool longReply: false
property color elementsColor: isCurrentUser ? Style.current.chatReplyCurrentUser : Style.current.secondaryText
property var container
property int chatHorizontalPadding
property var stickerData
signal clickMessage(bool isProfileClick, bool isSticker, bool isImage, var image, bool emojiOnly, bool hideEmojiPicker, bool isReply)
// TODO bring those back and remove dynamic scoping
// property bool isCurrentUser: false
// property int repliedMessageType // property int repliedMessageType
// property string repliedMessageImage // property string repliedMessageImage
// property string repliedMessageUserIdenticon // property string repliedMessageUserIdenticon
@ -25,15 +33,8 @@ Loader {
// property string repliedMessageUserImage // property string repliedMessageUserImage
// property string repliedMessageAuthor // property string repliedMessageAuthor
// property string repliedMessageContent // 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 string responseTo: ""
property var stickerData
// signal scrollToBottom(bool isit, var container) // signal scrollToBottom(bool isit, var container)
signal clickMessage(bool isProfileClick, bool isSticker, bool isImage, var image, bool emojiOnly, bool hideEmojiPicker, bool isReply)
sourceComponent: Component { sourceComponent: Component {
Item { Item {

View File

@ -14,14 +14,16 @@ Item {
width: childrenRect.width width: childrenRect.width
property int imageMargin: 4 property int imageMargin: 4
// property bool isCurrentUser
// property var emojiReactionsModel
// property bool isMessageActive
signal addEmojiClicked() signal addEmojiClicked()
signal hoverChanged(bool hovered) signal hoverChanged(bool hovered)
signal toggleReaction(int emojiID) signal toggleReaction(int emojiID)
signal setMessageActive(string messageId, bool active) signal setMessageActive(string messageId, bool active)
// TODO bring those back and remove dynamic scoping
// property bool isCurrentUser
// property var emojiReactionsModel
// property bool isMessageActive
Row { Row {
spacing: root.imageMargin spacing: root.imageMargin

View File

@ -1,63 +0,0 @@
import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import "../../../../shared"
import "../../../../shared/popups"
import "../../../../shared/status"
import utils 1.0
// TODO: replace with StatusPopupmenu
//Todo Unsed?
PopupMenu {
//% "Fetch Messages"
title: qsTrId("fetch-messages")
// TODO call fetch for the wanted duration
//% "Last 24 hours"
Action {
text: qsTrId("last-24-hours");
icon.width: 0;
onTriggered: {
chatsModel.requestMoreMessages(Constants.fetchRangeLast24Hours)
timer.setTimeout(function(){
chatsModel.messageView.hideLoadingIndicator()
}, 3000);
}
}
//% "Last 2 days"
Action {
text: qsTrId("last-2-days");
icon.width: 0;
onTriggered: {
chatsModel.requestMoreMessages(Constants.fetchRangeLast2Days)
timer.setTimeout(function(){
chatsModel.messageView.hideLoadingIndicator()
}, 4000);
}
}
//% "Last 3 days"
Action {
text: qsTrId("last-3-days");
icon.width: 0;
onTriggered: {
chatsModel.requestMoreMessages(Constants.fetchRangeLast3Days)
timer.setTimeout(function(){
chatsModel.messageView.hideLoadingIndicator()
}, 5000);
}
}
//% "Last 7 days"
Action {
text: qsTrId("last-7-days");
icon.width: 0;
onTriggered: {
chatsModel.requestMoreMessages(Constants.fetchRangeLast7Days)
timer.setTimeout(function(){
chatsModel.messageView.hideLoadingIndicator()
}, 7000);
}
}
}

View File

@ -20,6 +20,12 @@ MouseArea {
property int statusAgeEpoch: 0 property int statusAgeEpoch: 0
property var messageContextMenu property var messageContextMenu
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)
// TODO bring those back and remove dynamic scoping
// property var emojiReactionsModel // property var emojiReactionsModel
// property string timestamp: "" // property string timestamp: ""
// property bool isCurrentUser: false // property bool isCurrentUser: false
@ -31,10 +37,6 @@ MouseArea {
// property bool isMessage: false // property bool isMessage: false
// property string profileImageSource: "" // property string profileImageSource: ""
// property string userIdenticon: "" // 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.top: parent.top
anchors.topMargin: 0 anchors.topMargin: 0
@ -100,7 +102,7 @@ MouseArea {
anchors.verticalCenter: chatName.verticalCenter anchors.verticalCenter: chatName.verticalCenter
anchors.left: chatName.right anchors.left: chatName.right
anchors.leftMargin: Style.current.halfPadding anchors.leftMargin: Style.current.halfPadding
timestamp: root.timestamp //timestamp: timestamp
} }
ChatTextView { ChatTextView {

View File

@ -8,6 +8,10 @@ import "../controls"
import "../views" import "../views"
Item { Item {
id: root
width: rectangleBubble.width
height: rectangleBubble.height
property var commandParametersObject: { property var commandParametersObject: {
try { try {
return JSON.parse(commandParameters) return JSON.parse(commandParameters)
@ -30,6 +34,7 @@ Item {
property var focusedAccount property var focusedAccount
property string activeChannelName property string activeChannelName
property string activeChannelIdenticon property string activeChannelIdenticon
property var balanceView
signal getGasPrice() signal getGasPrice()
signal sendTransactionClicked(string fromAddress) signal sendTransactionClicked(string fromAddress)
property var token: JSON.parse(commandParametersObject.contract) // TODO: handle {} property var token: JSON.parse(commandParametersObject.contract) // TODO: handle {}
@ -39,8 +44,8 @@ Item {
if (!tokenAmount || !token.symbol) { if (!tokenAmount || !token.symbol) {
return "0" return "0"
} }
var defaultFiatSymbol = walletModel.balanceView.defaultCurrency var defaultFiatSymbol = root.balanceView.defaultCurrency
return walletModel.balanceView.getFiatValue(tokenAmount, token.symbol, defaultFiatSymbol) + " " + defaultFiatSymbol.toUpperCase() return root.balanceView.getFiatValue(tokenAmount, token.symbol, defaultFiatSymbol) + " " + defaultFiatSymbol.toUpperCase()
} }
property int state: commandParametersObject.commandState property int state: commandParametersObject.commandState
@ -55,10 +60,6 @@ Item {
} }
} }
id: root
width: rectangleBubble.width
height: rectangleBubble.height
Rectangle { Rectangle {
id: rectangleBubble id: rectangleBubble
width: (bubbleLoader.active ? bubbleLoader.width : valueContainer.width) width: (bubbleLoader.active ? bubbleLoader.width : valueContainer.width)

View File

@ -23,6 +23,7 @@ Column {
signal editButtonClicked() signal editButtonClicked()
signal transferOwnershipButtonClicked() signal transferOwnershipButtonClicked()
signal leaveButtonClicked() signal leaveButtonClicked()
signal copyToClipboard(string link)
Item { Item {
height: Math.max(46, communityDescription.height + 16) height: Math.max(46, communityDescription.height + 16)
@ -54,7 +55,8 @@ Column {
icon.name: "copy" icon.name: "copy"
iconButton.onClicked: { iconButton.onClicked: {
let link = `${Constants.communityLinkPrefix}${root.community.id}` let link = `${Constants.communityLinkPrefix}${root.community.id}`
chatsModel.copyToClipboard(link) //chatsModel.copyToClipboard(link)
root.copyToClipboard(link);
tooltip.visible = !tooltip.visible tooltip.visible = !tooltip.visible
} }
width: parent.width width: parent.width

View File

@ -24,7 +24,7 @@ Item {
property var contactsList property var contactsList
property string profilePubKey property string profilePubKey
property var messageContextMenu property var messageContextMenu
property QtObject community: chatsModel.communities.activeCommunity property var community
StyledText { StyledText {
id: titleText id: titleText

View File

@ -21,6 +21,7 @@ Rectangle {
border.color: Style.current.border border.color: Style.current.border
radius: 16 radius: 16
color: Style.current.transparent color: Style.current.transparent
property var activeCommunity
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
@ -55,7 +56,7 @@ Rectangle {
type: StatusQControls.StatusFlatRoundButton.Type.Tertiary type: StatusQControls.StatusFlatRoundButton.Type.Tertiary
onClicked: { onClicked: {
let hiddenBannerIds = appSettings.hiddenCommunityWelcomeBanners let hiddenBannerIds = appSettings.hiddenCommunityWelcomeBanners
hiddenBannerIds.push(chatsModel.communities.activeCommunity.id) hiddenBannerIds.push(root.activeCommunity.id)
appSettings.hiddenCommunityWelcomeBanners = hiddenBannerIds appSettings.hiddenCommunityWelcomeBanners = hiddenBannerIds
root.visible = false root.visible = false
} }
@ -85,7 +86,7 @@ Rectangle {
anchors.bottom: manageBtn.top anchors.bottom: manageBtn.top
anchors.bottomMargin: Style.current.halfPadding anchors.bottomMargin: Style.current.halfPadding
onClicked: openPopup(inviteFriendsToCommunityPopup, { onClicked: openPopup(inviteFriendsToCommunityPopup, {
community: chatsModel.communities.activeCommunity community: root.activeCommunity
}) })
} }
@ -97,7 +98,7 @@ Rectangle {
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.bottomMargin: Style.current.padding anchors.bottomMargin: Style.current.padding
onClicked: openPopup(communityProfilePopup, { onClicked: openPopup(communityProfilePopup, {
community: chatsModel.communities.activeCommunity community: root.activeCommunity
}) })
} }
} }

View File

@ -183,10 +183,11 @@ ModalPopup {
messageStore.showEdit = false; messageStore.showEdit = false;
messageStore.messageContextMenu = msgContextMenu; messageStore.messageContextMenu = msgContextMenu;
} }
MessageContextMenuPanel { MessageContextMenuView {
id: msgContextMenu id: msgContextMenu
pinnedPopup: true pinnedPopup: true
pinnedMessage: true pinnedMessage: true
store: popup.rootStore
reactionModel: popup.rootStore.emojiReactionsModel reactionModel: popup.rootStore.emojiReactionsModel
onShouldCloseParentPopup: { onShouldCloseParentPopup: {
messageDelegate.listView.closePopup(); messageDelegate.listView.closePopup();

View File

@ -71,6 +71,11 @@ StatusModal {
chatsModel.communities.leaveCommunity(popup.community.id) chatsModel.communities.leaveCommunity(popup.community.id)
popup.close() popup.close()
} }
onCopyToClipboard: {
//TODO
//root.store.copyToClipboard(link);
chatsModel.copyToClipboard(link);
}
} }
} }

View File

@ -11,6 +11,16 @@ QtObject {
property var walletModelInst: walletModel property var walletModelInst: walletModel
property var profileModelInst: profileModel property var profileModelInst: profileModel
property var activeCommunity: chatsModelInst.communities.activeCommunity
function copyToClipboard(text) {
chatsModelInst.copyToClipboard(text);
}
function deleteMessage(messageId) {
chatsModelInst.messageView.deleteMessage(messageId);
}
function lastTwoItems(nodes) { function lastTwoItems(nodes) {
//% " and " //% " and "
return nodes.join(qsTrId("-and-")); return nodes.join(qsTrId("-and-"));
@ -50,4 +60,23 @@ QtObject {
} }
return tooltip return tooltip
} }
function getCommunity(communityId) {
try {
const communityJson = chatsModelInst.communities.list.getCommunityByIdJson(communityId);
if (!communityJson) {
return null;
}
let community = JSON.parse(communityJson);
if (community) {
community.nbMembers = community.members.length;
}
return community
} catch (e) {
console.error("Error parsing community", e);
}
return null;
}
} }

View File

@ -97,7 +97,7 @@ Item {
font.pixelSize: 10 font.pixelSize: 10
visible: true visible: true
color: Style.current.secondaryText color: Style.current.secondaryText
timestamp: root.timestamp //timestamp: root.timestamp
} }
} }

View File

@ -110,8 +110,9 @@ Item {
} }
} }
MessageContextMenuPanel { MessageContextMenuView {
id: contextmenu id: contextmenu
store: chatColumnLayout.rootStore
reactionModel: chatColumnLayout.rootStore.emojiReactionsModel reactionModel: chatColumnLayout.rootStore.emojiReactionsModel
} }

View File

@ -158,7 +158,7 @@ StatusPopupMenu {
Component { Component {
id: deleteChatConfirmationDialogComponent id: deleteChatConfirmationDialogComponent
ConfirmationDialog { ConfirmationDialog {
property string chatId: chatItem.id property string chatId: !!chatItem ? chatItem.id : ""
btnType: "warn" btnType: "warn"
header.title: communityActive ? qsTr("Delete #%1").arg(chatItem.name) : header.title: communityActive ? qsTr("Delete #%1").arg(chatItem.name) :
chatItem && chatItem.chatType === Constants.chatTypeOneToOne ? chatItem && chatItem.chatType === Constants.chatTypeOneToOne ?

View File

@ -7,7 +7,7 @@ import utils 1.0
StyledText { StyledText {
id: chatTime id: chatTime
property string timestamp //property string timestamp
visible: chatTime.messageStore.isMessage visible: chatTime.messageStore.isMessage
color: Style.current.secondaryText color: Style.current.secondaryText
text: Utils.formatTime(timestamp) text: Utils.formatTime(timestamp)

View File

@ -23,6 +23,7 @@ Item {
// TODO unhardcode // TODO unhardcode
property int chatGroupsListViewCount: communityChatListAndCategories.chatList.count property int chatGroupsListViewCount: communityChatListAndCategories.chatList.count
property Component pinnedMessagesPopupComponent property Component pinnedMessagesPopupComponent
property var rootStore
StatusChatInfoToolBar { StatusChatInfoToolBar {
id: communityHeader id: communityHeader
@ -240,7 +241,9 @@ Item {
anchors.top: communityChatListAndCategories.bottom anchors.top: communityChatListAndCategories.bottom
anchors.topMargin: active ? Style.current.padding : 0 anchors.topMargin: active ? Style.current.padding : 0
sourceComponent: Component { sourceComponent: Component {
CommunityWelcomeBannerPanel {} CommunityWelcomeBannerPanel {
activeCommunity: rootStore.activeCommunity
}
} }
} }

View File

@ -297,7 +297,7 @@ Item {
anchors.left: chatName.right anchors.left: chatName.right
anchors.leftMargin: 4 anchors.leftMargin: 4
color: Style.current.secondaryText color: Style.current.secondaryText
timestamp: timestamp //timestamp: timestamp
} }
Loader { Loader {
@ -565,6 +565,7 @@ Item {
anchors.topMargin: active ? (chatName.visible ? 4 : 6) : 0 anchors.topMargin: active ? (chatName.visible ? 4 : 6) : 0
sourceComponent: Component { sourceComponent: Component {
TransactionBubblePanel { TransactionBubblePanel {
balanceView: root.store.walletModelInst.balanceView
focusedAccount: root.store.walletModelInst.accountsView.focusedAccount focusedAccount: root.store.walletModelInst.accountsView.focusedAccount
activeChannelName: root.store.chatsModelInst.channelView.activeChannel.name activeChannelName: root.store.chatsModelInst.channelView.activeChannel.name
activeChannelIdenticon: root.store.chatsModelInst.channelView.activeChannel.identicon activeChannelIdenticon: root.store.chatsModelInst.channelView.activeChannel.identicon
@ -585,7 +586,8 @@ Item {
anchors.topMargin: active ? 8 : 0 anchors.topMargin: active ? 8 : 0
sourceComponent: Component { sourceComponent: Component {
id: invitationBubble id: invitationBubble
InvitationBubblePanel { InvitationBubbleView {
store: root.store
communityId: container.communityId communityId: container.communityId
} }
} }

View File

@ -235,14 +235,17 @@ Item {
target: profileModel.contacts.list target: profileModel.contacts.list
onContactChanged: { onContactChanged: {
for (var i = 0; i < channelList.chatListItems.count; i++) { for (var i = 0; i < channelList.chatListItems.count; i++) {
let chatItem = channelList.statusChatListItems.model.itemAt(i); let chatItem = !!channelList.statusChatListItems.model.itemAt(i) ?
if (chatItem.chatId === pubkey) { channelList.statusChatListItems.model.itemAt(i) : null
let profileImage = appMain.getProfileImage(pubkey) if (!!chatItem) {
if (!!profileImage) { if (chatItem.chatId === pubkey) {
chatItem.image.isIdenticon = false let profileImage = appMain.getProfileImage(pubkey)
chatItem.image.source = profileImage if (!!profileImage) {
chatItem.image.isIdenticon = false
chatItem.image.source = profileImage
}
break;
} }
break;
} }
} }
} }

View File

@ -11,19 +11,20 @@ import "../../../../shared/panels"
import "../../../../shared/popups" import "../../../../shared/popups"
Item { Item {
property string communityId
property var invitedCommunity
property int innerMargin: 12
property bool isLink: false
id: root id: root
anchors.left: parent.left anchors.left: parent.left
height: rectangleBubbleLoader.height height: rectangleBubbleLoader.height
width: rectangleBubbleLoader.width width: rectangleBubbleLoader.width
property string communityId
property var invitedCommunity
property int innerMargin: 12
property bool isLink: false
property var store
function getCommunity() { function getCommunity() {
try { try {
const communityJson = chatsModel.communities.list.getCommunityByIdJson(communityId) const communityJson = root.store.chatsModelInst.communities.list.getCommunityByIdJson(communityId)
if (!communityJson) { if (!communityJson) {
return null return null
} }
@ -45,7 +46,7 @@ Item {
} }
Connections { Connections {
target: chatsModel.communities target: root.store.chatsModelInst.communities
onCommunityChanged: function (communityId) { onCommunityChanged: function (communityId) {
if (communityId === root.communityId) { if (communityId === root.communityId) {
root.invitedCommunity = getCommunity() root.invitedCommunity = getCommunity()
@ -87,7 +88,7 @@ Item {
Rectangle { Rectangle {
id: rectangleBubble id: rectangleBubble
property alias button: joinBtn property alias button: joinBtn
property bool isPendingRequest: chatsModel.communities.isCommunityRequestPending(communityId) property bool isPendingRequest: root.store.chatsModelInst.communities.isCommunityRequestPending(communityId)
width: 270 width: 270
height: title.height + title.anchors.topMargin + height: title.height + title.anchors.topMargin +
invitedYou.height + invitedYou.anchors.topMargin + invitedYou.height + invitedYou.anchors.topMargin +
@ -105,7 +106,7 @@ Item {
states: [ states: [
State { State {
name: "requiresEns" name: "requiresEns"
when: invitedCommunity.ensOnly && !profileModel.profile.ensVerified when: invitedCommunity.ensOnly && !root.store.profileModelInst.profile.ensVerified
PropertyChanges { PropertyChanges {
target: joinBtn target: joinBtn
//% "Membership requires an ENS username" //% "Membership requires an ENS username"
@ -172,7 +173,7 @@ Item {
] ]
Connections { Connections {
target: chatsModel.communities target: root.store.chatsModelInst.communities
onMembershipRequestChanged: function(communityId, communityName, requestAccepted) { onMembershipRequestChanged: function(communityId, communityName, requestAccepted) {
if (communityId === root.communityId) { if (communityId === root.communityId) {
rectangleBubble.isPendingRequest = false rectangleBubble.isPendingRequest = false
@ -200,10 +201,10 @@ Item {
StatusBaseText { StatusBaseText {
id: invitedYou id: invitedYou
text: { text: {
if (chatsModel.channelView.activeChannel.chatType === Constants.chatTypeOneToOne) { if (root.store.chatsModelInst.channelView.activeChannel.chatType === Constants.chatTypeOneToOne) {
return isCurrentUser ? return isCurrentUser ?
//% "You invited %1 to join a community" //% "You invited %1 to join a community"
qsTrId("you-invited--1-to-join-a-community").arg(chatsModel.userNameOrAlias(chatsModel.channelView.activeChannel.id)) qsTrId("you-invited--1-to-join-a-community").arg(root.store.chatsModelInst.userNameOrAlias(root.store.chatsModelInst.channelView.activeChannel.id))
//% "%1 invited you to join a community" //% "%1 invited you to join a community"
: qsTrId("-1-invited-you-to-join-a-community").arg(displayUserName) : qsTrId("-1-invited-you-to-join-a-community").arg(displayUserName)
} else { } else {
@ -301,16 +302,16 @@ Item {
let error let error
if (rectangleBubble.state === "joined") { if (rectangleBubble.state === "joined") {
chatsModel.communities.setActiveCommunity(communityId); root.store.chatsModelInst.communities.setActiveCommunity(communityId);
return return
} else if (rectangleBubble.state === "unjoined") { } else if (rectangleBubble.state === "unjoined") {
error = chatsModel.communities.joinCommunity(communityId, true) error = root.store.chatsModelInst.communities.joinCommunity(communityId, true)
} }
else if (rectangleBubble.state === "requestToJoin") { else if (rectangleBubble.state === "requestToJoin") {
error = chatsModel.communities.requestToJoinCommunity(communityId, error = root.store.chatsModelInst.communities.requestToJoinCommunity(communityId,
profileModel.profile.ensVerified ? profileModel.profile.username : "") root.store.profileModelInst.profile.ensVerified ? root.store.profileModelInst.profile.username : "")
if (!error) { if (!error) {
rectangleBubble.isPendingRequest = chatsModel.communities.isCommunityRequestPending(communityId) rectangleBubble.isPendingRequest = root.store.chatsModelInst.communities.isCommunityRequestPending(communityId)
} }
} }

View File

@ -19,6 +19,7 @@ Column {
property var container property var container
property bool isCurrentUser: false property bool isCurrentUser: false
property bool isImageLink: false property bool isImageLink: false
property var rootStore
readonly property string uuid: Utils.uuid() readonly property string uuid: Utils.uuid()
spacing: Style.current.halfPadding spacing: Style.current.halfPadding
@ -210,7 +211,8 @@ Column {
Component { Component {
id: invitationBubble id: invitationBubble
InvitationBubblePanel { InvitationBubbleView {
store: root.rootStore
communityId: linkData.communityId communityId: linkData.communityId
isLink: true isLink: true
anchors.left: parent.left anchors.left: parent.left

View File

@ -15,9 +15,10 @@ import "../../../../shared/status"
import "../controls" import "../controls"
StatusPopupMenu { StatusPopupMenu {
id: messageContextMenu id: root
width: emojiContainer.visible ? emojiContainer.width : 176 width: emojiContainer.visible ? emojiContainer.width : 176
property var store
property string messageId property string messageId
property int contentType property int contentType
property bool isProfile: false property bool isProfile: false
@ -43,16 +44,16 @@ StatusPopupMenu {
property var setXPosition: function() {return 0} property var setXPosition: function() {return 0}
property var setYPosition: function() {return 0} property var setYPosition: function() {return 0}
property bool canPin: { property bool canPin: {
const nbPinnedMessages = chatsModel.messageView.pinnedMessagesList.count const nbPinnedMessages = root.store.chatsModelInst.messageView.pinnedMessagesList.count
return nbPinnedMessages < Constants.maxNumberOfPins return nbPinnedMessages < Constants.maxNumberOfPins
} }
onHeightChanged: { onHeightChanged: {
messageContextMenu.y = setYPosition() root.y = setYPosition()
} }
onWidthChanged: { onWidthChanged: {
messageContextMenu.x = setXPosition() root.x = setXPosition()
} }
signal shouldCloseParentPopup signal shouldCloseParentPopup
@ -72,9 +73,9 @@ StatusPopupMenu {
emojiReactionsReactedByUser = newEmojiReactions; emojiReactionsReactedByUser = newEmojiReactions;
/* // copy link feature not ready yet /* // copy link feature not ready yet
const numLinkUrls = messageContextMenu.linkUrls.split(" ").length const numLinkUrls = root.linkUrls.split(" ").length
copyLinkMenu.enabled = numLinkUrls > 1 copyLinkMenu.enabled = numLinkUrls > 1
copyLinkAction.enabled = !!messageContextMenu.linkUrls && numLinkUrls === 1 && !emojiOnly && !messageContextMenu.isProfile copyLinkAction.enabled = !!root.linkUrls && numLinkUrls === 1 && !emojiOnly && !root.isProfile
*/ */
popup() popup()
} }
@ -83,23 +84,23 @@ StatusPopupMenu {
id: emojiContainer id: emojiContainer
width: emojiRow.width width: emojiRow.width
height: visible ? emojiRow.height : 0 height: visible ? emojiRow.height : 0
visible: !hideEmojiPicker && (messageContextMenu.emojiOnly || !messageContextMenu.isProfile) visible: !hideEmojiPicker && (root.emojiOnly || !root.isProfile)
Row { Row {
id: emojiRow id: emojiRow
spacing: Style.current.halfPadding spacing: Style.current.halfPadding
leftPadding: Style.current.halfPadding leftPadding: Style.current.halfPadding
rightPadding: Style.current.halfPadding rightPadding: Style.current.halfPadding
bottomPadding: messageContextMenu.emojiOnly ? 0 : Style.current.padding bottomPadding: root.emojiOnly ? 0 : Style.current.padding
Repeater { Repeater {
model: messageContextMenu.reactionModel model: root.reactionModel
delegate: EmojiReaction { delegate: EmojiReaction {
source: Style.svg(filename) source: Style.svg(filename)
emojiId: model.emojiId emojiId: model.emojiId
reactedByUser: !!messageContextMenu.emojiReactionsReactedByUser[model.emojiId] reactedByUser: !!root.emojiReactionsReactedByUser[model.emojiId]
onCloseModal: { onCloseModal: {
chatsModel.toggleReaction(SelectedMessage.messageId, emojiId) chatsModel.toggleReaction(SelectedMessage.messageId, emojiId)
messageContextMenu.close() root.close()
} }
} }
} }
@ -108,7 +109,7 @@ StatusPopupMenu {
Item { Item {
id: profileHeader id: profileHeader
visible: messageContextMenu.isProfile visible: root.isProfile
width: parent.width width: parent.width
height: visible ? profileImage.height + username.height + Style.current.padding : 0 height: visible ? profileImage.height + username.height + Style.current.padding : 0
Rectangle { Rectangle {
@ -128,7 +129,7 @@ StatusPopupMenu {
StyledText { StyledText {
id: username id: username
text: Utils.removeStatusEns(isCurrentUser ? profileModel.ens.preferredUsername || userName : userName) text: Utils.removeStatusEns(isCurrentUser ? root.store.profileModelInst.ens.preferredUsername || userName : userName)
elide: Text.ElideRight elide: Text.ElideRight
maximumLineCount: 3 maximumLineCount: 3
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
@ -150,14 +151,14 @@ StatusPopupMenu {
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor
onClicked: { onClicked: {
openProfilePopup(userName, fromAuthor, identicon); openProfilePopup(userName, fromAuthor, identicon);
messageContextMenu.close() root.close()
} }
} }
} }
Separator { Separator {
anchors.bottom: viewProfileAction.top anchors.bottom: viewProfileAction.top
visible: !messageContextMenu.emojiOnly && !messageContextMenu.hideEmojiPicker visible: !root.emojiOnly && !root.hideEmojiPicker
} }
/* // copy link feature not ready yet /* // copy link feature not ready yet
@ -166,8 +167,8 @@ StatusPopupMenu {
//% "Copy link" //% "Copy link"
text: qsTrId("copy-link") text: qsTrId("copy-link")
onTriggered: { onTriggered: {
chatsModel.copyToClipboard(linkUrls.split(" ")[0]) root.store.chatsModelInst.copyToClipboard(linkUrls.split(" ")[0])
messageContextMenu.close() root.close()
} }
icon.name: "link" icon.name: "link"
enabled: false enabled: false
@ -181,13 +182,13 @@ StatusPopupMenu {
Repeater { Repeater {
id: linksRepeater id: linksRepeater
model: messageContextMenu.linkUrls.split(" ") model: root.linkUrls.split(" ")
delegate: MenuItem { delegate: MenuItem {
id: popupMenuItem id: popupMenuItem
text: modelData text: modelData
onTriggered: { onTriggered: {
chatsModel.copyToClipboard(modelData) root.store.chatsModelInst.copyToClipboard(modelData)
messageContextMenu.close() root.close()
} }
contentItem: StyledText { contentItem: StyledText {
text: popupMenuItem.text text: popupMenuItem.text
@ -211,8 +212,8 @@ StatusPopupMenu {
id: copyImageAction id: copyImageAction
text: qsTr("Copy image") text: qsTr("Copy image")
onTriggered: { onTriggered: {
chatsModel.copyImageToClipboard(imageSource ? imageSource : "") root.store.chatsModelInst.copyImageToClipboard(imageSource ? imageSource : "")
messageContextMenu.close() root.close()
} }
icon.name: "copy" icon.name: "copy"
enabled: isRightClickOnImage enabled: isRightClickOnImage
@ -223,7 +224,7 @@ StatusPopupMenu {
text: qsTr("Download image") text: qsTr("Download image")
onTriggered: { onTriggered: {
fileDialog.open() fileDialog.open()
messageContextMenu.close() root.close()
} }
icon.name: "download" icon.name: "download"
enabled: isRightClickOnImage enabled: isRightClickOnImage
@ -235,7 +236,7 @@ StatusPopupMenu {
text: qsTrId("view-profile") text: qsTrId("view-profile")
onTriggered: { onTriggered: {
openProfilePopup(userName, fromAuthor, identicon, "", nickname); openProfilePopup(userName, fromAuthor, identicon, "", nickname);
messageContextMenu.close() root.close()
} }
icon.name: "profile" icon.name: "profile"
enabled: isProfile enabled: isProfile
@ -243,19 +244,19 @@ StatusPopupMenu {
StatusMenuItem { StatusMenuItem {
id: sendMessageOrReplyTo id: sendMessageOrReplyTo
text: messageContextMenu.isProfile ? text: root.isProfile ?
//% "Send message" //% "Send message"
qsTrId("send-message") : qsTrId("send-message") :
//% "Reply to" //% "Reply to"
qsTrId("reply-to") qsTrId("reply-to")
onTriggered: { onTriggered: {
if (messageContextMenu.isProfile) { if (root.isProfile) {
appMain.changeAppSection(Constants.chat) appMain.changeAppSection(Constants.chat)
chatsModel.channelView.joinPrivateChat(fromAuthor, "") root.store.chatsModelInst.channelView.joinPrivateChat(fromAuthor, "")
} else { } else {
showReplyArea() showReplyArea()
} }
messageContextMenu.close() root.close()
} }
icon.name: "chat" icon.name: "chat"
enabled: isProfile || (!hideEmojiPicker && !emojiOnly && !isProfile && !isRightClickOnImage) enabled: isProfile || (!hideEmojiPicker && !emojiOnly && !isProfile && !isRightClickOnImage)
@ -285,7 +286,7 @@ StatusPopupMenu {
} }
onTriggered: { onTriggered: {
if (pinnedMessage) { if (pinnedMessage) {
chatsModel.messageView.unPinMessage(messageId, chatsModel.channelView.activeChannel.id) root.store.chatsModelInst.messageView.unPinMessage(messageId, root.store.chatsModelInst.channelView.activeChannel.id)
return return
} }
@ -295,20 +296,20 @@ StatusPopupMenu {
return return
} }
chatsModel.messageView.pinMessage(messageId, chatsModel.channelView.activeChannel.id) root.store.chatsModelInst.messageView.pinMessage(messageId, root.store.chatsModelInst.channelView.activeChannel.id)
messageContextMenu.close() root.close()
} }
icon.name: "pin" icon.name: "pin"
enabled: { enabled: {
if(isProfile || emojiOnly || isRightClickOnImage) if(isProfile || emojiOnly || isRightClickOnImage)
return false return false
switch (chatsModel.channelView.activeChannel.chatType) { switch (root.store.chatsModelInst.channelView.activeChannel.chatType) {
case Constants.chatTypePublic: return false case Constants.chatTypePublic: return false
case Constants.chatTypeStatusUpdate: return false case Constants.chatTypeStatusUpdate: return false
case Constants.chatTypeOneToOne: return true case Constants.chatTypeOneToOne: return true
case Constants.chatTypePrivateGroupChat: return chatsModel.channelView.activeChannel.isAdmin(profileModel.profile.pubKey) case Constants.chatTypePrivateGroupChat: return root.store.chatsModelInst.channelView.activeChannel.isAdmin(root.store.profileModelInst.profile.pubKey)
case Constants.chatTypeCommunity: return chatsModel.communities.activeCommunity.admin case Constants.chatTypeCommunity: return root.store.chatsModelInst.communities.activeCommunity.admin
} }
return false return false
@ -332,7 +333,7 @@ StatusPopupMenu {
text: qsTrId("delete-message") text: qsTrId("delete-message")
onTriggered: { onTriggered: {
if (!appSettings.showDeleteMessageWarning) { if (!appSettings.showDeleteMessageWarning) {
return chatsModel.messageView.deleteMessage(messageId) return root.store.chatsModelInst.messageView.deleteMessage(messageId)
} }
let confirmationDialog = openPopup(genericConfirmationDialog, { let confirmationDialog = openPopup(genericConfirmationDialog, {
@ -348,7 +349,7 @@ StatusPopupMenu {
} }
confirmationDialog.close() confirmationDialog.close()
chatsModel.messageView.deleteMessage(messageId) root.store.chatsModelInst.messageView.deleteMessage(messageId)
} }
}) })
} }
@ -357,12 +358,12 @@ StatusPopupMenu {
} }
StatusMenuItem { StatusMenuItem {
enabled: messageContextMenu.pinnedPopup enabled: root.pinnedPopup
text: qsTr("Jump to") text: qsTr("Jump to")
onTriggered: { onTriggered: {
positionAtMessage(messageContextMenu.messageId) positionAtMessage(root.messageId)
messageContextMenu.close() root.close()
messageContextMenu.shouldCloseParentPopup() root.shouldCloseParentPopup()
} }
icon.name: "up" icon.name: "up"
} }
@ -373,7 +374,7 @@ StatusPopupMenu {
selectFolder: true selectFolder: true
modality: Qt.NonModal modality: Qt.NonModal
onAccepted: { onAccepted: {
chatsModel.downloadImage(imageSource ? imageSource : "", fileDialog.fileUrls) root.store.chatsModelInst.downloadImage(imageSource ? imageSource : "", fileDialog.fileUrls)
fileDialog.close() fileDialog.close()
} }
onRejected: { onRejected: {

View File

@ -11,11 +11,10 @@ import "../panels"
import "../views" import "../views"
import "../controls" import "../controls"
Item { Column {
id: root id: root
width: parent.width width: parent.width
anchors.right: !isCurrentUser ? undefined : parent.right anchors.right: !isCurrentUser ? undefined : parent.right
height: visible ? childrenRect.height : 0
z: (typeof chatLogView === "undefined") ? 1 : (chatLogView.count - index) z: (typeof chatLogView === "undefined") ? 1 : (chatLogView.count - index)
////////////////////////////////////// //////////////////////////////////////
@ -249,123 +248,27 @@ Item {
} }
} }
Timer {
id: timer
}
Component { Component {
id: gapComponent id: gapComponent
Item { GapComponent {
id: wrapper onClicked: {
height: childrenRect.height + Style.current.smallPadding * 2 rootStore.chatsModelInst.messageView.fillGaps(messageStore.messageId);
anchors.left: parent.left root.visible = false;
anchors.right: parent.right root.height = 0;
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: {
chatsModel.messageView.fillGaps(messageId)
root.visible = false;
root.height = 0;
}
}
}
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
} }
} }
} }
Component { Component {
id: fetchMoreMessagesButtonComponent id: fetchMoreMessagesButtonComponent
Item { FetchMoreMessagesButton {
id: wrapper // nextMessageIndex: root.messageStore.nextMessageIndex
height: childrenRect.height + Style.current.smallPadding * 2 // nextMsgTimestamp: root.messageStore.nextMsgTimestamp
anchors.left: parent.left onClicked: {
anchors.right: parent.right rootStore.chatsModelInst.messageView.hideLoadingIndicator();
Separator {
id: sep1
} }
Loader { onTimerTriggered: {
id: fetchLoaderIndicator rootStore.chatsModelInst.requestMoreMessages(Constants.fetchRangeLast24Hours);
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: {
chatsModel.requestMoreMessages(Constants.fetchRangeLast24Hours);
fetchLoaderIndicator.active = true;
fetchMoreButton.visible = false;
fetchDate.visible = false;
timer.setTimeout(function(){
chatsModel.messageView.hideLoadingIndicator();
fetchLoaderIndicator.active = false;
fetchMoreButton.visible = true;
fetchDate.visible = true;
}, 3000);
}
}
}
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
} }
} }
} }

View File

@ -289,6 +289,7 @@ Item {
anchors.rightMargin: Style.current.padding anchors.rightMargin: Style.current.padding
sourceComponent: Component { sourceComponent: Component {
TransactionBubblePanel { TransactionBubblePanel {
balanceView: root.store.walletModelInst.balanceView
focusedAccount: root.store.walletModelInst.accountsView.focusedAccount focusedAccount: root.store.walletModelInst.accountsView.focusedAccount
activeChannelName: root.store.chatsModelInst.channelView.activeChannel.name activeChannelName: root.store.chatsModelInst.channelView.activeChannel.name
activeChannelIdenticon: root.store.chatsModelInst.channelView.activeChannel.identicon activeChannelIdenticon: root.store.chatsModelInst.channelView.activeChannel.identicon
@ -324,7 +325,7 @@ Item {
anchors.verticalCenter: isImage ? dateTimeBackground.verticalCenter : undefined anchors.verticalCenter: isImage ? dateTimeBackground.verticalCenter : undefined
anchors.right: isImage ? dateTimeBackground.right : (linksLoader.active ? linksLoader.right : chatBox.right) anchors.right: isImage ? dateTimeBackground.right : (linksLoader.active ? linksLoader.right : chatBox.right)
anchors.rightMargin: isImage ? 6 : (root.isCurrentUser ? 5 : Style.current.padding) anchors.rightMargin: isImage ? 6 : (root.isCurrentUser ? 5 : Style.current.padding)
timestamp: root.messageStore.timestamp //timestamp: root.messageStore.timestamp
} }
SentMessage { SentMessage {

View File

@ -338,7 +338,7 @@ Item {
anchors.bottomMargin: Style.current.padding anchors.bottomMargin: Style.current.padding
anchors.right: chatBox.right anchors.right: chatBox.right
anchors.rightMargin: Style.current.padding anchors.rightMargin: Style.current.padding
timestamp: root.timestamp //timestamp: root.timestamp
} }
StatusBaseText { StatusBaseText {
@ -350,8 +350,6 @@ Item {
font.pixelSize: 14 font.pixelSize: 14
color: Theme.palette.baseColor1 color: Theme.palette.baseColor1
} }
} }

View File

@ -10,7 +10,6 @@ import "../../../shared/controls"
import "../../../shared/status" import "../../../shared/status"
import "../Chat/views" import "../Chat/views"
import "../Chat/panels"
import "../Chat/popups" import "../Chat/popups"
import "../Chat/stores" import "../Chat/stores"
@ -214,8 +213,9 @@ ScrollView {
messageStore.timeout = model.timeout; messageStore.timeout = model.timeout;
messageStore.messageContextMenu = msgCntxtMenu; messageStore.messageContextMenu = msgCntxtMenu;
} }
MessageContextMenuPanel { MessageContextMenuView {
id: msgCntxtMenu id: msgCntxtMenu
store: root.store
reactionModel: EmojiReactions { } reactionModel: EmojiReactions { }
} }
} }

View File

@ -185,7 +185,7 @@ Popup {
id: btnAddStickerPack id: btnAddStickerPack
implicitWidth: 24 implicitWidth: 24
implicitHeight: 24 implicitHeight: 24
type: StatusRoundButton.Type.Secondary type: StatusQControls.StatusRoundButton.Type.Secondary
icon.name: "add" icon.name: "add"
state: root.stickerPacksLoaded ? "default" : "pending" state: root.stickerPacksLoaded ? "default" : "pending"
onClicked: { onClicked: {