浏览代码

cool styles implemented for players main page

miskson 2 年之前
父节点
当前提交
dd00e61e5c
共有 8 个文件被更改,包括 317 次插入157 次删除
  1. 26 16
      src/App.js
  2. 27 72
      src/App.scss
  3. 27 25
      src/components/Page/index.js
  4. 37 33
      src/components/Playerbar.js
  5. 5 11
      src/components/Sidebar/index.js
  6. 58 0
      src/styles/Page.scss
  7. 63 0
      src/styles/Playerbar.scss
  8. 74 0
      src/styles/Sidebar.scss

+ 26 - 16
src/App.js

@@ -4,12 +4,12 @@ import * as reducer from './reducers'
 import * as Logcomp from './components/Login'
 import * as Sidebar from './components/Sidebar'
 import * as Page from './components/Page'
-import  {PlayerbarConnect} from './components/Playerbar'
+import { PlayerbarConnect } from './components/Playerbar'
 
 import thunk from 'redux-thunk';
 import { createStore, combineReducers, applyMiddleware } from 'redux';
 import { Provider } from 'react-redux';
-import { Link, Route, Router, Switch } from 'react-router-dom';
+import { Route, Router, Switch } from 'react-router-dom';
 import createHistory from 'history/createBrowserHistory'
 
 export function jwtDecode(token) {
@@ -65,10 +65,31 @@ if (store.getState().auth?.token) {
   history.push('/login')
 }
 
+const GreetPg = () =>
+  <>
+    <h2>Welcome to online Player!</h2>
+    <div className='startpage__ulwrapper'>
+      <ul>
+        <li>
+          <strong className='highlightYellow'>Click "MY UPLOADS" - </strong><small>To see all of your uploaded tracks.</small>
+        </li>
+        <li>
+          <strong className='highlightGreen'>Click "NEW PLAYLIST" - </strong><small>To create new playlist.</small>
+        </li>
+        <li>
+          <strong>Drag 'n' drop track to playlist area - </strong><small>To upload the track and add it to current playlist.</small>
+        </li>
+        <li>
+          <strong>Drag a track within playlist - </strong><small>To chage the order of playlist tracks.</small>
+        </li>
+      </ul>
+    </div>
+  </>
+
 const Player = () =>
   <div>
     {/* <header><Link to="/player">Player</Link></header> */}
-    <div style={{ border:'1px solid blue', display: 'flex', maxHeight: '89vh', minHeight:'30vh', overflow:'none'}}>
+    <div className='page'>
       <aside className='sidebar' >
         <Sidebar.LogoutBtnConnect />
         <Sidebar.ProfileWindowDropzoneConnect />
@@ -76,26 +97,15 @@ const Player = () =>
         <Sidebar.PlaylistAddConnect />
         <Sidebar.PlaylistsConnect />
       </aside>
-      <main style={{ border: '1px solid red', width: '80%', height:'inherit', overflow:'auto'}}>
+      <main className='page__window'>
         <Switch>
           <Route path="/player/playlist/:_id" component={Page.PlaylistPageConnect} exact />
           <Route path="/player/tracks/:_id" component={Page.UserTracksPageConnect} exact />
-          <>
-            <h2>Welcome to online Player!</h2>
-            <div style={{ width: '50%', margin: '0 auto' }}>
-              <ul style={{ textAlign: 'start' }}>
-                <li><strong>Click "NEW PLAYLIST" - </strong><small>To create new playlist.</small></li>
-                <li><strong>Drag 'n' drop track to playlist area - </strong><small>To upload the track and add it to current playlist.</small></li>
-                <li><strong>Drag a track within playlist - </strong><small>To chage the order of playlist tracks.</small></li>
-                <li><strong>Click "MY UPLOADS" - </strong><small>To see all of your uploaded tracks.</small></li>
-              </ul>
-            </div>
-          </>
+          <GreetPg />
         </Switch>
       </main>
     </div>
     <PlayerbarConnect />
-    {/* <PlayerBar /> */}
   </div>
 
 function App() {

+ 27 - 72
src/App.scss

@@ -1,88 +1,36 @@
-body { background-color: #100d23; }
+@import './styles/Sidebar.scss';
+@import './styles/Page.scss';
+@import './styles/Playerbar.scss';
 
-.App {
-  text-align: center;
-  color: #70b2e7;
-}
-
-.sidebar {
-  background-color: #1e1d45;
-  width: 30%; 
-  overflow:auto;
-
-  &__link {
-    font-size: medium;
-    display: block;
-    text-decoration: none;
-    border-left: 5px solid #05f09b;
-    background-color: #100d23;
-    color: #05f09b;
-    margin: 5px;
-    padding: 5px;
-
-    &:hover {
-      background-color: #323151;
-    }
-  }
-
-  &__button {
-    background-color: #0e6147;
-    color: #05f09b;
-    font-size: medium;
-    width: 100%;
-    border-style: none;
-    padding: 10px;
-
-    &:active {
-      background-color: #05f09b;
-      color: #0e6147;
-    }
-  }
-
-  &__addpanel {
-    display: flex;
-    width: 95%;
-    margin: 0 auto;
-    border: 1px solid #05f09b;
-    padding: 0.5%;
+body { 
+  background-color: #100d23;
+  ::-webkit-scrollbar {
+    width: 12px;
 
-    input {
-      font-size: medium;
-      outline: none;
+    &-track {
       background-color: transparent;
-      width: 80%;
-      color: #05f09b;
-      border-style: none;
+      border: 1px solid rgba(105, 105, 105, 0.384);
     }
 
-    .btnWrapper {
-      display: inline-block;
-      width: 20%;
-      border: none;
+    &-thumb {
+      background-color: #534f7459;
 
-      button {
-        border: none;
-        background-color: transparent;
-        font-size: large;
-        padding: 4% 5% 2% 5%;
-        margin: 0 2%;
+      &:hover {
+        background-color: #534f74c7;
       }
     }
   }
 
-  &__profile {
-    //width: 40%;
-    margin: 0 auto;
-    //border-radius: 10%;
-    img {
-      max-width: 125px;
-      height: auto;
-      border-radius: 10%;
-      border: 2px solid #70b2e7;
-    }
+  :hover {
+    transition: 0.1s;
   }
 }
 
+.App {
+  text-align: center;
+  color: #70b2e7;
+}
+
 .highlightYellow {
   color: yellow;
   border-color: yellow;
@@ -97,3 +45,10 @@ body { background-color: #100d23; }
   color: #05f09b;
   border-color: #05f09b;
 }
+
+.highlightPaleGreen {
+  background-color: #0e6147;
+  color: #05f09b;
+}
+
+.lightText {font-weight: 300;}

+ 27 - 25
src/components/Page/index.js

@@ -15,25 +15,25 @@ const Track = ({ track, playlist, player, setTrack, playTrack, pauseTrack }) =>
   useEffect(() => setPlayer(player), [player])
 
   return (
-    <li style={{ border: '1px solid black', display: 'flex', alignItems: 'center' }}>
-      <div style={{ marginRight: '2%', padding: '2%' }}>
-
-        {isPlay && _player?.isPlaying && _player.track?._id === track._id ?
-          <button style={{ fontSize: '3vh', padding: '10px' }} onClick={() => { pauseTrack(); setPlay(false) }}> <FontAwesomeIcon style={{pointerEvents:'none'}} icon={faPause} /> </button> :
-          <button
-            style={{ fontSize: '3vh', padding: '10px' }}
-            onClick={() => {
-              if (track?._id !== _player?.track?._id) setTrack(track, playlist)
-              playTrack()
-              setPlay(true)
-            }}
-          > <FontAwesomeIcon style={{pointerEvents:'none'}} icon={faPlay} /> </button>
-        }
-      </div>
-      <div style={{ textAlign: 'left' }}>
-        <h5>{track.id3.artist || 'Artist: unknown'}</h5>
-        <h6>{track.id3.album || 'Album: unknown'}</h6>
-        <h5>{track.id3.title || track.originalFileName}</h5>
+    <li className={isPlay && _player?.isPlaying && _player.track?._id === track._id ? 'playlist__track highlightPaleGreen' : 'playlist__track'}>
+      {isPlay && _player?.isPlaying && _player.track?._id === track._id ?
+        <button 
+          className='highlightYellow' 
+          onClick={() => { pauseTrack(); setPlay(false) }}
+        ><FontAwesomeIcon style={{pointerEvents:'none'}} icon={faPause} /></button> :
+        <button
+          className='highlightGreen'
+          onClick={() => {
+            if (track?._id !== _player?.track?._id) setTrack(track, playlist)
+            playTrack()
+            setPlay(true)
+          }}
+        ><FontAwesomeIcon style={{pointerEvents:'none'}} icon={faPlay} /></button>
+      }
+      <div>
+        <small className='artist'>{track.id3.artist || 'Artist: unknown'}</small>
+        <small className='album'>{track.id3.album || 'Album: unknown'}</small>
+        <small className='title'>{track.id3.title || track.originalFileName}</small>
       </div>
     </li>
   )
@@ -71,7 +71,7 @@ const Playlist = ({ player, playlist, setPlaylist, updPlaylist, setIndex }) => {
 
   return (
     <>
-      <h2>{playlist[0]?.name || 'Playlist'}</h2>
+      <h2 className='highlightGreen'>{playlist[0]?.name || 'Playlist'}</h2>
       <SortableContainer onSortEnd={onSortEnd}>
         {(_tracks || []).map((track, index) => <SortableItem index={index} track={track} playlist={playlist[0]} />)}
       </SortableContainer>
@@ -104,9 +104,10 @@ const PlaylistTrackDropzone = ({ playlist, uploadTrack }) => {
   return (
     <div
       {...getRootProps()}
-      style={{ height: 'fit-content', border: `${isDragActive ? '1px solid mediumseagreen' : '1px solid black'}` }}
+      className='playlist'
+      style={{ border: `${isDragActive ? '1px solid yellow' : '1px solid transparent'}` }}
     >
-      {isDragActive ? <small>...drag here</small> : <small>to upload drag track here</small>}
+      <small className='lightText'>{isDragActive ? '...drop here' : 'to upload: drag and drop track here'}</small>
       <PlaylistConnect />
     </div>
   )
@@ -126,7 +127,7 @@ const UserTracks = ({ user, tracks }) => {
   let tracksRev = [...tracks].reverse()
   return (
     <>
-      <h2>{user.login || 'My'} uploaded tracks:</h2>
+      <h2 className='highlightYellow'>{user.login || 'My'} uploaded tracks:</h2>
       <ul>{(tracksRev || []).map(track => <TrackConnect track={track} playlist={tracksRev} />)}</ul>
     </>
   )
@@ -145,9 +146,10 @@ const UserTracksDropzone = ({ onLoad }) => {
   return (
     <div
       {...getRootProps()}
-      style={{ height: 'fit-content', border: `${isDragActive ? '1px solid mediumseagreen' : '1px solid black'}` }}
+      className='playlist'
+      style={{ height: 'fit-content', border: `${isDragActive ? '1px solid yellow' : '1px solid black'}` }}
     >
-      {isDragActive ? <small>...drag here</small> : <small>to upload drag track here</small>}
+      <small className='lightText'>{isDragActive ? '...drop here' : 'to upload: drag and drop track here'}</small>
       <UserTracksConnect />
     </div>
   )

+ 37 - 33
src/components/Playerbar.js

@@ -1,13 +1,13 @@
 import { useEffect, useState } from "react"
 import { connect } from "react-redux"
-import { faHome, faPlay, faPause, faForward, faBackward, faFastForward, faFastBackward, faVolumeUp} from "@fortawesome/free-solid-svg-icons";
+import { faPlay, faPause, faForward, faBackward, faFastForward, faFastBackward, faVolumeUp} from "@fortawesome/free-solid-svg-icons";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import * as action from "../actions"
 
 
 const Timestamp = ({time}) =>
-    <small style={{margin: '0 10px'}}>
-        {Math.floor((time / 60) % 60) < 10? `0` + Math.floor((time / 60) % 60) : Math.floor((time / 60) % 60)} : 
+    <small className="timestamp highlightYellow">
+        {Math.floor((time / 60) % 60) < 10? `0` + Math.floor((time / 60) % 60) : Math.floor((time / 60) % 60)}: 
         {Math.floor(time % 60) < 10?  `0`+ Math.floor(time % 60) : Math.floor(time % 60)}
     </small>
 
@@ -19,51 +19,55 @@ const Playerbar = ({ player, playTrack, pauseTrack, switchTrack, setTrackVolume,
     }, [player, _player])
 
     return (
-        <>
+        <footer className="playerbar">
             {_player?.track ?  
-                <footer style={{display: `${_player?.track ? 'block' : 'none'}`, width: '95%', margin:'0 auto'}}>
-                    <input
-                        style={{width:'100%'}}
-                        type="range" min="0" max={_player?.duration} step="any"
-                        value={_player?.currentTime}
-                        onChange={(e) => setCurrentTime(e.target.value)}
-                    />
-                    <div style={{display:"flex", justifyContent:"space-between", width:'95%', margin:'0 auto'}}>
-                        <Timestamp time={_player?.currentTime} />
-                        {_player ? (_player.track?.id3?.artist && _player.track?.id3?.title ?
-                            <strong>{_player.track?.id3?.artist} - {_player.track?.id3?.title}</strong> :
-                            <strong>{_player.track?.originalFileName}</strong>) : ''}
+                <div style={{display: `${_player?.track ? 'block' : 'none'}`}}>
+                    <div>
+                        <input
+                            className="playerbar__range plumline"
+                            style={{width: '95%'}}
+                            type="range" min="0" max={_player?.duration} step="any"
+                            value={_player?.currentTime}
+                            onChange={(e) => setCurrentTime(e.target.value)}
+                        />
+                    </div>
+                    <div className="playerbar__info">
+                        <Timestamp className="playerbar" time={_player?.currentTime} />
+                        <strong className="highlightYellow">
+                            <small className="lightText highlightGreen">{(_player.playlist.name || 'Uploads') + ' : '}</small>
+                            {(_player.track?.id3?.artist && _player.track?.id3?.title ? 
+                                _player.track?.id3?.artist + ' - ' + _player.track?.id3?.title : 
+                                _player.track?.originalFileName)}
+                        </strong>
                         <Timestamp time={_player?.duration} />
                     </div>
                     <div style={{marginTop:'0.5%'}}>
-                        <button
-                            style={{ fontSize: '2vh', padding: '5px' }}
-                            onClick={() => switchTrack(false, _player?.playlistIndex, _player?.playlist)}
-                        >
-                            {_player?.playlistIndex === 0 ? <FontAwesomeIcon icon={faFastBackward} />:
+                        <button onClick={() => switchTrack(false, _player?.playlistIndex, _player?.playlist)}>
+                            {_player?.playlistIndex === 0 ? <FontAwesomeIcon icon={faFastBackward} /> :
                                                             <FontAwesomeIcon icon={faBackward} />}
                         </button>
 
                         {_player?.isPlaying ?
-                            <button style={{ fontSize: '2vh', padding: '5px' }} onClick={() => pauseTrack()}><FontAwesomeIcon icon={faPause} /></button> :
-                            <button style={{ fontSize: '2vh', padding: '5px' }} onClick={() => playTrack()}><FontAwesomeIcon icon={faPlay} /></button>
+                            <button onClick={() => pauseTrack()}><FontAwesomeIcon icon={faPause} /></button> :
+                            <button onClick={() => playTrack()}><FontAwesomeIcon icon={faPlay} /></button>
                         }
 
-                        <button
-                            style={{ fontSize: '2vh', padding: '5px' }}
-                            onClick={() => switchTrack(true, _player?.playlistIndex, _player?.playlist)}
-                        >
-                            {_player?.playlistIndex === (_player?.playlist?.constructor.name === 'Array'? _player?.playlist?.length - 1 : _player?.playlist?.tracks.length - 1) ? 
-                                <FontAwesomeIcon icon={faFastForward} /> : <FontAwesomeIcon icon={faForward} />}
+                        <button onClick={() => switchTrack(true, _player?.playlistIndex, _player?.playlist)}>
+                            {_player?.playlistIndex === (_player?.playlist?.constructor.name === 'Array' ? 
+                                _player?.playlist?.length - 1 : _player?.playlist?.tracks.length - 1) ? 
+                                    <FontAwesomeIcon icon={faFastForward} /> :
+                                    <FontAwesomeIcon icon={faForward} />}
                         </button>
                         <label style={{marginLeft: '1%'}}>
                             <FontAwesomeIcon icon={faVolumeUp} />
-                            <input type="range" min="0" max="1" step="any" onChange={(e) => setTrackVolume(e.target.value)} />
+                            <input
+                                className="playerbar__range blueline"
+                                type="range" min="0" max="1" step="any" 
+                                onChange={(e) => setTrackVolume(e.target.value)} />
                         </label>
                     </div>
-                    {/* <small>{_player?.playlistIndex}</small> */}
-                </footer> : <div style={{width:'inherit', height:'inherit', padding:'2em'}}>C'mon, Push the play button on some track :)</div>}
-        </>
+                </div> : <div style={{width:'inherit', height:'inherit', padding:'2em'}}>C'mon, push the play button on some track :)</div>}
+        </footer>
     )
 }
 

+ 5 - 11
src/components/Sidebar/index.js

@@ -19,18 +19,12 @@ export const LogoutBtnConnect = connect(null, { onLogout: action.actionAuthLogou
 
 const ProfileWindow = ({ user }) => {
   let [userInfo, setUserInfo] = useState(user.payload)
-
-  useEffect(() => {
-    setUserInfo(user.payload)
-  }, [user, userInfo])
+  useEffect(() => setUserInfo(user.payload), [user, userInfo])
 
   return (
     <section >
       <h3>{userInfo?.login || 'user'}</h3>
-      <img
-        src={userInfo?.avatar?.url ? backendURL + '/' + userInfo?.avatar?.url : ''}
-        alt='avatar'
-      />
+      <img src={userInfo?.avatar?.url ? backendURL + '/' + userInfo?.avatar?.url : ''} alt='avatar' />
     </section>
   )
 }
@@ -49,7 +43,7 @@ const ProfileWindowDropzone = ({ onLoad }) => {
     >
       <input {...getInputProps()} />
       <ProfileWindowConnect />
-      {isDragActive ? <small>drop here...</small> : <small>change avatar</small>}
+      <small className='lightText'>{isDragActive ? '...drop here' : 'change avatar'}</small>
     </div>
   )
 }
@@ -74,7 +68,7 @@ const PlaylistAdd = ({ addPlaylist }) => {
       {
         !clicked ?
           <button
-            className='sidebar__button'
+            className='sidebar__button highlightPaleGreen'
             onClick={() => setClicked(true)}
           >NEW PLAYLIST</button>
           :
@@ -103,7 +97,7 @@ const PlaylistAdd = ({ addPlaylist }) => {
 }
 export const PlaylistAddConnect = connect(null, { addPlaylist: action.actionAddPlaylist })(PlaylistAdd)
 
-const Playlists = ({ playlists }) => {
+const Playlists = ( { playlists }) => {
   return (
     <div>
       {

+ 58 - 0
src/styles/Page.scss

@@ -0,0 +1,58 @@
+.page {
+    display: flex;
+    max-height: 89vh;
+    min-height: 30vh;
+    overflow: none;
+
+    &__window {
+        width: 80%;
+        height: inherit;
+        overflow: auto;
+    }
+}
+
+.startpage {
+    &__ulwrapper {
+        width: 50%;
+        margin: 0 auto;
+
+        ul {
+            text-align: start;
+            small { color: whitesmoke;}
+        }
+    }
+}
+
+.playlist {
+    background-color: #1e1d45;
+    height: fit-content;
+    width: 90%;
+    margin: 0 auto;
+    padding: 1% 2%;
+    &__track {
+        display: flex;
+        align-items: center;
+        background-color: #2a3da941;
+        margin: 10px;
+        padding: 2% 0;
+        color: #83d6f6;
+        box-shadow: 0 0 5px black;
+
+        button {
+            display: block;
+            background-color: #1e1d45;
+            border-style: solid;
+            font-size: x-large;
+            padding: 1%;
+            margin: 0 5%;
+        }
+        
+        small, strong {
+            display: block;
+        }
+
+        .artist {font-weight: 700; text-align: start;}
+        .album {font-weight: 400; text-align: start;}
+        .title {font-size: large; font-weight: 700; text-align: start;}
+    }
+}

+ 63 - 0
src/styles/Playerbar.scss

@@ -0,0 +1,63 @@
+.playerbar {
+    //border-top: 1px solid #05f09b;
+    position: fixed;
+    bottom: 0;
+    left: 0;
+    width: 100%;
+    padding-bottom: 1%;
+    background-color: #131341;
+
+    &__range {
+        margin: 0 10px 6px 10px;
+        -webkit-appearance: none;
+        outline: none;
+        cursor: pointer;
+        &::-webkit-slider-thumb {
+            -webkit-appearance: none;
+            border: 1px solid #000000;
+            height: 20px;
+            width: 20px;
+            border-radius: 100%;
+            background: yellow;
+            cursor: pointer;
+            margin-top: -8px;
+            box-shadow: 1px 1px 1px #000000, 0px 0px 1px #0d0d0d;
+        }
+
+        &::-webkit-slider-runnable-track {
+            width: 100%;
+            border: 1px solid rgba(255, 255, 0, 0.26);
+            height: 4px;
+        }
+    }
+
+    &__info {
+        display: flex;
+        justify-content: space-between;
+        width: 95%;
+        margin: 0 auto;
+    }
+
+    button {
+        font-size: large;
+        padding: 0.5%;
+        background-color: yellow;
+        border: none;
+        margin: 0 5px;
+    }
+}
+
+.timestamp {
+    margin: 0 10px;
+    font-weight: 500;
+}
+
+.plumline {
+    &::-webkit-slider-runnable-track { background: #2f1dce;}
+}
+
+.blueline {
+    &::-webkit-slider-runnable-track { 
+        background: #70b2e7;
+    }
+}

+ 74 - 0
src/styles/Sidebar.scss

@@ -0,0 +1,74 @@
+.sidebar {
+    background-color: #1e1d45;
+    width: 30%; 
+    overflow:auto;
+  
+    &__link {
+      font-size: medium;
+      display: block;
+      text-decoration: none;
+      border-left: 5px solid #05f09b;
+      background-color: #100d23;
+      color: #05f09b;
+      margin: 5px;
+      padding: 5px;
+  
+      &:hover {
+        background-color: #323151;
+      }
+    }
+  
+    &__button {
+      font-size: medium;
+      width: 100%;
+      border-style: none;
+      padding: 10px;
+  
+      &:active {
+        background-color: #05f09b;
+        color: #0e6147;
+      }
+    }
+  
+    &__addpanel {
+      display: flex;
+      width: 95%;
+      margin: 0 auto;
+      border: 1px solid #05f09b;
+      padding: 0.5%;
+      
+      input {
+        font-size: medium;
+        outline: none;
+        background-color: transparent;
+        width: 80%;
+        color: #05f09b;
+        border-style: none;
+      }
+  
+      .btnWrapper {
+        display: inline-block;
+        width: 20%;
+        border: none;
+  
+        button {
+          border: none;
+          background-color: transparent;
+          font-size: large;
+          padding: 4% 5% 2% 5%;
+          margin: 0 2%;
+        }
+      }
+    }
+  
+    &__profile {
+      margin: 0 auto;
+      img {
+        max-width: 100px;
+        height: auto;
+        border-radius: 10%;
+        border: 2px solid #70b2e7;
+        box-shadow: 0 0 15px black;
+      }
+    }
+  }