Skip to content

Commit a0dbd9e

Browse files
feat: Show archive on each session's page when recordingUrl or slideUrl exists (#309)
1 parent 9707b4a commit a0dbd9e

File tree

8 files changed

+87
-14
lines changed

8 files changed

+87
-14
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { StoryObj, Meta } from '@storybook/react'
2+
import { YouTubeEmbedFrame } from '.'
3+
4+
const meta: Meta<typeof YouTubeEmbedFrame> = {
5+
component: YouTubeEmbedFrame
6+
}
7+
export default meta
8+
9+
export const Default: StoryObj<typeof YouTubeEmbedFrame> = {
10+
args: {
11+
// A sample video from YouTube's help page.
12+
recordingUrl: 'https://www.youtube.com/embed/lJIrF4YjHfQ'
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { Box } from '@mui/material'
2+
import { FC } from 'react'
3+
4+
type Props = {
5+
recordingUrl: string
6+
}
7+
8+
export const YouTubeEmbedFrame: FC<Props> = ({ recordingUrl }) => {
9+
return (
10+
<Box sx={{ aspectRatio: '16/9', maxWidth: '680px', width: '100%', height: '100%' }}>
11+
<iframe
12+
src={recordingUrl}
13+
width="100%"
14+
height="100%"
15+
title="YouTube video player"
16+
allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
17+
allowFullScreen
18+
style={{ border: 'none' }}
19+
/>
20+
</Box>
21+
)
22+
}

src/components/molecules/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ export * from './TrackCard'
77
export * from './BoothCard'
88
export * from './TweetButton'
99
export * from './GoogleCalendarButton'
10+
export * from './YouTubeEmbedFrame'

src/i18n/en.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@
3030
"need_connpass_number": "Need your connpass receipt number.",
3131
"has_been_finished": "Go Conference 2023 Online has been finished",
3232
"thanks_for_corporate": "Thanks for everyone who talked, participated, sponsored, and operated for the conference!",
33-
"archive_will_be_published": "The publishable sessions will soon be published on each session’s page."
33+
"archive_will_be_published": "The publishable sessions will soon be published on each session’s page.",
34+
"see_slide": "See the slide"
3435
}

src/i18n/ja.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,6 @@
3030
"need_connpass_number": "connpass の受付番号が必要です。",
3131
"has_been_finished": "Go Conference 2023 Online は終了いたしました",
3232
"thanks_for_corporate": "ご登壇、ご参加いただいた皆さん、ご協力いただいたスポンサー、運営の皆さんありがとうございました!",
33-
"archive_will_be_published": "公開可能なセッションのアーカイブは、各セッションのページにて順次公開予定です。"
33+
"archive_will_be_published": "公開可能なセッションのアーカイブは、各セッションのページにて順次公開予定です。",
34+
"see_slide": "スライドを見る"
3435
}

src/modules/sessionize/schema.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ const sessionizeSessionSchema = z.object({
1818
),
1919
roomId: z.number(),
2020
liveUrl: z.null(),
21-
recordingUrl: z.null(),
21+
recordingUrl: z.string().nullable(),
2222
status: z.literal('Accepted')
2323
})
2424

@@ -107,3 +107,7 @@ export const CATEGORY_SESSION_TYPE = 46584
107107
* ID of the category for the session level.
108108
*/
109109
export const CATEGORY_SESSION_LEVEL = 53862
110+
/**
111+
* ID of the question for the slide URL.
112+
*/
113+
export const QUESTION_SLIDE_URL = 54981

src/modules/sessionize/utils.ts

+14
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
CATEGORY_SESSION_LEVEL,
44
CATEGORY_SESSION_TYPE,
55
QUESTION_SESSION_NUMBER,
6+
QUESTION_SLIDE_URL,
67
SessionizeCategorySchemaType,
78
SessionizeRoomSchemaType,
89
SessionizeSessionSchemaType,
@@ -159,3 +160,16 @@ export const formatSpeakerName = (firstName: string, lastName: string): string =
159160
}
160161
return `${firstName} ${lastName}`
161162
}
163+
164+
/**
165+
* Get URL for the slide of the session.
166+
* @param questionAnswers - list of the set of a question and an answer belongs to each session.
167+
*/
168+
export const getSlideUrl = (questionAnswers: SessionizeSessionSchemaType['questionAnswers']): string | null => {
169+
const questionForSlideUrl = questionAnswers.find(q => q.questionId === QUESTION_SLIDE_URL)
170+
if (!questionForSlideUrl) {
171+
return null
172+
}
173+
174+
return questionForSlideUrl.answerValue
175+
}

src/pages/sessions/[id].tsx

