Bladeren bron

Fix some bugs and other

Антон Задорожный 3 jaren geleden
bovenliggende
commit
8ba3172f94
10 gewijzigde bestanden met toevoegingen van 323 en 17560 verwijderingen
  1. 141 17447
      package-lock.json
  2. 1 0
      package.json
  3. 58 29
      src/App.js
  4. 0 1
      src/App.scss
  5. 58 37
      src/actions/index.js
  6. 3 5
      src/components/Dropzone.js
  7. 22 11
      src/components/Track.js
  8. 9 7
      src/pages/Auth.js
  9. 19 16
      src/pages/Library.js
  10. 12 7
      src/pages/Search.js

File diff suppressed because it is too large
+ 141 - 17447
package-lock.json


+ 1 - 0
package.json

@@ -12,6 +12,7 @@
     "@testing-library/user-event": "^13.5.0",
     "bootstrap": "^5.1.3",
     "cdbreact": "^1.2.1",
+    "music-metadata-browser": "^2.5.3",
     "react": "^17.0.2",
     "react-bootstrap": "^2.1.0",
     "react-dom": "^17.0.2",

+ 58 - 29
src/App.js

@@ -40,6 +40,8 @@ function* rootSaga() {
     loginWatcher(),
     registerWatcher(),
     findTracksWatcher(),
+    findPlaylistsWatcher(),
+    findUserTrackssWatcher(),
     setAvatarWatcher(),
     setNicknameWatcher(),
     setEmailWatcher(),
@@ -75,7 +77,7 @@ function* aboutMeWorker() {
   let { auth } = yield select();
   if (auth) {
     let { id } = auth?.payload?.sub;
-    yield call(promiseWatcher, actions.actionFindUser(id));
+    yield call(promiseWorker, actions.actionFindUser(id));
   }
 }
 
@@ -117,11 +119,11 @@ function* loginWatcher() {
 }
 
 function* registerWorker({ login, password }) {
-  let { _id } = yield call(
-    promiseWorker,
-    actions.actionRegister(login, password)
-  );
-  if (_id) {
+  yield call(promiseWorker, actions.actionRegister(login, password));
+  let token = yield call(promiseWorker, actions.actionLogin(login, password));
+  if (token) {
+    yield put(actions.actionAuthLogin(token));
+    let { auth } = yield select();
     let nick = login;
     if (nick.includes("@")) {
       nick = nick.substring(0, nick.indexOf("@"));
@@ -129,8 +131,9 @@ function* registerWorker({ login, password }) {
         nick = nick.substring(0, 8);
       }
     }
-    yield call(promiseWorker, actions.actionLogin(login, password));
-    yield call(promiseWorker, actions.actionUserUpdate({ _id, nick }));
+    let { id } = auth?.payload?.sub;
+    yield call(promiseWorker, actions.actionUserUpdate({ _id: id, nick }));
+    yield put(actions.actionAboutMe());
   }
 }
 
@@ -139,11 +142,43 @@ function* registerWatcher() {
 }
 
 function* findTracksWorker() {
-  yield call(promiseWatcher, actions.actionFindTracks());
+  yield call(promiseWorker, actions.actionFindTracks());
 }
 
 function* findTracksWatcher() {
-  yield takeEvery("FIND_TRACKS", findTracksWorker);
+  yield takeEvery("FIND_ALL_TRACKS", findTracksWorker);
+}
+
+if (localStorage.authToken && history.location.pathname === "/search") {
+  store.dispatch(actions.actionAllTracks());
+}
+
+function* findUserTracksWorker({ _id }) {
+  yield call(promiseWorker, actions.actionUserTracks(_id));
+}
+
+function* findUserTrackssWatcher() {
+  yield takeEvery("FIND_USER_TRACKS", findUserTracksWorker);
+}
+
+if (localStorage.authToken && history.location.pathname === "/library") {
+  let { auth } = store.getState();
+  if (auth) {
+    // let { id } = auth?.payload?.sub;
+    store.dispatch(actions.actionTracksUser("5fe35e5be926687ee86b0a49"));
+  }
+}
+
+function* findPlaylistsWorker({ _id }) {
+  yield call(promiseWorker, actions.actionUserPlaylists(_id));
+}
+
+function* findPlaylistsWatcher() {
+  yield takeEvery("FIND_PLAYLISTS", findPlaylistsWorker);
+}
+
+if (localStorage.authToken && history.location.pathname === "/") {
+  store.dispatch(actions.actionAllPlaylists());
 }
 
 function* setAvatarWorker({ file }) {
@@ -153,14 +188,16 @@ function* setAvatarWorker({ file }) {
   //   await dispatch(actionUserUpdate({ _id: id, avatar: { _id } }));
   //   await dispatch(actionAboutMe());
   // };
-  let { _id } = yield call(promiseWatcher, actions.actionUploadFile(file)); //upload file
-  let { id } = yield select().auth.payload.sub;
-  console.log("Set avatar");
-  yield call(
-    promiseWatcher,
-    actions.actionUserUpdate({ _id: id, avatar: { _id } })
-  );
-  yield put(actions.actionAboutMe());
+  let { _id } = yield call(promiseWorker, actions.actionUploadFile(file));
+  let { auth } = yield select();
+  if (auth) {
+    let { id } = auth?.payload?.sub;
+    yield call(
+      promiseWorker,
+      actions.actionUserUpdate({ _id: id, avatar: { _id } })
+    );
+    yield put(actions.actionAboutMe());
+  }
 }
 
 function* setAvatarWatcher() {
@@ -170,7 +207,7 @@ function* setAvatarWatcher() {
 function* setNicknameWorker({ _id, nick }) {
   //   await dispatch(actionUserUpdate({ _id, nick }));
   //   await dispatch(actionAboutMe());
-  yield call(promiseWatcher, actions.actionUserUpdate({ _id, nick }));
+  yield call(promiseWorker, actions.actionUserUpdate({ _id, nick }));
   yield put(actions.actionAboutMe());
 }
 
@@ -181,7 +218,7 @@ function* setNicknameWatcher() {
 function* setEmailWorker({ _id, login }) {
   //   await dispatch(actionUserUpdate({ _id, nick }));
   //   await dispatch(actionAboutMe());
-  yield call(promiseWatcher, actions.actionUserUpdate({ _id, login }));
+  yield call(promiseWorker, actions.actionUserUpdate({ _id, login }));
   yield put(actions.actionAboutMe());
 }
 
@@ -193,7 +230,7 @@ function* setNewPasswordWorker({ login, password, newPassword }) {
   //   await dispatch(actionChangePassword(login, password, newPassword));
   //   await dispatch(actionAboutMe());
   yield call(
-    promiseWatcher,
+    promiseWorker,
     actions.actionChangePassword(login, password, newPassword)
   );
   yield put(actions.actionAboutMe());
@@ -236,14 +273,6 @@ function* audioVolumeWatcher() {
   yield takeEvery("VOLUME_TRACK", audioVolumeWorker);
 }
 
-if (
-  localStorage.authToken &&
-  (history.location.pathname === "/search" ||
-    history.location.pathname === "/library")
-) {
-  store.dispatch(actions.actionFindTracks());
-}
-
 store.subscribe(() => console.log(store.getState()));
 
 function App() {

+ 0 - 1
src/App.scss

@@ -5,7 +5,6 @@ body {
   background-color: #34393d;
   color: white;
   font-family: "Catamaran", sans-serif;
-  height: 2000px;
 }
 
 .spoilerText {

+ 58 - 37
src/actions/index.js

@@ -29,7 +29,9 @@ export const actionChangePassword = (login, password, newPassword) =>
     "changePassword",
     gql(
       `mutation changePass($login:String!, $password:String!, $newPassword:String!){
-        changePassword(login:$login, password: $password, newPassword: $newPassword)
+        changePassword(login:$login, password: $password, newPassword: $newPassword){
+          _id login
+        }
       }`,
       { login, password, newPassword },
       true
@@ -41,7 +43,7 @@ export const actionLogin = (login, password) =>
     "login",
     gql(
       `query log($login:String!, $password:String!){
-        login(login:$login, password: $password)
+        login(login: $login, password: $password)
       }`,
       { login, password }
     )
@@ -77,22 +79,6 @@ export const actionFindUser = (_id) =>
     )
   );
 
-export const actionFindTracks = () =>
-  actionPromise(
-    "tracks",
-    gql(
-      `query findTracks($q:String){
-        TrackFind(query:$q){
-          _id url originalFileName owner {
-            _id login nick
-          }
-        }
-      }
-  `,
-      { q: "[{}]" }
-    )
-  );
-
 export const actionFindUsers = () =>
   actionPromise(
     "users",
@@ -109,9 +95,9 @@ export const actionFindUsers = () =>
     )
   );
 
-export const actionUploadFile = (file) => {
+export const actionUploadFile = (file, type = "photo") => {
   let fd = new FormData();
-  fd.append("photo", file);
+  fd.append(type, file);
   return actionPromise(
     "uploadFile",
     fetch(`${backURL}/upload`, {
@@ -124,40 +110,67 @@ export const actionUploadFile = (file) => {
   );
 };
 
-export const actionUserPlaylists = (_id) => {
+export const actionFindTracks = () =>
   actionPromise(
-    "userPlaylists",
+    "tracks",
     gql(
-      `
-          query getPlaylistByOwnerId($ownerId:String!) {
-              PlaylistFind(query: $ownerId) {
-                  _id, name
-              }
+      `query findTracks($q:String){
+        TrackFind(query: $q) {
+          _id url originalFileName
+          id3 {
+              title, artist
           }
-      `,
-      { ownerId: JSON.stringify([{ ___owner: _id }]) }
+          playlists {
+              _id, name
+          }
+          owner {
+            _id login nick
+          }
+      }
+      }
+  `,
+      { q: "[{}]" }
     )
   );
-};
 
 export const actionUserTracks = (_id) => {
+  // поиск одного трека по его айди
   return actionPromise(
     "userTracks",
     gql(
       `
-          query getUserTracks($ownerId: String!) {
-              TrackFind(query: $ownerId) {
-                  _id,
+          query getUserTracks($q: String!) {
+              TrackFind(query: $q) {
+                  _id url originalFileName
                   id3 {
                       title, artist
                   }
                   playlists {
                       _id, name
                   }
+                  owner {
+                    _id login nick
+                  }
               }
           }
       `,
-      { ownerId: JSON.stringify([{ ___owner: _id }]) }
+      { q: JSON.stringify([{ _id }]) }
+    )
+  );
+};
+
+export const actionUserPlaylists = (_id) => {
+  actionPromise(
+    "userPlaylists",
+    gql(
+      `
+          query getPlaylistByOwnerId($ownerId:String!) {
+              PlaylistFind(query: $ownerId) {
+                  _id, name
+              }
+          }
+      `,
+      { q: "[{}]" }
     )
   );
 };
@@ -247,9 +260,17 @@ export const actionFullRegister = (login, password) => ({
 // };
 
 export const actionAllTracks = () => ({
-  type: "FIND_TRACKS",
-  // name,
-  // promise,
+  type: "FIND_ALL_TRACKS",
+});
+
+export const actionAllPlaylists = (_id) => ({
+  type: "FIND_PLAYLISTS",
+  _id,
+});
+
+export const actionTracksUser = (_id) => ({
+  type: "FIND_USER_TRACKS",
+  _id,
 });
 
 export const actionSetAvatar = (file) => ({

+ 3 - 5
src/components/Dropzone.js

@@ -1,15 +1,14 @@
 import React, { useCallback } from "react";
 import { useDropzone } from "react-dropzone";
 import { connect } from "react-redux";
-import { actionAboutMe, actionSetAvatar } from "../actions";
+import { actionSetAvatar } from "../actions";
 
-const MyDropzone = ({ onload, aboutMe }) => {
+const MyDropzone = ({ onload }) => {
   const onDrop = useCallback(
     (acceptedFiles) => {
       onload(acceptedFiles[0]);
-      aboutMe();
     },
-    [onload, aboutMe]
+    [onload]
   );
   const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop });
 
@@ -30,5 +29,4 @@ const MyDropzone = ({ onload, aboutMe }) => {
 
 export const CMyDropzone = connect(null, {
   onload: actionSetAvatar,
-  aboutMe: actionAboutMe,
 })(MyDropzone);

+ 22 - 11
src/components/Track.js

@@ -1,7 +1,7 @@
 import { Button } from "react-bootstrap";
 import { connect } from "react-redux";
 import { backURL } from "../helpers/index";
-import { useState, useEffect, useRef } from "react";
+import { useState } from "react";
 import { CAudioController } from "./AudioController";
 
 import {
@@ -19,10 +19,17 @@ const Track = ({
   pauseAudio,
   volumeAudio,
   player,
+  promise,
 }) => {
   const [reproduction, setReproduction] = useState(false);
   let track = audio?.url ? `${backURL}/${audio.url}` : undefined;
   let audioTrack = new Audio(track);
+  let duration, currentTime, volume;
+  audioTrack.addEventListener("loadeddata", () => {
+    duration = audioTrack.duration;
+    currentTime = audioTrack.currentTime;
+    volume = audioTrack.volume;
+  });
 
   if (reproduction) {
     audioTrack.play();
@@ -52,7 +59,6 @@ const Track = ({
         <Button
           onClick={() => {
             setReproduction(!reproduction);
-            loadAudio(audioTrack, audioTrack.duration);
             reproduction ? pauseAudio(true) : playAudio(true);
           }}
         >
@@ -68,17 +74,22 @@ const Track = ({
       </div>
       <CAudioController
         name={audio?.originalFileName}
-        currentTime={audioTrack.currentTime}
-        duration={player.duration}
-        volume={player.volume}
+        currentTime={currentTime}
+        duration={duration}
+        volume={volume}
       />
     </>
   );
 };
 
-export const CTrack = connect((state) => ({ player: state.player }), {
-  loadAudio: actionLoadAudio,
-  playAudio: actionPlayAudio,
-  pauseAudio: actionPauseAudio,
-  volumeAudio: actionVolumeAudio,
-})(Track);
+// <div>{promise?.tracks?.}</div>
+
+export const CTrack = connect(
+  (state) => ({ promise: state.promise, player: state.player }),
+  {
+    loadAudio: actionLoadAudio,
+    playAudio: actionPlayAudio,
+    pauseAudio: actionPauseAudio,
+    volumeAudio: actionVolumeAudio,
+  }
+)(Track);

+ 9 - 7
src/pages/Auth.js

@@ -41,13 +41,7 @@ const Auth = ({ auth, promise, actionLogOut }) => {
           >
             Профиль
           </NavDropdown.Item>
-          <NavDropdown.Item
-            componentclass={Link}
-            href="/settings"
-            to={`/settings`}
-          >
-            Настройки
-          </NavDropdown.Item>
+
           <NavDropdown.Divider />
           <NavDropdown.Item as="button" onClick={() => actionLogOut()}>
             Выйти
@@ -67,6 +61,14 @@ const Auth = ({ auth, promise, actionLogOut }) => {
   );
 };
 
+// <NavDropdown.Item
+// componentclass={Link}
+// href="/settings"
+// to={`/settings`}
+// >
+// Настройки
+// </NavDropdown.Item>
+
 export const CAuth = connect(
   (state) => ({ auth: state.auth, promise: state.promise }),
   {

+ 19 - 16
src/pages/Library.js

@@ -1,7 +1,7 @@
 import { connect } from "react-redux";
 import { AuthCheck } from "./../components/AuthCheck";
 import { history } from "./../App";
-import { actionFindTracks, actionFindUser } from "./../actions/index";
+import { actionFindUser, actionUserTracks } from "./../actions/index";
 import { CMyDropzone } from "../components/Dropzone";
 import { CTrack } from "../components/Track";
 import { PlayerHeader } from "./../components/PlayerHeader";
@@ -12,21 +12,27 @@ const Library = ({ auth, promise, actionTracks, actionUser }) => {
     <div className="SearchPage">
       {auth.token && history.location.pathname === "/library" ? (
         <div className="d-block mx-auto mt-2 container w-50">
-          <h1 className="mb-3">
+          <h1 className="mb-3 text-center">
             Ваша библиотека с музыкой, {promise?.user?.payload?.nick}
           </h1>
           <CMyDropzone />
-          <PlayerHeader personal />
-          {promise?.tracks?.payload ? (
-            promise.tracks.payload.map((track, index) =>
-              track.owner._id === auth.payload.sub.id ? (
-                <CTrack audio={track} index={index} key={Math.random()} />
-              ) : (
-                <h2>В вашей библиотеке нет треков.</h2>
-              )
-            )
-          ) : (
+          {promise?.userTracks?.payload?.length !== 0 ? (
+            <PlayerHeader personal />
+          ) : null}
+          {promise.userTracks.status === "PENDING" ? (
             <Loader />
+          ) : promise?.userTracks?.payload &&
+            promise?.userTracks?.payload?.length !== 0 ? (
+            promise.userTracks.payload.map((track, index) => (
+              <CTrack audio={track} index={index} key={Math.random()} />
+            ))
+          ) : (
+            <h2 className="mt-5 text-center">
+              {promise?.user?.payload?.nick
+                ? promise?.user?.payload?.nick
+                : "user"}
+              , ваша библиотека пуста.
+            </h2>
           )}
         </div>
       ) : (
@@ -40,8 +46,5 @@ const Library = ({ auth, promise, actionTracks, actionUser }) => {
 
 export const CLibrary = connect(
   (state) => ({ auth: state.auth, promise: state.promise }),
-  {
-    actionTracks: actionFindTracks,
-    actionUser: actionFindUser,
-  }
+  null
 )(Library);

+ 12 - 7
src/pages/Search.js

@@ -14,13 +14,21 @@ const Search = ({ auth, promise }) => {
         <div className="d-block mx-auto mt-2 container w-50">
           <h1 className="text-center">Поиск по сайту</h1>
           <SearchField />
-          <PlayerHeader />
-          {promise?.tracks?.payload ? (
+          {promise?.tracks?.payload?.length !== 0 ? <PlayerHeader /> : null}
+          {promise.tracks.status === "PENDING" ? (
+            <Loader />
+          ) : promise?.tracks?.payload &&
+            promise?.tracks?.payload?.length !== 0 ? (
             promise.tracks.payload.map((track, index) => (
               <CTrack audio={track} index={index} key={Math.random()} />
             ))
           ) : (
-            <Loader />
+            <h2 className="mt-5 text-center">
+              {promise?.user?.payload?.nick
+                ? promise?.user?.payload?.nick
+                : "user"}
+              , на сайте не обнаружено треков.
+            </h2>
           )}
         </div>
       ) : (
@@ -34,8 +42,5 @@ const Search = ({ auth, promise }) => {
 
 export const CSearch = connect(
   (state) => ({ auth: state.auth, promise: state.promise }),
-  {
-    actionTracks: actionFindTracks,
-    actionUser: actionFindUser,
-  }
+  null
 )(Search);