diff --git a/js/actionCreators/files.ts b/js/actionCreators/files.ts index d45b4458..455c3419 100644 --- a/js/actionCreators/files.ts +++ b/js/actionCreators/files.ts @@ -7,6 +7,7 @@ import { promptForFileReferences, genArrayBufferFromFileReference, genMediaDuration, + genMediaTags, } from "../fileUtils"; import skinParser from "../skinParser"; import { @@ -22,6 +23,8 @@ import { BUFFER_TRACK, SET_MEDIA_TAGS, SET_MEDIA_DURATION, + MEDIA_TAG_REQUEST_INITIALIZED, + MEDIA_TAG_REQUEST_FAILED, SET_SKIN_DATA, LOADED, LOADING, @@ -30,7 +33,7 @@ import LoadQueue from "../loadQueue"; import { removeAllTracks } from "./playlist"; import { setPreamp, setEqBand } from "./equalizer"; -import { LoadStyle, Thunk, Action, Track, EqfPreset, SkinData } from "../types"; +import { LoadStyle, Thunk, Track, EqfPreset, SkinData } from "../types"; // Lower is better const DURATION_VISIBLE_PRIORITY = 5; @@ -294,8 +297,36 @@ function queueFetchingMediaTags(id: number): Thunk { }; } -export function fetchMediaTags(file: string | Blob, id: number): Action { - return { type: "FETCH_MEDIA_TAGS", file, id }; +export function fetchMediaTags(file: string | Blob, id: number): Thunk { + return async (dispatch, getState, { requireMusicMetadata }) => { + dispatch({ type: MEDIA_TAG_REQUEST_INITIALIZED, id }); + + try { + const metadata = await genMediaTags(file, await requireMusicMetadata()); + // 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); + } + dispatch({ + type: SET_MEDIA_TAGS, + artist: artist ? artist : "", + title: title ? title : "", + album, + albumArtUrl, + numberOfChannels, + bitrate, + sampleRate, + id, + }); + } catch (e) { + dispatch({ type: MEDIA_TAG_REQUEST_FAILED, id }); + } + }; } export function setEqFromFileReference(fileReference: File): Thunk { diff --git a/js/actionTypes.ts b/js/actionTypes.ts index e3988068..8daa196b 100644 --- a/js/actionTypes.ts +++ b/js/actionTypes.ts @@ -87,4 +87,3 @@ export const TOGGLE_RANDOMIZE_PRESETS = "TOGGLE_RANDOMIZE_PRESETS"; export const TOGGLE_PRESET_CYCLING = "TOGGLE_PRESET_CYCLING"; export const SCHEDULE_MILKDROP_MESSAGE = "SCHEDULE_MILKDROP_MESSAGE"; export const SET_MILKDROP_FULLSCREEN = "SET_MILKDROP_FULLSCREEN"; -export const FETCH_MEDIA_TAGS = "FETCH_MEDIA_TAGS"; diff --git a/js/epics.ts b/js/epics.ts deleted file mode 100644 index 0bc5e794..00000000 --- a/js/epics.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { Observable, of, defer, concat } from "rxjs"; -import { filter, mergeMap, catchError } from "rxjs/operators"; -import { Action, AppState, Extras } 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, - states: Observable, - { requireMusicMetadata }: Extras -): Observable => { - return actions.pipe( - filter(action => action.type === 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 const), - 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 const; - }).pipe( - catchError(e => { - console.error("Failed to fetch media tags", e); - return of({ - type: MEDIA_TAG_REQUEST_FAILED, - id, - } as const); - }) - ) - ); - }) - ); -}; diff --git a/js/store.ts b/js/store.ts index 8dfeaa20..1b0d4010 100644 --- a/js/store.ts +++ b/js/store.ts @@ -8,8 +8,6 @@ import { UPDATE_TIME_ELAPSED, STEP_MARQUEE } from "./actionTypes"; import Media from "./media"; import Emitter from "./emitter"; import { Extras, Dispatch, Action, AppState, Middleware } from "./types"; -import { createEpicMiddleware, combineEpics } from "redux-observable"; -import * as Epics from "./epics"; // TODO: Move to demo const compose = composeWithDevTools({ @@ -36,15 +34,10 @@ export default function( return next(action); }; - const epicMiddleware = createEpicMiddleware({ - dependencies: extras, - }); - const enhancer = compose( applyMiddleware( ...[ thunk.withExtraArgument(extras), - epicMiddleware, mediaMiddleware(media), emitterMiddleware, ...customMiddlewares, @@ -57,7 +50,5 @@ export default function( const store = initialState ? createStore(reducer, initialState, enhancer) : createStore(reducer, enhancer); - - epicMiddleware.run(combineEpics(...Object.values(Epics))); return store; } diff --git a/js/types.ts b/js/types.ts index 7dca66d5..cb98ca77 100644 --- a/js/types.ts +++ b/js/types.ts @@ -509,12 +509,7 @@ export type Action = index: number; transitionType: TransitionType; } - | { type: "TOGGLE_PRESET_OVERLAY" } - | { - type: "FETCH_MEDIA_TAGS"; - file: string | Blob; - id: number; - }; + | { type: "TOGGLE_PRESET_OVERLAY" }; export type MediaTagRequestStatus = | "INITIALIZED" diff --git a/package.json b/package.json index 7a450a3f..47629e79 100644 --- a/package.json +++ b/package.json @@ -154,9 +154,7 @@ }, "dependencies": { "eslint-plugin-react-hooks": "^1.5.1", - "fscreen": "^1.0.2", - "redux-observable": "^1.1.0", - "rxjs": "^6.5.2" + "fscreen": "^1.0.2" }, "bundlesize": [ { diff --git a/yarn.lock b/yarn.lock index a37e52dc..d740f52d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9079,11 +9079,6 @@ redux-devtools-extension@^2.13.2: resolved "https://registry.yarnpkg.com/redux-devtools-extension/-/redux-devtools-extension-2.13.8.tgz#37b982688626e5e4993ff87220c9bbb7cd2d96e1" integrity sha512-8qlpooP2QqPtZHQZRhx3x3OP5skEV1py/zUdMY28WNAocbafxdG2tRD1MWE7sp8obGMNYuLWanhhQ7EQvT1FBg== -redux-observable@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/redux-observable/-/redux-observable-1.1.0.tgz#323a8fe53e89fdb519be2807b55f08e21c13e6f1" - integrity sha512-G0nxgmTZwTK3Z3KoQIL8VQu9n0YCUwEP3wc3zxKQ8zAZm+iYkoZvBqAnBJfLi4EsD1E64KR4s4jFH/dFXpV9Og== - redux-thunk@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" @@ -9464,13 +9459,6 @@ rxjs@^6.4.0: dependencies: tslib "^1.9.0" -rxjs@^6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.2.tgz#2e35ce815cd46d84d02a209fb4e5921e051dbec7" - integrity sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg== - dependencies: - tslib "^1.9.0" - safe-buffer@5.1.1, safe-buffer@^5.1.0, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"