feat: make explore page article cards proper links

- Replace div+onClick with Link components
- Enable CMD+click to open articles in new tabs
- Preserve SPA navigation for normal clicks
- Better UX with standard browser link behavior
This commit is contained in:
Gigi
2025-10-09 18:27:18 +01:00
parent 9b3a4e20de
commit 0feaffb21b
2 changed files with 10 additions and 12 deletions

View File

@@ -1,4 +1,5 @@
import React from 'react' import React from 'react'
import { Link } from 'react-router-dom'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faCalendar, faUser } from '@fortawesome/free-solid-svg-icons' import { faCalendar, faUser } from '@fortawesome/free-solid-svg-icons'
import { formatDistance } from 'date-fns' import { formatDistance } from 'date-fns'
@@ -8,10 +9,10 @@ import { Models } from 'applesauce-core'
interface BlogPostCardProps { interface BlogPostCardProps {
post: BlogPostPreview post: BlogPostPreview
onClick: () => void href: string
} }
const BlogPostCard: React.FC<BlogPostCardProps> = ({ post, onClick }) => { const BlogPostCard: React.FC<BlogPostCardProps> = ({ post, href }) => {
const profile = useEventModel(Models.ProfileModel, [post.author]) const profile = useEventModel(Models.ProfileModel, [post.author])
const displayName = profile?.name || profile?.display_name || const displayName = profile?.name || profile?.display_name ||
`${post.author.slice(0, 8)}...${post.author.slice(-4)}` `${post.author.slice(0, 8)}...${post.author.slice(-4)}`
@@ -22,10 +23,10 @@ const BlogPostCard: React.FC<BlogPostCardProps> = ({ post, onClick }) => {
}) })
return ( return (
<div <Link
to={href}
className="blog-post-card" className="blog-post-card"
onClick={onClick} style={{ textDecoration: 'none', color: 'inherit' }}
style={{ cursor: 'pointer' }}
> >
{post.image && ( {post.image && (
<div className="blog-post-card-image"> <div className="blog-post-card-image">
@@ -52,7 +53,7 @@ const BlogPostCard: React.FC<BlogPostCardProps> = ({ post, onClick }) => {
</span> </span>
</div> </div>
</div> </div>
</div> </Link>
) )
} }

View File

@@ -1,5 +1,4 @@
import React, { useState, useEffect } from 'react' import React, { useState, useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faSpinner, faExclamationCircle, faCompass } from '@fortawesome/free-solid-svg-icons' import { faSpinner, faExclamationCircle, faCompass } from '@fortawesome/free-solid-svg-icons'
import { Hooks } from 'applesauce-react' import { Hooks } from 'applesauce-react'
@@ -14,7 +13,6 @@ interface ExploreProps {
} }
const Explore: React.FC<ExploreProps> = ({ relayPool }) => { const Explore: React.FC<ExploreProps> = ({ relayPool }) => {
const navigate = useNavigate()
const activeAccount = Hooks.useActiveAccount() const activeAccount = Hooks.useActiveAccount()
const [blogPosts, setBlogPosts] = useState<BlogPostPreview[]>([]) const [blogPosts, setBlogPosts] = useState<BlogPostPreview[]>([])
const [loading, setLoading] = useState(true) const [loading, setLoading] = useState(true)
@@ -67,7 +65,7 @@ const Explore: React.FC<ExploreProps> = ({ relayPool }) => {
loadBlogPosts() loadBlogPosts()
}, [relayPool, activeAccount]) }, [relayPool, activeAccount])
const handlePostClick = (post: BlogPostPreview) => { const getPostUrl = (post: BlogPostPreview) => {
// Get the d-tag identifier // Get the d-tag identifier
const dTag = post.event.tags.find(t => t[0] === 'd')?.[1] || '' const dTag = post.event.tags.find(t => t[0] === 'd')?.[1] || ''
@@ -78,8 +76,7 @@ const Explore: React.FC<ExploreProps> = ({ relayPool }) => {
identifier: dTag identifier: dTag
}) })
// Navigate to article view return `/a/${naddr}`
navigate(`/a/${naddr}`)
} }
if (loading) { if (loading) {
@@ -120,7 +117,7 @@ const Explore: React.FC<ExploreProps> = ({ relayPool }) => {
<BlogPostCard <BlogPostCard
key={`${post.author}:${post.event.tags.find(t => t[0] === 'd')?.[1]}`} key={`${post.author}:${post.event.tags.find(t => t[0] === 'd')?.[1]}`}
post={post} post={post}
onClick={() => handlePostClick(post)} href={getPostUrl(post)}
/> />
))} ))}
</div> </div>