Commit Graph

59 Commits

Author SHA1 Message Date
Gigi
0aba54bd23 feat(explore): add highlights tab to explore page
- Create fetchHighlightsFromAuthors function for fetching highlights from multiple contacts
- Add tab structure to Explore page (Writings and Highlights tabs)
- Update explore cache to handle both blog posts and highlights
- Add /explore/highlights route
- Keep UI consistent with /me page tab structure
- Implement pull-to-refresh for both tabs
- Add proper caching and streaming for highlights
2025-10-14 10:45:23 +02:00
Gigi
4c720aa049 feat: add public profile pages at /p/:npub
- Make AuthorCard clickable to navigate to user profiles
- Add /p/:npub and /p/:npub/writings routes
- Reuse Me component for public profiles with pubkey prop
- Show highlights and writings tabs for any user
- Hide private tabs (reading-list, archive) on public profiles
- Public profiles show only public data (highlights, writings)
- Private data (bookmarks, read articles) only visible on own profile
- Add clickable author card hover styles with indigo border
- Decode npub to pubkey for profile viewing
- DRY: Single Me component serves both /me and /p/:npub routes
2025-10-14 01:01:10 +02:00
Gigi
3c1e4312c9 feat(me): add Writings tab to display user's published articles
- Add 'writings' tab type to Me component
- Fetch articles written by logged-in user using fetchBlogPostsFromAuthors
- Display writings in same grid style as archive tab
- Add pen-to-square icon for writings tab
- Add /me/writings route
- Update Bookmarks component to handle writings tab routing
- Show article count in tab badge
- Empty state message for users with no published articles
2025-10-13 23:42:26 +02:00
Gigi
f882b63359 fix(ui): remove padding gaps around sidebars
Remove md:p-4 padding from root container to eliminate gaps between screen edges and sidebars
2025-10-13 23:26:25 +02:00
Gigi
aab67d8375 refactor(layout): switch to document scroll with sticky sidebars
- Remove fixed container heights from three-pane layout
- Desktop: sticky sidebars with max-height, document scrolls
- Mobile: keep fixed overlays unchanged
- Update scroll direction hook to use window scroll
- Update progress indicator z-index to 1102 (above mobile overlays)
- Apply Tailwind utilities to App container
- Maintain responsive behavior across breakpoints
2025-10-13 21:36:08 +02:00
Gigi
036ee20d98 feat: add URL routing for /me page tabs
- Add routes for /me/highlights, /me/reading-list, /me/archive
- Redirect /me to /me/highlights by default
- Update Bookmarks component to extract tab from URL path
- Pass activeTab prop to Me component based on current route
- Update Me component to use URL-based tab state instead of local state
- Update tab click handlers to navigate to appropriate URLs
- Enable deep-linking to specific tabs (e.g., /me/reading-list)
2025-10-13 20:09:46 +02:00
Gigi
418bcb0295 feat(pwa): upgrade to full PWA with vite-plugin-pwa
- Add web app manifest with proper metadata and icon support
- Configure vite-plugin-pwa with injectManifest strategy
- Migrate service worker to Workbox with precaching and runtime caching
- Add runtime caching for cross-origin images (preserves existing behavior)
- Add runtime caching for cross-origin article HTML for offline reading
- Create PWA install hook and UI component in settings
- Add online/offline status monitoring and toast notifications
- Add service worker update notifications
- Add placeholder PWA icons (192x192, 512x512, maskable variants)
- Update HTML with manifest link and theme-color meta tag
- Preserve existing relay/airplane mode functionality (WebSockets not intercepted)

The app now passes PWA installability criteria while maintaining all existing
offline functionality. Icons should be replaced with proper branded designs.
2025-10-11 20:41:49 +01:00
Gigi
76835e2509 feat: add /me page to show user's recent highlights
- Create Me component to display logged-in user's highlights
- Add /me route to App routing
- Update SidebarHeader to navigate to /me when clicking profile avatar
- Integrate Me page in ThreePaneLayout (same as Settings/Explore)
- Show user profile info and highlight count
- List all highlights created by the user

