Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions app/components/AudioProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
"use client";
import React, {
createContext,
useContext,
useEffect,
useState,
useRef,
} from "react";


interface AudioContextType {
musicVolume: number;
setMusicVolume: (value: number) => void;
sfxVolume: number;
setSfxVolume: (value: number) => void;
playBackgroundAudio: () => void;
pauseBackgroundAudio: () => void;
playAudioEffect: (src: string) => void;
playingBackgroundAudio: boolean;
}

const AudioContext = createContext<AudioContextType | undefined>(undefined);

export const useAudioCustom = () => {
const context = useContext(AudioContext);
if (!context) {
throw new Error("useAudio must be used within a AudioProvider");
}
return context;
};

export const AudioProvider: React.FC<{ children: React.ReactNode }> = ({
children,
}) => {
const [musicVolume, setMusicVolume] = useState(0.3); // music volume 30%
const [sfxVolume, setSfxVolume] = useState(1.0); // audio effect volume 100%
const backgroundAudioRef = useRef<HTMLAudioElement | null>(null);

const [playingBackgroundAudio, setplayingBackgroundAudio] = useState(false);

useEffect(() => {
backgroundAudioRef.current = new Audio("./assets/music/bg.mp3");
backgroundAudioRef.current.loop = true;
backgroundAudioRef.current.volume = musicVolume;
}, []);

useEffect(() => {
if (backgroundAudioRef.current) {
backgroundAudioRef.current.volume = musicVolume;
}
}, [musicVolume]);

const playBackgroundAudio = () => {
setplayingBackgroundAudio(true);
backgroundAudioRef.current
?.play()
.catch((error) =>
console.error("Error playing background music:", error)
);
};

const pauseBackgroundAudio = () => {
setplayingBackgroundAudio(false);
backgroundAudioRef.current?.pause();
};

const playAudioEffect = (src: string) => {
const audioEffect = new Audio(src);
audioEffect.volume = sfxVolume;
audioEffect.play();
};

return (
<AudioContext.Provider
value={{
musicVolume,
setMusicVolume,
sfxVolume,
setSfxVolume,
playBackgroundAudio,
pauseBackgroundAudio,
playAudioEffect,
playingBackgroundAudio,
}}
>
{children}
</AudioContext.Provider>
);
};
42 changes: 42 additions & 0 deletions app/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
"use client";
import { useAudioCustom } from "./AudioProvider";
import UNMUTE from "@/public/assets/images/unmute.png";
import MUTED from "@/public/assets/images/muted.png";
import Image from "next/image";
import { WalletConnectorModal } from "./WalletConnector";

export default function Header() {
const { playBackgroundAudio, pauseBackgroundAudio, playingBackgroundAudio } =
useAudioCustom();
return (
<>
<div className="absolute top-4 right-4 sm:top-8 sm:right-8 flex items-center gap-4">
<div className="h-[40px] sm:h-[62px] w-[50px] sm:w-[72px] bg-[#222C38] transform -skew-x-12 flex justify-center items-center">
{!playingBackgroundAudio && (
<button
type="button"
onClick={() => {
playBackgroundAudio();
}}
className="cursor-pointer"
>
<Image src={MUTED} alt="paused" width={48} height={48} />
</button>
)}
{playingBackgroundAudio && (
<button
type="button"
onClick={() => {
pauseBackgroundAudio();
}}
className="cursor-pointer"
>
<Image src={UNMUTE} alt="playing" width={48} height={48} />
</button>
)}
</div>
<WalletConnectorModal />
</div>
</>
);
}
7 changes: 6 additions & 1 deletion app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Metadata } from "next";
import { AudioProvider } from "./components/AudioProvider";
import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css";
import StarknetProvider from "./components/starknet-provider";
Expand All @@ -18,6 +19,8 @@ export const metadata: Metadata = {
description: "Generated by create next app",
};

// const { isPlaying, volume, togglePlay, setVolume } = useAudio()

export default function RootLayout({
children,
}: Readonly<{
Expand All @@ -28,7 +31,9 @@ export default function RootLayout({
<body
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
>
<StarknetProvider>{children}</StarknetProvider>
<StarknetProvider>
<AudioProvider>{children}</AudioProvider>
</StarknetProvider>
</body>
</html>
);
Expand Down
12 changes: 4 additions & 8 deletions app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
"use client";

import Image from "next/image";
import Link from "next/link";
import { WalletConnectorModal } from "./components/WalletConnector";
import Header from "./components/Header";

// import WalletConnectButton from './components/WalletConnectButton';

export default function Home() {
return (
<div className="grid grid-rows-[20px_1fr_20px] items-center justify-items-center min-h-screen p-8 pb-20 gap-16 sm:p-20 font-[family-name:var(--font-geist-sans)] bg-[url('/background.svg')] bg-no-repeat bg-cover">
<div className="absolute top-4 right-4 sm:top-8 sm:right-8 flex items-center gap-4">
<div className="h-[40px] sm:h-[62px] w-[50px] sm:w-[72px] bg-[#222C38] transform -skew-x-12"></div>
<WalletConnectorModal />
</div>

<Header />
<main className="flex flex-col gap-4 row-start-2 items-center w-full mt-12 sm:mt-20">
<div className="flex flex-col gap-4 w-full items-center sm:items-start sm:ml-8">
<Image
Expand Down
11 changes: 2 additions & 9 deletions app/profile/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Bowlby_One_SC } from "next/font/google";

import Header from "../components/Header";
const bowlby = Bowlby_One_SC({
weight: "400",
subsets: ["latin"],
Expand All @@ -11,14 +11,7 @@ export default function Profile() {
<div
className={`${bowlby.variable} flex flex-col items-center justify-center min-h-screen p-8 pb-20 sm:p-20 bg-[url('/background.svg')] bg-no-repeat bg-cover`}
>
<div className="absolute top-4 right-4 sm:top-8 sm:right-8 flex items-center gap-4">
<button className="relative bg-[#222C38] transform -skew-x-12 px-4 sm:px-8 h-[40px] sm:h-[62px]">
<span className="text-[#F3F5FF] text-sm sm:text-base font-bold transform skew-x-12">
CONNECT WALLET
</span>
</button>
</div>

<Header />
<main className="w-full max-w-4xl flex flex-col mx-auto">
<h1 className="text-[32px] font-bold self-start ml-6">PROFILE</h1>

Expand Down
Loading
Loading