# data[].attributes.body
Finish The Mobile Responsive Design on the 30-05-2021
Technically, Muserfly heavily depends on Spotify to upgrade their web playback SDK to make it work properly on most mobile devices

# data[].attributes.body
## Extended Features for Muserfly

### Mobile Responsive Design

This will be developed for mobile users

### The Emotion Map: Zoom Feature

This will be developed for mobile users

### The Emotion Map: Panning Feature

This will be developed for mobile users

### Song Mapping on Locations: AR.js

Locations strongly correlate to memories. And Memories bring back Emotions. What if you can use mixed reality technology to allow users to "plant" their playlist on a location and whenever they visit that physical location, they can see and play the playlist they listened to in the past?

This will open up possibilities to create a music app where people will be able to listen to a playlist as they physically and virtually walk passed it, regardless of their "planted playlist" or someone else's

# data[].attributes.headline
JSON Objects for Database Storage Completed

# data[].attributes.subject
JSON Objects for Database Storage Completed

# data[].attributes.body
The JSON design is based on the design schema

# data[].attributes.headline
Re-configure The Connection to MongoDB Everytime a Data is Sent to The Backend

# data[].attributes.subject
Re-configure The Connection to MongoDB Everytime a Data is Sent to The Backend

# data[].attributes.body
One downside for categorising different database collection like this is that the connection to MongoDB configuration has to be re-invoked over again depending on which collection is needed for a particular data schema (0: User Settings, 1: User Journey)

# data[].attributes.body
There are 2 JSON objects which will be stored in MongoDB Database

User Settings: When a user tries to change their personalisation settings
User Journey: When the song collection process finishes

# data[].attributes.headline
Google Tag Manager - Triggers to Track Events

# data[].attributes.subject
Google Tag Manager - Triggers to Track Events

# data[].attributes.body
Show a map of the app's influence

# data[].attributes.body
This piece of code snippet needs including to the deployed app to track any event happens on it

# data[].attributes.body
Still struggled to understand how the events were counted. As I was playing around with scrolling and clicking, but the number wasn't live updating.
My suspicion was that the site needed closing before the data of events was loaded

# data[].attributes.headline
Google Tag Manager Assistant Web Extension for Development Purposes

# data[].attributes.subject
Google Tag Manager Assistant Web Extension for Development Purposes

# data[].attributes.headline
Google Analytics Prepared for User Testing

# data[].attributes.subject
Google Analytics Prepared for User Testing

# data[].attributes.body
I added google analytics to my deployed site in order to track user experience / engagement to it

This tool is very useful when tracking web traffic, monetisation,... But in terms of tracking user's behaviour and engagement, it might still not be able to do its best, particularly when it comes to clicking and scrolling counts. However, more research needs to be done before coming to a conclusion

[1st conclusion]

The scrolling tracking feature can only detect user's scrolling relatively to the ENTIRE PAGE, but my app has different scrollable sections...

# data[].attributes.headline
Handle Cases of Searched Keywords with Accents / Diacritics

# data[].attributes.subject
Handle Cases of Searched Keywords with Accents / Diacritics

# data[].attributes.body
In Vietnamese language, there are 4 types of diacritics / accents that can change meaning of a word completely. Knowing this helps me a lot with putting in more thorough considerations on the search process. With words that contain the accents such as è, é, ẻ,....It is difficult to get back correct result from Spotify, or sometimes, it doesn't even return anything. Thanks to this answer from Stackoverflow [1], I was able to understand how using normalize function with vanilla javascript in combination with regex can remove such deformation in a language and convert a word into a much globally readable language.

[1] https://stackoverflow.com/questions/990904/remove-accents-diacritics-in-a-string-in-javascript

# data[].attributes.headline
Recommendation Search Based on Manual Search Via User Typing

# data[].attributes.subject
Recommendation Search Based on Manual Search Via User Typing

# data[].attributes.body
Again, this endpoint is great because not only did it return contemporary tracks and artists in a same era, it also tried to find closely matched affective values of songs.

I searched a rapper named Eminem, and it responded back with Linkin Park, Gym Class Heroes,...

On one hand, this new endpoint for related search is very positive to my app, both in terms of reducing the loading time and the randomness of searched keywords, instead adds in a much more logical search algorithm. On the other hand, the visualisation will not look as fluid and varied like it was before

# data[].attributes.headline
Recommendation Search Based on User's Playlists

# data[].attributes.subject
Recommendation Search Based on User's Playlists

