webamp/js/epics.ts
Jordan Eldredge 647a514d2d Use ofType
2019-05-21 17:18:36 -07:00

67 lines
2.1 KiB
TypeScript

import { Observable, of, defer, concat } from "rxjs";
import { ofType } from "redux-observable";
import { mergeMap, catchError } from "rxjs/operators";
import { Action, Extras, AppState } from "./types";
import {
MEDIA_TAG_REQUEST_INITIALIZED,
SET_MEDIA_TAGS,
MEDIA_TAG_REQUEST_FAILED,
FETCH_MEDIA_TAGS,
} from "./actionTypes";
import { genMediaTags } from "./fileUtils";
export const fetchMediaTagsEpic = (
actions: Observable<Action>,
states: Observable<AppState>,
{ requireMusicMetadata }: Extras
): Observable<Action> => {
return actions.pipe(
ofType(FETCH_MEDIA_TAGS),
mergeMap(action => {
// TODO: Check out https://github.com/piotrwitek/typesafe-actions
if (action.type !== FETCH_MEDIA_TAGS) {
throw new Error("Invalid");
}
const { file, id } = action;
return concat(
of({
type: MEDIA_TAG_REQUEST_INITIALIZED,
id,
} as Action),
defer(async () => {
const musicMetadata = await requireMusicMetadata();
const metadata = await genMediaTags(file, musicMetadata);
// There's more data here, but we don't have a use for it yet:
const { artist, title, album, picture } = metadata.common;
const { numberOfChannels, bitrate, sampleRate } = metadata.format;
let albumArtUrl = null;
if (picture && picture.length >= 1) {
const byteArray = new Uint8Array(picture[0].data);
const blob = new Blob([byteArray], { type: picture[0].format });
albumArtUrl = URL.createObjectURL(blob);
}
return {
type: SET_MEDIA_TAGS,
artist: artist ? artist : "",
title: title ? title : "",
album,
albumArtUrl,
numberOfChannels,
bitrate,
sampleRate,
id,
} as Action;
}).pipe(
catchError(e => {
console.error("Failed to fetch media tags", e);
return of({
type: MEDIA_TAG_REQUEST_FAILED,
id,
} as Action);
})
)
);
})
);
};