Skip to content

Commit

Permalink
player connected and switch track to cadence
Browse files Browse the repository at this point in the history
  • Loading branch information
hub-bla committed Sep 11, 2023
1 parent 5d16f89 commit e508029
Show file tree
Hide file tree
Showing 11 changed files with 381 additions and 61 deletions.
22 changes: 13 additions & 9 deletions App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,22 @@ import { StatusBar } from "expo-status-bar"
import { StyleSheet, View } from "react-native"
import { AuthContext, useAuthContextValues } from "./context"
import { Main } from "./pages"
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
import 'react-native-url-polyfill/auto';
const queryClient = new QueryClient()

import "react-native-url-polyfill/auto"
import {
PlaylistContext,
usePlaylistContextValues,
} from "./context/PlaylistContext"
import { PlayerContext, usePlayerContextValues } from "./context/PlayerContext"
export default function App() {
return (
<View style={styles.container}>
<QueryClientProvider client={queryClient}>
<AuthContext.Provider value={useAuthContextValues()}>
<Main />
</AuthContext.Provider>
</QueryClientProvider>
<AuthContext.Provider value={useAuthContextValues()}>
<PlaylistContext.Provider value={usePlaylistContextValues()}>
<PlayerContext.Provider value={usePlayerContextValues()}>
<Main />
</PlayerContext.Provider>
</PlaylistContext.Provider>
</AuthContext.Provider>
<StatusBar style='auto' />
</View>
)
Expand Down
35 changes: 25 additions & 10 deletions components/Playlists.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,37 @@
import { View, Text, StyleSheet } from "react-native"
import { View, Text, StyleSheet, TouchableOpacity } from "react-native"
import { useAuthContext } from "../context"
import { getCurrentUserPlaylists } from "../utils/currentUser"
import { Playlist } from "../utils/currentUser"
import { useState, useEffect } from "react"
import { getSongsFromPlaylist } from "../utils"
import { usePlaylistContext, usePlaylistContextValues } from "../context/PlaylistContext"

export const Playlists: React.FC = () => {
const { tokenData } = useAuthContext()
const [playlists, setPlaylists] = useState([])
const {handleSongsData} = usePlaylistContext()
const [playlistsArrOfObj, setplaylistsArrOfObj] = useState([])
const [selectedPlaylist, setSelectedPlaylist] = useState(null)
const [loading, setLoading] = useState(true)

const getPressedPlaylist = (name: string) => {
const { href } = playlistsArrOfObj.find((playlist) => playlist.name == name)
handleSongsData(href, tokenData.access_token)
}

useEffect(() => {
getCurrentUserPlaylists(tokenData.access_token).then((data: [Playlist]) => {
setPlaylists(
data.map((playlist: Playlist) => (
<View key={playlist.href} style={styles.playlist}>
<Text>{playlist.name}</Text>
</View>
))
)
setplaylistsArrOfObj(data)
})
}, [])
const playlists = playlistsArrOfObj.map((playlist: Playlist) => (
<TouchableOpacity
key={playlist.href}
onPress={() => getPressedPlaylist(playlist.name)}>
<View style={styles.playlist}>
<Text>{playlist.name}</Text>
</View>
</TouchableOpacity>
))

return <>{playlists}</>
}
Expand All @@ -28,6 +43,6 @@ const styles = StyleSheet.create({
backgroundColor: "#fca103",
alignItems: "center",
justifyContent: "center",
margin: 10,
margin: 10,
},
})
48 changes: 21 additions & 27 deletions context/AuthContext.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { createContext, useContext, useState } from "react"
import { Buffer } from "buffer"
import axios from "axios"
export const AuthContext = createContext(null)

type TokenData = {
Expand Down Expand Up @@ -28,23 +27,11 @@ export const useAuthContextValues = () => {
secret_client: "3b5bf406c52e48e982ad9466ee22f139",
})
const [tokenData, setTokenData] = useState<TokenData | null>(null)
const changeTokenRequest = (code, uri) => {
setTokenRequest((prev_token) => {
return {
code: code,
redirect_uri: uri,
...prev_token,
}
})
}
//dosent work

