Lofi Radio

  • Challenge :

    Design an interface for listening to lofi music from ChillHops across three pages, enabling effortless playback control.

  • My Role :

    Frontend Developer, Designer

  • Tools Used :

    Next.js, TypeScript, CSS, Embla


Project Architecture:

  1. 1.) To improve user experience, I designed a main page displaying essential data: Player Controls, a top album slider, a list of top songs, and the top 6 albums. This setup facilitates seamless navigation and song control.

  2. 2.) For efficient tracking of user-selected data and page navigation, I utilized the useContext hook in React. This choice simplified global state management, making it easier to show selected albums and songs, and switch between pages without page refreshes.


Playing songs with audio controls

The primary function of this app is to enable users to listen to songs. Here, I'll explain how I established this functionality and connected the controls to the audio and volume. To ensure users can control the audio from any page within the app, I've utilized global state. This state keeps track of an audio control component, facilitating control of the audio player. Key values maintained include the selected song, song duration, current timestamp, and play/pause status.

  • Play and Pause:

    When a user selects a song by clicking on it, the selectedSong state is updated. Subsequently, a function is triggered to attach a reference to the audio DOM element using the useRef hook. This grants access to vital information such as the playback status and current timestamp.

  • Next Song and Previous Song:

    After selecting a song, we execute a function called findAlbumThatHoldsSelectedSong. This function searches through the albums to find the one containing the selected song. This simplifies navigation, particularly when users want to move to the next or previous song within the same album.

  • Fastforward and Rewind:

    The timestamp slider allows users to navigate through a song's duration with precision. Leveraging the HTML range input type, we utilize the useRef hook to access the audio player's DOM element, storing it as audioRef. This direct access enables manipulation of the audio's properties and methods. The dragHandler function is invoked whenever the slider's value changes. It synchronizes the audio playback with the slider's position by updating the currentTime property of the audio element. Additionally, we update the global state (songInfo) to ensure consistency between the UI and the application's state.