parent
b1259a83f4
commit
b6ff7b9ded
|
@ -1 +1 @@
|
|||
Subproject commit 80a9cc9b3face23df65e7630afe5339a8acf8072
|
||||
Subproject commit ecc44cfae0f3c06cad5e3f3d7c94f4d1488fdf9b
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
// <out of scope> 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
|
||||
// <out of scope> 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
|
||||
// <out of scope> 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
|
||||
// <out of scope> categories: model.categories
|
||||
|
||||
onClicked: { d.navigateToCommunity(communityId) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -5,6 +5,7 @@ import utils 1.0
|
|||
QtObject {
|
||||
id: root
|
||||
|
||||
property int unreadNotificationsCount: activityCenterList.unreadCount
|
||||
property var nodeModelInst: nodeModel
|
||||
// property var profileModelInst: profileModel
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -5,6 +5,7 @@ import AppLayouts.Chat.stores 1.0
|
|||
|
||||
QtObject {
|
||||
id: root
|
||||
property int unreadNotificationsCount: activityCenterList.unreadCount
|
||||
|
||||
property var aboutModuleInst: aboutModule
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue