style: update episode responsiveness

This commit is contained in:
jinhojang6 2023-08-24 23:03:48 +09:00
parent b4993f6e95
commit 7021dab746
9 changed files with 97 additions and 56 deletions

View File

@ -1,12 +1,12 @@
import {
extractClassFromFirstTag,
extractIdFromFirstTag,
extractInnerHtml,
} from '@/utils/html.utils'
import { Typography } from '@acid-info/lsd-react'
import styled from '@emotion/styled'
import ReactPlayer from 'react-player'
import { LPE } from '../../types/lpe.types'
import { parseText, parseTimestamp } from '@/utils/string.utils'
export const RenderEpisodeBlock = ({
block,
@ -24,19 +24,24 @@ export const RenderEpisodeBlock = ({
<ReactPlayer url={youtubeLink[0]} />
) : (
<TranscriptionItem>
<Typography variant="body2">{parseTimestamp(block.text)}</Typography>
<Transcript
variant="body2"
component={'p'}
genericFontFamily="sans-serif"
className={extractClassFromFirstTag(block.html) || ''}
id={extractIdFromFirstTag(block.html) || `p-${block.id}`}
dangerouslySetInnerHTML={{ __html: extractInnerHtml(block.html) }}
/>
>
{parseText(block.text)}
</Transcript>
</TranscriptionItem>
)
}
const TranscriptionItem = styled.div`
display: flex;
flex-direction: column;
gap: var(--lsd-body2-lineHeight);
margin-bottom: calc(var(--lsd-body2-lineHeight) * 2);
`

View File

@ -5,6 +5,7 @@ import EpisodeHeader from './Header/Episode.Header'
import EpisodeTranscript from './Episode.Transcript'
import { playerState } from '../GlobalAudioPlayer/globalAudioPlayer.state'
import { useHookstate } from '@hookstate/core'
import { uiConfigs } from '@/configs/ui.configs'
interface Props {
episode: LPE.Podcast.Document
@ -39,9 +40,9 @@ const EpisodeContainer = styled.article`
display: flex;
position: relative;
flex-direction: column;
gap: 16px;
max-width: 700px;
max-width: 696px;
@media (min-width: 768px) and (max-width: 1200px) {
@media (max-width: 768px) {
margin-top: ${uiConfigs.navbarRenderedHeight - 16}px;
}
`

View File

@ -17,17 +17,19 @@ const EpisodeCredits = ({
open={open}
onChange={() => setOpen((prev) => !prev)}
>
{credits?.map((credit, idx) => (
<Reference key={idx}>
<Typography
component="p"
variant="body3"
id={credit.id.replace('#', '')}
>
{credit.text}
</Typography>
</Reference>
))}
<Credits>
{credits?.map((credit, idx) => (
<Credit key={idx}>
<Typography
component="p"
variant="body3"
id={credit.id.replace('#', '')}
>
{credit.text}
</Typography>
</Credit>
))}
</Credits>
</Collapse>
</Container>
) : null
@ -41,10 +43,18 @@ const Container = styled.div`
}
`
const Reference = styled.div`
const Credits = styled.div`
display: flex;
padding: 8px 14px;
gap: 8px;
flex-direction: column;
justify-content: center;
gap: var(--lsd-body3-lineHeight);
padding: 12px 14px;
`
const Credit = styled.div`
display: flex;
flex-direction: flex;
align-items: center;
`
export default EpisodeCredits

View File

@ -17,20 +17,22 @@ const EpisodeFootnotes = ({
open={open}
onChange={() => setOpen((prev) => !prev)}
>
{footnotes.map((footnote, idx) => (
<Reference key={idx}>
<Typography
component="a"
variant="body3"
href={`#${footnote.refId}`}
target="_blank"
id={footnote.id.replace('#', '')}
>
{footnote.refValue}
</Typography>
<P dangerouslySetInnerHTML={{ __html: footnote.valueHTML }} />
</Reference>
))}
<Footnotes>
{footnotes.map((footnote, idx) => (
<Footnote key={idx}>
<Typography
component="a"
variant="body3"
href={`#${footnote.refId}`}
target="_blank"
id={footnote.id.replace('#', '')}
>
{footnote.refValue}
</Typography>
<P dangerouslySetInnerHTML={{ __html: footnote.valueHTML }} />
</Footnote>
))}
</Footnotes>
</Collapse>
</Container>
) : null
@ -44,11 +46,18 @@ const Container = styled.div`
}
`
const Reference = styled.div`
const Footnotes = styled.div`
display: flex;
align-items: center;
padding: 8px 14px;
gap: 8px;
flex-direction: column;
justify-content: center;
gap: var(--lsd-body3-lineHeight);
padding: 12px 14px;
`
const Footnote = styled.div`
display: flex;
flex-direction: flex;
align-items: baseline;
`
const P = styled.p`

View File

@ -16,21 +16,21 @@ const renderChannel = (channel: LPE.Podcast.Channel) => {
return (
<Channel href={channel.url} target="_blank">
<SpotifyIcon width={16} height={16} />
<Typography variant="body2">Spotify</Typography>
<ChannelName variant="body2">Spotify</ChannelName>
</Channel>
)
case LPE.Podcast.ChannelNames.ApplePodcasts:
return (
<Channel href={channel.url} target="_blank">
<ApplePodcastsIcon width={16} height={16} />
<Typography variant="body2">Apple Podcasts</Typography>
<ChannelName variant="body2">Apple Podcasts</ChannelName>
</Channel>
)
case LPE.Podcast.ChannelNames.GooglePodcasts:
return (
<Channel href={channel.url} target="_blank">
<GooglePodcastsIcon width={16} height={16} />
<Typography variant="body2">Google Podcasts</Typography>
<ChannelName variant="body2">Google Podcasts</ChannelName>
</Channel>
)
default:
@ -53,7 +53,7 @@ const EpisodeChannelContainer = styled.header`
margin-top: 32px;
@media (max-width: 768px) {
padding-top: 32px;
margin-top: 24px;
}
`
@ -64,4 +64,11 @@ const Channel = styled(Link)`
text-decoration: none;
`
const ChannelName = styled(Typography)`
@media (max-width: 768px) {
font-size: var(--lsd-body3-fontSize) !important;
line-height: var(--lsd-body3-lineHeight) !important;
}
`
export default EpisodeChannels

View File

@ -69,10 +69,6 @@ const EpisodeHeader = ({
const EpisodeHeaderContainer = styled.header`
display: flex;
flex-direction: column;
@media (max-width: 768px) {
padding-top: 32px;
}
`
const CustomTypography = styled(Typography)`
@ -85,6 +81,8 @@ const EpisodeTitle = styled(Typography)`
margin-bottom: 16px;
@media (max-width: 768px) {
margin-bottom: 8px;
font-size: var(--lsd-h4-fontSize) !important;
line-height: var(--lsd-h4-lineHeight) !important;
}
`
@ -92,7 +90,9 @@ const EpisodeSubtitle = styled(CustomTypography)`
margin-top: 32px;
@media (max-width: 768px) {
font-size: var(--lsd-subtitle1-fontSize);
font-size: var(--lsd-subtitle1-fontSize) !important;
line-height: var(--lsd-subtitle1-lineHeight) !important;
margin-top: 24px;
}
`

View File

@ -207,7 +207,7 @@ const PlayerContainer = styled.div<{ isAudio: boolean }>`
margin-bottom: ${(props) => (props.isAudio ? '0' : '32px')};
position: relative;
padding-bottom: ${(props) => (props.isAudio ? '0' : '56.25%')};
padding-top: 30px;
padding-top: 32px;
height: 0;
overflow: hidden;
@ -220,6 +220,10 @@ const PlayerContainer = styled.div<{ isAudio: boolean }>`
width: 100%;
height: 100%;
}
@media (max-width: 768px) {
padding-top: 24px;
}
`
export default EpisodePlayer

View File

@ -13,11 +13,11 @@ const EpisodeContainer = (props: Props) => {
return (
<EpisodeGrid>
<Gap className={'w-4'} />
<GridItem className={'w-4'} />
<EpisodeBodyContainer className={'w-8'}>
<EpisodeBody episode={episode} relatedEpisodes={relatedEpisodes} />
</EpisodeBodyContainer>
<Gap className={'w-4'} />
<GridItem className={'w-4'} />
</EpisodeGrid>
)
}
@ -26,14 +26,10 @@ const EpisodeBodyContainer = styled(GridItem)``
const EpisodeGrid = styled(Grid)`
width: 100%;
margin-top: -47px; // offset for uiConfig.postSectionMargin
@media (min-width: 768px) and (max-width: 1200px) {
}
`
const Gap = styled(GridItem)`
@media (max-width: 550px) {
display: none;
}
`
export default EpisodeContainer

View File

@ -65,3 +65,12 @@ export function convertToIframe(url: string) {
return `<iframe height="200px" width="100%" frameborder="no" scrolling="no" seamless src="${url}"></iframe>`
}
export function parseText(text: string) {
return text.replace(/^\d{2}:\d{2}\s|\[\d+\]/g, '')
}
export function parseTimestamp(text: string) {
const time = text.match(/^\d{2}:\d{2}/g)
return time ? time[0] : ''
}