diff --git a/ui/StatusQ b/ui/StatusQ index 80a9cc9b3f..ecc44cfae0 160000 --- a/ui/StatusQ +++ b/ui/StatusQ @@ -1 +1 @@ -Subproject commit 80a9cc9b3face23df65e7630afe5339a8acf8072 +Subproject commit ecc44cfae0f3c06cad5e3f3d7c94f4d1488fdf9b diff --git a/ui/app/AppLayouts/Browser/BrowserLayout.qml b/ui/app/AppLayouts/Browser/BrowserLayout.qml index 4e70885dc8..c6f79634de 100644 --- a/ui/app/AppLayouts/Browser/BrowserLayout.qml +++ b/ui/app/AppLayouts/Browser/BrowserLayout.qml @@ -7,9 +7,10 @@ import Qt.labs.settings 1.0 import QtQuick.Controls.Styles 1.0 import QtQuick.Dialogs 1.2 +import StatusQ.Layout 0.1 + import utils 1.0 import shared.controls 1.0 - import shared 1.0 import shared.status 1.0 import shared.popups 1.0 @@ -22,17 +23,13 @@ import "stores" // Code based on https://code.qt.io/cgit/qt/qtwebengine.git/tree/examples/webengine/quicknanobrowser/BrowserWindow.qml?h=5.15 // Licensed under BSD -Rectangle { - id: browserWindow +StatusSectionLayout { + id: root property var globalStore property var sendTransactionModal - function openUrlInNewTab(url) { - var tab = _internal.addNewTab() - tab.item.url = _internal.determineRealURL(url) - } - + onNotificationButtonClicked: Global.openActivityCenterPopup() QtObject { id: _internal @@ -57,9 +54,9 @@ Rectangle { // TODO we'll need a new dialog at one point because this one is not using the same call, but it's good for now property Component sendTransactionModalComponent: SignTransactionModal { anchors.centerIn: parent - store: browserWindow.globalStore - contactsStore: browserWindow.globalStore.profileSectionStore.contactsStore - chainId: browserWindow.globalStore.getChainIdForBrowser() + store: root.globalStore + contactsStore: root.globalStore.profileSectionStore.contactsStore + chainId: root.globalStore.getChainIdForBrowser() } property Component signMessageModalComponent: SignMessageModal {} @@ -139,183 +136,331 @@ Rectangle { } } - Layout.fillHeight: true - Layout.fillWidth: true + centerPanel: Rectangle { + id: browserWindow + anchors.fill: parent + color: Style.current.inputBackground - color: Style.current.inputBackground - border.width: 0 - WebProviderObj { - id: provider - createAccessDialogComponent: function() { - return _internal.accessDialogComponent.createObject(browserWindow) + function openUrlInNewTab(url) { + var tab = _internal.addNewTab() + tab.item.url = _internal.determineRealURL(url) } - createSendTransactionModalComponent: function(request) { - return _internal.sendTransactionModalComponent.createObject(browserWindow, { - trxData: request.payload.params[0].data || "", + + WebProviderObj { + id: provider + createAccessDialogComponent: function() { + return _internal.accessDialogComponent.createObject(root) + } + createSendTransactionModalComponent: function(request) { + return _internal.sendTransactionModalComponent.createObject(root, { + trxData: request.payload.params[0].data || "", + selectedAccount: { + name: WalletStore.dappBrowserAccount.name, + address: request.payload.params[0].from, + iconColor: WalletStore.dappBrowserAccount.color, + assets: WalletStore.dappBrowserAccount.assets + }, + selectedRecipient: { + address: request.payload.params[0].to, + identicon: "", + name: RootStore.activeChannelName, + type: RecipientSelector.Type.Address + }, + selectedAsset: { + name: "ETH", + symbol: "ETH", + address: Constants.zeroAddress + }, + selectedFiatAmount: "42", // TODO calculate that + selectedAmount: RootStore.getWei2Eth(request.payload.params[0].value, 18) + }) + } + createSignMessageModalComponent: function(request) { + return _internal.signMessageModalComponent.createObject(root, { + request, selectedAccount: { name: WalletStore.dappBrowserAccount.name, - address: request.payload.params[0].from, - iconColor: WalletStore.dappBrowserAccount.color, - assets: WalletStore.dappBrowserAccount.assets - }, - selectedRecipient: { - address: request.payload.params[0].to, - identicon: "", - name: RootStore.activeChannelName, - type: RecipientSelector.Type.Address - }, - selectedAsset: { - name: "ETH", - symbol: "ETH", - address: Constants.zeroAddress - }, - selectedFiatAmount: "42", // TODO calculate that - selectedAmount: RootStore.getWei2Eth(request.payload.params[0].value, 18) + iconColor: WalletStore.dappBrowserAccount.color + } }) - } - createSignMessageModalComponent: function(request) { - return _internal.signMessageModalComponent.createObject(browserWindow, { - request, - selectedAccount: { - name: WalletStore.dappBrowserAccount.name, - iconColor: WalletStore.dappBrowserAccount.color - } - }) - } - showSendingError: function(message) { - _internal.sendingError.text = message - return _internal.sendingError.open() - } - showSigningError: function(message) { - _internal.signingError.text = message - return _internal.signingError.open() - } - showToastMessage: function(result) { - // TODO: WIP under PR https://github.com/status-im/status-desktop/pull/4274 - let url = `${WalletStore.getEtherscanLink()}/${result}`; - Global.displayToastMessage(qsTr("Transaction pending..."), - qsTr("View on etherscan"), - "", - true, - Constants.ephemeralNotificationType.normal, - url); - } - } - - BrowserShortcutActions { - id: keyboardShortcutActions - currentWebView: _internal.currentWebView - findBarComponent: findBar - browserHeaderComponent: browserHeader - onAddNewDownloadTab: _internal.addNewDownloadTab() - onRemoveView: tabs.removeView(tabs.currentIndex) - } - - WebChannel { - id: channel - registeredObjects: [provider] - } - - BrowserHeader { - id: browserHeader - anchors.top: parent.top - anchors.topMargin: tabs.tabHeight + tabs.anchors.topMargin - z: 52 - favoriteComponent: favoritesBar - currentFavorite: _internal.currentWebView && BookmarksStore.getCurrentFavorite(_internal.currentWebView.url) - dappBrowserAccName: WalletStore.dappBrowserAccount.name - dappBrowserAccIcon: WalletStore.dappBrowserAccount.color - settingMenu: settingsMenu - walletMenu: browserWalletMenu - currentUrl: _internal.currentWebView.url - isLoading: _internal.currentWebView.loading - canGoBack: _internal.currentWebView.canGoBack - canGoForward: _internal.currentWebView.canGoForward - currentTabConnected: RootStore.currentTabConnected - onOpenHistoryPopup: historyMenu.popup(xPos, yPos) - onGoBack: _internal.currentWebView.goBack() - onGoForward: _internal.currentWebView.goForward() - onReload: _internal.currentWebView.reload() - onStopLoading: _internal.currentWebView.stop() - onAddNewFavoritelClicked: { - Global.openPopup(addFavoriteModal, - { - x: xPos - 30, - y: browserHeader.y + browserHeader.height + 4, - modifiyModal: browserHeader.currentFavorite, - toolbarMode: true, - ogUrl: browserHeader.currentFavorite ? browserHeader.currentFavorite.url : _internal.currentWebView.url, - ogName: browserHeader.currentFavorite ? browserHeader.currentFavorite.name : _internal.currentWebView.title - }) - } - onLaunchInBrowser: { - // TODO: disable browsing local files? file:// - if (localAccountSensitiveSettings.useBrowserEthereumExplorer !== Constants.browserEthereumExplorerNone && url.startsWith("0x")) { - _internal.currentWebView.url = RootStore.get0xFormedUrl(localAccountSensitiveSettings.useBrowserEthereumExplorer, url) - return } - if (localAccountSensitiveSettings.shouldShowBrowserSearchEngine !== Constants.browserSearchEngineNone && !Utils.isURL(url) && !Utils.isURLWithOptionalProtocol(url)) { - _internal.currentWebView.url = RootStore.getFormedUrl(localAccountSensitiveSettings.shouldShowBrowserSearchEngine, url) - return - } else if (Utils.isURLWithOptionalProtocol(url)) { - url = "https://" + url + showSendingError: function(message) { + _internal.sendingError.text = message + return _internal.sendingError.open() + } + showSigningError: function(message) { + _internal.signingError.text = message + return _internal.signingError.open() + } + showToastMessage: function(result) { + // TODO: WIP under PR https://github.com/status-im/status-desktop/pull/4274 + let url = `${WalletStore.getEtherscanLink()}/${result}`; + Global.displayToastMessage(qsTr("Transaction pending..."), + qsTr("View on etherscan"), + "", + true, + Constants.ephemeralNotificationType.normal, + url); } - _internal.currentWebView.url = _internal.determineRealURL(url); } - } - BrowserTabView { - id: tabs - anchors.top: parent.top - anchors.topMargin: Style.current.halfPadding - anchors.bottom: devToolsView.top - anchors.bottomMargin: browserHeader.height - anchors.left: parent.left - anchors.right: parent.right - z: 50 - tabComponent: webEngineView - currentWebEngineProfile: _internal.currentWebView.profile - determineRealURL: function(url) { - return _internal.determineRealURL(url) + BrowserShortcutActions { + id: keyboardShortcutActions + currentWebView: _internal.currentWebView + findBarComponent: findBar + browserHeaderComponent: browserHeader + onAddNewDownloadTab: _internal.addNewDownloadTab() + onRemoveView: tabs.removeView(tabs.currentIndex) } - onOpenNewTabTriggered: _internal.addNewTab() - Component.onCompleted: { - _internal.defaultProfile.downloadRequested.connect(_internal.onDownloadRequested); - _internal.otrProfile.downloadRequested.connect(_internal.onDownloadRequested); - var tab = createEmptyTab(_internal.defaultProfile); - // For Devs: Uncomment the next lien if you want to use the simpeldapp on first load - // tab.item.url = Web3ProviderStore.determineRealURL("https://simpledapp.eth"); - } - } - ProgressBar { - id: progressBar - height: 3 - from: 0 - to: 100 - visible: value != 0 && value != 100 - value: (_internal.currentWebView && _internal.currentWebView.loadProgress < 100) ? _internal.currentWebView.loadProgress : 0 - anchors.bottom: parent.bottom - anchors.bottomMargin: Style.current.padding - anchors.right: parent.right - anchors.rightMargin: Style.current.padding - } - - WebEngineView { - id: devToolsView - visible: localAccountSensitiveSettings.devToolsEnabled - height: visible ? 400 : 0 - inspectedView: visible && tabs.currentIndex < tabs.count ? tabs.getTab(tabs.currentIndex).item : null - anchors.left: parent.left - anchors.right: parent.right - anchors.bottom: parent.bottom - onNewViewRequested: function(request) { - var tab = tabs.createEmptyTab(_internal.currentWebView.profile); - tabs.currentIndex = tabs.count - 1; - request.openIn(tab.item); + WebChannel { + id: channel + registeredObjects: [provider] + } + + BrowserHeader { + id: browserHeader + anchors.top: parent.top + anchors.topMargin: tabs.tabHeight + tabs.anchors.topMargin + z: 52 + favoriteComponent: favoritesBar + currentFavorite: _internal.currentWebView && BookmarksStore.getCurrentFavorite(_internal.currentWebView.url) + dappBrowserAccName: WalletStore.dappBrowserAccount.name + dappBrowserAccIcon: WalletStore.dappBrowserAccount.color + settingMenu: settingsMenu + walletMenu: browserWalletMenu + currentUrl: _internal.currentWebView.url + isLoading: _internal.currentWebView.loading + canGoBack: _internal.currentWebView.canGoBack + canGoForward: _internal.currentWebView.canGoForward + currentTabConnected: RootStore.currentTabConnected + onOpenHistoryPopup: historyMenu.popup(xPos, yPos) + onGoBack: _internal.currentWebView.goBack() + onGoForward: _internal.currentWebView.goForward() + onReload: _internal.currentWebView.reload() + onStopLoading: _internal.currentWebView.stop() + onAddNewFavoritelClicked: { + Global.openPopup(addFavoriteModal, + { + x: xPos - 30, + y: browserHeader.y + browserHeader.height + 4, + modifiyModal: browserHeader.currentFavorite, + toolbarMode: true, + ogUrl: browserHeader.currentFavorite ? browserHeader.currentFavorite.url : _internal.currentWebView.url, + ogName: browserHeader.currentFavorite ? browserHeader.currentFavorite.name : _internal.currentWebView.title + }) + } + onLaunchInBrowser: { + // TODO: disable browsing local files? file:// + if (localAccountSensitiveSettings.useBrowserEthereumExplorer !== Constants.browserEthereumExplorerNone && url.startsWith("0x")) { + _internal.currentWebView.url = RootStore.get0xFormedUrl(localAccountSensitiveSettings.useBrowserEthereumExplorer, url) + return + } + if (localAccountSensitiveSettings.shouldShowBrowserSearchEngine !== Constants.browserSearchEngineNone && !Utils.isURL(url) && !Utils.isURLWithOptionalProtocol(url)) { + _internal.currentWebView.url = RootStore.getFormedUrl(localAccountSensitiveSettings.shouldShowBrowserSearchEngine, url) + return + } else if (Utils.isURLWithOptionalProtocol(url)) { + url = "https://" + url + } + _internal.currentWebView.url = _internal.determineRealURL(url); + } + } + + BrowserTabView { + id: tabs + anchors.top: parent.top + anchors.topMargin: Style.current.halfPadding + anchors.bottom: devToolsView.top + anchors.bottomMargin: browserHeader.height + anchors.left: parent.left + anchors.right: parent.right + z: 50 + tabComponent: webEngineView + currentWebEngineProfile: _internal.currentWebView.profile + determineRealURL: function(url) { + return _internal.determineRealURL(url) + } + onOpenNewTabTriggered: _internal.addNewTab() + Component.onCompleted: { + _internal.defaultProfile.downloadRequested.connect(_internal.onDownloadRequested); + _internal.otrProfile.downloadRequested.connect(_internal.onDownloadRequested); + var tab = createEmptyTab(_internal.defaultProfile); + // For Devs: Uncomment the next lien if you want to use the simpeldapp on first load + // tab.item.url = Web3ProviderStore.determineRealURL("https://simpledapp.eth"); + } + } + + ProgressBar { + id: progressBar + height: 3 + from: 0 + to: 100 + visible: value != 0 && value != 100 + value: (_internal.currentWebView && _internal.currentWebView.loadProgress < 100) ? _internal.currentWebView.loadProgress : 0 + anchors.bottom: parent.bottom + anchors.bottomMargin: Style.current.padding + anchors.right: parent.right + anchors.rightMargin: Style.current.padding + } + + WebEngineView { + id: devToolsView + visible: localAccountSensitiveSettings.devToolsEnabled + height: visible ? 400 : 0 + inspectedView: visible && tabs.currentIndex < tabs.count ? tabs.getTab(tabs.currentIndex).item : null + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + onNewViewRequested: function(request) { + var tab = tabs.createEmptyTab(_internal.currentWebView.profile); + tabs.currentIndex = tabs.count - 1; + request.openIn(tab.item); + } + z: 100 + } + + FavoriteMenu { + id: favoriteMenu + openInNewTab: function (url) { + browserWindow.openUrlInNewTab(url) + } + onEditFavoriteTriggered: { + Global.openPopup(addFavoriteModal, { + modifiyModal: true, + ogUrl: favoriteMenu.currentFavorite ? favoriteMenu.currentFavorite.url : _internal.currentWebView.url, + ogName: favoriteMenu.currentFavorite ? favoriteMenu.currentFavorite.name : _internal.currentWebView.title}) + } + } + DownloadBar { + id: downloadBar + anchors.bottom: parent.bottom + z: 60 + downloadsModel: DownloadsStore.downloadModel + downloadsMenu: downloadMenu + onOpenDownloadClicked: { + if (downloadComplete) { + return DownloadsStore.openFile(index) + } + DownloadsStore.openDirectory(index) + } + onAddNewDownloadTab: _internal.addNewDownloadTab() + } + + FindBar { + id: findBar + visible: false + anchors.right: parent.right + anchors.top: browserHeader.bottom + z: 60 + + onFindNext: { + if (text) + _internal.currentWebView && _internal.currentWebView.findText(text); + else if (!visible) + visible = true; + } + onFindPrevious: { + if (text) + _internal.currentWebView && _internal.currentWebView.findText(text, WebEngineView.FindBackward); + else if (!visible) + visible = true; + } + } + + Rectangle { + id: statusBubble + color: "oldlace" + property int padding: 8 + visible: false + + anchors.left: parent.left + anchors.bottom: parent.bottom + width: statusText.paintedWidth + padding + height: statusText.paintedHeight + padding + + Text { + id: statusText + anchors.centerIn: statusBubble + elide: Qt.ElideMiddle + + Timer { + id: hideStatusText + interval: 750 + onTriggered: { + statusText.text = ""; + statusBubble.visible = false; + } + } + } + } + + DownloadMenu { + id: downloadMenu + } + + BrowserSettingsMenu { + id: settingsMenu + x: parent.width - width + y: browserHeader.y + (localAccountSensitiveSettings.shouldShowFavoritesBar ? browserHeader.height - 38 : browserHeader.height) + isIncognito: _internal.currentWebView && _internal.currentWebView.profile === _internal.otrProfile + onAddNewTab: _internal.addNewTab() + onGoIncognito: { + if (_internal.currentWebView) { + _internal.currentWebView.profile = checked ? _internal.otrProfile : _internal.defaultProfile; + } + } + onZoomIn: { + const newZoom = _internal.currentWebView.zoomFactor + 0.1 + _internal.currentWebView.changeZoomFactor(newZoom) + } + onZoomOut: { + const newZoom = currentWebView.zoomFactor - 0.1 + _internal.currentWebView.changeZoomFactor(newZoom) + } + onChangeZoomFactor: _internal.currentWebView.changeZoomFactor(1.0) + onLaunchFindBar: { + if (!findBar.visible) { + findBar.visible = true; + findBar.forceActiveFocus() + } + } + onToggleCompatibilityMode: { + for (let i = 0; i < tabs.count; ++i){ + tabs.getTab(i).item.stop() // Stop all loading tabs + } + + localAccountSensitiveSettings.compatibilityMode = checked; + + for (let i = 0; i < tabs.count; ++i){ + tabs.getTab(i).item.reload() // Reload them with new user agent + } + } + onLaunchBrowserSettings: { + Global.changeAppSectionBySectionType(Constants.appSection.profile, Constants.settingsSubsection.browserSettings); + } + } + + BrowserWalletMenu { + id: browserWalletMenu + y: browserHeader.height + browserHeader.anchors.topMargin + x: parent.width - width - Style.current.halfPadding + onSendTriggered: { + sendTransactionModal.selectedAccount = selectedAccount + sendTransactionModal.open() + } + onReload: { + for (let i = 0; i < tabs.count; ++i){ + tabs.getTab(i).item.reload(); + } + } + onDisconnect: { + Web3ProviderStore.disconnect(Utils.getHostname(browserHeader.addressBar.text)) + provider.postMessage("web3-disconnect-account", "{}"); + _internal.currentWebView.reload() + close() + } } - z: 100 } Component { @@ -323,19 +468,6 @@ Rectangle { AddFavoriteModal {} } - FavoriteMenu { - id: favoriteMenu - openInNewTab: function (url) { - browserWindow.openUrlInNewTab(url) - } - onEditFavoriteTriggered: { - Global.openPopup(addFavoriteModal, { - modifiyModal: true, - ogUrl: favoriteMenu.currentFavorite ? favoriteMenu.currentFavorite.url : _internal.currentWebView.url, - ogName: favoriteMenu.currentFavorite ? favoriteMenu.currentFavorite.name : _internal.currentWebView.title}) - } - } - MessageDialog { id: sslDialog @@ -365,136 +497,6 @@ Rectangle { } } - DownloadBar { - id: downloadBar - anchors.bottom: parent.bottom - z: 60 - downloadsModel: DownloadsStore.downloadModel - downloadsMenu: downloadMenu - onOpenDownloadClicked: { - if (downloadComplete) { - return DownloadsStore.openFile(index) - } - DownloadsStore.openDirectory(index) - } - onAddNewDownloadTab: _internal.addNewDownloadTab() - } - - FindBar { - id: findBar - visible: false - anchors.right: parent.right - anchors.top: browserHeader.bottom - z: 60 - - onFindNext: { - if (text) - _internal.currentWebView && _internal.currentWebView.findText(text); - else if (!visible) - visible = true; - } - onFindPrevious: { - if (text) - _internal.currentWebView && _internal.currentWebView.findText(text, WebEngineView.FindBackward); - else if (!visible) - visible = true; - } - } - - Rectangle { - id: statusBubble - color: "oldlace" - property int padding: 8 - visible: false - - anchors.left: parent.left - anchors.bottom: parent.bottom - width: statusText.paintedWidth + padding - height: statusText.paintedHeight + padding - - Text { - id: statusText - anchors.centerIn: statusBubble - elide: Qt.ElideMiddle - - Timer { - id: hideStatusText - interval: 750 - onTriggered: { - statusText.text = ""; - statusBubble.visible = false; - } - } - } - } - - DownloadMenu { - id: downloadMenu - } - - BrowserSettingsMenu { - id: settingsMenu - x: parent.width - width - y: browserHeader.y + (localAccountSensitiveSettings.shouldShowFavoritesBar ? browserHeader.height - 38 : browserHeader.height) - isIncognito: _internal.currentWebView && _internal.currentWebView.profile === _internal.otrProfile - onAddNewTab: _internal.addNewTab() - onGoIncognito: { - if (_internal.currentWebView) { - _internal.currentWebView.profile = checked ? _internal.otrProfile : _internal.defaultProfile; - } - } - onZoomIn: { - const newZoom = _internal.currentWebView.zoomFactor + 0.1 - _internal.currentWebView.changeZoomFactor(newZoom) - } - onZoomOut: { - const newZoom = currentWebView.zoomFactor - 0.1 - _internal.currentWebView.changeZoomFactor(newZoom) - } - onChangeZoomFactor: _internal.currentWebView.changeZoomFactor(1.0) - onLaunchFindBar: { - if (!findBar.visible) { - findBar.visible = true; - findBar.forceActiveFocus() - } - } - onToggleCompatibilityMode: { - for (let i = 0; i < tabs.count; ++i){ - tabs.getTab(i).item.stop() // Stop all loading tabs - } - - localAccountSensitiveSettings.compatibilityMode = checked; - - for (let i = 0; i < tabs.count; ++i){ - tabs.getTab(i).item.reload() // Reload them with new user agent - } - } - onLaunchBrowserSettings: { - Global.changeAppSectionBySectionType(Constants.appSection.profile, Constants.settingsSubsection.browserSettings); - } - } - - BrowserWalletMenu { - id: browserWalletMenu - y: browserHeader.height + browserHeader.anchors.topMargin - x: parent.width - width - Style.current.halfPadding - onSendTriggered: { - sendTransactionModal.selectedAccount = selectedAccount - sendTransactionModal.open() - } - onReload: { - for (let i = 0; i < tabs.count; ++i){ - tabs.getTab(i).item.reload(); - } - } - onDisconnect: { - Web3ProviderStore.disconnect(Utils.getHostname(browserHeader.addressBar.text)) - provider.postMessage("web3-disconnect-account", "{}"); - _internal.currentWebView.reload() - close() - } - } - Menu { id: historyMenu Instantiator { @@ -570,10 +572,10 @@ Rectangle { request.openIn(backgroundTab.item); // Disabling popups temporarily since we need to set that webengineview settings / channel and other properties /*} else if (request.destination === WebEngineView.NewViewInDialog) { - var dialog = browserDialogComponent.createObject(); - dialog.currentWebView.profile = currentWebView.profile; - dialog.currentWebView.webChannel = channel; - request.openIn(dialog.currentWebView);*/ + var dialog = browserDialogComponent.createObject(); + dialog.currentWebView.profile = currentWebView.profile; + dialog.currentWebView.webChannel = channel; + request.openIn(dialog.currentWebView);*/ } else { // Instead of opening a new window, we open a new tab // TODO: remove "open in new window" from context menu @@ -588,7 +590,7 @@ Rectangle { } onJavaScriptDialogRequested: function(request) { request.accepted = true; - var dialog = _internal.jsDialogComponent.createObject(browserWindow, {"request": request}); + var dialog = _internal.jsDialogComponent.createObject(root, {"request": request}); dialog.open(); } } diff --git a/ui/app/AppLayouts/Chat/views/ChatColumnView.qml b/ui/app/AppLayouts/Chat/views/ChatColumnView.qml index 3446b979c0..8b8475dd15 100644 --- a/ui/app/AppLayouts/Chat/views/ChatColumnView.qml +++ b/ui/app/AppLayouts/Chat/views/ChatColumnView.qml @@ -24,7 +24,6 @@ import "../../Wallet" Item { id: root - anchors.fill: parent // Important: we have parent module in this context only cause qml components // don't follow struct we have on the backend. @@ -214,8 +213,6 @@ Item { sourceComponent: ChatContentView { visible: !root.rootStore.openCreateChat && isActiveChannel - width: parent.width - height: parent.height clip: true rootStore: root.rootStore contactsStore: root.contactsStore @@ -227,15 +224,10 @@ Item { stickersLoaded: root.stickersLoaded isBlocked: model.blocked isActiveChannel: categoryChatLoader.isActiveChannel - activityCenterVisible: Global.activityCenterPopupOpened - activityCenterNotificationsCount: root.rootStore.unreadNotificationsCount pinnedMessagesPopupComponent: root.pinnedMessagesListPopupComponent onOpenStickerPackPopup: { root.openStickerPackPopup(stickerPackId) } - onNotificationButtonClicked: { - Global.openActivityCenterPopup() - } onOpenAppSearch: { root.openAppSearch(); } @@ -271,8 +263,6 @@ Item { sourceComponent: ChatContentView { visible: !root.rootStore.openCreateChat && isActiveChannel - width: parent.width - height: parent.height clip: true rootStore: root.rootStore contactsStore: root.contactsStore @@ -284,15 +274,10 @@ Item { stickersLoaded: root.stickersLoaded isBlocked: model.blocked isActiveChannel: chatLoader.isActiveChannel - activityCenterVisible: Global.activityCenterPopupOpened - activityCenterNotificationsCount: root.rootStore.unreadNotificationsCount pinnedMessagesPopupComponent: root.pinnedMessagesListPopupComponent onOpenStickerPackPopup: { root.openStickerPackPopup(stickerPackId) } - onNotificationButtonClicked: { - Global.openActivityCenterPopup() - } onOpenAppSearch: { root.openAppSearch(); } diff --git a/ui/app/AppLayouts/Chat/views/ChatContentView.qml b/ui/app/AppLayouts/Chat/views/ChatContentView.qml index 4af6f1b581..d30023c2ad 100644 --- a/ui/app/AppLayouts/Chat/views/ChatContentView.qml +++ b/ui/app/AppLayouts/Chat/views/ChatContentView.qml @@ -37,8 +37,6 @@ ColumnLayout { property bool isActiveChannel: false property bool isConnected: false property var emojiPopup - property bool activityCenterVisible: false - property int activityCenterNotificationsCount property alias textInputField: chatInput property UsersStore usersStore: UsersStore {} property Component pinnedMessagesPopupComponent @@ -48,7 +46,6 @@ ColumnLayout { } signal openAppSearch() - signal notificationButtonClicked() signal openStickerPackPopup(string stickerPackId) property Component sendTransactionNoEnsModal @@ -67,250 +64,6 @@ ColumnLayout { } } - Keys.onEscapePressed: { topBar.toolbarComponent = statusChatInfoButton } - - // Chat toolbar content option 1: - Component { - id: statusChatInfoButton - - StatusChatInfoButton { - objectName: "chatInfoBtnInHeader" - width: Math.min(implicitWidth, parent.width) - title: chatContentModule? chatContentModule.chatDetails.name : "" - subTitle: { - if(!chatContentModule) - return "" - - // In some moment in future this should be part of the backend logic. - // (once we add transaltion on the backend side) - switch (chatContentModule.chatDetails.type) { - case Constants.chatType.oneToOne: - return (chatContentModule.isMyContact(chatContentModule.chatDetails.id) ? - qsTr("Contact") : - qsTr("Not a contact")) - case Constants.chatType.publicChat: - return qsTr("Public chat") - case Constants.chatType.privateGroupChat: - const cnt = root.usersStore.usersModule.model.count - return qsTr("%n members(s)", "", cnt) - case Constants.chatType.communityChat: - return StatusQUtils.Utils.linkifyAndXSS(chatContentModule.chatDetails.description).trim() - default: - return "" - } - } - image.source: chatContentModule? chatContentModule.chatDetails.icon : "" - ringSettings.ringSpecModel: chatContentModule && chatContentModule.chatDetails.type === Constants.chatType.oneToOne ? - Utils.getColorHashAsJson(chatContentModule.chatDetails.id) : "" - icon.color: chatContentModule? - chatContentModule.chatDetails.type === Constants.chatType.oneToOne ? - Utils.colorForPubkey(chatContentModule.chatDetails.id) - : chatContentModule.chatDetails.color - : "" - icon.emoji: chatContentModule? chatContentModule.chatDetails.emoji : "" - icon.emojiSize: "24x24" - type: chatContentModule? chatContentModule.chatDetails.type : Constants.chatType.unknown - pinnedMessagesCount: chatContentModule? chatContentModule.pinnedMessagesModel.count : 0 - muted: chatContentModule? chatContentModule.chatDetails.muted : false - - onPinnedMessagesCountClicked: { - if(!chatContentModule) { - console.debug("error on open pinned messages - chat content module is not set") - return - } - Global.openPopup(pinnedMessagesPopupComponent, { - store: rootStore, - messageStore: messageStore, - pinnedMessagesModel: chatContentModule.pinnedMessagesModel, - messageToPin: "" - }) - } - onUnmute: { - if(!chatContentModule) { - console.debug("error on unmute chat - chat content module is not set") - return - } - chatContentModule.unmuteChat() - } - - sensor.enabled: { - if(!chatContentModule) - return false - - return chatContentModule.chatDetails.type !== Constants.chatType.publicChat && - chatContentModule.chatDetails.type !== Constants.chatType.communityChat - } - onClicked: { - switch (chatContentModule.chatDetails.type) { - case Constants.chatType.privateGroupChat: - Global.openPopup(root.rootStore.groupInfoPopupComponent, { - chatContentModule: chatContentModule, - chatDetails: chatContentModule.chatDetails - }) - break; - case Constants.chatType.oneToOne: - Global.openProfilePopup(chatContentModule.chatDetails.id) - break; - } - } - } - } - - // Chat toolbar content option 2: - Component { - id: contactsSelector - GroupChatPanel { - sectionModule: root.chatSectionModule - chatContentModule: root.chatContentModule - rootStore: root.rootStore - maxHeight: root.height - - onPanelClosed: topBar.toolbarComponent = statusChatInfoButton - } - } - - StatusChatToolBar { - id: topBar - z: parent.z + 1 - Layout.fillWidth: true - toolbarComponent: statusChatInfoButton - - membersButton.visible: { - if(!chatContentModule || chatContentModule.chatDetails.type === Constants.chatType.publicChat) - return false - - return localAccountSensitiveSettings.showOnlineUsers && - chatContentModule.chatDetails.isUsersListAvailable - } - membersButton.highlighted: localAccountSensitiveSettings.expandUsersList - notificationButton.tooltip.offset: localAccountSensitiveSettings.expandUsersList && membersButton.visible ? 0 : 14 - - notificationCount: root.activityCenterNotificationsCount - - onSearchButtonClicked: root.openAppSearch() - - onMembersButtonClicked: localAccountSensitiveSettings.expandUsersList = !localAccountSensitiveSettings.expandUsersList - notificationButton.highlighted: root.activityCenterVisible - onNotificationButtonClicked: root.notificationButtonClicked() - - popupMenu: ChatContextMenuView { - objectName: "moreOptionsContextMenu" - emojiPopup: root.emojiPopup - openHandler: function () { - if(!chatContentModule) { - console.debug("error on open chat context menu handler - chat content module is not set") - return - } - currentFleet = chatContentModule.getCurrentFleet() - isCommunityChat = chatContentModule.chatDetails.belongsToCommunity - amIChatAdmin = chatContentModule.amIChatAdmin() - chatId = chatContentModule.chatDetails.id - chatName = chatContentModule.chatDetails.name - chatDescription = chatContentModule.chatDetails.description - chatEmoji = chatContentModule.chatDetails.emoji - chatColor = chatContentModule.chatDetails.color - chatIcon = chatContentModule.chatDetails.icon - chatType = chatContentModule.chatDetails.type - chatMuted = chatContentModule.chatDetails.muted - channelPosition = chatContentModule.chatDetails.position - } - - onMuteChat: { - if(!chatContentModule) { - console.debug("error on mute chat from context menu - chat content module is not set") - return - } - chatContentModule.muteChat() - } - - onUnmuteChat: { - if(!chatContentModule) { - console.debug("error on unmute chat from context menu - chat content module is not set") - return - } - chatContentModule.unmuteChat() - } - - onMarkAllMessagesRead: { - if(!chatContentModule) { - console.debug("error on mark all messages read from context menu - chat content module is not set") - return - } - chatContentModule.markAllMessagesRead() - } - - onClearChatHistory: { - if(!chatContentModule) { - console.debug("error on clear chat history from context menu - chat content module is not set") - return - } - chatContentModule.clearChatHistory() - } - - onRequestAllHistoricMessages: { - // Not Refactored Yet - Check in the `master` branch if this is applicable here. - } - - onLeaveChat: { - if(!chatContentModule) { - console.debug("error on leave chat from context menu - chat content module is not set") - return - } - chatContentModule.leaveChat() - } - - onDeleteCommunityChat: root.rootStore.removeCommunityChat(chatId) - - onDownloadMessages: { - if(!chatContentModule) { - console.debug("error on leave chat from context menu - chat content module is not set") - return - } - chatContentModule.downloadMessages(file) - } - - onDisplayProfilePopup: { - Global.openProfilePopup(publicKey) - } - - onDisplayGroupInfoPopup: { - Global.openPopup(root.rootStore.groupInfoPopupComponent, { - chatContentModule: chatContentModule, - chatDetails: chatContentModule.chatDetails - }) - } - - onEditCommunityChannel: { - root.rootStore.editCommunityChannel( - chatId, - newName, - newDescription, - newEmoji, - newColor, - newCategory, - channelPosition // TODO change this to the signal once it is modifiable - ) - } - onAddRemoveGroupMember: { - topBar.toolbarComponent = contactsSelector - } - onFetchMoreMessages: { - root.rootStore.messageStore.requestMoreMessages(); - } - onLeaveGroup: { - chatContentModule.leaveChat(); - } - onUpdateGroupChatDetails: { - root.rootStore.chatCommunitySectionModule.updateGroupChatDetails( - chatId, - groupName, - groupColor, - groupImage - ) - } - } - } - Rectangle { id: connectedStatusRect Layout.fillWidth: true diff --git a/ui/app/AppLayouts/Chat/views/ChatHeaderContentView.qml b/ui/app/AppLayouts/Chat/views/ChatHeaderContentView.qml new file mode 100644 index 0000000000..64d7045b5e --- /dev/null +++ b/ui/app/AppLayouts/Chat/views/ChatHeaderContentView.qml @@ -0,0 +1,339 @@ +import QtQuick 2.14 +import QtQuick.Controls 2.14 +import QtQuick.Layouts 1.13 + +import StatusQ.Core 0.1 +import StatusQ.Core.Theme 0.1 +import StatusQ.Controls 0.1 + +import utils 1.0 + +import "../panels" + +RowLayout { + id: root + spacing: padding / 2 + + property alias menuButton: menuButton + property alias membersButton: membersButton + property alias searchButton: searchButton + + property var rootStore + property var chatContentModule: root.rootStore.currentChatContentModule() + property int padding: 8 + + signal searchButtonClicked() + + Loader { + id: loader + sourceComponent: statusChatInfoButton + Layout.fillWidth: true + Layout.fillHeight: true + Layout.alignment: Qt.AlignLeft + Layout.leftMargin: padding + } + + RowLayout { + id: actionButtons + Layout.alignment: Qt.AlignRight + Layout.rightMargin: padding + spacing: 8 + + StatusFlatRoundButton { + id: searchButton + icon.name: "search" + type: StatusFlatRoundButton.Type.Secondary + onClicked: root.searchButtonClicked() + + // initializing the tooltip + tooltip.text: qsTr("Search") + tooltip.orientation: StatusToolTip.Orientation.Bottom + tooltip.y: parent.height + 12 + } + + StatusFlatRoundButton { + id: membersButton + visible: { + if(!chatContentModule || chatContentModule.chatDetails.type === Constants.chatType.publicChat) + return false + + return localAccountSensitiveSettings.showOnlineUsers && + chatContentModule.chatDetails.isUsersListAvailable + } + highlighted: localAccountSensitiveSettings.expandUsersList + icon.name: "group-chat" + type: StatusFlatRoundButton.Type.Secondary + onClicked: { + localAccountSensitiveSettings.expandUsersList = !localAccountSensitiveSettings.expandUsersList; + } + // initializing the tooltip + tooltip.text: qsTr("Members") + tooltip.orientation: StatusToolTip.Orientation.Bottom + tooltip.y: parent.height + 12 + } + + StatusFlatRoundButton { + id: menuButton + objectName: "chatToolbarMoreOptionsButton" + icon.name: "more" + type: StatusFlatRoundButton.Type.Secondary + + // initializing the tooltip + tooltip.visible: !!tooltip.text && menuButton.hovered && !contextMenu.opened + tooltip.text: qsTr("More") + tooltip.orientation: StatusToolTip.Orientation.Bottom + tooltip.y: parent.height + 12 + + property bool showMoreMenu: false + onClicked: { + menuButton.highlighted = true + + let originalOpenHandler = contextMenu.openHandler + let originalCloseHandler = contextMenu.closeHandler + + contextMenu.openHandler = function () { + if (!!originalOpenHandler) { + originalOpenHandler() + } + } + + contextMenu.closeHandler = function () { + menuButton.highlighted = false + if (!!originalCloseHandler) { + originalCloseHandler() + } + } + + contextMenu.openHandler = originalOpenHandler + contextMenu.popup(-contextMenu.width + menuButton.width, menuButton.height + 4) + } + + ChatContextMenuView { + id: contextMenu + objectName: "moreOptionsContextMenu" + emojiPopup: root.emojiPopup + openHandler: function () { + if(!chatContentModule) { + console.debug("error on open chat context menu handler - chat content module is not set") + return + } + currentFleet = chatContentModule.getCurrentFleet() + isCommunityChat = chatContentModule.chatDetails.belongsToCommunity + amIChatAdmin = chatContentModule.amIChatAdmin() + chatId = chatContentModule.chatDetails.id + chatName = chatContentModule.chatDetails.name + chatDescription = chatContentModule.chatDetails.description + chatEmoji = chatContentModule.chatDetails.emoji + chatColor = chatContentModule.chatDetails.color + chatType = chatContentModule.chatDetails.type + chatMuted = chatContentModule.chatDetails.muted + channelPosition = chatContentModule.chatDetails.position + } + + onMuteChat: { + if(!chatContentModule) { + console.debug("error on mute chat from context menu - chat content module is not set") + return + } + chatContentModule.muteChat() + } + + onUnmuteChat: { + if(!chatContentModule) { + console.debug("error on unmute chat from context menu - chat content module is not set") + return + } + chatContentModule.unmuteChat() + } + + onMarkAllMessagesRead: { + if(!chatContentModule) { + console.debug("error on mark all messages read from context menu - chat content module is not set") + return + } + chatContentModule.markAllMessagesRead() + } + + onClearChatHistory: { + if(!chatContentModule) { + console.debug("error on clear chat history from context menu - chat content module is not set") + return + } + chatContentModule.clearChatHistory() + } + + onRequestAllHistoricMessages: { + // Not Refactored Yet - Check in the `master` branch if this is applicable here. + } + + onLeaveChat: { + if(!chatContentModule) { + console.debug("error on leave chat from context menu - chat content module is not set") + return + } + chatContentModule.leaveChat() + } + + onDeleteCommunityChat: root.rootStore.removeCommunityChat(chatId) + + onDownloadMessages: { + if(!chatContentModule) { + console.debug("error on leave chat from context menu - chat content module is not set") + return + } + chatContentModule.downloadMessages(file) + } + + onDisplayProfilePopup: { + Global.openProfilePopup(publicKey) + } + + onDisplayGroupInfoPopup: { + Global.openPopup(root.rootStore.groupInfoPopupComponent, { + chatContentModule: chatContentModule, + chatDetails: chatContentModule.chatDetails + }) + } + + onEditCommunityChannel: { + root.rootStore.editCommunityChannel( + chatId, + newName, + newDescription, + newEmoji, + newColor, + newCategory, + channelPosition // TODO change this to the signal once it is modifiable + ) + } + onAddRemoveGroupMember: { + loader.sourceComponent = contactsSelector + } + onFetchMoreMessages: { + root.rootStore.messageStore.requestMoreMessages(); + } + onLeaveGroup: { + chatContentModule.leaveChat(); + } + onUpdateGroupChatDetails: { + root.rootStore.chatCommunitySectionModule.updateGroupChatDetails( + chatId, + groupName, + groupColor, + groupImage + ) + } + } + } + + Rectangle { + implicitWidth: 1 + implicitHeight: 24 + color: Theme.palette.directColor7 + Layout.alignment: Qt.AlignVCenter + visible: (menuButton.visible || membersButton.visible || searchButton.visible) + } + } + + Keys.onEscapePressed: { loader.sourceComponent = statusChatInfoButton } + + // Chat toolbar content option 1: + Component { + id: statusChatInfoButton + + StatusChatInfoButton { + objectName: "chatInfoBtnInHeader" + width: Math.min(implicitWidth, parent.width) + title: chatContentModule? chatContentModule.chatDetails.name : "" + subTitle: { + if(!chatContentModule) + return "" + + // In some moment in future this should be part of the backend logic. + // (once we add transaltion on the backend side) + switch (chatContentModule.chatDetails.type) { + case Constants.chatType.oneToOne: + return (chatContentModule.isMyContact(chatContentModule.chatDetails.id) ? + qsTr("Contact") : + qsTr("Not a contact")) + case Constants.chatType.publicChat: + return qsTr("Public chat") + case Constants.chatType.privateGroupChat: + let cnt = root.usersStore.usersModule.model.count + if(cnt > 1) return qsTr("%n member(s)", "", cnt); + return qsTr("1 member"); + case Constants.chatType.communityChat: + return Utils.linkifyAndXSS(chatContentModule.chatDetails.description).trim() + default: + return "" + } + } + image.source: chatContentModule? chatContentModule.chatDetails.icon : "" + ringSettings.ringSpecModel: chatContentModule && chatContentModule.chatDetails.type === Constants.chatType.oneToOne ? + Utils.getColorHashAsJson(chatContentModule.chatDetails.id) : "" + icon.color: chatContentModule? + chatContentModule.chatDetails.type === Constants.chatType.oneToOne ? + Utils.colorForPubkey(chatContentModule.chatDetails.id) + : chatContentModule.chatDetails.color + : "" + icon.emoji: chatContentModule? chatContentModule.chatDetails.emoji : "" + icon.emojiSize: "24x24" + type: chatContentModule? chatContentModule.chatDetails.type : Constants.chatType.unknown + pinnedMessagesCount: chatContentModule? chatContentModule.pinnedMessagesModel.count : 0 + muted: chatContentModule? chatContentModule.chatDetails.muted : false + + onPinnedMessagesCountClicked: { + if(!chatContentModule) { + console.debug("error on open pinned messages - chat content module is not set") + return + } + Global.openPopup(pinnedMessagesPopupComponent, { + store: rootStore, + messageStore: messageStore, + pinnedMessagesModel: chatContentModule.pinnedMessagesModel, + messageToPin: "" + }) + } + onUnmute: { + if(!chatContentModule) { + console.debug("error on unmute chat - chat content module is not set") + return + } + chatContentModule.unmuteChat() + } + + sensor.enabled: { + if(!chatContentModule) + return false + + return chatContentModule.chatDetails.type !== Constants.chatType.publicChat && + chatContentModule.chatDetails.type !== Constants.chatType.communityChat + } + onClicked: { + switch (chatContentModule.chatDetails.type) { + case Constants.chatType.privateGroupChat: + Global.openPopup(root.rootStore.groupInfoPopupComponent, { + chatContentModule: chatContentModule, + chatDetails: chatContentModule.chatDetails + }) + break; + case Constants.chatType.oneToOne: + Global.openProfilePopup(chatContentModule.chatDetails.id) + break; + } + } + } + } + + // Chat toolbar content option 2: + Component { + id: contactsSelector + GroupChatPanel { + sectionModule: root.chatSectionModule + chatContentModule: root.chatContentModule + rootStore: root.rootStore + maxHeight: root.height + onPanelClosed: loader.sourceComponent = statusChatInfoButton + } + } +} diff --git a/ui/app/AppLayouts/Chat/views/ChatView.qml b/ui/app/AppLayouts/Chat/views/ChatView.qml index 11264be72d..0929e49b59 100644 --- a/ui/app/AppLayouts/Chat/views/ChatView.qml +++ b/ui/app/AppLayouts/Chat/views/ChatView.qml @@ -11,6 +11,7 @@ import shared.views.chat 1.0 import StatusQ.Layout 0.1 import StatusQ.Popups 0.1 +import StatusQ.Controls 0.1 import "." import "../panels" @@ -20,7 +21,7 @@ import "../helpers" import "../controls" import "../stores" -StatusAppThreePanelLayout { +StatusSectionLayout { id: root property var contactsStore @@ -57,6 +58,18 @@ StatusAppThreePanelLayout { } } + notificationButton.tooltip.offset: localAccountSensitiveSettings.expandUsersList && headerContent.membersButton.visible ? 0 : 14 + notificationButton.highlighted: activityCenter.visible + onNotificationButtonClicked: Global.openActivityCenterPopup() + notificationCount: root.rootStore.unreadNotificationsCount + + headerContent: ChatHeaderContentView { + id: headerContent + visible: !!root.rootStore.currentChatContentModule() + rootStore: root.rootStore + onSearchButtonClicked: root.openAppSearch() + } + leftPanel: Loader { id: contactColumnLoader sourceComponent: root.rootStore.chatCommunitySectionModule.isCommunity()? @@ -66,6 +79,7 @@ StatusAppThreePanelLayout { centerPanel: ChatColumnView { id: chatColumn + anchors.fill: parent parentModule: root.rootStore.chatCommunitySectionModule rootStore: root.rootStore contactsStore: root.contactsStore @@ -82,8 +96,8 @@ StatusAppThreePanelLayout { showRightPanel: { if (root.rootStore.openCreateChat || - !localAccountSensitiveSettings.showOnlineUsers || - !localAccountSensitiveSettings.expandUsersList) { + !localAccountSensitiveSettings.showOnlineUsers || + !localAccountSensitiveSettings.expandUsersList) { return false } @@ -98,9 +112,7 @@ StatusAppThreePanelLayout { return chatContentModule.chatDetails.isUsersListAvailable } - rightPanel: userListComponent - - Component { + rightPanel: Component { id: userListComponent UserListPanel { rootStore: root.rootStore @@ -203,4 +215,17 @@ StatusAppThreePanelLayout { Component.onCompleted: { rootStore.groupInfoPopupComponent = groupInfoPopupComponent; } + + ActivityCenterPopup { + id: activityCenter + y: 56 + height: (root.height - 56) * 2 // TODO get screen size // Taken from old code top bar height was fixed there to 56 + store: root.rootStore + chatSectionModule: root.rootStore.currentChatContentModule() + messageContextMenu: MessageContextMenuView { + id: contextmenu + store: root.rootStore + reactionModel: root.rootStore.emojiReactionsModel + } + } } diff --git a/ui/app/AppLayouts/Chat/views/CommunitySettingsView.qml b/ui/app/AppLayouts/Chat/views/CommunitySettingsView.qml index 98d5ce40fb..f2d7cbd9cf 100644 --- a/ui/app/AppLayouts/Chat/views/CommunitySettingsView.qml +++ b/ui/app/AppLayouts/Chat/views/CommunitySettingsView.qml @@ -20,14 +20,16 @@ import "../panels/communities" import "../popups/community" import "../layouts" -StatusAppTwoPanelLayout { +StatusSectionLayout { id: root + notificationCount: root.rootStore.unreadNotificationsCount + onNotificationButtonClicked: Global.openActivityCenterPopup() // TODO: get this model from backend? property var settingsMenuModel: root.rootStore.communityPermissionsEnabled ? [{name: qsTr("Overview"), icon: "help"}, {name: qsTr("Members"), icon: "group-chat"}, {name: qsTr("Permissions"), icon: "objects"}] : - [{name: qsTr("Overview"), icon: "help"}, + [{name: qsTr("Overview"), icon: "help"}, {name: qsTr("Members"), icon: "group-chat"}] // TODO: Next community settings options: // {name: qsTr("Tokens"), icon: "token"}, @@ -122,9 +124,14 @@ StatusAppTwoPanelLayout { } } - rightPanel: Loader { + centerPanel: Loader { anchors.fill: parent - anchors.margins: 32 + //anchors.margins: 32 + anchors { + leftMargin: 28 + rightMargin: 16 + bottomMargin: 16 + } active: root.community sourceComponent: StackLayout { currentIndex: d.currentIndex diff --git a/ui/app/AppLayouts/CommunitiesPortal/CommunitiesPortalLayout.qml b/ui/app/AppLayouts/CommunitiesPortal/CommunitiesPortalLayout.qml index a4b1baa179..b9bc5b863f 100644 --- a/ui/app/AppLayouts/CommunitiesPortal/CommunitiesPortalLayout.qml +++ b/ui/app/AppLayouts/CommunitiesPortal/CommunitiesPortalLayout.qml @@ -8,6 +8,7 @@ import StatusQ.Controls 0.1 import StatusQ.Components 0.1 import StatusQ.Popups 0.1 import StatusQ.Popups.Dialog 0.1 +import StatusQ.Layout 0.1 import utils 1.0 import shared.popups 1.0 @@ -17,7 +18,7 @@ import "controls" import "stores" import "popups" -StatusScrollView { +StatusSectionLayout { id: root objectName: "communitiesPortalLayout" @@ -26,6 +27,9 @@ StatusScrollView { property var createCommunitiesPopup: createCommunitiesPopupComponent property int contentPrefferedWidth: 100 + notificationCount: root.communitiesStore.unreadNotificationsCount + onNotificationButtonClicked: Global.openActivityCenterPopup() + QtObject { id: d @@ -40,146 +44,155 @@ StatusScrollView { } } - contentHeight: column.height + d.layoutVMargin - contentWidth: root.contentPrefferedWidth - d.layoutHMargin + centerPanel: Item { + implicitWidth: parent.width + implicitHeight: parent.height + clip: true - ColumnLayout { - id: column - width: parent.width - spacing: 18 + StatusScrollView { + contentHeight: column.height + d.layoutVMargin + contentWidth: root.contentPrefferedWidth - d.layoutHMargin - StatusBaseText { - Layout.topMargin: d.layoutVMargin - Layout.leftMargin: d.layoutHMargin - text: qsTr("Find community") - font.weight: Font.Bold - font.pixelSize: d.titlePixelSize - color: Theme.palette.directColor1 - } + ColumnLayout { + id: column + width: parent.availableWidth + height: childrenRect.height - RowLayout { - implicitWidth: parent.width - implicitHeight: 38 - spacing: Style.current.bigPadding + spacing: 18 - StatusInput { - id: searcher - implicitWidth: 327 - Layout.leftMargin: d.layoutHMargin - Layout.alignment: Qt.AlignVCenter - enabled: false // Out of scope - placeholderText: qsTr("Search") - input.icon.name: "search" - leftPadding: 0 - rightPadding: 0 - topPadding: 0 - bottomPadding: 0 - minimumHeight: 36 - maximumHeight: 36 - text: d.searchText - onTextChanged: { - console.warn("TODO: Community Cards searcher algorithm.") - // 1. Filter Community Cards by title, description or tags category. - // 2. Once some filter is applyed, update main tags row only showing the tags that are part of the categories of the filtered Community Cards. + StatusBaseText { + Layout.leftMargin: d.layoutHMargin + text: qsTr("Find community") + font.weight: Font.Bold + font.pixelSize: d.titlePixelSize + color: Theme.palette.directColor1 } - } - // Just a row filler to fit design - Item { Layout.fillWidth: true } + RowLayout { + Layout.fillWidth: true + Layout.preferredHeight: 38 + spacing: Style.current.bigPadding - StatusButton { - id: importBtn - Layout.fillHeight: true - text: qsTr("Import using key") - onClicked: Global.openPopup(importCommunitiesPopupComponent) - } + StatusInput { + id: searcher + implicitWidth: 327 + Layout.leftMargin: d.layoutHMargin + Layout.alignment: Qt.AlignVCenter + enabled: false // Out of scope + placeholderText: qsTr("Search") + input.icon.name: "search" + leftPadding: 0 + rightPadding: 0 + topPadding: 0 + bottomPadding: 0 + minimumHeight: 36 + maximumHeight: 36 + text: d.searchText + onTextChanged: { + console.warn("TODO: Community Cards searcher algorithm.") + // 1. Filter Community Cards by title, description or tags category. + // 2. Once some filter is applyed, update main tags row only showing the tags that are part of the categories of the filtered Community Cards. + } + } - StatusButton { - id: createBtn - objectName: "createCommunityButton" - Layout.fillHeight: true - text: qsTr("Create New Community") - onClicked: { - if (localAccountSensitiveSettings.isDiscordImportToolEnabled) { - Global.openPopup(chooseCommunityCreationTypePopupComponent) - } else { - Global.openPopup(createCommunitiesPopupComponent) + // Just a row filler to fit design + Item { Layout.fillWidth: true } + + StatusButton { + id: importBtn + Layout.fillHeight: true + text: qsTr("Import using key") + onClicked: Global.openPopup(importCommunitiesPopupComponent) + } + + StatusButton { + id: createBtn + objectName: "createCommunityButton" + Layout.fillHeight: true + text: qsTr("Create New Community") + onClicked: { + if (localAccountSensitiveSettings.isDiscordImportToolEnabled) { + Global.openPopup(chooseCommunityCreationTypePopupComponent) + } else { + Global.openPopup(createCommunitiesPopupComponent) + } + } } } - } - } - CommunityTagsRow { - tags: root.communitiesStore.communityTags - Layout.leftMargin: d.layoutHMargin - Layout.fillWidth: true - } - - StatusBaseText { - Layout.leftMargin: d.layoutHMargin - Layout.topMargin: 20 - text: qsTr("Featured") - font.weight: Font.Bold - font.pixelSize: d.subtitlePixelSize - color: Theme.palette.directColor1 - } - - GridLayout { - id: featuredGrid - Layout.leftMargin: d.layoutHMargin - columns: 3 - columnSpacing: Style.current.padding - rowSpacing: Style.current.padding - - Repeater { - model: root.communitiesStore.curatedCommunitiesModel - delegate: StatusCommunityCard { - visible: model.featured - locale: communitiesStore.locale - communityId: model.id - loaded: model.available - logo: model.icon - name: model.name - description: model.description - members: model.members - popularity: model.popularity - // categories: model.categories - - onClicked: { d.navigateToCommunity(communityId) } + CommunityTagsRow { + tags: root.communitiesStore.communityTags + Layout.leftMargin: d.layoutHMargin + Layout.fillWidth: true } - } - } - StatusBaseText { - Layout.leftMargin: d.layoutHMargin - Layout.topMargin: 20 - text: qsTr("Popular") - font.weight: Font.Bold - font.pixelSize: d.subtitlePixelSize - color: Theme.palette.directColor1 - } + StatusBaseText { + Layout.leftMargin: d.layoutHMargin + Layout.topMargin: 20 + text: qsTr("Featured") + font.weight: Font.Bold + font.pixelSize: d.subtitlePixelSize + color: Theme.palette.directColor1 + } - GridLayout { - Layout.leftMargin: d.layoutHMargin - columns: 3 - columnSpacing: Style.current.padding - rowSpacing: Style.current.padding + GridLayout { + id: featuredGrid + Layout.leftMargin: d.layoutHMargin + columns: 3 + columnSpacing: Style.current.padding + rowSpacing: Style.current.padding - Repeater { - model: root.communitiesStore.curatedCommunitiesModel - delegate: StatusCommunityCard { - visible: !model.featured - locale: communitiesStore.locale - communityId: model.id - loaded: model.available - logo: model.icon - name: model.name - description: model.description - members: model.members - popularity: model.popularity - // categories: model.categories + Repeater { + model: root.communitiesStore.curatedCommunitiesModel + delegate: StatusCommunityCard { + visible: model.featured + locale: communitiesStore.locale + communityId: model.id + loaded: model.available + logo: model.icon + name: model.name + description: model.description + members: model.members + popularity: model.popularity + // categories: model.categories - onClicked: { d.navigateToCommunity(communityId) } + onClicked: { d.navigateToCommunity(communityId) } + } + } + } + + StatusBaseText { + Layout.leftMargin: d.layoutHMargin + Layout.topMargin: 20 + text: qsTr("Popular") + font.weight: Font.Bold + font.pixelSize: d.subtitlePixelSize + color: Theme.palette.directColor1 + } + + GridLayout { + Layout.leftMargin: d.layoutHMargin + columns: 3 + columnSpacing: Style.current.padding + rowSpacing: Style.current.padding + + Repeater { + model: root.communitiesStore.curatedCommunitiesModel + delegate: StatusCommunityCard { + visible: !model.featured + locale: communitiesStore.locale + communityId: model.id + loaded: model.available + logo: model.icon + name: model.name + description: model.description + members: model.members + popularity: model.popularity + // categories: model.categories + + onClicked: { d.navigateToCommunity(communityId) } + } + } } } } diff --git a/ui/app/AppLayouts/CommunitiesPortal/stores/CommunitiesStore.qml b/ui/app/AppLayouts/CommunitiesPortal/stores/CommunitiesStore.qml index 9eab8d66e2..0d4d196d65 100644 --- a/ui/app/AppLayouts/CommunitiesPortal/stores/CommunitiesStore.qml +++ b/ui/app/AppLayouts/CommunitiesPortal/stores/CommunitiesStore.qml @@ -17,6 +17,7 @@ QtObject { property var advancedModule: profileSectionModule.advancedModule property bool isCommunityHistoryArchiveSupportEnabled: advancedModule? advancedModule.isCommunityHistoryArchiveSupportEnabled : false + property int unreadNotificationsCount: activityCenterList.unreadCount // TODO: Could the backend provide directly 2 filtered models?? //property var featuredCommunitiesModel: root.communitiesModuleInst.curatedFeaturedCommunities //property var popularCommunitiesModel: root.communitiesModuleInst.curatedPopularCommunities diff --git a/ui/app/AppLayouts/Node/NodeLayout.qml b/ui/app/AppLayouts/Node/NodeLayout.qml index f134ac5da6..25ca3c7fd0 100644 --- a/ui/app/AppLayouts/Node/NodeLayout.qml +++ b/ui/app/AppLayouts/Node/NodeLayout.qml @@ -2,6 +2,7 @@ import QtQuick 2.13 import QtQuick.Controls 2.13 import QtQuick.Layouts 1.13 +import StatusQ.Layout 0.1 import StatusQ.Core 0.1 import StatusQ.Core.Theme 0.1 @@ -13,14 +14,14 @@ import shared.controls 1.0 import "stores" import "views" -Item { +StatusSectionLayout { id: root - Layout.fillHeight: true - Layout.fillWidth: true property RootStore store: RootStore {} - ColumnLayout { + notificationCount: root.store.unreadNotificationsCount + onNotificationButtonClicked: Global.openActivityCenterPopup() + centerPanel: ColumnLayout { id: rpcColumn spacing: 0 anchors.fill: parent diff --git a/ui/app/AppLayouts/Node/stores/RootStore.qml b/ui/app/AppLayouts/Node/stores/RootStore.qml index cb58072c1d..39da65b4cb 100644 --- a/ui/app/AppLayouts/Node/stores/RootStore.qml +++ b/ui/app/AppLayouts/Node/stores/RootStore.qml @@ -5,6 +5,7 @@ import utils 1.0 QtObject { id: root + property int unreadNotificationsCount: activityCenterList.unreadCount property var nodeModelInst: nodeModel // property var profileModelInst: profileModel diff --git a/ui/app/AppLayouts/Profile/ProfileLayout.qml b/ui/app/AppLayouts/Profile/ProfileLayout.qml index bbd3c386a5..86635ae45e 100644 --- a/ui/app/AppLayouts/Profile/ProfileLayout.qml +++ b/ui/app/AppLayouts/Profile/ProfileLayout.qml @@ -13,14 +13,16 @@ import "views" import StatusQ.Layout 0.1 import StatusQ.Controls 0.1 -StatusAppTwoPanelLayout { - id: profileView +StatusSectionLayout { + id: root property ProfileSectionStore store property var globalStore property var systemPalette property var emojiPopup + notificationCount: root.store.unreadNotificationsCount + onNotificationButtonClicked: Global.openActivityCenterPopup() Component.onCompleted: { Global.privacyModuleInst = store.privacyStore.privacyModule } @@ -38,7 +40,7 @@ StatusAppTwoPanelLayout { leftPanel: LeftTabView { id: leftTab - store: profileView.store + store: root.store anchors.fill: parent anchors.topMargin: d.topMargin onMenuItemClicked: { @@ -49,16 +51,42 @@ StatusAppTwoPanelLayout { } } - rightPanel: Item { + 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 && - profileView.store.walletStore.areTestNetworksEnabled + root.store.walletStore.areTestNetworksEnabled type: StatusBanner.Type.Danger statusText: qsTr("Testnet mode is enabled. All balances, transactions and dApp interactions will be on testnets.") } @@ -72,7 +100,6 @@ StatusAppTwoPanelLayout { anchors.left: parent.left anchors.right: parent.right anchors.bottom: parent.bottom - anchors.topMargin: d.topMargin anchors.bottomMargin: d.bottomMargin anchors.leftMargin: d.leftMargin anchors.rightMargin: d.rightMargin @@ -89,20 +116,20 @@ StatusAppTwoPanelLayout { implicitWidth: parent.width implicitHeight: parent.height - walletStore: profileView.store.walletStore - profileStore: profileView.store.profileStore - privacyStore: profileView.store.privacyStore - sectionTitle: profileView.store.getNameForSubsection(Constants.settingsSubsection.profile) + walletStore: root.store.walletStore + profileStore: root.store.profileStore + privacyStore: root.store.privacyStore + sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.profile) contentWidth: d.contentWidth } ContactsView { implicitWidth: parent.width implicitHeight: parent.height - contactsStore: profileView.store.contactsStore + contactsStore: root.store.contactsStore sectionTitle: qsTr("Contacts") contentWidth: d.contentWidth - backButtonName: profileView.store.getNameForSubsection(Constants.settingsSubsection.messaging) + backButtonName: root.store.getNameForSubsection(Constants.settingsSubsection.messaging) onBackButtonClicked: { Global.changeAppSectionBySectionType(Constants.appSection.profile, Constants.settingsSubsection.messaging) @@ -117,9 +144,9 @@ StatusAppTwoPanelLayout { implicitWidth: parent.width implicitHeight: parent.height - ensUsernamesStore: profileView.store.ensUsernamesStore - contactsStore: profileView.store.contactsStore - stickersStore: profileView.store.stickersStore + ensUsernamesStore: root.store.ensUsernamesStore + contactsStore: root.store.contactsStore + stickersStore: root.store.stickersStore profileContentWidth: d.contentWidth } @@ -127,11 +154,10 @@ StatusAppTwoPanelLayout { MessagingView { implicitWidth: parent.width implicitHeight: parent.height - - messagingStore: profileView.store.messagingStore - advancedStore: profileView.store.advancedStore - sectionTitle: profileView.store.getNameForSubsection(Constants.settingsSubsection.messaging) - contactsStore: profileView.store.contactsStore + advancedStore: root.store.advancedStore + messagingStore: root.store.messagingStore + sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.messaging) + contactsStore: root.store.contactsStore contentWidth: d.contentWidth } @@ -139,9 +165,9 @@ StatusAppTwoPanelLayout { implicitWidth: parent.width implicitHeight: parent.height - walletStore: profileView.store.walletStore - emojiPopup: profileView.emojiPopup - sectionTitle: profileView.store.getNameForSubsection(Constants.settingsSubsection.wallet) + walletStore: root.store.walletStore + emojiPopup: root.emojiPopup + sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.wallet) contentWidth: d.contentWidth } @@ -149,19 +175,19 @@ StatusAppTwoPanelLayout { implicitWidth: parent.width implicitHeight: parent.height - appearanceStore: profileView.store.appearanceStore - sectionTitle: profileView.store.getNameForSubsection(Constants.settingsSubsection.appearance) + appearanceStore: root.store.appearanceStore + sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.appearance) contentWidth: d.contentWidth - systemPalette: profileView.systemPalette + systemPalette: root.systemPalette } LanguageView { implicitWidth: parent.width implicitHeight: parent.height - languageStore: profileView.store.languageStore - currencyStore: profileView.store.walletStore.currencyStore - sectionTitle: profileView.store.getNameForSubsection(Constants.settingsSubsection.language) + languageStore: root.store.languageStore + currencyStore: root.store.walletStore.currencyStore + sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.language) contentWidth: d.contentWidth } @@ -169,9 +195,9 @@ StatusAppTwoPanelLayout { implicitWidth: parent.width implicitHeight: parent.height - notificationsStore: profileView.store.notificationsStore - devicesStore: profileView.store.devicesStore - sectionTitle: profileView.store.getNameForSubsection(Constants.settingsSubsection.notifications) + notificationsStore: root.store.notificationsStore + devicesStore: root.store.devicesStore + sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.notifications) contentWidth: d.contentWidth } @@ -179,8 +205,8 @@ StatusAppTwoPanelLayout { implicitWidth: parent.width implicitHeight: parent.height - devicesStore: profileView.store.devicesStore - sectionTitle: profileView.store.getNameForSubsection(Constants.settingsSubsection.devicesSettings) + devicesStore: root.store.devicesStore + sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.devicesSettings) contentWidth: d.contentWidth } @@ -188,8 +214,8 @@ StatusAppTwoPanelLayout { implicitWidth: parent.width implicitHeight: parent.height - store: profileView.store - sectionTitle: profileView.store.getNameForSubsection(Constants.settingsSubsection.browserSettings) + store: root.store + sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.browserSettings) contentWidth: d.contentWidth } @@ -197,8 +223,8 @@ StatusAppTwoPanelLayout { implicitWidth: parent.width implicitHeight: parent.height - advancedStore: profileView.store.advancedStore - sectionTitle: profileView.store.getNameForSubsection(Constants.settingsSubsection.advanced) + advancedStore: root.store.advancedStore + sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.advanced) contentWidth: d.contentWidth } @@ -206,9 +232,9 @@ StatusAppTwoPanelLayout { implicitWidth: parent.width implicitHeight: parent.height - store: profileView.store - globalStore: profileView.globalStore - sectionTitle: profileView.store.getNameForSubsection(Constants.settingsSubsection.about) + store: root.store + globalStore: root.globalStore + sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.about) contentWidth: d.contentWidth } @@ -216,10 +242,10 @@ StatusAppTwoPanelLayout { implicitWidth: parent.width implicitHeight: parent.height - profileSectionStore: profileView.store - rootStore: profileView.globalStore - contactStore: profileView.store.contactsStore - sectionTitle: profileView.store.getNameForSubsection(Constants.settingsSubsection.communitiesSettings) + profileSectionStore: root.store + rootStore: root.globalStore + contactStore: root.store.contactsStore + sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.communitiesSettings) contentWidth: d.contentWidth } @@ -233,30 +259,5 @@ StatusAppTwoPanelLayout { } } } // Item - ModuleWarning { - id: secureYourSeedPhrase - width: parent.width - visible: { - if (profileContainer.currentIndex !== Constants.settingsSubsection.profile) { - return false - } - if (profileView.store.profileStore.userDeclinedBackupBanner) { - return false - } - return !profileView.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: { - profileView.store.profileStore.userDeclinedBackupBanner = true - } - - } } // StatusAppTwoPanelLayout diff --git a/ui/app/AppLayouts/Profile/stores/ProfileSectionStore.qml b/ui/app/AppLayouts/Profile/stores/ProfileSectionStore.qml index 3c67f3ed18..629edec3cf 100644 --- a/ui/app/AppLayouts/Profile/stores/ProfileSectionStore.qml +++ b/ui/app/AppLayouts/Profile/stores/ProfileSectionStore.qml @@ -5,6 +5,7 @@ import AppLayouts.Chat.stores 1.0 QtObject { id: root + property int unreadNotificationsCount: activityCenterList.unreadCount property var aboutModuleInst: aboutModule diff --git a/ui/app/AppLayouts/Wallet/WalletLayout.qml b/ui/app/AppLayouts/Wallet/WalletLayout.qml index 755d0ae01c..3bc7f189ba 100644 --- a/ui/app/AppLayouts/Wallet/WalletLayout.qml +++ b/ui/app/AppLayouts/Wallet/WalletLayout.qml @@ -13,7 +13,7 @@ import "views" import "stores" Item { - id: walletView + id: root property bool hideSignPhraseModal: false property var store @@ -45,25 +45,27 @@ Item { anchors.top: parent ? parent.top: undefined anchors.left: parent ? parent.left: undefined anchors.right: parent ? parent.right: undefined - contactsStore: walletView.contactsStore - sendModal: walletView.sendModal + contactsStore: root.contactsStore + sendModal: root.sendModal } } Component { id: walletContainer RightTabView { - store: walletView.store - sendModal: walletView.sendModal + store: root.store + sendModal: root.sendModal } } - StatusAppTwoPanelLayout { + StatusSectionLayout { anchors.top: seedPhraseWarning.bottom - height: walletView.height - seedPhraseWarning.height - width: walletView.width + height: root.height - seedPhraseWarning.height + width: root.width + notificationCount: RootStore.unreadNotificationsCount + onNotificationButtonClicked: Global.openActivityCenterPopup() Component.onCompleted: { // Read in RootStore // if(RootStore.firstTimeLogin){ @@ -96,13 +98,12 @@ Item { else rightPanelStackView.replace(walletContainer) } - emojiPopup: walletView.emojiPopup + emojiPopup: root.emojiPopup } - rightPanel: StackView { + centerPanel: StackView { id: rightPanelStackView anchors.fill: parent - anchors.topMargin: 49 anchors.leftMargin: 49 anchors.rightMargin: 49 initialItem: walletContainer diff --git a/ui/app/AppLayouts/Wallet/panels/SeedPhraseBackupWarning.qml b/ui/app/AppLayouts/Wallet/panels/SeedPhraseBackupWarning.qml index 5dd1eabada..7e2a4feed3 100644 --- a/ui/app/AppLayouts/Wallet/panels/SeedPhraseBackupWarning.qml +++ b/ui/app/AppLayouts/Wallet/panels/SeedPhraseBackupWarning.qml @@ -10,8 +10,8 @@ import "../stores" Rectangle { id: root - visible: !RootStore.mnemonicBackedUp height: visible ? 32 : 0 + visible: !RootStore.mnemonicBackedUp color: Style.current.red Row { @@ -61,8 +61,7 @@ Rectangle { SVGImage { id: closeImg - anchors.top: parent.top - anchors.topMargin: 6 + anchors.verticalCenter: parent.verticalCenter anchors.right: parent.right anchors.rightMargin: 18 source: Style.svg("close-white") diff --git a/ui/app/AppLayouts/Wallet/stores/RootStore.qml b/ui/app/AppLayouts/Wallet/stores/RootStore.qml index 8191300ea6..c3d7cd1f8b 100644 --- a/ui/app/AppLayouts/Wallet/stores/RootStore.qml +++ b/ui/app/AppLayouts/Wallet/stores/RootStore.qml @@ -7,6 +7,8 @@ import shared.stores 1.0 as SharedStore QtObject { id: root + + property int unreadNotificationsCount: activityCenterList.unreadCount property var currentAccount: Constants.isCppApp ? walletSectionAccounts.currentAccount: walletSectionCurrent property var accounts: walletSectionAccounts.model property var generatedAccounts: walletSectionAccounts.generated diff --git a/ui/app/mainui/AppMain.qml b/ui/app/mainui/AppMain.qml index 14090b92c2..0b86e11a89 100644 --- a/ui/app/mainui/AppMain.qml +++ b/ui/app/mainui/AppMain.qml @@ -227,13 +227,12 @@ Item { height: 440 } - StatusAppLayout { + StatusMainLayout { id: appLayout anchors.fill: parent - appNavBar: StatusAppNavBar { - height: parent.height + leftPanel: StatusAppNavBar { communityTypeRole: "sectionType" communityTypeValue: Constants.appSection.community sectionModel: mainModule.sectionsModel @@ -396,9 +395,8 @@ Item { } } - appView: ColumnLayout { - anchors.fill: parent - + rightPanel: ColumnLayout { + spacing: 0 ModuleWarning { id: versionWarning width: parent.width @@ -452,7 +450,6 @@ Item { StackLayout { id: appView - anchors.fill: parent currentIndex: { @@ -520,7 +517,6 @@ Item { ChatLayout { id: chatLayoutContainer Layout.fillWidth: true - Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillHeight: true chatView.pinnedMessagesListPopupComponent: pinnedMessagesPopupComponent @@ -554,7 +550,6 @@ Item { CommunitiesPortalLayout { id: communitiesPortalLayoutContainer Layout.fillWidth: true - Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillHeight: true contentPrefferedWidth: appView.width } @@ -562,7 +557,6 @@ Item { WalletLayout { id: walletLayoutContainer Layout.fillWidth: true - Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillHeight: true store: appMain.rootStore contactsStore: appMain.rootStore.profileSectionStore.contactsStore @@ -583,7 +577,6 @@ Item { sourceComponent: browserLayoutComponent active: false Layout.fillWidth: true - Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillHeight: true // Loaders do not have access to the context, so props need to be set // Adding a "_" to avoid a binding loop @@ -599,7 +592,6 @@ Item { ProfileLayout { id: profileLayoutContainer Layout.fillWidth: true - Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillHeight: true store: appMain.rootStore.profileSectionStore @@ -611,7 +603,6 @@ Item { NodeLayout { id: nodeLayoutContainer Layout.fillWidth: true - Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.fillHeight: true }