mfdok43 2 yıl önce
ebeveyn
işleme
ba537b6501

+ 15 - 1
src/App.scss

@@ -45,8 +45,22 @@ main {
 }
 
 footer {
-  height: 200px;
+  width: 100%;
   background-color: #303030;
+  position: fixed;
+ bottom: 0px;
+  .Player {
+    background: white;
+
+    button {
+      margin: 5px;
+    }
+
+    .currentTime {
+      width: 30%;
+    }
+
+  }
 }
 
 

+ 2 - 0
src/actions/gql-queries-backurl.js

@@ -1,4 +1,6 @@
 
+
+
 export const getGQL = url =>
     async (query, variables = {}) => {
         let obj = await fetch(url, {

+ 2 - 1
src/pages/footer.js

@@ -1,7 +1,8 @@
 import {Logo} from "./header";
+import {CPlayer} from "./player";
 
 export const Footer = () =>
     <footer>
         <Logo />
-        <h2>Тут будет всякое</h2>
+        <CPlayer />
     </footer>

+ 1 - 1
src/pages/index.js

@@ -5,4 +5,4 @@ export {UserTracks,CAllTracks,CAllUsers} from "./user-tracks";
 export {CMyPlaylists,MyPlaylistTracks,NoPlaylistMytracks} from "./my-tracks";
 export {CTrack} from "./track";
 export {CPlaylistDropZone,CTrackDropZone} from "./tools";
-
+export {CPlayer} from "./player";

+ 55 - 20
src/pages/my-tracks/my-tracks.js

@@ -6,41 +6,76 @@ import {arrayMoveImmutable} from 'array-move';
 import {useState,useEffect} from "react";
 import {CPreloaded} from "../preloader";
 
-const SortableItem = SortableElement(CTrack);
 
-const MyTracks = ( {children}) =>
+
+
+
+
+const MyTracks = ({playlist:{_id, name, tracks}={}}) =>
     <div className='Category'>
-        {children}
+        <h1>{name}</h1>
+        {(tracks || []).map(track => <CTrack track={track}/>)}
     </div>
-const SortableList = SortableContainer(MyTracks)
-// const CMyTracks = connect(state => ({playlist: state.promise.playlistById?.payload || []}))(MyTracks)
+
+const CMyTracks = connect(state => ({playlist: state.promise.playlistById?.payload || []}))(MyTracks)
 
 
 export const MyPlaylistTracks = ({match:{params:{_id}}}) =>
     <>
         <CPlaylistDropZone >
             <CPreloaded promiseName='playlistById'>
-            <CSortableComponent />
+            <CMyTracks />
             </CPreloaded>
      </CPlaylistDropZone >
     </>
 
 
-function SortableComponent({tracks=[]}) {
-    const [state, setState] = useState(tracks)
-    useEffect(() => {
-        setState (tracks)
-    },[tracks])
-    const onSortEnd = ({oldIndex, newIndex}) => {
-        setState((state) => (arrayMoveImmutable(state, oldIndex, newIndex)));
-    };
 
-    return <SortableList tracks={tracks} onSortEnd={onSortEnd}>
-        {state.map((value, index) => <SortableItem key={`item-${value}`} index={index} track={value}/>)}
-        {/*{console.log(state)}*/}
-    </SortableList>;
-}
 
-const CSortableComponent = connect(state => ({tracks: state.promise.playlistById?.payload?.tracks || []}))(SortableComponent)
+
+
+
+
+
+
+
+
+
+// const SortableItem = SortableElement(CTrack);
+//
+// const MyTracks = ( {children}) =>
+//     <div className='Category'>
+//         {children}
+//     </div>
+// const SortableList = SortableContainer(MyTracks)
+// // const CMyTracks = connect(state => ({playlist: state.promise.playlistById?.payload || []}))(MyTracks)
+//
+//
+// export const MyPlaylistTracks = ({match:{params:{_id}}}) =>
+//     <>
+//         <CPlaylistDropZone >
+//             <CPreloaded promiseName='playlistById'>
+//             <CSortableComponent />
+//             </CPreloaded>
+//      </CPlaylistDropZone >
+//     </>
+//
+//
+// function SortableComponent({tracks=[]}) {
+//     const [state, setState] = useState(tracks)
+//     useEffect(() => {
+//         setState (tracks)
+//     },[tracks])
+//     const onSortEnd = ({oldIndex, newIndex}) => {
+//         setState((state) => (arrayMoveImmutable(state, oldIndex, newIndex)));
+//     };
+//
+//     return <SortableList tracks={tracks} onSortEnd={onSortEnd}>
+//         {state.map((value, index) => <SortableItem key={`item-${value}`} index={index} track={value}/>)}
+//         {/*{console.log(state)}*/}
+//     </SortableList>;
+// }
+//
+// const CSortableComponent = connect(state => ({tracks: state.promise.playlistById?.payload?.tracks || []}))(SortableComponent)
 
 

+ 47 - 24
src/pages/my-tracks/no-playlist-mytracks.js

@@ -9,44 +9,67 @@ import {SortableContainer, SortableElement} from "react-sortable-hoc";
 import {CPreloaded} from "../preloader";
 
 
+const Mytracks = ({tracks={}}) => {
 
-const SortableItem = SortableElement(CTrack);
-
-const MyTracks = ({children}) =>
+    return(
         <div>
-            {children}
+            {tracks.map(track => <CTrack track={track}/> )}
         </div>
+    )
+}
+export const CMyTracks = connect(state => ({tracks: state.promise.findMyTracks1?.payload || []}))(Mytracks)
 
 
-const SortableList = SortableContainer(MyTracks)
-// export const CMyTracks = connect(state => ({tracks: state.promise.findMyTracks1?.payload || []}))(MyTracks)
-
 export const NoPlaylistMytracks = () =>
     <div>
     <h1>Моя музыка</h1>
         <CTrackDropZone>
             <CPreloaded promiseName='findMyTracks1'>
-            <CSortableComponent />
+            <CMyTracks />
             </CPreloaded>
         </CTrackDropZone>
     </div>
 
 
-function SortableComponent({tracks=[]}) {
-    const [state, setState] = useState(tracks)
-    useEffect(() => {
-        setState (tracks)
-    },[tracks])
-    const onSortEnd = ({oldIndex, newIndex}) => {
-        setState((state) => (arrayMoveImmutable(state, oldIndex, newIndex)));
-    };
-
-    return <SortableList tracks={tracks} onSortEnd={onSortEnd}>
-        {state.map((value, index) => <SortableItem key={`item-${value}`} index={index} track={value}/>)}
-    </SortableList>;
-}
-
-const CSortableComponent = connect(state => ({tracks: state.promise.findMyTracks1?.payload || []}))(SortableComponent)
 
-store.dispatch(actionFindMyTracks())
+//
+// const SortableItem = SortableElement(CTrack);
+//
+// const MyTracks = ({children}) =>
+//         <div>
+//             {children}
+//         </div>
+//
+//
+// const SortableList = SortableContainer(MyTracks)
+// // export const CMyTracks = connect(state => ({tracks: state.promise.findMyTracks1?.payload || []}))(MyTracks)
+//
+// export const NoPlaylistMytracks = () =>
+//     <div>
+//     <h1>Моя музыка</h1>
+//         <CTrackDropZone>
+//             <CPreloaded promiseName='findMyTracks1'>
+//             <CSortableComponent />
+//             </CPreloaded>
+//         </CTrackDropZone>
+//     </div>
+//
+//
+// function SortableComponent({tracks=[]}) {
+//     const [state, setState] = useState(tracks)
+//     useEffect(() => {
+//         setState (tracks)
+//     },[tracks])
+//     const onSortEnd = ({oldIndex, newIndex}) => {
+//         setState((state) => (arrayMoveImmutable(state, oldIndex, newIndex)));
+//     };
+//
+//     return <SortableList tracks={tracks} onSortEnd={onSortEnd}>
+//         {state.map((value, index) => <SortableItem key={`item-${value}`} index={index} track={value}/>)}
+//     </SortableList>;
+// }
+//
+// const CSortableComponent = connect(state => ({tracks: state.promise.findMyTracks1?.payload || []}))(SortableComponent)
+//
+// store.dispatch(actionFindMyTracks())
 

+ 46 - 0
src/pages/player.js

@@ -0,0 +1,46 @@
+import play from '../play.svg'
+import pause from '../pause.svg'
+import next from '../next.svg'
+import prev from '../prev.svg'
+import {connect} from "react-redux";
+import {actionTrackPlay, actionTrackStop,actionTrackVolume,actionTrackCurrentTime} from "../reducers";
+
+
+export const Player = ({player:{volume,duration,currentTime},
+                                trackPlay, trackStop,trackVolume,trackCurrentTime}) => {
+    return (
+        <div className='Player'>
+
+            <input className='currentTime'
+                type="range"
+                min={0}
+                step={0.1}
+                max={duration ? duration : `${duration}`}
+                onChange={(e) => trackCurrentTime(e.target.value)}
+                value={currentTime}/>
+
+            <button><img src={prev}/></button>
+
+            <button onClick={() => trackPlay()}>
+                <img src={play}/></button>
+
+            <button onClick={() => trackStop()}>
+                <img src={pause}/></button>
+
+            <button><img src={next}/></button>
+            <input
+                type="range"
+                min={0}
+                step={0.1}
+                max={1}
+                onChange={(e) => trackVolume(e.target.value)}
+                value={volume}/>
+        </div>
+    )
+}
+
+export const CPlayer = connect(state => ({player: state.player}),
+    {trackPlay: actionTrackPlay,
+                     trackStop: actionTrackStop,
+                     trackVolume:actionTrackVolume,
+                     trackCurrentTime:actionTrackCurrentTime})(Player)

+ 2 - 5
src/pages/tools/playlistdropzone.js

@@ -13,14 +13,11 @@ function PlaylistDropZone({playlist={}, onLoad, children }) {
             ...acceptedFiles
         ])
         onLoad(files.current);
-
-    }, [onLoad]);
-      // }, []);
-    const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });
+       }, []);
+    const { getRootProps, isDragActive } = useDropzone({ onDrop });
 
     return (
         <div {...getRootProps()}>
-            <input {...getInputProps()} />
             {isDragActive ? (
                 <p>Перетащите файл сюда ...</p>
             ) : (

+ 1 - 3
src/pages/tools/trackdropzone.js

@@ -9,11 +9,9 @@ function TrackDropZone({ onLoad, children }) {
         // Do something with the files
         onLoad(acceptedFiles);
     }, []);
-    const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });
-
+    const { getRootProps, isDragActive } = useDropzone({ onDrop });
     return (
         <div {...getRootProps()}>
-            <input {...getInputProps()} />
             {isDragActive ? (
                 <p>Перетащите файл сюда ...</p>
             ) : (

+ 13 - 20
src/pages/track.js

@@ -1,36 +1,28 @@
 import {useState,useEffect,useRef} from "react";
 import play from '../play.svg'
 import pause from '../pause.svg'
-import {store,actionTrackPlay,actionTrackStop} from "../reducers";
+import {store,actionTrackPlay,actionTrackStop,actionFullSetPlaylist} from "../reducers";
 import {connect} from "react-redux";
 import {backURL} from "../actions";
 
 
-export const Track = ({track:{id,url,originalFileName}}) => {
+export const Track = ({playlist=['fdgdf','dgdfgfd','dgdfgdfgdf'],track:{_id,url,originalFileName},
+                          trackPlay,trackStop,setPlaylist}) => {
 
     let audioSrc = backURL + '/'+ url
-    const [isPlaying, setIsPlaying] = useState(false);
-    const audioRef = useRef(new Audio(audioSrc));
-
-    useEffect(() => {
-        if (isPlaying) {
-            audioRef.current.play();
-        } else {
-            audioRef.current.pause();
-        }
-    }, [isPlaying]);
 
     return (
         <div className='Tracks'>
-            {isPlaying ? (
-                <button onClick={() => setIsPlaying(false)}>
-                    <img src={pause}/>
-                </button>
-            ) : (
-                <button onClick={() => setIsPlaying(true)}>
+                <button onClick={() => {
+                    trackPlay(audioSrc);
+                    // setTimeout(setPlaylist(playlist),5000)
+                      setPlaylist()
+                }}>
                     <img src={play}/>
                 </button>
-            )}
+                <button onClick={() => trackStop()}>
+                    <img src={pause}/>
+                </button>
             <span>{originalFileName}</span>
         </div>
     )
@@ -38,4 +30,5 @@ export const Track = ({track:{id,url,originalFileName}}) => {
 
 
 
-export const CTrack = connect(null, {trackPlay: actionTrackPlay, trackStop: actionTrackStop})(Track)
+export const CTrack = connect(state => ({playlist: state.promise.playlistById?.payload?.tracks || []}),
+    {trackPlay: actionTrackPlay, trackStop: actionTrackStop,setPlaylist:actionFullSetPlaylist})(Track)

+ 4 - 1
src/reducers/index.js

@@ -1,5 +1,8 @@
 export {store} from './store'
 export {actionPromise} from './promiseReducer'
-export {playerReducer,actionTrackPlay,actionTrackStop} from "./playerReducer";
+
+export {playerReducer,actionTrackPlay,actionTrackStop,
+    actionTrackVolume,actionTrackCurrentTime,actionFullSetPlaylist} from "./playerReducer";
+
 export {actionAuthLogin, actionAuthLogout} from './authReducer'
 export {CProtectedRoute} from "./routeReducer";

+ 104 - 21
src/reducers/playerReducer.js

@@ -1,34 +1,117 @@
-export function playerReducer(state={},{
-    type,
-    isPlaying=false,
-    isStopped,
-    duration,
-    track,
-    // playlist: {_id, name, tracks},
-    playlistIndex,
-    currentTime=0,
-    volume,
-}) {
-
-    if (type === 'TRACK_PLAY') {
+import {store} from "./store";
+import {actionPromise} from "./promiseReducer";
+import {gql} from "../actions";
+
+export const playerReducer = (
+    state = {},
+    {type,track,isPlaying=false,isPaused,duration,
+        playlist=[],playlistIndex,currentTime=0,volume=1,}) => {
+
+    if (type === "TRACK_PLAY") {
         return {
             ...state,
             isPlaying,
-            isStopped: !isPlaying,
+            isPaused: !isPlaying,
+        };
+    }
+
+    if (type === "TRACK_STOP") {
+        return {
+            ...state,
+            isPaused,
+            isPlaying: !isPaused,
+        };
+    }
+
+    if (type === "TRACK_VOLUME") {
+        return {
+            ...state,
+            volume,
         };
     }
-    if (type === 'TRACK_STOP') {
+
+    if (type === "TRACK_DURATION") {
+        return {
+            ...state,
+            duration,
+        };
+    }
+
+    if (type === "TRACK_CURRENT_TIME") {
         return {
             ...state,
-            isStopped,
-            isPlaying: !isStopped,
+            currentTime,
         };
     }
 
-    return state
+    if (type === "SET_PLAYLIST") {
+        return {
+            ...state,
+            playlist,
+        };
+    }
+    return state;
+};
+
+
+
+const audio = new Audio()
+
+
+
+export const actionTrackPlay = (audioSrc) => {
+    audio.src = audioSrc
+    audio.load()
+    audio.ondurationchange = function(){actionSetDuration()}
+    audio.ontimeupdate = function(){actionTrackCurrentTime()}
+    audio.play()
+    store.dispatch({type:"TRACK_PLAY",isPlaying:true,isPaused:false})
+    store.dispatch(actionFullSetPlaylist())
+}
+
+
+export const actionTrackStop = () => {
+    audio.pause()
+    store.dispatch({type:"TRACK_STOP",isPlaying:false,isPaused:true})
+}
+
+
+export const actionTrackVolume = (e) => {
+    audio.volume = e
+    store.dispatch({type:"TRACK_VOLUME", volume:e})
 }
 
-export const actionTrackPlay = (track,isPlaying) => ({type: "TRACK_PLAY",isPlaying: track.play()})
-export const actionTrackStop = (track,isStopped) => ({type: "TRACK_PLAY",isStopped: track.pause()})
 
-//все сломалось
+export const actionSetDuration = () => {
+    let e = audio.duration
+    store.dispatch({type:"TRACK_DURATION",duration:e})
+}
+
+export const actionTrackCurrentTime = () => {
+    let e = audio.currentTime
+    store.dispatch({type:"TRACK_CURRENT_TIME", currentTime:e})
+}
+
+const actionSetPlaylist = (tracks) => {
+    console.log(tracks)
+        store.dispatch({type:"SET_PLAYLIST",playlist:tracks})
+    }
+
+
+
+const actionPlaylistByIdForPlayer = (match) =>
+    actionPromise('playlistByIdForPlayer', gql(`query playlistByIdForPlayer($q: String){
+    PlaylistFindOne(query: $q){
+        _id name owner {login} tracks {_id url originalFileName}
+    }
+}`, { q: JSON.stringify([{ _id: match.params._id}]) }))
+
+
+
+export const actionFullSetPlaylist = (_id) =>
+    async function i(dispatch) {
+        let playlist = await dispatch(actionPlaylistByIdForPlayer(_id));
+        if (playlist) {
+            dispatch(actionSetPlaylist(playlist));
+        }
+    }