Updated `r2Service.js` to detect if the user inputs an S3 API endpoint (e.g. `*.r2.cloudflarestorage.com`) as the Public Bucket URL. If detected, it prevents saving and displays a clear error message instructing the user to use the correct public domain (e.g. `*.r2.dev`). This prevents CORS errors and confusion caused by using the wrong endpoint type.
- Switched to `esm.sh` bundle for `@aws-sdk/client-s3` to fix browser compatibility and `fs.readFile` errors.
- Removed `cf-create-bucket-if-missing` header from `multipartUpload` to prevent 403 Forbidden/CORS failures with standard API tokens.
- Refactored `verifyPublicAccess` to attempt CORS setup even if bucket check fails, and added specific error messaging for CORS issues.
- Updated documentation to include `POST` and `HEAD` in the recommended R2 CORS policy.
1. **Refactor R2 Verification**: Separated bucket existence checks from CORS configuration in `r2Service.js`. Previously, if `HeadBucket` failed (e.g., due to CORS restrictions), the CORS configuration step was skipped. Now, CORS setup is attempted independently, increasing the chance of successful auto-configuration.
2. **Improve Error Messaging**: Enhanced error handling in `verifyPublicAccess` to detect "Failed to fetch" errors and explicitly suggest checking Cloudflare R2 CORS settings in the UI.
3. **Fix AWS SDK Import**: Consolidated the AWS SDK import fix to use the `?bundle` version from `esm.sh` in `r2-s3.js`. This prevents `fs.readFile` runtime errors by ensuring a browser-compatible build is loaded.
- Fix circular dependency in `js/adminListStore.js` by importing from `js/nostrClientRegistry.js`.
- Update `js/services/hashtagPreferencesService.js` to include legacy kind 30005 in filters.
- Fix JSDOM mocking in `tests/modal-accessibility.test.mjs` (navigator getter) and `UploadModal` selectors.
- Add `getRoot()` to `js/ui/components/UploadModal.js` for API consistency.
- Update `tests/magnet-utils.test.mjs` expectations to reflect removed default tracker.
- Mock `ensureActiveSignerForPubkey` in `tests/moderation/submit-report.test.mjs`.
- Fix mock loader path in `tests/moderation/trust-seeds.test.mjs` to target `trustBootstrap.js`.
- Fix duplicate pointer tags in `js/nostrEventSchemas.js`'s `buildCommentEvent`.
- Update `tests/nostr/comment-events.test.mjs` and `tests/comment-event-builder.test.mjs` to match current code behavior (legacy kinds, unique tags).
- Added `deleteObject` to `js/storage/r2-s3.js` for cleanup.
- Added `verifyPublicAccess` to `js/services/r2Service.js` to test bucket configuration.
- Refactored `components/upload-modal.html` to support wizard steps.
- Updated `js/ui/components/UploadModal.js` to manage wizard state and trigger verification.
- Updated `R2Service` to attempt bucket creation via S3 API (`ensureBucketExists`) before upload. This improves the UX for users with Admin keys or custom domains while gracefully failing (with a warning) for users with minimal permissions.
- Modified `UploadModal` helper text to explicitly instruct users about enabling "Public Access" in the Cloudflare dashboard for new buckets.
- Updated `js/r2.js` to ensure the "Public Bucket URL" is always sanitized to include the `https://` protocol, fixing potential webseed generation issues.
- Removed requirement for Cloudflare API Token, Zone ID, and Worker Token from Upload Modal and R2Service.
- Simplified R2 configuration to require only Account ID, S3 Access Keys, and a user-provided Public Bucket URL.
- Added a read-only field in Upload Modal displaying the derived target bucket name (npub-based) for user reference.
- Implemented client-side torrent info hash calculation using `WebTorrent` (via `js/utils/torrentHash.js`) to generate magnet links before upload.
- Added a visual upload progress bar to the Upload Modal.
- Updated `js/r2.js` to ensure the Public Bucket URL always includes the `https://` protocol.
- Update `ModerationService` to recognize session actors and load mutes from local storage.
- Update `UserBlockListManager` to persist blocks locally for session actors without relay publication.
- Ensure `submitReport` falls back to the session actor's signer.
- Add `resolveStorage` helper to safely access localStorage.
- Fixed `ModerationService.reconcileTrustedMuteSubscriptions` to always force re-subscription to trusted seeds, bypassing previous state comparisons.
- Enhanced `ModerationService` to filter trusted seeds against the global admin blacklist.
- Added blacklist change event support to `AccessControl` and `TrustBootstrap` to dynamically update seeds when the blacklist changes.
- Added detailed logging to `ModerationService`, `TrustBootstrap`, and `AccessControl` to trace trust seed initialization and application.
- Fixed `ModerationService.reconcileTrustedMuteSubscriptions` to always force re-subscription to trusted seeds, bypassing previous state comparisons.
- Enhanced `ModerationService` to filter trusted seeds against the global admin blacklist.
- Added blacklist change event support to `AccessControl` and `TrustBootstrap` to dynamically update seeds when the blacklist changes.
- Added detailed logging to `ModerationService` for tracking subscription lifecycle.
- Fixed `ModerationService.clearTrustedMuteTracking` to properly force re-subscription to trusted seeds by passing an empty previous state.
- Enhanced `ModerationService` to filter trusted seeds against the global admin blacklist.
- Added blacklist change event support to `AccessControl` and `TrustBootstrap` to dynamically update seeds when the blacklist changes.
- Added file input and browse button for thumbnails in `upload-modal.html`.
- Updated `UploadModal.js` to handle thumbnail file selection and UI toggling.
- Updated `r2Service.js` to upload thumbnail file (if present) to R2 and update metadata.
- Ensured thumbnail keys are derived from video keys for consistent naming.
- Add new "Setup Guide" section to `docs/storage-r2.md` detailing the dual-credential requirement (S3 Keys + Cloudflare API Token) for full automation.
- Remove unsupported "manual/S3-only" workflow documentation to prevent user confusion.
- Update `js/services/r2Service.js` error message to explicitly prompt users for an API Token when the public domain is missing, instead of suggesting manual configuration.
Integrates WebTorrent client-side seeding into the Cloudflare R2 upload path.
- Adds `uploadFile` to `r2Service` for generic file uploads.
- Updates `UploadModal` to offer an optional "Create torrent & seed" flow.
- Generates magnet links and .torrent files in the browser after R2 upload.
- Uploads the .torrent file to R2 and populates `xs` tag.
- Populates `ws` (Web Seed) with the R2 public URL.
- Adds UI progress indicators for hashing and torrent upload.
- Enforces a 2GB file size limit for browser seeding to prevent crashes.
- Adds a mandatory legal rights confirmation checkbox for R2 uploads.
- Moves `bootstrapTrustedSeeds` logic from `js/bootstrap.js` to a new service `js/services/trustBootstrap.js`.
- Updates `js/app.js` to explicitly await `nostrClient.init()` before calling `bootstrapTrustedSeeds()`, resolving race conditions where admin lists were fetched before the relay pool was ready.
- Ensures `waitForRelaysReady` checks for `nostrClient.pool` existence.
Removes the metadata argument from `WatchHistoryService.publishView` and cleans up the associated caching and resolution logic in `watchHistory.js` and `watchHistoryFeed.js`. Deletes `js/watchHistoryMetadata.js` as it is no longer used.
This simplification ensures watch history strictly manages pointers and timestamps, leaving metadata resolution to higher-level consumers. It also reduces the payload size and complexity of persisted history records.
Tests have been updated to reflect the API changes.