2 커밋 23ae97ba4e ... 25ead7e987

작성자 SHA1 메시지 날짜
  RomanR 25ead7e987 Merge branch 'Development' of gitlab.a-level.com.ua:Roman456/gRomkoPlayer into Development 4 년 전
  RomanR 7fd4f37529 wip 4 년 전

+ 7 - 7
package-lock.json

@@ -8695,9 +8695,9 @@
       }
     },
     "node-forge": {
-      "version": "0.9.0",
-      "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz",
-      "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ=="
+      "version": "0.10.0",
+      "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
+      "integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA=="
     },
     "node-int64": {
       "version": "0.4.0",
@@ -12275,11 +12275,11 @@
       "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo="
     },
     "selfsigned": {
-      "version": "1.10.7",
-      "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz",
-      "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==",
+      "version": "1.10.8",
+      "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz",
+      "integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==",
       "requires": {
-        "node-forge": "0.9.0"
+        "node-forge": "^0.10.0"
       }
     },
     "semver": {

+ 6 - 1
src/App.js

@@ -1,4 +1,5 @@
 import React, { useEffect, useState } from "react";
+
 import {
   BrowserRouter as Router,
   Route,
@@ -10,6 +11,7 @@ import { connect } from "react-redux";
 import { Provider } from "react-redux";
 import store from "./store";
 import history from "./utils/history";
+// import {ConnectedRouter} from 'react-router-redux';
 
 import "./styles/Reset.css";
 import "./styles/App.css";
@@ -17,6 +19,7 @@ import "./styles/App.css";
 import RegisterForm from "./components/RegisterForm";
 import LoginForm from "./components/LoginForm";
 import Lib from "./components/Library";
+import Playlist from "./components/Playlist";
 
 const PrivateRoute = (props) => {
   console.log(props);
@@ -45,10 +48,12 @@ export default () => {
   return (
     <Provider store={store}>
       <div className="App">
+        {/* <Router history={history}> */}
         <Router history={history}>
           <Switch>
             <Route exact path="/" component={RegisterForm} />
-            <Route path="/login" component={LoginForm} />
+            <Route exact path="/login" component={LoginForm} />
+            <Route exact path="/playlist" component={Playlist} />
             <PrivateRoute path="/private">
               <Lib />
             </PrivateRoute>

+ 12 - 26
src/actions/authActions.js

@@ -1,4 +1,4 @@
-import getGQL from "../utils/getGQL";
+import { gql} from "../utils/getGQL";
 import * as actions from "../constants/actions/index";
 import history from "../utils/history";
 import { clearTrackList } from "../actions/playerActions";
@@ -18,36 +18,22 @@ function actionLogOut() {
 export const logOut = () => (dispatch) => {
   dispatch(clearTrackList());
   dispatch(actionLogOut());
-  history.push("/login");
 };
 
 export const doLogin = (login, password) => async (dispatch) => {
-  // debugger
   try {
-    await getGQL(
-      "/graphql"
-      // ,{Authorization : "Bearer " + localStorage.authToken}
-    )(
-      `query Login{
-        login(login: "${login}", password: "${password}")
-        }`
+      let response = await gql(
+      `query Login($login:String!, $password:String!){
+        login(login:$login, password:$password)
+        }`,
+        {
+            login, password,
+        } 
     ).then((data) => {
-      console.log(data);
-      // console.log(data.data.login);
-
-      // localStorage.authToken = data.data.login;
-      // const token = localStorage.authToken;
-      // dispatch(actionLogIn(token));
-
-      dispatch(actionLogIn(data.data.login));
-      // const originalFetch = fetch;
-      // fetch = (url, params = { headers: {} }) => {
-      //   params.headers.Authorization = "Bearer " + localStorage.authToken;
-      //   return originalFetch(url, params);
-      // };
-      // console.log("localStorage.authToken: " + localStorage.authToken);
-    });
-  } catch (error) {
+      console.log(data)
+      return dispatch(actionLogIn(data.data.login));
+    })
+    } catch (error) {
     console.log(error);
     if (error.message.includes("Invalid token")) {
       alert("Invalid credentials!");

+ 1 - 1
src/actions/logOutActions.js

@@ -1,7 +1,7 @@
 
 // import getGQL from "../utils/getGQL";
 import * as actions from "../constants/actions/index";
-import getGQL from "../utils/getGQL";
+import {getGQL }from "../utils/getGQL";
 
 
 function actionLogOut() {

+ 112 - 61
src/actions/playerActions.js

@@ -1,4 +1,4 @@
-import getGQL from "../utils/getGQL";
+import {gql}from "../utils/getGQL";
 import * as actions from "../constants/actions/index";
 
 const setTracks = (tracks) => ({
@@ -13,82 +13,133 @@ export const setCurrentTrack = (trackIndex) => ({
 
 export const getTracks = () => async (dispatch) => {
   try {
-    let response = await getGQL("/graphql", {
-      Authorization: `Bearer ${localStorage.authToken}`,
-    })(
-      `query tracksFind($query: String!){
+    // let response = await getGQL("/graphql", {
+    //   Authorization: `Bearer ${localStorage.authToken}`,
+    // })(
+      let response = await gql(
+      `query tracksFind($query: String){
               TrackFind(query: $query){
                   _id
                   url
                   originalFileName
               }
             }`,
-      { query: JSON.stringify([{}]) }
-    );
+      {
+        query: JSON.stringify([
+          {},
+          {
+            limit: [10],
+          },
+        ]),
+      }
+    ).then((data) => {
+      console.log(data)
+      return dispatch(setTracks(data.data.TrackFind));
+    });
 
     console.log(response);
-
-    dispatch(setTracks(response.data.TrackFind));
-
-    console.log(response.data.TrackFind);
+    // dispatch(setTracks(response.data.TrackFind));
+    // console.log(response.data.TrackFind);
   } catch (error) {
     console.log(error);
   }
 };
 
 export const clearTrackList = () => ({
-  type: actions.CLEAR_TRACK_LIST
-})
-
-
-
-
-
-
-
-
-
-
-
-
+  type: actions.CLEAR_TRACK_LIST,
+});
 
+export const getPlaylist = () => async (dispatch) => {
+  try {
+    // let response = await getGQL("/graphql", {
+    //   Authorization: `Bearer ${localStorage.authToken}`,
+    // })(
+      let response = await gql(
+      `query playList{
+          PlaylistFind(query:"[{}]"){
+            _id
+            name
+            description
+            tracks{
+              url
+              id3{
+              artist
+                album
+                title
+              }
+            }
+          }
+        }`,
+      {
+        query: JSON.stringify([
+          {},
+          {
+            limit: [10],
+          },
+        ]),
+      }
+    ).then((data) => {
+      console.log(data)
+      return dispatch(setPlayList(data.data.PlaylistFind));
+
+    });
+    // console.log(response.data.PlaylistFind);
+    // dispatch(setPlayList(response.data.PlaylistFind));
+  } catch (error) {
+    console.log(error);
+  }
+};
 
+const setPlayList = (playlists) => ({
+  type: actions.SET_PLAYLISTS,
+  playlists,
+});
 
+// export const setTrack = (track) => ({
+//   type: actions.SET_TRACK,
+//   track,
+// });
 
-// export const getTracks = (state) => async (dispatch) => {
+export const setTrack = (track) => ({
+  type: actions.SET_TRACK,
+  track,
+});
 
-// // const List = ({track: {_id, url, originalFileName}}) =>
-// // <li>
-// //     <p>
-// //         <span>{originalFileName}</span>
-// //         {/* <span>{_id}</span>  */}
-// //         {/* <span>{url}</span>  */}
-// //     </p>
-// // </li>
-// const TrackList = () => {
-//   const [tracks, setTracks] = useState([]);
-//   console.log(tracks);
-//   useEffect( async () => {
-//     // {debugger}
-//     let response = await getGQL("/graphql")
-//     (`query tracksFind($query: String!){
-//         TrackFind(query: $query){
-//             _id
-//             url
-//             originalFileName
-//         }
-//       }`,{query: JSON.stringify([{}])})//накой эта строчка нужна?
-//       console.log(response);
-//       (response)? setTracks(response.data.TrackFind) : alert('data is waiting');
-//   },[])//запрос работает, нужно залогиниться, получить токен, и затем перейти во вкладку libraries.
-//   const [list, setList] = useState([]);
-//   (tracks)? setList(tracks) &&  console.log(list) : alert('data is waiting');
-//   return (
-//       <div className="trackList">
-//           <ul>
-//               {/* {(tracks)? tracks.map(track => <List track={track}/>) : alert('data is waiting')} */}
-//           </ul>
-//       </div>
-//   )
-// }
-// }
+export const oneTrackFind = (id) => async(dispatch) => {
+try{
+    // let response  = await getGQL("/graphql", {
+    //   Authorization: `Bearer ${localStorage.authToken}`,
+    // })(
+      let response = await gql(
+      `query onePlaylistTracks($query: String!){
+        PlaylistFindOne(query: $query){
+          _id
+          name
+          tracks{
+            _id
+            url
+            originalFileName
+          }  
+        }
+      }`,
+        {
+          query: JSON.stringify([{ _id: id}]),
+        }
+      ).then((data) => {
+        console.log(data)
+        return dispatch(actionSetTrack(data.data.PlaylistFindOne.tracks, data.data.PlaylistFindOne.name, data.data.PlaylistFindOne._id));
+      });
+      console.log('response: ', response);
+      // dispatch(actionSetTrack(response.data.PlaylistFindOne.tracks, response.data.PlaylistFindOne.name, response.data.PlaylistFindOne._id));
+    }catch(error){
+    }
+}
+
+export function actionSetTrack(tracks, playlistTitle, playlistId) {
+  return {
+    type: 'SET_TRACK',
+    tracks: tracks == null ? [] : tracks,
+    playlistTitle,
+    playlistId,
+  };
+}

+ 10 - 6
src/components/Header.js

@@ -3,8 +3,12 @@ import React, { useState, useEffect } from "react";
 
 import { Link } from "react-router-dom";
 import { connect } from "react-redux";
-import history from "../utils/history";
 import { logOut } from "../actions/authActions";
+import { useHistory } from "react-router-dom";
+
+
+
+
 // const mapStateToProps = (state) => ({
 //   doLogOut: !!state.auth.token,
 // });
@@ -14,10 +18,13 @@ import { logOut } from "../actions/authActions";
 // });
 
 const Header = ({ login, logOut }) => {
+  let history = useHistory();
+
   console.log(login);
 
   function onLogOut() {
     logOut();
+    history.push("/login");
   }
 
   return (
@@ -26,10 +33,10 @@ const Header = ({ login, logOut }) => {
         <li>
           <h2>gRomkoPlayer</h2>
         </li>
-        <li>
+        <li onClick={()=>history.push("/private")}>
           <h2>Library</h2>
         </li>
-        <li>
+        <li onClick={()=>history.push("/playlist")}>
           <h2>Playlist</h2>
         </li>
         <li>
@@ -39,9 +46,6 @@ const Header = ({ login, logOut }) => {
           <h2>User: {login}</h2>
           <ul className="userMenu-child">
             <li onClick={onLogOut}>
-              {/* <li onClick={doLogOut}> */}
-              {/* <Link to="/login">Log out</Link> */}
-              {/* <a href="#">Log out</a> */}
               Log out
             </li>
           </ul>

+ 6 - 5
src/components/Library.js

@@ -26,7 +26,7 @@ const Lib = ({
     getTracks && getTracks();
   }, []);
 
-  const Track = ({ track, highlighted }) => {
+  const Track = ({ track, highlighted, }) => {
     const { originalFileName, url, _id, trackIndex } = track;
     return (
       <li
@@ -47,12 +47,13 @@ const Lib = ({
       <div className="main">
         <div className="trackList">
           <ul>
-            {playlist.map((track, trackIndex) => (
+            { playlist.map((track, trackIndex) => (
+              (track.originalFileName && track.url && track._id !==null)? 
               <Track
                 key={trackIndex}
                 track={{ ...track, trackIndex }}
                 highlighted={trackIndex === currentTrack}
-              />
+              /> : ''
               // console.log(track)
             ))}
           </ul>
@@ -63,7 +64,7 @@ const Lib = ({
   };
 
   return (
-    <>
+    <div className="wrapper">
       <Header login={login} />
       {!tracks.length && (
         <div className="container">
@@ -72,7 +73,7 @@ const Lib = ({
       )}
       <TrackList playlist={tracks} currentTrack={currentTrack} />
       <Footer />
-    </>
+    </div>
   );
 };
 

+ 2 - 2
src/components/LoginForm.js

@@ -15,7 +15,6 @@ import "../styles/RegisterForm.css";
 import { doLogin } from "../actions/authActions";
 
 // import { BrowserRouter as Router, Route } from 'react-router-dom';
-// import createHistory from 'history/createBrowserHistory';
 
 // const history = createHistory()
 
@@ -110,7 +109,8 @@ const LoginForm = ({ store, history, doLogin, isLoggedIn }) => {
           <Form.Item>
             <Button 
             type="primary" 
-            htmlType="submit" 
+            htmlType="submit"
+            disabled={!login || !password}
             onClick={onLogin}
             >
               Submit

+ 16 - 4
src/components/Player.js

@@ -1,12 +1,15 @@
 import React, { useState, useEffect } from "react";
 import Library from "./Library";
 import { connect } from "react-redux";
+import Playlist from "../components/Playlist";
 
 import "../styles/player.css";
 import { setCurrentTrack } from "../actions/playerActions";
 
 // this.props.playlist
-const Player = ({ playlist, currentTrack, setCurrentTrack }) => {
+const Player = ({ playlist, track, currentTrack, setCurrentTrack, turl }) => {
+  console.log(playlist)
+  console.log(track)
   const [isAutoplayed, setIsAutoplayed] = useState(true);
 
   function goPrevTrack() {
@@ -20,14 +23,21 @@ const Player = ({ playlist, currentTrack, setCurrentTrack }) => {
 
   return (
     <div className="player">
+                {/* {console.log(playlist[currentTrack])} */}
       <button className="prevTrack" onClick={goPrevTrack}></button>
-      {!!playlist.length && (
         <audio
           controls
-          src={playlist[currentTrack] && playlist[currentTrack].url}
+            src={    playlist &&         
+              // turl || 
+              playlist[currentTrack] && playlist[currentTrack].url ? playlist[currentTrack].url : turl
+            } 
+            // src={playlist[currentTrack].url}
+            // src={track[currentTrack] && track[currentTrack].url}
+          
+          // src={playlist[currentTrack] && playlist[currentTrack].url}
+          // src={track[currentTrack] && track[currentTrack].url}
           autoPlay={isAutoplayed}
         />
-      )}
       <button className="nextTrack" onClick={goNextTrack}></button>
     </div>
   );
@@ -35,10 +45,12 @@ const Player = ({ playlist, currentTrack, setCurrentTrack }) => {
 
 const mapStateToProps = (state) => ({
   currentTrack: state.player.currentTrack,
+  // currentTrack: state.playlistTrackReducer. ...,
 });
 
 const mapDispatchToProps = (dispatch) => ({
   setCurrentTrack: (trackIndex) => dispatch(setCurrentTrack(trackIndex)),
 });
 
+
 export default connect(mapStateToProps, mapDispatchToProps)(Player);

+ 217 - 0
src/components/Playlist.js

@@ -0,0 +1,217 @@
+import React, { useState, useEffect } from "react";
+import {
+  getPlaylist,
+  setTrack,
+  setCurrentTrack,
+  oneTrackFind,
+  actionSetTrack,
+} from "../actions/playerActions";
+// import { getPlaylist } from "../actions/playerActions";
+import { connect } from "react-redux";
+import * as actions from "../constants/actions/index";
+import Player from "./Player";
+import Library from "./Library";
+import store from "../store";
+
+import { Spin } from "antd";
+
+import Header from "./Header";
+import Footer from "./Footer";
+
+import "../styles/library.css";
+import "../styles/playlists.css";
+
+const Playlist = ({
+  actionOneTrackFind,
+  actionSetTrack,
+  state,
+  getPlaylist,
+  setTrack,
+  playlists = [],
+  // track,
+  playlistitem,
+  highlighted,
+  setCurrentTrack,
+  currentTrack,
+  oneTrackFind,
+}) => {
+  const [getTrack, setGetTrack] = useState([]);
+  console.log(state.player.playlists);
+  const Track = ({ track, dispatch }) => {
+    //выводм по треку из плейлиста
+    // const setTrack = ()=>{
+
+    // }
+    // dispatch(setTrack(track));
+    // let artist = "";
+    // let album = "";
+    // if (track.id3) {
+    //   if (track.id3.artist && track.id3.album) {
+    //     artist = track.id3.artist;
+    //     album = track.id3.album;
+    //   } else {
+    //   }
+    // } else {
+    // }
+    const [addTrack, setAddTrack] = useState()
+    const [prevTrack, setPrevTrack] = useState()
+    return( 
+      <>
+    {track.id3 ? (
+      track.id3.artist && track.id3.album ? (
+        <li onClick={(e) => 
+         setAddTrack(track.url)
+        // setCurrentTrack(e.target.id)
+         }>
+          <span>{track.id3.artist}</span>
+          <span>{track.id3.album}</span>
+        </li>
+      ) : (
+        ""
+      )
+    ) : (
+      ""
+    )}
+    {setPrevTrack(addTrack)}
+    {addTrack? <Player turl={addTrack} /> : <Player turl={prevTrack} />}
+    </>
+    );
+  };
+
+  const Tracks = ({
+    playlistsItem,
+    highlighted,
+    actionSetTrack,
+    actionOneTrackFind,
+  }) => {
+    //выводм по плейлисту из общего плейлиста(хранилища)
+    const { _id, name, tracks, trackIndex } = playlistsItem;
+    let arr =
+      playlistsItem && playlistsItem.tracks
+        ? playlistsItem.tracks.filter(
+            (track) => track.id3 && track.id3.artist && track.id3.album
+          )
+        : [];
+    // setGetTrack(arr);
+    // {
+    //     if (track.id3 && track.id3.artist && track.id3.album) {
+    //       return true; //оставляем в массиве
+    //     } else {
+    //       return false; //удалаяем из массива
+    //     }
+    //   })
+    // [];
+    return (
+      <>
+        {arr.length > 0 ? (
+          <li
+            id={_id}
+            onMouseEnter={
+              (e) => {
+                console.dir(e.target);
+                return actionOneTrackFind(e.target.id);
+              }
+              // console.log(e.target.id);
+
+              // return store.dispatch(actionSetTrack(, e.target.firstChild.data, e.target.id))
+            }
+            className={highlighted ? "highlighted" : null}
+            // onClick={(e) => setCurrentTrack(trackIndex)}
+            // onClick={() => {
+            // }}
+          >
+            {name}
+            <ul
+              className="playlist_item"
+              // onMouseOver={(e)=> {
+              //   // console.dir(e.target);
+              //   return actionOneTrackFind(e.target.parentElement.id)
+              // }}
+              // onMouseOver={(e)=> actionOneTrackFind(e.target.id)
+            >
+              {playlistsItem.tracks
+                ? arr.map((track) => <Track track={track} />)
+                : ""}
+            </ul>
+          </li>
+        ) : (
+          ""
+        )}
+      </>
+    );
+  };
+
+  useEffect(() => {
+    getPlaylist && getPlaylist();
+  }, []);
+  console.log(playlists);
+  useEffect(() => {
+    setTrack && setTrack();
+  }, []);
+  return (
+    <div className="wrapper">
+      <Header />
+      {!playlists.length && (
+        <div className="container">
+          <Spin size="large" />
+        </div>
+      )}
+      <div className="main">
+        <div className="trackList">
+          <ul className="playlists">
+            {/* onClick={(item)=>{item.tracks}} */}
+            {playlists.map((playlistsItem) =>
+              playlistsItem &&
+              playlistsItem.tracks &&
+              playlistsItem.tracks.length > 0 ? (
+                <Tracks
+                  playlistsItem={playlistsItem}
+                  actionOneTrackFind={actionOneTrackFind}
+                />
+              ) : (
+                ""
+              )
+            )}
+          </ul>
+        </div>
+      </div>
+      {/* <Player track={getTrack} /> */}
+      {/* <Player playlist={playlist} /> */}
+      {/* <Player playlist={tracks} /> */}
+      <Footer />
+    </div>
+  );
+};
+
+const mapDispatchToProps = (dispatch) => ({
+  getPlaylist: () => dispatch(getPlaylist()),
+  // oneTrackFind: ()=> dispatch(oneTrackFind()),
+  actionOneTrackFind: oneTrackFind,
+
+  // setTrack: () => dispatch(setTrack),
+});
+
+const mapDispatchToProps2 = {
+  getPlaylist: getPlaylist,
+  actionOneTrackFind: oneTrackFind,
+};
+
+const mapStateToProps = (state) => ({
+  playlists: state && state.player && state.player.playlists,
+  state: state,
+  // track: state.player.track,
+  // login: (state.auth.data.data && state.auth.data.data.sub.login) || "",
+});
+
+// const mapStateToProps = (state) => ({
+//   tracks: state.player.tracks,
+//   currentTrack: state.player.currentTrack,
+//   login: (state.auth.data.data && state.auth.data.data.sub.login) || "",
+// });
+
+// const mapDispatchToProps = (dispatch) => ({
+//   getPlaylist: () => dispatch(getPlaylist()),
+//   setCurrentTrack: (trackIndex) => dispatch(setCurrentTrack(trackIndex)),
+// });
+
+export default connect(mapStateToProps, mapDispatchToProps2)(Playlist);

+ 7 - 7
src/components/RegisterForm.js

@@ -4,8 +4,7 @@ import { UserOutlined, LockOutlined } from "@ant-design/icons";
 import { Link } from 'react-router-dom';
 
 // import { BrowserRouter as Router, Route } from 'react-router-dom';
-// import createHistory from 'history/createBrowserHistory';
-import getGQL from "../utils/getGQL";
+import {getGQL, url, headers }from "../utils/getGQL";
 
 import "../styles/RegisterForm.css";
 
@@ -88,17 +87,18 @@ export default ({store, history}) => {
 
           <Form.Item>
             <Button type="primary" htmlType="submit"
-            disabled = {password !== confPassword ? true : false}
+            disabled = {password !== confPassword}
             onClick={async () => {
-              await getGQL("/graphql")(
+              // await getGQL("/graphql")(
+                let response = await getGQL(url)(
                 `mutation User{
                 createUser (login: "${login}", password: "${password}"){
                 _id login
                   }
               }`
-              ).then((data) => {
-                console.log(data);
-                if (!data.errors && login && password) {
+              ).then((response) => {
+                console.log(response);
+                if (!response.errors && login && password) {
                   history.push("/login");
                 } else {
                 }

+ 5 - 1
src/constants/actions/index.js

@@ -5,4 +5,8 @@ export const SET_TRACKS = "SET_TRACKS";
 
 export const SET_CURRENT_TRACK = "SET_CURRENT_TRACK";
 
-export const CLEAR_TRACK_LIST = "CLEAR_TRACK_LIST";
+export const CLEAR_TRACK_LIST = "CLEAR_TRACK_LIST";
+
+export const SET_PLAYLISTS = "SET_PLAYLISTS";
+
+export const SET_TRACK = "SET_TRACK";

+ 5 - 1
src/reducers/authReducer.js

@@ -1,5 +1,6 @@
 import jwt_decode from "jwt-decode";
 import * as actions from "../constants/actions/index";
+import {getGQL, url, headers}from "../utils/getGQL";
 
 const initialState = {
   data: {},
@@ -22,7 +23,10 @@ let authReducer = (state = initialState, action) => {
 
     case actions.LOGOUT:
       localStorage.authToken = "";
-      return { ...state, data: initialState.data };
+      // headers = {}
+      return { ...state,
+         data: initialState.data, 
+        token: initialState.token};
 
     default:
       return { ...state };

+ 22 - 2
src/reducers/playerReducer.js

@@ -1,9 +1,23 @@
 import * as actions from "../constants/actions/index";
 
-const initialState = { tracks: [], currentTrack: {} };
+const initialState = {
+  tracks: [],
+  track: [],
+  currentTrack: {},
+  playlist: [],
+};
 
-export default (state = initialState, { type, tracks, trackIndex }) => {
+export default (
+  state = initialState,
+  { type, tracks, track, trackIndex, playlists }
+) => {
   switch (type) {
+    // case actions.SET_TRACK:
+    //   return {
+    //     ...state,
+    //     track,
+    //   };
+
     case actions.SET_TRACKS:
       return {
         ...state,
@@ -23,6 +37,12 @@ export default (state = initialState, { type, tracks, trackIndex }) => {
         tracks: [],
       };
 
+    case actions.SET_PLAYLISTS:
+      return {
+        ...state,
+        playlists,
+      };
+
     default:
       return { ...state };
   }

+ 29 - 0
src/reducers/playlistTrackReducer.js

@@ -0,0 +1,29 @@
+import * as actions from "../constants/actions/index";
+
+// switch (type){
+//     case actions.SET_TRACK:
+//     return {
+//         // ...state,
+//         track,
+//         playlistTitle,
+//         [playlistId]: [...(state[playlistId] || []), ...tracks],
+//     }
+//     default:
+//         return { ...state };
+// }
+
+export default function playlistTrackReducer(state, action) {
+  if (state === undefined) {
+    return {};
+  }
+  if (action.type === 'SET_TRACK') {
+    const { tracks, playlistTitle, playlistId } = action;
+    return {
+      // ...state,
+      track,
+      playlistTitle,
+      [playlistId]: [...(state[playlistId] || []), ...tracks],
+    };
+  }
+  return state;
+}

+ 4 - 1
src/store.js

@@ -6,4 +6,7 @@ const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
 
 const enhancer = composeEnhancers(applyMiddleware(thunk));
 
-export default createStore(mainReducer, enhancer); //вторым параметром идет
+const store = createStore(mainReducer, enhancer); //вторым параметром идет
+
+
+export default store;

+ 1 - 0
src/styles/Reset.css

@@ -24,6 +24,7 @@ time, mark, audio, video {
 	vertical-align: baseline;
 	margin: 0;
 	padding-inline-start: 0;
+	/* width: 100%; */
 }
 /* HTML5 display-role reset for older browsers */
 article, aside, details, figcaption, figure, 

+ 32 - 80
src/styles/library.css

@@ -5,23 +5,12 @@
     /* align-items: center; */
     width: 100%;
     top: 0;
-    /* left: 0;
-    right: 0; */
+    left: 0;
+    right: 0;
     position: fixed;
-    z-index:1;
+    z-index:5;
 }
 
-/* .header ul {
-    display: flex;
-    justify-content: center;
-    align-items: center;
-} */
-
-/* .header ul>li{
-    list-style-type: none;
-    width: 300px; 
-} */
-
 .mainMenu {
     display: flex;
     justify-content: center;
@@ -65,11 +54,14 @@
 .userMenu-child {
     top: 50px;
 }
-
+.wrapper {
+    width: 100%;
+    height:100%;
+    /* background: url("../images/girl.jpg");
+    background-attachment: fixed; */
+}
 .main{
     display: flex;
-    /* position:relative; */
-    flex-grow: 1;
     width: 100%;
     background: url("../images/girl.jpg");
     background-attachment: fixed;
@@ -91,37 +83,43 @@
 } */
 
 .trackList {
-    /* padding-top: 90px; */
     flex-grow: 1;
-    padding: 155px 0px 100px;
-    /* background: url("../images/girl.jpg"); */
+    padding: 65px 0px 100px;
     width: 100%;
     display: flex;
     justify-content: center;
     font-weight: bold;
     font-size: 20px;
 }
-
-.trackList ul>li {
-    padding: 5px;
+.trackList ul {
+    /* display: flex;
+    justify-content: center; */
+    width: 100%;
+    /* padding: 5px; */
 }
-
-.trackList ul>li:hover {
-    background-color: #85C0FF;
-    cursor: pointer;
+/* .trackList ul>li {
     display: flex;
+    padding: 5px;
     justify-content: center;
-    transition-duration: 0.2s
-}
+} */
 
+/* .trackList ul>li:hover {
+    display: flex;
+    background-color: #85C0FF;
+    cursor: pointer;
+    justify-content: center; */
+    /* transform: scale(1.1); */
+    /* transition-duration: 0.2s;
+    color: rgb(11, 9, 49);
+} */
+/* .trackList ul>li:hover 
+.trackList ul {
+        width: 90%;
+} */
 .highlighted {
     background-color: #335C81;
 }
 
-/* .mainMenu h2 {
-    margin-bottom: 0em;
-} */
-
 .footer {
     display: flex;
     border: 1px solid black;
@@ -134,6 +132,7 @@
     right: 0;
     bottom: 0;
     position: fixed;
+    z-index:5;
 }
 
 .container {
@@ -149,50 +148,3 @@
     text-align: center;
     background: rgba(0, 0, 0, 0.692);
 }
-
-
-/* .userMenu:hover {
-    top: 0;
-} */
-/*     position: absolute;
-    color: #fff;
-    background-color: grey;
-    border: none;
-    transform-origin: 0% 100%;
-    transform: rotate(90deg);
-    margin-top: 120px;
-    margin-left: 179px;
-    font-size: 16px;
-    line-height: 17px;
-    font-family: 'Times New Roman', Times, serif; */
-/* ///////////////////////// */
-/* .mainmenubtn {
-    background-color: red;
-    color: white;
-    border: none;
-    cursor: pointer;
-    padding:5px;
-}
-
-.mainmenubtn:hover {
-    background-color: red;
-    }
-    
-.dropdown {
-    position: relative;
-    display: inline-block;
-}
-.dropdown-child {
-    display: none;
-    background-color: black;
-    min-width: 10px;
-}
-.dropdown-child a {
-    color: white;
-    padding: 5px;
-    text-decoration: none;
-    display: block;
-}
-.dropdown:hover .dropdown-child {
-    display: block;
-} */

+ 48 - 0
src/styles/playlists.css

@@ -0,0 +1,48 @@
+/* .playlists {
+    flex-grow: 1;
+    padding: 155px 0px 100px;
+    width: 100%;
+    display: flex;
+    justify-content: center;
+    font-weight: bold;
+    font-size: 20px;
+}
+
+.playlists ul>li {
+    padding: 5px;
+}
+
+.playlists ul>li:hover {
+    background-color: #85C0FF;
+    cursor: pointer;
+    display: flex;
+    justify-content: center;
+    transition-duration: 0.2s
+}
+
+.highlighted {
+    background-color: #335C81;
+} */
+
+.playlists >li:hover
+.playlist_item
+{
+    display:block;
+    position: relative;
+    display: inline-block;
+    /* flex-wrap: wrap; */
+}
+
+.playlist_item{
+    display: none;
+    position: absolute;
+    /* background-color: #f9f9f9;
+    min-width: 160px;
+    box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
+    padding: 12px 16px; */
+    z-index: 1;
+    /* flex-wrap: wrap; */
+}
+
+
+

+ 27 - 1
src/utils/getGQL.js

@@ -1,4 +1,17 @@
-export default (url, headers = {}) => (query = "", variables = {}) =>
+export const url = "/graphql";
+export const headers = {
+  Authorization: "Bearer " + localStorage.authToken,
+};
+
+// const originalFetch = fetch;
+// fetch = (
+//   url,
+//   params = {
+//     headers: {},
+//   }
+// )
+
+export const getGQL = (url, headers = {}) => (query = "", variables = {}) =>
   fetch(url, {
     method: "POST",
     headers: {
@@ -8,3 +21,16 @@ export default (url, headers = {}) => (query = "", variables = {}) =>
     },
     body: JSON.stringify({ query, variables }),
   }).then((res) => res.json());
+
+  export const gql = getGQL(url, headers);
+
+
+//когда проходит разлогин, то токен удаляется!!!!
+//localStorage.AuthTocken = ""-- something like this shold be
+//When sheet happen, first of all check your code
+//getGQL()() first we call function getGQL (getGQL()), after that we call the retsul of function ()
+
+
+
+
+// const 

+ 4 - 2
src/utils/history.js

@@ -1,3 +1,5 @@
-import createHistory from "history/createBrowserHistory";
+// import createHistory from "history/createBrowserHistory";
+import createBrowserHistory from "history/createBrowserHistory";
 
-export default createHistory()
+
+export default createBrowserHistory()