From 7b212eff9495b5e7c381019fe25fc655da5c4a1e Mon Sep 17 00:00:00 2001 From: Prince Baghel Date: Tue, 21 Nov 2023 15:03:38 +0530 Subject: [PATCH] update: adding audio queue --- src/app/usr/layout.tsx | 10 +-- src/assets/audio.css | 23 +++++++ src/components/audioplayer.tsx | 119 +++++++++++++++++++++++++++++++++ src/components/chatmessage.tsx | 15 ++++- src/components/inputBar.tsx | 2 +- src/store/index.ts | 53 ++++++++++++++- 6 files changed, 212 insertions(+), 10 deletions(-) create mode 100644 src/assets/audio.css create mode 100644 src/components/audioplayer.tsx diff --git a/src/app/usr/layout.tsx b/src/app/usr/layout.tsx index 5b36a2fb..89c9aa71 100644 --- a/src/app/usr/layout.tsx +++ b/src/app/usr/layout.tsx @@ -3,7 +3,9 @@ import { Header } from "@/components/header"; // export const dynamic = "force-dynamic", // revalidate = 0; import useStore from "@/store"; + import { useRef, useEffect } from "react"; +import AudioPlayer from "@/components/audioplayer"; export default function LoggedInLayout({ children, // will be a page or nested layout @@ -28,13 +30,7 @@ export default function LoggedInLayout({ return (
- +
{children}
diff --git a/src/assets/audio.css b/src/assets/audio.css new file mode 100644 index 00000000..3e857123 --- /dev/null +++ b/src/assets/audio.css @@ -0,0 +1,23 @@ +audio::-webkit-media-controls-panel { + display: flex; + align-items: center; + justify-content: center; + /* background: transparent; */ +} + +audio::-webkit-media-controls-play-button{ + transform: scale(2.5); + /* background-color: black; */ + +} +audio::-webkit-media-controls-timeline-container, +audio::-webkit-media-controls-current-time-display, +audio::-webkit-media-controls-time-remaining-display, +audio::-webkit-media-controls-mute-button, +audio::-webkit-media-controls-volume-slider { + display: none !important; + width: 0 !important; + height: 0 !important; + margin: 0 !important; + padding: 0 !important; +} diff --git a/src/components/audioplayer.tsx b/src/components/audioplayer.tsx new file mode 100644 index 00000000..9290ff41 --- /dev/null +++ b/src/components/audioplayer.tsx @@ -0,0 +1,119 @@ +"use client"; +import React, { useRef } from "react"; +import { + DropdownMenu, + DropdownMenuTrigger, + DropdownMenuContent, + DropdownMenuSeparator, + DropdownMenuItem, + DropdownMenuLabel, +} from "@/components/ui/dropdownmeu"; +import { useStore } from "@/store"; +import { ChevronDown } from "lucide-react"; +import "../assets/audio.css"; + +type Props = {}; + +const AudioPlayer = (props: Props) => { + const { + audioSrc, + currentTrackIndex, + isPlaying, + pause, + play, + playNextTrack, + playTrack, + queueTracks, + reset, + setAudioSrc, + tracks, + } = useStore(); + const audioRef = useRef(null); + const currentTrack = + currentTrackIndex !== null ? tracks[currentTrackIndex] : null; + // console.log("currentTrack", currentTrack) + + const handlePlay = () => { + if (currentTrackIndex === null) { + console.log("no current track"); + playTrack(0); + } else { + play(); + if (audioRef.current) { + if (audioRef.current.paused) { + audioRef.current.play(); + } + } + } + }; + const handleReset = () => { + reset(); + if (audioRef.current) { + if (!audioRef.current.paused) { + audioRef.current.pause(); + } + } + }; + + const handlePause = () => { + if (audioRef.current) { + if (!audioRef.current.paused) { + audioRef.current.pause(); + } + } + console.log("pause", isPlaying); + pause(); + console.log("pause", isPlaying); + }; + + const handleEnded = () => { + console.log("ended the track"); + playNextTrack(); + }; + + const handleTrackClick = (index: number) => { + console.log("track clicked", index); + playTrack(index); + }; + + return ( + + + {/* {currentTrack ? ( */} + + {/* ) : null} */} + Music + + + +
+ Title + + {tracks.map((track: any, index) => ( + handleTrackClick(index)} + > + {track.title.split(" ").slice(0, 5).join(" ")} + + ))} +
+
+ + + +
+
+
+ ); +}; + +export default AudioPlayer; diff --git a/src/components/chatmessage.tsx b/src/components/chatmessage.tsx index ac699b9c..b5d269da 100644 --- a/src/components/chatmessage.tsx +++ b/src/components/chatmessage.tsx @@ -135,7 +135,13 @@ const ChatMessage = (props: ChatMessageProps) => { const textToSpeech = async (id: string) => { if (audioSrc !== "") { - store.setAudioSrc(audioSrc); + const length = store.tracks.length; + store.queueTracks({ + id: props.chat.id, + src: audioSrc, + title: props.chat.content, + }); + store.playTrack(length); return; } const text = props.chat.content; @@ -156,6 +162,13 @@ const ChatMessage = (props: ChatMessageProps) => { const url = data.audioUrl; props.setMessages(data.updatedMessages); store.setAudioSrc(url); + const length = store.tracks.length; + store.queueTracks({ + id: props.chat.id, + src: url, + title: props.chat.content, + }); + store.playTrack(length); setAudioSrc(url); } catch (err) { console.log(err); diff --git a/src/components/inputBar.tsx b/src/components/inputBar.tsx index 0fb3672a..f5591324 100644 --- a/src/components/inputBar.tsx +++ b/src/components/inputBar.tsx @@ -166,7 +166,7 @@ const InputBar = (props: InputBarProps) => { }; return ( -
+ void; reset: () => void; + tracks: track[]; + currentTrackIndex: number | null; + isPlaying: boolean; + play: () => void; + pause: () => void; + playTrack: (index: number) => void; + queueTracks: (track: track) => void; + playNextTrack: () => void; }; export const useStore = create()( @@ -15,7 +33,40 @@ export const useStore = create()( audioSrc: "", setAudioSrc: (src) => set((state) => ({ ...state, audioSrc: src })), reset: () => { - set({ audioSrc: undefined }); + set({ + tracks: [] as track[], + currentTrackIndex: null, + isPlaying: false, + }); + }, + tracks: [] as track[], + currentTrackIndex: null, + isPlaying: false, + play: () => set({ isPlaying: true }), + pause: () => set({ isPlaying: false }), + playTrack: (index) => + set({ + currentTrackIndex: index, + isPlaying: true, + }), + queueTracks: (track) => { + const { tracks } = get(); + const isAlreadyAdded = tracks.find((t) => t.id === track.id); + if (isAlreadyAdded) { + return; + } else { + set({ tracks: [...tracks, track] }); + } + }, + playNextTrack: () => { + const { tracks, currentTrackIndex } = get(); + const nextTrackIndex = + currentTrackIndex !== null ? currentTrackIndex + 1 : 0; + if (nextTrackIndex < tracks.length) { + set({ currentTrackIndex: nextTrackIndex }); + } else { + set({ currentTrackIndex: null, isPlaying: false }); + } }, }), {