Use web provider

This commit is contained in:
metalex9
2020-03-07 19:17:34 -06:00
parent 10b50df415
commit f0f52ff282
12 changed files with 411 additions and 284 deletions

View File

@@ -1,7 +1,8 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import propTypes from 'prop-types';
import { Redirect } from 'react-router';
import pieces from '@pieces';
import provider from '@pieces/provider';
import piecesById from '@pieces/by-id';
import LinkButton from '@components/shared/link-button';
import PieceFilter from './piece-filter';
@@ -31,7 +32,6 @@ const PiecesTabComponent = ({
changeSorting,
visiblePieceIds,
isOnline,
cachedPieceIds,
history,
}) => {
let isValidSinglePiece = false;
@@ -61,11 +61,34 @@ const PiecesTabComponent = ({
}
const currentSorting = sortings[sorting.key];
const [isPieceCachedMap, setIsPieceCachedMap] = useState(new Map());
const isPieceDisabled = piece =>
!isSupported ||
isRecordingGenerationInProgress ||
(!isOnline && !cachedPieceIds.has(piece.id));
(!isOnline && !isPieceCachedMap.get(piece.id));
useEffect(() => {
if (!isOnline) {
Promise.all(
pieces.map(({ id, sampleNames }) =>
provider.canProvide(sampleNames).then(result => [id, result])
)
).then(results => {
setIsPieceCachedMap(new Map(results));
});
}
}, [isOnline]);
useEffect(() => {
Promise.all(
pieces.map(({ id, sampleNames }) =>
provider.canProvide(sampleNames).then(result => [id, result])
)
).then(results => {
setIsPieceCachedMap(new Map(results));
});
}, []);
return (
<div className="pieces-tab">
@@ -177,7 +200,6 @@ PiecesTabComponent.propTypes = {
changeSorting: propTypes.func.isRequired,
visiblePieceIds: propTypes.array.isRequired,
isOnline: propTypes.bool.isRequired,
cachedPieceIds: propTypes.object.isRequired,
history: propTypes.object.isRequired,
};

View File

@@ -4,6 +4,7 @@ import { Link } from 'react-router-dom';
import { faTimes, faPlus } from '@fortawesome/free-solid-svg-icons';
import pieces from '@pieces';
import piecesById from '@pieces/by-id';
import provider from '@pieces/provider';
import ControlButtonComponent from '../controls/control-button';
import TextButton from '@components/shared/text-button';
import isSupported from '@config/is-supported';
@@ -23,7 +24,6 @@ const RecordTabComponent = ({
generatedRecordings,
lastRecordingGenerationLength,
isOnline,
cachedPieceIds,
removeRecordingGeneration,
startRecordingGeneration,
}) => {
@@ -51,8 +51,32 @@ const RecordTabComponent = ({
setIsGenerationInProgress(queue.some(({ isInProgress }) => isInProgress));
}, [generatedRecordings]);
const [isPieceCachedMap, setIsPieceCachedMap] = useState(new Map());
useEffect(() => {
if (!isOnline) {
Promise.all(
pieces.map(({ id, sampleNames }) =>
provider.canProvide(sampleNames).then(result => [id, result])
)
).then(results => {
setIsPieceCachedMap(new Map(results));
});
}
}, [isOnline]);
useEffect(() => {
Promise.all(
pieces.map(({ id, sampleNames }) =>
provider.canProvide(sampleNames).then(result => [id, result])
)
).then(results => {
setIsPieceCachedMap(new Map(results));
});
}, []);
const isPieceDisabled = piece =>
!piece.isRecordable || (!isOnline && !cachedPieceIds.has(piece.id));
!piece.isRecordable || (!isOnline && !isPieceCachedMap.get(piece.id));
const getIsRecordingValid = () =>
!isPieceDisabled(selectedPiece) &&
@@ -171,9 +195,7 @@ const RecordTabComponent = ({
} else if (url === '') {
status = ' - waiting to generate';
}
const displayText = `${lengthInMinutes} minutes of ${
piecesById[pieceId].title
}${status}`;
const displayText = `${lengthInMinutes} minutes of ${piecesById[pieceId].title}${status}`;
return (
<li
key={recordingId}
@@ -259,7 +281,6 @@ RecordTabComponent.propTypes = {
generatedRecordings: propTypes.object.isRequired,
lastRecordingGenerationLength: propTypes.string.isRequired,
isOnline: propTypes.bool.isRequired,
cachedPieceIds: propTypes.object.isRequired,
removeRecordingGeneration: propTypes.func.isRequired,
startRecordingGeneration: propTypes.func.isRequired,
};

View File

@@ -20,7 +20,6 @@ const mapStateToProps = ({
sorting,
visiblePieceIds,
isOnline,
cachedPieceIds,
}) => ({
selectedPieceId,
isPlaying,
@@ -30,7 +29,6 @@ const mapStateToProps = ({
sorting,
visiblePieceIds,
isOnline,
cachedPieceIds,
isLoading: loadingPieceBuildId !== '',
isRecordingGenerationInProgress: isRecordingGenerationInProgress(
generatedRecordings
@@ -47,7 +45,4 @@ const mapDispatchToProps = {
onPlayClick: play,
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(PiecesTabComponent);
export default connect(mapStateToProps, mapDispatchToProps)(PiecesTabComponent);

View File

@@ -10,21 +10,16 @@ const mapStateToProps = ({
generatedRecordings,
lastRecordingGenerationLength,
isOnline,
cachedPieceIds,
}) => ({
selectedPieceId,
generatedRecordings,
lastRecordingGenerationLength,
isOnline,
cachedPieceIds,
});
export default connect(
mapStateToProps,
{
selectPiece,
queueRecordingGeneration,
removeRecordingGeneration,
startRecordingGeneration,
}
)(recordTabComponent);
export default connect(mapStateToProps, {
selectPiece,
queueRecordingGeneration,
removeRecordingGeneration,
startRecordingGeneration,
})(recordTabComponent);

8
src/pieces/provider.js Normal file
View File

@@ -0,0 +1,8 @@
import getSamplesByFormat from '@generative-music/samples-alex-bainter';
import makeProvider from '@generative-music/web-provider';
import sampleFormat from '@config/sample-format';
const sampleIndex = getSamplesByFormat()[sampleFormat];
const provider = makeProvider(sampleIndex);
export default provider;

View File

@@ -2,12 +2,10 @@ import isMobile from '@config/is-mobile';
import getOnlineStatus from '@utils/get-online-status';
import objToMap from '@utils/obj-to-map';
import getSortedFilteredPieceIds from './get-sorted-filtered-piece-ids';
import { version } from '../../package.json';
const MOBILE_VOLUME_PCT = 95;
const getInitialState = storedState => {
const isNewVersion = storedState.version === version;
const initialState = Object.assign({}, storedState, {
isPlaying: false,
isUpdateAvailable: false,
@@ -32,9 +30,6 @@ const getInitialState = storedState => {
timer: Object.assign({}, storedState.timer, { remainingMS: 0 }),
favorites: new Set(storedState.favorites),
isInstallable: false,
cachedPieceIds: isNewVersion
? new Set(storedState.cachedPieceIds)
: new Set(),
});
if (typeof storedState.globalPlayTime === 'object') {

View File

@@ -1,6 +1,5 @@
import Tone from 'tone';
import getSamplesByFormat from '@generative-music/samples-alex-bainter';
import sampleFormat from '@config/sample-format';
import provider from '@pieces/provider';
import markPieceBuildLoading from '../../actions/creators/mark-piece-build-loading.creator';
import markPieceBuildLoaded from '../../actions/creators/mark-piece-build-loaded.creator';
import performance from './performance';
@@ -12,8 +11,6 @@ let lastBuildId;
let isPerformanceBuilding = false;
let queuedPiece = null;
const sampleIndex = getSamplesByFormat()[sampleFormat];
const makePlayPiece = (store, performances) => {
const playPiece = piece => {
if (!isPerformanceBuilding) {
@@ -49,31 +46,33 @@ const makePlayPiece = (store, performances) => {
// console.log(maxDb);
// }, 1000);
piece
.makePiece({
destination: pieceVol,
audioContext: Tone.context,
samples: sampleIndex,
})
.then(cleanUp => {
piecePerformance.addCleanupFn(cleanUp);
piecePerformance.isLoaded = true;
isPerformanceBuilding = false;
const { selectedPieceId, isPlaying } = store.getState();
store.dispatch(markPieceBuildLoaded(piecePerformance));
if (
lastBuildId === piecePerformance.performanceId &&
selectedPieceId === piece.id &&
isPlaying
) {
Tone.Transport.start();
} else {
stopPerformances(performances);
}
if (isPlaying && queuedPiece !== null) {
playPiece(queuedPiece, store);
}
});
provider.provide(piece.sampleNames, Tone.context).then(samples => {
piece
.makePiece({
destination: pieceVol,
audioContext: Tone.context,
samples,
})
.then(cleanUp => {
piecePerformance.addCleanupFn(cleanUp);
piecePerformance.isLoaded = true;
isPerformanceBuilding = false;
const { selectedPieceId, isPlaying } = store.getState();
store.dispatch(markPieceBuildLoaded(piecePerformance));
if (
lastBuildId === piecePerformance.performanceId &&
selectedPieceId === piece.id &&
isPlaying
) {
Tone.Transport.start();
} else {
stopPerformances(performances);
}
if (isPlaying && queuedPiece !== null) {
playPiece(queuedPiece, store);
}
});
});
} else {
queuedPiece = piece;
}

View File

@@ -1,8 +0,0 @@
import MARK_PIECE_BUILD_LOADED from '../actions/types/mark-piece-build-loaded.type';
const cachedPieceIdsReducer = (state = new Set(), action) =>
action.type === MARK_PIECE_BUILD_LOADED
? new Set([...state, action.payload.pieceId])
: state;
export default cachedPieceIdsReducer;

View File

@@ -20,7 +20,6 @@ import filter from './filter.reducer';
import sorting from './sorting.reducer';
import visiblePieceIdsReducer from './visible-piece-ids.reducer';
import isInstallable from './is-installable.reducer';
import cachedPieceIds from './cached-piece-ids.reducer';
import globalPlayTime from './global-play-time.reducer';
import favoriteCount from './favorite-count.reducer';
@@ -45,7 +44,6 @@ const combinedReducer = combineReducers({
filter,
sorting,
isInstallable,
cachedPieceIds,
globalPlayTime,
favoriteCount,
});

View File

@@ -4,7 +4,6 @@ const stringifyState = state =>
JSON.stringify(
Object.assign({}, state, {
favorites: [...state.favorites],
cachedPieceIds: [...state.cachedPieceIds],
globalPlayTime: mapToObj(state.globalPlayTime),
favoriteCount: mapToObj(state.favoriteCount),
})