2508 Commits

Author SHA1 Message Date
Gigi
76a117cdda fix: batch profile label updates to prevent UI flickering
- Use requestAnimationFrame to batch rapid profile label updates
- Collect pending updates in a ref instead of updating state immediately
- Apply all pending updates in one render cycle
- Add cleanup to cancel pending RAF on unmount/effect cleanup

This prevents flickering when multiple profiles stream in quickly while
still maintaining progressive updates as profiles arrive.
2025-11-02 21:53:22 +01:00
Gigi
d4c6747d98 refactor: remove timeouts and make profile fetching reactive
- Add optional onEvent callback to fetchProfiles (following queryEvents pattern)
- Remove all timeouts - rely entirely on EOSE signals
- Update useProfileLabels to use reactive streaming callback
- Labels update progressively as profiles arrive from relays
- Remove unused timer/takeUntil imports
- Backwards compatible: other callers of fetchProfiles still work

This follows the controller pattern from fetching-data-with-controllers rule:
'Since we are streaming results, we should NEVER use timeouts for fetching
data. We should always rely on EOSE.'
2025-11-02 21:48:39 +01:00
Gigi
6b221e4d13 perf: increase remote relay timeout for profile fetches
Increase timeout from 6s to 10s to give slow relays (including purplepag.es)
more time to respond with profile metadata. This may help find profiles that
were timing out before.
2025-11-02 21:43:00 +01:00
Gigi
7ec2ddcceb debug: add log before fetchProfiles call to verify it's being invoked 2025-11-02 21:42:07 +01:00
Gigi
5ce13c667d feat: ensure purplepag.es relay is used for profile lookups
Add logic to check if purplepag.es is in the active relay pool when fetching
profiles. If not, add it temporarily to ensure we query this relay for
profile metadata. This should help find profiles that might not be available
on other relays.

Also adds debug logging to show which active relays are being queried.
2025-11-02 21:41:03 +01:00
Gigi
c1877a40e9 debug: add detailed logging to fetchProfiles function
Add comprehensive logs prefixed with [fetch-profiles] to track:
- How many profiles are requested
- Cache lookup results
- Relay query configuration
- Each profile event as it's received
- Summary of fetched vs missing profiles
- Which profiles weren't found on relays

This will help diagnose why only 9/19 profiles are being returned.
2025-11-02 21:40:14 +01:00
Gigi
18a38d054f debug: add comprehensive logging to profile label resolution
Add detailed debug logs prefixed with [profile-labels] and [markdown-replace]
to track the profile resolution flow:
- Profile identifier extraction from content
- Cache lookup and eventStore checks
- Profile fetching from relays
- Label updates when profiles resolve
- Markdown URI replacement with profile labels

This will help diagnose why profile names aren't resolving correctly.
2025-11-02 21:37:14 +01:00
Gigi
500cec88d0 fix: allow profile labels to update from fallback to resolved names
Previously, useProfileLabels would set fallback npub labels immediately for
missing profiles, then skip updating them when profiles were fetched because
the condition checked if the label already existed.

Now we track which profiles were being fetched (pubkeysToFetch) and update
their labels even if they already have fallback labels set, allowing profiles
to resolve progressively from fallback npubs to actual names as they load.
2025-11-02 21:34:57 +01:00
Gigi
affd80ca2e refactor: standardize profile display name fallbacks across codebase
- Add getProfileDisplayName() utility function for consistent profile name resolution
- Update all components to use standardized npub fallback format instead of hex
- Fix useProfileLabels hook to include fallback npub labels when profiles lack names
- Refactor NostrMentionLink to eliminate duplication between npub/nprofile cases
- Remove debug console.log statements from RichContent component
- Update AuthorCard, SidebarHeader, HighlightItem, Support, BlogPostCard, ResolvedMention, and useEventLoader to use new utilities
2025-11-02 21:31:16 +01:00
Gigi
5e1ed6b8de refactor: clean up npub/nprofile display implementation
- Remove all debug console.log/error statements (39+) and ts() helpers
- Eliminate redundant localStorage cache check in useProfileLabels
- Standardize fallback display format using getNpubFallbackDisplay() utility
- Update ResolvedMention to use npub format consistently
2025-11-02 21:26:06 +01:00
Gigi
5d36d6de4f refactor: add logging to verify initialLabels are set correctly from cache 2025-11-02 21:10:56 +01:00
Gigi
93eb8a63de fix: implement LRU cache eviction to handle QuotaExceededError
- Add LRU eviction strategy: limit to 1000 cached profiles, evict oldest when full
- Track lastAccessed timestamp for each cached profile
- Automatically evict old profiles when quota is exceeded
- Reduce error logging spam: only log quota error once per session
- Silently handle cache errors to match articleService pattern
- Proactively evict before caching when approaching limit

