Skip to content

Instantly share code, notes, and snippets.

@mbeaudru
Created May 31, 2019 21:35
Show Gist options
  • Save mbeaudru/c26501c95befa68d902fdcc207c4a548 to your computer and use it in GitHub Desktop.
Save mbeaudru/c26501c95befa68d902fdcc207c4a548 to your computer and use it in GitHub Desktop.
import { useReducer, useEffect } from 'react';
import Cookies from 'js-cookie';
import SpotifyWebApi from 'spotify-web-api-js';
import qs from 'query-string';
const INVALIDATE_TOKEN = 'INVALIDATE_TOKEN';
const USE_TOKEN = 'USE_TOKEN';
const SPOTIFY_ACCESS_TOKEN_COOKIE = 'spotify-access-token';
const CLEAR_URL_ON_TOKEN_VALID = true;
function reducer(state, action) {
switch (action.type) {
case INVALIDATE_TOKEN: {
Cookies.set(SPOTIFY_ACCESS_TOKEN_COOKIE);
return {
...state,
tokenIsValid: false,
accessToken: undefined,
};
}
case USE_TOKEN: {
if (CLEAR_URL_ON_TOKEN_VALID) {
window.history.replaceState(null, null, window.location.pathname);
}
const { accessToken, expiresIn: expiresInSecs } = action;
const expiresInDays = (expiresInSecs * 24) / 3600;
Cookies.set(SPOTIFY_ACCESS_TOKEN_COOKIE, accessToken, {
expires: expiresInDays,
});
return {
...state,
tokenIsValid: true,
accessToken,
};
}
default: {
return state;
}
}
}
const initialState = {
accessToken: undefined,
tokenIsValid: undefined,
};
export default function useSpotifyAccessToken() {
const [state, dispatch] = useReducer(reducer, initialState);
const { accessToken, tokenIsValid } = state;
useEffect(() => {
const { accessToken, expiresIn } = readSpotifyAuth();
if (!accessToken) {
dispatch({ type: INVALIDATE_TOKEN });
return;
}
checkTokenValidity(accessToken)
.then(() => {
dispatch({ type: USE_TOKEN, accessToken, expiresIn });
})
.catch(() => {
dispatch({ type: INVALIDATE_TOKEN });
});
}, [accessToken]);
return { accessToken, tokenIsValid };
}
function checkTokenValidity(token) {
return new Promise((res, rej) => {
const spotifyApi = new SpotifyWebApi();
spotifyApi.setAccessToken(token);
spotifyApi
.getMe()
.then(response => res(response))
.catch(e => rej(e));
});
}
function readSpotifyAuth() {
const {
access_token = Cookies.get(SPOTIFY_ACCESS_TOKEN_COOKIE),
expires_in,
} = qs.parse(window.location.hash);
return { accessToken: access_token, expiresIn: expires_in };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment