From 8fd5ce3c880dc34ef136d9067e43f0e46e780269 Mon Sep 17 00:00:00 2001
From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com>
Date: Sun, 5 Oct 2025 18:45:03 -0400
Subject: [PATCH] Darken zap dialog and add send control
---
components/video-modal.html | 4 +-
css/style.css | 6 ++
js/app.js | 4 +-
js/channelProfile.js | 113 +++++++++++++++++++++++++++++----
js/ui/components/VideoModal.js | 4 +-
views/channel-profile.html | 78 +++++++++++++----------
6 files changed, 157 insertions(+), 52 deletions(-)
diff --git a/components/video-modal.html b/components/video-modal.html
index b48e26e9..3045c03f 100644
--- a/components/video-modal.html
+++ b/components/video-modal.html
@@ -58,7 +58,7 @@
aria-hidden="true"
>
- Send zap
+ Send
diff --git a/css/style.css b/css/style.css
index dea54de6..aad9283e 100644
--- a/css/style.css
+++ b/css/style.css
@@ -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 {
diff --git a/js/app.js b/js/app.js
index fd850e14..008aadf6 100644
--- a/js/app.js
+++ b/js/app.js
@@ -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 {
diff --git a/js/channelProfile.js b/js/channelProfile.js
index 7d634d17..20cb7549 100644
--- a/js/channelProfile.js
+++ b/js/channelProfile.js
@@ -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";
}
diff --git a/js/ui/components/VideoModal.js b/js/ui/components/VideoModal.js
index 701db469..4993d2fd 100644
--- a/js/ui/components/VideoModal.js
+++ b/js/ui/components/VideoModal.js
@@ -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");
}
diff --git a/views/channel-profile.html b/views/channel-profile.html
index 9ba77323..90747dd6 100644
--- a/views/channel-profile.html
+++ b/views/channel-profile.html
@@ -53,7 +53,7 @@
aria-label="Channel zap dialog"
>
to send zaps.
-
-
-
- Enter an amount to view the split.
-
-
-
+