Commit Graph
534 Commits
Author SHA1 Message Date
google-labs-jules[bot]andPR0M3TH3AN 555df62529 fix: resolve SyntaxError in js/app.js due to duplicate code block
Removed a duplicate/malformed code block in `js/app.js` that was causing `SyntaxError: Unexpected token '.'` during module loading. This error was breaking tests in `tests/app/channel-profile-moderation.test.mjs` and others.

Also restored `_initNostr` and `_initSessionActor` methods which were partially clobbered or malformed in the file structure.

Verified by running the affected unit tests locally.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-08 01:50:26 +00:00
thePR0M3TH3AN ae5174600d Merge branch 'unstable' into chore/code-health/remove-unused-promises-app-init-18262315909809877684 2026-02-07 20:07:22 -05:00
thePR0M3TH3AN 91cc2781b0 Merge pull request #2218 from PR0M3TH3AN/refactor-application-srp-12044709703939300356
🧹 Refactor Application to use AuthService and PlaybackService for state access
2026-02-07 20:04:32 -05:00
thePR0M3TH3AN 55269077ae Merge pull request #2217 from PR0M3TH3AN/refactor-feed-refresh-logic-11328377621655034485
Refactor duplicate feed refresh logic
2026-02-07 19:40:45 -05:00
google-labs-jules[bot]andPR0M3TH3AN 23b9e36958 Refactor Application.init method to improve readability and maintainability.
- Extracted logic into `_init*` private helper methods.
- Preserved execution order and async behavior.
- Cleaned up the main `init` method to act as an orchestrator.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-08 00:36:14 +00:00
google-labs-jules[bot]andPR0M3TH3AN bcacf46f8b Refactor Application to delegate state management to services
Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-08 00:36:05 +00:00
google-labs-jules[bot]andPR0M3TH3AN b094d2a035 Refactor duplicate feed refresh logic into unified refreshFeed method
- Unify `refreshForYouFeed`, `refreshKidsFeed`, `refreshExploreFeed`, and `refreshRecentFeed` into `refreshFeed(feedType, options)`.
- Update `js/app/feedCoordinator.js` to implement `refreshFeed` and use it in `loadFeedVideos`.
- Update `js/app.js` to delegate specific methods to `refreshFeed`.
- Add `FEED_TYPES` import to `js/app.js`.
- Update `tests/app/feedCoordinator.test.mjs` to match the refactoring.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-08 00:35:47 +00:00
google-labs-jules[bot]andPR0M3TH3AN 12ba9f07e6 chore: remove dead code and unused promises in Application.init
Removes commented-out `await Promise.all` and refactors the associated
`accessControlPromise` and `adminPanePromise` variables in `js/app.js`.

The promises were only assigned for use in the commented-out line.
This change:
- Converts `accessControl.refresh()` to a direct expression statement.
- Simplifies `adminPanePromise` logic into a direct `if` block, removing
  the unnecessary `else { Promise.resolve(null) }` branch.
- Preserves the existing fire-and-forget behavior for these initialization tasks.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-07 23:56:45 +00:00
google-labs-jules[bot]andPR0M3TH3AN 9571e3aedb Fix crash in feed loading by delegating loadFeedVideos
The `loadFeedVideos` method was missing from the `Application` class in `js/app.js`, but was being called by `loadVideos` inside the feed coordinator (which is bound to the application instance). This caused a `TypeError: this.loadFeedVideos is not a function` at runtime.

