Browse Source

playlist to queue, styles

Stepanova Asya 1 year ago
parent
commit
6f6fa54e2b

+ 27 - 23
src/components/EditPlaylistModal.js

@@ -3,6 +3,7 @@ import Modal from 'react-bootstrap/Modal';
 import React, {useState} from 'react';
 // import { sendForm } from './LoadTrackModal';
 import { sendForm } from './SendForm';
+import {Form, Image} from "react-bootstrap";
 
 
 export function EditPlaylistModal  (props)  {
@@ -22,38 +23,41 @@ export function EditPlaylistModal  (props)  {
 
         sendForm('playlists/' + props.playlist?.id + '/edit', data);  
     } 
+    const PreViewImage = (image) => {
+        if (image && typeof (image) !== "string") {
+            return <div className="d-flex justify-content-center">
+                        <label htmlFor="fileImage" className='me-4 playlist-img-box rounded-5 cursor-pointer' style={{backgroundImage: `url(${URL.createObjectURL(image)})`, backgroundSize: "cover", backgroundRepeat: "no-repeat", backgroundPosition: "center"}}></label>
+                    </div>
+            }
+    }
 
     return(
-    <Modal
+        <Modal
         {...props}
-        size="lg"
         aria-labelledby="contained-modal-title-vcenter"
         centered
     >
         <Modal.Header closeButton> 
-        <Modal.Title id="contained-modal-title-vcenter"></Modal.Title> 
+            <Modal.Title id="contained-modal-title-vcenter">Edit Playlist</Modal.Title>
         </Modal.Header>
         <Modal.Body >
-        <form onSubmit={PostEditPlaylist} className="authorization center align-items-center justify-content-center  d-flex" id='loadTracksForm'>
-            <div className="border p-3 col-9">
-                <h4 className="w-100 text-center">Edit Playlist</h4>
-                <hr/>
-                <div className="d-flex justify-content-between">
-                    <div className="w-auto">
-                        <label  className="form-label">Image</label>
-                        <input type="file" name="picture" accept="image/*" id="file" className='form-control mb-3' onChange={(e) => setImage(e.target.files[0])} multiple={false}/>
-                        {/* <input className="form-check-input me-3" type="checkbox" id="flexCheckIndeterminate" checked={privat} onChange={e => setPrivat(e.target.checked? 1 : 0)}/>
-                        <label className="form-check-label" >Private?</label>     */}
-                    </div>
-                    <div className="w-50">
-                        <label  className="form-label">Name</label><br/>
-                        <input type="text" id="username" className='input form-control mb-3' value={name} onChange={e => setName(e.target.value)}/>
-                        <label  className="form-label">Description</label>
-                        <textarea type="password" id="password" className='form-control mb-3' value={description || ''} onChange={e => setDescription(e.target.value)}/>
-                    </div>
-                </div>
-            </div>
-        </form>
+            <Form onSubmit={PostEditPlaylist} id='loadTracksForm'>
+                {PreViewImage(image)}
+                <Form.Group className="mb-3" >
+                    <Form.Label>Image</Form.Label>
+                    <Form.Control type="file" name="picture" accept="image/*" id="fileImage" className='form-control mb-3' onChange={(e) => {
+                        setImage(e.target.files[0]);
+                    }} multiple={false} />
+                </Form.Group>
+                <Form.Group className="mb-3" >
+                    <Form.Label>Name</Form.Label>
+                    <Form.Control type="text" id="username" className='input form-control mb-3' value={name} onChange={e => setName(e.target.value)} />
+                </Form.Group>
+                <Form.Group className="mb-3" >
+                    <Form.Label>Description</Form.Label>
+                    <Form.Control as="textarea" name="description" rows={3}  id="description" className='form-control mb-3' value={description || ''} onChange={e => setDescription(e.target.value)} />
+                </Form.Group>
+            </Form>
         </Modal.Body>
         <Modal.Footer> 
         <Button variant="outline-danger" type='submit' form='loadTracksForm' onClick={props.onHide}>Save</Button> 

+ 47 - 19
src/components/LoadTrackModal.js

@@ -6,7 +6,7 @@ import { store } from '../store/store';
 import { sendForm } from './SendForm';
 import { actionPlaylistById} from '../store/promiseReducer';
 import { actionFullSetPlaylist, actionFullSetTrack, actionFullSetTrackCount} from '../store/playerReducer';
-
+import {Form} from "react-bootstrap";
 
 export function LoadTrackModal  (props)  {
     const [tracks, setTrack] = useState(null);
@@ -21,39 +21,67 @@ export function LoadTrackModal  (props)  {
             data.append(`tracks[${i++}]`, track);
         }
         sendForm('playlists/load-tracks', data);
+        props.onHide();
+        setTimeout(() => {
+                store.dispatch(actionPlaylistById(props.id));
+                setTimeout(() => store.dispatch(actionFullSetPlaylist(store.getState().promise.plstById?.payload?.tracks)), 1000);
+            }
+            , 1000);
       }  
 
+      let TracksTableItem = ({name}) =>
+      <tr>
+          <td>
+              <span className="text-dark">  {name}</span>
+          </td>
+      </tr>
+
+  const PreViewTracks = (preTracks) => {
+      if (preTracks && preTracks.length > 0)
+          return (
+              <div className="preview-tracks-block">
+                  <table className="table table-light table-hover align-middle sticky-top bg-light">
+                      <thead>
+                          <tr>
+                              <th>
+                                  Loaded files
+                              </th>
+                          </tr>
+                      </thead>
+                  </table>
+                  <table className="table table-light table-hover align-middle">
+                      <tbody>
+                          {Array.from(preTracks).map((preTracks, i) => <TracksTableItem name={preTracks.name} key={i}></TracksTableItem>)}
+                      </tbody>
+                  </table>
+              </div>
+          )}
+
 return(
 <Modal
     {...props}
-    size="lg"
+    size=""
     aria-labelledby="contained-modal-title-vcenter"
     centered
   >
      <Modal.Header closeButton> 
       <Modal.Title id="contained-modal-title-vcenter">
-      Add Tracks
+      Load tracks
       </Modal.Title> 
     </Modal.Header>
     <Modal.Body >
-    <form onSubmit={PostLoadTracks} className="authorization center align-items-center justify-content-center  d-flex" id='loadTracksForm'>
-        <div className="mb-3">
-            <label className="form-label">Add your tracks</label>
-            
-            <input className="form-control"  accept=".mp3" type="file" id="formFileMultiple" multiple onChange={(e) => setTrack(e.target.files)}/>
-        </div>
-    </form>
+        <Form onSubmit={PostLoadTracks} className="authorization" id='loadTracksForm'>
+            <Form.Group className="mb-3">
+                <Form.Label>Select your tracks</Form.Label>
+                <Form.Control type="file" required  accept=".mp3" id="formFileMultiple" multiple onChange={(e) => {
+                    setTrack(e.target.files);
+                }} />
+            </Form.Group>
+        </Form>
+        {PreViewTracks(tracks)}
     </Modal.Body>
     <Modal.Footer> 
-      <Button variant="outline-danger" type='submit' form='loadTracksForm' onClick={() => {
-      props.onHide();
-      setTimeout(() => {
-        store.dispatch(actionPlaylistById(props.id));
-        setTimeout(() => store.dispatch(actionFullSetPlaylist(store.getState().promise.plstById?.payload?.tracks)), 1000);
-        }
-        , 1000);
-      }
-      }>Save</Button> 
+      <Button variant="outline-success" type='submit' form='loadTracksForm'>Save</Button>
      </Modal.Footer>
   </Modal>)
 }

+ 6 - 6
src/components/Playlist.js

@@ -7,12 +7,7 @@ import { actionFullSetPlaylist, actionFullSetTrack } from '../store/playerReduce
 import { actionPlaylistById} from '../store/promiseReducer';
 import image from '../images/card.png';
 import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
-import {
-    faAlignCenter,
-    faCompactDisc,
-    faHeadphonesSimple, faPlay,
-    faPlus
-} from "@fortawesome/free-solid-svg-icons";
+import {faCompactDisc, faPlay} from "@fortawesome/free-solid-svg-icons";
 import Button from "react-bootstrap/Button";
 
 const Playlist = ({playlist = {}}) => 
@@ -57,9 +52,14 @@ const Playlist = ({playlist = {}}) =>
 
 
 const PlaylistsAll = ({playlists= []}) => 
+<>
+  <div className="d-flex justify-content-between align-items-center py-3">
+    <h3 className="text-uppercase"> <FontAwesomeIcon icon={faCompactDisc} className="me-2"/>Playlists</h3>
+  </div>
 <div className='RootCategories d-flex justify-content-start flex-wrap'>
   {playlists.map((playlist, i) => <Playlist key={i} playlist={playlist}/>)}
 </div>
+</>
 
 
 export const CAllPlaylists = connect(state => ({playlists: state.promise.allPlaylists?.payload?.playlists?.data || []}), )(PlaylistsAll);

+ 4 - 0
src/components/Routs.js

@@ -9,6 +9,8 @@ import {CPlaylistById}  from './playlistById';
 import {СNowPlayingPlayer} from './playing'
 import { CEditProfile } from './EditProfile';
 import { Header } from './header';
+import { ArtistPage } from '../pages/artistPage';
+import { AlbumPage } from '../pages/albumPage';
 
 export const Main = ({auth}) =>
 
@@ -26,6 +28,8 @@ export const Main = ({auth}) =>
           <Route path={'/allplaylists'} component={Aside}/>
           <Route path={'/playlist'} component={CPlaylistById} />
           <Route path={'/user'} component={UserPage} />
+          <Route path={'/artist'} component={ArtistPage} />
+          <Route path={'/album'} component={AlbumPage} />
           <Route exact path="/">{auth ? <Redirect to="/user"/> : <Redirect to="/login" /> }</Route>
         </Switch>
       </div>

+ 25 - 6
src/components/Tracks.js

@@ -7,13 +7,23 @@ import Modal from 'react-bootstrap/Modal';
 import { sendForm } from './SendForm';
 import React, {useState} from 'react';
 import {FontAwesomeIcon} from "@fortawesome/react-fontawesome";
-import {faPlay} from "@fortawesome/free-solid-svg-icons";
+import {faCheck, faPlay} from "@fortawesome/free-solid-svg-icons";
 import { Link } from 'react-router-dom';
-import { Dropdown } from 'react-bootstrap';
+import { Dropdown , Form} from 'react-bootstrap';
 
 
 export let audio = new Audio();
 
+//!  --------
+// // const playlists = store.getState().promise?.usersPlaylists?.payload?.playlists;
+
+// const playlistOption = (playlists = null) => {
+//     // if (playlists) {
+//         // console.log(playlists)
+//         return <option value={"1"}>Add to...</option>
+//     // }
+// }
+//! ------
 
 const ButtonDeleteTrack = (track) => {
     const [deletePllstModal, setDeletePllstModal] = useState(false);
@@ -77,7 +87,16 @@ const Track = ({track = {}, trackone={}, playlist={}, plstnow={}},  key) =>
             <Dropdown.Toggle variant="outline-light" id="dropdown-basic"></Dropdown.Toggle>
 
             <Dropdown.Menu variant={"dark"}>
-                {playlist?.user_id === store.getState().auth.user.id ? <ButtonDeleteTrack track={track} /> : <Dropdown.Item>Add to Playlist</Dropdown.Item>}
+            {playlist?.user_id === store.getState().auth.user.id ? <ButtonDeleteTrack track={track} /> :
+
+            <Form className="input-group d-flex">
+                <select className="dropdown-item w-auto" id="inputGroupSelect04"
+                        aria-label="Example select with button addon">
+                    {/* {playlistOption()} */}
+                </select>
+                <button type={"submit"} className="btn btn-outline-secondary w-auto"><FontAwesomeIcon icon={faCheck}/></button>
+            </Form>
+}
                 <Dropdown.Item onClick={() => {
                                                     store.dispatch(actionAddTrackToQueue(track))
                                                 }}>Add to Queue</Dropdown.Item>
@@ -110,6 +129,6 @@ export const СAllTracks = connect(state => ({playlist: state.promise.plstById?.
                                  plstnow: state.promise?.plstnow || {}} ), )(TracksAll);
 
 export const CTrack = connect(state => ({playlist: state.promise.plstById?.payload || {},
-    tracks: state.promise?.plstById?.payload?.tracks || [],
-    trackone: state.player?.playlist || [],
-    plstnow: state.promise?.plstnow || {}} ), )(Track);
+                                tracks: state.promise?.plstById?.payload?.tracks || [],
+                                trackone: state.player?.playlist || [],
+                                plstnow: state.promise?.plstnow || {}} ), )(Track);

