mirror of
https://github.com/KRTirtho/spotube.git
synced 2025-09-13 07:55:18 +00:00
Fixed: <Switch> inifinite loop
Added: prefrencesContext Edited: PlaylistCard for enabling images
This commit is contained in:
parent
09467e6e9a
commit
b0c6781df4
33
src/app.tsx
33
src/app.tsx
@ -12,14 +12,16 @@ import express from "express";
|
|||||||
import open from "open";
|
import open from "open";
|
||||||
import spotifyApi from "./initializations/spotifyApi";
|
import spotifyApi from "./initializations/spotifyApi";
|
||||||
import showError from "./helpers/showError";
|
import showError from "./helpers/showError";
|
||||||
import fs from "fs"
|
import fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { confDir } from "./conf";
|
import { confDir } from "./conf";
|
||||||
import spotubeIcon from "../assets/icon.svg";
|
import spotubeIcon from "../assets/icon.svg";
|
||||||
|
import preferencesContext, { PreferencesContextProperties } from "./context/preferencesContext";
|
||||||
|
|
||||||
export enum CredentialKeys {
|
export enum LocalStorageKeys {
|
||||||
credentials = "credentials",
|
credentials = "credentials",
|
||||||
refresh_token = "refresh_token",
|
refresh_token = "refresh_token",
|
||||||
|
preferences = "user-preferences",
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Credentials {
|
export interface Credentials {
|
||||||
@ -42,6 +44,11 @@ const queryClient = new QueryClient({
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const initialPreferences: PreferencesContextProperties = {
|
||||||
|
playlistImages: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
//* Application start
|
||||||
function RootApp() {
|
function RootApp() {
|
||||||
const windowRef = useRef<QMainWindow>();
|
const windowRef = useRef<QMainWindow>();
|
||||||
const [currentTrack, setCurrentTrack] = useState<CurrentTrack>();
|
const [currentTrack, setCurrentTrack] = useState<CurrentTrack>();
|
||||||
@ -75,16 +82,28 @@ function RootApp() {
|
|||||||
},
|
},
|
||||||
[currentTrack]
|
[currentTrack]
|
||||||
);
|
);
|
||||||
|
// cache
|
||||||
|
const cachedPreferences = localStorage.getItem(LocalStorageKeys.preferences);
|
||||||
|
const cachedCredentials = localStorage.getItem(LocalStorageKeys.credentials);
|
||||||
|
// state
|
||||||
const [isLoggedIn, setIsLoggedIn] = useState<boolean>(false);
|
const [isLoggedIn, setIsLoggedIn] = useState<boolean>(false);
|
||||||
const [credentials, setCredentials] = useState<Credentials>({ clientId: "", clientSecret: "" });
|
const [credentials, setCredentials] = useState<Credentials>({ clientId: "", clientSecret: "" });
|
||||||
|
const [preferences, setPreferences] = useState<PreferencesContextProperties>(() => {
|
||||||
|
if (cachedPreferences) {
|
||||||
|
return JSON.parse(cachedPreferences);
|
||||||
|
}
|
||||||
|
return initialPreferences;
|
||||||
|
});
|
||||||
const [access_token, setAccess_token] = useState<string>("");
|
const [access_token, setAccess_token] = useState<string>("");
|
||||||
const [currentPlaylist, setCurrentPlaylist] = useState<CurrentPlaylist>();
|
const [currentPlaylist, setCurrentPlaylist] = useState<CurrentPlaylist>();
|
||||||
const cachedCredentials = localStorage.getItem(CredentialKeys.credentials);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setIsLoggedIn(!!cachedCredentials);
|
setIsLoggedIn(!!cachedCredentials);
|
||||||
}, []);
|
}, []);
|
||||||
|
// just saves the preferences
|
||||||
|
useEffect(() => {
|
||||||
|
localStorage.setItem(LocalStorageKeys.preferences, JSON.stringify(preferences));
|
||||||
|
}, [preferences]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const onWindowClose = () => {
|
const onWindowClose = () => {
|
||||||
@ -100,7 +119,7 @@ function RootApp() {
|
|||||||
});
|
});
|
||||||
// for user code login
|
// for user code login
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isLoggedIn && credentials && !localStorage.getItem(CredentialKeys.refresh_token)) {
|
if (isLoggedIn && credentials && !localStorage.getItem(LocalStorageKeys.refresh_token)) {
|
||||||
const app = express();
|
const app = express();
|
||||||
app.use(express.json());
|
app.use(express.json());
|
||||||
|
|
||||||
@ -110,7 +129,7 @@ function RootApp() {
|
|||||||
spotifyApi.setClientSecret(credentials.clientSecret);
|
spotifyApi.setClientSecret(credentials.clientSecret);
|
||||||
const { body: authRes } = await spotifyApi.authorizationCodeGrant(req.query.code);
|
const { body: authRes } = await spotifyApi.authorizationCodeGrant(req.query.code);
|
||||||
setAccess_token(authRes.access_token);
|
setAccess_token(authRes.access_token);
|
||||||
localStorage.setItem(CredentialKeys.refresh_token, authRes.refresh_token);
|
localStorage.setItem(LocalStorageKeys.refresh_token, authRes.refresh_token);
|
||||||
return res.end();
|
return res.end();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Failed to fullfil code grant flow: ", error);
|
console.error("Failed to fullfil code grant flow: ", error);
|
||||||
@ -141,6 +160,7 @@ function RootApp() {
|
|||||||
<Window ref={windowRef} on={windowEvents} windowState={WindowState.WindowMaximized} windowIcon={winIcon} windowTitle="Spotube" minSize={minSize}>
|
<Window ref={windowRef} on={windowEvents} windowState={WindowState.WindowMaximized} windowIcon={winIcon} windowTitle="Spotube" minSize={minSize}>
|
||||||
<MemoryRouter>
|
<MemoryRouter>
|
||||||
<authContext.Provider value={{ isLoggedIn, setIsLoggedIn, access_token, setAccess_token, ...credentials }}>
|
<authContext.Provider value={{ isLoggedIn, setIsLoggedIn, access_token, setAccess_token, ...credentials }}>
|
||||||
|
<preferencesContext.Provider value={{ ...preferences, setPreferences }}>
|
||||||
<playerContext.Provider value={{ currentPlaylist, currentTrack, setCurrentPlaylist, setCurrentTrack }}>
|
<playerContext.Provider value={{ currentPlaylist, currentTrack, setCurrentPlaylist, setCurrentTrack }}>
|
||||||
<QueryClientProvider client={queryClient}>
|
<QueryClientProvider client={queryClient}>
|
||||||
<View style={`flex: 1; flex-direction: 'column'; align-items: 'stretch';`}>
|
<View style={`flex: 1; flex-direction: 'column'; align-items: 'stretch';`}>
|
||||||
@ -149,6 +169,7 @@ function RootApp() {
|
|||||||
</View>
|
</View>
|
||||||
</QueryClientProvider>
|
</QueryClientProvider>
|
||||||
</playerContext.Provider>
|
</playerContext.Provider>
|
||||||
|
</preferencesContext.Provider>
|
||||||
</authContext.Provider>
|
</authContext.Provider>
|
||||||
</MemoryRouter>
|
</MemoryRouter>
|
||||||
</Window>
|
</Window>
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import React, { useContext, useState } from "react";
|
import React, { useContext, useState } from "react";
|
||||||
import { LineEdit, Text, Button, View } from "@nodegui/react-nodegui";
|
import { LineEdit, Text, Button, View } from "@nodegui/react-nodegui";
|
||||||
import authContext from "../context/authContext";
|
import authContext from "../context/authContext";
|
||||||
import { CredentialKeys, Credentials } from "../app";
|
import { LocalStorageKeys, Credentials } from "../app";
|
||||||
|
|
||||||
function Login() {
|
function Login() {
|
||||||
const { setIsLoggedIn } = useContext(authContext);
|
const { setIsLoggedIn } = useContext(authContext);
|
||||||
@ -55,7 +55,7 @@ function Login() {
|
|||||||
on={{
|
on={{
|
||||||
clicked: () => {
|
clicked: () => {
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
CredentialKeys.credentials,
|
LocalStorageKeys.credentials,
|
||||||
JSON.stringify({
|
JSON.stringify({
|
||||||
clientId: credentials.clientId,
|
clientId: credentials.clientId,
|
||||||
clientSecret: credentials.clientSecret,
|
clientSecret: credentials.clientSecret,
|
||||||
|
@ -1,14 +1,20 @@
|
|||||||
import { Text, View } from "@nodegui/react-nodegui";
|
import { Text, View } from "@nodegui/react-nodegui";
|
||||||
import React from "react";
|
import React, { useContext } from "react";
|
||||||
import Switch from "./shared/Switch";
|
import preferencesContext from "../context/preferencesContext";
|
||||||
|
import Switch, { SwitchProps } from "./shared/Switch";
|
||||||
|
|
||||||
function Settings() {
|
function Settings() {
|
||||||
|
const { setPreferences, ...preferences } = useContext(preferencesContext)
|
||||||
return (
|
return (
|
||||||
<View style="flex: 1; flex-direction: 'column'; justify-content: 'flex-start';">
|
<View style="flex: 1; flex-direction: 'column'; justify-content: 'flex-start';">
|
||||||
<Text>{`<center><h2>Settings</h2></center>`}</Text>
|
<Text>{`<center><h2>Settings</h2></center>`}</Text>
|
||||||
<View style="width: '100%'; flex-direction: 'column'; justify-content: 'flex-start';">
|
<View style="width: '100%'; flex-direction: 'column'; justify-content: 'flex-start';">
|
||||||
<SettingsCheckTile title="Use images instead of colors for playlist" subtitle="This will increase memory usage" />
|
<SettingsCheckTile
|
||||||
<SettingsCheckTile title="Some unknown settings" />
|
checked={preferences.playlistImages}
|
||||||
|
title="Use images instead of colors for playlist"
|
||||||
|
subtitle="This will increase memory usage"
|
||||||
|
onChange={(checked) => setPreferences({ ...preferences, playlistImages: checked })}
|
||||||
|
/>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
@ -19,9 +25,11 @@ export default Settings;
|
|||||||
interface SettingsCheckTileProps {
|
interface SettingsCheckTileProps {
|
||||||
title: string;
|
title: string;
|
||||||
subtitle?: string;
|
subtitle?: string;
|
||||||
|
checked: boolean;
|
||||||
|
onChange?: SwitchProps["onChange"];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function SettingsCheckTile({ title, subtitle = "" }: SettingsCheckTileProps) {
|
export function SettingsCheckTile({ title, subtitle = "", onChange, checked }: SettingsCheckTileProps) {
|
||||||
return (
|
return (
|
||||||
<View style="flex: 1; align-items: 'center'; padding: 15px 0; justify-content: 'space-between';">
|
<View style="flex: 1; align-items: 'center'; padding: 15px 0; justify-content: 'space-between';">
|
||||||
<Text>
|
<Text>
|
||||||
@ -30,7 +38,7 @@ export function SettingsCheckTile({ title, subtitle = "" }: SettingsCheckTilePro
|
|||||||
<p>${subtitle}</p>
|
<p>${subtitle}</p>
|
||||||
`}
|
`}
|
||||||
</Text>
|
</Text>
|
||||||
<Switch checked/>
|
<Switch checked={checked} onChange={onChange} />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,26 @@
|
|||||||
import { CursorShape, QIcon, QMouseEvent } from '@nodegui/nodegui';
|
import { CursorShape, QIcon, QMouseEvent } from "@nodegui/nodegui";
|
||||||
import { Text, View } from '@nodegui/react-nodegui';
|
import { Text, View } from "@nodegui/react-nodegui";
|
||||||
import React, { useContext, useMemo, useState } from 'react'
|
import React, { useContext, useMemo, useState } from "react";
|
||||||
import { useHistory } from 'react-router';
|
import { useHistory } from "react-router";
|
||||||
import { QueryCacheKeys } from '../../conf';
|
import { QueryCacheKeys } from "../../conf";
|
||||||
import playerContext from '../../context/playerContext';
|
import playerContext from "../../context/playerContext";
|
||||||
import { generateRandomColor, getDarkenForeground } from '../../helpers/RandomColor';
|
import preferencesContext from "../../context/preferencesContext";
|
||||||
import showError from '../../helpers/showError';
|
import { generateRandomColor, getDarkenForeground } from "../../helpers/RandomColor";
|
||||||
import usePlaylistReaction from '../../hooks/usePlaylistReaction';
|
import showError from "../../helpers/showError";
|
||||||
import useSpotifyQuery from '../../hooks/useSpotifyQuery';
|
import usePlaylistReaction from "../../hooks/usePlaylistReaction";
|
||||||
import { heart, heartRegular, pause, play } from '../../icons';
|
import useSpotifyQuery from "../../hooks/useSpotifyQuery";
|
||||||
import { audioPlayer } from '../Player';
|
import { heart, heartRegular, pause, play } from "../../icons";
|
||||||
import IconButton from './IconButton';
|
import { audioPlayer } from "../Player";
|
||||||
|
import CachedImage from "./CachedImage";
|
||||||
|
import IconButton from "./IconButton";
|
||||||
|
|
||||||
interface PlaylistCardProps {
|
interface PlaylistCardProps {
|
||||||
playlist: SpotifyApi.PlaylistObjectSimplified;
|
playlist: SpotifyApi.PlaylistObjectSimplified;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PlaylistCard = ({ playlist }: PlaylistCardProps) => {
|
const PlaylistCard = ({ playlist }: PlaylistCardProps) => {
|
||||||
|
const preferences = useContext(preferencesContext);
|
||||||
|
const thumbnail = playlist.images[0].url;
|
||||||
const { id, description, name, images } = playlist;
|
const { id, description, name, images } = playlist;
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
const [hovered, setHovered] = useState(false);
|
const [hovered, setHovered] = useState(false);
|
||||||
@ -31,7 +35,7 @@ const PlaylistCard = ({ playlist }: PlaylistCardProps) => {
|
|||||||
try {
|
try {
|
||||||
const { data: tracks, isSuccess } = await refetch();
|
const { data: tracks, isSuccess } = await refetch();
|
||||||
if (currentPlaylist?.id !== id && isSuccess && tracks) {
|
if (currentPlaylist?.id !== id && isSuccess && tracks) {
|
||||||
setCurrentPlaylist({ tracks, id, name, thumbnail: images[0].url });
|
setCurrentPlaylist({ tracks, id, name, thumbnail });
|
||||||
setCurrentTrack(tracks[0].track);
|
setCurrentTrack(tracks[0].track);
|
||||||
} else {
|
} else {
|
||||||
await audioPlayer.stop();
|
await audioPlayer.stop();
|
||||||
@ -46,7 +50,7 @@ const PlaylistCard = ({ playlist }: PlaylistCardProps) => {
|
|||||||
function gotoPlaylist(native?: any) {
|
function gotoPlaylist(native?: any) {
|
||||||
const key = new QMouseEvent(native);
|
const key = new QMouseEvent(native);
|
||||||
if (key.button() === 1) {
|
if (key.button() === 1) {
|
||||||
history.push(`/playlist/${id}`, { name, thumbnail: images[0].url });
|
history.push(`/playlist/${id}`, { name, thumbnail });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,14 +58,16 @@ const PlaylistCard = ({ playlist }: PlaylistCardProps) => {
|
|||||||
const color = useMemo(() => getDarkenForeground(bgColor1), [bgColor1]);
|
const color = useMemo(() => getDarkenForeground(bgColor1), [bgColor1]);
|
||||||
|
|
||||||
const playlistStyleSheet = `
|
const playlistStyleSheet = `
|
||||||
#playlist-container{
|
#playlist-container, #img-container{
|
||||||
width: 150px;
|
width: 150px;
|
||||||
flex-direction: column;
|
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
min-height: 150px;
|
|
||||||
background-color: ${bgColor1};
|
|
||||||
border-radius: 5px;
|
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: ${bgColor1};
|
||||||
|
}
|
||||||
|
#playlist-container{
|
||||||
|
border-radius: 5px;
|
||||||
|
min-height: 150px;
|
||||||
}
|
}
|
||||||
#playlist-container:hover{
|
#playlist-container:hover{
|
||||||
border: 1px solid green;
|
border: 1px solid green;
|
||||||
@ -70,34 +76,16 @@ const PlaylistCard = ({ playlist }: PlaylistCardProps) => {
|
|||||||
border: 5px solid green;
|
border: 5px solid green;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
const playlistAction = `
|
||||||
|
position: absolute;
|
||||||
|
bottom: 30px;
|
||||||
|
background-color: ${color};
|
||||||
|
`;
|
||||||
|
|
||||||
return (
|
const playlistActions = (
|
||||||
<View
|
|
||||||
id="playlist-container"
|
|
||||||
cursor={CursorShape.PointingHandCursor}
|
|
||||||
styleSheet={playlistStyleSheet}
|
|
||||||
on={{
|
|
||||||
MouseButtonRelease: gotoPlaylist,
|
|
||||||
HoverEnter() {
|
|
||||||
setHovered(true);
|
|
||||||
},
|
|
||||||
HoverLeave() {
|
|
||||||
setHovered(false);
|
|
||||||
},
|
|
||||||
}}>
|
|
||||||
{/* <CachedImage src={thumbnail} maxSize={{ height: 150, width: 150 }} scaledContents alt={name} /> */}
|
|
||||||
<Text style={`color: ${color};`} wordWrap on={{ MouseButtonRelease: gotoPlaylist }}>
|
|
||||||
{`
|
|
||||||
<center>
|
|
||||||
<h3>${name}</h3>
|
|
||||||
<p>${description}</p>
|
|
||||||
</center>
|
|
||||||
`}
|
|
||||||
</Text>
|
|
||||||
{(hovered || currentPlaylist?.id === id) && (
|
|
||||||
<>
|
<>
|
||||||
<IconButton
|
<IconButton
|
||||||
style={`position: absolute; bottom: 30px; left: '55%'; background-color: ${color};`}
|
style={preferences.playlistImages ? "" : playlistAction + "left: '55%'"}
|
||||||
icon={new QIcon(isFavorite(id) ? heart : heartRegular)}
|
icon={new QIcon(isFavorite(id) ? heart : heartRegular)}
|
||||||
on={{
|
on={{
|
||||||
clicked() {
|
clicked() {
|
||||||
@ -106,8 +94,8 @@ const PlaylistCard = ({ playlist }: PlaylistCardProps) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
|
style={preferences.playlistImages ? "" : playlistAction + "left: '80%'"}
|
||||||
icon={new QIcon(currentPlaylist?.id === id ? pause : play)}
|
icon={new QIcon(currentPlaylist?.id === id ? pause : play)}
|
||||||
style={`position: absolute; bottom: 30px; left: '80%'; background-color: ${color};`}
|
|
||||||
on={{
|
on={{
|
||||||
clicked() {
|
clicked() {
|
||||||
handlePlaylistPlayPause();
|
handlePlaylistPlayPause();
|
||||||
@ -115,7 +103,41 @@ const PlaylistCard = ({ playlist }: PlaylistCardProps) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
);
|
||||||
|
const hovers = {
|
||||||
|
HoverEnter() {
|
||||||
|
setHovered(true);
|
||||||
|
},
|
||||||
|
HoverLeave() {
|
||||||
|
setHovered(false);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
id={preferences.playlistImages ? "img-container" : "playlist-container"}
|
||||||
|
cursor={CursorShape.PointingHandCursor}
|
||||||
|
styleSheet={playlistStyleSheet}
|
||||||
|
on={{
|
||||||
|
MouseButtonRelease: gotoPlaylist,
|
||||||
|
...hovers,
|
||||||
|
}}>
|
||||||
|
{preferences.playlistImages && <CachedImage src={thumbnail} maxSize={{ height: 150, width: 150 }} scaledContents alt={name} />}
|
||||||
|
|
||||||
|
<Text style={`color: ${color};`} wordWrap on={{ MouseButtonRelease: gotoPlaylist, ...hovers }}>
|
||||||
|
{`
|
||||||
|
<center>
|
||||||
|
<h3>${name}</h3>
|
||||||
|
<p>${description}</p>
|
||||||
|
</center>
|
||||||
|
`}
|
||||||
|
</Text>
|
||||||
|
|
||||||
|
{(hovered || currentPlaylist?.id === id) && !preferences.playlistImages && playlistActions}
|
||||||
|
{preferences.playlistImages &&
|
||||||
|
<View style="flex: 1; justify-content: 'space-around';">{playlistActions}
|
||||||
|
</View>
|
||||||
|
}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -3,20 +3,22 @@ import { Slider } from "@nodegui/react-nodegui";
|
|||||||
import { CheckBoxProps } from "@nodegui/react-nodegui/dist/components/CheckBox/RNCheckBox";
|
import { CheckBoxProps } from "@nodegui/react-nodegui/dist/components/CheckBox/RNCheckBox";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
|
|
||||||
interface SwitchProps extends Omit<CheckBoxProps, "on" |"icon" | "text">{
|
export interface SwitchProps extends Omit<CheckBoxProps, "on" | "icon" | "text"> {
|
||||||
onChange?(checked:boolean): void
|
onChange?(checked: boolean): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
function Switch({ checked, onChange, ...props }: SwitchProps) {
|
function Switch({ checked: derivedChecked, onChange, ...props }: SwitchProps) {
|
||||||
const [value, setValue] = useState<0|1>(0);
|
const [checked, setChecked] = useState<boolean>(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setValue(checked ? 1 : 0);
|
if (derivedChecked) {
|
||||||
}, [checked])
|
setChecked(derivedChecked);
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Slider
|
<Slider
|
||||||
value={value}
|
value={checked ? 1 : 0}
|
||||||
hasTracking
|
hasTracking
|
||||||
mouseTracking
|
mouseTracking
|
||||||
orientation={Orientation.Horizontal}
|
orientation={Orientation.Horizontal}
|
||||||
@ -30,13 +32,13 @@ function Switch({ checked, onChange, ...props }: SwitchProps) {
|
|||||||
MouseButtonRelease(native: any) {
|
MouseButtonRelease(native: any) {
|
||||||
const mouse = new QMouseEvent(native);
|
const mouse = new QMouseEvent(native);
|
||||||
if (mouse.button() === 1) {
|
if (mouse.button() === 1) {
|
||||||
setValue(value===1?0:1)
|
setChecked(!checked);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
}}
|
||||||
{...props}
|
{...props}
|
||||||
/>);
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Switch;
|
export default Switch;
|
||||||
|
15
src/context/preferencesContext.ts
Normal file
15
src/context/preferencesContext.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import React, { Dispatch, SetStateAction } from "react";
|
||||||
|
|
||||||
|
export interface PreferencesContextProperties {
|
||||||
|
playlistImages: boolean;
|
||||||
|
}
|
||||||
|
export interface PreferencesContext extends PreferencesContextProperties {
|
||||||
|
setPreferences: Dispatch<SetStateAction<PreferencesContextProperties>>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const preferencesContext = React.createContext<PreferencesContext>({
|
||||||
|
playlistImages: false,
|
||||||
|
setPreferences() { }
|
||||||
|
});
|
||||||
|
|
||||||
|
export default preferencesContext;
|
@ -1,6 +1,6 @@
|
|||||||
import chalk from "chalk";
|
import chalk from "chalk";
|
||||||
import { useContext, useEffect } from "react";
|
import { useContext, useEffect } from "react";
|
||||||
import { CredentialKeys } from "../app";
|
import { LocalStorageKeys } from "../app";
|
||||||
import authContext from "../context/authContext";
|
import authContext from "../context/authContext";
|
||||||
import showError from "../helpers/showError";
|
import showError from "../helpers/showError";
|
||||||
import spotifyApi from "../initializations/spotifyApi";
|
import spotifyApi from "../initializations/spotifyApi";
|
||||||
@ -13,7 +13,7 @@ function useSpotifyApi() {
|
|||||||
isLoggedIn,
|
isLoggedIn,
|
||||||
setAccess_token,
|
setAccess_token,
|
||||||
} = useContext(authContext);
|
} = useContext(authContext);
|
||||||
const refreshToken = localStorage.getItem(CredentialKeys.refresh_token);
|
const refreshToken = localStorage.getItem(LocalStorageKeys.refresh_token);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isLoggedIn && clientId && clientSecret && refreshToken) {
|
if (isLoggedIn && clientId && clientSecret && refreshToken) {
|
||||||
|
Loading…
Reference in New Issue
Block a user