Commit Graph
553 Commits
Author SHA1 Message Date
google-labs-jules[bot]andPR0M3TH3AN 691e02adbf refactor(ai): extract CreatorProfileController from js/app.js (agent)
Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-10 03:15:11 +00:00
thePR0M3TH3AN fd3f9e723a Split subscriptions/hashtag readiness and expose unavailable preference states 2026-02-08 14:10:39 -05:00
thePR0M3TH3AN ffc248ecd3 Track auth list sync outcomes and expose retryable auth status 2026-02-08 13:52:04 -05:00
thePR0M3TH3AN 4d56d964c6 Merge branch 'unstable' into refactor-app-constructor-8693111500998222747 2026-02-08 13:28:55 -05:00
thePR0M3TH3AN ec50db8645 Merge pull request #2243 from PR0M3TH3AN/refactor-application-monolith-3243348981324014635
Refactor Application class into Router and UI Coordinators
2026-02-08 10:57:44 -05:00
thePR0M3TH3AN 1bf2c06022 Merge pull request #2235 from PR0M3TH3AN/refactor-app-init-2313962746277118562
🧹 Refactor Application.init into initialization phases
2026-02-08 10:49:35 -05:00
google-labs-jules[bot]andPR0M3TH3AN 44e9f42ac0 Refactor Application class into smaller coordinators
Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-08 03:51:43 +00:00
google-labs-jules[bot]andPR0M3TH3AN 0665a3392e refactor(app): Move heavy initialization from constructor to setup()
- Introduces a `setup()` method in `Application` class to handle complex initialization and side effects.
- Updates `constructor` to be lightweight, only storing configuration options.
- Updates `js/bootstrap.js`, `js/embed.js`, and relevant tests to call `app.setup()` explicitly after instantiation.
- Resolves "Heavy Constructor" code health issue.
- Fixes `tests/video-modal-zap.test.mjs` environment issue with `globalThis.navigator`.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-08 03:44:38 +00:00
google-labs-jules[bot]andPR0M3TH3AN 6c31434a36 Refactor Application constructor to simplify loadView assignment
Replaced the explicit `typeof` check for `viewLoader` with a simpler assignment using the logical OR operator (`|| null`). This removes excessive defensive coding while preserving the behavior of defaulting to `null` when the argument is undefined or falsy.

Verified with a reproduction test case that confirms `loadView` is correctly assigned or defaulted to `null`.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-08 03:41:17 +00:00
google-labs-jules[bot]andPR0M3TH3AN fa7a2997e8 Refactor Application.init into initialization phases
Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-08 03:40:49 +00:00
thePR0M3TH3AN 88227bd4ce Merge pull request #2226 from PR0M3TH3AN/claude/speed-up-nostr-login-BZBNv
Fix auto-login signer restoration and optimize critical login path
2026-02-07 21:09:02 -05:00
Claude 8bf8da03b9 Speed up Nostr login and fix list sync, signer persistence, and feed registration
The NIP-07 login flow was extremely slow because list decryption (blocks,
subscriptions, hashtag preferences) started before the signer was ready.
On page refresh, all three services failed with "permission-required" and
scheduled 3-second retry delays, adding 6-10 seconds to every login.

Key fixes:
- List loading now waits for the permission pre-grant to complete before
  attempting decryption, ensuring the signer is available on first try
- Extension wait timeout increased from 3s to 5s for slower extensions
- Decrypt timeouts reduced from 20s to 10s (signer is guaranteed ready)
- Auto-login now forwards authType/providerId from saved profiles
- Storage tab unlock falls back to ensureActiveSignerForPubkey when the
  global signer is not yet registered
- Watch history feed registration adds defensive re-registration and
  try/catch fallback to prevent "Feed not registered" errors
- Decryption scheme cache TTL extended from 10 minutes to 2 hours
- ensureExtensionPermissions waits for extension injection when there
  are outstanding permissions to request (was returning immediately)

https://claude.ai/code/session_01T4wwPu7m5qp1Nxx3H2v57j
2026-02-08 02:02:51 +00:00
thePR0M3TH3AN 07a9284cb1 Merge branch 'unstable' into test-hashtag-strip-helper-resize-7955570684281399740 2026-02-07 21:00:57 -05:00
thePR0M3TH3AN 32cd6dc2a2 Merge pull request #2222 from PR0M3TH3AN/nip04-worker-tests-17203445750544777231
🧪 Add tests for NIP-04 worker client
2026-02-07 20:54:07 -05:00
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 ce16140343 Merge pull request #2225 from PR0M3TH3AN/fix-feed-coordinator-refresh-feed-error-14415813432609543851
Fix TypeError: this.refreshFeed is not a function in Application
2026-02-07 20:39:01 -05:00
google-labs-jules[bot]andPR0M3TH3AN b1e93046fd Fix: Add missing refreshFeed method to Application class to prevent TypeError
The `feedCoordinator` logic assumes `this.refreshFeed` exists on the Application instance (because methods are bound via `bindCoordinator`). However, `Application` previously only implemented `refreshRecentFeed`, `refreshForYouFeed`, etc., but not the generic `refreshFeed`.

This caused a `TypeError: this.refreshFeed is not a function` when `loadFeedVideos` (which calls `refreshFeed`) was invoked.

This commit adds `async refreshFeed(...args)` to `Application` in `js/app.js`, delegating to `this._feed.refreshFeed(...args)`.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-08 01:34:41 +00:00
google-labs-jules[bot]andPR0M3TH3AN 2e2ea34d3c fix: Resolve js/app.js syntax error and update test mocks
- Removed orphaned code block in `js/app.js` that caused syntax errors during module loading.
- Updated `tests/helpers/moderation-test-helpers.mjs` to implement `resumePendingModeratedPlayback` and decoration logic in `MockApplication`, fixing `tests/app/moderation-overrides.test.mjs` and `tests/app/moderation-settings-refresh.test.mjs` failures.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-08 01:29:09 +00:00
google-labs-jules[bot]andPR0M3TH3AN e734f9ca79 fix: restore _initNostr and fix syntax error in app.js
- Restored missing `_initNostr` method in `js/app.js` which was causing `SyntaxError: Unexpected token '.'` and `nostrClient.init is not a function` errors.
- Removed dangling code block that was causing the syntax error (orphaned `accessControl.refresh()...` block).
- This fixes unit tests (e.g. `tests/app/channel-profile-moderation.test.mjs`) and application initialization.

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-08 01:26:43 +00:00
google-labs-jules[bot]andPR0M3TH3AN db76432ab6 fix(app.js): resolve syntax error and restore _initNostr method
Removes a malformed code block that was causing an "Unexpected token '.'" syntax error and restores the `_initNostr` method which correctly initializes the Nostr client.

Fixes: #1083 (SyntaxError in app.js)

Co-authored-by: PR0M3TH3AN <[email protected]>
2026-02-08 01:20:48 +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