diff options
| author | nsfisis <nsfisis@gmail.com> | 2025-03-04 21:37:22 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2025-03-04 21:37:22 +0900 |
| commit | 5062cb9460915624e3f7b808c8f814ba9c31db75 (patch) | |
| tree | c6fc829aaf17092ea6c5ad2b5b0f8b73f1088a23 | |
| parent | a966efb99f9dee4850fcb1240e9d4472631a99b2 (diff) | |
| download | phperkaigi-2025-albatross-5062cb9460915624e3f7b808c8f814ba9c31db75.tar.gz phperkaigi-2025-albatross-5062cb9460915624e3f7b808c8f814ba9c31db75.tar.zst phperkaigi-2025-albatross-5062cb9460915624e3f7b808c8f814ba9c31db75.zip | |
rm audio feature
| -rw-r--r-- | backend/admin/handler.go | 22 | ||||
| -rw-r--r-- | backend/admin/templates/audio.html | 14 | ||||
| -rw-r--r-- | backend/admin/templates/dashboard.html | 3 | ||||
| -rw-r--r-- | frontend/app/.client/audio/AudioController.ts | 105 | ||||
| -rw-r--r-- | frontend/app/.client/audio/SoundEffect.ts | 47 | ||||
| -rw-r--r-- | frontend/app/components/GolfWatchAppWithAudioPlayRequest.client.tsx | 34 | ||||
| -rw-r--r-- | frontend/app/routes/golf.$gameId.watch.tsx | 4 | ||||
| -rw-r--r-- | frontend/app/states/watch.ts | 3 |
8 files changed, 2 insertions, 230 deletions
diff --git a/backend/admin/handler.go b/backend/admin/handler.go index c3e40e9..ca70639 100644 --- a/backend/admin/handler.go +++ b/backend/admin/handler.go @@ -69,7 +69,6 @@ func (h *Handler) RegisterHandlers(g *echo.Group) { g.GET("/games", h.getGames) g.GET("/games/:gameID", h.getGameEdit) g.POST("/games/:gameID", h.postGameEdit) - g.GET("/audio", h.getAudioTest) } func (h *Handler) getDashboard(c echo.Context) error { @@ -290,24 +289,3 @@ func (h *Handler) postGameEdit(c echo.Context) error { return c.Redirect(http.StatusSeeOther, basePath+"/admin/games") } - -func (h *Handler) getAudioTest(c echo.Context) error { - return c.Render(http.StatusOK, "audio", echo.Map{ - "BasePath": basePath, - "Title": "Audio Test", - "Audio": []echo.Map{ - {"FileName": "EX_33.wav", "Label": "終了"}, - {"FileName": "EX_34.wav", "Label": "勝敗1"}, - {"FileName": "EX_35.wav", "Label": "勝敗2"}, - {"FileName": "EX_36.wav", "Label": "グッド1"}, - {"FileName": "EX_37.wav", "Label": "グッド2"}, - {"FileName": "EX_38.wav", "Label": "グッド3"}, - {"FileName": "EX_39.wav", "Label": "グッド4"}, - {"FileName": "EX_40.wav", "Label": "スコア更新1"}, - {"FileName": "EX_41.wav", "Label": "スコア更新2"}, - {"FileName": "EX_42.wav", "Label": "スコア更新3"}, - {"FileName": "EX_43.wav", "Label": "コンパイルエラー1"}, - {"FileName": "EX_44.wav", "Label": "コンパイルエラー2"}, - }, - }) -} diff --git a/backend/admin/templates/audio.html b/backend/admin/templates/audio.html deleted file mode 100644 index 21ec463..0000000 --- a/backend/admin/templates/audio.html +++ /dev/null @@ -1,14 +0,0 @@ -{{ template "base.html" . }} - -{{ define "breadcrumb" }} -<a href="{{ .BasePath }}/admin/dashboard">Dashboard</a> -{{ end }} - -{{ define "content" }} - {{ range .Audio }} - <figure> - <figcaption>{{ .Label }}</figcaption> - <audio controls src="{{ $.BasePath }}/files/audio/{{ .FileName }}"></audio> - </figure> - {{ end }} -{{ end }} diff --git a/backend/admin/templates/dashboard.html b/backend/admin/templates/dashboard.html index 0f1fbaf..15b10ff 100644 --- a/backend/admin/templates/dashboard.html +++ b/backend/admin/templates/dashboard.html @@ -7,9 +7,6 @@ <p> <a href="{{ .BasePath }}/admin/games">Games</a> </p> -<p> - <a href="{{ .BasePath }}/admin/audio">Audio Test</a> -</p> <form method="post" action="{{ .BasePath }}/logout"> <button type="submit">Logout</button> </form> diff --git a/frontend/app/.client/audio/AudioController.ts b/frontend/app/.client/audio/AudioController.ts deleted file mode 100644 index 296f685..0000000 --- a/frontend/app/.client/audio/AudioController.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { SoundEffect, getFileUrl } from "./SoundEffect"; - -export class AudioController { - audioElements: Record<SoundEffect, HTMLAudioElement | null>; - - constructor() { - this.audioElements = { - finish: null, - winner_1: null, - winner_2: null, - good_1: null, - good_2: null, - good_3: null, - good_4: null, - new_score_1: null, - new_score_2: null, - new_score_3: null, - compile_error_1: null, - compile_error_2: null, - }; - } - - loadAll(): Promise<void> { - return new Promise((resolve) => { - const files = Object.keys(this.audioElements).map( - (se) => [se as SoundEffect, getFileUrl(se as SoundEffect)] as const, - ); - const totalCount = files.length; - let loadedCount = 0; - - files.forEach(([se, fileUrl]) => { - const audio = new Audio(fileUrl); - - audio.addEventListener( - "canplaythrough", - () => { - loadedCount++; - this.audioElements[se] = audio; - if (loadedCount === totalCount) { - resolve(); - } - }, - { once: true }, - ); - - audio.addEventListener("error", () => { - console.log(`Failed to load audio file: ${fileUrl}`); - // Ignore the error and continue loading other files. - }); - }); - }); - } - - async playDummySoundEffect(): Promise<void> { - const audio = this.audioElements["good_1"]; - if (!audio) { - return; - } - audio.muted = true; - audio.currentTime = 0; - await audio.play(); - audio.muted = false; - } - - async playSoundEffect(soundEffect: SoundEffect): Promise<void> { - const audio = this.audioElements[soundEffect]; - if (!audio) { - return; - } - audio.currentTime = 0; - await audio.play(); - } - - async playSoundEffectFinish(): Promise<void> { - await this.playSoundEffect("finish"); - } - - async playSoundEffectWinner(winner: 1 | 2): Promise<void> { - await this.playSoundEffect(`winner_${winner}`); - } - - async playSoundEffectGood(): Promise<void> { - const variant = Math.floor(Math.random() * 4) + 1; - if (variant !== 1 && variant !== 2 && variant !== 3 && variant !== 4) { - return; // unreachable - } - return await this.playSoundEffect(`good_${variant}`); - } - - async playSoundEffectNewScore(): Promise<void> { - const variant = Math.floor(Math.random() * 3) + 1; - if (variant !== 1 && variant !== 2 && variant !== 3) { - return; // unreachable - } - return await this.playSoundEffect(`new_score_${variant}`); - } - - async playSoundEffectCompileError(): Promise<void> { - const variant = Math.floor(Math.random() * 2) + 1; - if (variant !== 1 && variant !== 2) { - return; // unreachable - } - return await this.playSoundEffect(`compile_error_${variant}`); - } -} diff --git a/frontend/app/.client/audio/SoundEffect.ts b/frontend/app/.client/audio/SoundEffect.ts deleted file mode 100644 index 99eccdd..0000000 --- a/frontend/app/.client/audio/SoundEffect.ts +++ /dev/null @@ -1,47 +0,0 @@ -export type SoundEffect = - | "finish" - | "winner_1" - | "winner_2" - | "good_1" - | "good_2" - | "good_3" - | "good_4" - | "new_score_1" - | "new_score_2" - | "new_score_3" - | "compile_error_1" - | "compile_error_2"; - -const BASE_URL = - process.env.NODE_ENV === "development" - ? `http://localhost:8003/phperkaigi/2025/code-battle/files/audio` - : `/phperkaigi/2025/code-battle/files/audio`; - -export function getFileUrl(soundEffect: SoundEffect): string { - switch (soundEffect) { - case "finish": - return `${BASE_URL}/EX_33.wav`; - case "winner_1": - return `${BASE_URL}/EX_34.wav`; - case "winner_2": - return `${BASE_URL}/EX_35.wav`; - case "good_1": - return `${BASE_URL}/EX_36.wav`; - case "good_2": - return `${BASE_URL}/EX_37.wav`; - case "good_3": - return `${BASE_URL}/EX_38.wav`; - case "good_4": - return `${BASE_URL}/EX_39.wav`; - case "new_score_1": - return `${BASE_URL}/EX_40.wav`; - case "new_score_2": - return `${BASE_URL}/EX_41.wav`; - case "new_score_3": - return `${BASE_URL}/EX_42.wav`; - case "compile_error_1": - return `${BASE_URL}/EX_43.wav`; - case "compile_error_2": - return `${BASE_URL}/EX_44.wav`; - } -} diff --git a/frontend/app/components/GolfWatchAppWithAudioPlayRequest.client.tsx b/frontend/app/components/GolfWatchAppWithAudioPlayRequest.client.tsx deleted file mode 100644 index ce5a59c..0000000 --- a/frontend/app/components/GolfWatchAppWithAudioPlayRequest.client.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import { useAtom } from "jotai"; -import { AudioController } from "../.client/audio/AudioController"; -import { audioControllerAtom } from "../states/watch"; -import GolfWatchApp, { type Props } from "./GolfWatchApp.client"; -import SubmitButton from "./SubmitButton"; - -export default function GolfWatchAppWithAudioPlayRequest({ - game, - sockToken, -}: Omit<Props, "audioController">) { - const [audioController, setAudioController] = useAtom(audioControllerAtom); - const audioPlayPermitted = audioController !== null; - - if (audioPlayPermitted) { - return <GolfWatchApp game={game} sockToken={sockToken} />; - } else { - return ( - <div className="min-h-screen bg-gray-100 flex items-center justify-center"> - <div className="text-center"> - <SubmitButton - onClick={async () => { - const audioController = new AudioController(); - await audioController.loadAll(); - await audioController.playDummySoundEffect(); - setAudioController(audioController); - }} - > - 開始 - </SubmitButton> - </div> - </div> - ); - } -} diff --git a/frontend/app/routes/golf.$gameId.watch.tsx b/frontend/app/routes/golf.$gameId.watch.tsx index f04f6b0..cdfc908 100644 --- a/frontend/app/routes/golf.$gameId.watch.tsx +++ b/frontend/app/routes/golf.$gameId.watch.tsx @@ -3,7 +3,7 @@ import { ClientLoaderFunctionArgs, useLoaderData } from "@remix-run/react"; import { useHydrateAtoms } from "jotai/utils"; import { apiGetGame, apiGetToken } from "../.server/api/client"; import { ensureUserLoggedIn } from "../.server/auth"; -import GolfWatchAppWithAudioPlayRequest from "../components/GolfWatchAppWithAudioPlayRequest.client"; +import GolfWatchApp from "../components/GolfWatchApp.client"; import GolfWatchAppConnecting from "../components/GolfWatchApps/GolfWatchAppConnecting"; import { codeAAtom, @@ -183,5 +183,5 @@ export default function GolfWatch() { [submitResultBAtom, playerStateB.submitResult], ]); - return <GolfWatchAppWithAudioPlayRequest game={game} sockToken={sockToken} />; + return <GolfWatchApp game={game} sockToken={sockToken} />; } diff --git a/frontend/app/states/watch.ts b/frontend/app/states/watch.ts index 5f5c4db..cb719eb 100644 --- a/frontend/app/states/watch.ts +++ b/frontend/app/states/watch.ts @@ -1,5 +1,4 @@ import { atom } from "jotai"; -import { AudioController } from "../.client/audio/AudioController"; import type { components } from "../.server/api/schema"; import type { SubmitResult } from "../types/SubmitResult"; @@ -251,5 +250,3 @@ export const handleWsSubmitResultMessageAtom = atom( callback(player_id, newResult, score); }, ); - -export const audioControllerAtom = atom<AudioController | null>(null); |
