- UI
- Created auto player route for channel and tags
This commit is contained in:
parent
8d06e911d9
commit
fcffc4f295
@ -1,12 +1,27 @@
|
|||||||
|
import type { Tag } from "@prisma/client";
|
||||||
import { Link } from "@remix-run/react";
|
import { Link } from "@remix-run/react";
|
||||||
import type { ConvertDatesToStrings } from "@remix-run/router/utils";
|
|
||||||
import type { StationWithTags } from "~/models/station.server";
|
import type { StationWithTags } from "~/models/station.server";
|
||||||
|
import type { Channel } from "~/routes/listen.channel.$channel";
|
||||||
|
import type { ConvertDatesToStrings } from "~/utils";
|
||||||
|
|
||||||
export type StationsGalleryProps = {
|
export type StationsGalleryProps = {
|
||||||
stations: ConvertDatesToStrings<NonNullable<StationWithTags>>[]
|
stations: ConvertDatesToStrings<NonNullable<StationWithTags>>[];
|
||||||
|
tag?: ConvertDatesToStrings<Tag>;
|
||||||
|
channel?: ConvertDatesToStrings<Channel>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function StationsGallery({ stations }: StationsGalleryProps) {
|
export function StationsGallery({ stations, tag, channel }: StationsGalleryProps) {
|
||||||
|
|
||||||
|
function getStationUrl(id: string): string {
|
||||||
|
if (channel) {
|
||||||
|
return `/listen/channel/${channel.slug}/${id}`;
|
||||||
|
}
|
||||||
|
if (tag) {
|
||||||
|
return `/listen/tag/${tag?.slug}/${id}`;
|
||||||
|
}
|
||||||
|
return `/listen/station/${id}`;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-3 gap-4">
|
<div className="grid grid-cols-3 gap-4">
|
||||||
{stations.map((station) => {
|
{stations.map((station) => {
|
||||||
@ -25,7 +40,7 @@ export function StationsGallery({ stations }: StationsGalleryProps) {
|
|||||||
</h2>
|
</h2>
|
||||||
<p>{station.description}</p>
|
<p>{station.description}</p>
|
||||||
<div className="card-actions justify-end">
|
<div className="card-actions justify-end">
|
||||||
<button className="btn btn-primary">Listen Now</button>
|
<Link to={getStationUrl(station.id)} className="btn btn-primary">Listen Now</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
33
app/routes/listen.channel.$channel.$station.tsx
Normal file
33
app/routes/listen.channel.$channel.$station.tsx
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
import type { LoaderArgs } from "@remix-run/node";
|
||||||
|
import { json } from "@remix-run/node";
|
||||||
|
import { useLoaderData } from "@remix-run/react";
|
||||||
|
import { getStationById } from "~/models/station.server";
|
||||||
|
import { notFound } from "~/utils";
|
||||||
|
|
||||||
|
|
||||||
|
export async function loader({ params }: LoaderArgs) {
|
||||||
|
if (!params.station) {
|
||||||
|
throw notFound();
|
||||||
|
}
|
||||||
|
|
||||||
|
const station = await getStationById(params.station);
|
||||||
|
if (!station) {
|
||||||
|
throw notFound();
|
||||||
|
}
|
||||||
|
return json({ station });
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function ListenChanelStation() {
|
||||||
|
const { station } = useLoaderData<typeof loader>();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="fixed bottom-0 left-0 w-full h-[70px] px-4 py-2 z-50 flex justify-end"
|
||||||
|
data-theme="aqua">
|
||||||
|
|
||||||
|
<audio controls autoPlay src={station.streamUrl}>
|
||||||
|
Your browser does not support the audio element.
|
||||||
|
</audio>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import type { LoaderArgs } from "@remix-run/node";
|
import type { LoaderArgs } from "@remix-run/node";
|
||||||
import { json } from "@remix-run/node";
|
import { json } from "@remix-run/node";
|
||||||
import { Link, useLoaderData } from "@remix-run/react";
|
import { Link, Outlet, useLoaderData } from "@remix-run/react";
|
||||||
import { Breadcrumbs } from "~/components/breadcrumbs";
|
import { Breadcrumbs } from "~/components/breadcrumbs";
|
||||||
import { StationsGallery } from "~/components/stations-gallery";
|
import { StationsGallery } from "~/components/stations-gallery";
|
||||||
import type { StationWithTags } from "~/models/station.server";
|
import type { StationWithTags } from "~/models/station.server";
|
||||||
@ -51,7 +51,8 @@ export default function ListenChannel() {
|
|||||||
<Link to="/listen">Home</Link>
|
<Link to="/listen">Home</Link>
|
||||||
<Link to={`/listen/${channel.slug}`}>{channel.name}</Link>
|
<Link to={`/listen/${channel.slug}`}>{channel.name}</Link>
|
||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
<StationsGallery stations={stations} />
|
<StationsGallery stations={stations} channel={channel} />
|
||||||
|
<Outlet />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
7
app/routes/listen.tag.$tag.$station.tsx
Normal file
7
app/routes/listen.tag.$tag.$station.tsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import ListenChanelStation from "~/routes/listen.channel.$channel.$station";
|
||||||
|
|
||||||
|
export { loader } from "~/routes/listen.channel.$channel.$station";
|
||||||
|
export default ListenChanelStation;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
import type { LoaderArgs } from "@remix-run/node";
|
import type { LoaderArgs } from "@remix-run/node";
|
||||||
import { json } from "@remix-run/node";
|
import { json } from "@remix-run/node";
|
||||||
import { Link, useLoaderData } from "@remix-run/react";
|
import { Link, Outlet, useLoaderData } from "@remix-run/react";
|
||||||
import { Breadcrumbs } from "~/components/breadcrumbs";
|
import { Breadcrumbs } from "~/components/breadcrumbs";
|
||||||
import { StationsGallery } from "~/components/stations-gallery";
|
import { StationsGallery } from "~/components/stations-gallery";
|
||||||
import type { StationWithTags } from "~/models/station.server";
|
import type { StationWithTags } from "~/models/station.server";
|
||||||
@ -34,7 +34,8 @@ export default function ListenTag() {
|
|||||||
<Link to="/listen">Home</Link>
|
<Link to="/listen">Home</Link>
|
||||||
<Link to={`/listen/${tag.slug}`} className="capitalize">{tag.name}</Link>
|
<Link to={`/listen/${tag.slug}`} className="capitalize">{tag.name}</Link>
|
||||||
</Breadcrumbs>
|
</Breadcrumbs>
|
||||||
<StationsGallery stations={stations} />
|
<StationsGallery stations={stations} tag={tag} />
|
||||||
|
<Outlet />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -98,3 +98,11 @@ export function slugify(string: string): string {
|
|||||||
.replace(/^-+/, "") // Trim - from start of text
|
.replace(/^-+/, "") // Trim - from start of text
|
||||||
.replace(/-+$/, ""); // Trim - from end of text
|
.replace(/-+$/, ""); // Trim - from end of text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type ConvertDatesToStrings<T> = T extends Date
|
||||||
|
? string
|
||||||
|
: T extends Array<infer U>
|
||||||
|
? ConvertDatesToStrings<U>[]
|
||||||
|
: T extends object
|
||||||
|
? { [K in keyof T]: ConvertDatesToStrings<T[K]> }
|
||||||
|
: T;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user