mirror of
https://github.com/dergigi/boris.git
synced 2025-12-24 01:54:19 +01:00
refactor(reader): extract ReaderHeader to keep ContentPanel concise (<210 lines)
This commit is contained in:
@@ -2,12 +2,13 @@ import React, { useMemo, useEffect, useRef, useState } from 'react'
|
|||||||
import ReactMarkdown from 'react-markdown'
|
import ReactMarkdown from 'react-markdown'
|
||||||
import remarkGfm from 'remark-gfm'
|
import remarkGfm from 'remark-gfm'
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
import { faSpinner, faHighlighter, faClock } from '@fortawesome/free-solid-svg-icons'
|
import { faSpinner } from '@fortawesome/free-solid-svg-icons'
|
||||||
import { Highlight } from '../types/highlights'
|
import { Highlight } from '../types/highlights'
|
||||||
import { applyHighlightsToHTML } from '../utils/highlightMatching'
|
import { applyHighlightsToHTML } from '../utils/highlightMatching'
|
||||||
import { readingTime } from 'reading-time-estimator'
|
import { readingTime } from 'reading-time-estimator'
|
||||||
import { filterHighlightsByUrl } from '../utils/urlHelpers'
|
import { filterHighlightsByUrl } from '../utils/urlHelpers'
|
||||||
import { hexToRgb } from '../utils/colorHelpers'
|
import { hexToRgb } from '../utils/colorHelpers'
|
||||||
|
import ReaderHeader from './ReaderHeader'
|
||||||
|
|
||||||
interface ContentPanelProps {
|
interface ContentPanelProps {
|
||||||
loading: boolean
|
loading: boolean
|
||||||
@@ -162,30 +163,13 @@ const ContentPanel: React.FC<ContentPanelProps> = ({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{image && (
|
<ReaderHeader
|
||||||
<div className="reader-hero-image">
|
title={title}
|
||||||
<img src={image} alt={title || 'Article image'} />
|
image={image}
|
||||||
</div>
|
readingTimeText={readingStats ? readingStats.text : null}
|
||||||
)}
|
hasHighlights={hasHighlights}
|
||||||
{title && (
|
highlightCount={relevantHighlights.length}
|
||||||
<div className="reader-header">
|
/>
|
||||||
<h2 className="reader-title">{title}</h2>
|
|
||||||
<div className="reader-meta">
|
|
||||||
{readingStats && (
|
|
||||||
<div className="reading-time">
|
|
||||||
<FontAwesomeIcon icon={faClock} />
|
|
||||||
<span>{readingStats.text}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{hasHighlights && (
|
|
||||||
<div className="highlight-indicator">
|
|
||||||
<FontAwesomeIcon icon={faHighlighter} />
|
|
||||||
<span>{relevantHighlights.length} highlight{relevantHighlights.length !== 1 ? 's' : ''}</span>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{markdown || html ? (
|
{markdown || html ? (
|
||||||
markdown ? (
|
markdown ? (
|
||||||
finalHtml ? (
|
finalHtml ? (
|
||||||
|
|||||||
52
src/components/ReaderHeader.tsx
Normal file
52
src/components/ReaderHeader.tsx
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
import { faHighlighter, faClock } from '@fortawesome/free-solid-svg-icons'
|
||||||
|
|
||||||
|
interface ReaderHeaderProps {
|
||||||
|
title?: string
|
||||||
|
image?: string
|
||||||
|
readingTimeText?: string | null
|
||||||
|
hasHighlights: boolean
|
||||||
|
highlightCount: number
|
||||||
|
}
|
||||||
|
|
||||||
|
const ReaderHeader: React.FC<ReaderHeaderProps> = ({
|
||||||
|
title,
|
||||||
|
image,
|
||||||
|
readingTimeText,
|
||||||
|
hasHighlights,
|
||||||
|
highlightCount
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{image && (
|
||||||
|
<div className="reader-hero-image">
|
||||||
|
<img src={image} alt={title || 'Article image'} />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{title && (
|
||||||
|
<div className="reader-header">
|
||||||
|
<h2 className="reader-title">{title}</h2>
|
||||||
|
<div className="reader-meta">
|
||||||
|
{readingTimeText && (
|
||||||
|
<div className="reading-time">
|
||||||
|
<FontAwesomeIcon icon={faClock} />
|
||||||
|
<span>{readingTimeText}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{hasHighlights && (
|
||||||
|
<div className="highlight-indicator">
|
||||||
|
<FontAwesomeIcon icon={faHighlighter} />
|
||||||
|
<span>{highlightCount} highlight{highlightCount !== 1 ? 's' : ''}</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ReaderHeader
|
||||||
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user