Darken zap dialog and add send control

This commit is contained in:
thePR0M3TH3AN committed 2025-10-05 18:45:03 -04:00
1 parent 0fd54abde8
commit 8fd5ce3c88
6 files changed
+157 -52

No files matched your search

+2 -2
View File
@@ -58,7 +58,7 @@
aria-hidden="true"
>
<div
class="zap-popover__content w-72 max-w-[calc(100vw-2rem)] rounded-lg bg-gray-900/95 p-4 shadow-lg backdrop-blur"
class="zap-popover__content w-72 max-w-[calc(100vw-2rem)] rounded-lg p-4 shadow-lg"
>
<div class="mb-3 flex items-center justify-between gap-4">
<h3
@@ -146,7 +146,7 @@
id="modalZapSendBtn"
class="rounded bg-blue-500 px-4 py-2 text-sm font-semibold text-white transition-colors hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-400 focus:ring-offset-2 focus:ring-offset-gray-900"
>
Send zap
Send
</button>
</div>
</form>
+6
View File
@@ -1027,6 +1027,12 @@ body.modal-open #app {
.zap-popover__content {
width: 18rem;
max-width: calc(100vw - 2rem);
background: rgba(11, 17, 32, 0.96);
color: #e5e7eb;
border: 1px solid rgba(148, 163, 184, 0.35);
box-shadow: 0 22px 48px -18px rgba(8, 14, 28, 0.7);
-webkit-backdrop-filter: blur(12px);
backdrop-filter: blur(12px);
}
.modal-actions__overflow {
+2 -2
View File
@@ -6603,8 +6603,8 @@ class Application {
const tone = tracker.length > failureShares.length ? "warning" : "error";
const statusMessage =
tracker.length > failureShares.length
? `Partial zap failure. Tap zap again to retry: ${summary}.`
: `Zap failed. Tap zap again to retry: ${summary}.`;
? `Partial zap failure. Press Send again to retry: ${summary}.`
: `Zap failed. Press Send again to retry: ${summary}.`;
this.videoModal?.setZapStatus(statusMessage, tone);
this.showError(error?.message || statusMessage);
} else {
+99 -14
View File
@@ -105,6 +105,7 @@ let cachedZapButton = null;
let cachedChannelShareButton = null;
let cachedChannelMenu = null;
let cachedZapControls = null;
let cachedZapForm = null;
let cachedZapAmountInput = null;
let cachedZapSplitSummary = null;
let cachedZapStatus = null;
@@ -112,6 +113,7 @@ let cachedZapReceipts = null;
let cachedZapWalletPrompt = null;
let cachedZapWalletLink = null;
let cachedZapCloseBtn = null;
let cachedZapSendBtn = null;
let pendingZapRetry = null;
let zapInFlight = false;
@@ -131,6 +133,7 @@ function setChannelZapVisibility(visible) {
const zapButton = getChannelZapButton();
const controls = getZapControlsContainer();
const amountInput = getZapAmountInput();
const sendButton = getZapSendButton();
if (!zapButton) {
return;
}
@@ -161,6 +164,17 @@ function setChannelZapVisibility(visible) {
if (amountInput) {
amountInput.disabled = !shouldShow;
}
if (sendButton) {
sendButton.disabled = !shouldShow;
sendButton.setAttribute("aria-hidden", (!shouldShow).toString());
if (shouldShow) {
sendButton.removeAttribute("tabindex");
sendButton.removeAttribute("aria-busy");
sendButton.classList.remove("opacity-50", "pointer-events-none");
} else {
sendButton.setAttribute("tabindex", "-1");
}
}
const hasWallet =
typeof app?.hasActiveWalletConnection === "function"
@@ -210,6 +224,16 @@ function getZapControlsContainer() {
return cachedZapControls;
}
function getZapFormElement() {
if (cachedZapForm && !document.body.contains(cachedZapForm)) {
cachedZapForm = null;
}
if (!cachedZapForm) {
cachedZapForm = document.getElementById("zapForm");
}
return cachedZapForm;
}
function getZapAmountInput() {
if (cachedZapAmountInput && !document.body.contains(cachedZapAmountInput)) {
cachedZapAmountInput = null;
@@ -250,6 +274,16 @@ function getZapReceiptsList() {
return cachedZapReceipts;
}
function getZapSendButton() {
if (cachedZapSendBtn && !document.body.contains(cachedZapSendBtn)) {
cachedZapSendBtn = null;
}
if (!cachedZapSendBtn) {
cachedZapSendBtn = document.getElementById("zapSendBtn");
}
return cachedZapSendBtn;
}
function getZapWalletPrompt() {
if (cachedZapWalletPrompt && !document.body.contains(cachedZapWalletPrompt)) {
cachedZapWalletPrompt = null;
@@ -528,6 +562,13 @@ function resetZapRetryState() {
zapButton.setAttribute("aria-label", "Open zap dialog");
zapButton.title = "Open zap dialog";
}
const sendButton = getZapSendButton();
if (sendButton) {
delete sendButton.dataset.retryPending;
sendButton.textContent = "Send";
sendButton.setAttribute("aria-label", "Send a zap");
sendButton.removeAttribute("title");
}
}
function markZapRetryPending(shares) {
@@ -546,6 +587,13 @@ function markZapRetryPending(shares) {
zapButton.setAttribute("aria-label", "Retry failed zap shares");
zapButton.title = "Retry failed zap shares";
}
const sendButton = getZapSendButton();
if (sendButton) {
sendButton.dataset.retryPending = "true";
sendButton.textContent = "Retry";
sendButton.setAttribute("aria-label", "Retry failed zap shares");
sendButton.title = "Retry failed zap shares";
}
}
function getZapVideoEvent() {
@@ -947,16 +995,39 @@ async function executePendingRetry({ walletSettings }) {
resetZapRetryState();
}
async function handleZapButtonClick(event) {
function handleZapButtonClick(event) {
if (event) {
event.preventDefault();
}
const zapButton = getChannelZapButton();
if (!zapButton) {
return;
}
if (!isZapControlsOpen()) {
openZapControls({ focus: true });
return;
}
if (zapInFlight) {
return;
}
closeZapControls({ focusButton: true });
}
async function handleZapSend(event) {
if (event?.preventDefault) {
event.preventDefault();
}
const zapButton = getChannelZapButton();
const amountInput = getZapAmountInput();
const sendButton = getZapSendButton();
const app = getApp();
if (!zapButton || !amountInput) {
if (!amountInput || !sendButton) {
return;
}
@@ -966,8 +1037,9 @@ async function handleZapButtonClick(event) {
}
if (!currentChannelLightningAddress) {
setZapStatus("This creator has not configured a Lightning address yet.", "error");
app?.showError?.("This creator has not configured a Lightning address yet.");
const message = "This creator has not configured a Lightning address yet.";
setZapStatus(message, "error");
app?.showError?.(message);
return;
}
@@ -981,9 +1053,13 @@ async function handleZapButtonClick(event) {
}
zapInFlight = true;
zapButton.disabled = true;
zapButton.setAttribute("aria-busy", "true");
zapButton.classList.add("opacity-50", "pointer-events-none");
if (zapButton) {
zapButton.disabled = true;
zapButton.setAttribute("aria-disabled", "true");
}
sendButton.disabled = true;
sendButton.setAttribute("aria-busy", "true");
sendButton.classList.add("opacity-50", "pointer-events-none");
amountInput.disabled = true;
let attemptedAmount = null;
@@ -1028,7 +1104,7 @@ async function handleZapButtonClick(event) {
? error.__zapShareTracker
: [];
logZapError(
"handleZapButtonClick",
"handleZapSend",
{
amount: attemptedAmount,
walletSettings,
@@ -1055,8 +1131,8 @@ async function handleZapButtonClick(event) {
const tone = tracker.length > failureShares.length ? "warning" : "error";
const statusMessage =
tracker.length > failureShares.length
? `Partial zap failure. Tap zap again to retry: ${summary}.`
: `Zap failed. Tap zap again to retry: ${summary}.`;
? `Partial zap failure. Press Send again to retry: ${summary}.`
: `Zap failed. Press Send again to retry: ${summary}.`;
setZapStatus(statusMessage, tone);
app?.showError?.(error?.message || statusMessage);
} else {
@@ -1067,9 +1143,13 @@ async function handleZapButtonClick(event) {
}
} finally {
zapInFlight = false;
zapButton.disabled = false;
zapButton.removeAttribute("aria-busy");
zapButton.classList.remove("opacity-50", "pointer-events-none");
if (zapButton) {
zapButton.disabled = false;
zapButton.removeAttribute("aria-disabled");
}
sendButton.disabled = false;
sendButton.removeAttribute("aria-busy");
sendButton.classList.remove("opacity-50", "pointer-events-none");
amountInput.disabled = false;
}
}
@@ -1297,7 +1377,8 @@ function setupZapButton() {
const zapButton = getChannelZapButton();
const amountInput = getZapAmountInput();
const controls = getZapControlsContainer();
if (!zapButton || !amountInput || !controls) {
const zapForm = getZapFormElement();
if (!zapButton || !amountInput || !controls || !zapForm || !getZapSendButton()) {
return;
}
@@ -1332,6 +1413,10 @@ function setupZapButton() {
updateZapSplitSummary();
amountInput.addEventListener("input", handleZapAmountChange);
amountInput.addEventListener("change", handleZapAmountChange);
if (zapForm.dataset.initialized !== "true") {
zapForm.addEventListener("submit", handleZapSend);
zapForm.dataset.initialized = "true";
}
zapButton.addEventListener("click", handleZapButtonClick);
zapButton.dataset.initialized = "true";
}
+2 -2
View File
@@ -857,7 +857,7 @@ export class VideoModal {
if (pending) {
this.modalZapSendBtn.dataset.retryPending = "true";
this.modalZapSendBtn.textContent = "Retry zap";
this.modalZapSendBtn.textContent = "Retry";
this.modalZapSendBtn.setAttribute(
"aria-label",
"Retry failed zap shares"
@@ -867,7 +867,7 @@ export class VideoModal {
}
} else {
delete this.modalZapSendBtn.dataset.retryPending;
this.modalZapSendBtn.textContent = "Send zap";
this.modalZapSendBtn.textContent = "Send";
this.modalZapSendBtn.setAttribute("aria-label", "Send a zap");
this.modalZapSendBtn.removeAttribute("title");
}
+46 -32
View File
@@ -53,7 +53,7 @@
aria-label="Channel zap dialog"
>
<div
class="zap-popover__content w-72 max-w-[calc(100vw-2rem)] rounded-lg bg-gray-900/95 p-4 shadow-lg backdrop-blur"
class="zap-popover__content w-72 max-w-[calc(100vw-2rem)] rounded-lg p-4 shadow-lg"
>
<div class="mb-3 flex items-center justify-between gap-4">
<h3
@@ -85,37 +85,51 @@
</button>
to send zaps.
</p>
<label
for="zapAmountInput"
id="zapAmountLabel"
class="mb-2 block text-xs font-semibold uppercase tracking-wide text-gray-300"
>
Zap amount (sats)
</label>
<input
id="zapAmountInput"
type="number"
min="1"
step="1"
inputmode="numeric"
class="w-full rounded border border-gray-600 bg-gray-800 px-3 py-2 text-sm text-gray-100 focus:border-blue-400 focus:outline-none focus:ring-1 focus:ring-blue-400"
placeholder="Enter sats"
aria-labelledby="zapAmountLabel"
/>
<p
id="zapSplitSummary"
class="mt-3 text-sm text-gray-300"
aria-live="polite"
>
Enter an amount to view the split.
</p>
<p
id="zapStatus"
class="mt-2 text-xs text-gray-400"
role="status"
aria-live="polite"
></p>
<ul id="zapReceipts" class="mt-3 space-y-2 text-xs text-gray-300"></ul>
<form id="zapForm" class="space-y-3">
<div>
<label
for="zapAmountInput"
id="zapAmountLabel"
class="mb-2 block text-xs font-semibold uppercase tracking-wide text-gray-300"
>
Zap amount (sats)
</label>
<input
id="zapAmountInput"
type="number"
min="1"
step="1"
inputmode="numeric"
class="w-full rounded border border-gray-600 bg-gray-800 px-3 py-2 text-sm text-gray-100 focus:border-blue-400 focus:outline-none focus:ring-1 focus:ring-blue-400"
placeholder="Enter sats"
aria-labelledby="zapAmountLabel"
/>
</div>
<p
id="zapSplitSummary"
class="text-sm text-gray-300"
aria-live="polite"
>
Enter an amount to view the split.
</p>
<p
id="zapStatus"
class="text-xs text-gray-400"
role="status"
aria-live="polite"
></p>
<ul id="zapReceipts" class="space-y-2 text-xs text-gray-300"></ul>
<div class="flex items-center justify-end gap-2">
<button
type="submit"
id="zapSendBtn"
class="rounded bg-blue-500 px-4 py-2 text-sm font-semibold text-white transition-colors hover:bg-blue-600 focus:outline-none focus:ring-2 focus:ring-blue-400 focus:ring-offset-2 focus:ring-offset-gray-900"
aria-label="Send a zap"
>
Send
</button>
</div>
</form>
</div>
</div>
</div>