Build An 8-bit Spotify Controller | Phase 6

The final Phase of our Cyberpunk 2077-inspired React-Chrome Extension

This is Phase Six of a multi-phase project where we build a Spotify Chrome Extension powered by ReactJS that allows us to control the user’s Spotify session.

Phase One can be found here.

This series of tutorials supposes that you…

Understand how Google Chrome Extensions work:

Need an in-depth course? Try our Teachable:

We have a course for completely-new-to-web-dev’ers
as well as for experienced web dev’s who want a more curated experience.

Like any Chrome Extension, we need to inject the foreground page into the User’s browser.

We, of course, inject from our Background.js script.

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === ‘complete’ && tab.url.includes(‘http’)) {
active_tabId = tabId;
chrome.tabs.executeScript(tabId, { file: ‘./inject_script.js’ }, function () {
chrome.tabs.executeScript(tabId, { file: ‘./foreground.bundle.js’ }, function () {
console.log(“INJECTED AND EXECUTED”);
});
});
}
});
chrome.tabs.onActivated.addListener(activeInfo => {
chrome.tabs.get(activeInfo.tabId, function (tab) {
if (tab.url.includes(‘http’)) active_tabId = activeInfo.tabId;
});
});

Staying in our Background.js file, we’ll create those two functions…

function get_state() {
return new Promise((resolve, reject) => {
chrome.storage.local.get(‘chrome-ext-Spotify-controller’, item => {
if (chrome.runtime.lastError) {
reject(‘fail’);
} else {
const state = item[‘chrome-ext-Spotify-controller’] ? item[‘chrome-ext-Spotify-controller’] : “{}”;
resolve(JSON.parse(state));
}
});
});
}
function set_state(_state) {
return new Promise((resolve, reject) => {
get_state()
.then(res => {
const updated_state = {
…res,
…_state
}
chrome.storage.local.set({ ‘chrome-ext-Spotify-controller’: JSON.stringify(updated_state) }, () => {
if (chrome.runtime.lastError) {
reject(‘fail’);
} else {
resolve(‘success’);
}
});
});
});
}

All that’s left to do is pair our Spotify API logic in the Background script to the function calls in our Foreground script.

We won’t go into every function pairing here, we’ll show you one.
See the video tutorial for a detailed walk-through.

In the Foreground.js component we have our start_pause function message our Background.js script.

start_pause = () => {
chrome.runtime.sendMessage({ message: this.state.isPlaying ? ‘pause’ : ‘play’, payload: { isPlaying: !this.state.isPlaying } }, response => {
if (response.message === ‘success’) {
this.setState(_state => {
return {
isPlaying: !_state.isPlaying,
current_track: response.current_track
}
});
}
});
}

In our Background.js script, we catch that message, call the Spotify API, and send back a response to the Foreground.js component.


if (request.message === ‘play’) {
player.play()
.then(res => set_state(request.payload))
.then(res => player.current())
.then(res => sendResponse({ message: ‘success’, current_track: res.current_track }))
.catch(err => sendResponse({ message: ‘fail’ }));
return true;
} else if (request.message === ‘pause’) {
player.pause()
.then(res => set_state(request.payload))
.then(res => player.current())
.then(res => sendResponse({ message: ‘success’, current_track: res.current_track }))
.catch(err => sendResponse({ message: ‘fail’ }));
return true;

After merging our Background and Foreground, we handle the Login System.

If you want to see how that’s done see the video tutorial below.

You can find the final source files for this project here.

If you would like a more in-depth guide, check out my full video tutorial on YouTube, An Object Is A.

Build a Cyberpunk 2077-inspired Spotify Controller — Phase 6

Learning to code…

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store