mirror of
https://github.com/dergigi/boris.git
synced 2026-01-31 12:44:37 +01:00
feat: add author info card for nostr-native articles
- Create AuthorCard component showing profile picture and bio - Display author card after mark as read button - Only shown for nostr-native articles (not external URLs) - Fetch author profile data using applesauce ProfileModel - Card displays author name, avatar, and bio (truncated to 3 lines) - Responsive design with smaller avatar on mobile - Elegant card styling matching app design system Author information helps readers learn more about article authors directly within the reading experience.
This commit is contained in:
43
src/components/AuthorCard.tsx
Normal file
43
src/components/AuthorCard.tsx
Normal file
@@ -0,0 +1,43 @@
|
||||
import React from 'react'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import { faUserCircle } from '@fortawesome/free-solid-svg-icons'
|
||||
import { useEventModel } from 'applesauce-react/hooks'
|
||||
import { Models } from 'applesauce-core'
|
||||
|
||||
interface AuthorCardProps {
|
||||
authorPubkey: string
|
||||
}
|
||||
|
||||
const AuthorCard: React.FC<AuthorCardProps> = ({ authorPubkey }) => {
|
||||
const profile = useEventModel(Models.ProfileModel, [authorPubkey])
|
||||
|
||||
const getAuthorName = () => {
|
||||
if (profile?.name) return profile.name
|
||||
if (profile?.display_name) return profile.display_name
|
||||
return `${authorPubkey.slice(0, 8)}...${authorPubkey.slice(-8)}`
|
||||
}
|
||||
|
||||
const authorImage = profile?.picture || profile?.image
|
||||
const authorBio = profile?.about
|
||||
|
||||
return (
|
||||
<div className="author-card">
|
||||
<div className="author-card-avatar">
|
||||
{authorImage ? (
|
||||
<img src={authorImage} alt={getAuthorName()} />
|
||||
) : (
|
||||
<FontAwesomeIcon icon={faUserCircle} />
|
||||
)}
|
||||
</div>
|
||||
<div className="author-card-content">
|
||||
<div className="author-card-name">{getAuthorName()}</div>
|
||||
{authorBio && (
|
||||
<p className="author-card-bio">{authorBio}</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default AuthorCard
|
||||
|
||||
@@ -16,6 +16,7 @@ import { useHighlightedContent } from '../hooks/useHighlightedContent'
|
||||
import { useHighlightInteractions } from '../hooks/useHighlightInteractions'
|
||||
import { UserSettings } from '../services/settingsService'
|
||||
import { createEventReaction, createWebsiteReaction } from '../services/reactionService'
|
||||
import AuthorCard from './AuthorCard'
|
||||
|
||||
interface ContentPanelProps {
|
||||
loading: boolean
|
||||
@@ -222,6 +223,13 @@ const ContentPanel: React.FC<ContentPanelProps> = ({
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Author info card for nostr-native articles */}
|
||||
{isNostrArticle && currentArticle && (
|
||||
<div className="author-card-container">
|
||||
<AuthorCard authorPubkey={currentArticle.pubkey} />
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div className="reader empty">
|
||||
|
||||
@@ -1018,6 +1018,99 @@ body.mobile-sidebar-open {
|
||||
}
|
||||
}
|
||||
|
||||
/* Author Card */
|
||||
.author-card-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
padding: 2rem 1rem;
|
||||
}
|
||||
|
||||
.author-card {
|
||||
display: flex;
|
||||
gap: 1rem;
|
||||
padding: 1.5rem;
|
||||
background: #1a1a1a;
|
||||
border: 1px solid #333;
|
||||
border-radius: 12px;
|
||||
max-width: 600px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.author-card-avatar {
|
||||
flex-shrink: 0;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
background: #2a2a2a;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.author-card-avatar img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.author-card-avatar svg {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.author-card-content {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.author-card-name {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
color: #ddd;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.author-card-bio {
|
||||
font-size: 0.9rem;
|
||||
color: #999;
|
||||
line-height: 1.5;
|
||||
margin: 0;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.author-card-container {
|
||||
padding: 1.5rem 1rem;
|
||||
}
|
||||
|
||||
.author-card {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.author-card-avatar {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
.author-card-avatar svg {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.author-card-name {
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.author-card-bio {
|
||||
font-size: 0.85rem;
|
||||
-webkit-line-clamp: 2;
|
||||
}
|
||||
}
|
||||
|
||||
.bookmark-item {
|
||||
background: #1a1a1a;
|
||||
padding: 1.5rem;
|
||||
|
||||
Reference in New Issue
Block a user