Tutorials: Station Playback
Retrieving a current source
The query is added to the currentlyPlaying.graphql
file under src > graphql > queries.
#import "../fragments/trackItem.graphql"
#import "../fragments/audioAdItem.graphql"
#import "../fragments/artistMessageItem.graphql"
#import "../fragments/customTrackItem.graphql"
#import "../fragments/idleTimeoutItem.graphql"
#import "../fragments/simStreamViolationItem.graphql"
#import "../fragments/voiceTrackItem.graphql"
query currentPlaying($deviceUuid: String!) {
playback {
current (deviceUuid: $deviceUuid) {
sourceId
...trackItem
...audioAdItem
...artistMessageItem
...customTrackItem
...idleTimeoutItem
...simStreamViolationItem
...voiceTrackItem
}
}
}
Fragments are used for the different playback source types, since these are reused in other queries and mutations. To get a better understanding of the different types and when they would be used, head over to this section.
The deviceUuid is sent to the query to fetch the last active source on a specific device. When you change the deviceUuid you will get a different source or an error to say that a source has not been set.
A provider was created that serves 2 main functions:
- Export the query in order for components to use the query as is
- Export a higher-order component that takes a Component and returns the component with 3 properties (
isLoading
,playbackItem
, anderrorMessage
) set once the query is run.
These exports can be found in this file: src > graphql > playback > currentlyPlaying.jsx
.
const currentlyPlaying = loader('../queries/currentlyPlaying.graphql');
const withCurrentlyPlaying = graphql(currentlyPlaying, {
skip: (props) => !props.deviceUuid,
props: ({ ownProps, data: { loading, playback, error } }) => {
let errorMessage = error && error.message !== ErrorType.SOURCE_NOT_SET && 'Something went wrong';
if (errorMessage === ErrorType.SKIP_LIMIT_REACHED) {
errorMessage = 'Skip limit reached';
}
let playbackItem = undefined;
if (playback) {
let { current } = playback;
let { audioUrl, feedbackValue, index, interactions, track, sourceId, trackToken } = current ? current : {};
let { meta } = track ? track : {};
let { art, artist, duration, name: trackTitle, id: trackId } = meta ? meta : {};
let { url } = art ? art : {};
let { name: artistName } = artist ? artist : {};
playbackItem = {
audioUrl,
url,
artistName,
trackTitle,
duration,
index,
sourceId,
trackId,
trackToken,
interactions,
feedbackValue,
}
}
let playbackProps = {
isLoading: loading,
playbackItem,
errorMessage: errorMessage,
};
return playbackProps;
},
options: ({ deviceUuid }) => {
return { variables: { deviceUuid } }}
});
export { withCurrentlyPlaying, currentlyPlaying };
In the above code example you will see that the query is imported and loaded with the graphql.macro library. This library compiles GraphQL ASTs at build time using babel macros.
The provider (withCurrentlyPlaying
) is then created. It takes a component as an argument and returns a new component with 3 properties:
isLoading
- is set when the query is still loadingplaybackItem
- contains the response values of the queryerrorMessage
- contains the error message when the query was unsuccessful.
The response of the query is transformed into a flatter structure that is easier to use in components using this provider.
The provider and the query is then both exported.