Skip to content

Commit

Permalink
update: adding audio queue
Browse files Browse the repository at this point in the history
  • Loading branch information
PrinceBaghel258025 committed Nov 21, 2023
1 parent 55d4e49 commit 7b212ef
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 10 deletions.
10 changes: 3 additions & 7 deletions src/app/usr/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -28,13 +30,7 @@ export default function LoggedInLayout({
return (
<div className="relative">
<Header className="bg-black/40 backdrop-blur-md">
<audio
ref={audioRef}
src={store.audioSrc}
controls
controlsList="nodownload noplaybackrate"
className="max-h-[60px]"
></audio>
<AudioPlayer />
</Header>
<div className="pl-5 pr-5 z-10 relative">{children}</div>
</div>
Expand Down
23 changes: 23 additions & 0 deletions src/assets/audio.css
Original file line number Diff line number Diff line change
@@ -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;
}
119 changes: 119 additions & 0 deletions src/components/audioplayer.tsx
Original file line number Diff line number Diff line change
@@ -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<HTMLAudioElement>(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 (
<DropdownMenu>
<DropdownMenuTrigger className="flex items-center gap-2 outline-none">
{/* {currentTrack ? ( */}
<audio
ref={audioRef}
src={currentTrack ? currentTrack?.src : undefined}
onEnded={handleEnded}
autoPlay={isPlaying}
controls
controlsList="nodownload noplaybackrate"
className="max-h-[60px]"
></audio>
{/* ) : null} */}
Music
<ChevronDown />
</DropdownMenuTrigger>
<DropdownMenuContent className=" grid grid-cols-2 bg-background max-w-[700px]">
<div>
<DropdownMenuLabel>Title</DropdownMenuLabel>
<DropdownMenuSeparator />
{tracks.map((track: any, index) => (
<DropdownMenuItem
key={track.id}
onClick={() => handleTrackClick(index)}
>
{track.title.split(" ").slice(0, 5).join(" ")}
</DropdownMenuItem>
))}
</div>
<div className="flex flex-col gap-4">
<button onClick={handlePlay}>Play</button>
<button onClick={handlePause}>Pause</button>
<button onClick={handleReset}>Reset</button>
</div>
</DropdownMenuContent>
</DropdownMenu>
);
};

export default AudioPlayer;
15 changes: 14 additions & 1 deletion src/components/chatmessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/components/inputBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ const InputBar = (props: InputBarProps) => {
};

return (
<form onSubmit={handleSubmit} className="flex flex-grow">
<form onSubmit={handleSubmit} className="flex flex-grow sm:min-w-[700px]">
<motion.div
layout
className="flex flex-grow bg-linear-900 p-2 pt-2 rounded-sm gap-2 "
Expand Down
53 changes: 52 additions & 1 deletion src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,28 @@
import { create } from "zustand";
import { persist } from "zustand/middleware";

type track = {
id: string;
title: string;
// artist: string;
// album: string;
// albumArt: string;
// duration: number;
src: string;
};

type Store = {
audioSrc: string | undefined;
setAudioSrc: (src: string | undefined) => 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<Store>()(
Expand All @@ -15,7 +33,40 @@ export const useStore = create<Store>()(
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 });
}
},
}),
{
Expand Down

0 comments on commit 7b212ef

Please sign in to comment.