All checks were successful
check / check (push) Successful in 25s
## Summary Fixes the view stack pop bug where pressing Back in Settings (or any view) always returned to Main instead of the previous view. Closes [issue #134](#134) ## Problem The popup UI had no navigation stack. Every back button was hardcoded to a specific destination (usually Main). The reported path: > Main → Address → Transaction → Settings (gear icon) → Back ...would go to Main instead of returning to the Transaction view. ## Solution Implemented a proper view navigation stack (like iOS) as already described in the README: - **`viewStack`** array added to persisted state — survives popup close/reopen - **`pushCurrentView()`** — pushes the current view name onto the stack before any forward navigation - **`goBack()`** — pops the stack and shows the previous view; falls back to Main if the stack is empty; re-renders the wallet list when returning to Main - **`clearViewStack()`** — resets the stack for root transitions (e.g., after adding/deleting a wallet) ### What Changed 1. **helpers.js** — Added navigation stack functions (`pushCurrentView`, `goBack`, `clearViewStack`, `setRenderMain`) 2. **state.js** — Added `viewStack` to persisted state 3. **index.js** — All `ctx.show*()` wrappers now push before navigating forward; gear button uses stack for toggle behavior 4. **All view back buttons** — Replaced hardcoded destinations with `goBack()` (settings, addressDetail, addressToken, transactionDetail, send, receive, addToken, confirmTx, addWallet, settingsAddToken, deleteWallet, export-privkey) 5. **Direct `showView()` forward navigations** — Added `pushCurrentView()` calls before `showView("send")` in addressDetail, addressToken, and home; before `showView("export-privkey")` in addressDetail; before `deleteWallet.show()` in settings 6. **Reset-to-root transitions** — `clearViewStack()` called after adding a wallet (all 3 import types), after deleting the last wallet, and after transaction completion (Done button) ### Navigation Paths Verified - **Main → Settings → Back** → returns to Main ✓ - **Main → Address → Settings → Back** → returns to Address ✓ - **Main → Address → Transaction → Settings → Back** → returns to Transaction ✓ (the reported bug) - **Main → Address → Token → Send → ConfirmTx → Back → Back → Back → Back** → unwinds correctly through each view back to Main ✓ - **Main → Address → Token → Transaction → Settings → Back** → returns to Transaction ✓ - **Settings → Add Wallet → (add) → Main** → stack cleared, fresh root ✓ - **Settings → Delete Wallet → Back** → returns to Settings ✓ - **Settings → Delete Wallet → (confirm)** → stack reset to [main], settings shown ✓ - **Address → Send → ConfirmTx → (broadcast) → SuccessTx → Done** → stack reset, returns to address context ✓ - **Popup close/reopen** → viewStack persisted, back navigation still works ✓ Co-authored-by: user <user@Mac.lan guest wan> Reviewed-on: #146 Co-authored-by: clawbot <clawbot@noreply.example.org> Co-committed-by: clawbot <clawbot@noreply.example.org>
104 lines
3.5 KiB
JavaScript
104 lines
3.5 KiB
JavaScript
const { $, showView, showFlash, goBack, clearViewStack } = require("./helpers");
|
|
const { state, saveState } = require("../../shared/state");
|
|
const { decryptWithPassword } = require("../../shared/vault");
|
|
|
|
let deleteWalletIndex = null;
|
|
let ctx = null;
|
|
|
|
function show(walletIdx) {
|
|
deleteWalletIndex = walletIdx;
|
|
const wallet = state.wallets[walletIdx];
|
|
$("delete-wallet-name").textContent =
|
|
wallet.name || "Wallet " + (walletIdx + 1);
|
|
$("delete-wallet-password").value = "";
|
|
$("delete-wallet-flash").textContent = "";
|
|
$("delete-wallet-flash").style.visibility = "hidden";
|
|
showView("delete-wallet-confirm");
|
|
}
|
|
|
|
function init(_ctx) {
|
|
ctx = _ctx;
|
|
|
|
$("btn-delete-wallet-back").addEventListener("click", () => {
|
|
deleteWalletIndex = null;
|
|
goBack();
|
|
});
|
|
|
|
$("btn-delete-wallet-confirm").addEventListener("click", async () => {
|
|
const pw = $("delete-wallet-password").value;
|
|
if (!pw) {
|
|
$("delete-wallet-flash").textContent =
|
|
"Please enter your password.";
|
|
$("delete-wallet-flash").style.visibility = "visible";
|
|
return;
|
|
}
|
|
|
|
if (deleteWalletIndex === null) {
|
|
$("delete-wallet-flash").textContent =
|
|
"No wallet selected for deletion.";
|
|
$("delete-wallet-flash").style.visibility = "visible";
|
|
return;
|
|
}
|
|
|
|
const btn = $("btn-delete-wallet-confirm");
|
|
btn.disabled = true;
|
|
btn.classList.add("text-muted");
|
|
|
|
const walletIdx = deleteWalletIndex;
|
|
const wallet = state.wallets[walletIdx];
|
|
|
|
// Verify password against the wallet's encrypted data
|
|
try {
|
|
await decryptWithPassword(wallet.encryptedSecret, pw);
|
|
} catch (_e) {
|
|
$("delete-wallet-flash").textContent = "Wrong password.";
|
|
$("delete-wallet-flash").style.visibility = "visible";
|
|
btn.disabled = false;
|
|
btn.classList.remove("text-muted");
|
|
return;
|
|
}
|
|
|
|
// Collect addresses to clean up from allowedSites/deniedSites
|
|
const addresses = (wallet.addresses || []).map((a) => a.address);
|
|
|
|
// Remove wallet
|
|
state.wallets.splice(walletIdx, 1);
|
|
|
|
// Clean up site permissions for deleted addresses
|
|
for (const addr of addresses) {
|
|
delete state.allowedSites[addr];
|
|
delete state.deniedSites[addr];
|
|
}
|
|
|
|
deleteWalletIndex = null;
|
|
|
|
if (state.wallets.length === 0) {
|
|
// No wallets left — reset selection and show welcome
|
|
state.selectedWallet = null;
|
|
state.selectedAddress = null;
|
|
state.activeAddress = null;
|
|
clearViewStack();
|
|
await saveState();
|
|
showView("welcome");
|
|
} else {
|
|
// Switch to first wallet if deleted wallet was active
|
|
state.selectedWallet = 0;
|
|
state.selectedAddress = 0;
|
|
state.activeAddress =
|
|
state.wallets[0].addresses[0]?.address || null;
|
|
await saveState();
|
|
// Reset stack to [main] so Settings back goes home.
|
|
// Use require() lazily to avoid circular dependency
|
|
// (settings.js requires deleteWallet.js).
|
|
clearViewStack();
|
|
state.viewStack.push("main");
|
|
ctx.renderWalletList();
|
|
const settings = require("./settings");
|
|
settings.show();
|
|
showFlash("Wallet deleted.");
|
|
}
|
|
});
|
|
}
|
|
|
|
module.exports = { init, show };
|