Skip to content

Musify is a clone of the popular Spotify app with some tweaks. It is built completely using Jetpack compose. It uses the Spotify API to fetch the data.

Notifications You must be signed in to change notification settings

snehaawate/Musify

Repository files navigation

Musify

Project Status: Active – The project has reached a stable, usable state and is being actively developed.

Musify is a clone of the popular Spotify app built completely using Jetpack compose. Both podcasts episodes and tracks are available for playback. Under the hood, it uses the Spotify API to fetch the data. It is completely built using Jetpack compose. It is also worth noting that it is not a complete one-on-one clone of the app. It can be considered as an app that is heavily inspired by the design of the official Spotify app with some custom design tweaks. It uses many API’s such as Hilt,Retrofit, and Paging 3. I built this project purely for educational purposes. I neither intend to release, nor do I plan on monetizing any part of this project.

Table of contents

  1. Demo
  2. Screenshots
  3. Tech Stack
  4. Notable features
  5. Source code, Architecture, & Testing
  6. Building and running the app

Demo

musify-demo-emulator.mp4

Screenshots

   

Podcasts

   

Tech Stack

Notable features

Global Playback state ▶️
The currently playing track gets highlighted in any screen that contains the currently playing track. This is achieved by maintaining a global playback state. Once the currently playing state changes, it will be notified to all the screens.
Dynamic theme 🎨
This app uses Google’s Palette API to fetch the background color of the screens based on an image. For example, the album art associated with the first search result determines the background gradient color of the search screen.
Specific error messages ⚠️
When there is an error, the app will try to be as specific as possible. For example, if no tracks are found for a particular search query, then it’ll be specific and state that no “tracks” where found instead of displaying a generic “no results found” message. This applies for the rest of the app as well. In certain cases, it even provides a retry button.
Insets ⌨️
The app uses insets to ensure that the content of the screen doesn't get overlaid by system views. It even accomondates the UI for the IME (on screen keyboard). For example, in the search screen, the loading animation will be moved up when the on screen keyboard appears.
Time & Locale based in-app content 🕐
The content displayed in the home screen is based on the current time and locale associated with the user's device. This is made possible because the Spotify API allows the specification of timestamp and locale as query parameters.
Backstack management 🗂
The app ensures that the backstack is properly managed. By poping upto, but not including the Home Screen everytime the user navigates to a bottom naivgation destination, the number of destinations in the backstack gets reduced. This imporves the overall UX of the app.
Attention to tiny details 🔍
The app was built with an attention to even the tiniest of details. These features might seem trivial, but it affects the UX negatively if they are not present. The app tries to mimic such functionality even though they might get unnoticed in order to immitate the features that the app would need, if it were to be officially released. The following are some of the many UX improving features that the app has.
  • The clear button of the search bar in the search screen will only appear if there is text within it. It also uses a subtle animation while entering/exiting.
  • If the user is inside a nested navigation destination associated with a bottom navigation destination, and taps on the bottom navigation icon, the backstack would be popped.
  • Plural strings are used to display gramatically correct text. This can be specifically seen in the metadata of podcast episodes where the date and duration strings are formatted in a gramatically corrected manner. For example, an episode that has a duration of 1 hour is displayed as '1 hr', whereas an episode that has a duration of 2 or more hours, is displayed with 'hrs' as a suffix.
HTML styled text🖌
The app leverages compose-view interop to display html styled text. It's mainly used in the descriptions of the podcast show/episode detail screens. This means, these textfields can display text in different styles, such as italics and bold. Moreover, since the text is html styled, it can even display text in other forms such as lists. The URLs in the descriptions are even clickable, allowing the user to navigate to a linked website.
Additional features 🎄
As of writing this, the IOS version of the official Spotify app uses a dynamic background color in the search screen. The Android version of the app doesn't have that feature. The Musify app mimics that feature by using a dynamic background color for the search screen.

Source code, Architecture, & Testing

  • All concrete implementations are prefixed by the term "Musify".
  • Uses multi-repository pattern.
  • MVVM archtecture.
  • Commit messages follow the Conventional Commits specification.
  • Consists of extensive unit tests with a predominant focus on testing the data layer.
  • An illustration depicting the setup of the navigation graph can be found here.

Building and running the app

  1. Create a Spotify account and log into the Spotify Developer Dashboard.
  2. Create an app from the dashboard and get the Client ID and Client Secret.
  3. Add the two fields to the local.properties file of your project in the following manner.
SPOTIFY_CLIENT_ID = PASTE-YOUR-CLIENT-ID-HERE
SPOTIFY_CLIENT_SECRET = PASTE-YOUR-CLIENT-SECRET-HERE
  1. Build the app in release mode and run it.

Note

You might experience performance issues if you do not build the app in release mode. Please make sure to build the app in release mode. For more info on why this is important, especially in an app built completely with jetpack compose, read this blog post.

About

Musify is a clone of the popular Spotify app with some tweaks. It is built completely using Jetpack compose. It uses the Spotify API to fetch the data.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages