diff --git a/packages/app/app/actions/tag.js b/packages/app/app/actions/tag.ts similarity index 79% rename from packages/app/app/actions/tag.js rename to packages/app/app/actions/tag.ts index 226cf53fb8..ca7800cdb3 100644 --- a/packages/app/app/actions/tag.js +++ b/packages/app/app/actions/tag.ts @@ -7,14 +7,14 @@ export const LOAD_TAG_INFO_SUCCESS = 'LOAD_TAG_INFO_SUCCESS'; export const LOAD_TAG_INFO_ERROR = 'LOAD_TAG_INFO_ERROR'; const lastfm = new rest.LastFmApi(globals.lastfmApiKey, globals.lastfmApiSecret); -export function loadTagInfoStart(tag) { +export function loadTagInfoStart(tag: string) { return { type: LOAD_TAG_INFO_START, payload: tag }; } -export function loadTagInfoSuccess(tag, data) { +export function loadTagInfoSuccess(tag: string, data) { return { type: LOAD_TAG_INFO_SUCCESS, payload: { @@ -24,14 +24,14 @@ export function loadTagInfoSuccess(tag, data) { }; } -export function loadTagInfoError(tag) { +export function loadTagInfoError(tag: string) { return { type: LOAD_TAG_INFO_ERROR, payload: tag }; } -export function loadTagInfo(tag) { +export function loadTagInfo(tag: string) { return dispatch => { dispatch(loadTagInfoStart(tag)); @@ -41,8 +41,7 @@ export function loadTagInfo(tag) { lastfm.getTagAlbums(tag), lastfm.getTagArtists(tag) ]) - .then(results => Promise.all(results.map(r => r.json()))) - .then(results => { + .then((results) => { dispatch(loadTagInfoSuccess(tag, results)); }) .catch(error => { diff --git a/packages/app/app/components/TagView/index.js b/packages/app/app/components/TagView/index.js index 7529e541e5..3e1e23653c 100644 --- a/packages/app/app/components/TagView/index.js +++ b/packages/app/app/components/TagView/index.js @@ -42,7 +42,6 @@ class TagView extends React.Component { ); } - renderTopAlbums (topAlbums) { return ( diff --git a/packages/app/app/reducers/tag.js b/packages/app/app/reducers/tag.ts similarity index 100% rename from packages/app/app/reducers/tag.js rename to packages/app/app/reducers/tag.ts diff --git a/packages/core/src/rest/Lastfm.ts b/packages/core/src/rest/Lastfm.ts index 6586e03739..4a79658d78 100644 --- a/packages/core/src/rest/Lastfm.ts +++ b/packages/core/src/rest/Lastfm.ts @@ -1,4 +1,5 @@ import md5 from 'md5'; +import { LastFmArtistInfo, LastfmAlbum, LastfmArtistShort, LastfmTag, LastfmTrackMatch } from './Lastfm.types'; const scrobblingApiUrl = 'https://ws.audioscrobbler.com/2.0/'; @@ -6,7 +7,7 @@ class LastFmApi { constructor( private key: string, private secret: string - ) {} + ) { } sign(url: string): string { const tokens = decodeURIComponent((url.split('?')[1].split('&').sort().join()).replace(/,/g, '').replace(/=/g, '')); @@ -16,8 +17,8 @@ class LastFmApi { prepareUrl(url: string): string { const withApiKey = `${url}&api_key=${this.key}`; - - return `${withApiKey}&api_sig=${this.sign(withApiKey)}` ; + + return `${withApiKey}&api_sig=${this.sign(withApiKey)}`; } addApiKey(url: string): string { @@ -29,20 +30,20 @@ class LastFmApi { } lastFmLogin(authToken: string): Promise { - return fetch(this.prepareUrl(scrobblingApiUrl + '?method=auth.getSession&token=' + authToken)+'&format=json'); + return fetch(this.prepareUrl(scrobblingApiUrl + '?method=auth.getSession&token=' + authToken) + '&format=json'); } scrobble(artist: string, track: string, session: string): Promise { return fetch(this.prepareUrl( scrobblingApiUrl + - '?method=track.scrobble&sk=' + - session + - '&artist=' + - encodeURIComponent(artist) + - '&track=' + - encodeURIComponent(track) + - '×tamp=' + - (Math.floor(Date.now() /1000 - 540))), + '?method=track.scrobble&sk=' + + session + + '&artist=' + + encodeURIComponent(artist) + + '&track=' + + encodeURIComponent(track) + + '×tamp=' + + (Math.floor(Date.now() / 1000 - 540))), { method: 'POST' } @@ -52,12 +53,12 @@ class LastFmApi { updateNowPlaying(artist: string, track: string, session: string): Promise { return fetch(this.prepareUrl( scrobblingApiUrl + - '?method=track.updateNowPlaying&sk=' + - session + - '&artist=' + - encodeURIComponent(artist) + - '&track=' + - encodeURIComponent(track)), + '?method=track.updateNowPlaying&sk=' + + session + + '&artist=' + + encodeURIComponent(artist) + + '&track=' + + encodeURIComponent(track)), { method: 'POST' } @@ -67,94 +68,101 @@ class LastFmApi { getArtistInfo(artist: string): Promise { return fetch(this.addApiKey( scrobblingApiUrl + - '?method=artist.getinfo&artist=' + - encodeURIComponent(artist) + - '&format=json' + '?method=artist.getinfo&artist=' + + encodeURIComponent(artist) + + '&format=json' )); } getArtistTopTracks(artist: string): Promise { return fetch(this.addApiKey( scrobblingApiUrl + - '?method=artist.gettoptracks&artist=' + - encodeURIComponent(artist) + - '&format=json' + '?method=artist.gettoptracks&artist=' + + encodeURIComponent(artist) + + '&format=json' )); } getTopTags(): Promise { return fetch(this.addApiKey( scrobblingApiUrl + - '?method=tag.getTopTags&format=json' + '?method=tag.getTopTags&format=json' )); } getTopTracks(): Promise { return fetch(this.addApiKey( scrobblingApiUrl + - '?method=chart.getTopTracks&format=json' + '?method=chart.getTopTracks&format=json' )); } - getTagInfo(tag: string): Promise { - return fetch(this.addApiKey( + async getTagInfo(tag: string): Promise { + const result = await (await fetch(this.addApiKey( scrobblingApiUrl + - '?method=tag.getInfo&format=json&tag=' + - tag - )); + '?method=tag.getInfo&format=json&tag=' + + tag + ))).json(); + + return result.tag as LastfmTag; } - getTagTracks(tag: string): Promise { - return fetch(this.addApiKey( + async getTagTracks(tag: string): Promise { + const result = await (await fetch(this.addApiKey( scrobblingApiUrl + - '?method=tag.getTopTracks&format=json&tag=' + - tag - )); + '?method=tag.getTopTracks&format=json&tag=' + + tag + ))).json(); + + return result.tracks.track as LastfmTrackMatch[]; } - getTagAlbums(tag: string): Promise { - return fetch(this.addApiKey( + async getTagAlbums(tag: string): Promise { + const result = await (await fetch(this.addApiKey( scrobblingApiUrl + - '?method=tag.getTopAlbums&format=json&tag=' + - tag - )); + '?method=tag.getTopAlbums&format=json&tag=' + + tag + ))).json(); + return result.albums.album as LastfmAlbum[]; } - getTagArtists(tag: string): Promise { - return fetch(this.addApiKey( + async getTagArtists(tag: string): Promise { + const result = await (await fetch(this.addApiKey( scrobblingApiUrl + - '?method=tag.getTopArtists&format=json&tag=' + - tag - )); + '?method=tag.getTopArtists&format=json&tag=' + + tag + ))).json(); + + return result.topartists.artist as LastfmArtistShort[]; } getSimilarTags(tag: string): Promise { return fetch(this.addApiKey( scrobblingApiUrl + - '?method=tag.getSimilar&format=json&tag=' + - tag + '?method=tag.getSimilar&format=json&tag=' + + tag )); } getSimilarTracks(artist: string, track: string, limit = 100): Promise { return fetch(this.addApiKey( scrobblingApiUrl + - '?method=track.getSimilar&format=json&artist=' + - artist + - '&track=' + - track + - '&limit=' + - limit + '?method=track.getSimilar&format=json&artist=' + + artist + + '&track=' + + track + + '&limit=' + + limit )); } searchTracks(terms: string, limit = 30): Promise { return fetch(this.addApiKey( scrobblingApiUrl + - '?method=track.search&format=json&track=' + - encodeURIComponent(terms) + - '&limit=' + - limit + '?method=track.search&format=json&track=' + + encodeURIComponent(terms) + + '&limit=' + + limit )); } diff --git a/packages/core/src/rest/Lastfm.types.ts b/packages/core/src/rest/Lastfm.types.ts index 374a83bbd5..3ecfb1e935 100644 --- a/packages/core/src/rest/Lastfm.types.ts +++ b/packages/core/src/rest/Lastfm.types.ts @@ -12,6 +12,12 @@ export type LastfmArtistShort = { export type LastfmTag = { name: string; url: string; + reach: number; + taggings: number; + wiki: { + summary: string; + content: string; + }; } export type LastFmArtistInfo = { @@ -49,13 +55,13 @@ export type LastfmTopTracks = { } export type LastfmTrackMatch = { - name: string - artist: string - image: LastfmImage[] - listeners: string - mbid: string - streamable: string - url: string + name: string; + mbid: string; + url: string; + streamable: string; + artist: string; + image: LastfmImage[]; + listeners: string; } export type LastfmTrackMatchInternal = LastfmTrackMatch & { thumbnail: string } @@ -65,3 +71,11 @@ export type LastfmTopTag = { count: number reach: number } + +export type LastfmAlbum = { + name: string; + mbid: string; + url: string; + artist: string; + image: LastfmImage[]; +}