diff --git a/frontend/src/components/molecules/RadioDetails/RadioContainer.tsx b/frontend/src/components/molecules/RadioDetails/RadioContainer.tsx new file mode 100644 index 000000000..611b1588b --- /dev/null +++ b/frontend/src/components/molecules/RadioDetails/RadioContainer.tsx @@ -0,0 +1,102 @@ +import React, { FC } from "react"; +import styled from "styled-components"; +import ReactMarkdown from "react-markdown"; +import { useLocation } from "react-router-dom"; +import { device, color } from "@/constants/styles"; +import { CHK } from "@/constants/url"; + +import { RadioPlayer } from "@/components/molecules/RadioDetails/RadioPlayer"; +import Personalities from "@/components/molecules/Personalities"; +import { Share } from "@/components/molecules/RadioDetails/Share"; + +import { IRadio } from "@/api/RadioApi"; +import { PersonalityProfileMiniCard } from "@/components/atoms/FeaturedPersonality/PersonalityProfileMiniCard"; + +interface Props { + radio: IRadio | undefined; +} + +export const RadioContainer: FC = ({ radio }) => { + const location = useLocation(); + const SHARE_URL = CHK.FRONT_END.PROD + location.pathname; + + if (radio) { + return ( + <> + + + + + + + + + + + + + + + 出演しているパーソナリティー + + + + + + + {radio.title} + + + + + + 出演しているパーソナリティー + {radio.personalities.map(({ name, image, id }) => ( + + ))} + + + + ); + } + + return null; +}; + +const PCWrapper = styled.div` + padding: 50px; +`; + +const MobileWrapper = styled.div` + width: calc(100% - 20px); + margin: 0 auto; +`; + +const Top = styled.div` + display: flex; + width: 100%; +`; + +const Left = styled.div` + width: 50%; + padding-right: 25px; +`; + +const Right = styled.div` + width: 50%; + padding-left: 25px; +`; + +const Title = styled.h2` + font-size: 1.5rem; + text-align: left; + color: ${color.BLUE}; + margin: 5px 0; +`; + +const Description = styled.div``; + +const Bottom = styled.div` + width: 100%; + margin-top: 50px; +`; diff --git a/frontend/src/pages/RadioDetail.tsx b/frontend/src/pages/RadioDetail.tsx index b63224794..17eddbf20 100644 --- a/frontend/src/pages/RadioDetail.tsx +++ b/frontend/src/pages/RadioDetail.tsx @@ -1,24 +1,16 @@ import React, { Suspense, useState, useEffect } from "react"; import styled from "styled-components"; -import { useParams, useLocation } from "react-router-dom"; +import { useParams } from "react-router-dom"; import { observer } from "mobx-react-lite"; -import ReactMarkdown from "react-markdown"; -import { device, color } from "@/constants/styles"; -import { CHK } from "@/constants/url"; - +import { device } from "@/constants/styles"; import RootStore from "@/stores/RootStore"; import RadioStore from "@/stores/RadioStore"; - import { RadioDetailHeroArea } from "@/components/molecules/HeroArea/RadioDetailHeroArea"; import TweetStream from "@/components/atoms/Features/TweetStream"; import { PopularRadiosWrapper } from "@/components/molecules/PopularRadio/PopularRadioWrapper"; -import { RadioPlayer } from "@/components/molecules/RadioDetails/RadioPlayer"; -import Personalities from "@/components/molecules/Personalities"; -import { Share } from "@/components/molecules/RadioDetails/Share"; +import { RadioContainer } from "@/components/molecules/RadioDetails/RadioContainer"; import CircleSpinner from "@/components/atoms/Spinners/CircleSpinner"; - import { IRadio } from "@/api/RadioApi"; -import { PersonalityProfileMiniCard } from "@/components/atoms/FeaturedPersonality/PersonalityProfileMiniCard"; interface Props { radioStore: RadioStore; @@ -27,59 +19,30 @@ interface Props { } const Main: React.FC = ({ radioStore, setRadio, radio }) => { - const location = useLocation(); - const SHARE_URL = CHK.FRONT_END.PROD + location.pathname; const { radioId } = useParams(); + const reFetchRadio = async () => { + const cache = await radioStore.fetchRadio(Number(radioId)); + setRadio(cache); + }; + + useEffect(() => { + reFetchRadio(); + }, [radioId]); + if (radio) { - return ( - <> - - - - - - - - - - - - - - - 出演しているパーソナリティー - - - - - - - {radio ? radio.title : ""} - - - - - - 出演しているパーソナリティー - {radio.personalities.map(({ name, image, id }) => ( - - ))} - - - - ); + return ; } throw (async () => { - const cache = await radioStore.fetchRadio(Number(radioId)); - setRadio(cache); + reFetchRadio(); })(); }; export const RadioDetail = observer((props: { rootStore: RootStore }) => { const { rootStore } = props; const { radioStore } = rootStore; + const { radioId } = useParams(); const [radio, setRadio] = useState(undefined); @@ -94,7 +57,7 @@ export const RadioDetail = observer((props: { rootStore: RootStore }) => { useEffect(() => { const radios = radioStore.shuffledRadios({ limit: 3 }); setPopularRadios(radios); - }, [radioStore.radios]); + }, [radioStore.radios, radioId]); return (
@@ -137,41 +100,3 @@ const MainContentWrapper = styled.div` flex: 0 0 100%; } `; - -const PCWrapper = styled.div` - padding: 50px; -`; - -const MobileWrapper = styled.div` - width: calc(100% - 20px); - margin: 0 auto; -`; - -const Top = styled.div` - display: flex; - width: 100%; -`; - -const Left = styled.div` - width: 50%; - padding-right: 25px; -`; - -const Right = styled.div` - width: 50%; - padding-left: 25px; -`; - -const Title = styled.h2` - font-size: 1.5rem; - text-align: left; - color: ${color.BLUE}; - margin: 5px 0; -`; - -const Description = styled.div``; - -const Bottom = styled.div` - width: 100%; - margin-top: 50px; -`; diff --git a/frontend/src/stores/RadioStore.ts b/frontend/src/stores/RadioStore.ts index 37a097591..2c0793357 100644 --- a/frontend/src/stores/RadioStore.ts +++ b/frontend/src/stores/RadioStore.ts @@ -34,7 +34,13 @@ export default class RadioStore { ]; } - return shuffledRadio.slice(0, limit); + const randomOffset = Math.floor( + Math.random() * (shuffledRadio.length - (limit || 0)) + ); + + return limit + ? shuffledRadio.slice(randomOffset, randomOffset + limit) + : shuffledRadio; } public async fetchRadio(radioId: number) {