Merge pull request #2652 from PR0M3TH3AN/agents/weekly/ui-ux-upload-modal-9071792270818240779

Replace alert() with non-blocking notifications in UploadModal
This commit is contained in:
thePR0M3TH3AN authored and GitHub committed 2026-02-21 13:18:43 -05:00
commit c5388fac76
3 files changed
+35 -10

No files matched your search

@@ -0,0 +1,19 @@
# Weekly Agent Task Log: 2025-02-21 (Jules)
**Agent:** ui-ux-marketing-expert
**Status:** Completed
## Execution Summary
1. **Scheduler Setup:**
* Skipped `nostr-lock.mjs` as the script was missing from the environment.
* Created log directory.
2. **UI/UX Expert Task:**
* **Audit:** Audited `js/ui/profileModalController.js` and `views/` for hardcoded styles. No significant violations found (clean use of utility classes).
* **Remediation:** Identified `alert()` calls in `js/ui/components/UploadModal.js` as a UX violation (blocking UI). Replaced all instances with `this.showError()` or `this.showSuccess()` to align with the design system.
* **Documentation:** Updated `docs/design-system.md` to explicitly forbid `alert()`/`confirm()` and recommend non-blocking alternatives.
3. **Verification:**
* Ran `tests/ui/uploadModal-integration.test.mjs`: Passed.
* Ran `npm run lint`: Passed.
+6
View File
@@ -181,6 +181,12 @@ Mix in Tailwind utilities for icon spacing (`gap-3`), sizing (`px-lg`, `py-sm`),
`.badge` renders an inline pill (`bg-panel`, uppercase text). Opt into semantic variants with `data-variant="info"`, `data-variant="critical"`, or `data-variant="neutral"`. Layer on utilities for icon alignment or truncation.
### Interaction Guidelines
- **No blocking alerts:** Do not use `window.alert()` or `window.confirm()`. These native modals block the main thread and disrupt the user experience.
- **Preferred pattern:** Use the `showError(message)` and `showSuccess(message)` callbacks provided to controllers, or render inline `.notification-banner` elements for persistent feedback.
- **Complex confirmations:** For destructive actions requiring confirmation, use a dedicated modal or a two-step button state (e.g., "Click to confirm") rather than a native confirm dialog.
### Messaging & Notification Tokens
Use the dedicated messaging tokens when styling chat surfaces and banners so they inherit theme-safe contrast and icon colors:
+10 -10
View File
@@ -477,12 +477,12 @@ export class UploadModal {
if (!file) return;
if (!this.storageConfigured) {
alert("Please configure storage before selecting a file.");
this.showError("Please configure storage before selecting a file.");
e.target.value = ""; // Clear selection
return;
}
if (!this.isStorageUnlocked) {
alert("Please unlock storage before selecting a file.");
this.showError("Please unlock storage before selecting a file.");
e.target.value = "";
return;
}
@@ -696,7 +696,7 @@ export class UploadModal {
if (this.results.magnet) this.results.magnet.value = "Upload Failed";
if (this.results.torrentUrl) this.results.torrentUrl.value = "Upload Failed";
alert(`Upload failed: ${err.message}`);
this.showError(`Upload failed: ${err.message}`);
this.inputs.file.value = ""; // Reset
}
@@ -798,7 +798,7 @@ export class UploadModal {
userLogger.error("Thumbnail upload failed:", err);
this.thumbnailUploadState.status = 'error';
this.updateThumbnailProgress(null, "Failed.");
alert("Thumbnail upload failed.");
this.showError("Thumbnail upload failed.");
}
}
@@ -934,7 +934,7 @@ export class UploadModal {
? signer.canSign()
: typeof signer?.signEvent === "function";
if (!canSign) {
alert("No signer available to unlock storage.");
this.showError("No signer available to unlock storage.");
return;
}
@@ -942,7 +942,7 @@ export class UploadModal {
if (signer?.type === "extension") {
const permissionResult = await requestDefaultExtensionPermissions();
if (!permissionResult?.ok) {
alert("Extension permissions are required to unlock storage.");
this.showError("Extension permissions are required to unlock storage.");
return;
}
}
@@ -956,7 +956,7 @@ export class UploadModal {
await this.loadFromStorage();
} catch (err) {
userLogger.error("Unlock failed", err);
alert("Failed to unlock storage: " + err.message);
this.showError("Failed to unlock storage: " + err.message);
} finally {
if (this.toggles.storageUnlock) {
this.toggles.storageUnlock.textContent = "Unlock";
@@ -1012,17 +1012,17 @@ export class UploadModal {
// Check upload state
if (this.activeSource === "upload") {
if (this.videoUploadState.status === 'uploading' || this.thumbnailUploadState.status === 'uploading') {
alert("Please wait for uploads to complete.");
this.showError("Please wait for uploads to complete.");
return;
}
if (this.videoUploadState.status === 'error') {
alert("Video upload failed. Please try again.");
this.showError("Video upload failed. Please try again.");
return;
}
if (this.videoUploadState.status !== 'complete') {
// Fallback: If no file selected, maybe they want to submit without a new file?
// (Not supported in this simplified modal, assume file required)
alert("Please select a video file and wait for it to upload.");
this.showError("Please select a video file and wait for it to upload.");
return;
}
}