# data[].attributes.body
Red Dots on The Map Represents Songs In User's Playlists

I chose a song by Michael Jackson from my own playlist, and Spotify API recommended songs and artists came from the contemporary generation: Whitney Houston, Corinne Bailey Rae,...

# data[].attributes.body
Spotify API just released a bunch of new endpoints, particularly regarding recommendations and personalisations: (Link to Recommendation endpoint)

This added feature to its endpoints really helped the search time of my system go by MUCH MUCH MUCH FASTER.
But in order to create some dynamism to the search process, I kept the feature of random search at the beginning of the search process, and then followed by a loop of recommendation search based on the very first result.

One thing is that now, as the endpoint allows search for maximum and minimum mood values (valence & arousal). This is a very good thing, but the results are much more close to each other regarding affective scores, which leads to a clustered visualisation of the song dots on The Map

# data[].attributes.body
1. Finished Draggable Song Tracks and Adding Them to A Playlist

2. Added Visualisation of User-Added Songs on The Emotion Map with A Different Colour

3. Added User Settings to The Database

4. Reduced The Number of Stars on The Emotion Map (for computational performance purposes)

# data[].attributes.headline
WhiteListing IP Address For Access to MongoDB Database

# data[].attributes.subject
WhiteListing IP Address For Access to MongoDB Database

# data[].attributes.body
Okay! It's the database accessibility now.

MongoDB is really strict with its user's security. Therefore, whitelisting IP address to access the database is also a requirement. Using it for local development is no problem, because it automatically detects a user's IP address via their account. But to deploy it on Heroku and use it in production, a developer needs to know Heroku's IP address......Hmmmmm

There are a couple of ways, according to some of the research:

1. Use an add-on for "Static IP addresses for database requests and other TCP connections" [1] such as Fixie Socks. We can think of this as a proxying tool for IP address

2. Find any available region where my Heroku app is, then find IP address ranges in that region and whitelist them in MongoDB Atlas Network Access (IP Address for every region around the globe)

3. A quick and dirty way: Set one whitelisted IP address to 0.0.0.0/0, which means global access is allowed. Now everyone around the world can access my database basically, which is not a very wise option professionally

However, I will choose the third option for now, because I really need to focus on the development of my app and constantly test its functionality in production.
If that sounds like an excuse, which it is, then according to a quick research:
The 1st option can only provide developers 100 requests/month to its static IP address, which is okay, but I'll have to install a plugin on Heroku, and that's annoying

The 2nd option is the best so far in my opinion. However, the IP address ranges "are subject to change over time" [2]

[1] https://stackoverflow.com/questions/42159175/connecting-heroku-app-to-atlas-mongodb-cloud-service
[2] https://developer.mongodb.com/how-to/use-atlas-on-heroku

# data[].attributes.headline
When Instantiating Monk, ASYN/AWAIT is VERY REDUNDANT

# data[].attributes.subject
When Instantiating Monk, ASYN/AWAIT is VERY REDUNDANT

# data[].attributes.body
When there is a chain of endpoint calls and one of them has implementation of ASYNCHRONOUS FUNCTION. Fetch API won't wait for this for too long and end up skipping waiting if it takes too much of the time. Therefore, this leads to invalid returned values.

I was running into this trouble when I updated my deployed app to Heroku. If it hadn't been thanks to the deploying process, I would've thought my app would be fine in production.

It was my fault from the start when trying to instantiate the Monk package for MongoDB Atlas connection in ASYNC FUNCTION. This caused a delay in the data fetching process and the fetch API decided to skip the waiting and get hung in the middle of the process without a response (no error, no succeed message).

It took me pretty much a day or two to trace back every little step of the code flow in order to detect the code hang basically because no responses were returned.
Sometimes, error is just a beautiful thing. Please appreciate it !!!

# data[].attributes.body
maybe .then() function cannot return a value?
So when I used try and catch, the data is valid because it can perform a value return? Interesting...

Maybe if I had created a global variable and reassigned it to a data inside .then() function, and returned that global variable outside of the .then() block, that...could've worked?

# data[].attributes.headline
The Start of Setting Up MongoDB Database Connection

# data[].attributes.subject
The Start of Setting Up MongoDB Database Connection

# data[].attributes.body
Redirecting my focus onto the database creation, this log is not gonna be as visual as others.

Getting started with setting up connection to MongoDB Atlas, I'm planning to use a npm package called Monk which proxies my server communication to MongoDB Atlas.

