Commit Graph
19 Commits
Author SHA1 Message Date
Alex Jbanca 754276d853 perf(wallet): build the wallet section around what the user is waiting for
A wallet section activation built everything it would ever need before it
showed anything: both panels inline, both detail views, every row of two
lists synchronously, and a set of subtrees that exist for cases that almost
never occur. This reorders that around a single rule - build what is on
screen first, build the rest in the incubation controller's metered bites,
and build the rest of the rest only when something asks for it.

Lists fill preemptibly. A ListView refill is one uninterruptible call inside
the window's polish phase, and QQuickItemView creates visible delegates with
AsynchronousIfNested - so a list first laid out after its enclosing Loader is
already Ready builds every visible row synchronously. On a warm load that was
one 34.7ms GUI-thread block against a 3.2ms budget for the assets list, and
8.7-13.5ms of post-content polish across both lists. The assets and accounts
delegates become TokenDelegateShell and WalletAccountDelegateShell: an Item
carrying the row's geometry and its placeholder tiles, with the real row
behind a nested asynchronous Loader. The refill builds shells; the rows
incubate afterwards.

Row height is the shell's, not the content's. StatusListItem.implicitHeight
is Math.max(64, titleArea.height + 16), and both a token row and an account
row resolve to that 64px floor, which is what placeholderHeight is.
tst_TokenDelegateShell and tst_WalletAccountDelegateShell gate the two
staying equal, so a change that makes a row taller fails a test rather than
moving contentHeight and the scroll position mid-fill. Each placeholder
mirrors the skeleton the per-tab loader showed a moment earlier, so the two
loading states read as one handoff.

Subtrees built for the exceptional case are latched off. The token row's two
warning buttons, the asset detail's four chain-tag warning buttons, its
header community tag and its "Minted by" tile were all built unconditionally
and merely hidden. Each now sits behind the condition that used to drive
`visible`. AssetsDetailsHeader loses its `communityTag` alias, which existed
only so callers could reach in and set the tag's contents; it takes
communityName/communityImage and builds the tag itself.

The two detail views move behind async Loaders keyed on the stack index. The
token to show becomes state held in `d` and bound into the view rather than
assigned into it, so a second click landing mid-incubation wins without a
queue-and-replay; the resets that hung off onVisibleChanged hang off
onActiveChanged, which fires on the same edges.

Panels build in the order the user sees them. WalletLayout declared both
panels as plain object bindings, so activation built LeftTabView and the
centre StackView inline and the chrome's two PanelSwapGates could not fire
independently - they opened 5ms apart because both panel properties resolve
when WalletLayout completes. Each panel now sits behind its own async Loader
with its own readiness, the primary one first, and once a skeleton is on
screen with no panel switch running the primary panel is built synchronously:
the pacing exists to protect section-switch animations, and here the only
thing a synchronous block could stutter is the skeleton it replaces.

Wrapping the panels in Loaders exposed three geometry defects. A Loader
reports its item's implicit size as its own, so the centre StackView's
content width propagated into the chrome and pushed the panel past the right
edge on a narrow screen; the loaders are bound to the chrome's geometry for
the unparented phase, the stack no longer anchors to its loader, and the side
inset moves onto the content where it belongs.

Panel geometry is coalesced across a rotation. A device rotation walks the
window through nine sizes over ~430ms and LayoutItemProxy forwarded every one
to the section's panels - a full relayout of a populated subtree each time -
and parked a panel at a degenerate box for ~148ms on the portrait/landscape
handoff. SectionPanelSlot replaces the panel proxies in both sub-layouts and
publishes the box each slot will give its panel, which is also what a section
building panels outside the tree needs: the centre slot cannot be guessed, as
it is short by the header and footer and narrow by the left column in
landscape. Wallet and chat both pre-size their incubating panels to it.

Two fixes fall out of that work. BaseProxyPanel looked its SwipeView page up
at a fixed implicitIndex, but SwipeView indices close up as pages come and
go, so hiding the right panel with no left panel present silently left its
page in the view, still swipeable; it now looks the page up by identity.
SectionPanelSlot also has to be listed in statusq.qrc - without it the type
is absent from the binary's resources, StatusSectionLayout becomes
unavailable and the UI process dies precompiling AppMain.

Measured on a whale profile, Release, arms alternated between rounds:

  warm t_first_asset_row       119-159ms -> 51-74ms
  warm max_stall_ms             31.7-42.6 -> 17.2-26.3ms
  section ready                     631ms -> 207ms
  visible panel promoted            609ms -> 338ms
  cold: skeleton shown -> visible  2272ms -> 1836ms
  objects_total (cold)               4602 -> 3344   (-27%)
  objects_settled                    9569 -> 8297   (-13%)
  token row QObjects                  326 -> 279
  panel geometry distinct sizes    24 -> 5 centre, 19 -> 2 left
  degenerate 0x0 box written    12 occurrences -> 0

Device numbers are only comparable once the app has settled; a run taken
while startup backend work is still in flight measured 925ms for a path that
measures ~520ms settled.

Measurements come from an offscreen storybook wallet bench that is not part
of this PR; see branch `feat/storybook-wallet-loader`.
2026-08-23 09:40:36 +03:00
Michał Cieślak c7e5964a7e WalletHeader replaced by WalletAccountHeader and WalletSavedAddressesHeader 2025-10-07 01:29:44 +02:00
Michał Cieślak c8c4b05972 RightTabBaseView simplified 2025-10-07 01:29:44 +02:00
Michał Cieślak 0c842d6dd8 Wallet: SavedAddresses layout fixed
- SavedAddresses: list view made scrollable
- RightTabBaseView - LayoutItemProxy as a content holder
- RightTabView, SavedAddressesView - minor cleanup

