fix(AppMain): Made all banners global and stacked

This commit is contained in:
Igor Sirotin 2022-09-02 17:56:14 +03:00 committed by Igor Sirotin
parent 2bb346a09e
commit b2485603de
5 changed files with 342 additions and 226 deletions

View File

@ -38,7 +38,6 @@ Item {
property bool isReply: false
property bool isImage: false
property bool isExtendedInput: isReply || isImage
property bool isConnected: false
property string contactToRemove: ""
property bool isSectionActive: mainModule.activeSection.id === parentModule.getMySectionId()
property string activeChatId: parentModule && parentModule.activeItem.id
@ -217,7 +216,6 @@ Item {
rootStore: root.rootStore
contactsStore: root.contactsStore
emojiPopup: root.emojiPopup
isConnected: root.isConnected
sendTransactionNoEnsModal: cmpSendTransactionNoEns
receiveTransactionModal: cmpReceiveTransaction
sendTransactionWithEnsModal: cmpSendTransactionWithEns
@ -266,7 +264,6 @@ Item {
clip: true
rootStore: root.rootStore
contactsStore: root.contactsStore
isConnected: root.isConnected
emojiPopup: root.emojiPopup
sendTransactionNoEnsModal: cmpSendTransactionNoEns
receiveTransactionModal: cmpReceiveTransaction

View File

@ -35,7 +35,6 @@ ColumnLayout {
property var rootStore
property var contactsStore
property bool isActiveChannel: false
property bool isConnected: false
property var emojiPopup
property alias textInputField: chatInput
property UsersStore usersStore: UsersStore {}
@ -64,52 +63,6 @@ ColumnLayout {
}
}
Rectangle {
id: connectedStatusRect
Layout.fillWidth: true
height: 40
Layout.alignment: Qt.AlignHCenter
z: 60
visible: false
color: isConnected ? Style.current.green : Style.current.darkGrey
Text {
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
color: Style.current.white
id: connectedStatusLbl
text: isConnected ?
qsTr("Connected") :
qsTr("Disconnected")
}
Connections {
target: mainModule
onOnlineStatusChanged: {
if (connected === isConnected) return;
isConnected = connected;
if(isConnected) {
onlineStatusTimer.start();
} else {
connectedStatusRect.visible = true;
}
}
}
Component.onCompleted: {
isConnected = mainModule.isOnline
if(!isConnected){
connectedStatusRect.visible = true
}
}
}
Timer {
id: onlineStatusTimer
interval: 5000
onTriggered: {
connectedStatusRect.visible = false;
}
}
StatusBanner {
Layout.fillWidth: true
visible: root.isBlocked

View File

@ -30,7 +30,7 @@ StatusSectionLayout {
QtObject {
id: d
readonly property int topMargin: secureYourSeedPhrase.visible ? secureYourSeedPhrase.height : 0
readonly property int topMargin: 0
readonly property int bottomMargin: 56
readonly property int leftMargin: 48
readonly property int rightMargin: 48
@ -53,50 +53,13 @@ StatusSectionLayout {
centerPanel: Item {
anchors.fill: parent
ModuleWarning {
id: secureYourSeedPhrase
width: parent.width
visible: {
if (profileContainer.currentIndex !== Constants.settingsSubsection.profile) {
return false
}
if (root.store.profileStore.userDeclinedBackupBanner) {
return false
}
return !root.store.profileStore.privacyStore.mnemonicBackedUp
}
color: Style.current.red
btnWidth: 100
text: qsTr("Secure your seed phrase")
btnText: qsTr("Back up now")
onClick: function(){
Global.openBackUpSeedPopup();
}
onClosed: {
root.store.profileStore.userDeclinedBackupBanner = true
}
}
StatusBanner {
id: banner
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
height: visible ? childrenRect.height : 0
visible: profileContainer.currentIndex === Constants.settingsSubsection.wallet &&
root.store.walletStore.areTestNetworksEnabled
type: StatusBanner.Type.Danger
statusText: qsTr("Testnet mode is enabled. All balances, transactions and dApp interactions will be on testnets.")
}
StackLayout {
id: profileContainer
readonly property var currentItem: (currentIndex >= 0 && currentIndex < children.length) ? children[currentIndex] : null
anchors.top: banner.visible? banner.bottom : parent.top
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom

View File

@ -5,6 +5,7 @@ import QtMultimedia 5.13
import Qt.labs.qmlmodels 1.0
import Qt.labs.platform 1.1
import Qt.labs.settings 1.0
import QtQml.Models 2.14
import AppLayouts.Wallet 1.0
import AppLayouts.Node 1.0
@ -28,6 +29,7 @@ import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import StatusQ.Layout 0.1
import StatusQ.Popups 0.1
import StatusQ.Popups.Dialog 0.1
import StatusQ.Core 0.1
import AppLayouts.Browser.stores 1.0 as BrowserStores
@ -46,18 +48,6 @@ Item {
// set from main.qml
property var sysPalette
Connections {
target: rootStore.aboutModuleInst
onAppVersionFetched: {
rootStore.setLatestVersionInfo(available, version, url);
if (!available) {
versionUpToDate.show()
} else {
versionWarning.show()
}
}
}
Connections {
target: rootStore.mainModuleInst
onDisplayUserProfile: Global.openProfilePopup(publicKey)
@ -399,53 +389,188 @@ Item {
spacing: 0
objectName: "mainRightView"
ModuleWarning {
id: versionWarning
width: parent.width
height: 32
visible: appMain.rootStore.newVersionAvailable
color: Style.current.green
btnWidth: 100
text: qsTr("A new version of Status (%1) is available").arg(appMain.rootStore.latestVersion)
btnText: qsTr("Download")
onClick: function(){
Global.openDownloadModal(appMain.rootStore.newVersionAvailable, appMain.rootStore.latestVersion, appMain.rootStore.downloadURL)
}
onClosed: {
appMain.rootStore.resetLastVersion();
ColumnLayout {
id: bannersLayout
property var updateBanner: null
property var connectedBanner: null
readonly property bool isConnected: mainModule.isOnline
function processUpdateAvailable() {
if (!updateBanner)
updateBanner = updateBannerComponent.createObject(this)
}
function show() {
versionWarning.visible = true
function processConnected() {
if (!connectedBanner)
connectedBanner = connectedBannerComponent.createObject(this)
}
Layout.fillWidth: true
Layout.maximumHeight: implicitHeight
spacing: 1
onIsConnectedChanged: {
processConnected()
}
Connections {
target: rootStore.aboutModuleInst
onAppVersionFetched: {
rootStore.setLatestVersionInfo(available, version, url);
bannersLayout.processUpdateAvailable()
}
}
ModuleWarning {
id: testnetBanner
Layout.fillWidth: true
text: qsTr("Testnet mode is enabled. All balances, transactions and dApp interactions will be on testnets.")
buttonText: qsTr("Turn off")
type: ModuleWarning.Danger
active: appMain.rootStore.profileSectionStore.walletStore.areTestNetworksEnabled
onClicked: {
testnetBannerDialog.open()
}
onCloseClicked: {
testnetBannerDialog.open()
}
StatusDialog {
id: testnetBannerDialog
width: 400
title: qsTr("Turn off Testnet mode")
StatusBaseText {
anchors.fill: parent
text: qsTr("Closing this banner will turn off Testnet mode.\nAll future transactions will be on mainnet or other active networks.")
font.pixelSize: 15
wrapMode: Text.WordWrap
}
footer: StatusDialogFooter {
rightButtons: ObjectModel {
StatusButton {
type: StatusButton.Danger
text: qsTr("Turn off Testnet")
onClicked: {
appMain.rootStore.profileSectionStore.walletStore.toggleTestNetworksEnabled()
testnetBannerDialog.close()
}
}
}
}
}
}
ModuleWarning {
id: secureYourSeedPhrase
Layout.fillWidth: true
active: !appMain.rootStore.profileSectionStore.profileStoree.userDeclinedBackupBanner
&& !appMain.rootStore.profileSectionStore.profileStore.privacyStore.mnemonicBackedUp
type: ModuleWarning.Danger
text: qsTr("Secure your seed phrase")
buttonText: qsTr("Back up now")
onClicked: {
Global.openBackUpSeedPopup();
}
onCloseClicked: {
appMain.rootStore.profileSectionStore.profileStore.userDeclinedBackupBanner = true
}
}
Component {
id: connectedBannerComponent
ModuleWarning {
readonly property bool isConnected: bannersLayout.isConnected
Layout.fillWidth: true
text: isConnected ? qsTr("Connected") : qsTr("Disconnected")
type: isConnected ? ModuleWarning.Success : ModuleWarning.Danger
function updateState() {
if (isConnected)
showFor()
else
show();
}
Component.onCompleted: {
updateState()
}
onIsConnectedChanged: {
updateState();
}
onCloseClicked: {
hide();
}
onHideStarted: {
bannersLayout.connectedBanner = null
}
onHideFinished: {
destroy()
}
}
}
Component {
id: updateBannerComponent
ModuleWarning {
readonly property string version: appMain.rootStore.latestVersion
readonly property bool updateAvailable: appMain.rootStore.newVersionAvailable
Layout.fillWidth: true
type: ModuleWarning.Success
text: updateAvailable ? qsTr("A new version of Status (%1) is available").arg(version)
: qsTr("Your version is up to date")
buttonText: updateAvailable ? qsTr("Update")
: qsTr("Close")
function updateState() {
if (updateAvailable)
show()
else
showFor(5000)
}
Component.onCompleted: {
updateState()
}
onUpdateAvailableChanged: {
updateState();
}
onClicked: {
if (updateAvailable)
Global.openDownloadModal(appMain.rootStore.newVersionAvailable,
appMain.rootStore.latestVersion,
appMain.rootStore.downloadURL)
else
close()
}
onCloseClicked: {
if (updateAvailable)
appMain.rootStore.resetLastVersion();
hide()
}
onHideStarted: {
bannersLayout.updateBanner = null
}
onHideFinished: {
destroy()
}
}
}
}
ModuleWarning {
id: versionUpToDate
width: parent.width
height: 32
visible: false
color: Style.current.green
btnWidth: 100
text: qsTr("Your version is up to date")
btnText: qsTr("Close")
Timer {
id: timer
}
function show() {
versionUpToDate.visible = true
timer.setTimeout(function() {
versionUpToDate.close()
}, 4000);
}
onClick: function(){
versionUpToDate.close()
}
}
Item {
Layout.fillWidth: true
Layout.fillHeight: true
@ -693,6 +818,7 @@ Item {
}
}
}
} // ColumnLayout
property var mailserverNotWorkingPopup: null

View File

@ -3,111 +3,188 @@ import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import QtGraphicalEffects 1.13
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import utils 1.0
import "../"
import "./"
Rectangle {
Item {
id: root
objectName: "moduleWarningBanner"
height: visible ? 32 : 0
implicitHeight: height
color: Style.current.red
property string text: ""
property string btnText: ""
property int btnWidth: 58
property bool closing: false
property var onClick: function() {}
signal closed()
function close() {
closeBtn.clicked(null)
closed();
enum Type {
Danger,
Success
}
Row {
spacing: Style.current.halfPadding
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
property bool active: false
property int type: ModuleWarning.Danger
property string text: ""
property alias buttonText: button.text
StyledText {
text: root.text
font.pixelSize: 13
anchors.verticalCenter: parent.verticalCenter
color: Style.current.white
signal clicked()
signal closeClicked()
signal showStarted()
signal showFinihsed()
signal hideStarted()
signal hideFinished()
function show() {
hideTimer.stop()
active = true;
}
function showFor(duration = 5000) {
show();
hide(duration);
}
function hide(timeout = 0) {
hideTimer.interval = timeout
hideTimer.start()
}
function close() {
closeButtonMouseArea.clicked(null)
}
implicitHeight: root.active ? content.implicitHeight : 0
visible: implicitHeight > 0
onActiveChanged: {
active ? showAnimation.start() : hideAnimation.start()
}
NumberAnimation {
id: showAnimation
target: root
property: "implicitHeight"
from: 0
to: content.implicitHeight
duration: 500
easing.type: Easing.OutCubic
onStarted: {
root.showStarted()
}
onFinished: {
root.showFinihsed()
}
}
NumberAnimation {
id: hideAnimation
target: root
property: "implicitHeight"
to: 0
from: content.implicitHeight
duration: 500
easing.type: Easing.OutCubic
onStarted: {
root.hideStarted()
}
onFinished: {
root.hideFinished()
}
}
Timer {
id: hideTimer
repeat: false
running: false
onTriggered: {
root.active = false
}
}
Rectangle {
id: content
anchors.bottom: parent.bottom
width: parent.width
implicitHeight: 32
readonly property color baseColor: {
switch (root.type) {
case ModuleWarning.Danger: return Theme.palette.dangerColor1
case ModuleWarning.Success: return Theme.palette.successColor1
default: return Theme.palette.baseColor1
}
}
Button {
width: btnWidth
height: 24
contentItem: Item {
anchors.fill: parent
Text {
text: btnText
font.pixelSize: 13
color: baseColor
Behavior on color {
ColorAnimation {
duration: 150
}
}
RowLayout {
id: layout
spacing: 12
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
StatusBaseText {
text: root.text
Layout.alignment: Qt.AlignVCenter
font.pixelSize: 13
color: Theme.palette.indirectColor1
}
Button {
id: button
visible: text != ""
padding: 5
onClicked: {
root.clicked()
}
contentItem: Text {
text: button.text
font.pixelSize: 12
font.weight: Font.Medium
font.family: Style.current.fontRegular.name
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
color: Style.current.white
color: Theme.palette.indirectColor1
}
background: Rectangle {
radius: 4
border.width: 1
border.color: Theme.palette.indirectColor3
color: Theme.palette.getColor("white", button.hovered ? 0.4 : 0.1)
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: Qt.PointingHandCursor
}
}
background: Rectangle {
radius: 4
anchors.fill: parent
border.color: Style.current.white
color: "#19FFFFFF"
}
}
StatusIcon {
id: closeImg
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 18
height: 20
width: 20
icon: "close-circle"
color: Theme.palette.indirectColor1
opacity: closeButtonMouseArea.containsMouse ? 1 : 0.7
MouseArea {
cursorShape: Qt.PointingHandCursor
id: closeButtonMouseArea
anchors.fill: parent
onClicked: root.onClick()
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
root.closeClicked()
}
}
}
}
SVGImage {
id: closeImg
anchors.top: parent.top
anchors.topMargin: 6
anchors.right: parent.right
anchors.rightMargin: 18
source: Style.svg("close-white")
height: 20
width: 20
}
ColorOverlay {
anchors.fill: closeImg
source: closeImg
color: Style.current.white
opacity: 0.7
}
MouseArea {
id: closeBtn
anchors.fill: closeImg
cursorShape: Qt.PointingHandCursor
onClicked: {
closing = true
}
}
ParallelAnimation {
running: closing
PropertyAnimation { target: root; property: "visible"; to: false; }
PropertyAnimation { target: root; property: "y"; to: -1 * root.height }
onRunningChanged: {
if(!running){
closing = false;
root.y = 0;
root.closed();
}
}
}
}