From a690e5b63e8a9b6c08cc3e22affacf6550d8ecb7 Mon Sep 17 00:00:00 2001 From: asepharyana Date: Fri, 7 Aug 2026 14:27:33 +0700 Subject: [PATCH] refactor(media): remove volume control from FE & BE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Volume sudah di-set default 0.3 di gateway (suara kecil saat play), dan user bisa naikin sendiri di Discord (command media:volume) — jadi kontrol volume lewat dashboard tak perlu. Hapus: - BE: POST /api/media/volume route, mediaVolumeSchema, setVolume service - FE: useMediaVolume hook, mediaApi.volume, slider volume di music-player + mini-player, field volume/setVolume di MediaPlayerProvider Pertahankan COMMAND_MEDIA_VOLUME di gateway (masih dipakai command DC) dan mic volume (terpisah, tetap di voice page). --- .../backend/src/modules/media/media.routes.ts | 16 ++--------- .../backend/src/modules/media/media.schema.ts | 5 ---- .../src/modules/media/media.service.ts | 18 ------------ .../src/components/media/mini-player.tsx | 21 ++------------ .../src/components/media/music-player.tsx | 28 ++----------------- services/frontend/src/hooks/index.ts | 1 - services/frontend/src/hooks/use-media.ts | 4 --- services/frontend/src/lib/api/media.ts | 2 -- .../src/lib/hooks/use-media-player.tsx | 17 ----------- 9 files changed, 6 insertions(+), 106 deletions(-) diff --git a/services/backend/src/modules/media/media.routes.ts b/services/backend/src/modules/media/media.routes.ts index 747d2a0..443009e 100644 --- a/services/backend/src/modules/media/media.routes.ts +++ b/services/backend/src/modules/media/media.routes.ts @@ -2,8 +2,8 @@ import type { Request, Response, Router } from "express"; import express from "express"; import { createChildLogger } from "@/shared/logger/index"; import { asyncHandler, validateBody } from "../../shared/middlewares/index.js"; -import { mediaQueueSchema, mediaVolumeSchema } from "./media.schema.js"; -import { getStatus, queue, setVolume, skip, stop } from "./media.service.js"; +import { mediaQueueSchema } from "./media.schema.js"; +import { getStatus, queue, skip, stop } from "./media.service.js"; const logger = createChildLogger("media.routes"); @@ -55,17 +55,5 @@ export function createMediaRouter(): Router { }), ); - // POST /api/media/volume - router.post( - "/media/volume", - validateBody(mediaVolumeSchema), - asyncHandler(async (req: Request, res: Response) => { - const { volume } = req.body as { volume: number }; - logger.debug({ volume }, "Media volume requested"); - const state = await setVolume(volume); - res.json(state); - }), - ); - return router; } diff --git a/services/backend/src/modules/media/media.schema.ts b/services/backend/src/modules/media/media.schema.ts index dbb2a42..7f91999 100644 --- a/services/backend/src/modules/media/media.schema.ts +++ b/services/backend/src/modules/media/media.schema.ts @@ -5,9 +5,4 @@ export const mediaQueueSchema = z.object({ mode: z.enum(["music", "screen"]).default("music"), }); -export const mediaVolumeSchema = z.object({ - volume: z.number().min(0).max(1).default(0.3), -}); - export type MediaQueueInput = z.infer; -export type MediaVolumeInput = z.infer; diff --git a/services/backend/src/modules/media/media.service.ts b/services/backend/src/modules/media/media.service.ts index 6760f48..3488c60 100644 --- a/services/backend/src/modules/media/media.service.ts +++ b/services/backend/src/modules/media/media.service.ts @@ -6,7 +6,6 @@ import { COMMAND_MEDIA_QUEUE, COMMAND_MEDIA_SKIP, COMMAND_MEDIA_STOP, - COMMAND_MEDIA_VOLUME, MEDIA_STATUS_KEY, } from "../../shared/index.js"; import { publishCommand, readRedisStatus } from "../../shared/redis/index.js"; @@ -149,20 +148,3 @@ export async function stop(): Promise { "stop", ); } - -/** - * Set volume via Redis command to discord-gateway. - */ -export async function setVolume(volume: number): Promise { - logger.info({ volume }, "setVolume called"); - return tryCommandThenFallback( - () => - publishCommand( - COMMAND_MEDIA_VOLUME, - { volume }, - DEFAULT_COMMAND_TIMEOUT_MS, - ), - () => readStatusFallback(), - "setVolume", - ); -} diff --git a/services/frontend/src/components/media/mini-player.tsx b/services/frontend/src/components/media/mini-player.tsx index 2a7b45b..2777ba6 100644 --- a/services/frontend/src/components/media/mini-player.tsx +++ b/services/frontend/src/components/media/mini-player.tsx @@ -1,11 +1,10 @@ "use client"; -import { Disc3, Music, SkipForward, Square, Volume2 } from "lucide-react"; +import { Disc3, Music, SkipForward, Square } from "lucide-react"; import { useMediaPlayer } from "@/lib/hooks/use-media-player"; export function MiniPlayer() { - const { playing, current, queue, volume, pending, skip, stop, setVolume } = - useMediaPlayer(); + const { playing, current, queue, pending, skip, stop } = useMediaPlayer(); // Nothing to show if no track is playing and nothing is queued if (!current && queue.length === 0) return null; @@ -61,22 +60,6 @@ export function MiniPlayer() { )} - - {/* Volume */} -
- - setVolume(Number(e.target.value))} - className="w-20 h-1 appearance-none rounded-full bg-glass-bg accent-primary cursor-pointer - [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:size-3 [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:bg-primary" - aria-label="Volume" - /> -
); } diff --git a/services/frontend/src/components/media/music-player.tsx b/services/frontend/src/components/media/music-player.tsx index 55a5646..c5c3569 100644 --- a/services/frontend/src/components/media/music-player.tsx +++ b/services/frontend/src/components/media/music-player.tsx @@ -1,24 +1,21 @@ "use client"; -import { Disc3, Music, Play, SkipForward, Square, Volume2 } from "lucide-react"; +import { Disc3, Music, Play, SkipForward, Square } from "lucide-react"; import Image from "next/image"; import { useCallback, useState } from "react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Input } from "@/components/ui/input"; -import { Slider } from "@/components/ui/slider"; import { useMediaQueue, useMediaSkip, useMediaState, useMediaStop, - useMediaVolume, useMediaWsSync, } from "@/hooks"; -import type { WsHook } from "@/lib/ws-hook"; - import type { MediaState } from "@/lib/types"; +import type { WsHook } from "@/lib/ws-hook"; interface MusicPlayerProps { ws: WsHook; @@ -31,7 +28,6 @@ export function MusicPlayer({ ws, initialData }: MusicPlayerProps) { const queueMut = useMediaQueue(); const skipMut = useMediaSkip(); const stopMut = useMediaStop(); - const volumeMut = useMediaVolume(); const [queueUrl, setQueueUrl] = useState(""); const [screenMode, setScreenMode] = useState(false); @@ -47,14 +43,6 @@ export function MusicPlayer({ ws, initialData }: MusicPlayerProps) { setQueueUrl(""); }, [queueUrl, queueMut, screenMode]); - const handleVolume = useCallback( - (value: number | readonly number[]) => { - const vol = Array.isArray(value) ? value[0] : value; - volumeMut.mutate(vol); - }, - [volumeMut], - ); - return ( @@ -143,18 +131,6 @@ export function MusicPlayer({ ws, initialData }: MusicPlayerProps) { Skip -
- - -
{mediaState && mediaState.queue.length > 0 && ( diff --git a/services/frontend/src/hooks/index.ts b/services/frontend/src/hooks/index.ts index 756d5da..c22370d 100644 --- a/services/frontend/src/hooks/index.ts +++ b/services/frontend/src/hooks/index.ts @@ -15,7 +15,6 @@ export { useMediaSkip, useMediaState, useMediaStop, - useMediaVolume, useMediaWsSync, } from "./use-media"; export { diff --git a/services/frontend/src/hooks/use-media.ts b/services/frontend/src/hooks/use-media.ts index 1034338..bc3ebf1 100644 --- a/services/frontend/src/hooks/use-media.ts +++ b/services/frontend/src/hooks/use-media.ts @@ -38,10 +38,6 @@ export function useMediaStop() { return useMediaAction(() => mediaApi.stop()); } -export function useMediaVolume() { - return useMediaAction((volume: number) => mediaApi.volume(volume)); -} - /** Subscribe to WS media_state events to keep cache fresh */ export function useMediaWsSync(ws: WsHook) { const { mutate } = useSWRConfig(); diff --git a/services/frontend/src/lib/api/media.ts b/services/frontend/src/lib/api/media.ts index d172a11..94e133d 100644 --- a/services/frontend/src/lib/api/media.ts +++ b/services/frontend/src/lib/api/media.ts @@ -7,6 +7,4 @@ export const mediaApi = { api.post("/api/media/queue", { source, mode }), skip: () => api.post("/api/media/skip", {}), stop: () => api.post("/api/media/stop", {}), - volume: (volume: number) => - api.post("/api/media/volume", { volume }), }; diff --git a/services/frontend/src/lib/hooks/use-media-player.tsx b/services/frontend/src/lib/hooks/use-media-player.tsx index b0b8514..13295e7 100644 --- a/services/frontend/src/lib/hooks/use-media-player.tsx +++ b/services/frontend/src/lib/hooks/use-media-player.tsx @@ -20,8 +20,6 @@ interface MediaPlayerContextValue { current: MediaItem | null; /** Upcoming queue */ queue: MediaItem[]; - /** Current volume [0-1] */ - volume: number; /** True while a mutation is in flight */ pending: boolean; @@ -29,8 +27,6 @@ interface MediaPlayerContextValue { skip: () => void; /** Stop playback */ stop: () => void; - /** Set volume [0-1] */ - setVolume: (vol: number) => void; /** Queue a URL for playback */ queueUrl: (url: string) => void; } @@ -96,17 +92,6 @@ export function MediaPlayerProvider({ children }: { children: ReactNode }) { .finally(() => setPending(false)); }, []); - const setVolume = useCallback((vol: number) => { - mediaApi - .volume(vol) - .then((data) => { - if (data) setState(data as MediaState); - }) - .catch(() => { - // ignore - }); - }, []); - const queueUrl = useCallback((url: string) => { setPending(true); mediaApi @@ -126,11 +111,9 @@ export function MediaPlayerProvider({ children }: { children: ReactNode }) { playing: state.playing, current: state.current, queue: state.queue, - volume: state.musicVolume, pending, skip, stop, - setVolume, queueUrl, }} >