diff --git a/app/components/station-player.tsx b/app/components/station-player.tsx index 04a8b5a..36f8f32 100644 --- a/app/components/station-player.tsx +++ b/app/components/station-player.tsx @@ -1,13 +1,20 @@ +import { useNavigate } from "@remix-run/react"; import type { ReactNode} from "react"; import { useEffect, useState } from "react"; import type { StationWithTagsClientSide } from "~/models/station.server"; +import { getStationUrl } from "~/utils"; export type StationPlayerProps = { - station: StationWithTagsClientSide | null + station: StationWithTagsClientSide | null, + nextPrevStationIds: { + prev?: string; + next?: string; + }, }; -export function StationPlayer({ station }: StationPlayerProps) { +export function StationPlayer({ station, nextPrevStationIds }: StationPlayerProps) { const [player, setPlayer] = useState(null); + const route = useNavigate(); useEffect(() => { if (typeof window === 'undefined') return; @@ -18,10 +25,20 @@ export function StationPlayer({ station }: StationPlayerProps) { const module = await import('react-radio-player'); const RadioBottomBarPlayer = module.RadioBottomBarPlayer; setPlayer( { + if (!nextPrevStationIds.next) return; + route(getStationUrl(nextPrevStationIds.next)) + }} + onPrevButtonClicked={() => { + if (!nextPrevStationIds.prev) return; + route(getStationUrl(nextPrevStationIds.prev)) + }} secondDescription={<>★ {station.popularity}} />); } catch (error) { diff --git a/app/components/stations-gallery.tsx b/app/components/stations-gallery.tsx index 611c06b..dcbe0c9 100644 --- a/app/components/stations-gallery.tsx +++ b/app/components/stations-gallery.tsx @@ -3,7 +3,7 @@ import type { Tag } from "@prisma/client"; import { Link } from "@remix-run/react"; import { ListenLink } from "~/components/page-layout"; import type { StationWithTagsClientSide } from "~/models/station.server"; -import type { ConvertDatesToStrings } from "~/utils"; +import { getStationUrl, type ConvertDatesToStrings } from "~/utils"; export type StationsGalleryProps = { stations: StationWithTagsClientSide[]; @@ -11,14 +11,6 @@ export type StationsGalleryProps = { }; export function StationsGallery({ stations, tag }: StationsGalleryProps) { - - function getStationUrl(id: string): string { - if (tag) { - return `/listen/tag/${tag?.slug}?station=${id}`; - } - return `/listen?station=${id}`; - } - return (
{stations.map((station) => { @@ -37,7 +29,7 @@ export function StationsGallery({ stations, tag }: StationsGalleryProps) {

{station.description}

- Listen Now diff --git a/app/models/station.server.ts b/app/models/station.server.ts index 9c9fb63..07613b9 100644 --- a/app/models/station.server.ts +++ b/app/models/station.server.ts @@ -37,6 +37,34 @@ export function getStations(reliability: number = 80) { }); } +/** + * + * @param stationId current station id that we want to get next and prev + * @returns + */ +export const getPrevNextStations = async (stationId?: string) => { + const defaultData = { + prev: undefined, + next: undefined + } + if (!stationId) return defaultData; + + const stations = await getStations(); + + return stations.reduce((prev, currStation, index, array) => { + if (currStation.id === stationId) { + return { + prev: array[index - 1]?.id, + next: array[index + 1]?.id, + } + } + return prev + }, defaultData as { + prev?: string, + next?: string, + }) +} + /** * Fetch stations tagged with `tags` and a reliability score GTE to the `reliability` parameter. */ diff --git a/app/routes/listen.tsx b/app/routes/listen.tsx index b397e02..80a483a 100644 --- a/app/routes/listen.tsx +++ b/app/routes/listen.tsx @@ -4,7 +4,7 @@ import { Outlet, useLoaderData } from "@remix-run/react"; import { PageLayout } from "~/components/page-layout"; import { StationPlayer } from "~/components/station-player"; import type { StationWithTags } from "~/models/station.server"; -import { getStationById } from "~/models/station.server"; +import { getPrevNextStations, getStationById } from "~/models/station.server"; import type { TagWithStations } from "~/models/tag.server"; import { getTags } from "~/models/tag.server"; import { getUser } from "~/session.server"; @@ -15,15 +15,18 @@ export async function loader({ request }: LoaderArgs) { const url = new URL(request.url); const stationId = url.searchParams.get("station"); const station: StationWithTags | null = stationId ? await getStationById(stationId) : null; - return json({ user, tags, station }); + const prevNextStationIds = await getPrevNextStations(station?.id) + return json({ user, tags, station, prevNextStationIds }); } export default function ListenLayout() { - const { tags, user, station } = useLoaderData(); + const { tags, user, station, prevNextStationIds } = useLoaderData(); + + console.log(prevNextStationIds) return ( - + ); } diff --git a/app/utils.ts b/app/utils.ts index 3908ba0..aab0a7c 100644 --- a/app/utils.ts +++ b/app/utils.ts @@ -27,6 +27,13 @@ export function safeRedirect( return to; } +export function getStationUrl(id: string, tag?: {slug: string}): string { + if (tag) { + return `/listen/tag/${tag?.slug}?station=${id}`; + } + return `/listen?station=${id}`; +} + /** * This base hook is used in other hooks to quickly search for specific data * across all loader data using useMatches. diff --git a/package.json b/package.json index b7ab204..83260b8 100644 --- a/package.json +++ b/package.json @@ -39,7 +39,7 @@ "isbot": "^3.6.8", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-radio-player": "^0.1.4", + "react-radio-player": "^0.1.8", "tiny-invariant": "^1.3.1" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index eb33225..33b1508 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7712,10 +7712,10 @@ react-is@^18.0.0, react-is@^18.2.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== -react-radio-player@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/react-radio-player/-/react-radio-player-0.1.5.tgz#5fe89392c539997b090f7101797ad0f6e0acd328" - integrity sha512-8lA309mOq2vT+JIznfimEJsWliIvJzxmvSXK8SA4BfRN9iXyd8oqm9VtI4311JPFgwYnG5ymvRXxp7GUj/bluw== +react-radio-player@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/react-radio-player/-/react-radio-player-0.1.8.tgz#85ad58adab1fd7f846ba39d79ef1a115eb50bca4" + integrity sha512-PWCDBWfemSfMY7hoAeLBYwE8o49dEBg+PMIuIZDe3ZTpHqNIuPaL54SFmYHW4iMqSaE+9bToziXxpid9izberw== dependencies: rc-slider "^10.5.0" styled-components "^6.1.1"