Clicking the profile picture now takes you to your personal highlights page.
2025-10-11 08:07:20 +01:00
Gigi
461b0936e2 fix: use clearActive() method for logout instead of setActive(null)
Changed logout to use the proper clearActive() method from AccountManager instead of setActive(null), which was causing TypeScript type errors. This is the correct way to clear the active account according to the applesauce-accounts API.
2025-10-10 13:22:50 +01:00
Gigi
5e66c5ef76 fix: correct logout functionality by using null instead of undefined
The logout button wasn't working because setActive was being called with 'undefined as never', which is an incorrect type hack. Changed to use null instead, which properly clears the active account. Also removed redundant localStorage.removeItem('active') call since the active$ subscription already handles localStorage cleanup.
2025-10-10 13:19:34 +01:00
Gigi
962062130a feat(routing): render /explore via Bookmarks to keep side panels 2025-10-09 21:10:51 +01:00
Gigi
ceafe277d3 feat: add /explore route to discover blog posts from friends
- Create exploreService to fetch kind:30023 events from followed users
- Add BlogPostCard component for displaying blog post previews
- Add Explore page component with grid layout
- Add /explore route to App.tsx (not linked in navigation yet)
- Add responsive CSS styles for explore page and blog post cards
- Clicking blog post cards navigates to article view
2025-10-09 18:02:07 +01:00
Gigi
ebe801ae92 fix(relays): keep all relay connections alive, not just local ones
Previously only local relays had keep-alive subscriptions, causing remote relays to disconnect when no active subscriptions were running. This made the app appear to be in flight mode even when online.

