Skip to content

Commit

Permalink
Add to playlist - Add ability to add to multiple playlists at once #141
Browse files Browse the repository at this point in the history
  • Loading branch information
mgireesha committed May 5, 2024
1 parent 8fd9d7b commit 748ac0d
Show file tree
Hide file tree
Showing 16 changed files with 295 additions and 21 deletions.
46 changes: 41 additions & 5 deletions src/g-player-react/src/Components/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1660,21 +1660,21 @@ body{
display: grid;
grid-template-columns: 1fr 1fr;

img{
img, a{
height: 4.5em;
width: 4.5em;
}

img:first-child{
>img:first-child, a:first-child img{
border-top-left-radius: 5px;
}
img:nth-child(2){
>img:nth-child(2), a:nth-child(2) img{
border-top-right-radius: 5px;
}
img:nth-child(3){
>img:nth-child(3), a:nth-child(3) img{
border-bottom-left-radius: 5px;
}
img:last-child{
>img:last-child, a:last-child img{
border-bottom-right-radius: 5px;
}
}
Expand Down Expand Up @@ -2660,6 +2660,42 @@ a.disabled-click{

}

.playlist-selector-v2{
display: flex;
flex-wrap: wrap;
column-gap: 20px;
row-gap: 10px;
justify-content: space-between;
padding: 0 5px;

.row{
border: 1px solid;
padding: 5px;
border-radius: 4px;
width: 10em;
text-wrap: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: center;
justify-content: center;
cursor: pointer;
label{
cursor: pointer;
}
}

// .row:hover{
// text-wrap: unset;
// }

.row.selected{
background-color: #0e684b;
color: beige;
}
}



.playlist-selector::-webkit-scrollbar{
width: 5px;
}
Expand Down
10 changes: 8 additions & 2 deletions src/g-player-react/src/Components/playlist/PlaylistImg.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import React, { useEffect, useState } from "react";
import def_album_art from '../images/def_album_art.png';
import { Link } from "react-router-dom";

export const PlaylistImg = ({albumNames}) => {
export const PlaylistImg = ({albumNames, link}) => {
const [albumNameList, setAlbumNameList] = useState([]);

useEffect(()=>{
Expand All @@ -16,7 +17,12 @@ export const PlaylistImg = ({albumNames}) => {
<div className="playlist-img-container">
{albumNameList.length > 0 &&
<div className="playlist-img">
{albumNameList.map((albumName, i) =>
{link && albumNameList.map((albumName, i) =>
<Link key={i} to={`/music/albums/${albumName}`}>
<img src={`/gp_images/albums/${albumName}.jpg`} />
</Link>
)}
{!link && albumNameList.map((albumName, i) =>
<img src={`/gp_images/albums/${albumName}.jpg`} key={i} />
)}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export const PlaylistPageHeader = ({albumNames, songsCount, playAll}) => {

return(
<div className="playlist-page-header">
<PlaylistImg albumNames={albumNames} />
<PlaylistImg albumNames={albumNames} link={true} />
<div className="playlist-details">
<div className="playlist-name">
<h2>{playlistName}</h2>
Expand Down
138 changes: 138 additions & 0 deletions src/g-player-react/src/Components/playlist/PlayllistSelectorV2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import React, { useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import { ADD_TO_NEW_PLAYLIST_LABEL, ALBUM, ARTIST, CREATE, CREATE_LABEL, GENRE, GP_CONTEXT_MENU, INPUT, LANGUAGE, MAIN_CONTAINER, NEW_PLAYLIST_BTN_LABEL, PLAYLIST_NAME, PLAYLIST_SELECTOR, TRACK } from "../redux/GPActionTypes";
import { addToPlaylist, createPlaylist, fetchAssignedPlaylists, fetchAssignedPlaylistsSucc, removeFromPlaylist } from "../redux/playlist/PlaylistActions";
import { PLAYLIST_ADD_TO_PLAYLIST_FAIL, PLAYLIST_ADD_TO_PLAYLIST_SUCCESS } from "../redux/playlist/PlaylistActionTypes";
import { setCommonPopupObj, setShowContextMenu, setShowPlaylistSelector } from "../redux/library/LibraryActions";
import { HiPlus } from 'react-icons/hi';
import { getCreatePlaylistObj } from "./PlalistUtil";

export const PlaylistSelector = () => {
const dispatch = useDispatch();
const playLists = useSelector(state => state.playlist.playlists);
const contextObj = useSelector(state => state.library.contextObj);
const plPhase = useSelector(state => state.playlist.phase);
const assignedPlaylists = useSelector(state => state.playlist.assignedPlaylists);

const [styles, setStyles] = useState({display:'none'});
const [obj, setobj] = useState(null);

useEffect(()=>{
if(contextObj.type === TRACK){
dispatch(fetchAssignedPlaylists(contextObj.type, contextObj.obj.songId));
}else if(contextObj.type === ALBUM){
// console.log(contextObj)
dispatch(fetchAssignedPlaylistsSucc([]));
}
setobj(contextObj.obj);
},[contextObj])

console.log("contextObj: ",contextObj)


useEffect(()=>{
if(contextObj && contextObj.position){
const position = contextObj.position;
const tempStyles = {
left: parseInt(position.x)+185,
width: 'auto',
overflowY:'auto',
maxHeight:'50vh'
}
// const mainContainerHeight = document.getElementById(MAIN_CONTAINER).clientHeight;
// let gpCtxtMenuHeight = document.getElementById(GP_CONTEXT_MENU).clientHeight;
// if(gpCtxtMenuHeight === undefined || gpCtxtMenuHeight === 0)gpCtxtMenuHeight = 160;

// if((mainContainerHeight - position.top) > gpCtxtMenuHeight+ 40){
// tempStyles.top = parseInt(position.y)+25;

// }else{
// tempStyles.top = parseInt(position.y)-gpCtxtMenuHeight;
// }

// const mainContainerWidth = document.getElementById(MAIN_CONTAINER).clientWidth;
// let gpCtxtMenuWidth = document.getElementById(GP_CONTEXT_MENU).clientWidth;
// if(gpCtxtMenuWidth === undefined || gpCtxtMenuWidth === 0)gpCtxtMenuWidth = 200;
// if((mainContainerWidth - position.left) < gpCtxtMenuWidth+40){
// tempStyles.left = parseInt(position.x)-gpCtxtMenuWidth-154;
// }

setStyles(tempStyles);
}
},[contextObj]);

const onAddToPlaylist = (playlistId,playlistName) => {
const reqPLObj = {
playlist: playlistName,
playlistId: playlistId
}
if(contextObj.type === ALBUM){
reqPLObj["albumId"] = parseInt(contextObj.obj.albumId);
reqPLObj["albumName"] = contextObj.obj.albumName;
}else if(contextObj.type === TRACK){
reqPLObj["songId"] = contextObj.obj.songId;
reqPLObj["albumName"] = contextObj.obj.album;
}else if(contextObj.type === LANGUAGE){
reqPLObj["language"] = contextObj.obj;
}else if(contextObj.type === GENRE){
reqPLObj["genre"] = contextObj.obj;
}else if(contextObj.type === ARTIST){
reqPLObj["artist"] = contextObj.obj;
}
dispatch(addToPlaylist(reqPLObj));
}

useEffect(()=>{

if(plPhase === PLAYLIST_ADD_TO_PLAYLIST_SUCCESS || plPhase === PLAYLIST_ADD_TO_PLAYLIST_FAIL){
dispatch(setShowPlaylistSelector(false));
dispatch(setShowContextMenu(false));
}

},[plPhase]);

const addToNewPlayist = () => {
const addToNewPLPopupObj = {
showPopup: true,
title: ADD_TO_NEW_PLAYLIST_LABEL,
content: "Untitled Playlist",
placeHolder:'New Playlist Name',
contentType: INPUT,
primaryBtnAction: CREATE,
primaryBtnLabel:CREATE_LABEL,
className:"create",
elementId:PLAYLIST_NAME,
primaryBtnFun: onAddToNewPlaylist
}
dispatch(setCommonPopupObj(addToNewPLPopupObj));
}

const onAddToNewPlaylist = () => {
const createPlaylistObj = getCreatePlaylistObj();
createPlaylistObj.addedNewPlaylistObj = {isAddToNewPlaylist: true};
dispatch(createPlaylist(createPlaylistObj));
}
const handleOnPlaylistClick = (id, name) => {
if(assignedPlaylists.includes(name)){
dispatch(removeFromPlaylist(id, contextObj.obj.songId))
}else{
onAddToPlaylist(id, name);
}
}

return(
<div id={PLAYLIST_SELECTOR} className="playlist-selector-v2" style={styles}>
<div className="row" style={{display:'flex',width:'100%', border:'none'}}>
{obj && obj.title+" - "+obj.album}
</div>
<div className="row" style={{display:'flex',width:'100%'}} onClick={addToNewPlayist}>
<HiPlus style={{marginTop:4,marginRight:5}} /><label>{NEW_PLAYLIST_BTN_LABEL}</label>
</div>
{playLists && playLists.map(playlist =>
<div className={assignedPlaylists.includes(playlist.name) ? "selected row" : "row"} onClick={()=>handleOnPlaylistClick(playlist.id,playlist.name)} title={playlist.name}>
<label>{playlist.name}</label>
</div>
)}
</div>
);
}
1 change: 1 addition & 0 deletions src/g-player-react/src/Components/redux/GPActionTypes.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export const A_TO_Z = "A_TO_Z";
export const A_TO_Z_DESC = "A_TO_Z_DESC";
export const ADD = 'ADD';
export const ADD_TO_NEW_PLAYLIST_LABEL = 'ADD_TO_NEW_PLAYLIST_LABEL';
export const ADD_TOPLAYLIST_LABEL = 'Add to Playlist';
export const ALBUM = 'ALBUM';
export const ALBUM_LABEL = 'Album';
export const ALBUMS = 'ALBUMS';
Expand Down
4 changes: 4 additions & 0 deletions src/g-player-react/src/Components/redux/GPApis.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,10 @@ export const exportPlaylistsAPI = () => {
export const importPlaylistsAPI = (payload, fileType) => {
return iAxios.post(`/playlist/import/${fileType}`, JSON.stringify(payload)).then(response => response);
}

export const fetchAssignedPlaylistsAPI = (payload) => {
return iAxios.get(`/playlist/playlists/${payload.objType}/identifier/${payload.identifier}`).then(response => response);
}
//Playlist - End

//Edit metadata - start
Expand Down
5 changes: 3 additions & 2 deletions src/g-player-react/src/Components/redux/GPSaga.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { onDeleteMusicPath, onEditAlbumInfo, onEditTrackInfo, onFetchAlbum, onFetchAlbumimgs, onFetchAlbumListOfAA, onFetchAlbumsByGenre, onFetchAlbumTracks, onFetchAllAlbumArtistsDtls, onFetchAllAlbumDtls, onFetchAllAlbums, onFetchAllArtistsDtls, onFetchAllHistory, onFetchAllSongs, onFetchBuildStatus, onFetchGenreDetails, onFetchLanguageDetails, onFetchMessagesByType, onFetchMostPlayedData, onFetchMusicPath, onFetchSongsByArtist, onFetchSongsByGenre, onFetchSongsByLanguage, onInitArtistImgDownload, onInitDeltaLibraryBuild, onInitLibraryBuild, onsaveMusicPath, onSearchByKey, onUpdateHistory, onUploadArtistImg } from "./library/LibrarySaga";
import {all} from 'redux-saga/effects'
import { onDeleteLyrics, onFetchCurrentSongAndStatus, onFetchCurrentSongStatus, onPlayASong, onPlayPause, onSetMediaVolume, onSetPlayBackTime, onUpdateLyrics } from "./player/PlayerSaga";
import { onAddToPlaylist, onCreatePlaylist, onDeletePlaylist, onExportPlaylists, onFetchPlaylistNames, onFetchSongsInPlaylist, onImportPlaylists, onRemoveFromPlaylist, onRenamePlaylist } from "./playlist/PlaylistSaga";
import { onAddToPlaylist, onCreatePlaylist, onDeletePlaylist, onExportPlaylists, onFetchAssignedPlaylits, onFetchPlaylistNames, onFetchSongsInPlaylist, onImportPlaylists, onRemoveFromPlaylist, onRenamePlaylist } from "./playlist/PlaylistSaga";

export function* GPSaga(){
yield all([
Expand Down Expand Up @@ -51,6 +51,7 @@ export function* GPSaga(){
onFetchSongsByLanguage(),
onEditTrackInfo(),
onEditAlbumInfo(),
onFetchMessagesByType()
onFetchMessagesByType(),
onFetchAssignedPlaylits()
])
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,8 @@ export const PLAYLIST_EXPORT_PLAYLISTS_FAIL = 'PLAYLIST_EXPORT_PLAYLISTS_FAIL';
export const PLAYLIST_IMPORT_PLAYLISTS_START = 'PLAYLIST_IMPORT_PLAYLISTS_START';
export const PLAYLIST_IMPORT_PLAYLISTS_SUCCESS= 'PLAYLIST_IMPORT_PLAYLISTS_SUCCESS';
export const PLAYLIST_IMPORT_PLAYLISTS_FAIL = 'PLAYLIST_IMPORT_PLAYLISTS_FAIL';
export const PLAYLIST_FETCH_ASSIGNED_PLAYLISTS_START = 'PLAYLIST_FETCH_ASSIGNED_PLAYLISTS_START';
export const PLAYLIST_FETCH_ASSIGNED_PLAYLISTS_SUCCESS = 'PLAYLIST_FETCH_ASSIGNED_PLAYLISTS_SUCCESS';
export const PLAYLIST_FETCH_ASSIGNED_PLAYLISTS_FAILURE = 'PLAYLIST_FETCH_ASSIGNED_PLAYLISTS_FAILURE';

export const SET_ADDED_NEW_PLAYLIST_OBJ = 'SET_ADDED_NEW_PLAYLIST_OBJ';
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { PLAYLIST_ADD_TO_PLAYLIST_FAIL, PLAYLIST_ADD_TO_PLAYLIST_START, PLAYLIST
PLAYLIST_CREATE_PLAYLIST_START, PLAYLIST_CREATE_PLAYLIST_SUCCESS,
PLAYLIST_DELETE_PLAYLIST_START, PLAYLIST_DELETE_PLAYLIST_SUCCESS,
PLAYLIST_EXPORT_PLAYLISTS_START, PLAYLIST_EXPORT_PLAYLISTS_SUCCESS,
PLAYLIST_FETCH_ASSIGNED_PLAYLISTS_START,
PLAYLIST_FETCH_ASSIGNED_PLAYLISTS_SUCCESS,
PLAYLIST_FETCH_PLAYLIST_NAMES_START, PLAYLIST_FETCH_PLAYLIST_NAMES_SUCCESS,
PLAYLIST_FETCH_SONGS_IN_PLAYLIST_START, PLAYLIST_FETCH_SONGS_IN_PLAYLIST_SUCCESS,
PLAYLIST_IMPORT_PLAYLISTS_START, PLAYLIST_IMPORT_PLAYLISTS_SUCCESS,
Expand Down Expand Up @@ -36,9 +38,9 @@ export const addToPlaylist = (reqPLObj) => ({
reqPLObj
})

export const addToPlaylistSucc = (playlists) => ({
export const addToPlaylistSucc = (response) => ({
type:PLAYLIST_ADD_TO_PLAYLIST_SUCCESS,
playlists
response
})

export const addToPlaylistFail = (error) => ({
Expand Down Expand Up @@ -110,6 +112,17 @@ export const importPlaylistsSucc = () => ({
type: PLAYLIST_IMPORT_PLAYLISTS_SUCCESS
})

export const fetchAssignedPlaylists = (objType, identifier) => ({
type: PLAYLIST_FETCH_ASSIGNED_PLAYLISTS_START,
objType,
identifier
})

export const fetchAssignedPlaylistsSucc = (response) => ({
type: PLAYLIST_FETCH_ASSIGNED_PLAYLISTS_SUCCESS,
response
})

export const getUpdatedPlayListNames = (playlists, playlist, action) => {
if(action === ADD){
return [...playlists, playlist];
Expand Down Expand Up @@ -140,4 +153,13 @@ export const removeRemovedSongFromPlaylist = (playlistSongs, playlistItem) => {
}
}
return playlistSongs;
}

export const getUpdatedAssignedPlaylits = (assignedPlaylists, plItem, action) => {
if(action === ADD){
assignedPlaylists.push(plItem.playlist);
}else{
assignedPlaylists = assignedPlaylists.filter(pl=>pl!=plItem.playlist);
}
return assignedPlaylists;
}
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { ADD, INIT, LOADING, PLAYLIST_ALBUMS, PLAYLIST_NAMES, PLAYLIST_SONGS_COUNT, REMOVE, RENAME, SUCCESS } from "../GPActionTypes";
import { PLAYLIST_ADD_TO_PLAYLIST_FAIL, PLAYLIST_ADD_TO_PLAYLIST_SUCCESS, PLAYLIST_CREATE_PLAYLIST_START, PLAYLIST_CREATE_PLAYLIST_SUCCESS, PLAYLIST_DELETE_PLAYLIST_START, PLAYLIST_DELETE_PLAYLIST_SUCCESS, PLAYLIST_FETCH_PLAYLIST_NAMES_START, PLAYLIST_FETCH_PLAYLIST_NAMES_SUCCESS, PLAYLIST_FETCH_SONGS_IN_PLAYLIST_START, PLAYLIST_FETCH_SONGS_IN_PLAYLIST_SUCCESS, PLAYLIST_REMOVE_FROM_PLAYLIST_START, PLAYLIST_REMOVE_FROM_PLAYLIST_SUCCESS, PLAYLIST_RENAME_PLAYLIST_START, PLAYLIST_RENAME_PLAYLIST_SUCCESS, SET_SHOW_CREATE_PLAYLIST_POPUP } from "./PlaylistActionTypes";
import { getUpdatedPlayListAlbums, getUpdatedPlayListNames, removeRemovedSongFromPlaylist } from "./PlaylistActions";
import { PLAYLIST_ADD_TO_PLAYLIST_FAIL, PLAYLIST_ADD_TO_PLAYLIST_SUCCESS, PLAYLIST_CREATE_PLAYLIST_START, PLAYLIST_CREATE_PLAYLIST_SUCCESS, PLAYLIST_DELETE_PLAYLIST_START, PLAYLIST_DELETE_PLAYLIST_SUCCESS, PLAYLIST_FETCH_ASSIGNED_PLAYLISTS_SUCCESS, PLAYLIST_FETCH_PLAYLIST_NAMES_START, PLAYLIST_FETCH_PLAYLIST_NAMES_SUCCESS, PLAYLIST_FETCH_SONGS_IN_PLAYLIST_START, PLAYLIST_FETCH_SONGS_IN_PLAYLIST_SUCCESS, PLAYLIST_REMOVE_FROM_PLAYLIST_START, PLAYLIST_REMOVE_FROM_PLAYLIST_SUCCESS, PLAYLIST_RENAME_PLAYLIST_START, PLAYLIST_RENAME_PLAYLIST_SUCCESS, SET_SHOW_CREATE_PLAYLIST_POPUP } from "./PlaylistActionTypes";
import { getUpdatedAssignedPlaylits, getUpdatedPlayListAlbums, getUpdatedPlayListNames, removeRemovedSongFromPlaylist } from "./PlaylistActions";

export const initialState = {
playlists:[],
playlistAlbums:{},
playlistSongs:[],
playlistSongsCount:{},
addedNewPlaylistObj:{},
assignedPlaylists:[],
phase:INIT
}

Expand All @@ -16,6 +17,7 @@ const playlistReducer = (state = initialState, action) => {
case PLAYLIST_ADD_TO_PLAYLIST_SUCCESS:
return{
...state,
assignedPlaylists: getUpdatedAssignedPlaylits([...state.assignedPlaylists],action.response.playlistItems[0], ADD),
phase: PLAYLIST_ADD_TO_PLAYLIST_SUCCESS
}
case PLAYLIST_ADD_TO_PLAYLIST_FAIL:
Expand Down Expand Up @@ -93,8 +95,15 @@ const playlistReducer = (state = initialState, action) => {
return{
...state,
playlistSongs: removeRemovedSongFromPlaylist([...state.playlistSongs], action.playlistItem),
assignedPlaylists: getUpdatedAssignedPlaylits([...state.assignedPlaylists],action.playlistItem, REMOVE),
phase: PLAYLIST_REMOVE_FROM_PLAYLIST_SUCCESS
}
case PLAYLIST_FETCH_ASSIGNED_PLAYLISTS_SUCCESS:
return{
...state,
assignedPlaylists: action.response,
phase: PLAYLIST_FETCH_ASSIGNED_PLAYLISTS_SUCCESS
}
default:
return {
...state,
Expand Down
Loading

0 comments on commit 748ac0d

Please sign in to comment.