const getToken: (arg1: string, arg2: string) => void = async (
code,
redirected_url
) => {
console.log(`CODE: ${code}`)
console.log(`REDIRECTED: ${redirected_url}`)


const authOptions = {
method: "POST",
Expand Down Expand Up @@ -80,22 +67,29 @@ export const useAuthContextValues = () => {
}

const refreshToken: () => void = async () => {
const params = new URLSearchParams({
refresh_token: tokenData.refresh_token,
grant_type: "refresh_token",
})

const buff = Buffer.from(
tokenRequest.client_id + ":" + tokenRequest.secret_client
).toString("base64")

const response = await fetch("https://accounts.spotify.com/api/token", {
const authOptions = {
method: "POST",
headers: {
Authorization: "Basic " + buff,
Authorization:
"Basic " +
Buffer.from(
tokenRequest.client_id + ":" + tokenRequest.secret_client
).toString("base64"),
"Content-Type": "application/x-www-form-urlencoded",
},
body: params,
})
body: new URLSearchParams({
refresh_token: tokenData.refresh_token,
grant_type: "refresh_token",
}).toString(),
}



const response = await fetch(
"https://accounts.spotify.com/api/token",
authOptions
)

response.json().then((data) => {
setTokenData((prevTokenData) => {
Expand All @@ -107,8 +101,8 @@ export const useAuthContextValues = () => {
}
})
})

}
console.log(tokenData)
return {
isAuthorized,
getToken,
Expand Down
70 changes: 70 additions & 0 deletions context/PlayerContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { createContext, useContext, useState } from "react"

export const PlayerContext = createContext(null)

export const usePlayerContext = () => {
const context = useContext(PlayerContext)
if (!context) {
throw new Error("PlayerContext must be used within PlayerContext.Provider")
}
return context
}

export const usePlayerContextValues = () => {
const [currentSong, setCurrentSong] = useState(null)
const [devices, setDevices] = useState([])
const [currentDevice, setCurrDevice] = useState(null)
const getDevices = async (token: string) => {
await (
await fetch(`https://api.spotify.com/v1/me/player/devices`, {
headers: {
Authorization: "Bearer " + token,
},
})
)
.json()
.then((data) => {
console.log("DATA", typeof data)
setDevices(
data.devices.map((device) => {
return {
id: device.id,
name: device.name,
}
})
)
})
}

const playSong = async (song, token) => {
console.log(song.uri)
console.log(currentDevice)
if (currentSong != song && currentDevice) {
//add to queue

await fetch(
`https://api.spotify.com/v1/me/player/queue?uri=${song.uri}&device_id=${currentDevice.id}`,
{
method: "POST",
headers: {
Authorization: "Bearer " + token,
},
}
)

//skip to added track
await fetch(`https://api.spotify.com/v1/me/player/next`, {
method: "POST",
headers: {
Authorization: "Bearer " + token,
},
body: new URLSearchParams({
device_id: currentDevice.id,
}).toString(),
})
setCurrentSong(song)
}
}

return { getDevices, devices, setCurrDevice, currentDevice, playSong }
}
62 changes: 62 additions & 0 deletions context/PlaylistContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { createContext, useContext, useState } from "react";
import { getSongsFromPlaylist } from "../utils";


export const PlaylistContext = createContext(null)


export const usePlaylistContext = () => {
const context = useContext(PlaylistContext)

if (!context){
throw new Error("PlaylistContext must be used within PlaylistContext.Provider")
}
return context
}



export const usePlaylistContextValues = () => {
const [songs, setSongs] = useState({})
const [matchingTempoArr, setMatchingTempoArr] = useState([])
const [isPicked, setIsPicked] = useState(false)


const handleSongsData = (href:string, token:string) =>{
getSongsFromPlaylist(href, token)
.then(({idTempoArr, songData}) => {
setSongs(songData)
setMatchingTempoArr(idTempoArr)
})
setIsPicked(true)
}


const findSuitableSong = (currentCadence:number) => {
let min = matchingTempoArr[0];
let left = 0
let right = matchingTempoArr.length

console.log(currentCadence)
while (left<right){
let middle = Math.floor((right+left)/2)
const distance = Math.abs(currentCadence - matchingTempoArr[middle][1])
if (distance < min[1]){
min = matchingTempoArr[middle]
}
if (currentCadence>matchingTempoArr[middle][1]){
right = middle
}

else{
left = middle+1
}
}

return songs[min[0]]
}



return {handleSongsData, findSuitableSong, isPicked}
}
17 changes: 12 additions & 5 deletions pages/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,29 @@ import { Login, Playlists } from "../components"
import { useAuthContext } from "../context"
import { Text } from "react-native"
import { useEffect } from "react"
import { usePlaylistContext } from "../context/PlaylistContext"
import { RunPage } from "./RunPage"
import { PlayerContext, usePlayerContextValues } from "../context/PlayerContext"
export const Main: React.FC = () => {
const { isAuthorized, refreshToken, tokenData } = useAuthContext()
const { isPicked } = usePlaylistContext()
useEffect(() => {
if (isAuthorized && tokenData.access_token !=null) {
setInterval(() => refreshToken(), tokenData.expires_in*1000)
if (isAuthorized && tokenData.access_token != null) {
setInterval(() => refreshToken(), tokenData.expires_in * 1000)
}
}, [isAuthorized])


if (!isAuthorized) {
return <Login />
}


if (isPicked) {
return <RunPage />
}
console.log(isPicked)
return (
<>
<Playlists/>
<Playlists />
</>
)
}
Loading

0 comments on commit e508029

Please sign in to comment.