<repo_name>thinhtanpham/Intify-Music-App-Mobile<file_sep>/Intify-new/Server/config/deleteFile.js
const fs = require("fs");
const rimraf = require("rimraf");
const path = require("path");
module.exports = function deleteFile(uploadDir) {
    uploadDir = "public/" + uploadDir.slice(25);
    try {
        fs.unlinkSync(uploadDir);
    } catch (err) {
        console.error(err);
    }
};
<file_sep>/Intify-new/Server/Router/index.js
const MusicRouter= require('./MusicRouter')
const UserRouter= require('./UserRouter')

function router (app) {

    app.use('/', MusicRouter)
    app.use('/account', UserRouter)
}

module.exports = router<file_sep>/Intify-new/Intify/Component/Login.js
import React, {Component} from 'react';
import {
  StyleSheet,
  Text,
  View,
  TextInput,
  Button,
  TouchableHighlight,
  Image,
  Alert,
} from 'react-native';
import AsyncStorage from '@react-native-async-storage/async-storage';
import LinearGradient from 'react-native-linear-gradient';
import api from '../api';

export default class LoginView extends Component {
  constructor(props) {
    super(props);
    this.state = {
      username: '',
      password: '',
      success: true,
    };
  }

  async Login(navigation) {
    try {
      const response = await fetch('http://'+api+':5000/account/checkLogin', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          username: this.state.username,
          password: <PASSWORD>,
        }),
      });
      if (response.status === 500) {
        this.setState({
          success: !this.state.success,
        });
        setTimeout(() => {
          this.setState({
            success: !this.state.success,
          });
        }, 4000);
      } else {
        const json = await response.json();
        try {
          await AsyncStorage.setItem(
            '@storage_accessToken',
            json.message.accessToken,
          );
          await AsyncStorage.setItem(
            '@storage_refreshToken',
            json.message.refreshToken,
          );
          console.log("ass: " +await AsyncStorage.getItem(
            '@storage_accessToken'
          ))
          console.log("ref: " +await AsyncStorage.getItem(
            '@storage_refreshToken'
          ))
          navigation.replace('User');
        } catch (error) {
          console.log(error);
        }
      }
    } catch (error) {
      console.error(error);
    }
  }

  render() {
    const {navigation} = this.props;
    return (
      <LinearGradient colors={['#52697A', '#5A6C91']} style={{flex: 1}}>
        <Image style={styles.imgLogo} source={require('./src/img/logo2.png')} />
        <View style={styles.container}>
          <Text style={styles.warningText}>
            {' '}
            {this.state.success ? '' : '*Wrong Username or Password'}
          </Text>
          <View style={styles.inputContainer}>
            <TextInput
              style={styles.inputs}
              placeholder="Username"
              underlineColorAndroid="transparent"
              onChangeText={username => this.setState({username})}
            />
          </View>

          <View style={styles.inputContainer}>
            <TextInput
              style={styles.inputs}
              placeholder="<PASSWORD>"
              secureTextEntry={true}
              underlineColorAndroid="transparent"
              onChangeText={password => this.setState({password})}
            />
          </View>

          <TouchableHighlight
            style={[styles.buttonContainer, styles.loginButton]}
            onPress={() => this.Login(navigation)}>
            <Text style={styles.loginText}>Login</Text>
          </TouchableHighlight>

          {/* <TouchableHighlight
          style={styles.buttonContainer}
          onPress={}>
          <Text>Forgot your password?</Text>
        </TouchableHighlight>

        <TouchableHighlight
          style={styles.buttonContainer}
          onPress={}>
          <Text>Register</Text>
        </TouchableHighlight> */}
        </View>
      </LinearGradient>
    );
  }
}

const styles = StyleSheet.create({
  imgLogo: {
    height: 200,
    width: 200,
    marginLeft: 'auto',
    marginRight: 'auto',
    marginTop: 50,
  },
  container: {
    marginTop: 50,
    flex: 1,
    alignItems: 'center',
  },
  inputContainer: {
    borderBottomColor: '#F5FCFF',
    backgroundColor: '#FFFFFF',
    borderRadius: 5,
    borderBottomWidth: 1,
    width: 300,
    height: 45,
    marginBottom: 30,
    flexDirection: 'row',
    alignItems: 'center',
  },
  inputs: {
    height: 45,
    marginLeft: 16,
    borderBottomColor: '#FFFFFF',
    flex: 1,
  },
  inputIcon: {
    width: 30,
    height: 30,
    marginLeft: 15,
    justifyContent: 'center',
  },
  buttonContainer: {
    height: 45,
    flexDirection: 'row',
    justifyContent: 'center',
    alignItems: 'center',
    marginBottom: 20,
    marginTop: 50,
    width: 250,
    borderRadius: 5,
  },
  loginButton: {
    backgroundColor: '#F7FA43',
  },
  loginText: {
    color: 'black',
    fontWeight: 'bold',
    fontSize: 15,
  },
  warningText: {
    color: 'red',
    marginBottom: 5,
    fontSize: 12,
  },
});
<file_sep>/Intify-new/Intify/Redux/Reducer/isPlayingReducer.js
import { is } from 'immer/dist/internal';
import {ADD_PLAYING, RE_PLAYING} from '../Type/isPlayingType';

const isPlaying = {
    rePlaying: {},
    isPlaying: {},
};

function isPlayingReducer(state = isPlaying, action) {
switch (action.type) {
    case ADD_PLAYING:
        state.isPlaying = action.music
        state.isPlaying = {...state.isPlaying}
        return {...state};

    case RE_PLAYING:
        state.rePlaying = action.music;
        state.rePlaying = {...state.rePlaying};
        return {...state};

    default:
        return {...state};
}
}

