Skip to content

Commit

Permalink
Load stream sources one by one instead of all at once
Browse files Browse the repository at this point in the history
  • Loading branch information
nukeop committed Oct 17, 2022
1 parent 51db070 commit f2f59d7
Show file tree
Hide file tree
Showing 12 changed files with 729 additions and 45 deletions.
1 change: 0 additions & 1 deletion packages/app/app/actions/actionTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,5 +169,4 @@ export enum Queue {
STREAM_FAILED = 'STREAM_FAILED',
CHANGE_TRACK_STREAM = 'CHANGE_TRACK_STREAM',
ADD_NEW_STREAM = 'ADD_NEW_STREAM',
SET_TRACK_LOADING = 'SET_TRACK_LOADING',
}
23 changes: 13 additions & 10 deletions packages/app/app/actions/queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ export const clearQueue = createStandardAction(Queue.CLEAR_QUEUE)();
export const nextSongAction = createStandardAction(Queue.NEXT_TRACK)();
export const previousSongAction = createStandardAction(Queue.PREVIOUS_TRACK)();
export const selectSong = createStandardAction(Queue.SELECT_TRACK)<number>();
export const setTrackLoading = createStandardAction(Queue.SET_TRACK_LOADING)<number>();
export const playNext = (item: QueueItem) => addToQueue(item, true);

export const addToQueue =
Expand All @@ -118,6 +117,7 @@ export const addToQueue =
const { local }: RootState = getState();
item = {
...safeAddUuid(item),
stream: item.local ? item.stream : undefined,
loading: false
};

Expand All @@ -134,25 +134,28 @@ export const addToQueue =
}
};