+ 6 - 2
src/components/playlistById.js

@@ -101,8 +101,12 @@ export const PlaylistById = ({playlist = {}, tracks={}}) => {
                             </div>
 
                             <Link className="link-secondary mb-2" title='Author' to='#'><FontAwesomeIcon className='me-2' icon={faUserAstronaut} />  {playlist.user_name}</Link>
-                            <p className='text-white-50 mb-2'><FontAwesomeIcon className='me-2' icon={faCompactDisc} /> {playlist?.tracks?.length} Tracks</p>
-                            <p className='text-white-50 mb-2'><FontAwesomeIcon className='me-2' icon={faAlignCenter} /> {playlist.description}</p>
+                            <p className='text-white-50 mb-2'>
+                                <FontAwesomeIcon className='me-2' icon={faCompactDisc} /> {playlist?.tracks?.length} Tracks
+                            </p>
+                            <p className='text-white-50 mb-2'>
+                                <FontAwesomeIcon className='me-2' icon={faAlignCenter} /> {playlist.description ?? "There could be a description here, but I'm too lazy"}
+                            </p>
                         </div>
 
                     

+ 1 - 1
src/components/userPage.js

@@ -50,7 +50,7 @@ const Playlist = ({playlist = {}}) =>
   export const UsersPlaylistsAll = ({playlists= []}) => {
     const [modalShow, setModalShow] = React.useState(false);
     return (
-  <>
+  <> 
       <div className="d-flex justify-content-between align-items-center py-3">
           <h3 className="text-uppercase"> <FontAwesomeIcon icon={faHeadphonesSimple} className="me-2"/>My playlists</h3>
           <Button  variant="outline-success" title='Delete playlist' onClick={() => setModalShow(true)}>

+ 9 - 0
src/index.css

@@ -31,12 +31,21 @@ code {
 .playlist-img-box{
   min-height: 250px;
   min-width: 250px;
+  max-height: 250px;
+  max-width: 250px;
   overflow: hidden;
 }
+.cursor-pointer {
+  cursor: pointer;
+}
 .playlist-play-box{
   bottom: 15px;
   right: 15px;
 }
+.preview-tracks-block{
+  max-height: 200px;
+  overflow:auto;
+}
 .playlist-grey-box{
   background: rgba(0, 0, 0, 0.54);
   position: absolute;

+ 4 - 0
src/pages/albumPage.js

@@ -0,0 +1,4 @@
+
+
+export const AlbumPage = () => 
+    <>Album</>

+ 5 - 0
src/pages/artistPage.js

@@ -0,0 +1,5 @@
+
+
+
+export const ArtistPage = () => 
+ <>Artist</>