- Recordings: custom RecordingAudioPlayer (play/pause, buffering spinner, click-to-seek, time label, eq bars, single-playback antar kartu) + highlight kartu now-playing - Media: thumbnail di disc hero + queue row, equalizer saat playing, badge 'up next', label Paused vs Now playing - MiniPlayer global di AppFrame (fixed bottom-right, hidden on /media) menggantikan use-media-player.tsx dead provider (dihapus) - Voice: mic level meter live (AnalyserNode RMS) + slider mic/listen volume
3.3 KiB
3.3 KiB
Spec: Perbagus fitur Voice + Audio Playback (GMW frontend)
Tanggal: 2026-08-22 · Scope: frontend only (backend/gateway API sudah cukup)
Masalah (audit)
- Recordings: semua kartu pakai
<audio controls>native — tampilan identik, tidak ada indikasi which-clip-playing / loading / paused, dan N audio bisa play bareng (overlap). - Media view:
thumbnailUrldari gateway tidak dipakai; tidak ada visual "sedang playing" selain disc spin; queue item semua sama tanpa badge up-next. - Mini-player (
lib/hooks/use-media-player.tsx) ada tapi TIDAK PERNAH dimount → dead code, user tidak lihat status musik di halaman lain. - Voice page:
useMicTransmit.setVolume+useVoiceListen.setVolumetersedia tapi tak ada UI-nya; mic live tidak punya level feedback.
Desain
A. RecordingAudioPlayer (baru, components/voice/recording-audio-player.tsx)
Custom player menggantikan <audio controls>:
- Play/pause button (ikon berubah), spinner saat buffering (
waitingevent). - Progress bar seekable (click-to-seek) + time label
m:ss / m:ss. - Waveform-ish equalizer bars saat playing (CSS animation, reduced-motion safe).
- Single-playback: module-level registry
activePlayers— memainkan satu clip otomatis pause yang lain. - Kartu pemilik player aktif dapat highlight border signal + "Now playing" chip.
B. Recordings view — pasang player baru
- Ganti
<audio>→<RecordingAudioPlayer src download_url>. - Highlight kartu via state lifted:
playingIddi view, callbackonPlay.
C. Media view polish
- Hero: thumbnail (jika
current.thumbnailUrl) sebagai disc center image; fallback ListMusic icon. Equalizer bars animasi CSS saatplaying. - Queue row pertama: badge "up next"; baris current track diberi ring signal.
- Volume read-only tetap.
D. MiniPlayer global
- Hapus
lib/hooks/use-media-player.tsx(dead) — ganti dengan komponencomponents/media/mini-player.tsxyang subscribeuseMediaState+useMediaWsSynclangsung (SWR cache shared antar route), mounted diAppFramebawah layar (fixed bottom, hidden di route/media). - Menampilkan: thumbnail kecil/judul, tombol skip/stop, link ke /media.
E. Voice UI
- Mic live: level meter (Equalizer bars) — mic-transmitter sudah punya worklet;
tambah
getLevel()via AnalyserNode pada stream (simple RMS) di hook. - Listen: volume slider (input range) wired ke
listen.setVolume. - Mic volume slider wired ke
mic.setVolume.
File touched
| File | Aksi |
|---|---|
| services/frontend/src/components/voice/recording-audio-player.tsx | new |
| services/frontend/src/app/(dashboard)/recordings/view.tsx | edit |
| services/frontend/src/app/(dashboard)/media/view.tsx | edit |
| services/frontend/src/components/media/mini-player.tsx | new |
| services/frontend/src/components/shell/ambient-app.tsx | mount MiniPlayer |
| services/frontend/src/lib/hooks/use-media-player.tsx | delete |
| services/frontend/src/hooks/use-voice.ts | tambah micLevel |
| services/frontend/src/lib/audio/mic-transmit.ts | expose analyser level |
| services/frontend/src/app/(dashboard)/voice/view.tsx | sliders + meter |
Verifikasi
pnpm lint(biome) +pnpm buildclean.- Smoke di port 4024 (BUKAN 4017) → curl 200 semua route.
- Commit (tanpa trailer) → push →
gh run watch→ live check https://imphnen.asepharyana.my.id/{media,recordings,voice}/ = 200.