feature/version-1 #1

Open
behnam wants to merge 9 commits from feature/version-1 into main
7 changed files with 69 additions and 22 deletions
Showing only changes of commit 93d96e362d - Show all commits

View File

@ -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<ReactNode | null>(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(<RadioBottomBarPlayer
streamUrl={station.streamUrl}
streamUrl={"http://91.223.70.109:8000/radio.mp3"}
title={station.name}
description={station.description || undefined}
image={station.imgUrl}
isNextButtonDisabled={!nextPrevStationIds.next}
isPrevButtonDisabled={!nextPrevStationIds.prev}
onNextButtonClicked={() => {
if (!nextPrevStationIds.next) return;
route(getStationUrl(nextPrevStationIds.next))
}}
onPrevButtonClicked={() => {
if (!nextPrevStationIds.prev) return;
route(getStationUrl(nextPrevStationIds.prev))
}}
secondDescription={<>&#9733; {station.popularity}</>}
/>);
} catch (error) {

View File

@ -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 (
<div className="grid grid-cols-1 md:grid-cols-3 xl:grid-cols-4 gap-4">
{stations.map((station) => {
@ -37,7 +29,7 @@ export function StationsGallery({ stations, tag }: StationsGalleryProps) {
</h2>
<p>{station.description}</p>
<div className="card-actions justify-end">
<Link preventScrollReset to={getStationUrl(station.id)}
<Link preventScrollReset to={getStationUrl(station.id, tag)}
className={`btn btn-primary gap-2 plausible-event-name=play-station plausible-event-station=${station.slug}`}>
<PlayIcon className="h-6 w-6" />
Listen Now

View File

@ -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.
*/

View File

@ -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<typeof loader>();
const { tags, user, station, prevNextStationIds } = useLoaderData<typeof loader>();
console.log(prevNextStationIds)
return (
<PageLayout tags={tags} user={user} station={station}>
<Outlet />
<StationPlayer station={station} />
<StationPlayer station={station} nextPrevStationIds={prevNextStationIds} />
</PageLayout>
);
}

View File

@ -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.

View File

@ -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": {

View File

@ -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"