Skip to content

Commit 4a5b25e

Browse files
committed
Merge branch 'fix/681-banner-details-overlap' into fix/multi-wallet
2 parents 7f85f2e + 9a70e71 commit 4a5b25e

File tree

9 files changed

+165
-185
lines changed

9 files changed

+165
-185
lines changed

.coderabbit.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
reviews:
33
auto_review:
44
enabled: true
5+
drafts: false
56
base_branches:
67
- master
78
- v1.0-dev

.github/workflows/clippy.yml

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ on:
66
- main
77
- "v*-dev"
88
pull_request:
9+
types: [opened, synchronize, reopened, ready_for_review]
910

1011
concurrency:
1112
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
@@ -17,33 +18,10 @@ env:
1718
jobs:
1819
clippy:
1920
name: Clippy
21+
if: github.event.pull_request.draft != true
2022
runs-on: ubuntu-latest
2123

2224
steps:
23-
- name: Free disk space
24-
run: |
25-
echo "=== Disk space before cleanup ==="
26-
df -h
27-
# Remove large unnecessary directories
28-
sudo rm -rf /usr/share/dotnet
29-
sudo rm -rf /usr/local/lib/android
30-
sudo rm -rf /opt/ghc
31-
sudo rm -rf /opt/hostedtoolcache/CodeQL
32-
sudo rm -rf /opt/hostedtoolcache/go
33-
sudo rm -rf /opt/hostedtoolcache/node
34-
sudo rm -rf /usr/local/share/boost
35-
sudo rm -rf /usr/share/swift
36-
sudo rm -rf /usr/local/graalvm
37-
sudo rm -rf /usr/local/.ghcup
38-
# Clean docker
39-
sudo docker image prune --all --force || true
40-
sudo docker system prune --all --force || true
41-
# Clean apt cache
42-
sudo apt-get clean
43-
sudo rm -rf /var/lib/apt/lists/*
44-
echo "=== Disk space after cleanup ==="
45-
df -h
46-
4725
- name: Checkout code
4826
uses: actions/checkout@v4
4927

.github/workflows/release.yml

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -42,31 +42,6 @@ jobs:
4242
runs-on: ${{ matrix.runs-on }}
4343

4444
steps:
45-
- name: Free disk space
46-
if: ${{ runner.os == 'Linux' }}
47-
run: |
48-
echo "=== Disk space before cleanup ==="
49-
df -h
50-
# Remove large unnecessary directories
51-
sudo rm -rf /usr/share/dotnet
52-
sudo rm -rf /usr/local/lib/android
53-
sudo rm -rf /opt/ghc
54-
sudo rm -rf /opt/hostedtoolcache/CodeQL
55-
sudo rm -rf /opt/hostedtoolcache/go
56-
sudo rm -rf /opt/hostedtoolcache/node
57-
sudo rm -rf /usr/local/share/boost
58-
sudo rm -rf /usr/share/swift
59-
sudo rm -rf /usr/local/graalvm
60-
sudo rm -rf /usr/local/.ghcup
61-
# Clean docker
62-
sudo docker image prune --all --force || true
63-
sudo docker system prune --all --force || true
64-
# Clean apt cache
65-
sudo apt-get clean
66-
sudo rm -rf /var/lib/apt/lists/*
67-
echo "=== Disk space after cleanup ==="
68-
df -h
69-
7045
- name: Check out code
7146
uses: actions/checkout@v4
7247

.github/workflows/tests.yml

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ on:
66
- main
77
- "v*-dev"
88
pull_request:
9+
types: [opened, synchronize, reopened, ready_for_review]
910

1011
concurrency:
1112
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
@@ -17,33 +18,10 @@ env:
1718
jobs:
1819
test:
1920
name: Test Suite
21+
if: github.event.pull_request.draft != true
2022
runs-on: ubuntu-latest
2123

2224
steps:
23-
- name: Free disk space
24-
run: |
25-
echo "=== Disk space before cleanup ==="
26-
df -h
27-
# Remove large unnecessary directories
28-
sudo rm -rf /usr/share/dotnet
29-
sudo rm -rf /usr/local/lib/android
30-
sudo rm -rf /opt/ghc
31-
sudo rm -rf /opt/hostedtoolcache/CodeQL
32-
sudo rm -rf /opt/hostedtoolcache/go
33-
sudo rm -rf /opt/hostedtoolcache/node
34-
sudo rm -rf /usr/local/share/boost
35-
sudo rm -rf /usr/share/swift
36-
sudo rm -rf /usr/local/graalvm
37-
sudo rm -rf /usr/local/.ghcup
38-
# Clean docker
39-
sudo docker image prune --all --force || true
40-
sudo docker system prune --all --force || true
41-
# Clean apt cache
42-
sudo apt-get clean
43-
sudo rm -rf /var/lib/apt/lists/*
44-
echo "=== Disk space after cleanup ==="
45-
df -h
46-
4725
- name: Checkout code
4826
uses: actions/checkout@v4
4927

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Manual Test: Banner Details Overlap Fix (#681)
2+
3+
## Prerequisites
4+
- Developer mode enabled (to see "Show details" links on error banners)
5+
- Ability to trigger multiple backend errors (e.g., invalid network config, expired identity operations)
6+
7+
## Test Scenario: Multiple Expanded Details
8+
9+
1. Trigger 2+ error banners that include technical details (e.g., attempt operations on a disconnected network, or perform actions that produce different errors in sequence)
10+
2. Verify all banners appear stacked vertically without overlap
11+
3. Click "Show details" on the **first** banner — verify the details section expands inline, pushing subsequent banners down
12+
4. Click "Show details" on the **second** banner — verify its details section also expands without overlapping the first
13+
5. Scroll within each details section independently — verify scroll positions are independent (no shared state)
14+
6. Click "Hide details" on one banner — verify only that banner's details collapse; the other remains expanded
15+
7. Dismiss one banner — verify remaining banners reflow correctly
16+
17+
## Expected Result
18+
- Each banner's details section occupies its own vertical space
19+
- No visual overlap between expanded details of different banners
20+
- Scroll areas within each details section are independent
21+
22+
## Regression Check
23+
- Single banner with "Show details" still works as before
24+
- Banners without details are unaffected

src/context/mod.rs

Lines changed: 20 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -354,27 +354,16 @@ impl AppContext {
354354
return None;
355355
}
356356

357-
// If defaulting to RPC is desired, swap provider after binding.
358-
if app_context.core_backend_mode() == CoreBackendMode::Rpc {
359-
if let Err(e) = app_context
357+
// If defaulting to RPC, rebind the RPC provider (overrides SPV registration above).
358+
if app_context.core_backend_mode() == CoreBackendMode::Rpc
359+
&& let Err(e) = app_context
360360
.rpc_context_provider
361361
.read()
362362
.map_err(|_| "RPC provider lock poisoned".to_string())
363363
.and_then(|provider| provider.bind_app_context(app_context.clone()))
364-
{
365-
tracing::error!("Failed to bind RPC provider: {}", e);
366-
return None;
367-
}
368-
} else {
369-
// Ensure SDK uses the SPV provider
370-
let provider = match app_context.spv_context_provider.read() {
371-
Ok(p) => p.clone(),
372-
Err(_) => {
373-
tracing::error!("SPV provider lock poisoned");
374-
return None;
375-
}
376-
};
377-
app_context.sdk.load().set_context_provider(provider);
364+
{
365+
tracing::error!("Failed to bind RPC provider: {}", e);
366+
return None;
378367
}
379368

380369
app_context.bootstrap_loaded_wallets();
@@ -417,32 +406,31 @@ impl AppContext {
417406
tracing::error!("Failed to persist core backend mode: {}", e);
418407
}
419408

420-
// Switch SDK context provider to match the selected backend
409+
// Switch SDK context provider to match the selected backend.
410+
// Early returns are defensive: if code is added after this match, a failed
411+
// bind should not proceed with a stale provider.
412+
#[allow(clippy::needless_return)]
421413
match mode {
422414
CoreBackendMode::Spv => {
423-
// Clone the SPV provider and bind app context on the clone
424-
let provider = match self.spv_context_provider.read() {
425-
Ok(p) => p.clone(),
426-
Err(_) => {
427-
tracing::error!("SPV provider lock poisoned");
428-
return;
429-
}
430-
};
431-
if let Err(e) = provider.bind_app_context(Arc::clone(self)) {
415+
if let Err(e) = self
416+
.spv_context_provider
417+
.read()
418+
.map_err(|_| "SPV provider lock poisoned".to_string())
419+
.and_then(|provider| provider.bind_app_context(Arc::clone(self)))
420+
{
432421
tracing::error!("Failed to bind SPV provider: {}", e);
433422
return;
434423
}
435-
self.sdk.load().set_context_provider(provider);
436424
}
437425
CoreBackendMode::Rpc => {
438-
// RPC provider binding also sets itself on the SDK
439426
if let Err(e) = self
440427
.rpc_context_provider
441428
.read()
442429
.map_err(|_| "RPC provider lock poisoned".to_string())
443430
.and_then(|provider| provider.bind_app_context(Arc::clone(self)))
444431
{
445432
tracing::error!("Failed to bind RPC provider: {}", e);
433+
return;
446434
}
447435
}
448436
}
@@ -559,7 +547,9 @@ impl AppContext {
559547
}
560548
self.sdk.store(Arc::new(new_sdk));
561549

562-
// Rebind providers to ensure they hold the new AppContext reference
550+
// Rebind providers to ensure they hold the new AppContext reference.
551+
// bind_app_context also registers the provider with the SDK, so the
552+
// active provider (last bound) wins.
563553
self.spv_context_provider
564554
.read()
565555
.map_err(|_| "SPV provider lock poisoned".to_string())?
@@ -569,13 +559,6 @@ impl AppContext {
569559
.read()
570560
.map_err(|_| "RPC provider lock poisoned".to_string())?
571561
.bind_app_context(self.clone())?;
572-
} else {
573-
let provider = self
574-
.spv_context_provider
575-
.read()
576-
.map_err(|_| "SPV provider lock poisoned".to_string())?
577-
.clone();
578-
self.sdk.load().set_context_provider(provider);
579562
}
580563

581564
Ok(())

0 commit comments

Comments
 (0)