+27-11
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,18 @@ import { replaceUrlWithLink } from 'src/modules/util/text'
1212
import { fetchSessionize } from 'src/modules/sessionize/fetch-sessionize'
1313
import {
1414
formatSpeakerName,
15-
getGoogleCalendarEventCreationLink,
1615
getRoom,
1716
getSession,
1817
getSessionLevel,
1918
getSessionType,
19+
getSlideUrl,
2020
getSpeaker,
2121
getTwitterUserName
2222
} from 'src/modules/sessionize/utils'
2323
import Head from 'next/head'
24-
import { GoogleCalendarButton, TweetButton } from 'src/components/molecules'
25-
import { PageHeading } from 'src/components/atoms'
24+
import { TweetButton, YouTubeEmbedFrame } from 'src/components/molecules'
25+
import { Button, PageHeading } from 'src/components/atoms'
26+
import { useTranslation } from 'react-i18next'
2627

2728
type Props = {
2829
title: string
@@ -31,7 +32,8 @@ type Props = {
3132
description: string
3233
sessionType: string | null
3334
sessionLevel: string | null
34-
googleCalendarEventCreationLink: string
35+
recordingUrl: string | null
36+
slideUrl: string | null
3537
speaker: {
3638
fullName: string
3739
profilePicture: string
@@ -97,14 +99,14 @@ export const getStaticProps: GetStaticProps<Props> = async ({ params }) => {
9799
roomId,
98100
categoryItems,
99101
speakers: speakerIds,
100-
startsAt,
101-
endsAt
102+
questionAnswers,
103+
recordingUrl
102104
} = getSession(sessions, sessionId)
103105

104106
const { name: roomName } = getRoom(rooms, roomId)
105107
const sessionLevel = getSessionLevel(categories, categoryItems)
106108
const sessionType = getSessionType(categories, categoryItems)
107-
const googleCalendarEventCreationLink = getGoogleCalendarEventCreationLink(startsAt, endsAt, title, description)
109+
const slideUrl = getSlideUrl(questionAnswers)
108110
const { firstName, lastName, profilePicture, bio, tagLine, links } = getSpeaker(speakers, speakerIds[0])
109111
const fullName = formatSpeakerName(firstName, lastName)
110112
const twitterUserName = getTwitterUserName(links)
@@ -117,7 +119,8 @@ export const getStaticProps: GetStaticProps<Props> = async ({ params }) => {
117119
description,
118120
sessionLevel,
119121
sessionType,
120-
googleCalendarEventCreationLink,
122+
recordingUrl,
123+
slideUrl,
121124
speaker: { fullName, profilePicture, bio, tagLine, twitterUserName }
122125
}
123126
}
@@ -130,9 +133,11 @@ const Page: NextPage<InferGetStaticPropsType<typeof getStaticProps>> = ({
130133
description,
131134
sessionLevel,
132135
sessionType,
133-
googleCalendarEventCreationLink,
136+
recordingUrl,
137+
slideUrl,
134138
speaker: { fullName, profilePicture, bio, tagLine, twitterUserName }
135139
}) => {
140+
const { t } = useTranslation()
136141
return (
137142
<Layout>
138143
<Head>
@@ -150,6 +155,18 @@ const Page: NextPage<InferGetStaticPropsType<typeof getStaticProps>> = ({
150155
>
151156
<PageHeading textAlign="left">{title}</PageHeading>
152157

158+
{/* Archive */}
159+
{(recordingUrl || slideUrl) && (
160+
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '24px', alignItems: 'center', mb: '40px' }}>
161+
{recordingUrl && <YouTubeEmbedFrame recordingUrl={recordingUrl} />}
162+
{slideUrl && (
163+
<a href={slideUrl} target="_blank">
164+
<Button text={t('see_slide')} />
165+
</a>
166+
)}
167+
</Box>
168+
)}
169+
153170
{/* Session's info */}
154171
<Box sx={{ display: 'flex', flexDirection: 'column', gap: '16px', mb: '32px' }}>
155172
<Box sx={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
@@ -209,8 +226,7 @@ const Page: NextPage<InferGetStaticPropsType<typeof getStaticProps>> = ({
209226
</Box>
210227

211228
{/* Share */}
212-
<Box sx={{ display: 'flex', gap: '16px', justifyContent: 'flex-end', mb: '64px' }}>
213-
<GoogleCalendarButton googleCalendarEventCreationLink={googleCalendarEventCreationLink} />
229+
<Box sx={{ display: 'flex', justifyContent: 'flex-end', mb: '64px' }}>
214230
<TweetButton sessionId={sessionId} title={title} roomName={roomName} />
215231
</Box>
216232

0 commit comments

Comments
 (0)