Great start with an authentication error during the connection. Looks like I'm very famous with these authentication bugs.

[couple of hours later]

Okay, it looks like I won't need to use a connection string provided by MongoDB Atlas on cloud to connect to its database. I can basically install MongoDB CLI and work on the database locally.

Then when I re-deploy the system with MongoDB connection, I'll add in the mLab MongDB tool in Resource section on Heroku, so that Heroku will create an online connection string for my system to link to.
Coding Garden Tutorial on MongoDB app deployment

[minutes later]

mLab MongoDB has discontinued their MongoDB add-ons on Heroku. Looks like an alternative to that is ObjectRocket which costs at least $46. Great!!!!!!

[an eternity later]

Wait, so I've been going in a loop........I was correct when thinking about using MongDB Atlas, so why do I have to use mLab for deployment whilst Atlas itself is already a cloud-based service? That Youtube tutorial from the Coding Garden is old.

The bug was not from the connection string itself, it was from the way I coded to setup MongoDB connection following their tutorial. It looks, to me that .then() function is unable to return a value, it can only perform executing callbacks after a Promise obj is returned. So that was why I couldn't get any value out, and subsequently, the code exited out because of invalid data.

# data[].attributes.body
Although this process tends to be the very last step of a development stage, I still wanted to see whether the core playback functionality worked, and other reactive elements responded well to users' actions on the app

# data[].attributes.body
Implemented toggling functionality on the settings display and logout functionality

# data[].attributes.headline
Gradient Colours on The Map, More Images & Icons and Live Update Playlist Info & Loading Bar

# data[].attributes.subject
Gradient Colours on The Map, More Images & Icons and Live Update Playlist Info & Loading Bar

# data[].attributes.body
Everytime, there's a major update to the app, it will be immediately available in production. This is due to one and only reason, DEBUGGING PRODUCTION ERROR
Again URLs to the app and github repo:
https://muserfly.herokuapp.com/#/ (Please bear in mind my account on Heroku is a free one so waking up a Heroku app will take sometime)
https://github.com/vudoan1708-cyber/Emotion-Based-Music-Streaming-App-WEB/

# data[].attributes.headline
Updates on The Playlist Info Section (the pane on the right side of the screen)

# data[].attributes.subject
Updates on The Playlist Info Section (the pane on the right side of the screen)

# data[].attributes.headline
Live Hosted App & More Updates on The UI

# data[].attributes.subject
Live Hosted App & More Updates on The UI

# data[].attributes.body
Live URL of the app (still in development): https://muserfly.herokuapp.com/#/

No more displaying song titles on the map. Instead, all the song detail, ideally, will be shown on the right pane of the screen (not implemented yet).
However, this approach can change users attention from the map to the right pane completely. In order to balance out this attention seeking, showing tracks detail will still be kept from the previous design. But this can only be performed via mouse hovering, to reduce the busyness on the map

# data[].attributes.headline
How About Displaying Song's Names on The Map As Well?

# data[].attributes.subject
How About Displaying Song's Names on The Map As Well?

# data[].attributes.body
In order not to overwhelm users with alien interface, with not much information given, displaying song's names alongside the dots on The Emotion Map is not a bad idea.

But this can become drastically messy, as the map gets busier with hundreds of dots and names. There should be a more thorough consideration on this aspect: could be an on/off button to show/hide songs' names, on mouse hovering for further details (but this won't be ideal for mobile users),.....

# data[].attributes.body
Test on Song Play using Quince's premium Spotify account (Spotify tracks are only playable via its playback SDK if a user subscribes to its premium membership)

Minimum number of collected songs by default: 5

# data[].attributes.headline
Git Repository URL & Updates on The App's UI

# data[].attributes.subject
Git Repository URL & Updates on The App's UI

# data[].attributes.body
https://github.com/vudoan1708-cyber/Emotion-Based-Music-Streaming-App-WEB/

# data[].attributes.body
Name: Muserfly

Music + Butterfly with Butterfly representing transformation, hope and life.
The music platform that can bring transformation, hope and life to its users

# data[].attributes.body
Neighbours are represented by the blue stars

# data[].attributes.headline
Visualisation of Songs Within or Outside The Zone of The Accepted

# data[].attributes.subject
Visualisation of Songs Within or Outside The Zone of The Accepted

# data[].attributes.body
Terminology:

The Emotion Map:
A Map whose dots represent 2 affective values: valence and arousal