This prevents localStorage quota exceeded errors and ensures
the most recently accessed profiles remain cached.
2025-11-02 21:09:11 +01:00
Gigi
6074caaae3 refactor: change profile-cache log prefix to npub-cache for consistency 2025-11-02 21:07:44 +01:00
Gigi
d206ff228e fix: remove unnecessary label comparison and fix useEffect dependencies 2025-11-02 21:06:40 +01:00
Gigi
074af764ed fix: disable eslint warning for useEffect dependencies in useProfileLabels 2025-11-02 21:06:16 +01:00
Gigi
e814aadb5b fix: initialize profile labels synchronously from cache for instant display
- Use useMemo to check localStorage cache synchronously during render, before useEffect
- Initialize useState with labels from cache, so first render shows cached profiles immediately
- Add detailed logging for cache operations to debug caching issues
- Fix ESLint warnings about unused variables and dependencies

This eliminates the delay where profiles were only resolved after useEffect ran,
causing profiles to display instantly on page reload when cached.
2025-11-02 21:06:02 +01:00
Gigi
aaddd0ef6b feat: add localStorage caching for profile resolution
- Add localStorage caching functions to profileService.ts following articleService.ts pattern
  - getCachedProfile: get single cached profile with TTL validation (30 days)
  - cacheProfile: save profile to localStorage with error handling
  - loadCachedProfiles: batch load multiple profiles from cache