Closes: #18932
2025-10-07 01:29:44 +02:00
Noelia 6e11604fa8 refactor(ContactsStore): Move ContactsStore to top-level scope and unify references
- Moved `ContactsStore` out of `ProfileSectionsStore` to a higher-level location, as it's now considered cross-domain.
- Removed redundant references to `ContactsStore`.
- Unified all code to reference the store consistently from the new location.
2025-07-16 12:13:07 +02:00
Michał Cieślak 80bdfc11ee Remove qml import versions from ui code (ui dir) 2025-07-14 10:48:53 +02:00
dlipicar ee79b494ec Network selection improvements (#17184)
* feat(network): implement new networks selection screen

* fix: proper handling of test network icon

* feat: changes to Network selector

* feat: implement blockchain explorers menu

* chore: move networks related properties and functions to NetworksStore

* feat: remove usage of tiny network icons

* fix: misc fixes

* chore: change exception with error
2025-02-19 12:22:45 -03:00
Alex Jbanca b6bc5d1e29 feat(dapps): Adding dapp metrics
closes #16912

Sending the dapps events to mixpanel

| Event Name | Properties | Possible Values | Notes |
| --- | --- | --- | --- |
| dapps-health | state | - wc_available
- wc_unavailable
- chains_down
- network_down
- pair_error
- connection_error
- sign_error |  |
|  | error |  | string description |
| dapps-navigation | flow | - dapps_list_opened
- connect_initiated
- disconnect_initiated
- pair_initiated |  |
|  | connector | - wallet_connect
- browser_connect |  |
| dapps-connection | flow | - proposal_received
- proposal_accepted
- proposal_rejected
- connected
- disconnected |  |
|  | networks | networks[string] - array of networks | Array of proposed or connected networks |
|  | methods | methods[string] - array of methods | Array of proposed methods |
|  | dapp | dapp uri |  |
|  | connector | - wallet_connect
- browser_connect |  |
|  | isSiwe | boolean |  |
| dapps-sign | flow | - sign_received
- sign_accepted
- sign_rejected |  |
|  | connector | - wallet_connect
- browser_connect |  |
|  | method | - personal_sign
- eth_sign
- eth_signTypedData_v4
- eth_signTypedData
- eth_signTransaction
- eth_sendTransaction |  |
|  | dapp | string - dapp uri |  |
|  | chainId | int - chain id |  |
2025-01-22 11:40:00 +02:00
Alex Jbanca c0aeae5ea5 fix(dapps): Fixing the dApps disabled state if the dapps service is not online
closes #16883 #16882

1. connect the dapps service online state to the enabled state for the dapps button
2. Fix the connect modal primary action button
3. Align DappsComboBox disabled color with the refresh button disabled color

(cherry picked from commit 2c4f6b5da3)
2024-12-12 15:42:47 +02:00
Khushboo Mehta 0c2674e7cb chore(@desktop/wallet): Chnage the send modal mechanism to follow new architecture guidelines.
After this change there is not need to pass sendModal instance from AppMain to other parts of app.
Then SendModal should be launched simply by calling Global.openSendModal(....)
2024-12-04 21:34:12 +01:00
Alex Jbanca 9490dbb57e refactoring(dapps): Move WC and BC popups in the global scope
closes #16831

Moving the dapp popups to the global scope in order for them to be triggered on any view.
There are a few changes required for this:
1. DAppsWorkflow has been split. Previously all popups were declared in the `DappsComboBox`. Now the DAppsWorkflow inherits the QObject instead and the `DappsComboBox` is used as is in the wallet header.
2. The DAppsWorkflow has been moved to AppMain. The DAppsWorkflow will be constructed in the scope of DAppsService and connected directly to the service signals
3. Updated tests and storybook with the new structure
4. Removed the `dAppsService` from `Global`. There's no reason to keep the `dAppsService` instance in the `Global` singleton.
2024-12-03 09:52:28 +02:00
Alex Jbanca 7e1e827148 feat(WC): Enable Wallet Connect feature by default
+ Update the dialog where the user choses the connection to enable or disable the connection option based on flags
+ Separating the walletConnect flag and browserConnect flag usage so that either one can be disabled without affecting the other feature
+ Update qml test
2024-11-20 18:10:29 +02:00
Lukáš Tinkl 2e249f9941 fix[WalletConnect] Incorrect authentication method icon on sign modal
- `loginType` was not propagated correctly, also due to a wrong
RootStore
- plus an evil typo: `account.migragedToKeycard` :)

Fixes #16089
2024-09-29 11:01:35 +02:00
Seitseman 2275fe4f1f fix(Stored): Make stores typed
Adding types instead of var for stores used in qml components

Closes: #14801
2024-08-27 10:52:18 +02:00
Lukáš Tinkl a7e74f3e00 chore(Global): Remove FeatureFlags access via Global singleton
- rationale: do not save global state in a singleton, gather and
propagate the values via FeatureFlagsStore

Fixes #14697
2024-08-12 20:00:31 +02:00
Cuteivist fae86bcb8d feat(@wallet): Show community activity (#13627) 2024-02-22 15:41:19 +01:00
Ivan Belyakov 49adcd9b59 fix(wallet): fix qml warnings and errors in Wallet 2024-02-01 09:39:00 +01:00
Lukáš Tinkl f80f4abb0b fix(wallet): unbreak scrolling of the wallet views
Fixes #13157
2024-01-10 12:02:22 +01:00
Sale Djenic 3ac13a7678 chore(savedaddresses): preparing saved address for reuse in wallet settings section
Part 1 of #13088
2024-01-04 17:45:57 +01:00