The Zone of The Accepted or The Zone:
The idea of creating a "green zone" which contains songs being closely matched with affective values a user chooses on The Emotion Map

Neighbours:
Users who choose a coordinates that is closely matched to others will be shown on the map

Loading:
The loading time varies and seems to drag on for a long while. Therefore, in order to distract users away from the waiting time, a couple of method will need using:

A loading bar will show its loading progress

The visualisation itself will also be the key factor of distraction: when a dot is hovered, a song's title, artist name and its affective values will display on screen, and if it suits their liking, they can drag the dot to The Zone to count the song to a playlist

A random line of words from the app's manuals / instructions will also be included right above the loading bar at the bottom of the page. This is meant to explain anything existing in the app (the explanations of the terminology, definitions of valence and arousal,... One downside is that this can only be a factor of distraction for first-time users

Below are 4 different examples of fetching songs based on 4 different moods: happy (green), sad (blue), angry (orange), and calm (purple).

The green shape represents The Zone, and green dots inside it represent collected songs. Other gray dots are visualised but will not be collected to a playlist (this is just a design prototype, so it is very uninformative).

# data[].attributes.headline
Prototypes For The Song Playing Visualisation

# data[].attributes.subject
Prototypes For The Song Playing Visualisation

# data[].attributes.body
Prototype With A Rainbow Path

Prototype Without A Rainbow Path

# data[].attributes.body
The plan of connecting users listening to the same music of a moment was not supposed to be included in the system initially according to the proposal.
However, the aim of the app is, no other than, creating a society where people can join in and feel each other's presence whilst discovering a new approach of listening to music. This concept is, connecting people who listen to music which has closely matched mood values via choosing them on an emotion map.

Therefore, in order to technically fulfil the nature of the app, there is a need of socket connections being implemented in it. Realtime applications implemented with Node.js have been reported to be MUCH FASTER and MORE EFFICIENT than Python Flask.

Link

# data[].attributes.body
Final Look of the Star Dots version (changes in size and brightness of each star)

# data[].attributes.body
The delay / lagging was caused by screen recording and it had no connection with the actual web app performances

# data[].attributes.headline
Star-Dots Map Without The Ghosting Effects

# data[].attributes.subject
Star-Dots Map Without The Ghosting Effects

# data[].attributes.body
The delay / lagging was caused by screen recording and it had no connection with the actual web app performances

# data[].attributes.body
The delay / lagging was caused by screen recording and it had no connection with the actual web app performances

# data[].attributes.body
The most horrible iteration I would personally say

# data[].attributes.body
It's starting to look less uniform and more organic from now

# data[].attributes.body
Instead of the circles, how about actual stars?

# data[].attributes.body
This time, I was trying out possibilities for the emotion map design that users can just click on a dot on the 2D graph, and it will map the coordinates to valence & arousal values. So that when calling Spotify API, the scores will be compared in this way (No more sentiment analysis)
Live Link on Codepen  (This is just a design-based prototype, there is no functionality to the system yet)

# data[].attributes.body
A Github page

# data[].attributes.body
Proxy to Backend Server

# data[].attributes.body
Doing it this way is really dangerous, as the clientside still needs to ask the server to perform a redirection to eventually obtain an access token
But if a request coming from one side, to another, then being redirected back to the original requesting source, it will create what is called a "Redirect Loop"
A "Redirect Loop" is a loop created when side A requests side B to perform a task, but within the task, there is a redirecting back to side A, which forms a cycle of repetition within this communication, causing repeating web refreshes (A -> B -> A)

One way around this is to create a proxy to side B, so that the request from side A is now fetched by a duplicate of side B, which is mimicked within side A. This will stop the loop from happening (A -> A -> A)

# data[].attributes.body
An approach which redirects from python flask to vue frontend app. This communication in fact, starts from the serverside, whose tasks (authorisation and such) will be performed within the backend app itself
After the tasks are done, it redirects back to the clientside. No complex methods needed for this operation

# data[].attributes.headline
Let's Not Make This Dress The Traditional Way

# data[].attributes.subject
Let's Not Make This Dress The Traditional Way

# data[].attributes.body
As mentioned, Spotify API has an authorisation code flow which redirects a client to its authentication site, bringing along an access token that can finally be used for any available service

# data[].attributes.headline
Web Browser Compatibility For Web Speech Recognition API

# data[].attributes.subject
Web Browser Compatibility For Web Speech Recognition API