refactor: delete-wallet-confirm as standalone full view
All checks were successful
check / check (push) Successful in 22s
All checks were successful
check / check (push) Successful in 22s
Replace the inline confirmation div at the bottom of Settings with a proper full-screen view (view-delete-wallet-confirm). This fixes the issue where the confirmation was offscreen on the 360x600 popup. - New view with back button, title, warning text, password input, and red-text Confirm Delete button - Dedicated flash area for password errors - New deleteWallet.js module with init/show pattern - Added delete-wallet-confirm to VIEWS array in helpers.js - Removed old inline confirmation HTML and logic from settings
This commit is contained in:
@@ -841,39 +841,41 @@
|
|||||||
</p>
|
</p>
|
||||||
<div id="settings-denied-sites"></div>
|
<div id="settings-denied-sites"></div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<!-- ============ DELETE WALLET CONFIRM ============ -->
|
||||||
id="delete-wallet-confirm"
|
<div id="view-delete-wallet-confirm" class="view hidden">
|
||||||
class="hidden border border-border border-dashed p-3 mt-2 mb-3"
|
<button
|
||||||
|
id="btn-delete-wallet-back"
|
||||||
|
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer mb-2"
|
||||||
>
|
>
|
||||||
<h3 class="font-bold mb-1">Confirm Deletion</h3>
|
< Back
|
||||||
<p class="text-xs text-muted mb-2">
|
</button>
|
||||||
Delete <strong id="delete-wallet-name"></strong>? This
|
<h2 class="font-bold mb-3">Delete Wallet</h2>
|
||||||
is permanent. Any funds will be unrecoverable without
|
<p class="text-xs mb-3">
|
||||||
your recovery phrase.
|
Deleting
|
||||||
|
<strong id="delete-wallet-name"></strong> is permanent. Any
|
||||||
|
funds will be unrecoverable without your recovery phrase.
|
||||||
</p>
|
</p>
|
||||||
<p class="text-xs mb-2">Enter your password to confirm:</p>
|
<div
|
||||||
|
id="delete-wallet-flash"
|
||||||
|
class="text-xs text-red-500 mb-2 hidden"
|
||||||
|
></div>
|
||||||
|
<div class="mb-2">
|
||||||
|
<label class="block mb-1">Password</label>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
id="delete-wallet-password"
|
id="delete-wallet-password"
|
||||||
class="border border-border p-1 w-full text-sm bg-bg text-fg mb-2"
|
class="border border-border p-1 w-full font-mono text-sm bg-bg text-fg"
|
||||||
placeholder="Password"
|
placeholder="Enter your password to confirm"
|
||||||
/>
|
/>
|
||||||
<div class="flex gap-2">
|
</div>
|
||||||
<button
|
<button
|
||||||
id="btn-delete-wallet-confirm"
|
id="btn-delete-wallet-confirm"
|
||||||
class="border border-border text-fg px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer"
|
class="border border-border text-red-500 px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer"
|
||||||
>
|
>
|
||||||
Delete
|
Confirm Delete
|
||||||
</button>
|
</button>
|
||||||
<button
|
|
||||||
id="btn-delete-wallet-cancel"
|
|
||||||
class="border border-border px-2 py-1 hover:bg-fg hover:text-bg cursor-pointer"
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ============ SETTINGS: ADD TOKEN ============ -->
|
<!-- ============ SETTINGS: ADD TOKEN ============ -->
|
||||||
|
|||||||
90
src/popup/views/deleteWallet.js
Normal file
90
src/popup/views/deleteWallet.js
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
const { $, showView, showFlash } = 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").classList.add("hidden");
|
||||||
|
showView("delete-wallet-confirm");
|
||||||
|
}
|
||||||
|
|
||||||
|
function init(_ctx) {
|
||||||
|
ctx = _ctx;
|
||||||
|
|
||||||
|
$("btn-delete-wallet-back").addEventListener("click", () => {
|
||||||
|
deleteWalletIndex = null;
|
||||||
|
showView("settings");
|
||||||
|
});
|
||||||
|
|
||||||
|
$("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").classList.remove("hidden");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deleteWalletIndex === null) {
|
||||||
|
$("delete-wallet-flash").textContent =
|
||||||
|
"No wallet selected for deletion.";
|
||||||
|
$("delete-wallet-flash").classList.remove("hidden");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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").classList.remove("hidden");
|
||||||
|
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;
|
||||||
|
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();
|
||||||
|
showFlash("Wallet deleted.");
|
||||||
|
ctx.renderWalletList();
|
||||||
|
showView("settings");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { init, show };
|
||||||
@@ -25,6 +25,7 @@ const VIEWS = [
|
|||||||
"receive",
|
"receive",
|
||||||
"add-token",
|
"add-token",
|
||||||
"settings",
|
"settings",
|
||||||
|
"delete-wallet-confirm",
|
||||||
"settings-addtoken",
|
"settings-addtoken",
|
||||||
"transaction",
|
"transaction",
|
||||||
"approve-site",
|
"approve-site",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ const { $, showView, showFlash, escapeHtml } = require("./helpers");
|
|||||||
const { state, saveState } = require("../../shared/state");
|
const { state, saveState } = require("../../shared/state");
|
||||||
const { ETHEREUM_MAINNET_CHAIN_ID } = require("../../shared/constants");
|
const { ETHEREUM_MAINNET_CHAIN_ID } = require("../../shared/constants");
|
||||||
const { log, debugFetch } = require("../../shared/log");
|
const { log, debugFetch } = require("../../shared/log");
|
||||||
const { decryptWithPassword } = require("../../shared/vault");
|
const deleteWallet = require("./deleteWallet");
|
||||||
|
|
||||||
const runtime =
|
const runtime =
|
||||||
typeof browser !== "undefined" ? browser.runtime : chrome.runtime;
|
typeof browser !== "undefined" ? browser.runtime : chrome.runtime;
|
||||||
@@ -66,8 +66,6 @@ function renderTrackedTokens() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let deleteWalletIndex = null;
|
|
||||||
|
|
||||||
function renderWalletListSettings() {
|
function renderWalletListSettings() {
|
||||||
const container = $("settings-wallet-list");
|
const container = $("settings-wallet-list");
|
||||||
if (state.wallets.length === 0) {
|
if (state.wallets.length === 0) {
|
||||||
@@ -86,12 +84,7 @@ function renderWalletListSettings() {
|
|||||||
container.querySelectorAll(".btn-delete-wallet").forEach((btn) => {
|
container.querySelectorAll(".btn-delete-wallet").forEach((btn) => {
|
||||||
btn.addEventListener("click", () => {
|
btn.addEventListener("click", () => {
|
||||||
const idx = parseInt(btn.dataset.idx, 10);
|
const idx = parseInt(btn.dataset.idx, 10);
|
||||||
const wallet = state.wallets[idx];
|
deleteWallet.show(idx);
|
||||||
deleteWalletIndex = idx;
|
|
||||||
$("delete-wallet-name").textContent =
|
|
||||||
wallet.name || "Wallet " + (idx + 1);
|
|
||||||
$("delete-wallet-password").value = "";
|
|
||||||
$("delete-wallet-confirm").classList.remove("hidden");
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -134,8 +127,6 @@ function show() {
|
|||||||
renderTrackedTokens();
|
renderTrackedTokens();
|
||||||
renderSiteLists();
|
renderSiteLists();
|
||||||
renderWalletListSettings();
|
renderWalletListSettings();
|
||||||
deleteWalletIndex = null;
|
|
||||||
$("delete-wallet-confirm").classList.add("hidden");
|
|
||||||
|
|
||||||
showView("settings");
|
showView("settings");
|
||||||
}
|
}
|
||||||
@@ -150,6 +141,8 @@ function renderSiteLists() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function init(ctx) {
|
function init(ctx) {
|
||||||
|
deleteWallet.init(ctx);
|
||||||
|
|
||||||
$("btn-save-rpc").addEventListener("click", async () => {
|
$("btn-save-rpc").addEventListener("click", async () => {
|
||||||
const url = $("settings-rpc").value.trim();
|
const url = $("settings-rpc").value.trim();
|
||||||
if (!url) {
|
if (!url) {
|
||||||
@@ -259,72 +252,6 @@ function init(ctx) {
|
|||||||
ctx.renderWalletList();
|
ctx.renderWalletList();
|
||||||
showView("main");
|
showView("main");
|
||||||
});
|
});
|
||||||
|
|
||||||
$("btn-delete-wallet-cancel").addEventListener("click", () => {
|
|
||||||
$("delete-wallet-confirm").classList.add("hidden");
|
|
||||||
$("delete-wallet-password").value = "";
|
|
||||||
deleteWalletIndex = null;
|
|
||||||
});
|
|
||||||
|
|
||||||
$("btn-delete-wallet-confirm").addEventListener("click", async () => {
|
|
||||||
const pw = $("delete-wallet-password").value;
|
|
||||||
if (!pw) {
|
|
||||||
showFlash("Password required.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (deleteWalletIndex === null) {
|
|
||||||
showFlash("No wallet selected for deletion.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const walletIdx = deleteWalletIndex;
|
|
||||||
const wallet = state.wallets[walletIdx];
|
|
||||||
|
|
||||||
// Verify password against the wallet's encrypted data
|
|
||||||
try {
|
|
||||||
await decryptWithPassword(wallet.encryptedSecret, pw);
|
|
||||||
} catch (_e) {
|
|
||||||
showFlash("Wrong password.");
|
|
||||||
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;
|
|
||||||
await saveState();
|
|
||||||
$("delete-wallet-confirm").classList.add("hidden");
|
|
||||||
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();
|
|
||||||
$("delete-wallet-confirm").classList.add("hidden");
|
|
||||||
showFlash("Wallet deleted.");
|
|
||||||
renderWalletListSettings();
|
|
||||||
ctx.renderWalletList();
|
|
||||||
showView("main");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { init, show, renderSiteLists };
|
module.exports = { init, show, renderSiteLists };
|
||||||
|
|||||||
Reference in New Issue
Block a user