jamtrack player, cusmtom mixes and download mixes
This commit is contained in:
parent
f904bdfc1c
commit
3b451427fc
|
|
@ -23,7 +23,7 @@ describe('JamTracks Page', () => {
|
|||
cy.get('input[type="search"]').should('exist');
|
||||
});
|
||||
|
||||
describe('search artists', () => {
|
||||
describe('search', () => {
|
||||
beforeEach(() => {
|
||||
//http://www.jamkazam.local:3000/api/jamtracks/autocomplete?match=ac+&limit=5
|
||||
// cy.intercept('GET', /S+\/jamtracks\/autocomplete\?match=ac\S+/, {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
/// <reference types="cypress" />
|
||||
|
||||
import makeFakeUser from '../../factories/user';
|
||||
|
||||
describe('JamTracks Page', () => {
|
||||
beforeEach(() => {
|
||||
const currentUser = makeFakeUser();
|
||||
cy.stubAuthenticate({ id: currentUser.id });
|
||||
cy.visit('/my-jamtracks');
|
||||
});
|
||||
|
||||
it('should display the My JamTracks page', () => {
|
||||
cy.get('.card-header h5').should('contain', 'My JamTracks');
|
||||
});
|
||||
|
||||
it('should display the search bar', () => {
|
||||
cy.get('input[type="search"]').should('exist');
|
||||
});
|
||||
|
||||
describe('filter', () => {
|
||||
beforeEach(() => {
|
||||
cy.intercept('GET', /\S+\/jamtracks\/purchased\?page=1\&\S+/, { fixture: 'my_jamtracks_page1' }).as('getMyJamTracks_page1');
|
||||
});
|
||||
|
||||
it('should display the JamTracks', () => {
|
||||
cy.get('input[type="search"]').type('ba');
|
||||
cy.wait('@getMyJamTracks_page1');
|
||||
cy.get('[data-testid=myJamTrackList]').should('contain', 'Back in Black by AC DC');
|
||||
});
|
||||
|
||||
it('clicking on a JamTrack should navigate to the JamTrack page', () => {
|
||||
cy.get('input[type="search"]').type('ba');
|
||||
cy.wait('@getMyJamTracks_page1');
|
||||
cy.get('[data-testid=myJamTrackList] a').first().click();
|
||||
cy.url().should('include', '/jamtracks/1');
|
||||
});
|
||||
})
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
|
@ -0,0 +1,562 @@
|
|||
|
||||
{
|
||||
"next": 10,
|
||||
"count": 3756,
|
||||
"jamtracks": [
|
||||
{
|
||||
"id": "1",
|
||||
"name": "Back in Black",
|
||||
"description": "This is a JamTrack audio file for use exclusively with the JamKazam service. This JamTrack is a high quality cover of the AC DC song \"Back in Black\".",
|
||||
"recording_type": "Cover",
|
||||
"original_artist": "AC DC",
|
||||
"songwriter": null,
|
||||
"publisher": null,
|
||||
"sales_region": "Worldwide",
|
||||
"price": "1.99",
|
||||
"version": "0",
|
||||
"duration": 221,
|
||||
"year": null,
|
||||
"plan_code": "jamtrack-acdc-backinblack",
|
||||
"allow_free": true,
|
||||
"download_price": "2.99",
|
||||
"upgrade_price": "1.0",
|
||||
"tracks": [
|
||||
{
|
||||
"id": "103dea4d-f2a3-4414-8efe-d2ca378dda60",
|
||||
"part": "Master Mix",
|
||||
"instrument": {
|
||||
"id": "computer",
|
||||
"description": "Computer",
|
||||
"created_at": "2021-02-02T23:16:46.168Z",
|
||||
"updated_at": "2021-02-02T23:16:46.168Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Master",
|
||||
"position": 1000,
|
||||
"preview_mp3_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Master%20Mix-44100-preview-e9a5a63f34b4d523ee1842fff31f88ce.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Master%20Mix-44100-preview-25fcba7ace7086e3cb6b97d7e33ba72e.ogg",
|
||||
"preview_aac_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Master%20Mix-44100-preview-9f0b072ed9f4b546e170fcdfb302137e.mp3"
|
||||
},
|
||||
{
|
||||
"id": "2755cbdd-0476-4f3b-9ba1-e2da561ddb4e",
|
||||
"part": "Lead",
|
||||
"instrument": {
|
||||
"id": "voice",
|
||||
"description": "Voice",
|
||||
"created_at": "2021-02-02T23:16:46.168Z",
|
||||
"updated_at": "2021-02-02T23:16:46.168Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 1,
|
||||
"preview_mp3_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Vocal%20-%20Lead-44100-preview-d35c328fc3936dad9a79fe102dc72950.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Vocal%20-%20Lead-44100-preview-b97b37651eae352fae3b3060918c7bcb.ogg",
|
||||
"preview_aac_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Vocal%20-%20Lead-44100-preview-d35c328fc3936dad9a79fe102dc72950.aac"
|
||||
},
|
||||
{
|
||||
"id": "0db7c4e1-5e8d-43fe-bd35-98acd8f68b26",
|
||||
"part": "Drums",
|
||||
"instrument": {
|
||||
"id": "drums",
|
||||
"description": "Drums",
|
||||
"created_at": "2021-02-02T23:16:46.168Z",
|
||||
"updated_at": "2021-02-02T23:16:46.168Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 2,
|
||||
"preview_mp3_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Drums-44100-preview-03aadceb966caf40b96334bdd00234f6.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Drums-44100-preview-854914e3e0d6fdc5f0794325b0ecaead.ogg",
|
||||
"preview_aac_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Drums-44100-preview-03aadceb966caf40b96334bdd00234f6.aac"
|
||||
},
|
||||
{
|
||||
"id": "2cc79ab6-dab8-4905-85e6-0df5f8e087f1",
|
||||
"part": "Bass",
|
||||
"instrument": {
|
||||
"id": "bass guitar",
|
||||
"description": "Bass Guitar",
|
||||
"created_at": "2021-02-02T23:16:46.168Z",
|
||||
"updated_at": "2021-02-02T23:16:46.168Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 3,
|
||||
"preview_mp3_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Bass-44100-preview-61c334ac87f811bd010ed3a910764c2e.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Bass-44100-preview-4066dafd7b72e9993b0c0fe1dba2b332.ogg",
|
||||
"preview_aac_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Bass-44100-preview-61c334ac87f811bd010ed3a910764c2e.aac"
|
||||
},
|
||||
{
|
||||
"id": "ed1d3487-3b32-442f-9c76-8a36fe3bb643",
|
||||
"part": "Solo",
|
||||
"instrument": {
|
||||
"id": "electric guitar",
|
||||
"description": "Electric Guitar",
|
||||
"created_at": "2021-02-02T23:16:46.168Z",
|
||||
"updated_at": "2021-02-02T23:16:46.168Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 4,
|
||||
"preview_mp3_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Electric%20Guitar%20-%20Solo-44100-preview-e9fe8572a9ac1022762642cbd92b3c34.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Electric%20Guitar%20-%20Solo-44100-preview-5fb058042254206cfa9fb4dcb0310b2c.ogg",
|
||||
"preview_aac_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Electric%20Guitar%20-%20Solo-44100-preview-e9fe8572a9ac1022762642cbd92b3c34.aac"
|
||||
},
|
||||
{
|
||||
"id": "f4ce7c91-7542-4e03-8fc2-68b31683d33e",
|
||||
"part": "Rhythm 1",
|
||||
"instrument": {
|
||||
"id": "electric guitar",
|
||||
"description": "Electric Guitar",
|
||||
"created_at": "2021-02-02T23:16:46.168Z",
|
||||
"updated_at": "2021-02-02T23:16:46.168Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 5,
|
||||
"preview_mp3_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Electric%20Guitar%20-%20Rhythm%201-44100-preview-6b498479823d4131a01fa535817d5eab.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Electric%20Guitar%20-%20Rhythm%201-44100-preview-f4cbb31dbde3e1a3e6012730a7e0e10f.ogg",
|
||||
"preview_aac_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Electric%20Guitar%20-%20Rhythm%201-44100-preview-6b498479823d4131a01fa535817d5eab.aac"
|
||||
},
|
||||
{
|
||||
"id": "2d96c7ec-59f1-4d56-8a7f-7f4c75a0ccef",
|
||||
"part": "Rhythm 2",
|
||||
"instrument": {
|
||||
"id": "electric guitar",
|
||||
"description": "Electric Guitar",
|
||||
"created_at": "2021-02-02T23:16:46.168Z",
|
||||
"updated_at": "2021-02-02T23:16:46.168Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 6,
|
||||
"preview_mp3_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Electric%20Guitar%20-%20Rhythm%202-44100-preview-a626d7c632560f6737e1b6024141289e.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Electric%20Guitar%20-%20Rhythm%202-44100-preview-06a0e5af451f001f3465992efcd34ec0.ogg",
|
||||
"preview_aac_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Electric%20Guitar%20-%20Rhythm%202-44100-preview-a626d7c632560f6737e1b6024141289e.aac"
|
||||
},
|
||||
{
|
||||
"id": "fce018ca-c897-4137-aa10-ef56a8e1831f",
|
||||
"part": "Intro Scrapes",
|
||||
"instrument": {
|
||||
"id": "electric guitar",
|
||||
"description": "Electric Guitar",
|
||||
"created_at": "2021-02-02T23:16:46.168Z",
|
||||
"updated_at": "2021-02-02T23:16:46.168Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 7,
|
||||
"preview_mp3_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Electric%20Guitar%20-%20Intro%20Scrapes-44100-preview-0ddfaa7154e9ba35d05d60477d5dd3e9.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Electric%20Guitar%20-%20Intro%20Scrapes-44100-preview-f53ce3c5f9dcf81af51560f52635fbb0.ogg",
|
||||
"preview_aac_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Electric%20Guitar%20-%20Intro%20Scrapes-44100-preview-0ddfaa7154e9ba35d05d60477d5dd3e9.aac"
|
||||
},
|
||||
{
|
||||
"id": "c9b3e0a8-4db0-4d0f-9769-398a6d56506e",
|
||||
"part": "Main",
|
||||
"instrument": {
|
||||
"id": "electric guitar",
|
||||
"description": "Electric Guitar",
|
||||
"created_at": "2021-02-02T23:16:46.168Z",
|
||||
"updated_at": "2021-02-02T23:16:46.168Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 8,
|
||||
"preview_mp3_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Electric%20Guitar%20-%20Main-44100-preview-234a224f75a97d7ff8f55442ece6fcde.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Electric%20Guitar%20-%20Main-44100-preview-828c9691f5435dea1c90182fa2618c9b.ogg",
|
||||
"preview_aac_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Electric%20Guitar%20-%20Main-44100-preview-234a224f75a97d7ff8f55442ece6fcde.aac"
|
||||
},
|
||||
{
|
||||
"id": "28c3df07-2a88-45a9-9ae6-3399a5d2eb20",
|
||||
"part": "Sound FX",
|
||||
"instrument": {
|
||||
"id": "computer",
|
||||
"description": "Computer",
|
||||
"created_at": "2021-02-02T23:16:46.168Z",
|
||||
"updated_at": "2021-02-02T23:16:46.168Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 9,
|
||||
"preview_mp3_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Sound%20Effects-44100-preview-6c859c73036cd55bceb65f19f2d2f2f3.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Sound%20Effects-44100-preview-f840d8df4c7388f776477139025ee712.ogg",
|
||||
"preview_aac_url": "https://jamkazam-dev-public.s3.amazonaws.com/jam_track_previews/AC%20DC/Back%20in%20Black/Back%20in%20Black%20Stem%20-%20Sound%20Effects-44100-preview-6c859c73036cd55bceb65f19f2d2f2f3.aac"
|
||||
}
|
||||
],
|
||||
"licensor": null,
|
||||
"genres": ["Rock", "Pop"],
|
||||
"added_cart": true,
|
||||
"can_download": true,
|
||||
"purchased": true
|
||||
},
|
||||
{
|
||||
"id": "531",
|
||||
"name": "1234",
|
||||
"description": "This is a JamTrack audio file for use exclusively with the JamKazam service. This JamTrack is a high quality cover of the Feist song \"1234\".",
|
||||
"recording_type": "Cover",
|
||||
"original_artist": "Feist",
|
||||
"songwriter": null,
|
||||
"publisher": null,
|
||||
"sales_region": "Worldwide",
|
||||
"price": "1.99",
|
||||
"version": "1",
|
||||
"duration": 184,
|
||||
"year": 2007,
|
||||
"plan_code": "jamtrack-feist-1234",
|
||||
"allow_free": true,
|
||||
"download_price": "2.99",
|
||||
"upgrade_price": "1.0",
|
||||
"tracks": [
|
||||
{
|
||||
"id": "b834ce9c-2624-4977-a079-0b1b5d90ad6e",
|
||||
"part": "Clicktrack",
|
||||
"instrument": {
|
||||
"id": "computer",
|
||||
"description": "Computer",
|
||||
"created_at": "2013-01-03T01:57:43.040Z",
|
||||
"updated_at": "2013-01-03T01:57:43.040Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Click",
|
||||
"position": 10000,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234%20-%20Tency%20Music/1234%20Clicktrack-44100-preview-90bed87ea6402ab0f8d283ffe094c95f.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234%20-%20Tency%20Music/1234%20Clicktrack-44100-preview-7198bae1519e40827aff0bd704e2066b.ogg",
|
||||
"preview_aac_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234%20-%20Tency%20Music/1234%20Clicktrack-44100-preview-90bed87ea6402ab0f8d283ffe094c95f.aac"
|
||||
},
|
||||
{
|
||||
"id": "b5a67d64-f94f-453e-9dab-691304275bc2",
|
||||
"part": "Master Mix",
|
||||
"instrument": {
|
||||
"id": "computer",
|
||||
"description": "Computer",
|
||||
"created_at": "2013-01-03T01:57:43.040Z",
|
||||
"updated_at": "2013-01-03T01:57:43.040Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Master",
|
||||
"position": 1000,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1%202%203%204%20Master%20Mix-44100-preview-5fe2a923a614f17dd9c6440b65c1e884.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1%202%203%204%20Master%20Mix-44100-preview-aaefd823d7deaa1bc862eb8ec1e53fe3.ogg",
|
||||
"preview_aac_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1%202%203%204%20Master%20Mix-44100-preview-6d3edecd174080e88e611984969f1b2d.aac"
|
||||
},
|
||||
{
|
||||
"id": "27353eb1-9f2b-487b-9047-93f49446b4db",
|
||||
"part": "Lead",
|
||||
"instrument": {
|
||||
"id": "voice",
|
||||
"description": "Voice",
|
||||
"created_at": "2013-01-03T01:57:43.040Z",
|
||||
"updated_at": "2013-01-03T01:57:43.040Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 1,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1234%20Stem%20-%20Vocal%20-%20Lead-44100-preview-426d923380d10fbdf2d5a4e4108b0de2.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1234%20Stem%20-%20Vocal%20-%20Lead-44100-preview-30eaef3aea1499493cbad76c5c3c8a50.ogg",
|
||||
"preview_aac_url": null
|
||||
},
|
||||
{
|
||||
"id": "78736d23-e657-4922-b145-9f7db40bb36e",
|
||||
"part": "Backing",
|
||||
"instrument": {
|
||||
"id": "voice",
|
||||
"description": "Voice",
|
||||
"created_at": "2013-01-03T01:57:43.040Z",
|
||||
"updated_at": "2013-01-03T01:57:43.040Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 2,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1234%20Stem%20-%20Vocal%20-%20Backing-44100-preview-c0fb7721f3c8cd3253c8c5a6d6b034dd.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1234%20Stem%20-%20Vocal%20-%20Backing-44100-preview-b7145437bbb6b01b566f10ef9009d001.ogg",
|
||||
"preview_aac_url": null
|
||||
},
|
||||
{
|
||||
"id": "1978c439-115b-4214-85a6-beec780310a1",
|
||||
"part": "Drums",
|
||||
"instrument": {
|
||||
"id": "drums",
|
||||
"description": "Drums",
|
||||
"created_at": "2013-01-03T01:57:43.040Z",
|
||||
"updated_at": "2013-01-03T01:57:43.040Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 3,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1234%20Stem%20-%20Drums%20-%20Drums-44100-preview-da3d7e78b9a7b50bea7bcc8f13a7d4b0.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1234%20Stem%20-%20Drums%20-%20Drums-44100-preview-d320dc7600c6d9c08af19b813d6d8176.ogg",
|
||||
"preview_aac_url": null
|
||||
},
|
||||
{
|
||||
"id": "8457c55d-924d-4048-8c5f-46b5c7668552",
|
||||
"part": "Bass",
|
||||
"instrument": {
|
||||
"id": "bass guitar",
|
||||
"description": "Bass Guitar",
|
||||
"created_at": "2013-01-03T01:57:43.040Z",
|
||||
"updated_at": "2013-01-03T01:57:43.040Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 4,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1234%20Stem%20-%20Bass%20Guitar%20-%20Bass-44100-preview-c4b1ce442a9645f6ead0f078afe48d3d.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1234%20Stem%20-%20Bass%20Guitar%20-%20Bass-44100-preview-8a0b0d664802015a219f3320d4d5c0cd.ogg",
|
||||
"preview_aac_url": null
|
||||
},
|
||||
{
|
||||
"id": "ca5d5597-1a19-45b1-9d1b-478f6b6c4b19",
|
||||
"part": "Piano",
|
||||
"instrument": {
|
||||
"id": "piano",
|
||||
"description": "Piano",
|
||||
"created_at": "2014-02-16T13:10:07.059Z",
|
||||
"updated_at": "2014-02-16T13:10:07.059Z",
|
||||
"popularity": 2
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 5,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1234%20Stem%20-%20Piano%20-%20Piano-44100-preview-208fb9e053bb445c1d55ec443809211c.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1234%20Stem%20-%20Piano%20-%20Piano-44100-preview-8940844b3972b39ad9b786805496bc1b.ogg",
|
||||
"preview_aac_url": null
|
||||
},
|
||||
{
|
||||
"id": "755c6c48-fc6c-4dc8-bbf2-9dc0d0a5f2a8",
|
||||
"part": "Acoustic",
|
||||
"instrument": {
|
||||
"id": "acoustic guitar",
|
||||
"description": "Acoustic Guitar",
|
||||
"created_at": "2013-01-03T01:57:43.040Z",
|
||||
"updated_at": "2013-01-03T01:57:43.040Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 6,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1234%20Stem%20-%20Acoustic%20Guitar%20-%20Acoustic-44100-preview-11bde0963b7a833072a49c1096a0b6ef.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1234%20Stem%20-%20Acoustic%20Guitar%20-%20Acoustic-44100-preview-92c44a32feac702880796fd9d6d5f883.ogg",
|
||||
"preview_aac_url": null
|
||||
},
|
||||
{
|
||||
"id": "508bcbaa-4d29-44c0-8cdd-f57fd3fee717",
|
||||
"part": "Banjo",
|
||||
"instrument": {
|
||||
"id": "banjo",
|
||||
"description": "Banjo",
|
||||
"created_at": "2013-01-03T01:57:43.040Z",
|
||||
"updated_at": "2013-01-03T01:57:43.040Z",
|
||||
"popularity": 2
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 7,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1234%20Stem%20-%20Banjo%20-%20Banjo-44100-preview-6ed9db0acb0616651e297b0c057f453d.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1234%20Stem%20-%20Banjo%20-%20Banjo-44100-preview-1e18e0b352e4b05fefa35ce7fd9c84a1.ogg",
|
||||
"preview_aac_url": null
|
||||
},
|
||||
{
|
||||
"id": "6ef8af53-6615-450c-b78b-4310fb0e0395",
|
||||
"part": "Strings",
|
||||
"instrument": {
|
||||
"id": "orchestra",
|
||||
"description": "Orchestra",
|
||||
"created_at": "2015-08-11T16:08:58.806Z",
|
||||
"updated_at": "2015-08-11T16:08:58.806Z",
|
||||
"popularity": 1
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 8,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1234%20Stem%20-%20Orchestra%20-%20Strings-44100-preview-7017822e5edaedbe91fea259cc29666c.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1234%20Stem%20-%20Orchestra%20-%20Strings-44100-preview-70f5d96ed08b1d6a625f21c8be3f691c.ogg",
|
||||
"preview_aac_url": null
|
||||
},
|
||||
{
|
||||
"id": "91427115-63be-49e6-adb1-078f4a7f7ae8",
|
||||
"part": "Trumpet",
|
||||
"instrument": {
|
||||
"id": "trumpet",
|
||||
"description": "Trumpet",
|
||||
"created_at": "2013-01-03T01:57:43.040Z",
|
||||
"updated_at": "2013-01-03T01:57:43.040Z",
|
||||
"popularity": 2
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 9,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1234%20Stem%20-%20Trumpet%20-%20Trumpet-44100-preview-74d7ab8c5af40dc9768176df2afd691a.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Feist/1234/1234%20Stem%20-%20Trumpet%20-%20Trumpet-44100-preview-df093dfebc96d3c22c13ed8d14b44ed0.ogg",
|
||||
"preview_aac_url": null
|
||||
}
|
||||
],
|
||||
"licensor": { "id": "027d90a1-b126-4d5a-8af6-3167296dfb04", "name": "Tency Music" },
|
||||
"genres": ["Folk", "Alternative Rock"],
|
||||
"added_cart": false,
|
||||
"can_download": false,
|
||||
"purchased": false
|
||||
},
|
||||
{
|
||||
"id": "1437",
|
||||
"name": "18 And Life",
|
||||
"description": "This is a JamTrack audio file for use exclusively with the JamKazam service. This JamTrack is a high quality cover of the Skid Row song \"18 And Life\".",
|
||||
"recording_type": "Cover",
|
||||
"original_artist": "Skid Row",
|
||||
"songwriter": null,
|
||||
"publisher": null,
|
||||
"sales_region": "Worldwide",
|
||||
"price": "1.99",
|
||||
"version": "1",
|
||||
"duration": 227,
|
||||
"year": 1989,
|
||||
"plan_code": "jamtrack-skidrow-18andlife",
|
||||
"allow_free": true,
|
||||
"download_price": "2.99",
|
||||
"upgrade_price": "1.0",
|
||||
"tracks": [
|
||||
{
|
||||
"id": "7c515f02-bebd-4fdd-b30a-81b72ec277b9",
|
||||
"part": "Clicktrack",
|
||||
"instrument": {
|
||||
"id": "computer",
|
||||
"description": "Computer",
|
||||
"created_at": "2013-01-03T01:57:43.040Z",
|
||||
"updated_at": "2013-01-03T01:57:43.040Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Click",
|
||||
"position": 10000,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life%20-%20Tency%20Music/click-44100-preview-424086caaa67c89532635ef0970b2d75.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life%20-%20Tency%20Music/click-44100-preview-d30de7c1353826896110d3ce5f459b23.ogg",
|
||||
"preview_aac_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life%20-%20Tency%20Music/click-44100-preview-424086caaa67c89532635ef0970b2d75.aac"
|
||||
},
|
||||
{
|
||||
"id": "db0a34e4-71e9-4342-b04a-e7c7f068b4fb",
|
||||
"part": "Master Mix",
|
||||
"instrument": {
|
||||
"id": "computer",
|
||||
"description": "Computer",
|
||||
"created_at": "2013-01-03T01:57:43.040Z",
|
||||
"updated_at": "2013-01-03T01:57:43.040Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Master",
|
||||
"position": 1000,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life/18%20And%20Life%20Master%20Mix-44100-preview-5bf5b2872e898dc43875f829e238b62b.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life/18%20And%20Life%20Master%20Mix-44100-preview-3ba1eb2b8ab936212cc299cfb8db34ac.ogg",
|
||||
"preview_aac_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life/18%20And%20Life%20Master%20Mix-44100-preview-146e9a850f83a2f76dc31dc9489dc3aa.aac"
|
||||
},
|
||||
{
|
||||
"id": "cc237bfd-5d87-413b-a460-55d17594f785",
|
||||
"part": "Lead",
|
||||
"instrument": {
|
||||
"id": "voice",
|
||||
"description": "Voice",
|
||||
"created_at": "2013-01-03T01:57:43.040Z",
|
||||
"updated_at": "2013-01-03T01:57:43.040Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 1,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life/ld-44100-preview-04a953ee8607a97e8533ea5adf4560a1.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life/ld-44100-preview-3486ef50eb889b71208040a0a13de52f.ogg",
|
||||
"preview_aac_url": null
|
||||
},
|
||||
{
|
||||
"id": "a182cf33-1d61-41a8-8e9b-fd23d501885c",
|
||||
"part": "Drums",
|
||||
"instrument": {
|
||||
"id": "drums",
|
||||
"description": "Drums",
|
||||
"created_at": "2013-01-03T01:57:43.040Z",
|
||||
"updated_at": "2013-01-03T01:57:43.040Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 2,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life/drums-44100-preview-7ec143f7aa0dc019a2af48c6861c400b.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life/drums-44100-preview-6fd8eacb6a8bd35a85e0d4a3a8ec120c.ogg",
|
||||
"preview_aac_url": null
|
||||
},
|
||||
{
|
||||
"id": "406c1f87-c6c1-406f-85a9-05768267ff46",
|
||||
"part": "Bass",
|
||||
"instrument": {
|
||||
"id": "bass guitar",
|
||||
"description": "Bass Guitar",
|
||||
"created_at": "2013-01-03T01:57:43.040Z",
|
||||
"updated_at": "2013-01-03T01:57:43.040Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 3,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life/bass-44100-preview-37326a28b8d55f4b61a00eb7406a4da9.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life/bass-44100-preview-ff2e87a89ae7693fa8f15a3d065c5833.ogg",
|
||||
"preview_aac_url": null
|
||||
},
|
||||
{
|
||||
"id": "fa46fcd7-0647-4f94-93fd-bddb403abc8b",
|
||||
"part": "Lead",
|
||||
"instrument": {
|
||||
"id": "electric guitar",
|
||||
"description": "Electric Guitar",
|
||||
"created_at": "2013-01-03T01:57:43.040Z",
|
||||
"updated_at": "2013-01-03T01:57:43.040Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 4,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life/18%20And%20Life%20Stem%20-%20Electric%20Guitar%20-%20Lead-44100-preview-7b8ac822d2a0ccf341c4607919e5125a.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life/18%20And%20Life%20Stem%20-%20Electric%20Guitar%20-%20Lead-44100-preview-3d13650573ebe20f939a7e2d661f9fab.ogg",
|
||||
"preview_aac_url": null
|
||||
},
|
||||
{
|
||||
"id": "42e6c71e-715c-48b9-b000-fb7fdabd3fe3",
|
||||
"part": "Rhythm Distorted",
|
||||
"instrument": {
|
||||
"id": "electric guitar",
|
||||
"description": "Electric Guitar",
|
||||
"created_at": "2013-01-03T01:57:43.040Z",
|
||||
"updated_at": "2013-01-03T01:57:43.040Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 5,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life/18%20And%20Life%20Stem%20-%20Electric%20Guitar%20-%20Rhythm%20Distorted-44100-preview-4f0312e6d429fa211c873ecd671c2629.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life/18%20And%20Life%20Stem%20-%20Electric%20Guitar%20-%20Rhythm%20Distorted-44100-preview-36e75c706ff27930a54be1159afafd9a.ogg",
|
||||
"preview_aac_url": null
|
||||
},
|
||||
{
|
||||
"id": "a16a69b1-2b89-4bca-8039-bb927c7f517f",
|
||||
"part": "Arpeggios Clean",
|
||||
"instrument": {
|
||||
"id": "electric guitar",
|
||||
"description": "Electric Guitar",
|
||||
"created_at": "2013-01-03T01:57:43.040Z",
|
||||
"updated_at": "2013-01-03T01:57:43.040Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 6,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life/18%20And%20Life%20Stem%20-%20Electric%20Guitar%20-%20Arpeggios%20Clean-44100-preview-f1f3df4288f9ac9bd8183303099f1a40.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life/18%20And%20Life%20Stem%20-%20Electric%20Guitar%20-%20Arpeggios%20Clean-44100-preview-f8da9761dbed9afd32d636fb0ba2f757.ogg",
|
||||
"preview_aac_url": null
|
||||
},
|
||||
{
|
||||
"id": "8246f3fb-6d35-4a31-9bcd-ef81fd39c66f",
|
||||
"part": "Arpeggios Distorted",
|
||||
"instrument": {
|
||||
"id": "electric guitar",
|
||||
"description": "Electric Guitar",
|
||||
"created_at": "2013-01-03T01:57:43.040Z",
|
||||
"updated_at": "2013-01-03T01:57:43.040Z",
|
||||
"popularity": 3
|
||||
},
|
||||
"track_type": "Track",
|
||||
"position": 7,
|
||||
"preview_mp3_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life/18%20And%20Life%20Stem%20-%20Electric%20Guitar%20-%20Arpeggios%20Distorted-44100-preview-2bf523d0f429eaff366691fff0dbcb5f.mp3",
|
||||
"preview_ogg_url": "https://jamkazam-public.s3.amazonaws.com/jam_track_previews/Skid%20Row/18%20And%20Life/18%20And%20Life%20Stem%20-%20Electric%20Guitar%20-%20Arpeggios%20Distorted-44100-preview-e25718a81d9d0a011746def84547f1e9.ogg",
|
||||
"preview_aac_url": null
|
||||
}
|
||||
],
|
||||
"licensor": { "id": "027d90a1-b126-4d5a-8af6-3167296dfb04", "name": "Tency Music" },
|
||||
"genres": ["Metal", "Rock", "Hard Rock"],
|
||||
"added_cart": false,
|
||||
"can_download": false,
|
||||
"purchased": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,13 +1,19 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import { Table, Row, Col, Input, Button } from 'reactstrap';
|
||||
import JKInstrumentIcon from '../profile/JKInstrumentIcon';
|
||||
import Select from 'react-select';
|
||||
import { useForm, Controller } from 'react-hook-form';
|
||||
import { createMixdown } from '../../helpers/rest';
|
||||
import { createMyMixdown, addMixdown } from '../../store/features/jamTrackSlice';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { Scrollbar } from 'react-scrollbars-custom';
|
||||
|
||||
const JKCreateCustomMix = () => {
|
||||
const MAX_MIXDOWNS = 5;
|
||||
|
||||
const JKCreateCustomMix = ({ jamTrack }) => {
|
||||
const [tracks, setTracks] = useState([]);
|
||||
//const [selectedTracks, setSelectedTracks] = useState([]);
|
||||
const [mixdowns, setMixdowns] = useState([]);
|
||||
const [selectedTracks, setSelectedTracks] = useState([]);
|
||||
const dispatch = useDispatch();
|
||||
const scrollbar = useRef();
|
||||
|
||||
const TEMPO_OPTIONS = [
|
||||
{ value: '0', label: 'Original tempo' },
|
||||
|
|
@ -61,6 +67,9 @@ const JKCreateCustomMix = ({ jamTrack }) => {
|
|||
{ value: '12', label: 'Up 12 semitone' }
|
||||
];
|
||||
|
||||
const jamTrack = useSelector(state => state.jamTrack.jamTrack);
|
||||
const newMixdownLoadingStatus = useSelector(state => state.jamTrack.newMixdownLoadingStatus);
|
||||
|
||||
const {
|
||||
control,
|
||||
handleSubmit,
|
||||
|
|
@ -81,13 +90,13 @@ const JKCreateCustomMix = ({ jamTrack }) => {
|
|||
mixdownTracks: []
|
||||
}
|
||||
});
|
||||
|
||||
const onSubmit = data => {
|
||||
console.log('data', data);
|
||||
const _tracks = [];
|
||||
let countIn = false;
|
||||
const selectedTracks = getValues('mixdownTracks');
|
||||
const selected = getValues('mixdownTracks');
|
||||
tracks.forEach(track => {
|
||||
const muted = selectedTracks.includes(track.id);
|
||||
const muted = selected.includes(track.id);
|
||||
if (track.id === 'count-in') {
|
||||
if (countIn === false) {
|
||||
countIn = !muted;
|
||||
|
|
@ -95,7 +104,7 @@ const JKCreateCustomMix = ({ jamTrack }) => {
|
|||
} else {
|
||||
_tracks.push({
|
||||
id: track.id,
|
||||
mute: selectedTracks.includes(track.id)
|
||||
mute: selected.includes(track.id)
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -105,39 +114,46 @@ const JKCreateCustomMix = ({ jamTrack }) => {
|
|||
const mixData = {
|
||||
jamTrackID: jamTrack.id,
|
||||
name: data.mixName,
|
||||
settings: { speed: data.tempo.value, pitch: data.pitch.value, 'count-in': countIn, tracks: _tracks }
|
||||
settings: { speed: parseInt(data.tempo.value), pitch: parseInt(data.pitch.value), 'count-in': countIn, tracks: _tracks }
|
||||
};
|
||||
|
||||
console.log('mixData', mixData);
|
||||
const tempMixdown = {...mixData, id: 'temp', jam_track_id: jamTrack.id};
|
||||
dispatch(addMixdown(tempMixdown));
|
||||
|
||||
createMixdown(mixData)
|
||||
.then(response => {
|
||||
console.log('mixdown created', response);
|
||||
//TODO: add this mixdown to global state of jamtrack mixdowns
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('mixdown create error', error);
|
||||
});
|
||||
dispatch(createMyMixdown(mixData));
|
||||
};
|
||||
|
||||
const toggleTrack = e => {
|
||||
const trackId = e.target.value;
|
||||
const selectedTracks = getValues('mixdownTracks');
|
||||
if (selectedTracks.includes(trackId)) {
|
||||
//setSelectedTracks(selectedTracks.filter(track => track !== trackId));
|
||||
const selected = getValues('mixdownTracks');
|
||||
if (selected.includes(trackId)) {
|
||||
setValue('mixdownTracks', selectedTracks.filter(track => track !== trackId));
|
||||
} else {
|
||||
//setSelectedTracks([...selectedTracks, trackId]);
|
||||
setValue('mixdownTracks', [...selectedTracks, trackId]);
|
||||
}
|
||||
setSelectedTracks(getValues('mixdownTracks'));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (jamTrack) {
|
||||
setTracks(jamTrack.tracks.filter(track => track.track_type === 'Track' || track.track_type === 'Click'));
|
||||
setMixdowns(jamTrack.mixdowns);
|
||||
}
|
||||
}, [jamTrack]);
|
||||
|
||||
useEffect(() => {
|
||||
if (jamTrack) {
|
||||
if(newMixdownLoadingStatus === 'succeeded') {
|
||||
setValue('mixName', '');
|
||||
setValue('tempo', TEMPO_OPTIONS[0]);
|
||||
setValue('pitch', PITCH_OPTIONS[0]);
|
||||
setValue('mixdownTracks', []);
|
||||
setSelectedTracks([]);
|
||||
setMixdowns(jamTrack.mixdowns);
|
||||
}
|
||||
}
|
||||
}, [newMixdownLoadingStatus]);
|
||||
|
||||
const trackName = track => {
|
||||
if (track.track_type === 'Track' || track.track_type === 'Click') {
|
||||
if (track.track_type === 'Click') {
|
||||
|
|
@ -153,38 +169,42 @@ const JKCreateCustomMix = ({ jamTrack }) => {
|
|||
}
|
||||
};
|
||||
|
||||
const hasExceededMax = mixdowns.length >= MAX_MIXDOWNS;
|
||||
|
||||
return (
|
||||
<>
|
||||
<p>
|
||||
Mute any tracks you like. Adjust the pitch or tempo of playback. Then give your mix a descriptive name, and
|
||||
click the Create Mix button. It will take few minutes for us to create your custom mix.
|
||||
</p>
|
||||
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<Row>
|
||||
<Col>
|
||||
<Table striped bordered className="fs--1">
|
||||
<Scrollbar ref={scrollbar} style={{ width: '100%', height: 300 }} mobileNative={true}>
|
||||
<Table striped bordered className="fs--1 mb-0">
|
||||
<thead className="bg-200 text-900">
|
||||
<tr>
|
||||
<th>Tracks {tracks.length > 0 && <>({tracks.length})</>}</th>
|
||||
<th>Mute</th>
|
||||
<th class="text-center">Mute</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
{tracks &&
|
||||
tracks.map((track, index) => (
|
||||
<tr key={index}>
|
||||
<td>
|
||||
<JKInstrumentIcon instrumentId={track.instrumentId} instrumentName={trackName(track)} />
|
||||
<span className="ml-1">{trackName(track)}</span>
|
||||
<span>{trackName(track)}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox" value={track.id} onClick={toggleTrack} />
|
||||
<td class="text-center">
|
||||
<input type="checkbox" value={track.id} onClick={toggleTrack} checked={ selectedTracks.includes(track.id)} disabled={hasExceededMax} />
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
|
||||
</tbody>
|
||||
</Table>
|
||||
</Scrollbar>
|
||||
<Controller
|
||||
name="mixdownTracks"
|
||||
control={control}
|
||||
|
|
@ -201,28 +221,28 @@ const JKCreateCustomMix = ({ jamTrack }) => {
|
|||
</Col>
|
||||
</Row>
|
||||
|
||||
<Row className="mb-1">
|
||||
<Col>Tempo</Col>
|
||||
<Row className="mb-3 mt-3">
|
||||
<Col sm={6} md={4} lg={3}>Tempo</Col>
|
||||
<Col>
|
||||
<Controller
|
||||
name="tempo"
|
||||
control={control}
|
||||
render={({ field }) => <Select {...field} options={TEMPO_OPTIONS} />}
|
||||
render={({ field }) => <Select {...field} options={TEMPO_OPTIONS} isDisabled={hasExceededMax} />}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row className="mb-1">
|
||||
<Col>Pitch</Col>
|
||||
<Row className="mb-3">
|
||||
<Col sm={6} md={4} lg={3}>Pitch</Col>
|
||||
<Col>
|
||||
<Controller
|
||||
name="pitch"
|
||||
control={control}
|
||||
render={({ field }) => <Select {...field} options={PITCH_OPTIONS} />}
|
||||
render={({ field }) => <Select {...field} options={PITCH_OPTIONS} isDisabled={hasExceededMax} />}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
<Row className="mb-1">
|
||||
<Col>Mix Name</Col>
|
||||
<Row className="mb-3">
|
||||
<Col sm={6} md={4} lg={3}>Mix Name</Col>
|
||||
<Col>
|
||||
<Controller
|
||||
name="mixName"
|
||||
|
|
@ -230,7 +250,7 @@ const JKCreateCustomMix = ({ jamTrack }) => {
|
|||
rules={{
|
||||
required: 'Mix name is required'
|
||||
}}
|
||||
render={({ field }) => <Input {...field} />}
|
||||
render={({ field }) => <Input {...field} disabled={hasExceededMax} />}
|
||||
/>
|
||||
{errors.mixName && (
|
||||
<div className="text-danger">
|
||||
|
|
@ -240,8 +260,10 @@ const JKCreateCustomMix = ({ jamTrack }) => {
|
|||
</Col>
|
||||
</Row>
|
||||
<Row>
|
||||
<Col>
|
||||
<Button>Create Mix</Button>
|
||||
<Col className='d-flex justify-content-end'>
|
||||
<Button color="primary" disabled={newMixdownLoadingStatus === 'loading' || hasExceededMax }>
|
||||
{newMixdownLoadingStatus === 'loading' ? 'Creating Mix...' : 'Create Mix'}
|
||||
</Button>
|
||||
</Col>
|
||||
</Row>
|
||||
</form>
|
||||
|
|
|
|||
|
|
@ -1,37 +1,34 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useResponsive } from '@farfetch/react-context-responsive';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { Card, CardBody, Row, Col, Progress } from 'reactstrap';
|
||||
import { Card, CardBody, Row, Col } from 'reactstrap';
|
||||
import FalconCardHeader from '../common/FalconCardHeader';
|
||||
import { getJamTrack, getUserDetail, postUserEvent, userOpenedJamTrackWebPlayer } from '../../helpers/rest';
|
||||
import { getUserDetail, postUserEvent, userOpenedJamTrackWebPlayer } from '../../helpers/rest';
|
||||
import JKJamTrackPlayer from './JKJamTrackPlayer';
|
||||
import JKMyJamTrackMixes from './JKMyJamTrackMixes';
|
||||
import JKCreateCustomMix from './JKCreateCustomMix';
|
||||
import { useAuth } from '../../context/UserAuth';
|
||||
|
||||
import { fetchJamTrack } from '../../store/features/jamTrackSlice';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
const JKJamTrack = () => {
|
||||
console.log('JKJamTrack rendering');
|
||||
|
||||
const { t } = useTranslation('jamtracks');
|
||||
const { greaterThan } = useResponsive();
|
||||
const { id } = useParams();
|
||||
const [jamTrack, setJamTrack] = useState(null);
|
||||
|
||||
const [loading, setLoading] = useState(false);
|
||||
const { currentUser } = useAuth();
|
||||
|
||||
const fetchJamTrack = async () => {
|
||||
console.log('fetching jam track', id);
|
||||
try {
|
||||
setLoading(true);
|
||||
const resp = await getJamTrack({ id });
|
||||
const data = await resp.json();
|
||||
console.log('jam track 123', data);
|
||||
setJamTrack(data);
|
||||
} catch (error) {
|
||||
console.log('Error when fetching jam track', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const jamTrack = useSelector(state => state.jamTrack.jamTrack);
|
||||
const jamTrackLoadingStatus = useSelector(state => state.jamTrack.status);
|
||||
|
||||
const fetchJamTrackRecord = () => {
|
||||
dispatch(fetchJamTrack({ id }));
|
||||
};
|
||||
|
||||
const fetchUserDetail = async () => {
|
||||
|
|
@ -58,31 +55,36 @@ const JKJamTrack = () => {
|
|||
}, [currentUser, jamTrack]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchJamTrack();
|
||||
fetchJamTrackRecord();
|
||||
}, [id]);
|
||||
|
||||
return (
|
||||
<Row>
|
||||
<Col>
|
||||
<Card className="mx-auto mb-4">
|
||||
<FalconCardHeader title={t('jamtrack.player.title')} titleClass="font-weight-semi-bold" />
|
||||
<CardBody className="pt-3">{jamTrack && <JKJamTrackPlayer jamTrack={jamTrack} />}</CardBody>
|
||||
</Card>
|
||||
<Card className="mx-auto">
|
||||
<FalconCardHeader title={t('jamtrack.my_mixes.title')} titleClass="font-weight-semi-bold" />
|
||||
<CardBody className="pt-3">{jamTrack && <JKMyJamTrackMixes jamTrack={jamTrack} />}</CardBody>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col>
|
||||
<Card className="mx-auto">
|
||||
<FalconCardHeader title={t('jamtrack.create_mix.title')} titleClass="font-weight-semi-bold" />
|
||||
<CardBody className="pt-3">
|
||||
{ jamTrack && <JKCreateCustomMix jamTrack={jamTrack} /> }
|
||||
</CardBody>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col />
|
||||
</Row>
|
||||
<>
|
||||
{jamTrackLoadingStatus === 'loading' || jamTrackLoadingStatus == 'idel' ? (
|
||||
<div>Loading...</div>
|
||||
) : Object.keys(jamTrack).length ? (
|
||||
<Row>
|
||||
<Col sm={12} md={4}>
|
||||
<Card className="mx-auto mb-4">
|
||||
<FalconCardHeader title={t('jamtrack.player.title')} titleClass="font-weight-semi-bold" />
|
||||
<CardBody className="pt-3">{jamTrack && <JKJamTrackPlayer />}</CardBody>
|
||||
</Card>
|
||||
<Card className="mx-auto">
|
||||
<FalconCardHeader title={t('jamtrack.my_mixes.title')} titleClass="font-weight-semi-bold" />
|
||||
<CardBody className="pt-3">{jamTrack && <JKMyJamTrackMixes />}</CardBody>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col sm={12} md={4} className={ greaterThan.sm ? null : 'mt-4' }>
|
||||
<Card className="mx-auto">
|
||||
<FalconCardHeader title={t('jamtrack.create_mix.title')} titleClass="font-weight-semi-bold" />
|
||||
<CardBody className="pt-3">{jamTrack && <JKCreateCustomMix />}</CardBody>
|
||||
</Card>
|
||||
</Col>
|
||||
|
||||
<Col />
|
||||
</Row>
|
||||
) : null}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,22 +1,20 @@
|
|||
import React, { useState, useEffect, useRef } from 'react';
|
||||
import Select from 'react-select';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { Row, Col } from 'reactstrap';
|
||||
import PropTypes from 'prop-types';
|
||||
import { markMixdownActive } from '../../helpers/rest';
|
||||
import FingerprintJS from '@fingerprintjs/fingerprintjs';
|
||||
import { useSelector } from 'react-redux';
|
||||
|
||||
const JKJamTrackPlayer = ({ jamTrack }) => {
|
||||
const JKJamTrackPlayer = () => {
|
||||
const [options, setOptions] = useState([]);
|
||||
const [selectedOption, setSelectedOption] = useState(null);
|
||||
const fpPromise = FingerprintJS.load();
|
||||
const [audioUrl, setAudioUrl] = useState(null);
|
||||
const audioRef = useRef(null);
|
||||
const jamTrack = useSelector(state => state.jamTrack.jamTrack);
|
||||
|
||||
useEffect(() => {
|
||||
if (jamTrack) {
|
||||
console.log('_JamTrackPlayer_ jamTrack', jamTrack);
|
||||
const opts = jamTrack.mixdowns.map(mix => ({ value: mix.id, label: mix.name }));
|
||||
const opts = jamTrack.mixdowns.map(mix => ({ value: mix.id, label: mix.name })).filter(mix => mix.value !== 'temp');
|
||||
opts.unshift({ value: 'original', label: 'Original' });
|
||||
setOptions(opts);
|
||||
if (jamTrack.last_mixdown_id) {
|
||||
|
|
@ -37,8 +35,6 @@ const JKJamTrackPlayer = ({ jamTrack }) => {
|
|||
return;
|
||||
}
|
||||
|
||||
console.log('_JamTrackPlayer_ selectedOption', selectedOption);
|
||||
|
||||
if (selectedOption.value === 'original') {
|
||||
const audioUrl = getMasterTrack();
|
||||
setAudioUrl(audioUrl);
|
||||
|
|
@ -56,7 +52,6 @@ const JKJamTrackPlayer = ({ jamTrack }) => {
|
|||
|
||||
const getMasterTrack = () => {
|
||||
const masterTrack = jamTrack.tracks.find(track => track.track_type === 'Master');
|
||||
console.log('_JamTrackPlayer_ master', masterTrack);
|
||||
if (masterTrack) {
|
||||
const audioUrl = masterTrack.preview_mp3_url;
|
||||
return audioUrl;
|
||||
|
|
@ -91,8 +86,4 @@ const JKJamTrackPlayer = ({ jamTrack }) => {
|
|||
);
|
||||
};
|
||||
|
||||
JKJamTrackPlayer.propTypes = {
|
||||
jamTrack: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
export default JKJamTrackPlayer;
|
||||
export default JKJamTrackPlayer;
|
||||
|
|
@ -1,71 +1,121 @@
|
|||
import React, { useState, useEffect } from 'react';
|
||||
import { Table } from 'reactstrap';
|
||||
import FingerprintJS from '@fingerprintjs/fingerprintjs';
|
||||
import { removeMixdown } from '../../store/features/jamTrackSlice';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
|
||||
const JKMyJamTrackMixes = ({ jamTrack }) => {
|
||||
const JKMyJamTrackMixes = () => {
|
||||
const [mixes, setMixes] = useState([]);
|
||||
const fpPromise = FingerprintJS.load();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const jamTrack = useSelector(state => state.jamTrack.jamTrack);
|
||||
const mixdownsLoadingStatus = useSelector(state => state.jamTrack.mixdownsLoadingStatus);
|
||||
const deleteMixdownStatus = useSelector(state => state.jamTrack.deleteMixdownStatus);
|
||||
const tempMixdownLoadingStatus = useSelector(state => state.jamTrack.tempMixdownLoadingStatus);
|
||||
|
||||
useEffect(() => {
|
||||
if(!jamTrack) {
|
||||
if (!jamTrack) {
|
||||
return;
|
||||
}
|
||||
setMixes(jamTrack.mixdowns)
|
||||
}, []);
|
||||
if (mixdownsLoadingStatus === 'succeeded') {
|
||||
setMixes(jamTrack.mixdowns.filter(m => m.id !== 'temp'));
|
||||
}
|
||||
}, [mixdownsLoadingStatus]);
|
||||
|
||||
useEffect(() => {
|
||||
if (tempMixdownLoadingStatus === 'succeeded') {
|
||||
setMixes(jamTrack.mixdowns);
|
||||
}
|
||||
}, [tempMixdownLoadingStatus]);
|
||||
|
||||
const downloadJamTrack = async () => {
|
||||
console.log('Downloading JamTrack');
|
||||
if(!jamTrack.can_download) {
|
||||
if (!jamTrack.can_download) {
|
||||
console.log('Cannot download JamTrack');
|
||||
return
|
||||
return;
|
||||
}
|
||||
const fp = await fpPromise;
|
||||
const result = await fp.get();
|
||||
const redirectTo = `${process.env.REACT_APP_API_BASE_URL}/jamtracks/${jamTrack.id}/stems/master/download.mp3?file_type=mp3&download=1&mark=${result.visitorId}`;
|
||||
window.open(redirectTo, '_blank');
|
||||
}
|
||||
const src = `${process.env.REACT_APP_API_BASE_URL}/jamtracks/${
|
||||
jamTrack.id
|
||||
}/stems/master/download.mp3?file_type=mp3&download=1&mark=${result.visitorId}`;
|
||||
openDownload(src);
|
||||
};
|
||||
|
||||
const downloadMix = async (mixId) => {
|
||||
console.log('Download mixdown')
|
||||
const downloadMix = async mixId => {
|
||||
console.log('Download mixdown');
|
||||
const mixdown = mixes.find(m => m.id === mixId);
|
||||
const mixdownPackage = mixdown.packages.find(p => p.file_type === 'mp3');
|
||||
if(mixdownPackage?.signing_state == 'SIGNED'){
|
||||
if (mixdownPackage?.signing_state == 'SIGNED') {
|
||||
const fp = await fpPromise;
|
||||
const result = await fp.get();
|
||||
const redirectTo = `${process.env.REACT_APP_API_BASE_URL}/mixdowns/${mixdown.id}/download.mp3?file_type=mp3&sample_rate=48&download=1&mark=${result.visitorId}`
|
||||
window.open(redirectTo, '_blank');
|
||||
const src = `${process.env.REACT_APP_API_BASE_URL}/mixdowns/${
|
||||
mixdown.id
|
||||
}/download.mp3?file_type=mp3&sample_rate=48&download=1&mark=${result.visitorId}`;
|
||||
openDownload(src);
|
||||
}else{
|
||||
console.log('Mixdown not signed');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const deleteMix = (mixId) => {
|
||||
if(window.confirm("Delete this custom mix?")){
|
||||
console.log("Deleting mixdown", mixId)
|
||||
const openDownload = async src => {
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.src = src;
|
||||
iframe.style.display = 'none';
|
||||
document.body.appendChild(iframe);
|
||||
};
|
||||
|
||||
const deleteMix = mixId => {
|
||||
if (window.confirm('Delete this custom mix?')) {
|
||||
console.log('Deleting mixdown', mixId);
|
||||
dispatch(removeMixdown({ id: mixId }));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<p>You can save a maximum of 5 mixes on JamKazam. If you need to make more mixes, download a mix to save it, then delete it to make more room</p >
|
||||
<Table striped bordered className="fs--1" >
|
||||
<p>
|
||||
You can save a <strong>maximum of 5 mixes</strong> on JamKazam. If you need to make more mixes, download a mix
|
||||
to save it, then delete it to make more room
|
||||
</p>
|
||||
<Table striped bordered className="fs--1">
|
||||
<thead className="bg-200 text-900">
|
||||
<tr>
|
||||
<th>Mix</th>
|
||||
<th>Actions</th>
|
||||
<th class="text-center">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Full JamTrack</td>
|
||||
<td>
|
||||
<button onClick={downloadJamTrack}>Download</button>
|
||||
<td class="text-center">
|
||||
<a onClick={downloadJamTrack}>
|
||||
<FontAwesomeIcon icon="download" size="lg" className="mr-3" />
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
{mixes.map(mix => (
|
||||
<tr key={mix.id}>
|
||||
<td>{mix.name}</td>
|
||||
<td>
|
||||
<button onClick={() => downloadMix(mix.id)}>Download</button>
|
||||
<button onClick={() => deleteMix(mix.id)}>Delete</button>
|
||||
<td class="text-center">
|
||||
{mix.id === 'temp' ? (
|
||||
<FontAwesomeIcon icon="spinner" size="lg" />
|
||||
) : (
|
||||
<>
|
||||
<a onClick={() => downloadMix(mix.id)} style={{ cursor: 'pointer' }}>
|
||||
<FontAwesomeIcon icon="download" size="lg" className="mr-3" />
|
||||
</a>
|
||||
<a
|
||||
onClick={() => deleteMix(mix.id)}
|
||||
disabled={deleteMixdownStatus === 'loading'}
|
||||
style={{ cursor: 'pointer' }}
|
||||
>
|
||||
<FontAwesomeIcon icon="trash" size="xl" />
|
||||
</a>
|
||||
</>
|
||||
)}
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
|
|
|
|||
|
|
@ -3,33 +3,35 @@ import { Card, CardBody, ListGroup, ListGroupItem, FormGroup, Input, InputGroup,
|
|||
import FalconCardHeader from '../common/FalconCardHeader';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useResponsive } from '@farfetch/react-context-responsive';
|
||||
import { getPurchasedJamTracks } from '../../helpers/rest';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import useOnScreen from '../../hooks/useOnScreen';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { fetchMyJamTracks } from '../../store/features/myJamTracksSlice';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
|
||||
const JKMyJamTracks = () => {
|
||||
const { t } = useTranslation('jamtracks');
|
||||
const { greaterThan } = useResponsive();
|
||||
const [jamTracks, setJamTracks] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [inputValue, setInputValue] = useState('');
|
||||
const inputRef = React.createRef();
|
||||
const containerRef = useRef(null);
|
||||
const [lastJamTrackRef, setLastJamTrackRef] = useState(null);
|
||||
const isIntersecting = useOnScreen({ current: lastJamTrackRef });
|
||||
const [nextPage, setNextPage] = useState(1);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const jamTracks = useSelector(state => state.myJamTrack.jamTracks);
|
||||
const loadingStatus = useSelector(state => state.myJamTrack.status);
|
||||
const nextPage = useSelector(state => state.myJamTrack.next);
|
||||
|
||||
const handleInputChange = e => {
|
||||
const val = e.target.value;
|
||||
setInputValue(val);
|
||||
// const params = { page: 1, search: val };
|
||||
// fetchJamTracks(params);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const getMyJamTracks = setTimeout(() => {
|
||||
fetchJamTracks({ page: 1, search: inputValue});
|
||||
const getMyJamTracks = setTimeout(async () => {
|
||||
await fetchJamTracks({ page: 1, search: inputValue});
|
||||
}, 1000);
|
||||
return () => clearTimeout(getMyJamTracks);
|
||||
}, [inputValue]);
|
||||
|
|
@ -37,37 +39,23 @@ const JKMyJamTracks = () => {
|
|||
const fetchJamTracks = async (params) => {
|
||||
const { page } = params;
|
||||
try {
|
||||
setLoading(true);
|
||||
const resp = await getPurchasedJamTracks(params);
|
||||
const data = await resp.json();
|
||||
if (page === 1) {
|
||||
setJamTracks(data.jamtracks);
|
||||
}else{
|
||||
setJamTracks(prev => [...prev, ...data.jamtracks]);
|
||||
}
|
||||
setNextPage(data.next);
|
||||
|
||||
dispatch(fetchMyJamTracks(params));
|
||||
} catch (error) {
|
||||
console.log('Error when fetching jam tracks', error);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
//setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (isIntersecting) {
|
||||
if (nextPage && !loading && nextPage !== 1) {
|
||||
if (nextPage && loadingStatus !== 'loading' && nextPage !== 1) {
|
||||
const params = { page: nextPage };
|
||||
fetchJamTracks(params);
|
||||
}
|
||||
}
|
||||
}, [isIntersecting]);
|
||||
|
||||
useEffect(() => {
|
||||
const params = { page: nextPage };
|
||||
fetchJamTracks(params);
|
||||
}, []);
|
||||
|
||||
const containerStyle = {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
|
|
@ -83,7 +71,7 @@ const JKMyJamTracks = () => {
|
|||
<div className="d-flex align-items-center">
|
||||
<InputGroup>
|
||||
<InputGroupText style={{ borderRadius: '0', borderRight: '0' }}>
|
||||
{loading ? (
|
||||
{loadingStatus === 'loading' ? (
|
||||
<span className="spinner-grow spinner-grow-sm" aria-hidden="true" />
|
||||
) : (
|
||||
<FontAwesomeIcon icon="search" transform="shrink-4 down-1" />
|
||||
|
|
@ -102,18 +90,25 @@ const JKMyJamTracks = () => {
|
|||
</div>
|
||||
</FormGroup>
|
||||
<div style={containerStyle} ref={containerRef}>
|
||||
<ListGroup className="mt-1">
|
||||
{jamTracks.map((jamTrack, index) => (
|
||||
<div key={jamTrack.id} ref={ref => (jamTracks.length - 1 === index ? setLastJamTrackRef(ref) : null)}>
|
||||
<ListGroupItem >
|
||||
<Link to={`/jamtracks/${jamTrack.id}`}>{jamTrack.name}</Link>
|
||||
{jamTrack.original_artist && ` by ${jamTrack.original_artist}`}
|
||||
</ListGroupItem>
|
||||
</div>
|
||||
|
||||
))}
|
||||
</ListGroup>
|
||||
{ loading && <div className="d-flex justify-content-center"> Loading... </div>}
|
||||
{ loadingStatus === 'loading' ? (
|
||||
<div className="d-flex justify-content-center"> Loading... </div>
|
||||
) : loadingStatus === 'failed' ? (
|
||||
<div className="d-flex justify-content-center"> Error loading jam tracks </div>
|
||||
) : loadingStatus === 'succeeded' ? (
|
||||
<ListGroup className="mt-1" data-testid="myJamTrackList">
|
||||
{jamTracks && jamTracks.map((jamTrack, index) => (
|
||||
<div key={jamTrack.id} ref={ref => (jamTracks.length - 1 === index ? setLastJamTrackRef(ref) : null)}>
|
||||
<ListGroupItem >
|
||||
<Link to={`/jamtracks/${jamTrack.id}`}>{jamTrack.name}</Link>
|
||||
{jamTrack.original_artist && ` by ${jamTrack.original_artist}`}
|
||||
</ListGroupItem>
|
||||
</div>
|
||||
|
||||
))}
|
||||
</ListGroup>
|
||||
) : null }
|
||||
|
||||
|
||||
</div>
|
||||
</CardBody>
|
||||
</Card>
|
||||
|
|
|
|||
|
|
@ -35,8 +35,11 @@ import {
|
|||
faPaperPlane as farPaperPlane,
|
||||
faQuestionCircle as farQuestionCircle,
|
||||
faSmileBeam as farSmileBeam,
|
||||
faStar as farStar
|
||||
faStar as farStar,
|
||||
faMinus as farMinus,
|
||||
far,
|
||||
} from '@fortawesome/free-regular-svg-icons';
|
||||
|
||||
import {
|
||||
faAlignLeft,
|
||||
faAlignRight,
|
||||
|
|
@ -164,7 +167,9 @@ import {
|
|||
faPlayCircle,
|
||||
faPauseCircle,
|
||||
faStopCircle,
|
||||
faInfoCircle
|
||||
faInfoCircle,
|
||||
faDownload,
|
||||
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
//import { faAcousticGuitar } from "../icons";
|
||||
|
|
@ -339,6 +344,7 @@ library.add(
|
|||
farCircle,
|
||||
farCopy,
|
||||
farComment,
|
||||
|
||||
faMinus,
|
||||
faDownload,
|
||||
//faAcousticGuitar,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -389,6 +389,7 @@ export const autocompleteJamTracks = (input, limit) => {
|
|||
};
|
||||
|
||||
export const getPurchasedJamTracks = (options = {}) => {
|
||||
options = { ...options, show_purchased_only: true };
|
||||
return new Promise((resolve, reject) => {
|
||||
apiFetch(`/jamtracks/purchased?${new URLSearchParams(options)}`)
|
||||
.then(response => resolve(response))
|
||||
|
|
@ -482,7 +483,7 @@ export const placeOrder = () => {
|
|||
|
||||
export const postUserEvent = (options = {}) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
apiFetch(`users/event/record`, {
|
||||
apiFetch(`/users/event/record`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(options)
|
||||
})
|
||||
|
|
@ -493,7 +494,7 @@ export const postUserEvent = (options = {}) => {
|
|||
|
||||
export const userOpenedJamTrackWebPlayer = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
apiFetch(`/api/users/progression/opened_jamtrack_web_player`, {
|
||||
apiFetch(`/users/progression/opened_jamtrack_web_player`, {
|
||||
method: 'POST'
|
||||
})
|
||||
.then(response => resolve(response))
|
||||
|
|
@ -530,3 +531,13 @@ export const createMixdown = options => {
|
|||
.catch(error => reject(error));
|
||||
});
|
||||
}
|
||||
|
||||
export const deleteMixdown = id => {
|
||||
return new Promise((resolve, reject) => {
|
||||
apiFetch(`/mixdowns/${id}`, {
|
||||
method: 'DELETE'
|
||||
})
|
||||
.then(response => resolve(response))
|
||||
.catch(error => reject(error));
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
|
||||
import { deleteMixdown, getJamTrack, createMixdown } from '../../helpers/rest';
|
||||
|
||||
const initialState = {
|
||||
jamTrack: {},
|
||||
jamTrackLoadingStatus: 'idle',
|
||||
mixdownsLoadingStatus: 'idle',
|
||||
deleteMixdownStatus: 'idle',
|
||||
newMixdownLoadingStatus: 'idle',
|
||||
tempMixdownLoadingStatus: 'idle',
|
||||
|
||||
error: null
|
||||
}
|
||||
|
||||
export const fetchJamTrack = createAsyncThunk('jamTracks/fetchJamTrack', async(options, thunkAPI) => {
|
||||
const response = await getJamTrack(options)
|
||||
return response.json();
|
||||
});
|
||||
|
||||
export const createMyMixdown = createAsyncThunk('jamTracks/createMixdown', async(options, thunkAPI) => {
|
||||
const response = await createMixdown(options)
|
||||
return response.json();
|
||||
});
|
||||
|
||||
export const removeMixdown = createAsyncThunk('jamTracks/removeMixdown', async(options, thunkAPI) => {
|
||||
console.log('removeMixdown', options);
|
||||
const { id } = options;
|
||||
const response = await deleteMixdown(id)
|
||||
return { id };
|
||||
});
|
||||
|
||||
export const jamTrackSlice = createSlice({
|
||||
name: 'jamTrack',
|
||||
initialState,
|
||||
reducers: {
|
||||
addMixdown: (state, action) => {
|
||||
const payload = action.payload;
|
||||
const jamTrack = state.jamTrack;
|
||||
if (jamTrack) {
|
||||
state.jamTrack.mixdowns = [...jamTrack.mixdowns, payload];
|
||||
state.tempMixdownLoadingStatus = 'succeeded';
|
||||
}
|
||||
},
|
||||
},
|
||||
extraReducers: builder => {
|
||||
builder
|
||||
.addCase(fetchJamTrack.pending, (state, action) => {
|
||||
state.jamTrackLoadingStatus = 'loading'
|
||||
state.mixdownsLoadingStatus = 'loading'
|
||||
})
|
||||
.addCase(fetchJamTrack.fulfilled, (state, action) => {
|
||||
state.jamTrack = action.payload
|
||||
state.jamTrackLoadingStatus = 'succeeded'
|
||||
|
||||
if (action.payload.mixdowns) {
|
||||
state.mixdownsLoadingStatus = 'succeeded'
|
||||
}
|
||||
})
|
||||
.addCase(fetchJamTrack.rejected, (state, action) => {
|
||||
state.status = 'failed'
|
||||
state.jamTrackLoadingStatus = 'failed'
|
||||
state.mixdownsLoadingStatus = 'failed'
|
||||
state.error = action.error.message;
|
||||
})
|
||||
.addCase(createMyMixdown.pending, (state, action) => {
|
||||
state.newMixdownLoadingStatus = 'loading'
|
||||
state.mixdownsLoadingStatus = 'loading'
|
||||
})
|
||||
.addCase(createMyMixdown.fulfilled, (state, action) => {
|
||||
state.jamTrack.mixdowns = [...state.jamTrack.mixdowns, action.payload];
|
||||
state.newMixdownLoadingStatus = 'succeeded'
|
||||
state.mixdownsLoadingStatus = 'succeeded'
|
||||
state.tempMixdownLoadingStatus = 'idle'
|
||||
})
|
||||
.addCase(createMyMixdown.rejected, (state, action) => {
|
||||
state.error = action.error.message;
|
||||
state.newMixdownLoadingStatus = 'failed'
|
||||
state.tempMixdownLoadingStatus = 'idle'
|
||||
})
|
||||
.addCase(removeMixdown.pending, (state, action) => {
|
||||
state.mixdownsLoadingStatus = 'loading'
|
||||
state.deleteMixdownStatus = 'loading'
|
||||
})
|
||||
.addCase(removeMixdown.fulfilled, (state, action) => {
|
||||
console.log('mixdown removed', action.payload)
|
||||
const mixdowns = state.jamTrack.mixdowns.filter(mix => mix.id !== action.payload.id);
|
||||
state.jamTrack.mixdowns = mixdowns;
|
||||
state.mixdowns = mixdowns;
|
||||
state.mixdownsLoadingStatus = 'succeeded'
|
||||
state.deleteMixdownStatus = 'succeeded'
|
||||
})
|
||||
.addCase(removeMixdown.rejected, (state, action) => {
|
||||
state.error = action.error.message;
|
||||
state.mixdownsLoadingStatus = 'failed'
|
||||
state.deleteMixdownStatus = 'failed'
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
export const { addMixdown } = jamTrackSlice.actions;
|
||||
export default jamTrackSlice.reducer;
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
|
||||
import { getPurchasedJamTracks } from '../../helpers/rest';
|
||||
|
||||
const initialState = {
|
||||
jamTracks: [],
|
||||
status: 'idle',
|
||||
error: null,
|
||||
next: null,
|
||||
};
|
||||
|
||||
export const fetchMyJamTracks = createAsyncThunk('jamTracks/fetchMyJamTracks', async (options, thunkAPI) => {
|
||||
|
||||
const response = await getPurchasedJamTracks(options);
|
||||
return response.json();
|
||||
});
|
||||
|
||||
|
||||
export const myJamTracksSlice = createSlice({
|
||||
name: 'jamTracks',
|
||||
initialState,
|
||||
reducers: {
|
||||
addJamTrack: (state, action) => {
|
||||
state.jamTracks.push(action.payload);
|
||||
},
|
||||
// updateJamTrack: (state, action) => {
|
||||
// const { id, name } = action.payload;
|
||||
// const existingJamTrack = state.jamTracks.find(jamTrack => jamTrack.id === id);
|
||||
// if (existingJamTrack) {
|
||||
// existingJamTrack.name = name;
|
||||
// }
|
||||
// },
|
||||
deleteJamTrack: (state, action) => {
|
||||
const { id } = action.payload;
|
||||
state.jamTracks = state.jamTracks.filter(jamTrack => jamTrack.id !== id);
|
||||
}
|
||||
},
|
||||
extraReducers: builder => {
|
||||
builder
|
||||
.addCase(fetchMyJamTracks.pending, (state, action) => {
|
||||
state.status = 'loading';
|
||||
})
|
||||
.addCase(fetchMyJamTracks.fulfilled, (state, action) => {
|
||||
state.status = 'succeeded';
|
||||
state.jamTracks = action.payload.jamtracks;
|
||||
|
||||
//--- amend the state to include only unique jamTracks
|
||||
// const records = new Set([...state.jamTracks, ...action.payload.jamtracks]);
|
||||
// const unique = [];
|
||||
// records.map(x => (unique.filter(a => a.id === x.id).length > 0 ? null : unique.push(x)));
|
||||
// state.jamTracks = unique;
|
||||
// state.next = action.payload.next;
|
||||
// state.status = 'succeeded';
|
||||
//---
|
||||
})
|
||||
.addCase(fetchMyJamTracks.rejected, (state, action) => {
|
||||
state.status = 'failed';
|
||||
state.error = action.error.message;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export const { addJamTrack, deleteJamTrack } = myJamTracksSlice.actions;
|
||||
export default myJamTracksSlice.reducer;
|
||||
|
|
@ -8,6 +8,8 @@ import notificationReducer from './features/notificationSlice'
|
|||
import latencyReducer from "./features/latencySlice"
|
||||
import friendReducer from "./features/friendsSlice"
|
||||
import sessionsHistoryReducer from "./features/sessionsHistorySlice"
|
||||
import myJamTracksSlice from "./features/myJamTracksSlice"
|
||||
import jamTrackSlice from "./features/jamTrackSlice"
|
||||
|
||||
export default configureStore({
|
||||
reducer: {
|
||||
|
|
@ -20,5 +22,7 @@ export default configureStore({
|
|||
lobbyChat: lobbyChatMessagesReducer,
|
||||
friend: friendReducer,
|
||||
sessionsHistory: sessionsHistoryReducer, // this is the slice that holds the sessions history
|
||||
myJamTrack: myJamTracksSlice,
|
||||
jamTrack: jamTrackSlice
|
||||
}
|
||||
})
|
||||
Loading…
Reference in New Issue