mirror of
https://github.com/dergigi/boris.git
synced 2025-12-18 15:14:20 +01:00
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:
@@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
Reference in New Issue
Block a user