This change adds the missing delegation method to `Application` in `js/app.js`, forwarding the call to `this._feed.loadFeedVideos`.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-07 23:55:17 +00:00
google-labs-jules[bot]andPR0M3TH3AN aae2ea7d16 perf: use batch fetch for profile refresh
Replaces the sequential loop in `forceRefreshAllProfiles` with `batchFetchProfiles` to reduce network requests.
Updates `batchFetchProfilesFromRelays` to support `forceRefresh`, ensuring fresh data is requested while maintaining optimistic UI updates.
Adds unit tests for `forceRefresh` behavior.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-07 23:15:13 +00:00
thePR0M3TH3AN c539fef553 Merge pull request #2183 from PR0M3TH3AN/jules-fix-unused-import-appjs-3659969045676148831
chore(js): remove unused splitAndZap import in app.js
2026-02-07 17:40:17 -05:00
google-labs-jules[bot]andPR0M3TH3AN 31dc297991 chore(js): remove unused splitAndZap import in app.js
Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-07 22:14:19 +00:00
thePR0M3TH3AN 38f63e5851 Merge pull request #2181 from PR0M3TH3AN/refactor/deduplicate-hex64-regex-4819369490365472168
🧹 Refactor: Deduplicate HEX64_REGEX constant
2026-02-07 16:57:49 -05:00
google-labs-jules[bot]andPR0M3TH3AN a084bb59de refactor: deduplicate HEX64_REGEX to js/utils/hex.js
Moves the repeatedly defined HEX64_REGEX constant to a shared utility
module to improve maintainability and consistency. Updates all consumers
to import from the new location.

Signed-off-by: Jules <[email protected]>

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-07 21:52:51 +00:00
google-labs-jules[bot]andPR0M3TH3AN 5f12eadd4d chore: remove unused MAX_WALLET_DEFAULT_ZAP import from app.js
Removes the unused `MAX_WALLET_DEFAULT_ZAP` import from `js/app.js` to improve code health and reduce confusion. This variable was imported from `config.js` but never used within `app.js`.

Verification:
- Confirmed `MAX_WALLET_DEFAULT_ZAP` is not present in `js/app.js`.
- Ran `tests/app/is-user-logged-in.test.mjs` to ensure `js/app.js` still loads and functions correctly.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-07 21:42:58 +00:00
Claude 3a55e1bf03 fix: resolve coordinator refactoring regressions breaking DM, lists, and feed pipeline
- Remove undefined hashtagPreferencesPromise reference in handleAuthLogin
  that caused the feed sync Promise.allSettled to silently fail, preventing
  proper list/profile synchronization before grid refresh
- Add missing getModerationSettings and getActiveProfilePubkey dependency
  injection to authSessionCoordinator, fixing crashes during logout
  moderation reset and profile switch pubkey resolution
- Parallelize NIP-07 permission request with relay readiness instead of
  gating list loading behind it; parallelize subscriptions and hashtag
  preference loading (independent of each other, only blocks must sequence)
- Add native run() alias to feedEngine so callers don't rely solely on
  the applicationBootstrap compatibility shim
- Remove redundant refreshVisibleModerationUi call from renderVideoList
  that re-decorated every video immediately after decoration
- Avoid re-normalizing moderation settings on every getActiveModerationThresholds
  call when settings are already an object

https://claude.ai/code/session_01FCosieUXjEn95KtUeyGemY
2026-02-06 21:42:49 +00:00
Claude 41a12669f6 refactor: extract Application method clusters into coordinator modules
Move cohesive method groups out of the monolithic Application class
(js/app.js, ~10K lines) into five coordinator modules under js/app/:

- feedCoordinator: feed registration, runtime building, refresh,
  video loading, URL-health helpers, and feed telemetry
- playbackCoordinator: URL-first + magnet fallback pipeline, probing,
  torrent status intervals, and video timestamp resolution
- authSessionCoordinator: signer lifecycle, profile switching,
  relay/block/wallet management, and cleanup
- modalCoordinator: modal open/close, view-count subscriptions,
  watch-history metadata, and playback logging
- moderationCoordinator: moderation settings, video decoration,
  override/block/hide action routing

Each coordinator factory receives injected dependencies instead of
importing globals. Application retains thin delegator methods so all
public call-sites remain unchanged. Coordinator initialisation is
idempotent (via _initCoordinators) and supports both constructor-based
and Object.create()-based instantiation used by test harnesses.

