diff --git a/client/src/api.ts b/client/src/api.ts index 748c80c..812ad32 100644 --- a/client/src/api.ts +++ b/client/src/api.ts @@ -22,6 +22,14 @@ export interface ArtistDetails { export function isArtistDetails(q: any): q is ArtistDetails { return 'artistId' in q; } +export interface AlbumDetails { + albumId: number, + name: string, + storeLinks?: string[], +} +export function isAlbumDetails(q: any): q is ArtistDetails { + return 'albumId' in q; +} export interface TagDetails { tagId: number, name: string, @@ -45,6 +53,7 @@ export interface SongDetails { songId: number, title: string, artists?: ArtistDetails[], + albums?: AlbumDetails[], tags?: TagDetails[], storeLinks?: string[], rankings?: RankingDetails[], diff --git a/client/src/components/Window.tsx b/client/src/components/Window.tsx index e6d3013..52856da 100644 --- a/client/src/components/Window.tsx +++ b/client/src/components/Window.tsx @@ -4,6 +4,7 @@ import { QueryElem, toApiQuery } from '../lib/query/Query'; import QueryBuilder from './querybuilder/QueryBuilder'; import * as serverApi from '../api'; import { SongTable } from './tables/ResultsTable'; +import stringifyList from '../lib/stringifyList'; var _ = require('lodash'); const darkTheme = createMuiTheme({ @@ -96,8 +97,8 @@ export default function Window(props: any) { const songGetters = { getTitle: (song: any) => song.title, - getArtist: (song: any) => "Artist", - getAlbum: (song: any) => "Album", + getArtist: (song: any) => stringifyList(song.artists, (a: any) => a.name), + getAlbum: (song: any) => stringifyList(song.albums, (a: any) => a.name), } const doQuery = async (_query: QueryElem) => { diff --git a/client/src/lib/stringifyList.tsx b/client/src/lib/stringifyList.tsx new file mode 100644 index 0000000..dc883ba --- /dev/null +++ b/client/src/lib/stringifyList.tsx @@ -0,0 +1,13 @@ +export default function stringifyList( + s: any[], + stringifyElem?: (e: any) => string, +) { + const stringify = stringifyElem || ((e: any) => e); + var r = ""; + if (s.length > 0) { r += stringify(s[0]) } + for (let i = 1; i < s.length; i++) { + r += ", " + stringify(s[i]); + } + + return r; +} \ No newline at end of file diff --git a/server/endpoints/QueryEndpointHandler.ts b/server/endpoints/QueryEndpointHandler.ts index 7eedd3f..3be1197 100644 --- a/server/endpoints/QueryEndpointHandler.ts +++ b/server/endpoints/QueryEndpointHandler.ts @@ -297,13 +297,19 @@ export const QueryEndpointHandler: EndpointHandler = async (req: any, res: any, return await getLinkedObjects(knex, ObjectType.Song, ObjectType.Tag, await songIdsPromise); })() : (async () => { return {}; })(); + const songsAlbumsPromise: Promise> = (songLimit && songLimit > 0) ? + (async () => { + return await getLinkedObjects(knex, ObjectType.Song, ObjectType.Album, await songIdsPromise); + })() : + (async () => { return {}; })(); const [ songs, artists, tags, songsArtists, - songsTags + songsTags, + songsAlbums, ] = await Promise.all([ songsPromise, @@ -311,6 +317,7 @@ export const QueryEndpointHandler: EndpointHandler = async (req: any, res: any, tagsPromise, songsArtistsPromise, songsTagsPromise, + songsAlbumsPromise, ]); const response: api.QueryResponse = { @@ -332,7 +339,13 @@ export const QueryEndpointHandler: EndpointHandler = async (req: any, res: any, name: tag['tags.name'], }; }), - albums: [], //FIXME + albums: songsAlbums[song['songs.id']].map((album: any) => { + return { + albumId: album['albums.id'], + name: album['albums.name'], + storeLinks: asJson(album['albums.storeLinks']), + }; + }), } }), artists: artists.map((artist: any) => { @@ -355,94 +368,4 @@ export const QueryEndpointHandler: EndpointHandler = async (req: any, res: any, } catch (e) { catchUnhandledErrors(e); } - - // try { - // const songLimit = reqObject.offsetsLimits.songLimit; - // const songOffset = reqObject.offsetsLimits.songOffset; - // const tagLimit = reqObject.offsetsLimits.tagLimit; - // const tagOffset = reqObject.offsetsLimits.tagOffset; - // const artistLimit = reqObject.offsetsLimits.artistLimit; - // const artistOffset = reqObject.offsetsLimits.artistOffset; - - // const songs = (songLimit && songLimit > 0) && await models.Song.findAll({ - // // NOTE: have to disable limit and offset because of bug: https://github.com/sequelize/sequelize/issues/11938. - // // Custom pagination is implemented before responding. - // where: getSequelizeWhere(reqObject.query, QueryType.Song), - // order: getSequelizeOrder(reqObject.ordering, QueryType.Song), - // include: [ models.Artist, models.Album, models.Tag, models.Ranking ], - // //limit: reqObject.limit, - // //offset: reqObject.offset, - // }) - // const artists = (artistLimit && artistLimit > 0) && await models.Artist.findAll({ - // // NOTE: have to disable limit and offset because of bug: https://github.com/sequelize/sequelize/issues/11938. - // // Custom pagination is implemented before responding. - // where: getSequelizeWhere(reqObject.query, QueryType.Artist), - // order: getSequelizeOrder(reqObject.ordering, QueryType.Artist), - // include: [models.Song, models.Album, models.Tag], - // //limit: reqObject.limit, - // //offset: reqObject.offset, - // }) - // const tags = (tagLimit && tagLimit > 0) && await models.Tag.findAll({ - // // NOTE: have to disable limit and offset because of bug: https://github.com/sequelize/sequelize/issues/11938. - // // Custom pagination is implemented before responding. - // where: getSequelizeWhere(reqObject.query, QueryType.Tag), - // order: getSequelizeOrder(reqObject.ordering, QueryType.Tag), - // include: [models.Song, models.Album, models.Artist], - // //limit: reqObject.limit, - // //offset: reqObject.offset, - // }) - - // const response: api.QueryResponse = { - // songs: ((songLimit || -1) <= 0) ? [] : await Promise.all(songs.map(async (song: any) => { - // const artists = song.getArtists(); - // const tags = song.getTags(); - // const rankings = song.getRankings(); - // return { - // songId: song.id, - // title: song.title, - // storeLinks: song.storeLinks, - // artists: (await artists).map((artist: any) => { - // return { - // artistId: artist.id, - // name: artist.name, - // } - // }), - // tags: (await tags).map((tag: any) => { - // return { - // tagId: tag.id, - // name: tag.name, - // } - // }), - // rankings: await (await rankings).map(async (ranking: any) => { - // const maybeTagContext: api.TagDetails | undefined = await ranking.getTagContext(); - // const maybeArtistContext: api.ArtistDetails | undefined = await ranking.getArtistContext(); - // const maybeContext = maybeTagContext || maybeArtistContext; - // return { - // rankingId: ranking.id, - // type: api.ItemType.Song, - // rankedId: song.id, - // context: maybeContext, - // value: ranking.value, - // } - // }) - // }; - // }).slice(songOffset || 0, (songOffset || 0) + (songLimit || 10))), - // // TODO: custom pagination due to bug mentioned above - // artists: ((artistLimit || -1) <= 0) ? [] : await Promise.all(artists.map(async (artist: any) => { - // return { - // artistId: artist.id, - // name: artist.name, - // }; - // }).slice(artistOffset || 0, (artistOffset || 0) + (artistLimit || 10))), - // tags: ((tagLimit || -1) <= 0) ? [] : await Promise.all(tags.map(async (tag: any) => { - // return { - // tagId: tag.id, - // name: tag.name, - // }; - // }).slice(tagOffset || 0, (tagOffset || 0) + (tagLimit || 10))), - // }; - // res.send(response); - // } catch (e) { - // catchUnhandledErrors(e); - // } } \ No newline at end of file