Skip to content

Commit c672022

Browse files
committed
feat: activities in a browser wallet
1 parent 7a001af commit c672022

File tree

16 files changed

+269
-58
lines changed

16 files changed

+269
-58
lines changed

src/app/modules/main/browser_section/module.nim

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import ../../../../app_service/service/dapp_permissions/service as dapp_permissi
1414
import ../../../../app_service/service/wallet_account/service as wallet_account_service
1515
import ../../../../app_service/service/token/service as token_service
1616
import ../../../../app_service/service/currency/service as currency_service
17+
import ../../../../app_service/service/saved_address/service as saved_address_service
18+
import ../wallet_section/activity/controller as activity_controller
1719

1820
export io_interface
1921

@@ -27,6 +29,7 @@ type
2729
bookmarkModule: bookmark_module.AccessInterface
2830
dappsModule: dapps_module.AccessInterface
2931
currentAccountModule: current_account_module.AccessInterface
32+
activityController: activity_controller.Controller
3033

3134
proc newModule*(delegate: delegate_interface.AccessInterface,
3235
events: EventEmitter,
@@ -36,12 +39,19 @@ proc newModule*(delegate: delegate_interface.AccessInterface,
3639
dappPermissionsService: dapp_permissions_service.Service,
3740
walletAccountService: wallet_account_service.Service,
3841
tokenService: token_service.Service,
39-
currencyService: currency_service.Service
42+
currencyService: currency_service.Service,
43+
savedAddressService: saved_address_service.Service
4044
): Module =
4145
result = Module()
4246
result.delegate = delegate
4347
result.events = events
44-
result.view = view.newView(result)
48+
result.activityController = activity_controller.newController(
49+
currencyService,
50+
tokenService,
51+
savedAddressService,
52+
networkService,
53+
events)
54+
result.view = view.newView(result, result.activityController)
4555
result.viewVariant = newQVariant(result.view)
4656
result.moduleLoaded = false
4757
result.bookmarkModule = bookmark_module.newModule(result, events, bookmarkService)
@@ -51,6 +61,7 @@ proc newModule*(delegate: delegate_interface.AccessInterface,
5161
method delete*(self: Module) =
5262
self.view.delete
5363
self.viewVariant.delete
64+
self.activityController.delete
5465
self.bookmarkModule.delete
5566
self.dappsModule.delete
5667
self.currentAccountModule.delete

src/app/modules/main/browser_section/view.nim

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
import nimqml
22
import io_interface
3+
import ../wallet_section/activity/controller as activity_controller
34

45
QtObject:
56
type
67
View* = ref object of QObject
78
delegate: io_interface.AccessInterface
9+
activityController: activity_controller.Controller
810

911
proc setup(self: View)
1012
proc delete*(self: View)
11-
proc newView*(delegate: io_interface.AccessInterface): View =
13+
proc newView*(delegate: io_interface.AccessInterface,
14+
activityController: activity_controller.Controller): View =
1215
new(result, delete)
1316
result.delegate = delegate
17+
result.activityController = activityController
1418
result.setup()
1519

1620
proc load*(self: View) =
@@ -20,6 +24,12 @@ QtObject:
2024
proc sendOpenUrlSignal*(self: View, url: string) =
2125
self.openUrl(url)
2226

27+
proc getActivityController*(self: View): QVariant {.slot.} =
28+
return newQVariant(self.activityController)
29+
30+
QtProperty[QVariant] activityController:
31+
read = getActivityController
32+
2333
proc setup(self: View) =
2434
self.QObject.setup
2535

src/app/modules/main/module.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ proc newModule*[T](
227227
result.browserSectionModule = browser_section_module.newModule(
228228
result, events, bookmarkService, settingsService, networkService,
229229
dappPermissionsService, walletAccountService,
230-
tokenService, currencyService
230+
tokenService, currencyService, savedAddressService
231231
)
232232
result.profileSectionModule = profile_section_module.newModule(
233233
result, events, accountsService, settingsService, stickersService,

storybook/pages/TransactionDelegatePage.qml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ SplitView {
9494
}
9595
}
9696
flatNetworks: NetworksModel.flatNetworks
97-
walletRootStore: WalletStores.RootStore
97+
activityStore: WalletStores.RootStore
9898
}
9999
}
100100
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import QtQuick
2+
3+
QtObject {
4+
id: root
5+
6+
required property var browserWalletStore
7+
8+
readonly property var activityController: browserSection.activityController
9+
10+
readonly property string selectedAddress: browserWalletStore.dappBrowserAccount.address
11+
readonly property bool isNonArchivalNode: false
12+
readonly property bool showAllAccounts: false
13+
readonly property var transactionActivityStatus: activityController.status
14+
readonly property bool loadingHistoryTransactions: activityController.status.loadingData
15+
readonly property bool newDataAvailable: activityController.status.newDataAvailable
16+
17+
readonly property var historyTransactions: activityController.model
18+
19+
readonly property QtObject currentActivityFiltersStore: QtObject {
20+
readonly property bool filtersSet: false
21+
22+
function applyAllFilters() {}
23+
function updateCollectiblesModel() {}
24+
function updateRecipientsModel() {}
25+
}
26+
27+
function updateTransactionFilterIfDirty() {}
28+
function fetchMoreTransactions() {}
29+
function resetActivityData() {}
30+
function getEtherscanLink(chainID) { return "" }
31+
function getTransactionType(transaction) { return 0 }
32+
function getNameForAddress(address) { return "" }
33+
function getDappDetails(chainId, contractAddress) { return undefined }
34+
function isOwnedAccount(address) { return true }
35+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
BrowserRootStore 1.0 BrowserRootStore.qml
22
BrowserWalletStore 1.0 BrowserWalletStore.qml
3+
BrowserActivityStore 1.0 BrowserActivityStore.qml
34
BookmarksStore 1.0 BookmarksStore.qml
45
DownloadsStore 1.0 DownloadsStore.qml
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import QtQuick
2+
3+
// Required mock of: src/app/modules/main/browser_section/view.nim
4+
5+
Item {
6+
readonly property string contextPropertyName: "browserSection"
7+
8+
readonly property QtObject activityController: QtObject {
9+
readonly property QtObject model: QtObject {
10+
readonly property int count: 0
11+
readonly property bool hasMore: false
12+
}
13+
readonly property QtObject status: QtObject {
14+
readonly property bool loadingData: false
15+
readonly property bool isFilterDirty: false
16+
readonly property bool newDataAvailable: false
17+
readonly property int errorCode: 0
18+
}
19+
20+
function setFilterAddressesJson(addresses) {}
21+
function setFilterChainsJson(chains, allEnabled) {}
22+
function newFilterSession() {}
23+
function loadMoreItems() {}
24+
function updateFilter() {}
25+
function resetActivityData() {}
26+
function updateCollectiblesModel() {}
27+
function updateRecipientsModel() {}
28+
}
29+
}

ui/app/AppLayouts/Browser/popups/BrowserWalletMenu.qml

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,13 @@ import StatusQ
77
import StatusQ.Controls
88
import StatusQ.Core
99
import StatusQ.Core.Theme
10+
import StatusQ.Core.Utils as SQUtils
11+
12+
import SortFilterProxyModel
1013

1114
import shared.controls
1215
import shared.views
16+
import shared.stores as SharedStores
1317
import utils
1418

1519
import AppLayouts.Browser.stores as BrowserStores
@@ -28,8 +32,8 @@ Dialog {
2832

2933
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
3034
parent: Overlay.overlay
31-
width: 360
32-
height: contentItem.childrenRect.height + 2 * Theme.padding
35+
width: 720
36+
height: 480
3337
background: Rectangle {
3438
id: bgPopup
3539
color: Theme.palette.background
@@ -101,13 +105,24 @@ Dialog {
101105
target: root.browserWalletStore.dappBrowserAccount
102106
function onConnectedAccountDeleted() {
103107
root.reload()
104-
// This is done because when an account is deleted and the account is updated to default one,
105-
// only the properties are updated and we need to listen to those events and update the selected account
108+
// Reset to default account when connected account is deleted
106109
accountSelectorRow.currentAddress = ""
107110
accountSelector.selectedAddress = Qt.binding(function () {return root.browserWalletStore.dappBrowserAccount.address})
108111
}
109112
}
110113

114+
Connections {
115+
target: browserActivityStore.transactionActivityStatus
116+
enabled: root.visible
117+
function onIsFilterDirtyChanged() {
118+
browserActivityStore.updateTransactionFilterIfDirty()
119+
}
120+
function onFilterChainsChanged() {
121+
browserActivityStore.currentActivityFiltersStore.updateCollectiblesModel()
122+
browserActivityStore.currentActivityFiltersStore.updateRecipientsModel()
123+
}
124+
}
125+
111126
Item {
112127
property string currentAddress: ""
113128
id: accountSelectorRow
@@ -125,7 +140,6 @@ Dialog {
125140
selectedAddress: root.browserWalletStore.dappBrowserAccount.address
126141
onCurrentAccountAddressChanged: {
127142
if (!accountSelectorRow.currentAddress) {
128-
// We just set the account for the first time. Nothing to do here
129143
accountSelectorRow.currentAddress = currentAccountAddress
130144
return
131145
}
@@ -136,6 +150,11 @@ Dialog {
136150
accountSelectorRow.currentAddress = currentAccountAddress
137151
root.browserWalletStore.switchAccountByAddress(currentAccountAddress)
138152
root.accountChanged(currentAccountAddress)
153+
154+
browserActivityStore.activityController.setFilterAddressesJson(
155+
JSON.stringify([currentAccountAddress])
156+
)
157+
139158
reload()
140159
}
141160
}
@@ -163,6 +182,39 @@ Dialog {
163182
}
164183
}
165184

185+
BrowserStores.BrowserActivityStore {
186+
id: browserActivityStore
187+
browserWalletStore: root.browserWalletStore
188+
}
189+
190+
HistoryView {
191+
id: walletInfoContent
192+
width: parent.width
193+
anchors.top: accountSelectorRow.bottom
194+
anchors.topMargin: Theme.bigPadding
195+
anchors.bottom: parent.bottom
196+
197+
activityStore: browserActivityStore
198+
overview: root.browserWalletStore.dappBrowserAccount
199+
communitiesStore: null
200+
currencyStore: SharedStores.CurrenciesStore {}
201+
networksStore: SharedStores.NetworksStore {}
202+
showAllAccounts: false
203+
displayValues: true
204+
filterVisible: false
205+
disableShadowOnScroll: true
206+
hideVerticalScrollbar: false
207+
208+
Component.onCompleted: {
209+
const activeChainIds = SQUtils.ModelUtils.modelToFlatArray(networksStore.activeNetworks, "chainId")
210+
if (activeChainIds.length > 0) {
211+
browserActivityStore.activityController.setFilterChainsJson(JSON.stringify(activeChainIds), true)
212+
}
213+
214+
const currentAddress = root.browserWalletStore.dappBrowserAccount.address
215+
browserActivityStore.activityController.setFilterAddressesJson(JSON.stringify([currentAddress]))
216+
}
217+
}
166218
onClosed: {
167219
root.destroy();
168220
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import QtQuick
2+
3+
import utils
4+
5+
QtObject {
6+
id: root
7+
8+
required property var browserWalletStore
9+
10+
readonly property var activityController: browserSection.activityController
11+
12+
readonly property string selectedAddress: browserWalletStore.dappBrowserAccount.address
13+
readonly property bool isNonArchivalNode: false
14+
readonly property bool showAllAccounts: false
15+
readonly property var transactionActivityStatus: activityController.status
16+
readonly property bool loadingHistoryTransactions: activityController.status.loadingData
17+
readonly property bool newDataAvailable: activityController.status.newDataAvailable
18+
19+
readonly property var historyTransactions: activityController.model
20+
21+
// Browser view doesn't provide transaction filtering UI
22+
readonly property QtObject currentActivityFiltersStore: QtObject {
23+
readonly property bool filtersSet: false
24+
25+
function applyAllFilters() {
26+
root.activityController.updateFilter()
27+
}
28+
29+
function updateCollectiblesModel() {
30+
root.activityController.updateCollectiblesModel()
31+
}
32+
33+
function updateRecipientsModel() {
34+
root.activityController.updateRecipientsModel()
35+
}
36+
}
37+
38+
function updateTransactionFilterIfDirty() {
39+
if (transactionActivityStatus.isFilterDirty) {
40+
activityController.updateFilter()
41+
}
42+
}
43+
44+
function fetchMoreTransactions() {
45+
if (historyTransactions.count === 0
46+
|| !historyTransactions.hasMore
47+
|| loadingHistoryTransactions)
48+
return
49+
activityController.loadMoreItems()
50+
}
51+
52+
function resetActivityData() {
53+
activityController.resetActivityData()
54+
}
55+
56+
function getEtherscanLink(chainID) {
57+
return networksModule.getBlockExplorerTxURL(chainID)
58+
}
59+
60+
function getTransactionType(transaction) {
61+
if (!transaction) return Constants.TransactionType.Send
62+
return transaction.txType
63+
}
64+
65+
function getNameForAddress(address) {
66+
const name = walletSectionAccounts.getNameByAddress(address)
67+
return name.length > 0 ? name : ""
68+
}
69+
70+
function getDappDetails(chainId, contractAddress) {
71+
return undefined
72+
}
73+
74+
function isOwnedAccount(address) {
75+
return walletSectionAccounts.isOwnedAccount(address)
76+
}
77+
}

ui/app/AppLayouts/Browser/stores/BrowserWalletStore.qml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,6 @@ QtObject {
88
property string defaultCurrency: walletSection.currentCurrency
99
property string signingPhrase: walletSection.signingPhrase // FIXME
1010

11-
function getEtherscanLink(chainID) {
12-
return networksModule.getBlockExplorerTxURL(chainID)
13-
}
14-
1511
function switchAccountByAddress(address) {
1612
browserSectionCurrentAccount.switchAccountByAddress(address)
1713
}

0 commit comments

Comments
 (0)