feat: 完成歌名透传
This commit is contained in:
parent
c26d2b578c
commit
ec1620462d
13
app/danmu/current-input.tsx
Normal file
13
app/danmu/current-input.tsx
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useContext } from "react";
|
||||||
|
import { DanmuContext } from "./provider";
|
||||||
|
|
||||||
|
export default function CurrentInput() {
|
||||||
|
const state = useContext(DanmuContext);
|
||||||
|
return (
|
||||||
|
<div className="input">
|
||||||
|
{state.songName ?? ""} {state.songId ? "-" : ""} {state.songArtist ?? ""}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
34
app/danmu/live-check.tsx
Normal file
34
app/danmu/live-check.tsx
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useContext } from "react";
|
||||||
|
import { DanmuContext } from "./provider";
|
||||||
|
|
||||||
|
export default function LiveCheck({ lives }: { lives: any[] }) {
|
||||||
|
const { dispatch, ...state } = useContext(DanmuContext);
|
||||||
|
return (
|
||||||
|
<ul className="divide-y divide-gray-300">
|
||||||
|
{lives.map((live, i) => (
|
||||||
|
<li key={i}>
|
||||||
|
<label>
|
||||||
|
{live.name} - {live.room_id}
|
||||||
|
<input
|
||||||
|
onChange={(e) => {
|
||||||
|
dispatch({
|
||||||
|
type: "lives",
|
||||||
|
payload: {
|
||||||
|
liveId: live.room_id,
|
||||||
|
liveName: live.name,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
className="raido radio-primary"
|
||||||
|
type="radio"
|
||||||
|
name="live"
|
||||||
|
checked={live.room_id === state.liveId}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
}
|
@ -3,6 +3,10 @@ import Controls from "./controls";
|
|||||||
import Danmu from "./danmu";
|
import Danmu from "./danmu";
|
||||||
import { listLives } from "@/lib/actions/live";
|
import { listLives } from "@/lib/actions/live";
|
||||||
import { listSongs } from "../songs/actions";
|
import { listSongs } from "../songs/actions";
|
||||||
|
import DanmuProvider from "./provider";
|
||||||
|
import LiveCheck from "./live-check";
|
||||||
|
import SongCheck from "./song-check";
|
||||||
|
import CurrentInput from "./current-input";
|
||||||
|
|
||||||
export default async function Page() {
|
export default async function Page() {
|
||||||
const token = await getToken();
|
const token = await getToken();
|
||||||
@ -10,61 +14,37 @@ export default async function Page() {
|
|||||||
const songs = await listSongs();
|
const songs = await listSongs();
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col md:flex-row">
|
<div className="flex flex-col md:flex-row">
|
||||||
<section className="basis-1/3 card">
|
<DanmuProvider>
|
||||||
<div className="h-[50vh] md:h-[80vh] overflow-auto card bg-base-100 card-bordered m-8">
|
<section className="basis-1/3 card">
|
||||||
<div className="card-body">
|
<div className="h-[50vh] md:h-[80vh] overflow-auto card bg-base-100 card-bordered m-8">
|
||||||
<div className="card-title">直播间列表</div>
|
<div className="card-body">
|
||||||
<ul>
|
<div className="card-title">直播间列表</div>
|
||||||
{lives.map((live, i) => (
|
<LiveCheck lives={lives} />
|
||||||
<li key={i}>
|
|
||||||
<label>
|
|
||||||
{live.name} - {live.room_id}
|
|
||||||
<input
|
|
||||||
className="raido radio-primary"
|
|
||||||
type="radio"
|
|
||||||
name="live"
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section className="basis-1/3 card">
|
|
||||||
<div className="h-[50vh] md:h-[80vh] overflow-auto card bg-base-100 card-bordered m-8">
|
|
||||||
<div className="card-body">
|
|
||||||
<div className="card-title">收藏的歌曲</div>
|
|
||||||
<ul>
|
|
||||||
{songs.map((song, i) => (
|
|
||||||
<li key={i}>
|
|
||||||
<label>
|
|
||||||
{song.name} - {song.artist}
|
|
||||||
<input
|
|
||||||
className="raido radio-primary"
|
|
||||||
type="radio"
|
|
||||||
name="song"
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
</li>
|
|
||||||
))}
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section className="basis-1/3 card">
|
|
||||||
<div className="card-body">
|
|
||||||
<div className="mockup-browser border">
|
|
||||||
<div className="mockup-browser-toolbar">
|
|
||||||
<div className="input">红豆</div>
|
|
||||||
</div>
|
|
||||||
<div className="divide-y divide-gray-300">
|
|
||||||
<Controls />
|
|
||||||
<Danmu token={token} />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</section>
|
||||||
</section>
|
<section className="basis-1/3 card">
|
||||||
|
<div className="h-[50vh] md:h-[80vh] overflow-auto card bg-base-100 card-bordered m-8">
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="card-title">收藏的歌曲</div>
|
||||||
|
<SongCheck songs={songs} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section className="basis-1/3 card">
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="mockup-browser border">
|
||||||
|
<div className="mockup-browser-toolbar">
|
||||||
|
<CurrentInput />
|
||||||
|
</div>
|
||||||
|
<div className="divide-y divide-gray-300">
|
||||||
|
<Controls />
|
||||||
|
<Danmu token={token} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</DanmuProvider>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
45
app/danmu/provider.tsx
Normal file
45
app/danmu/provider.tsx
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
"use client";
|
||||||
|
import { createContext, useReducer } from "react";
|
||||||
|
|
||||||
|
export interface DanmuPayload {
|
||||||
|
liveName?: string;
|
||||||
|
liveId?: string;
|
||||||
|
songId?: string;
|
||||||
|
songName?: string;
|
||||||
|
songArtist?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DanmuAction {
|
||||||
|
type: string;
|
||||||
|
payload: DanmuPayload;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const DanmuContext = createContext<DanmuPayload & { dispatch?: any }>(
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
const reducer = (state: DanmuPayload, action: DanmuAction): DanmuPayload => {
|
||||||
|
const payload = action.payload;
|
||||||
|
switch (action.type) {
|
||||||
|
case "songs":
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
songId: payload.songId,
|
||||||
|
songName: payload.songName,
|
||||||
|
songArtist: payload.songArtist,
|
||||||
|
};
|
||||||
|
case "lives":
|
||||||
|
return { ...state, liveId: payload.liveId, liveName: payload.liveName };
|
||||||
|
default:
|
||||||
|
throw new Error("not support action");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function DanmuProvider(props: any) {
|
||||||
|
const [state, dispatch] = useReducer(reducer, {});
|
||||||
|
return (
|
||||||
|
<DanmuContext.Provider value={{ ...state, dispatch }}>
|
||||||
|
{props.children}
|
||||||
|
</DanmuContext.Provider>
|
||||||
|
);
|
||||||
|
}
|
35
app/danmu/song-check.tsx
Normal file
35
app/danmu/song-check.tsx
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { useContext } from "react";
|
||||||
|
import { DanmuContext } from "./provider";
|
||||||
|
|
||||||
|
export default function SongCheck({ songs }: { songs: any[] }) {
|
||||||
|
const { dispatch, ...state } = useContext(DanmuContext);
|
||||||
|
return (
|
||||||
|
<ul className="divide-y divide-gray-300">
|
||||||
|
{songs.map((song, i) => (
|
||||||
|
<li key={i}>
|
||||||
|
<label>
|
||||||
|
{song.name} - {song.artist}
|
||||||
|
<input
|
||||||
|
onChange={(e) => {
|
||||||
|
dispatch({
|
||||||
|
type: "songs",
|
||||||
|
payload: {
|
||||||
|
songId: song.source_id,
|
||||||
|
songName: song.name,
|
||||||
|
songArtist: song.artist,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
className="raido radio-primary"
|
||||||
|
type="radio"
|
||||||
|
name="songs"
|
||||||
|
checked={song.source_id === state.songId}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user