export const findStreamForCurrentTrack = () => async (dispatch, getState) => {
export const findStreamForTrack = (idx: number) => async (dispatch, getState) => {
const {queue}: RootState = getState();

const currentTrack = queue.queueItems[queue.currentSong];
if (!currentTrack.local && !currentTrack.stream) {
dispatch(setTrackLoading(queue.currentSong));
const track = queue.queueItems[idx];
if (track && !track.local && !track.stream) {
dispatch(updateQueueItem({
...track,
loading: true
}));
const selectedStreamProvider = getSelectedStreamProvider(getState);
try {
const streamData = await getTrackStream(
currentTrack,
track,
selectedStreamProvider
);

if (streamData === undefined) {
dispatch(removeFromQueue(currentTrack));
dispatch(removeFromQueue(track));
} else {
dispatch(
updateQueueItem({
...currentTrack,
...track,
loading: false,
error: false,
stream: streamData
Expand All @@ -161,12 +164,12 @@ export const findStreamForCurrentTrack = () => async (dispatch, getState) => {
}
} catch (e) {
logger.error(
`An error has occurred when searching for a stream with ${selectedStreamProvider.sourceName} for "${currentTrack.artist} - ${currentTrack.name}."`
`An error has occurred when searching for a stream with ${selectedStreamProvider.sourceName} for "${track.artist} - ${track.name}."`
);
logger.error(e);
dispatch(
updateQueueItem({
...currentTrack,
...track,
loading: false,
error: {
message: `An error has occurred when searching for a stream with ${selectedStreamProvider.sourceName}.`,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { waitFor } from '@testing-library/react';
import { mountedComponentFactory, setupI18Next } from '../../../test/testUtils';
import { buildStoreState } from '../../../test/storeBuilders';
import PlayerBarContainer from '../PlayerBarContainer';

describe('Album view container', () => {
beforeAll(() => {
Expand Down Expand Up @@ -186,15 +187,15 @@ describe('Album view container', () => {
]);
});

it('should load the stream source only for the current track in the queue', async () => {
it('should load the stream sources one by one', async () => {
const { component, store } = mountComponent();
await waitFor(() => component.getByTestId('more-button').click());
await waitFor(() => component.getByText(/Add album to queue/i).click());
component.getByText(/Add album to queue/i).click();
const state = store.getState();

expect(state?.queue?.queueItems[1].stream).toBeUndefined();
expect(state?.queue?.queueItems[2].stream).toBeUndefined();
expect(state?.queue?.queueItems).toEqual([
waitFor(() => expect(state?.queue?.queueItems).toEqual([
expect.objectContaining({
artist: 'test artist',
name: 'test track 1',
Expand All @@ -210,7 +211,7 @@ describe('Album view container', () => {
artist: 'test artist',
name: 'test track 3'
})
]);
]));
});

it('should add album to downloads after clicking the button', async () => {
Expand Down Expand Up @@ -256,6 +257,7 @@ describe('Album view container', () => {
.withArtistDetails()
.withPlugins()
.withConnectivity()
.build()
.build(),
PlayerBarContainer
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -490,6 +490,139 @@ exports[`Album view container should display an album 1`] = `
</div>
</div>
</div>
<div
class="nuclear player_bar"
>
<div
class="nuclear seekbar"
data-testid="seekbar"
>
<div
class="nuclear seekbar_progress"
data-testid="seekbar-fill"
style="width: 0%;"
/>
</div>
<div
class="player_bar_bottom"
>
<div
class="track_info"
>
<div
class="nuclear cover_container"
>
<img
src="test-file-stub"
/>
</div>
</div>
<div
class="player_controls"
>
<button
class="player_button disabled"
data-testid="player-controls-back"
>
<i
aria-hidden="true"
class="step backward large inverted icon"
/>
</button>
<button
class="player_button disabled"
data-testid="player-controls-play"
>
<i
aria-hidden="true"
class="play big inverted icon"
/>
</button>
<button
class="player_button disabled"
data-testid="player-controls-forward"
>
<i
aria-hidden="true"
class="step forward large inverted icon"
/>
</button>
</div>
<div
class="volume_controls_container"
>
<div
class="play_options"
>
<i
aria-hidden="true"
class="repeat large icon play_option_icon"
data-testid="loop-play-option"
/>
<i
aria-hidden="true"
class="random large icon play_option_icon"
data-testid="shuffle-play-option"
/>
<i
aria-hidden="true"
class="magic large icon play_option_icon"
data-testid="autoradio-play-option"
/>
<i
aria-hidden="true"
class="compress large icon play_option_icon"
data-testid="mini-player-play-option"
/>
</div>
<div
class="volume_controls"
>
<div
class="volume_icon"
>
<i
aria-hidden="true"
class="volume up large icon"
/>
</div>
<div
class="volume_slider"
>
<div
class="range"
style="width: 100%;"
>
<div
class="baseDiv"
style="height: 12px;"
>
<div
class="track"
style="border-radius: 4px; background: rgb(68, 71, 90); top: 4px; height: 4px;"
/>
<div
class="fill"
style="border-radius: 4px; background: rgb(248, 248, 242); width: calc(100% * 0.5 + 6px); top: 4px; height: 4px;"
/>
<div
class="thumb"
style="width: 12px; height: 12px; border-radius: 12px; background: rgb(248, 248, 242);"
/>
<input
class="range_input"
max="100"
min="0"
style="top: 4px; height: 12px; width: calc(100% - 12px); margin-left: 6px; margin-right: 6px;"
type="range"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</DocumentFragment>
`;

Expand Down Expand Up @@ -519,5 +652,138 @@ exports[`Album view container should show that an album is still loading 1`] = `
</div>
</div>
</div>
<div
class="nuclear player_bar"
>
<div
class="nuclear seekbar"
data-testid="seekbar"
>
<div
class="nuclear seekbar_progress"
data-testid="seekbar-fill"
style="width: 0%;"
/>
</div>
<div
class="player_bar_bottom"
>
<div
class="track_info"
>
<div
class="nuclear cover_container"
>
<img
src="test-file-stub"
/>
</div>
</div>
<div
class="player_controls"
>
<button
class="player_button disabled"
data-testid="player-controls-back"
>
<i
aria-hidden="true"
class="step backward large inverted icon"
/>
</button>
<button
class="player_button disabled"
data-testid="player-controls-play"
>
<i
aria-hidden="true"
class="play big inverted icon"
/>
</button>
<button
class="player_button disabled"
data-testid="player-controls-forward"
>
<i
aria-hidden="true"
class="step forward large inverted icon"
/>
</button>
</div>
<div
class="volume_controls_container"
>
<div
class="play_options"
>
<i
aria-hidden="true"
class="repeat large icon play_option_icon"
data-testid="loop-play-option"
/>
<i
aria-hidden="true"
class="random large icon play_option_icon"
data-testid="shuffle-play-option"
/>
<i
aria-hidden="true"
class="magic large icon play_option_icon"
data-testid="autoradio-play-option"
/>
<i
aria-hidden="true"
class="compress large icon play_option_icon"
data-testid="mini-player-play-option"
/>
</div>
<div
class="volume_controls"
>
<div
class="volume_icon"
>
<i
aria-hidden="true"
class="volume up large icon"
/>
</div>
<div
class="volume_slider"
>
<div
class="range"
style="width: 100%;"
>
<div
class="baseDiv"
style="height: 12px;"
>
<div
class="track"
style="border-radius: 4px; background: rgb(68, 71, 90); top: 4px; height: 4px;"
/>
<div
class="fill"
style="border-radius: 4px; background: rgb(248, 248, 242); width: calc(100% * 0.5 + 6px); top: 4px; height: 4px;"
/>
<div
class="thumb"
style="width: 12px; height: 12px; border-radius: 12px; background: rgb(248, 248, 242);"
/>
<input
class="range_input"
max="100"
min="0"
style="top: 4px; height: 12px; width: calc(100% - 12px); margin-left: 6px; margin-right: 6px;"
type="range"
/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</DocumentFragment>
`;
Loading

0 comments on commit f2f59d7

Please sign in to comment.