Skip to content

Commit

Permalink
Add new APIs to Webamp NPM module
Browse files Browse the repository at this point in the history
  • Loading branch information
captbaritone committed Aug 25, 2024
1 parent 10bdc0f commit b52efcd
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 6 deletions.
8 changes: 7 additions & 1 deletion packages/webamp/js/selectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ export const getOrderedTracks = createSelector(
(tracks, trackOrder) => trackOrder.filter((id) => tracks[id])
);

export const getPlaylistTracks = createSelector(
getTracks,
getTrackOrder,
(tracks, trackOrder) => trackOrder.map((id) => tracks[id]).filter(Boolean)
);

export const getUserTracks = createSelector(
getTracks,
getTrackOrder,
Expand Down Expand Up @@ -135,7 +141,7 @@ export const getRunningTimeMessage = createSelector(
)}`
);

// TODO: use slectors to get memoization
// TODO: use selectors to get memoization
export const getCurrentTrackIndex = (state: AppState): number => {
const { playlist } = state;
if (playlist.currentTrack == null) {
Expand Down
75 changes: 70 additions & 5 deletions packages/webamp/js/webampLazy.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
PartialState,
Options,
MediaStatus,
PlaylistTrack,
} from "./types";
import getStore from "./store";
import App from "./components/App";
Expand Down Expand Up @@ -230,14 +231,14 @@ class Webamp {
}

/**
* Seek backward n seconds in the curent track
* Seek backward n seconds in the current track
*/
seekBackward(seconds: number) {
this.store.dispatch(Actions.seekBackward(seconds));
}

/**
* Seek forward n seconds in the curent track
* Seek forward n seconds in the current track
*/
seekForward(seconds: number) {
this.store.dispatch(Actions.seekForward(seconds));
Expand All @@ -250,6 +251,20 @@ class Webamp {
this.store.dispatch(Actions.seekToTime(seconds));
}

/**
* Check if shuffle is enabled
*/
isShuffleEnabled(): boolean {
return Selectors.getShuffle(this.store.getState());
}

/**
* Check if repeat is enabled
*/
isRepeatEnabled(): boolean {
return Selectors.getRepeat(this.store.getState());
}

/**
* Play the next track
*/
Expand All @@ -264,6 +279,13 @@ class Webamp {
this.store.dispatch(Actions.previous());
}

/**
* Play a specific track by index
*/
playTrack(index: number): void {
this.store.dispatch(Actions.playTrack(index));
}

/**
* Add an array of `Track`s to the end of the playlist.
*/
Expand All @@ -281,6 +303,13 @@ class Webamp {
this.store.dispatch(Actions.loadMediaFiles(tracks, LOAD_STYLE.PLAY));
}

/**
* Get the current playlist in order.
*/
getPlaylistTracks(): PlaylistTrack[] {
return Selectors.getPlaylistTracks(this.store.getState());
}

/**
* Get the current "playing" status.
*/
Expand Down Expand Up @@ -325,14 +354,50 @@ class Webamp {
this.store.dispatch(Actions.open());
}

/**
* A callback which will be called whenever a the current track changes.
*
* The callback is passed the current track and the zero-based index of the
* current track's position within the playlist.
*
* Note: This is different from the `onTrackDidChange` callback which is only
* called when a new track first starts loading.
*
* @returns An "unsubscribe" function. Useful if at some point in the future
* you want to stop listening to these events.
*/
onCurrentTrackDidChange(
cb: (currentTrack: PlaylistTrack, trackIndex: number) => void
): () => void {
let previousTrack: PlaylistTrack | null = null;
return this.store.subscribe(() => {
const state = this.store.getState();
const currentTrack = Selectors.getCurrentTrack(state);
if (currentTrack == null || currentTrack === previousTrack) {
return;
}
previousTrack = currentTrack;
const trackIndex = Selectors.getCurrentTrackIndex(state);
cb(currentTrack, trackIndex);
});
}

/**
* A callback which will be called when a new track starts loading.
*
* This can happen on startup when the first track starts buffering, or when a subsequent track starts playing.
* The callback will be called with an object `({url: 'https://example.com/track.mp3'})` containing the URL of the track.
* This can happen on startup when the first track starts buffering, or when a
* subsequent track starts playing. The callback will be called with an
* object `({url: 'https://example.com/track.mp3'})` containing the URL of the
* track.
*
* Note: If the user drags in a track, the URL may be an ObjectURL.
*
* @returns An "unsubscribe" function. Useful if at some point in the future you want to stop listening to these events.
* Note: This is different from the `onCurrentTrackDidChange` callback which
* is called every time a track changes. This callback is only called when a
* new track starts loading.
*
* @returns An "unsubscribe" function. Useful if at some point in the future
* you want to stop listening to these events.
*/
onTrackDidChange(cb: (trackInfo: LoadedURLTrack | null) => void): () => void {
let previousTrackId: number | null = null;
Expand Down

0 comments on commit b52efcd

Please sign in to comment.