- Modify fetchProfiles() to check localStorage cache first, only fetch missing/expired profiles, and cache fetched profiles
- Update useProfileLabels hook to check localStorage before EventStore, add cached profiles to EventStore for consistency
- Update logging to show cache hits from localStorage
- Benefits: instant profile resolution on page reload, reduced relay queries, offline support for previously-seen profiles
2025-11-02 21:03:10 +01:00
Gigi
8a39258d8e fix: remove unused useMemo import 2025-11-02 20:54:45 +01:00
Gigi
3136b198d5 perf: add timing metrics and reduce excessive logging
- Add duration tracking for fetchProfiles (shows how long it takes)
- Add total time tracking for entire resolution process
- Reduce log noise by only logging when profileLabels size changes
- Helps identify performance bottlenecks
2025-11-02 20:54:40 +01:00
Gigi
8a431d962e debug: add timestamps to all npub-resolve logs for performance analysis
- Add timestamp helper function (HH:mm:ss.SSS format)
- Update all console.log/error statements to include timestamps
- Helps identify timing bottlenecks in profile resolution
2025-11-02 20:53:22 +01:00
Gigi
50ab59ebcd fix: use fetchedProfiles array directly instead of only checking eventStore
- fetchProfiles returns profiles that we should use immediately
- Check returned array first, then fallback to eventStore lookup
- Fixes issue where profiles were returned but not used for resolution
2025-11-02 20:49:34 +01:00
Gigi
3ba5bce437 debug: add detailed logging to diagnose nprofile resolution issues
- Log fetchProfiles return count
- Log profile events found in store vs missing
- Log profiles with names vs without names
- Help diagnose why 0 profiles are being resolved
2025-11-02 20:46:23 +01:00
Gigi
9ed56b213e fix: add periodic re-checking of eventStore for async profile arrivals
- Poll eventStore every 200ms for up to 2 seconds after fetchProfiles
- Accumulate resolved labels across checks instead of resetting
- Add detailed logging to diagnose why profiles aren't resolving
- Fixes issue where profiles arrive asynchronously after fetchProfiles completes
2025-11-02 20:44:15 +01:00
Gigi
34804540c5 fix: re-check eventStore after fetchProfiles to resolve all profiles
- After fetchProfiles completes, re-check eventStore for all profiles
- This ensures profiles are resolved even if fetchProfiles returns partial results
- Fixes issue where only 5 out of 19 profiles were being resolved
2025-11-02 20:41:34 +01:00
Gigi
30c2ca5b85 feat: remove 'npub1' prefix from shortened npub displays
- Show @derggg instead of @npub1derggg for truncated npubs
- Update getNostrUriLabel to skip first 5 chars ('npub1')
- Update NostrMentionLink fallback display to match
2025-11-02 20:40:12 +01:00
Gigi
68e6fcd3ac debug: standardize all npub resolution debug logs with [npub-resolve] prefix 2025-11-02 20:38:26 +01:00
Gigi
da385cd037 fix: resolve Rules of Hooks violation by using eventStore instead of useEventModel in map 2025-11-02 20:37:50 +01:00
Gigi
3b30bc98c7 fix: correct syntax error in RichContent try-catch structure 2025-11-02 20:04:34 +01:00
Gigi
056da1ad23 debug: add debug logs to trace NIP-19 parsing and profile resolution
- Add logs to useProfileLabels hook
- Add logs to useMarkdownToHTML hook
- Add logs to RichContent component
- Add logs to extractNostrUris function
- Add error handling with fallbacks
2025-11-02 20:04:01 +01:00
Gigi
b7cda7a351 refactor: replace custom NIP-19 parsing with applesauce helpers and add progressive profile resolution
- Replace custom regex patterns with Tokens.nostrLink from applesauce-content
- Use getContentPointers() and getPubkeyFromDecodeResult() from applesauce helpers
- Add useProfileLabels hook for shared profile resolution logic
- Implement progressive profile name updates in markdown articles
- Remove unused ContentWithResolvedProfiles component
- Simplify useMarkdownToHTML by extracting profile resolution to shared hook
- Fix TypeScript and ESLint errors
2025-11-02 20:01:51 +01:00
Gigi
5896a5d6db chore: consolidate duplicate and related entries in CHANGELOG
- Merge related bookmark button changes in 0.10.31
- Consolidate image preloading entries in 0.10.27
- Group flight mode fixes in 0.10.26
- Combine OpenGraph-related changes in 0.10.24
- Consolidate bookmark sorting fixes in 0.10.11
- Merge reading progress bar fixes in 0.10.25
- Reduce file from 2158 to 2108 lines
2025-11-02 19:19:34 +01:00
Gigi
af91e52555 chore: condense CHANGELOG from 3220 to 2157 lines
- Remove nested bullets and verbose explanations
- Condense implementation details to user-facing changes
- Maintain Keep a Changelog format and structure
2025-11-02 19:16:58 +01:00
Gigi
b4ebb6334f docs: update CHANGELOG for v0.10.31 2025-11-02 19:11:53 +01:00
Gigi
27178bc3d1 chore: bump version to 0.10.31 v0.10.31 2025-11-02 19:11:22 +01:00
Gigi
76fefc88ca Merge pull request #33 from dergigi/big-plus-button
Move add bookmark button to filter bar
2025-11-02 19:09:55 +01:00
Gigi
98c006939b fix: align add bookmark button with filter buttons
- Match CompactButton styling to filter-btn when inside filter bar
- Ensure same size, padding, and alignment for consistent appearance
2025-11-02 18:49:44 +01:00
Gigi
80ed646dd4 feat: move add bookmark button to filter bar
- Move add bookmark button from web section header to filter bar
- Position button on the right side of filter bar
- Remove conditional rendering (always show button)
- Add bookmark-filters-wrapper styling for proper layout
2025-11-02 18:47:10 +01:00
Gigi
7ea868d0b2 docs: update CHANGELOG for v0.10.30 2025-11-01 10:25:02 +01:00
Gigi
88e1bc3419 chore: bump version to 0.10.30 v0.10.30 2025-11-01 10:24:32 +01:00
Gigi
4ec34a0379 fix: reset scroll to top when navigating to profile pages 2025-11-01 10:23:27 +01:00
Gigi
aec2dcb75c feat: navigate to author's writings page from article author card 2025-11-01 10:22:15 +01:00
Gigi
5bdc435f5d fix: preserve image aspect ratio when full-width images setting is enabled
- Add object-fit: contain to prevent image squishing
- Make max-height conditional: none when full-width enabled, 70vh otherwise
- Apply fix to both desktop and mobile image styles
2025-11-01 10:15:58 +01:00
Gigi
db46edd39e docs: update CHANGELOG for v0.10.29 2025-11-01 00:35:17 +01:00
Gigi
c9739f804d chore: bump version to 0.10.29 v0.10.29 2025-11-01 00:34:50 +01:00
Gigi
eeb44e344f Merge pull request #32 from dergigi/full-width-image-going-over
fix: correct fullWidthImages setting to use width instead of max-width
2025-11-01 00:34:32 +01:00
Gigi
a6674610b8 fix: correct fullWidthImages setting to use width instead of max-width
- Change from --image-max-width CSS variable to --image-width
- When enabled, sets images to width: 100% (enlarging small images)
- Always constrains with max-width: 100% to prevent overflow
- Update mobile responsive styles to respect the setting
2025-11-01 00:32:51 +01:00
Gigi
6ae3decafb docs: update CHANGELOG for v0.10.28 2025-11-01 00:27:08 +01:00
Gigi
00da638e81 chore: bump version to 0.10.28 v0.10.28 2025-11-01 00:26:17 +01:00
Gigi
f04c0a401e Merge pull request #31 from dergigi/fix-boris-post-issues
Fix nested markdown links from processing nostr URIs in URLs
2025-11-01 00:26:00 +01:00
Gigi
f5e9f164f5 chore: remove debug console.log statements from nostrUriResolver
Removed all debug logging that was added for troubleshooting the
link processing issue. The functionality remains intact, including
the parser-based markdown link detection and HTTP URL protection.
2025-11-01 00:23:57 +01:00