export default isPlayingReducer;
<file_sep>/Intify-new/Server/Model/Music.js
const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const Music = new Schema(
  {
    nameSong: { type: String, required: true },
    nameArtist: { type: String, required: true },
    idUser: { type: String, required: true},
    img: { type: String, required: true },
    mp3: { type: String, required: true },
  },
  {
    timestamps: true,
  }
);

module.exports = mongoose.model("Music", Music);
<file_sep>/Intify-new/Server/config/mongooseConvert.js
module.exports= {
    arrayObjMongoose: function (mongoose) {
        return mongoose.map(mongoose => mongoose.toObject())
    },

    objMongoose: function (mongoose) {
        console.log(mongoose.toObject())
        return mongoose ? mongoose.toObject() : mongoose
    }
}<file_sep>/README.md
# Intify-Music-App-Mobile
 PRM
<file_sep>/Intify-new/Server/Router/MusicRouter.js
const express = require("express");
const MusicController = require("../Controller/MusicController");
const Music = require("../Model/Music");
const router = express.Router();
const multer = require("multer");
const { isImg, isSong } = require("../config/compareFile");
const jwt = require('jsonwebtoken')
const authenticateToken = require('../config/authenticate')

const storage = multer.diskStorage({
  
  destination: function (req, file, cb) {
    if (isImg(file.fieldname)) {
      cb(null, "public/uploads/imgSong");
    } else if (isSong(file.fieldname)) {
      cb(null, "public/uploads/mp3");
    }
  },
  filename: function (req, file, cb) {
    //const fileType = file.originalname.split(".");
    if (isImg(file.fieldname)) {
      cb(null, req.body.nameSong.split(' ').join('-') + "-" + req.body.nameArtist.split(' ').join('-') +".jpg");
    } else if (isSong(file.fieldname)) {
      cb(null, req.body.nameSong.split(' ').join('-') + "-" + req.body.nameArtist.split(' ').join('-') +".mp3");
    }
  },
});

const upload = multer({ storage: storage });
const newSingUpload = upload.fields([{ name: "img" }, { name: "mp3" }]);

router.get("/", MusicController.showListMusic);
router.get("/artists", MusicController.showListArtist);
router.get("/musics/:id", MusicController.musicsOfArtist);
router.post("/add/newSong",authenticateToken, newSingUpload, MusicController.addNewMusic);
// router.put("/editMusic/:_id",authenticateToken, MusicController.editMusic)
router.delete("/delete/:id",MusicController.deleteMusic)


module.exports = router;
<file_sep>/Intify-new/Intify/Redux/Action/isPlayingAction.js
import {ADD_PLAYING, RE_PLAYING} from '../Type/isPlayingType';

export function addPlaying(music) {
    return {
        type: ADD_PLAYING,
        music
    };
}

export function rePlaying(music) {
    return {
        type: RE_PLAYING,
        music
    };
}
<file_sep>/Intify-new/Intify/Component/UserComponent/UploadMusic.js
import React, {useState} from 'react';
import {
  StyleSheet,
  Text,
  View,
  TouchableOpacity,
  TextInput,
} from 'react-native';
import Modal from 'react-native-modal';
import DocumentPicker from 'react-native-document-picker';
import AsyncStorage from '@react-native-async-storage/async-storage';
import refreshToken from '../../refreshToken';
import StatusModal from './StatusModal';
import api from '../../api';