All existing unit tests, lint checks, and syntax validation pass.

https://claude.ai/code/session_01C3PKJTCdavsGbk5jjC85EB
2026-02-06 20:47:10 +00:00
Claude 416a809ae4 fix: apply block/mute list filtering to DM messages and conversations
The user's block/mute list (NIP-51) was not being checked when
processing direct messages, allowing blocked users' messages to appear
in conversations, trigger notifications, and increment unseen counts.

This adds block filtering at four layers:
- nostrService.applyDirectMessage: drops incoming DMs from blocked users
  before they enter the in-memory message cache
- nostrService.persistDirectMessageRecord: prevents blocked DM senders
  from being persisted to IndexedDB or triggering notifications
- profileModalController.buildDmConversationData: filters blocked users
  from the conversation list UI (catches pre-block persisted messages)
- applicationBootstrap: excludes blocked-user conversations from the
  unread DM badge count

The block checker is injected via setDmBlockChecker() to keep
nostrService decoupled from userBlocks, wired up in app.js init().

https://claude.ai/code/session_01EAVLtAM14GN99Eik8otLg2
2026-02-06 19:41:50 +00:00
google-labs-jules[bot]andPR0M3TH3AN a375b8336b Fix slow/failing NIP-07 private-list sync & decryption
- Implemented concurrent queue for NIP-07 requests (max 2)
- Added pre-authorization step at login to prevent redundant prompts
- Sequentialized critical list loading (blocks, subscriptions)
- Optimized decryption with result caching and high priority for critical lists
- Fixed MaxListenersExceededWarning by increasing relay listener limit
- Added concurrency tests

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-06 01:26:41 +00:00
Claude 8a335c2ec8 Fix slow Nostr list sync by decoupling from profile and awaiting before feed render
The login-to-feed pipeline had several issues causing lists (blocks,
subscriptions, hashtag preferences) to load too slowly or not reflect
in the feed:

1. All list loading was chained after profileStatePromise, adding
   2.5-6s of unnecessary delay. Lists only need relay URLs, not profile
   data. Now they chain off relaysReadyPromise instead, loading in
   parallel with profile fetching.

2. The video grid refreshed immediately without waiting for any lists,
   so the feed briefly displayed unfiltered content. Now the grid refresh
   waits (up to 8s) for critical feed-filtering lists to settle.

3. Hashtag preferences weren't cached into the snapshot before the feed
   rendered, so interests/disinterests were empty on first paint.

4. Subscription ensureLoaded had a 6s timeout that was too aggressive
   for relay fetch (12s) + decryption (3-12s), causing silent failures.
   Increased to 30s.

5. Subscription relay fetches for user and session actor ran sequentially.
   Now they run in parallel via Promise.all.

