Personal Information
Name: Jasjeet Singh
IRC nick: jasje
Email: 07jasjeet@gmail.com
Github: 07jasjeet
Time Zone: UTC+05:30
Feed Section in ListenBrainz Android App
Project Overview
Currently, ListenBrainz Android app consists of various features like BrainzPlayer, Listens Service, Listens history, YIM and many more which already make the app very interesting.
ListenBrainz website is an amazing platform that inculcates an idea which I believed in past but had no power to do so, i.e., having a social media app that revolves around music. Feed section is one of the core functionalities of this idea and the Android app lacks it. This feature has the potential to attract more users than ever because social media is something people access frequently and a mobile device is the best place to have it.
This project aims to integrate the Feed Section into the Android app.
My contributions up till now:
My Pull Requests: Check Out
My Commits: Check Out
Implementation
Going with the flow that ListenBrainz Android Docs mentions, this project will be implemented through the following stages:
-
Planning
These are the following additions according to the ideas page.
-
Feed section is a replacement for home page (tentative), hence a lot of the burden comes to optimising this page to induce smooth startup experience.
-
The feed should showcase all ListenBrainz social events like whenever a user’s follower listens to a track, recommends a track in general or to them personally, follows another user or a user follows them, pins a track, reviews an album, reviews a track, or ListenBrainz has new announcements. ListenBrainz server has appropriate APIs for these tasks which will be mentioned in Knowing the APIs section.
-
Spotify remote player must be used in order to play songs on demand when the user clicks on an event that consists of a recording.
-
Follow/Following functionality is required is to bundled with appropriate methods to allow user to search for another user.
-
Test first approach will be followed for unit tests and proper testing architecture will be followed throughout. Instrumented tests will be implemented once the project has a screen flow.
-
-
Designing
Designing process will be done under the watch of MetaBrainz team’s in-house designer and my mentor. Being accustomed to how things work in the organisation, it will be a smooth process. All designs will be created on Figma with frequent reviews from mentors.
These are some quick mockups of what feed might look like:
-
Knowing the APIs
The following API endpoints will be responsible for the functionality of this feature:
-
GET /1/user/(user_name)/feed/events?count=20&max_ts=<max_ts>
: This API endpoint is responsible to provide information for all feed events.count
andmax_ts
will be used to get events in batches of 20. LB Token required. -
POST /1/user/(user_name)/timeline-event/create/recommend-personal
: This API endpoint will let the user to personally recommend a recording to their some of their followers. LB Token required. -
POST /1/user/(user_name)/timeline-event/create/recording
: This API endpoint will let the user to recommend a recording to all their followers without any message or blurb content. LB Token required. -
POST /1/user/(user_name)/timeline-event/create/review
: This API endpoint will let the user post a CritiqueBrainz Review to the feed. The user must link their CritiqueBrainz account with ListenBrainz for this functionality to work. Error will be thrown if they haven’t. LB Token required. -
GET /1/user/(user_name)/services
: This API endpoint will allow us to verify if the user has linked CritiqueBrainz account with ListenBrainz or not. LB Token required. -
POST /1/user/(user_name)/feed/events/delete
: This API endpoint will allow the user to delete an event that belongs to themselves. This endpoint supports deletion of recommendation and notification, so delete option will be limited to those only. User will also be given an appropriate window to cancel this action in order to avoid accidents. LB Token required. -
POST /1/user/(user_name)/feed/events/hide
: This API endpoint allows user to hiderecording_recommendation
andrecording_pin
events of users they are following. Appropriate time interval to undo hide action will be given to avoid accidents and an extra call to unhide. LB Token required. -
POST /1/user/(user_name)/feed/events/unhide
: This API endpoint will allow the user to unhide a previously hidden event. LB Token required. -
POST /1/pin
: This API endpoint is used to pin a recording. LB Token required. -
POST /1/user/(user_name)/follow
: This API endpoint will let user follow another ListenBrainz user. LB Token required. -
POST /1/user/(user_name)/unfollow
: This API endpoint will let user unfollow another ListenBrainz user (which they are following). LB Token required. -
GET /1/user/(user_name)/followers
: This API endpoint will fetch the list of followers of the user. -
GET /1/user/(user_name)/following
: This API endpoint will fetch the list of users followed by the user. -
GET /1/user/(user_name)/similar-users
: This API endpoint returns an array of dictionaries which contain a “similar” user. This endpoint will be used to recommend the user, other users on ListenBrainz that have same taste as the user itself. -
GET /1/search/users?search_term=<user_name>
: This API endpoint returns list of users that closely resemble input username. This endpoint will be used to search ListenBrainz users through their username. Debouncing will be implemented.
Most these API endpoints require Authorization headers which must include LB access token.
-
-
Coding
Step by step process of how coding part will go:
-
API calls setup for User Search page with tests.
-
View-model setup for User Search page. This will consist of
SearchViewModel
which will contain all code related to follow/unfollow interactions and User Search methods. -
User Search page UI implementation and performance testing. This page will probably be merged via tabination (Use of Tabs) with Feed but is kept tentative as of writing this proposal. This requires a brief discussion with mentors such that the app design is in line with the website. Mockup of components to be used in user page (tentative):
-
API calls setup for Feed page with tests.
-
View-model setup for Feed page consisting of two view-models namely:
FeedViewModel
(will only consist of strictly feed related business logic and follow/unfollow logic) andSocialViewModel
(will consist all the reusable drop down calls such as recommend, personally recommend, write a review and more).For
FeedViewModel
we may need some helper functions and variables all packed up as a seald class as follows:sealed class FeedEvent ( val type: String, /* @DrawableRes val icon: Int, val isPlayable: Boolean */ ) { object RECORDING_RECOMMENDATION : FeedEvent("recording_recommendation"){ // Function to get composable with appropriate params. @Composable fun Content(/*params*/) { // Content } // Other helper functions } object PERSONAL_RECORDING_RECOMMENDATION : FeedEvent("personal_recording_recommendation") object RECORDING_PIN : FeedEvent("recording_pin") object LIKE : FeedEvent("like") object LISTEN : FeedEvent("listen") object FOLLOW : FeedEvent("follow") object NOTIFICATION : FeedEvent("notification") object REVIEW : FeedEvent("critiquebrainz_review") object UNKNOWN : FeedEvent("update_app") // In case a new event is added in future that had not been published to the app. }
-
Spotify App Remote SDK is currently used in
ListensViewModel
. Since the App Remote is very dependent on context, testing scope is hampered. To tackle this, Spotify App Remote SDK will be converted into a repository (which is easier to mock) and a mock will be established.ListensViewModel
will be refactored for the same. -
Creating Compose UI for the feed page.
Workflow:-
Implement Basic cards and list item for showcasing various events. Example:
-
Integrate Spotify App Remote.
-
Create drop-down menu for feed cards.
-
Implement each mini-feature which consists of the following:
- Implement drop down that mutates according to the feed event.
- Implement all the required reusable components for the functionalities inside the drop down.
This includes:
-
SnackBar
implementation to accommodate Undo for accidental events. -
Delete an event from feed functionality. Only recommendations and notifications can be deleted. Example Body of the post request:
{ "event_type": "<recording_recommendation or notification or recording_pin>", "id": "<integer ID of the event>" }
-
Hidden Card component when a user hides or unhides an event.
Example Body for post request to hide an event:{ "event_type": "<recording_recommendation or recording_pin>", # Can only hide pins/recommendations of followed users from our feed. "event_id": "<integer id of the event>" }
Example Body for post request to unhide an event:
{ "event_type": "recording_pin", # Can only unhide pins/recommendations of followed users from our feed. "event_id": "<integer id of the event>" }
-
Personally Recommend feature requires a dialog that contains a search box where users can search and select through their followers to whom they want to recommend the recording. Draft saving (Point 5) will be implemented for Personally Recommend. Both recommend to followers and personally recommend to followers share the same data class as follows:
{ "metadata": { "artist_name": "<The name of the artist, required>", "track_name": "<The name of the track, required>", "recording_msid": "<The MessyBrainz ID of the recording, required>", "release_name": "<The name of the release, optional>", "recording_mbid": "<The MusicBrainz ID of the recording, optional>", "users": [<usernames of the persons you want to recommend to, required>] # Only required in Personal recommendation. "blurb_content": "<String containing personalized recommendation>" # Only required in Personal recommendation. } }
-
Write a CritiqueBrainz Review feature requires another dialog that allows user to input text which is then sent as a review. For this task,
POST /1/user/(user_name)/timeline-event/create/review
endpoint will be used. Example body data:{ "metadata": { "entity_name": "Shakira", "entity_id": "bf24ca37-25f4-4e34-9aec-460b94364cfc", "entity_type": "artist", "text": "TEXT", # Text should be minimum 25 characters, error should be thrown if not. "language": "en", "rating": 4, # Rating should lie between 1..5 }, }
Since CritiqueBrainz should be linked to ListenBrainz account for this to work, login check will be performed first. If the user is not logged in, they will be redirected to this page in order to link their account to ListenBrainz.
Also, draft saving will be implemented for reviews. When a user leaves a review in-between to check some things, user may lose progress accidentally. To prevent this, reviews will be cached and a new caching system will be implemented. Proper time-out system will be implemented to clear cache after some specified time interval. Tests included.
-
Pin recordings directly from feed. Example Body of the post request:
{ "recording_msid": "<required>", "recording_mbid": "<this field is optional>", "blurb_content": "TEXT", "pinned_until": 1824001816 }
These are all the features included in this package. Given that
Inspect Listen
andLink with MusicBrainz
ultimately lead to the website, those features will be kept tentative. -
Performance test the feed composable.
-
-
Implementing instrumented tests for both features.
Manual testing will be part of this project throughout thus encouraging TDD (Test driven development).
-
Timeline
Following is an overview of how I will be spending my time during the duration of GSOC:
Pre-Community Bonding Period (4 April - 3 May):
Work on restructuring and write tests for the app. Discuss the UI for the feed with my mentors. Work on the UI ideas.
Community Bonding Period (3 May - 29 May):
Start Phase 1 early if no work persists. Since my college exams are scheduled in this period, work will be affected.
Phase 1 : User Search Page
Week 1 (29 May - 5 June)
-
Setting up API calls to the following required endpoints with their respective Unit tests:
POST /1/user/(user_name)/follow
POST /1/user/(user_name)/unfollow
GET /1/user/(user_name)/followers
GET /1/user/(user_name)/following
GET /1/user/(user_name)/similar-users
GET /1/search/users?search_term=<user_name>
-
Setting up dependency injection.
Week 2-3 (5 June - 19 June)
-
Implementing Search Page user interface. This includes the following:
- Search Bar with debouncing technique to limit API calls.
- Follow/Following list.
- Similar users list.
- Tabination (Use of Tabs) to inculcate this page with feed page. Both, Feed and Search-User pages will share the same bottom navigation icon and have tabs to navigate internally.
-
Performance test the screen.
Phase 2 : Feed page
Week 4 (19 June - 26 June)
-
Setting up API calls to the following required endpoints with their respective Unit tests:
-
All endpoints except “
GET /1/search/users?search_term=<user_name>
” will be used in feed. -
Since 6 of the all the calls would be setup already, rest 7 would be implemented. These following endpoints require heavy work, so, 1.5 to 2 weeks are required.
GET /1/user/(user_name)/feed/events?count=20&max_ts=<max_ts>
POST /1/user/(user_name)/timeline-event/create/recommend-personal
POST /1/user/(user_name)/timeline-event/create/recording
POST /1/user/(user_name)/timeline-event/create/review
POST /1/user/(user_name)/feed/events/delete
POST /1/user/(user_name)/feed/events/hide
POST /1/user/(user_name)/feed/events/unhide
GET /1/user/(user_name)/services
-
-
Setting up dependency injection.
Week 5-6 (26 June - 10 July)
- Finish up remaining Unit tests, if any.
- Setting up required view-model (with tests) and integrate connectivity observer.
- Creating repository for Spotify App Remote, adding it to dependency tree and injecting it into view-model’s various cases where recordings are found.
Week 7-9 (10 July - 31 July)
- Begin UI implementation.
Please checkout point 4 of Coding part in implementation section for more clarity on the exact chronological order of implementation of each functionality. - Connect all UI components to prepare a beta product.
Week 10 (31 July - 7 August)
- Compose UI is prone to performance issues (or recompositions to be exact) if not implemented correctly, hence improve code quality overall.
- UI has to be tested for each screen aspect-ratio as the app supports Android phones with a minimum of Android 5.0 (Lollipop).
- Test all the services and linked components for error/edge cases.
- Start implementing Instrumented Tests for the feature if the project seems stable.
Week 11 (7 August - 14 August)
- Implement Instrumented Tests for the feature. This includes tests for both Search page and Feed page.
Week 12 (14 August - 21 August)
- Finish up pending work, if any.
- Start writing documentation for the project.
- Discuss with mentors about any final changes.
Stretch goals
- Integrate BrainzPlayer with Remote Players such that users are able to control media playback from mini-player and only from notification of original service by removing notification of BrainzPlayer when remote players are active. Removing notification helps in keeping notification bar clean from unnecessary notifications in Android 10 and below.
Detailed Information About Yourself
My name is Jasjeet Singh, currently residing in Chandigarh. I am a sophomore pursuing Bachelors in IT from University Institute of Engineering and Technology, Panjab University, Chandigarh, India. I had not known much about coding until I came to college. Started with C in my 1st semester. Didn’t last long due to distractions and slight obsession with games (CS; and yes 1v1 accepted ). Soon after, I realized this habit won’t help me in the long run. I had to pick any development to make “things” or projects as we call them. I’ve always had a thing for Android, so I picked it!
Tell us about the computer(s) you have available for working on your SoC project!
I have my Lenovo Legion 5 Pro, with Ryzen 7 5800H, RTX 3060 and 16 GB of RAM.
When did you first start programming?
I stepped into the coding world with C as my first programming language last year.
What type of music do you listen to? (Please list a series of MBIDs as examples.)
I mostly listen to Punjabi music artists like Arjan Dhillon, Karan Aujla, Sidhu Moose Wala or Tame Impala for some change.
I’ve also added one recording and artist to MusicBrainz database respectively:
Some MBIDs of my favorite recodings :
5279bc04-6b83-4897-814d-4f604fedd79c (The one I added to MusicBrainz)
5ecd8c60-c756-4532-8207-c45886df2feb
f078699c-9b68-4040-9ba4-b1e4f7d86598
31eeb9db-cff0-40ab-bc5a-5474a432519c
What aspects of the project you’re applying for the interest you the most?
I love Android Development and listening to music, so there’s no better project than ListenBrainz that keeps me engaged and happy. I’ve been working on ListenBrainz Android for some months now and honestly, I really have passion about moving the app further, exploring its scope and making it better continuously.
Have you contributed to other Open Source projects? If so, which projects and can we see some of your code?
ListenBrainz is my first point of contact with open source and feels really good to be this way.
What sorts of programming projects have you done on your own time?
I mostly play with Android Development, hence most of my projects are Android projects like Drawing App and Quiz App. I also have some C projects (here) and some flask projects (which I’m currently learning btw) but they are pretty teensy and under active development.
How much time do you have available, and how would you plan to use it?
I will be providing 40 to 45 hours per week to the project. There may be slight ups and downs due to college exams and other activities.