const UploadMusic = () => {
  const [imgUpload, setImgUpload] = useState(null);
  const [mp3Upload, setMp3Upload] = useState(null);
  const [nameSong, setNameSong] = useState('');
  const [nameArtist, setNameArtist] = useState('');
  const [stateUpload, setStateUpload] = useState('');
  const [status, setStatus] = useState(false);
  const [nullField, setNullField] = useState(false);

  const uploadSong = async e => {
    if (
      imgUpload != null &&
      mp3Upload != null &&
      nameSong.nameSong.length !== 0 && 
      nameArtist.nameArtist.length !== 0
    ) {
      setStateUpload('Waiting...');
      setStatus(true);
      const data = new FormData();
      data.append('nameSong', nameSong.nameSong);
      data.append('nameArtist', nameArtist.nameArtist);
      data.append('img', {
        uri: imgUpload[0].uri,
        type: imgUpload[0].type,
        name: imgUpload[0].name,
      });
      data.append('mp3', {
        uri: mp3Upload[0].uri,
        type: mp3Upload[0].type,
        name: mp3Upload[0].name,
      });
      try {
        const asAccessTk = await AsyncStorage.getItem('@storage_accessToken');
        await fetch('http://' + api + ':3002/add/newSong', {
          method: 'post',
          headers: {
            Accept: 'application/json',
            type: 'formData',
            authorization: 'Bearer ' + asAccessTk,
          },
          body: data,
        })
          .then(async response => {
            const resJs = await response.json();
            if (resJs.status === 200) {
              setStateUpload('Upload Successfull');
              e.persist();
              setTimeout(() => setStatus(false), 3000);
            }
          })
          .catch(async error => {
            refreshToken();
            try {
              const asAccessTk = await AsyncStorage.getItem(
                '@storage_accessToken',
              );
              await fetch('http://' + api + ':3002/add/newSong', {
                method: 'post',
                headers: {
                  Accept: 'application/json',
                  type: 'formData',
                  authorization: 'Bearer ' + asAccessTk,
                },
                body: data,
              })
                .then(async response => {
                  const resJs = await response.json();
                  if (resJs.status === 200) {
                    setStateUpload('Upload Successfull');
                    e.persist();
                    setTimeout(() => setStatus(false), 3000);
                  }
                })
                .catch(error => {
                  if (error) {
                    setStateUpload('Upload Failed');
                    e.persist();
                    setTimeout(() => setStatus(false), 3000);
                  }
                });
            } catch (error) {
              if (error) {
                setStateUpload('Upload Failed');
                e.persist();
                setTimeout(() => setStatus(false), 3000);
              }
            }
          });
      } catch (error) {
        if (error) {
          setStateUpload(false);
          e.persist();
          setTimeout(() => setStatus(false), 3000);
        }
      }
    } else {
      setNullField(true);
      e.persist();
      setTimeout(() => setNullField(false), 5000);
    }
  };

  const selectImage = async () => {
    try {
      const res = await DocumentPicker.pick({
        type: DocumentPicker.types.images,
      });
      setImgUpload(res); //setState
    } catch (err) {
      console.log(err);
    }
  };

  const selectMp3 = async () => {
    try {
      const res = await DocumentPicker.pick({
        type: DocumentPicker.types.audio,
      });
      setMp3Upload(res); //setState
    } catch (err) {
      console.log(err);
    }
  };
  return (
    <View style={styles.mainBody}>
      <StatusModal status={status} stateUpload={stateUpload} />
      <View style={{justifyContent: 'center'}}>
        {nullField ? (
          <Text style={styles.textErr}>* Not null field</Text>
        ) : (
          <Text style={styles.textErr}></Text>
        )}
        <View style={styles.inputContainer}>
          <TextInput
            style={styles.inputs}
            placeholder="name-song"
            underlineColorAndroid="transparent"
            onChangeText={nameSong => setNameSong({nameSong})}
          />
        </View>
        <View style={styles.inputContainer}>
          <TextInput
            style={styles.inputs}
            placeholder="name-artist"
            underlineColorAndroid="transparent"
            onChangeText={nameArtist => setNameArtist({nameArtist})}
          />
        </View>
        <TouchableOpacity
          style={styles.buttonStyle}
          activeOpacity={0.5}
          onPress={selectImage}>
          <Text style={styles.buttonTextStyle}>Select Image</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.buttonStyle}
          activeOpacity={0.5}
          onPress={selectMp3}>
          <Text style={styles.buttonTextStyle}>Select File</Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={styles.buttonStyle}
          activeOpacity={0.5}
          onPress={uploadSong}>
          <Text style={styles.buttonTextStyle}>Upload File</Text>
        </TouchableOpacity>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  mainBody: {
    flex: 1,
    justifyContent: 'center',
    padding: 20,
  },
  buttonStyle: {
    backgroundColor: '#307ecc',
    borderWidth: 0,
    color: '#FFFFFF',
    borderColor: '#307ecc',
    height: 40,
    alignItems: 'center',
    borderRadius: 30,
    marginLeft: 35,
    marginRight: 35,
    marginTop: 15,
  },
  buttonTextStyle: {
    color: '#FFFFFF',
    paddingVertical: 10,
    fontSize: 16,
  },
  textStyle: {
    backgroundColor: '#fff',
    fontSize: 15,
    marginTop: 16,
    marginLeft: 35,
    marginRight: 35,
    textAlign: 'center',
  },
  inputContainer: {
    borderBottomWidth: 1,
    width: 300,
    height: 45,
    marginBottom: 10,
    flexDirection: 'row',
    marginRight: 'auto',
    marginLeft: 'auto',
  },
  inputs: {
    height: 45,
    marginLeft: 12,
    borderBottomColor: '#FFFFFF',
    flex: 1,
  },
  textErr: {
    height: 20,
    color: 'red',
    marginLeft: 'auto',
    marginRight: 'auto',
  },
  modal: {
    width: 350,
    backgroundColor: 'white',
    borderRadius: 5,
    marginTop: 250,
    marginBottom: 250,
    marginLeft: 'auto',
    marginRight: 'auto',
  },
});

export default UploadMusic;
<file_sep>/Intify-new/Intify/App.js
import React, {useState} from 'react';
import {StyleSheet, StatusBar, Button, Text} from 'react-native';
import ListMusics from './Component/ListMusics';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import FullMusic from './Component/FullMusic';
import ListMusicsArtist from './Component/ListMusicsArtist'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome';
import {faUserCircle} from '@fortawesome/free-solid-svg-icons';
import LoginView from './Component/Login';
import UploadMusic from './Component/UserComponent/UploadMusic';
import AsyncStorage from '@react-native-async-storage/async-storage';
import User from './Component/User';
import {Provider as StoreProvider} from 'react-redux';
import rootStore from './Redux/store';
import Context from './Component/Context'

const Stack = createNativeStackNavigator();


function App() {
  const [isPlaying, setPlaying] = useState({});
  return (
    <StoreProvider store={rootStore}>
      <NavigationContainer>
        <Context.Provider
          value={{
            isPlaying: isPlaying,
            setMusicPlaying: isPlaying => { 
              setPlaying(isPlaying)
            }
          }}>
          <StatusBar hidden={true} />
          <Stack.Navigator initialRouteName="ListMusics">
            <Stack.Screen
              name="ListMusics"
              component={ListMusics}
              isPlaying={({params}) => params}
              options={({navigation}) => ({
                headerTitle: '',
                headerRight: () => (
                  <FontAwesomeIcon
                    icon={faUserCircle}
                    onPress={async () => {
                      try {
                        const asAccessTk = await AsyncStorage.getItem(
                          '@storage_accessToken',
                        );
                        asAccessTk
                          ? navigation.navigate('User')
                          : navigation.navigate('Login');
                      } catch (error) {
                        console.log(error);
                      }
                    }}
                    style={styles.icon}
                    size={25}
                  />
                ),
                headerStyle: {
                  backgroundColor: '#243039',
                },
              })}
            />
            <Stack.Screen
              name="FullMusic"
              component={FullMusic}
              options={({navigation}) => ({
                headerBackVisible: true,
                headerTitle: "",
                headerTintColor: "white",
                headerRight: () => (
                  <FontAwesomeIcon
                    icon={faUserCircle}
                    onPress={async () => {
                      try {
                        const asAccessTk = await AsyncStorage.getItem(
                          '@storage_accessToken',
                        );
                        asAccessTk
                          ? navigation.navigate('User')
                          : navigation.navigate('Login');
                      } catch (error) {
                        console.log(error);
                      }
                    }}
                    style={styles.icon}
                    size={25}
                  />
                ),
                headerStyle: {
                  backgroundColor: '#243039',
                },
              })}
            />
            <Stack.Screen
              name="Login"
              component={LoginView}
              options={{headerStyle: {backgroundColor: '#243039'},
              headerTitleStyle: {color: "white"},
              headerTintColor: "white"
            }}
            />
            <Stack.Screen name="User" component={User} />
            <Stack.Screen name="ListMusicsArtist" component={ListMusicsArtist}
            options={{headerStyle: {backgroundColor: '#243039'}, headerTitle: "", headerTintColor: "white"}}
            />
          </Stack.Navigator>
        </Context.Provider>
      </NavigationContainer>
    </StoreProvider>
  );
}

export default App;

const styles = StyleSheet.create({
  header: {
    backgroundColor: '#243039',
  },
  headerLogin: {
    backgroundColor: '#587788',
  },
  icon: {
    color: 'white',
  },
});
<file_sep>/Intify-new/Server/Controller/MusicController.js
const Music = require("../Model/Music");
const { arrayObjMongoose } = require("../config/mongooseConvert");
const User = require("../Model/User");
const { findOne } = require("../Model/User");
const fs = require("fs");
const path = require("path");
const deleteFile = require("../config/deleteFile");

class MusicController {
  editMusic(req, res, next) {
    User.findOne({ username: req.user.name }, (err, user) => {
      if (err)
        return res.json({
          status: 404,
          descp: err,
        });
      if (!user)
        return res.json({
          status: 404,
        });
      else {
        Music.updateOne({ _id: req.params._id }, req.body)
          .then(
            res.json({
              status: 200,
              descp: "Chinh sua thanh cong",
            })
          )
          .catch((error) =>
            res.json({
              status: 404,
              descp: error,
            })
          );
      }
    });
  }

  //GET ListMusic
  showListMusic(req, res, body) {
    Music.find({})
      .then((music) => res.json({ musics: music }))
      .catch((error) => next(error));
  }

  showListArtist(req, res, body) {
    User.find({ hasUpload: true })
      .then((users) => {
        const arrArtist = [];
        users.map((user) => {
          const artist = {};
          artist.id = user.id;
          artist.nameApp = user.nameApp;
          artist.imgArtist = user.imgArtist;
          arrArtist.push(artist);
        });
        res.json({ artists: arrArtist });
      })
      .catch((error) =>
        res.json({
          status: 404,
          descp: error,
        })
      );
  }

  musicsOfArtist(req, res, body) {
    Music.find({ idUser: req.params.id })
      .then((music) => {
        res.json({
          status: 200,
          musics: music,
        });
      })
      .catch((error) =>
        res.json({
          status: 404,
          err: error,
        })
      );
  }

  //POST AddNewMusic
  addNewMusic(req, res, body) {
    User.findOne({ username: req.user.username }, (err, user) => {
      if (err)
        return res.json({
          status: 404,
          descp: err,
        });
      User.updateOne({ _id: user._id }, { hasUpload: true })
        .then()
        .catch((error) =>
          res.json({
            status: 404,
            descp: error,
          })
        );
      const newMusic = req.body;
      newMusic.idUser = user._id;
      newMusic.img =
        "http://192.168.0.18:3002/" +
        req.files.img[0].path.split("\\").splice(1).join("/");
      newMusic.mp3 =
        "http://192.168.0.18:3002/" +
        req.files.mp3[0].path.split("\\").splice(1).join("/");
      const music = new Music(newMusic);
      music
        .save()
        .then(
          res.json({
            status: 200,
            descp: "create new music success",
          })
        )
        .catch((error) =>
          res.json({
            status: 404,
            descp: error,
          })
        );
    });
  }

  deleteMusic(req, res, body) {
    Music.findById(req.params.id)
      .then((music) => {
        deleteFile(music.img);
        deleteFile(music.mp3);
        Music.findByIdAndDelete(req.params.id)
          .then(
            res.json({
              status: 200,
              msg: "success delete",
            })
          )
          .catch((err) =>
            res.json({
              status: 404,
              msg: err,
            })
          );
      })
      .catch((err) =>
        res.json({
          status: 404,
          msg: err,
        })
      );
  }
}

module.exports = new MusicController();
<file_sep>/Intify-new/Server/DB/dbConnect.js
const mongoose = require('mongoose');

async function Connect () {
    try{
    await mongoose.connect('mongodb://localhost:27017/Intify');
    console.log("kết nối thành công nè")
    } catch(error){
        console.log("lõi nè:" + error)
    }
}

module.exports= {Connect}<file_sep>/Intify-new/Intify/Component/User.js
import React, {Component} from 'react';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import InfomationUser from './UserComponent/InfomationUser';
import UploadMusic from './UserComponent/UploadMusic';
import {StatusBar} from 'react-native';
import MyUpload from './UserComponent/MyUpload';
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome';
import {faUserCircle, faUpload, faClipboardList, faList} from '@fortawesome/free-solid-svg-icons';

const Tab = createBottomTabNavigator();
export default class User extends Component {
  render() {
    return (
      <Tab.Navigator>
        <Tab.Screen
          options={{
            headerShown: false,
            title: "User",
            tabBarIcon: () => <FontAwesomeIcon icon={faUserCircle} size={20} style={{color:"#307ecc"}}/>
          }}
          name="InformationUser"
          component={InfomationUser}
        />
        <Tab.Screen
          options={{
            headerShown: false,
            title: "Upload",
            tabBarIcon: () => <FontAwesomeIcon icon={faUpload} size={20} style={{color:"#307ecc"}}/>
          }}
          name="UploadMusic"
          component={UploadMusic}
        />
        <Tab.Screen
          options={{
            headerShown: false,
            title: "My List",
            tabBarIcon: () => <FontAwesomeIcon icon={faList} size={20} style={{color:"#307ecc"}}/>
          }}
          name="MyList"
          component={MyUpload}
        />
      </Tab.Navigator>
    );
  }
}
<file_sep>/Intify-new/Intify/Component/FullMusic.js
import React, {Component, useEffect} from 'react';
import {Text, Button, View, Image, StyleSheet, FlatList} from 'react-native';
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome';
import {
  faPauseCircle,
  faPlayCircle,
  faEllipsisV,
  faHeart,
  faVolumeUp,
} from '@fortawesome/free-solid-svg-icons';
import Slider from '@react-native-community/slider';
import systemSetting from 'react-native-system-setting';
import {connect} from 'react-redux';
import {addPlaying} from '../Redux/Action/isPlayingAction';
import Context from './Context';
import SplashScreen from './SplashScreen';
import FullLyrics from './ListMusicsArtist'

const Sound = require('react-native-sound');
Sound.setCategory('Playback', true);

class FullMusic extends Component {
  constructor(props) {
    super(props);
    this.state = {
      music: {},
      musicPlaying: {},
      timeDurarion: 0,
      currentTime: 0,
      setTime: {},
      status: true,
      visible: false,
      volume: 0,
    };
  }

  async componentDidMount() {
    await systemSetting.getVolume().then(volume => {
      this.setState({
        volume: volume,
      });
    });
    this.setState(
      {
        music: this.props.rePlaying,
      },
      async () => {
        const musicPlaying = new Sound(
          this.state.music.mp3,
          Sound.MAIN_BUNDLE,
          err => {
            if (err) {
              consoloe.log(err);
            } else {
              musicPlaying.nameArtist = this.state.music.nameArtist;
              musicPlaying.nameSong = this.state.music.nameSong;
              musicPlaying.img = this.state.music.img;
              this.setState({
                musicPlaying: musicPlaying,
                timeDurarion: musicPlaying.getDuration(),
              });
            }
          },
        );
      },
    );
  }

  async componentWillUnmount() {
    clearInterval(this.state.setTime);
  }

  convertTime(time) {
    const mn = Math.floor(time / 60);
    const sc = time % 60;
    return mn + ':' + sc;
  }

  changedVolume(index) {
    systemSetting.setVolume(index);
    this.setState({
      volume: index,
    });
  }

  isEmpty(obj) {
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) return true;
    }
    return false;
  }

  statusMusic(status, value) {
    this.setState(
      {
        status: status,
      },
      async () => {
        const {musicPlaying} = this.state;
        if (status) {
          this.props.addPlaying(musicPlaying);
          clearInterval(this.state.setTime);
          musicPlaying.setCurrentTime(value);
          musicPlaying.play(success => {
            if (success) {
              console.log('successfully finished playing');
            } else {
              console.log('playback failed due to audio decoding errors');
            }
          });
          this.state.setTime = setInterval(() => {
            musicPlaying.getCurrentTime(second => {
              this.setState({
                currentTime: second,
              });
            });
          }, 1000);
        } else {
          musicPlaying.pause();
          clearInterval(this.state.setTime);
          musicPlaying.setCurrentTime(value);
          musicPlaying.getCurrentTime(second => {
            this.setState({
              currentTime: second,
            });
          });
        }
      },
    );
  }

  renderBotView() {
    return (
      <>
        <View style={styles.botPlay}>
          <View style={{flex: 2, flexDirection: 'row'}}>
            <View style={{flex: 1, flexDirection: 'row', marginLeft: 50}}>
              <FontAwesomeIcon
                icon={faVolumeUp}
                size={20}
                onPress={() => {
                  this.setState({
                    visible: !this.state.visible,
                  });
                  setTimeout(() => {
                    this.setState({
                      visible: !this.state.visible,
                    });
                  }, 4000);
                }}
                style={styles.iconVolume}
              />
              {this.state.visible ? (
                <View
                  style={styles.modal}
                  animationType={'fade'}
                  transparent={true}
                  visible={this.state.visible}>
                  <View
                    style={{
                      backgroundColor: 'white',
                      height: 30,
                      width: 175,
                      borderRadius: 15,
                    }}>
                    <Slider
                      style={styles.sliderVolume}
                      minimumValue={0}
                      maximumValue={1}
                      value={this.state.volume}
                      step={0.1}
                      onValueChange={value => this.changedVolume(value)}
                      minimumTrackTintColor="#243039"
                      maximumTrackTintColor="#000000"
                    />
                  </View>
                </View>
              ) : (
                <></>
              )}
            </View>
          </View>

          <View style={styles.sliderView}>
            <Slider
              style={styles.slider}
              minimumValue={0}
              maximumValue={this.state.timeDurarion}
              value={this.state.currentTime}
              onValueChange={value =>
                this.statusMusic(this.state.status, value)
              }
              minimumTrackTintColor="#FFFFFF"
              maximumTrackTintColor="#000000"
            />
            <View style={styles.timeView}>
              <Text>{this.convertTime(parseInt(this.state.currentTime))}</Text>
              <Text>{this.convertTime(parseInt(this.state.timeDurarion))}</Text>
            </View>
          </View>

          <View style={{flexDirection: 'row', flex: 2}}>
            <Context.Consumer>
              {context => (
                <FontAwesomeIcon
                  icon={
                    this.state.musicPlaying._playing
                      ? faPauseCircle
                      : faPlayCircle
                  }
                  onPress={async () => {
                    this.state.musicPlaying._playing
                      ? (context.setMusicPlaying(this.state.musicPlaying),
                        this.statusMusic(false, this.state.currentTime))
                      : (context.setMusicPlaying(this.state.musicPlaying),
                        this.statusMusic(true, this.state.currentTime));
                  }}
                  style={styles.iconPlayPause}
                  size={40}
                />
              )}
            </Context.Consumer>
          </View>
        </View>
      </>
    );
  }

  renderTopView(music) {
    return (
      <>
        <View style={styles.header}>
          <Image source={{uri: music.img}} style={styles.img}></Image>
        </View>
        <View style={styles.title}>
          <FontAwesomeIcon icon={faEllipsisV} style={styles.icon} size={20} />
          <View>
            <Text style={styles.titleNameSong}>
              {music.nameSong.length > 25
                ? music.nameSong.slice(0, 25).concat('...')
                : music.nameSong}
            </Text>
            <Text style={styles.titleNameArtist}>
              {music.nameArtist.length > 30
                ? music.nameArtist.slice(0, 30).concat('...')
                : music.nameArtist}
            </Text>
          </View>
          <FontAwesomeIcon icon={faHeart} style={styles.icon} size={20} />
        </View>
      </>
    );
  }

  render() {
    const {music} = this.state;
    return this.isEmpty(this.state.musicPlaying) ? (
      <View style={styles.main}>
        <View style={styles.viewTop}>{this.renderTopView(music)}</View>
        <View style={styles.viewBot}>{this.renderBotView(music)}</View>
      </View>
    ) : (
      <SplashScreen></SplashScreen>
    );
  }
}

const styles = StyleSheet.create({
  header: {
    flex: 8,
    marginTop: 20,
  },
  title: {
    flex: 2,
    marginTop: 30,
    flexDirection: 'row',
    justifyContent: 'space-around',
  },
  main: {
    flex: 1,
    backgroundColor: '#364855',
    justifyContent: 'space-around',
  },
  img: {
    height: '100%',
    width: 250,
    borderRadius: 5,
    marginLeft: 'auto',
    marginRight: 'auto',
  },
  viewTop: {
    flex: 1,
  },
  viewBot: {
    flex: 1,
    justifyContent: 'flex-end',
    height: 335,
  },
  botPlay: {
    width: '97%',
    flex: 0.9,
    marginRight: 'auto',
    marginLeft: 'auto',
    backgroundColor: 'rgba(96, 103, 109, 0.56)',
    borderTopRightRadius: 10,
    borderTopLeftRadius: 10,
  },
  icon: {
    marginTop: 30,
    color: '#C4C4C4',
  },
  iconPlayPause: {
    marginTop: 30,
    color: '#C4C4C4',
    marginLeft: 'auto',
    marginRight: 'auto',
  },
  iconVolume: {
    marginTop: 30,
    color: '#C4C4C4',
    marginTop: 'auto',
    marginBottom: 'auto',
  },
  titleNameSong: {
    textAlign: 'center',
    color: 'white',
    fontSize: 20,
  },
  titleNameArtist: {
    textAlign: 'center',
    color: 'white',
    fontSize: 15,
  },
  timeView: {
    flexDirection: 'row',
    justifyContent: 'space-around',
  },
  slider: {
    marginRight: 'auto',
    marginLeft: 'auto',
    width: 319,
    height: 40,
  },
  sliderVolume: {
    marginRight: 'auto',
    marginLeft: 'auto',
    marginTop: 'auto',
    marginBottom: 'auto',
    width: 150,
    height: 40,
  },
  sliderView: {
    flex: 1,
  },
  modal: {
    marginTop: 'auto',
    marginBottom: 'auto',
    marginLeft: 10,
    height: 30,
    margin: 0,
  },
  icon: {
    color: '#C4C4C4',
  },
});

const mapStateToProps = state => {
  return {
    rePlaying: state.isPlayingReducer.rePlaying,
    isPlaying: state.isPlayingReducer.isPlaying,
  };
};
const mapDispatchToProps = dispatch => {
  return {
    addPlaying: music => {
      dispatch(addPlaying(music));
    },
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(FullMusic);
<file_sep>/Intify-new/Intify/Component/ListMusicsArtist.js
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome';
import React, {Component} from 'react';
import {View, StyleSheet, Image, Text, Button, ScrollView} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import api from '../api';
import MusicItem from './MusicItem';
import {faUserCircle} from '@fortawesome/free-solid-svg-icons';

export default class ListMusicsArtist extends Component {
  constructor() {
    super();
    this.state = {
      musicsOfArt: [],
    };
  }

  async componentDidMount() {
    try {
      await fetch(
        'http://' + api + ':3002/musics/' + this.props.route.params.id,
      )
        .then(async res => {
          const resJson = await res.json();
          this.setState({
            musicsOfArt: resJson.musics,
          });
        })
        .catch(error => console.error(error));
    } catch (error) {
      console.error(error);
    }
  }

  renderFullLyrics(params) {
    return (
      <>
        <LinearGradient
          colors={['#FFFFFF21', '#FFFFFF00']}
          style={styles.area_Lyric}>
          <View style={{flex: 1}}>
            {params.imgArtist ? (
              <Image
                source={{uri: params.imgArtist}}
                style={styles.img}></Image>
            ) : (
              <FontAwesomeIcon
                style={styles.iconAva}
                icon={faUserCircle}
                size={150}
              />
            )}
            <Text style={styles.name}>{params.nameApp}</Text>
          </View>
          <View style={styles.listMusics}>
            <ScrollView showsVerticalScrollIndicator={false}>
              {this.state.musicsOfArt.map((music, index) => (
                <MusicItem
                  key={index}
                  music={music}
                  navigation={this.props.navigation}
                />
              ))}
            </ScrollView>
          </View>
        </LinearGradient>
      </>
    );
  }

  render() {
    const {params} = this.props.route;
    return (
      <View style={styles.mainFullLyrics}>
        <View style={styles.mainTop}></View>
        <View style={styles.mainBot}>{this.renderFullLyrics(params)}</View>
      </View>
    )
  }
}

const styles = StyleSheet.create({
  mainFullLyrics: {
    backgroundColor: '#364855',
    flex: 1,
  },
  iconAva: {
    top: -100,
    height: 160,
    width: 160,
    borderRadius: 5,
    marginLeft: 'auto',
    marginRight: 'auto',
    color: "#364855"
  },
  mainTop: {
    flex: 1,
  },
  mainBot: {
    flex: 4,
  },
  img: {
    top: -100,
    height: 160,
    width: 160,
    borderRadius: 5,
    marginLeft: 'auto',
    marginRight: 'auto',
  },
  area_Lyric: {
    marginLeft: 'auto',
    marginRight: 'auto',
    flex: 1,
    width: '95%',
    borderTopRightRadius: 10,
    borderTopLeftRadius: 10,
    flexDirection: 'column',
    justifyContent: 'space-evenly',
  },
  listMusics: {
    flex: 4,
  },
  name: {
    color: 'white',
    top: -90,
    fontSize: 25,
    fontWeight: 'bold',
    marginLeft: 'auto',
    marginRight: 'auto',
  },
});
<file_sep>/Intify-new/Intify/Component/Modal-Overlays/SmallPlaying.js
import React, {Component} from 'react';
import {TouchableOpacity, View, Image, Text, StyleSheet} from 'react-native';
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome';
import {faPauseCircle, faPlayCircle} from '@fortawesome/free-solid-svg-icons';
import Slider from '@react-native-community/slider';
import Context from '../Context';
import {icon} from '@fortawesome/fontawesome-svg-core';

export default class SmallPlaying extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isPlaying: this.props.music._playing,
    };
  }

  isEmpty(obj) {
    for (var key in obj) {
      if (obj.hasOwnProperty(key)) return true;
    }
    return false;
  }

  render() {
    const {music} = this.props;
    if (this.isEmpty(music)) {
      return (
        <View style={styles.itemView}>
          <View style={{marginBottom: 'auto', marginTop: 'auto'}}>
            <Image source={{uri: music.img}} style={styles.img}></Image>
          </View>
          <View style={styles.itemContent}>
            <View style={{flexDirection: 'row', flex: 1}}>
              <Text style={styles.titleNameSong}>{music.nameSong}</Text>
              <Text style={styles.titleNameSong}> - </Text>
              <Text style={styles.titleNameArtist}>{music.nameArtist}</Text>
            </View>
            <View style={{flexDirection: 'row', flex: 1}}>
              {/* <Context.Consumer>
              {(context) =>
                 */}
              <FontAwesomeIcon
                icon={this.state.isPlaying ? faPlayCircle : faPauseCircle}
                onPress={async () => {
                  music._playing
                    ? (this.setState({
                        isPlaying: !this.state.isPlaying,
                      }),
                      music.pause())
                    : (this.setState({
                        isPlaying: !this.state.isPlaying,
                      }),
                      music.play());
                }}
                style={styles.iconPlayPause}
                size={30}
              />
              {/* }
            </Context.Consumer> */}
            </View>
          </View>
        </View>
      );
    } else {
      return <></>;
    }
  }
}

const styles = StyleSheet.create({
  itemView: {
    backgroundColor: 'white',
    flexDirection: 'row',
    height: 82,
    zIndex: 3,
  },
  itemContent: {
    flexDirection: 'column',
    marginLeft: 'auto',
    marginRight: 'auto',
  },
  img: {
    marginLeft: 20,
    height: 75,
    width: 75,
    borderRadius: 5,
  },
  titleNameSong: {
    marginTop: 'auto',
    marginBottom: 'auto',
    color: 'black',
    fontSize: 15,
  },
  titleNameArtist: {
    marginTop: 'auto',
    marginBottom: 'auto',
    color: 'black',
    fontSize: 15,
  },
  iconPlayPause: {
    color: '#C4C4C4',
    marginLeft: 'auto',
    marginRight: 'auto',
  },
  slider: {
    marginRight: 'auto',
    marginLeft: 'auto',
    width: 250,
    height: 40,
  },
});
<file_sep>/Intify-new/Intify/Component/UserItem.js
import React, {Component} from 'react';
import {View, Text, StyleSheet, Image, TouchableOpacity} from 'react-native';
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome';
import {faUserCircle} from '@fortawesome/free-solid-svg-icons';

export default class UserItem extends Component {
  render() {
    const {artist, navigation} = this.props;
    return (
      <TouchableOpacity onPress={()=> {
        navigation.push('ListMusicsArtist', artist)
        }} >
      <View style={styles.view}>
        {artist.imgArtist ? (
          <Image
            style={styles.imgAvaBac}
            source={{uri: artist.imgArtist}}
            blurRadius={100}></Image>
        ) : (
          <FontAwesomeIcon
            style={styles.avatar}
            icon={faUserCircle}
            size={150}
          />
        )}
        <Image style={styles.imgAvaBac2} source={{uri: artist.imgArtist}} blurRadius={20}></Image>
        <Image style={styles.imgAva} source={{uri: artist.imgArtist}}></Image>
        <Text style={styles.name}>{artist.nameApp}</Text>
      </View>
      </TouchableOpacity>
    );
  }
}

const styles = StyleSheet.create({
  view: {
    marginBottom: 'auto',
    marginTop: 'auto',
    height: 200,
    width: 200,
    marginLeft: 20,
    marginRight: 10,
  },
  avatar: {
    marginBottom: 20,
    marginLeft: 'auto',
    marginRight: 'auto',
    color: '#307ecc',
  },
  name: {
    position: 'absolute',
    marginTop: -13,
    shadowColor: "black",
    textShadowOffset: { width: 2, height: 2 },
    textShadowRadius:10,
    marginLeft: 20,
    color: 'white',
    fontSize: 25,
    fontWeight: 'bold',
    textAlign: 'center',
  },
  imgAva: {
    height: 152,
    width: 152,
    marginTop: 20,
    borderWidth: 1,
    borderRadius: 10,
    marginLeft: 50,
    marginRight: 'auto',
  },
  imgAvaBac: {
    position: 'absolute',
    height: 172,
    width: 172,
    top: -10,
    left: 10,
    opacity: 0.2,
    borderWidth: 2,
    borderRadius: 10,
    marginLeft: 'auto',
    marginRight: 'auto',
  },
  imgAvaBac2: {
    position: 'absolute',
    height: 162,
    width: 162,
    top: 5,
    left: 30,
    opacity: 0.3,
    borderWidth: 2,
    borderRadius: 10,
    marginLeft: 'auto',
    marginRight: 'auto',
  },
});
<file_sep>/Intify-new/Intify/Component/ListMusics.js
import React, {Component} from 'react';
import {View, ScrollView, StyleSheet, Text, RefreshControl, StatusBar} from 'react-native';
import getListMusic from '../Server';
import MusicItem from './MusicItem';
import LinearGradient from 'react-native-linear-gradient';
import FullMusic from './FullMusic';
import {connect} from 'react-redux';
import {thisExpression} from '@babel/types';
import SmallPlaying from './Modal-Overlays/SmallPlaying';
import Context from './Context'
import SplashScreen from './SplashScreen';
import UserItem from './UserItem';
import { combineReducers } from 'redux';
import api from '.././api'

export default class ListMusics extends Component {
  constructor(props) {
    super(props);
    this.state = {
      musicsList: [],
      artistsList: [],
      music: {},
      refresh: false
    };
  }

  callApiMyList() {
    getListMusic()
    .then(json => {
      this.setState({musicsList: json.musics});
    })
    .catch(err => consoloe.log(err));
  }

  async componentDidMount() {
    this.callApiMyList()
    try {
      await fetch('http://'+ api +':3002/artists')
      .then(async res => {
        const resJson = await res.json()
        this.setState({
          artistsList: resJson.artists
        })
      })
      .catch(error => console.error(error))
    } catch (error) {
      console.error(error);
    }
  }

  refreshList(){
    this.setState({
      refresh: !this.state.refresh
    })
    this.callApiMyList()
    setTimeout(() => {
      this.setState({
        refresh: !this.state.refresh
      })
    }, 2000);    
  }

  render() {
    const {navigation} = this.props;
    return (
      this.state.musicsList.length > 0 ? 
      <View style={{flex: 1, backgroundColor: '#364855'}}>
        <StatusBar hidden={false}  animated={true}
        backgroundColor="#243039"/>
        <View style={styled.topArea}>
          <ScrollView 
          horizontal={true}
          showsHorizontalScrollIndicator={false}>
            {this.state.artistsList.map((artist, index) => 
              <UserItem navigation={navigation} key={index} artist={artist}/>
            )}
          </ScrollView>
        </View>
        <View style={styled.bottomArea}>
          <Text style={styled.allList}>All List</Text>
          <LinearGradient
            colors={['#FFFFFF15', '#FFFFFF01']}
            style={styled.scrollView}>
            <ScrollView
            refreshControl={
              <RefreshControl
                refreshing={this.state.refresh}
                onRefresh={() => this.refreshList(this.state.refresh)}
              />
            }>
              {this.state.musicsList.map((music, index) => (
                <MusicItem navigation={navigation} music={music} key={index} />
              ))}
            </ScrollView>
          </LinearGradient>
        </View>
        <Context.Consumer>{context => <SmallPlaying music={context.isPlaying}/>}
        </Context.Consumer>
      </View>
      :
      <SplashScreen></SplashScreen>
    );
  }
}

const styled = StyleSheet.create({
  bottomArea: {
    flex: 6,
    marginLeft: 5,
    marginRight: 5,
    borderTopLeftRadius: 5,
    borderTopRightRadius: 5,
  },
  topArea: {
    flex: 4,
  },
  scrollView: {
    flex: 1,
    marginLeft: 'auto',
    marginRight: 'auto',
    width: '99.5%',
    borderTopRightRadius: 5,
    borderTopLeftRadius: 5,
  },
  allList: {
    fontSize: 30,
    color: 'white',
  },
});