https://claude.ai/code/session_01UKmTWb83AnQPRVQo3bKZqm
2026-02-05 23:55:50 +00:00
google-labs-jules[bot]andPR0M3TH3AN f77c89baf6 fix: ensure active feed refreshes when hashtag preferences change
* Update `refreshAllVideoGrids` in `js/app.js` to detect the currently active feed (For You, Kids, Explore, or Recent) and invoke the corresponding loader, preventing staleness when interacting with the UI.
* Refactor `HashtagPreferencesService` mutation methods (`addInterest`, etc.) to be `async` and await the `publish()` call, ensuring state is persisted before returning.
* Remove redundant `persistPreferencesFromMenu` call in `TagPreferenceMenuController`, relying on the service's internal persistence logic.
* Update unit tests for `HashtagPreferencesService` and `TagPreferenceMenuController` to align with the async behavior.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-03 01:55:21 +00:00
google-labs-jules[bot]andPR0M3TH3AN 511cfa25cf fix(for-you): preload watch history and filter watched videos
Preload watch history in `refreshForYouFeed` to ensure `watchHistoryService` has the latest data.
Update `buildForYouFeedRuntime` to include a `watchHistory` suppression hook that checks against preloaded watch history items.
Register `createWatchHistorySuppressionStage` in the "for-you" feed pipeline to filter out watched videos.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-02 02:55:55 +00:00
google-labs-jules[bot]andPR0M3TH3AN 1dfc23c11a refactor(ai): extract notification logic from js/app.js (agent)
- Moved `showError`, `showStatus`, `showSuccess`, and `updateNotificationPortalVisibility` logic to `js/ui/notificationController.js`.
- Instantiated `NotificationController` in `js/ui/applicationBootstrap.js`.
- Refactored `js/app.js` to delegate notification calls to the controller.
- Added unit tests for `NotificationController`.
- Followed AGENTS.md refactoring checklist.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-01 03:08:05 +00:00
google-labs-jules[bot]andPR0M3TH3AN 51087fad7e refactor(ai): extract handleAddProfile from js/app.js (agent)
Moves `handleAddProfile` logic from the main application class into `ProfileModalController` to improve separation of concerns as per `AGENTS.md`.

- Extracts `handleAddProfile` to `js/ui/profileModalController.js`.
- Updates `ProfileModalController` to handle add account flow internally.
- Removes legacy callback wiring from `js/app.js` and `js/ui/applicationBootstrap.js`.
- Adds unit tests for the extracted logic in `tests/ui/profileModalController-addProfile.test.mjs`.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-01-31 03:32:52 +00:00
thePR0M3TH3AN 7ef420e1e2 Defer block list permission prompts during login 2026-01-30 15:53:57 -05:00
thePR0M3TH3AN deec2cd573 Merge pull request #1994 from PR0M3TH3AN/codex/handle-auth-login-failures-and-permissions
Add permission CTA and retry flow for subscriptions & hashtag preferences
2026-01-30 15:40:12 -05:00
thePR0M3TH3AN acf73bc5a3 Add permission CTA for subscriptions and hashtags 2026-01-30 15:39:52 -05:00
google-labs-jules[bot]andPR0M3TH3AN 6347ab0db1 fix(auth): optimize login speed and list decryption
- Reduced decryption timeout for user lists from 90s to 15s to fail faster.
- Optimized NIP-07 decryption calls to avoid retries and long timeouts during critical loading paths.
- Fixed a bug where `loginWithExtension` triggered `getPublicKey` twice, doubling the user interaction time.
- Added a 10s grace period for relay health warnings to prevent false positives on startup.
- Verified `deferBlocks` logic in `authService` prevents blocking the login UI on slow list decryption.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-01-30 20:31:24 +00:00
google-labs-jules[bot]andPR0M3TH3AN 9481de9e0a fix(app): sequence user list loading after profile relays are initialized
Prior to this change, user-specific lists (block lists, subscriptions, hashtag preferences, DMs, NWC settings) were fetched concurrently with the profile/relay initialization in `handleAuthLogin`. This caused a race condition where the application would attempt to fetch sensitive user data using default relays instead of the user's preferred relays, often resulting in empty or stale data.

This patch refactors `handleAuthLogin` in `js/app.js` to chain the loading of these lists to the completion of `profileStatePromise` (which ensures relays are loaded via `postLoginPromise`). This guarantees that the correct relays are used for fetching user-specific data.

Also defines `dmStatePromise`, `nwcPromise` and `hashtagPreferencesPromise` which were previously referenced but seemingly undefined in the scope, ensuring proper promise tracking.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-01-30 17:25:07 +00:00
google-labs-jules[bot]andPR0M3TH3AN fdc070479b Optimize post-login sequence to load relays before other data
Prioritizes fetching the user's relay list (NIP-65) immediately after login, ensuring that subsequent data fetches (profile, contact list, DMs, feed) utilize the user's preferred relays instead of default ones. This prevents "slow" or incomplete data loading issues caused by relying on defaults.

