Post Audio
deso-ui/post-audioFreeBlock
A component for displaying an audio post.
Install it
npx shadcn@latest add https://ui.deso.com/r/post-audio.jsonSource
1'use client';23import React, { useRef, useEffect, useState, useCallback } from 'react';4import WaveSurfer from 'wavesurfer.js';5import { cn } from '@/lib/utils/deso';6import { Button } from '../ui/button';7import { Play, Pause, Volume2, VolumeX } from 'lucide-react';8import { Slider } from '../ui/slider';910export interface PostAudioProps {11 url: string;12 className?: string;13}1415const formatTime = (seconds: number) => {16 const date = new Date(0);17 date.setSeconds(seconds || 0);18 return date.toISOString().substr(14, 5);19};2021export const PostAudio: React.FC<PostAudioProps> = ({ url, className }) => {22 const containerRef = useRef<HTMLDivElement>(null);23 const wavesurferRef = useRef<WaveSurfer | null>(null);24 const [isPlaying, setIsPlaying] = useState(false);25 const [currentTime, setCurrentTime] = useState(0);26 const [duration, setDuration] = useState(0);27 const [volume, setVolume] = useState(0.5);28 const [isMuted, setIsMuted] = useState(false);2930 useEffect(() => {31 if (!containerRef.current) return;3233 const ws = WaveSurfer.create({34 container: containerRef.current,35 waveColor: '#ddd',36 progressColor: '#333',37 barWidth: 5,38 barGap: 4,39 barRadius: 100,40 height:40,41 url,42 });4344 wavesurferRef.current = ws;45 ws.setVolume(volume);4647 ws.on('play', () => setIsPlaying(true));48 ws.on('pause', () => setIsPlaying(false));49 ws.on('finish', () => setIsPlaying(false));50 ws.on('ready', (newDuration) => setDuration(newDuration));51 ws.on('timeupdate', (newTime) => setCurrentTime(newTime));5253 return () => {54 ws.destroy();55 };56 }, [url]);5758 const onPlayPause = useCallback(() => {59 wavesurferRef.current?.playPause();60 }, []);6162 const onVolumeChange = useCallback((newVolume: number[]) => {63 const newVol = newVolume[0];64 wavesurferRef.current?.setVolume(newVol);65 setVolume(newVol);66 if (newVol > 0) {67 setIsMuted(false);68 }69 }, []);7071 const onMuteToggle = useCallback(() => {72 const newMuted = !isMuted;73 wavesurferRef.current?.setMuted(newMuted);74 setIsMuted(newMuted);75 }, [isMuted]);7677 return (78 <div className={cn('mt-2 rounded-lg border border-border bg-muted', className)}>79 <div className="p-6 bg-background rounded-t-lg" ref={containerRef} />80 <div className="flex justify-between items-center border-t border-border p-2">81 <div className="flex-grow flex gap-4">82 <Button onClick={onPlayPause} variant="outline" size="icon">83// … truncated
Files it writes
More from deso-ui
All 47 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| Action Menuaction-menu | deso-ui | Blocks | Free | no deps | |
| Confirmation Dialogconfirmation-dialog | deso-ui | Blocks | Free | no deps | |
| Copy Buttoncopy-button | deso-ui | Blocks | Free | no deps | |
| Editoreditor | deso-ui | Blocks | Free | no deps | |
| Editor Emoji Pickereditor-emoji-picker | deso-ui | Blocks | Free | no deps | |
| Editor Markdowneditor-markdown | deso-ui | Blocks | Free | no deps | |
| Editor Uploadeditor-upload | deso-ui | Blocks | Free | no deps | |
| Feed Listfeed-list | deso-ui | Blocks | Free | no deps |