Now create a persistent subscription for all relays to maintain connections.
2025-10-09 16:05:26 +01:00
Gigi
e7c05b2c52 feat: keep local relay connections alive in flight mode
- Add persistent keep-alive subscription for local relays
- Prevents disconnection when no other subscriptions are active
- Uses minimal subscription (kinds: [0], limit: 0) to keep connection open
- Properly cleans up subscription on app unmount
- Resolves issue where local relays disconnect after idle period in flight mode
2025-10-09 14:08:37 +01:00
Gigi
39d0147cfa feat(routing): add /settings route and URL-based settings navigation
- Add /settings route to router
- Derive showSettings from location.pathname instead of state
- Update onOpenSettings to navigate to /settings
- Update onCloseSettings to navigate back to previous location
- Track previous location to restore context when closing settings
- Remove showSettings state from useBookmarksUI hook
2025-10-09 12:27:43 +01:00
Gigi
8285df487f revert: use documented applesauce imports; remove alias shim
- Import EventStore from 'applesauce-core'
- Remove Vite alias/shim and node:path reference
- Keep config minimal and standard-compliant
2025-10-07 06:24:33 +01:00
Gigi
f455f61795 build: deep import EventStore to bypass re-export resolution on Vercel
- Import EventStore from applesauce-core/dist/event-store/event-store.js
- Add TS module declaration shim for deep import typing
- No functional changes, fixes Vercel bundling for async-event-store.js
2025-10-07 06:15:48 +01:00
Gigi
107d6757bd feat: add routing support for external URLs
- Add /r/* route in App.tsx for external URL content
- Create useExternalUrlLoader hook to load external web content
- Add fetchHighlightsForUrl service to fetch highlights by URL using 'r' tag
- Update Bookmarks component to handle both nostr-native (naddr) and external URLs
- Support two URL patterns: /a/naddr... for nostr content, /r/https://... for external URLs
2025-10-06 19:22:18 +01:00
Gigi
8b023af6a0 refactor: simplify to single RELAYS constant (DRY) 2025-10-05 23:41:27 +01:00
Gigi
6e2f1102f7 feat: add local relay support and centralize relay configuration 2025-10-05 23:38:56 +01:00
Gigi
c3aece1722 fix: properly await account loading from localStorage on refresh 2025-10-05 23:34:33 +01:00
Gigi
7a4cb77aa3 refactor: remove dedicated login page, handle login through main UI 2025-10-05 23:32:52 +01:00
Gigi
9065501043 fix: add protected routes to prevent logout on page refresh 2025-10-05 23:31:30 +01:00
Gigi
89b14ce5b7 feat(toast): add login/logout success messages using existing toast system 2025-10-05 22:19:30 +01:00
Gigi
ce2ccd54b3 fix(lint): resolve all linting and TypeScript errors 2025-10-05 22:12:07 +01:00
Gigi
959e83699a fix(auth): implement logout functionality to clear active account and localStorage 2025-10-05 22:08:11 +01:00
Gigi
e710391962 style(ui): replace all loading text with spinners per fontawesome rule 2025-10-05 22:02:01 +01:00
Gigi
4aea7b899b feat: persist accounts to localStorage
- Register common account types for deserialization
- Load persisted accounts and active account on app init
- Subscribe to account changes and save to localStorage
- Add cleanup for subscriptions on unmount
2025-10-05 13:26:28 +01:00
Gigi
43492a4488 refactor: simplify login by handling it directly in sidebar
Instead of navigating to /login route, login now happens directly when
clicking the login button in the sidebar header.

Changes:
- Moved login logic from Login component to SidebarHeader
- Uses Accounts.ExtensionAccount.fromExtension() directly
- Removed onLogin prop chain (App → Bookmarks → BookmarkList)
- Removed unnecessary BookmarksRoute wrapper component
- Shows 'Connecting...' state in button title during login
- Keeps code DRY by reusing same login logic without navigation

Result: Simpler, more direct user experience - one click to log in
from anywhere in the app.
2025-10-05 13:17:22 +01:00
Gigi
1552dd85d9 feat: show login button when logged out instead of logout button
- Added onLogin prop to Bookmarks, BookmarkList, and SidebarHeader
- SidebarHeader now conditionally renders login or logout button
- Login button uses faRightToBracket icon
- Logout button uses faRightFromBracket icon
- Clicking login button navigates to /login route
- Created BookmarksRoute wrapper to handle navigation
- Better UX for anonymous users browsing articles
2025-10-05 13:12:32 +01:00
Gigi
82ab07e606 feat: configure default article via environment variable
- Add VITE_DEFAULT_ARTICLE_NADDR env variable support
- Create .env with default article naddr
- Create .env.example for documentation
- Add vite-env.d.ts for TypeScript type support
- Fallback to hardcoded value if env var not set
- Using Vite's built-in env variable support (no dotenv needed)
2025-10-05 09:08:10 +01:00
Gigi
1f5e3f82b0 feat: load default article on startup with collapsed sidebars
- Redirect root path to default article (naddr)
- Start with both sidebars (bookmarks and highlights) collapsed
- Auto-fetch and show highlights for the article author
- No authentication required to view articles
- Highlights panel auto-expands when article loads
- Login page moved to /login route
2025-10-05 09:06:54 +01:00
Gigi
edd4e20e22 refactor: integrate long-form article rendering into existing reader view
- Create articleService to fetch articles by naddr
- Update Bookmarks component to detect naddr in URL params
- Articles now render in the existing ContentPanel with highlight support
- Remove standalone Article component
- Articles work seamlessly within the existing three-pane layout
- Support for article metadata (title, image, published date, summary)
2025-10-05 08:12:55 +01:00
Gigi
9b0c59b1ae feat: add native support for rendering Nostr long-form articles (NIP-23)
- Install react-router-dom for routing support
- Create Article component to decode naddr and fetch/render articles
- Add /a/:naddr route to App.tsx for article viewing
- Use applesauce relay pool patterns for event fetching
- Render articles with markdown using ReactMarkdown
- Support article metadata (title, image, published date, summary)
2025-10-05 08:08:34 +01:00
Gigi
55c4fe9d4e refactor(ui): move user info and logout to sidebar header bar
- Create new SidebarHeader component as bar-shaped container
- Combine collapse button, user info, and logout button in one bar
- Position header bar at top of bookmark sidebar with matching width
- Remove fixed top-right positioning for user header
- Style as cohesive bar with background, border, and spacing
- Update all prop passing from App through Bookmarks to BookmarkList
- Remove old UserHeader component
2025-10-03 02:00:54 +02:00
Gigi
e644f07828 refactor(ui): move user info to top-right app header
- Create UserHeader component to display user info and logout button
- Move 'Logged in as: user' from sidebar to app-header in top-right
- Remove user info display from BookmarkList and Bookmarks components
- Simplify bookmarks-header layout (only contains collapse button now)
- Update CSS to display user info and logout button inline with proper spacing
2025-10-03 01:56:16 +02:00
Gigi
ef3ce445f5 refactor(ui): move logout button to top-right of app
- Move logout IconButton from sidebar to App component
- Position logout button fixed at top-right corner
- Remove onLogout prop from Bookmarks and BookmarkList components
- Clean up sidebar header by removing logout button
- Add app-header CSS with fixed positioning and high z-index
2025-10-03 01:51:03 +02:00
Gigi
d2cf27db42 refactor(ui): remove header text from app
- Remove 'Markr' title and 'A minimal nostr bookmark client' subtitle
- Clean up the app header for a more minimal interface
2025-10-03 01:46:24 +02:00
Gigi
20f37b94e1 fix(profile): enable reactive profile fetch via address loader lookup relays and improve fallback display\n\n- Configure createAddressLoader with common profile relays (purplepag.es, primal, nostr.band)\n- Avoid sticky 'Loading profile...' label; fallback to short pubkey until profile loads 2025-10-03 00:16:04 +02:00
Gigi
7a5dd2f444 fix(applesauce): attach address/replaceable loaders so ProfileModel resolves reactively
- Use createAddressLoader from applesauce-loaders
- Set eventStore.addressableLoader and replaceableLoader
- Enables reactive profile fetching for logged-in user and mentions
2025-10-03 00:08:10 +02:00
Gigi
00638410c0 feat: add more relays and fix logging for better bookmark debugging
- Add more popular relays for better bookmark discovery
- Fix variable scoping in bookmark event logging
- Enhanced debugging to see dTag and tag content structure
2025-10-02 20:50:07 +02:00
Gigi
eb282fcbb0 fix: fix hidden bookmark detection by using applesauce's built-in logic
- Remove custom isEncryptedContent function that was too restrictive
- Use applesauce's hasHiddenContent() and hasHiddenTags() functions instead
- These properly detect encrypted content regardless of format
- Remove failing relay.snort.social from relay list
- Add detailed logging to show hidden content detection status
2025-10-02 20:38:46 +02:00
Gigi
03c6a0c9c7 feat: add wot.dergigi.com relay for improved connectivity
- Add wot.dergigi.com as additional relay option
- Now using 6 relays total for maximum bookmark data availability
2025-10-02 20:09:41 +02:00
Gigi
dc36992199 feat: add relay.dergigi.com to relay list for better connectivity
- Add relay.dergigi.com as additional relay option
- Improve chances of fetching private bookmarks from multiple sources
2025-10-02 20:09:00 +02:00
Gigi
4fb5babc0a fix: remove unused imports from App.tsx
- Remove unused Loaders import from applesauce-loaders
- Remove unused NostrEvent import from nostr-tools
- Clean up imports to pass linting and type checking
2025-10-02 08:58:44 +02:00
Gigi
ae9f2607a1 fix: implement proper applesauce relay pool query pattern
- Replace addressLoader with direct relayPool usage
- Use relayPool.query() with proper filter for kind:10003 events
- Add RelayPool import to Bookmarks component
- Update TypeScript interfaces to use RelayPool instead of addressLoader
- Follow applesauce documentation pattern for querying events
2025-10-02 08:53:39 +02:00
Gigi
ff7da4c6a2 debug: add detailed logging to diagnose addressLoader type issue
- Log addressLoader creation and type in App.tsx
- Log addressLoader type and value in Bookmarks component
- This will help identify why addressLoader is not a function
- The error shows addressLoader exists but isn't callable

This should reveal what createAddressLoader actually returns.
2025-10-02 08:41:54 +02:00
Gigi
f0cf31252f debug: add extensive logging and alerts to diagnose bookmark fetching
- Add console logs for relay group creation and relay URLs
- Add detailed logging in Bookmarks useEffect to track dependencies
- Add alert to confirm bookmark fetch is starting
- Log addressLoader and activeAccount availability
- Track when fetchBookmarks is called vs when dependencies are missing

This will help diagnose why bookmarks aren't appearing and
why console logs might not be visible.
2025-10-02 08:37:50 +02:00
Gigi
8058a99cf2 improve: optimize applesauce-relay usage following documentation patterns
- Create relay group using pool.group() for better event deduplication
- Follow applesauce-relay documentation for relay group management
- Remove manual relay connection monitoring (handled by pool)
- Use pool directly with address loader for optimal performance
- Add logging for relay group creation
- Maintain extraRelays configuration for address loader
- Follow applesauce-relay best practices for relay pool usage

This follows the applesauce-relay documentation exactly as shown
in the Relay Group example, providing better deduplication and
connection management.
2025-10-02 08:37:05 +02:00
Gigi
3d8b19d05f feat: add nostr.band relay for better bookmark coverage
- Add wss://relay.nostr.band to relay list
- Increase relay diversity for better bookmark discovery
- nostr.band is a popular relay with good event coverage

This should improve the chances of finding bookmarks
across different relay networks.
2025-10-02 08:36:01 +02:00