- Refactored `authService.applyPostLoginState` to sequence relay loading before profile/block loading.
- Refactored `app.handleAuthLogin` to await relay loading before initiating dependent fetches (Hashtags, Moderation, DMs, NWC, Lists, Feed).
- Updated unit tests in `tests/auth-service.test.mjs` to verify sequential execution and correct return values.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-01-30 16:34:12 +00:00
thePR0M3TH3AN 5a5fd50641 Improve relay sanitization and health checks 2026-01-30 10:48:28 -05:00
thePR0M3TH3AN abdfa4b68b Defer NIP-07 encryption permissions 2026-01-30 10:29:00 -05:00
thePR0M3TH3AN 2007e53b39 Add probe caching and dedupe for playback 2026-01-30 10:11:31 -05:00
thePR0M3TH3AN 8cdeebed03 Consolidate torrent status interval handling 2026-01-30 10:03:47 -05:00
thePR0M3TH3AN 80a0bc8bb2 Merge branch 'unstable' into ai/refactor-videomodal-controller-18342133587526974097 2026-01-30 09:18:22 -05:00
thePR0M3TH3AN db9a6b8e69 Merge pull request #1955 from PR0M3TH3AN/ai/smoke-tests-20250129-1837019461609586530
chore(ai): add smoke test script (agent)
2026-01-30 09:14:46 -05:00
google-labs-jules[bot]andPR0M3TH3AN 3dfba92e04 refactor(ai): extract VideoModalController from js/app.js (agent)
Co-authored-by: PR0M3TH3AN <[email protected]>
2026-01-30 03:40:36 +00:00
google-labs-jules[bot]andPR0M3TH3AN 624dabc576 chore(ai): add smoke test script (agent)
- Added `scripts/agent/smoke-test.mjs` which performs an end-to-e2e smoke test using a local relay, Node.js client, and headless Playwright browser.
- Fixed a bug in `js/app.js` where `activeProfilePubkey` and `savedProfiles` getters were missing, preventing auto-login and session restoration.
- The smoke test verifies:
    - Login flow (using ephemeral keys and localStorage injection).
    - Relay connection (using a local test relay).
    - Publish and Receive flow (Video Post).
    - DM Encryption/Decryption flow (Node.js client).

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-01-29 21:45:32 +00:00
thePR0M3TH3AN a196e95127 Centralize relay list subscriptions 2026-01-29 16:32:11 -05:00
thePR0M3TH3AN bba94b9908 Improve login hydration parallelism 2026-01-29 16:13:35 -05:00
thePR0M3TH3AN 7596f8b8fd Batch relay-driven UI refreshes 2026-01-29 16:05:03 -05:00
thePR0M3TH3AN 1642b787ec Reset caches on logout 2026-01-29 15:54:44 -05:00
thePR0M3TH3AN aad2fe465a Tier login hydration and trim DM fetch 2026-01-29 15:43:34 -05:00
thePR0M3TH3AN e9db549406 Update login flow loading states 2026-01-29 15:13:12 -05:00
thePR0M3TH3AN 379287c87c Defer subscription and hashtag decrypt prompts 2026-01-29 13:08:35 -05:00
thePR0M3TH3AN ce5e0e5726 Load DMs on login and fix identity refresh 2026-01-29 12:46:54 -05:00
thePR0M3TH3AN 377e6283a7 Remove duplicate block list load from app login 2026-01-29 12:43:58 -05:00
thePR0M3TH3AN 95dc380f54 Emit post-login hydration events 2026-01-29 12:40:50 -05:00
thePR0M3TH3AN 589fdd2ec4 Warm up NIP-07 extension state 2026-01-29 12:33:27 -05:00
thePR0M3TH3AN c3e986c9d3 Improve relay hygiene and count status 2026-01-29 09:58:35 -05:00