- Moved NIP-07 extension detection and permission logic from `NostrClient` to `nip07` provider.
- Removed redundant `login` method from `NostrClient`.
- Increased concurrency and added timeouts to `fetchListIncrementally` to prevent hanging on slow relays.
- Updated `UserBlocks` to force full fetch on cache miss, fixing "empty list" issues.
- Updated unit tests for login permissions and hashtag preferences to reflect architectural changes.
Co-authored-by: PR0M3TH3AN <[email protected]>
- Wrapped NIP-07 adapter extension calls in `retryNip07Call` to handle transient failures and timeouts robustly.
- Updated `HashtagPreferencesService` to autosave changes to relays immediately on modification.
- Added race condition protection in `HashtagPreferencesService.load` to prevent overwriting optimistic local updates with stale relay data.
Co-authored-by: PR0M3TH3AN <[email protected]>
- Update `fetchListIncrementally` in `js/nostr/client.js` to throw an error if all relays fail, preventing empty returns from being interpreted as data loss.
- Update `HashtagPreferencesService`, `UserBlockListManager`, and `SubscriptionsManager` to handle fetch errors gracefully without wiping local state.
- Update `js/nostr/nip07Permissions.js` to use a short timeout (3s) for experimental permission requests, fixing "clunky" login issues while preserving user interaction time for standard login.
- Remove `try/catch` in `adminListStore.js` fetch logic to allow error propagation to the fallback cache logic.
Co-authored-by: PR0M3TH3AN <[email protected]>
- Updated `NostrClient.fetchListIncrementally` to accept a `since` override.
- Updated `HashtagPreferencesService.load` to pass `since` based on local cache timestamp.
- Ensures preferences are refreshed if local state is stale or missing, overriding potentially incorrect `SyncMetadataStore` state.
- Added regression tests for `fetchListIncrementally` since parameter logic.
Co-authored-by: PR0M3TH3AN <[email protected]>
- Implemented optimistic UI updates for the channel subscribe button to improve responsiveness.
- Fixed a race condition in `js/subscriptions.js` and `js/services/hashtagPreferencesService.js` where lists were wiped on refresh due to `profileCache.activePubkey` not being initialized in time. Now using `profileCache.getProfileData(pubkey, ...)` to ensure the correct cache entry is loaded.
- Validated with targeted unit tests.
Co-authored-by: PR0M3TH3AN <[email protected]>
Removes a redundant `const normalizedInfoHash` declaration in `s3UploadService.js` that caused a `SyntaxError` and prevented the application from loading. The variable is already declared in the outer scope of the `try` block.
Introduces a race condition between the primary playback source (URL or Torrent) and a configurable timeout. If the primary source fails to reach the 'playing' state within the timeout window, the system automatically falls back to the alternative source.
- Adds `DEFAULT_PLAYBACK_START_TIMEOUT` to instance config (3000ms).
- Updates `PlaybackService` to implement timeout logic using `withTimeout` wrapper.
- Ensures proper cleanup of stalled attempts (resetting video element, destroying torrent client).
- Added `DEFAULT_PLAYBACK_SOURCE` to `config/instance-config.js` to allow choosing between "url" (default) and "torrent" priority.
- Updated `js/constants.js` to derive `URL_FIRST_ENABLED` flag from the configuration.
- Refactored `PlaybackService.execute()` in `js/services/playbackService.js` to robustly support "Torrent First" logic with fallback to URL, while maintaining "URL First" with fallback to Torrent.
- Added unit tests in `tests/services/playbackService_order.test.mjs` to verify playback order and fallback mechanics.
- Refactored `UploadModal.js` to trigger uploads immediately on file selection.
- Added progress bars and result fields (Video URL, Magnet, Torrent) to the UI.
- Fixed a crash in `r2Service.js` caused by `userLogger.debug` usage.
- Exposed `prepareUpload` and `uploadFile` methods in `r2Service` and `s3UploadService` for granular control.
- Updated `upload-modal.html` with new UI elements.
Previously, `StorageService.saveConnection` allowed multiple connections to be marked as `defaultForUploads: true` because it did not unset the flag on existing connections. This caused `loadFromStorage` (which uses `find`) to potentially pick up an old, invalid connection instead of the newly configured one, leading to a loop where the user is asked to configure credentials again.
This change modifies `saveConnection` to iterate through existing connections and unset `defaultForUploads` if the new connection is being saved as the default. This ensures the "default" invariant is maintained.
Added a unit test case to verify this behavior.
Introduced `waitForReady` in `AccessControl` to block until moderation lists are fetched, and updated `playVideoByEventId` and `trustBootstrap` to use it, preventing false "not whitelisted" errors in private tabs.
- Deleted `js/magnet.js` as it was a redundant wrapper for `js/magnetUtils.js`.
- Refactored `js/services/videoNotePayload.js`, `js/ui/components/EditModal.js`, and `js/nostr/nip71.js` to use `magnetUtils.js` and `magnetShared.js`.
- Updated `tests/magnet-utils.test.mjs` to remove tests for the deleted file.
- Removed unused exports `DEFAULT_FEED_CONFIG` and `DEFAULT_CONFIG_SCHEMA` from `js/feedEngine/engine.js` and `index.js`.
- Verified changes with unit tests.
- Format `css/tailwind.source.css` with Prettier.
- Add allowlist entry for `VideoCard.js` media query pixel value in `scripts/check-design-tokens.mjs`.
- Remove accidental artifact `js/ui/dm/jules_session_4520373547615093905.zip`.
- Fix bug in `js/app.js` and `js/services/moderationActionController.js` where blocked users' videos were not correctly hidden in the UI immediately after blocking.
- Fix bug in `tests/app/moderation-overrides.test.mjs` where `userBlocks` mocks were insufficient to reflect state changes.
- Reduced view threshold from 12s to 5s in watchHistoryTelemetry.js
- Enabled immediate watch history republishing (0ms delay) for the first attempt in watchHistory.js
- Updated watchHistoryService.js to recursively schedule queue flushes if items accumulate during an inflight sync
Extracts `decorateVideoModeration` and related helper methods from `js/app.js` into a new `js/services/moderationDecorator.js` service. This improves separation of concerns by moving complex moderation logic out of the main application class.
AGENTS.md Checklist:
1. Identify Logic: Extracted `decorateVideoModeration`, `deriveModerationReportType`, `deriveModerationTrustedCount`, `getReporterDisplayName`, `normalizeModerationSettings`, `getActiveModerationThresholds`.
2. Create Controller Method: Created `ModerationDecorator` class with `decorateVideo` method.
3. Create `bitvidApp` Wrapper: Replaced `decorateVideoModeration` in `js/app.js` with a wrapper that delegates to `this.moderationDecorator.decorateVideo`.
4. Wire Up Callbacks: Passed `getProfileCacheEntry` to `ModerationDecorator` constructor.
5. Remove Old Code: Removed extracted methods from `js/app.js`.
Also added unit tests for `ModerationDecorator` and ensured runtime settings updates are propagated.