From ca339ac0b2cd753301ec69871ff587acf109d956 Mon Sep 17 00:00:00 2001 From: Gigi Date: Wed, 15 Oct 2025 09:57:14 +0200 Subject: [PATCH 01/10] refactor: remove all eslint-disable statements and fix underlying issues - Replace @typescript-eslint/no-explicit-any with proper Filter type from nostr-tools/filter in dataFetch.ts and helpers.ts - Replace @typescript-eslint/no-explicit-any with IAccount and AccountManager types from applesauce-accounts in hooks - Replace @typescript-eslint/no-explicit-any with unknown type casts in App.tsx for keep-alive subscription - Fix react-hooks/exhaustive-deps warnings by including all dependencies in useEffect hooks - Remove unused _settings parameters in useImageCache.ts that were causing no-unused-vars warnings --- src/App.tsx | 10 ++++------ src/components/AddBookmarkModal.tsx | 3 +-- src/components/Bookmarks.tsx | 3 +-- src/hooks/useBookmarksData.ts | 7 +++---- src/hooks/useHighlightCreation.ts | 4 ++-- src/hooks/useImageCache.ts | 10 ++-------- src/services/dataFetch.ts | 4 ++-- src/utils/helpers.ts | 4 ++-- 8 files changed, 17 insertions(+), 28 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 68486c89..942b8f20 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -215,8 +215,7 @@ function App() { console.log('🔗 Created keep-alive subscription for', RELAYS.length, 'relay(s)') // Store subscription for cleanup - // eslint-disable-next-line @typescript-eslint/no-explicit-any - ;(pool as any)._keepAliveSubscription = keepAliveSub + ;(pool as unknown as { _keepAliveSubscription: typeof keepAliveSub })._keepAliveSubscription = keepAliveSub // Attach address/replaceable loaders so ProfileModel can fetch profiles const addressLoader = createAddressLoader(pool, { @@ -235,10 +234,9 @@ function App() { accountsSub.unsubscribe() activeSub.unsubscribe() // Clean up keep-alive subscription if it exists - // eslint-disable-next-line @typescript-eslint/no-explicit-any - if ((pool as any)._keepAliveSubscription) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (pool as any)._keepAliveSubscription.unsubscribe() + const poolWithSub = pool as unknown as { _keepAliveSubscription?: { unsubscribe: () => void } } + if (poolWithSub._keepAliveSubscription) { + poolWithSub._keepAliveSubscription.unsubscribe() } } } diff --git a/src/components/AddBookmarkModal.tsx b/src/components/AddBookmarkModal.tsx index 26601351..b5eff9c3 100644 --- a/src/components/AddBookmarkModal.tsx +++ b/src/components/AddBookmarkModal.tsx @@ -140,8 +140,7 @@ const AddBookmarkModal: React.FC = ({ onClose, onSave }) clearTimeout(fetchTimeoutRef.current) } } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [url]) // Only depend on url - title, description, tagsInput are intentionally checked but not dependencies + }, [url, title, description, tagsInput]) const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() diff --git a/src/components/Bookmarks.tsx b/src/components/Bookmarks.tsx index bddc1d6e..3718f036 100644 --- a/src/components/Bookmarks.tsx +++ b/src/components/Bookmarks.tsx @@ -130,8 +130,7 @@ const Bookmarks: React.FC = ({ relayPool, onLogout }) => { if (isMobile && isSidebarOpen) { toggleSidebar() } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [location.pathname]) + }, [location.pathname, isMobile, isSidebarOpen, toggleSidebar]) // Handle highlight navigation from explore page useEffect(() => { diff --git a/src/hooks/useBookmarksData.ts b/src/hooks/useBookmarksData.ts index 2eb550f4..6505ad6a 100644 --- a/src/hooks/useBookmarksData.ts +++ b/src/hooks/useBookmarksData.ts @@ -1,5 +1,6 @@ import { useState, useEffect, useCallback } from 'react' import { RelayPool } from 'applesauce-relay' +import { IAccount, AccountManager } from 'applesauce-accounts' import { Bookmark } from '../types/bookmarks' import { Highlight } from '../types/highlights' import { fetchBookmarks } from '../services/bookmarkService' @@ -9,10 +10,8 @@ import { UserSettings } from '../services/settingsService' interface UseBookmarksDataParams { relayPool: RelayPool | null - // eslint-disable-next-line @typescript-eslint/no-explicit-any - activeAccount: any - // eslint-disable-next-line @typescript-eslint/no-explicit-any - accountManager: any + activeAccount: IAccount | undefined + accountManager: AccountManager naddr?: string currentArticleCoordinate?: string currentArticleEventId?: string diff --git a/src/hooks/useHighlightCreation.ts b/src/hooks/useHighlightCreation.ts index 2539b8cb..0a9bfafe 100644 --- a/src/hooks/useHighlightCreation.ts +++ b/src/hooks/useHighlightCreation.ts @@ -3,6 +3,7 @@ import { flushSync } from 'react-dom' import { RelayPool } from 'applesauce-relay' import { NostrEvent } from 'nostr-tools' import { IEventStore } from 'applesauce-core' +import { IAccount } from 'applesauce-accounts' import { Highlight } from '../types/highlights' import { ReadableContent } from '../services/readerService' import { createHighlight } from '../services/highlightCreationService' @@ -10,8 +11,7 @@ import { HighlightButtonRef } from '../components/HighlightButton' import { UserSettings } from '../services/settingsService' interface UseHighlightCreationParams { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - activeAccount: any + activeAccount: IAccount | undefined relayPool: RelayPool | null eventStore: IEventStore | null currentArticle: NostrEvent | undefined diff --git a/src/hooks/useImageCache.ts b/src/hooks/useImageCache.ts index f3d52b90..6d93fe41 100644 --- a/src/hooks/useImageCache.ts +++ b/src/hooks/useImageCache.ts @@ -1,5 +1,3 @@ -import { UserSettings } from '../services/settingsService' - /** * Hook to return image URL for display * Service Worker handles all caching transparently @@ -9,9 +7,7 @@ import { UserSettings } from '../services/settingsService' * @returns The image URL (Service Worker handles caching) */ export function useImageCache( - imageUrl: string | undefined, - // eslint-disable-next-line no-unused-vars - _settings?: UserSettings + imageUrl: string | undefined ): string | undefined { // Service Worker handles everything - just return the URL as-is return imageUrl @@ -22,9 +18,7 @@ export function useImageCache( * Triggers a fetch so the SW can cache it even if not visible yet */ export function useCacheImageOnLoad( - imageUrl: string | undefined, - // eslint-disable-next-line no-unused-vars - _settings?: UserSettings + imageUrl: string | undefined ): void { // Service Worker will cache on first fetch // This hook is now a no-op, kept for API compatibility diff --git a/src/services/dataFetch.ts b/src/services/dataFetch.ts index f4f31bb4..011c71d2 100644 --- a/src/services/dataFetch.ts +++ b/src/services/dataFetch.ts @@ -1,6 +1,7 @@ import { RelayPool, completeOnEose, onlyEvents } from 'applesauce-relay' import { Observable, merge, takeUntil, timer, toArray, tap, lastValueFrom } from 'rxjs' import { NostrEvent } from 'nostr-tools' +import { Filter } from 'nostr-tools/filter' import { prioritizeLocalRelays, partitionRelays } from '../utils/helpers' import { LOCAL_TIMEOUT_MS, REMOTE_TIMEOUT_MS } from '../config/network' @@ -17,8 +18,7 @@ export interface QueryOptions { */ export async function queryEvents( relayPool: RelayPool, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - filter: any, + filter: Filter, options: QueryOptions = {} ): Promise { const { diff --git a/src/utils/helpers.ts b/src/utils/helpers.ts index 071dac6a..b3fcafa4 100644 --- a/src/utils/helpers.ts +++ b/src/utils/helpers.ts @@ -102,13 +102,13 @@ export const prioritizeLocalRelays = (relayUrls: string[]): string[] => { // Parallel request helper import { completeOnEose, onlyEvents, RelayPool } from 'applesauce-relay' import { Observable, takeUntil, timer } from 'rxjs' +import { Filter } from 'nostr-tools/filter' export function createParallelReqStreams( relayPool: RelayPool, localRelays: string[], remoteRelays: string[], - // eslint-disable-next-line @typescript-eslint/no-explicit-any - filter: any, + filter: Filter, localTimeoutMs = 1200, remoteTimeoutMs = 6000 ): { local$: Observable; remote$: Observable } { From 8e57d3d49179569efd81e2e067f0a1a3f892cf8d Mon Sep 17 00:00:00 2001 From: Gigi Date: Wed, 15 Oct 2025 10:01:43 +0200 Subject: [PATCH 02/10] refactor: remove unused settings parameter from image cache and bookmark components - Remove settings parameter from useImageCache and useCacheImageOnLoad hooks as it was never used - Update all call sites in CardView, CompactView, LargeView, and ReaderHeader - Remove settings prop from BookmarkItem and its child view components - Remove settings prop from BookmarkList component - Update ThreePaneLayout to not pass settings to BookmarkList This change cascades through the component tree to clean up unused props that were introduced when we refactored the image caching to use Service Worker instead of local storage. --- src/components/BookmarkItem.tsx | 7 ++----- src/components/BookmarkList.tsx | 4 ---- src/components/BookmarkViews/CardView.tsx | 7 ++----- src/components/BookmarkViews/CompactView.tsx | 7 ++----- src/components/BookmarkViews/LargeView.tsx | 7 ++----- src/components/ReaderHeader.tsx | 2 +- src/components/ThreePaneLayout.tsx | 1 - 7 files changed, 9 insertions(+), 26 deletions(-) diff --git a/src/components/BookmarkItem.tsx b/src/components/BookmarkItem.tsx index 0345bc37..bd97cbdd 100644 --- a/src/components/BookmarkItem.tsx +++ b/src/components/BookmarkItem.tsx @@ -11,17 +11,15 @@ import { getPreviewImage, fetchOgImage } from '../utils/imagePreview' import { CompactView } from './BookmarkViews/CompactView' import { LargeView } from './BookmarkViews/LargeView' import { CardView } from './BookmarkViews/CardView' -import { UserSettings } from '../services/settingsService' interface BookmarkItemProps { bookmark: IndividualBookmark index: number onSelectUrl?: (url: string, bookmark?: { id: string; kind: number; tags: string[][]; pubkey: string }) => void viewMode?: ViewMode - settings?: UserSettings } -export const BookmarkItem: React.FC = ({ bookmark, index, onSelectUrl, viewMode = 'cards', settings }) => { +export const BookmarkItem: React.FC = ({ bookmark, index, onSelectUrl, viewMode = 'cards' }) => { const [ogImage, setOgImage] = useState(null) const short = (v: string) => `${v.slice(0, 8)}...${v.slice(-8)}` @@ -115,8 +113,7 @@ export const BookmarkItem: React.FC = ({ bookmark, index, onS getAuthorDisplayName, handleReadNow, articleImage, - articleSummary, - settings + articleSummary } if (viewMode === 'compact') { diff --git a/src/components/BookmarkList.tsx b/src/components/BookmarkList.tsx index e4036142..6b7a6244 100644 --- a/src/components/BookmarkList.tsx +++ b/src/components/BookmarkList.tsx @@ -9,7 +9,6 @@ import SidebarHeader from './SidebarHeader' import IconButton from './IconButton' import { ViewMode } from './Bookmarks' import { extractUrlsFromContent } from '../services/bookmarkHelpers' -import { UserSettings } from '../services/settingsService' import { usePullToRefresh } from 'use-pull-to-refresh' import RefreshIndicator from './RefreshIndicator' import { BookmarkSkeleton } from './Skeletons' @@ -29,7 +28,6 @@ interface BookmarkListProps { lastFetchTime?: number | null loading?: boolean relayPool: RelayPool | null - settings?: UserSettings isMobile?: boolean } @@ -48,7 +46,6 @@ export const BookmarkList: React.FC = ({ lastFetchTime, loading = false, relayPool, - settings, isMobile = false }) => { const bookmarksListRef = useRef(null) @@ -161,7 +158,6 @@ export const BookmarkList: React.FC = ({ index={index} onSelectUrl={onSelectUrl} viewMode={viewMode} - settings={settings} /> )} diff --git a/src/components/BookmarkViews/CardView.tsx b/src/components/BookmarkViews/CardView.tsx index 39361651..8af56045 100644 --- a/src/components/BookmarkViews/CardView.tsx +++ b/src/components/BookmarkViews/CardView.tsx @@ -10,7 +10,6 @@ import { classifyUrl } from '../../utils/helpers' import { IconGetter } from './shared' import { useImageCache } from '../../hooks/useImageCache' import { getPreviewImage, fetchOgImage } from '../../utils/imagePreview' -import { UserSettings } from '../../services/settingsService' import { getEventUrl } from '../../config/nostrGateways' interface CardViewProps { @@ -26,7 +25,6 @@ interface CardViewProps { handleReadNow: (e: React.MouseEvent) => void articleImage?: string articleSummary?: string - settings?: UserSettings } export const CardView: React.FC = ({ @@ -41,8 +39,7 @@ export const CardView: React.FC = ({ getAuthorDisplayName, handleReadNow, articleImage, - articleSummary, - settings + articleSummary }) => { const firstUrl = hasUrls ? extractedUrls[0] : null const firstUrlClassificationType = firstUrl ? classifyUrl(firstUrl)?.type : null @@ -59,7 +56,7 @@ export const CardView: React.FC = ({ // Determine which image to use (article image, instant preview, or OG image) const previewImage = articleImage || instantPreview || ogImage - const cachedImage = useImageCache(previewImage || undefined, settings) + const cachedImage = useImageCache(previewImage || undefined) // Fetch OG image if we don't have any other image React.useEffect(() => { diff --git a/src/components/BookmarkViews/CompactView.tsx b/src/components/BookmarkViews/CompactView.tsx index 86613d4b..f4d61499 100644 --- a/src/components/BookmarkViews/CompactView.tsx +++ b/src/components/BookmarkViews/CompactView.tsx @@ -5,7 +5,6 @@ import { IndividualBookmark } from '../../types/bookmarks' import { formatDateCompact } from '../../utils/bookmarkUtils' import ContentWithResolvedProfiles from '../ContentWithResolvedProfiles' import { useImageCache } from '../../hooks/useImageCache' -import { UserSettings } from '../../services/settingsService' interface CompactViewProps { bookmark: IndividualBookmark @@ -15,7 +14,6 @@ interface CompactViewProps { onSelectUrl?: (url: string, bookmark?: { id: string; kind: number; tags: string[][]; pubkey: string }) => void articleImage?: string articleSummary?: string - settings?: UserSettings } export const CompactView: React.FC = ({ @@ -25,15 +23,14 @@ export const CompactView: React.FC = ({ extractedUrls, onSelectUrl, articleImage, - articleSummary, - settings + articleSummary }) => { const isArticle = bookmark.kind === 30023 const isWebBookmark = bookmark.kind === 39701 const isClickable = hasUrls || isArticle || isWebBookmark // Get cached image for thumbnail - const cachedImage = useImageCache(articleImage || undefined, settings) + const cachedImage = useImageCache(articleImage || undefined) const handleCompactClick = () => { if (!onSelectUrl) return diff --git a/src/components/BookmarkViews/LargeView.tsx b/src/components/BookmarkViews/LargeView.tsx index 116b3190..80001976 100644 --- a/src/components/BookmarkViews/LargeView.tsx +++ b/src/components/BookmarkViews/LargeView.tsx @@ -6,7 +6,6 @@ import { formatDate } from '../../utils/bookmarkUtils' import ContentWithResolvedProfiles from '../ContentWithResolvedProfiles' import { IconGetter } from './shared' import { useImageCache } from '../../hooks/useImageCache' -import { UserSettings } from '../../services/settingsService' import { getEventUrl } from '../../config/nostrGateways' interface LargeViewProps { @@ -22,7 +21,6 @@ interface LargeViewProps { getAuthorDisplayName: () => string handleReadNow: (e: React.MouseEvent) => void articleSummary?: string - settings?: UserSettings } export const LargeView: React.FC = ({ @@ -37,10 +35,9 @@ export const LargeView: React.FC = ({ eventNevent, getAuthorDisplayName, handleReadNow, - articleSummary, - settings + articleSummary }) => { - const cachedImage = useImageCache(previewImage || undefined, settings) + const cachedImage = useImageCache(previewImage || undefined) const isArticle = bookmark.kind === 30023 const triggerOpen = () => handleReadNow({ preventDefault: () => {} } as React.MouseEvent) diff --git a/src/components/ReaderHeader.tsx b/src/components/ReaderHeader.tsx index d6e348de..3a93f6ac 100644 --- a/src/components/ReaderHeader.tsx +++ b/src/components/ReaderHeader.tsx @@ -33,7 +33,7 @@ const ReaderHeader: React.FC = ({ highlights = [], highlightVisibility = { nostrverse: true, friends: true, mine: true } }) => { - const cachedImage = useImageCache(image, settings) + const cachedImage = useImageCache(image) const formattedDate = published ? format(new Date(published * 1000), 'MMM d, yyyy') : null const isLongSummary = summary && summary.length > 150 diff --git a/src/components/ThreePaneLayout.tsx b/src/components/ThreePaneLayout.tsx index 016f3650..05036530 100644 --- a/src/components/ThreePaneLayout.tsx +++ b/src/components/ThreePaneLayout.tsx @@ -303,7 +303,6 @@ const ThreePaneLayout: React.FC = (props) => { lastFetchTime={props.lastFetchTime} loading={props.bookmarksLoading} relayPool={props.relayPool} - settings={props.settings} isMobile={isMobile} /> From ebea872c72103fadcae7736778f34b2bc9a3d5e6 Mon Sep 17 00:00:00 2001 From: Gigi Date: Wed, 15 Oct 2025 10:09:08 +0200 Subject: [PATCH 03/10] feat: move filter icon buttons to the right in explore page --- src/components/Explore.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Explore.tsx b/src/components/Explore.tsx index b02e81dd..d345f0ae 100644 --- a/src/components/Explore.tsx +++ b/src/components/Explore.tsx @@ -398,7 +398,7 @@ const Explore: React.FC = ({ relayPool, eventStore, settings, acti {/* Visibility filters */} -
+
setVisibility({ ...visibility, nostrverse: !visibility.nostrverse })} From e11184426ef192bca4cf19d3f4cbb1192765747f Mon Sep 17 00:00:00 2001 From: Gigi Date: Wed, 15 Oct 2025 10:09:55 +0200 Subject: [PATCH 04/10] feat: default explore filter to friends only --- src/components/Explore.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/Explore.tsx b/src/components/Explore.tsx index d345f0ae..ec2fbbbf 100644 --- a/src/components/Explore.tsx +++ b/src/components/Explore.tsx @@ -42,11 +42,11 @@ const Explore: React.FC = ({ relayPool, eventStore, settings, acti const [loading, setLoading] = useState(true) const [refreshTrigger, setRefreshTrigger] = useState(0) - // Visibility filters (defaults from settings) + // Visibility filters (defaults from settings, or friends only) const [visibility, setVisibility] = useState({ - nostrverse: settings?.defaultHighlightVisibilityNostrverse !== false, - friends: settings?.defaultHighlightVisibilityFriends !== false, - mine: settings?.defaultHighlightVisibilityMine !== false + nostrverse: settings?.defaultHighlightVisibilityNostrverse ?? false, + friends: settings?.defaultHighlightVisibilityFriends ?? true, + mine: settings?.defaultHighlightVisibilityMine ?? false }) // Update local state when prop changes From dcbe4bd23eb1d9892b413dfacf4cff3dea4a65dd Mon Sep 17 00:00:00 2001 From: Gigi Date: Wed, 15 Oct 2025 10:11:40 +0200 Subject: [PATCH 05/10] feat: update writings tab icon to use newspaper icon --- src/components/Explore.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Explore.tsx b/src/components/Explore.tsx index ec2fbbbf..6d8577e3 100644 --- a/src/components/Explore.tsx +++ b/src/components/Explore.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect, useMemo } from 'react' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faNewspaper, faPenToSquare, faHighlighter, faUser, faUserGroup, faNetworkWired } from '@fortawesome/free-solid-svg-icons' +import { faNewspaper, faHighlighter, faUser, faUserGroup, faNetworkWired } from '@fortawesome/free-solid-svg-icons' import IconButton from './IconButton' import { BlogPostSkeleton, HighlightSkeleton } from './Skeletons' import { Hooks } from 'applesauce-react' @@ -392,7 +392,7 @@ const Explore: React.FC = ({ relayPool, eventStore, settings, acti data-tab="writings" onClick={() => navigate('/explore/writings')} > - + Writings
From d721e84e4269a2a4cb8de1fa622d2c9f4aec063a Mon Sep 17 00:00:00 2001 From: Gigi Date: Wed, 15 Oct 2025 10:15:52 +0200 Subject: [PATCH 06/10] feat: add refresh button to the left of filter buttons in explore page --- src/components/Explore.tsx | 77 +++++++++++++++++++++----------------- 1 file changed, 43 insertions(+), 34 deletions(-) diff --git a/src/components/Explore.tsx b/src/components/Explore.tsx index 6d8577e3..d47d12e9 100644 --- a/src/components/Explore.tsx +++ b/src/components/Explore.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect, useMemo } from 'react' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' -import { faNewspaper, faHighlighter, faUser, faUserGroup, faNetworkWired } from '@fortawesome/free-solid-svg-icons' +import { faNewspaper, faHighlighter, faUser, faUserGroup, faNetworkWired, faArrowsRotate } from '@fortawesome/free-solid-svg-icons' import IconButton from './IconButton' import { BlogPostSkeleton, HighlightSkeleton } from './Skeletons' import { Hooks } from 'applesauce-react' @@ -398,42 +398,51 @@ const Explore: React.FC = ({ relayPool, eventStore, settings, acti
{/* Visibility filters */} -
+
setVisibility({ ...visibility, nostrverse: !visibility.nostrverse })} - title="Toggle nostrverse content" - ariaLabel="Toggle nostrverse content" + icon={faArrowsRotate} + onClick={() => setRefreshTrigger(prev => prev + 1)} + title="Refresh content" + ariaLabel="Refresh content" variant="ghost" - style={{ - color: visibility.nostrverse ? 'var(--highlight-color-nostrverse, #9333ea)' : undefined, - opacity: visibility.nostrverse ? 1 : 0.4 - }} - /> - setVisibility({ ...visibility, friends: !visibility.friends })} - title={activeAccount ? "Toggle friends content" : "Login to see friends content"} - ariaLabel="Toggle friends content" - variant="ghost" - disabled={!activeAccount} - style={{ - color: visibility.friends ? 'var(--highlight-color-friends, #f97316)' : undefined, - opacity: visibility.friends ? 1 : 0.4 - }} - /> - setVisibility({ ...visibility, mine: !visibility.mine })} - title={activeAccount ? "Toggle my content" : "Login to see your content"} - ariaLabel="Toggle my content" - variant="ghost" - disabled={!activeAccount} - style={{ - color: visibility.mine ? 'var(--highlight-color-mine, #eab308)' : undefined, - opacity: visibility.mine ? 1 : 0.4 - }} /> +
+ setVisibility({ ...visibility, nostrverse: !visibility.nostrverse })} + title="Toggle nostrverse content" + ariaLabel="Toggle nostrverse content" + variant="ghost" + style={{ + color: visibility.nostrverse ? 'var(--highlight-color-nostrverse, #9333ea)' : undefined, + opacity: visibility.nostrverse ? 1 : 0.4 + }} + /> + setVisibility({ ...visibility, friends: !visibility.friends })} + title={activeAccount ? "Toggle friends content" : "Login to see friends content"} + ariaLabel="Toggle friends content" + variant="ghost" + disabled={!activeAccount} + style={{ + color: visibility.friends ? 'var(--highlight-color-friends, #f97316)' : undefined, + opacity: visibility.friends ? 1 : 0.4 + }} + /> + setVisibility({ ...visibility, mine: !visibility.mine })} + title={activeAccount ? "Toggle my content" : "Login to see your content"} + ariaLabel="Toggle my content" + variant="ghost" + disabled={!activeAccount} + style={{ + color: visibility.mine ? 'var(--highlight-color-mine, #eab308)' : undefined, + opacity: visibility.mine ? 1 : 0.4 + }} + /> +
From c96347a33117431934fcc2bfff49da19e134acdc Mon Sep 17 00:00:00 2001 From: Gigi Date: Wed, 15 Oct 2025 10:19:52 +0200 Subject: [PATCH 07/10] fix: position refresh button next to filter buttons instead of far left --- src/components/Explore.tsx | 74 +++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 38 deletions(-) diff --git a/src/components/Explore.tsx b/src/components/Explore.tsx index d47d12e9..bcf5c2e7 100644 --- a/src/components/Explore.tsx +++ b/src/components/Explore.tsx @@ -398,7 +398,7 @@ const Explore: React.FC = ({ relayPool, eventStore, settings, acti {/* Visibility filters */} -
+
setRefreshTrigger(prev => prev + 1)} @@ -406,43 +406,41 @@ const Explore: React.FC = ({ relayPool, eventStore, settings, acti ariaLabel="Refresh content" variant="ghost" /> -
- setVisibility({ ...visibility, nostrverse: !visibility.nostrverse })} - title="Toggle nostrverse content" - ariaLabel="Toggle nostrverse content" - variant="ghost" - style={{ - color: visibility.nostrverse ? 'var(--highlight-color-nostrverse, #9333ea)' : undefined, - opacity: visibility.nostrverse ? 1 : 0.4 - }} - /> - setVisibility({ ...visibility, friends: !visibility.friends })} - title={activeAccount ? "Toggle friends content" : "Login to see friends content"} - ariaLabel="Toggle friends content" - variant="ghost" - disabled={!activeAccount} - style={{ - color: visibility.friends ? 'var(--highlight-color-friends, #f97316)' : undefined, - opacity: visibility.friends ? 1 : 0.4 - }} - /> - setVisibility({ ...visibility, mine: !visibility.mine })} - title={activeAccount ? "Toggle my content" : "Login to see your content"} - ariaLabel="Toggle my content" - variant="ghost" - disabled={!activeAccount} - style={{ - color: visibility.mine ? 'var(--highlight-color-mine, #eab308)' : undefined, - opacity: visibility.mine ? 1 : 0.4 - }} - /> -
+ setVisibility({ ...visibility, nostrverse: !visibility.nostrverse })} + title="Toggle nostrverse content" + ariaLabel="Toggle nostrverse content" + variant="ghost" + style={{ + color: visibility.nostrverse ? 'var(--highlight-color-nostrverse, #9333ea)' : undefined, + opacity: visibility.nostrverse ? 1 : 0.4 + }} + /> + setVisibility({ ...visibility, friends: !visibility.friends })} + title={activeAccount ? "Toggle friends content" : "Login to see friends content"} + ariaLabel="Toggle friends content" + variant="ghost" + disabled={!activeAccount} + style={{ + color: visibility.friends ? 'var(--highlight-color-friends, #f97316)' : undefined, + opacity: visibility.friends ? 1 : 0.4 + }} + /> + setVisibility({ ...visibility, mine: !visibility.mine })} + title={activeAccount ? "Toggle my content" : "Login to see your content"} + ariaLabel="Toggle my content" + variant="ghost" + disabled={!activeAccount} + style={{ + color: visibility.mine ? 'var(--highlight-color-mine, #eab308)' : undefined, + opacity: visibility.mine ? 1 : 0.4 + }} + />
From e05efaa4f6fb8d20246d88c97726dc6d67f3dc65 Mon Sep 17 00:00:00 2001 From: Gigi Date: Wed, 15 Oct 2025 10:20:45 +0200 Subject: [PATCH 08/10] feat: make refresh button spin during loading and pull-to-refresh --- src/components/Explore.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/Explore.tsx b/src/components/Explore.tsx index bcf5c2e7..a3a25672 100644 --- a/src/components/Explore.tsx +++ b/src/components/Explore.tsx @@ -405,6 +405,8 @@ const Explore: React.FC = ({ relayPool, eventStore, settings, acti title="Refresh content" ariaLabel="Refresh content" variant="ghost" + spin={loading || isRefreshing} + disabled={loading || isRefreshing} /> Date: Wed, 15 Oct 2025 10:21:26 +0200 Subject: [PATCH 09/10] feat: move tabs below filter buttons in explore page --- src/components/Explore.tsx | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/components/Explore.tsx b/src/components/Explore.tsx index a3a25672..a3c7bf81 100644 --- a/src/components/Explore.tsx +++ b/src/components/Explore.tsx @@ -378,25 +378,6 @@ const Explore: React.FC = ({ relayPool, eventStore, settings, acti Discover highlights and blog posts from your friends and others

-
- - -
- {/* Visibility filters */}
= ({ relayPool, eventStore, settings, acti }} />
+ +
+ + +
{renderTabContent()} From 394311622dd64aa900ad4ab5cd97d3b3ddc24c37 Mon Sep 17 00:00:00 2001 From: Gigi Date: Wed, 15 Oct 2025 10:22:19 +0200 Subject: [PATCH 10/10] refactor: remove subtitle from explore page --- src/components/Explore.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/Explore.tsx b/src/components/Explore.tsx index a3c7bf81..ab7559fc 100644 --- a/src/components/Explore.tsx +++ b/src/components/Explore.tsx @@ -374,9 +374,6 @@ const Explore: React.FC = ({ relayPool, eventStore, settings, acti Explore -

- Discover highlights and blog posts from your friends and others -

{/* Visibility filters */}