import React, { useEffect, useState, useReducer } from 'react';
import { Box, Typography, IconButton, CircularProgress } from '@material-ui/core';
import PersonIcon from '@material-ui/icons/Person';
import * as serverApi from '../../../api/api';
import { WindowState } from '../Windows';
import StoreLinkIcon, { whichStore } from '../../common/StoreLinkIcon';
import EditableText from '../../common/EditableText';
import SubmitChangesButton from '../../common/SubmitChangesButton';
import TrackTable, { TrackGetters } from '../../tables/ResultsTable';
import { modifyArtist } from '../../../lib/saveChanges';
import { QueryLeafBy, QueryLeafOp } from '../../../lib/query/Query';
import { queryArtists, queryTracks } from '../../../lib/backend/queries';
import { trackGetters } from '../../../lib/trackGetters';
import { useParams } from 'react-router';
import { handleNotLoggedIn, NotLoggedInError } from '../../../lib/backend/request';
import { useAuth } from '../../../lib/useAuth';
export type ArtistMetadata = serverApi.ArtistWithId;
export type ArtistMetadataChanges = serverApi.PatchArtistRequest;
export interface ArtistWindowState extends WindowState {
id: number,
metadata: ArtistMetadata | null,
pendingChanges: ArtistMetadataChanges | null,
tracksByArtist: any[] | null,
trackGetters: TrackGetters,
}
export enum ArtistWindowStateActions {
SetMetadata = "SetMetadata",
SetPendingChanges = "SetPendingChanges",
SetTracks = "SetTracks",
Reload = "Reload",
}
export function ArtistWindowReducer(state: ArtistWindowState, action: any) {
switch (action.type) {
case ArtistWindowStateActions.SetMetadata:
return { ...state, metadata: action.value }
case ArtistWindowStateActions.SetPendingChanges:
return { ...state, pendingChanges: action.value }
case ArtistWindowStateActions.SetTracks:
return { ...state, tracksByArtist: action.value }
case ArtistWindowStateActions.Reload:
return { ...state, metadata: null, pendingChanges: null, tracksByArtist: null }
default:
throw new Error("Unimplemented ArtistWindow state update.")
}
}
export interface IProps {
state: ArtistWindowState,
dispatch: (action: any) => void,
}
export async function getArtistMetadata(id: number) {
let response: any = await queryArtists(
{
a: QueryLeafBy.ArtistId,
b: id,
leafOp: QueryLeafOp.Equals,
}, 0, 1, serverApi.QueryResponseType.Details
);
return response[0];
}
export default function ArtistWindow(props: {}) {
const { id } = useParams<{ id: string }>();
const [state, dispatch] = useReducer(ArtistWindowReducer, {
id: parseInt(id),
metadata: null,
pendingChanges: null,
trackGetters: trackGetters,
tracksByArtist: null,
});
return
}
export function ArtistWindowControlled(props: {
state: ArtistWindowState,
dispatch: (action: any) => void,
}) {
let { metadata, id: artistId, pendingChanges, tracksByArtist } = props.state;
let { dispatch } = props;
let auth = useAuth();
// Effect to get the artist's metadata.
useEffect(() => {
getArtistMetadata(artistId)
.then((m: ArtistMetadata) => {
dispatch({
type: ArtistWindowStateActions.SetMetadata,
value: m
});
})
.catch((e: any) => { handleNotLoggedIn(auth, e) })
}, [artistId, dispatch]);
// Effect to get the artist's tracks.
useEffect(() => {
if (tracksByArtist) { return; }
(async () => {
const tracks = await queryTracks(
{
a: QueryLeafBy.ArtistId,
b: artistId,
leafOp: QueryLeafOp.Equals,
}, 0, -1, serverApi.QueryResponseType.Details,
)
.catch((e: any) => { handleNotLoggedIn(auth, e) });
dispatch({
type: ArtistWindowStateActions.SetTracks,
value: tracks,
});
})();
}, [tracksByArtist, dispatch, artistId]);
const [editingName, setEditingName] = useState(null);
const name = setEditingName(v)}
onChangeChangedValue={(v: string | null) => {
let newVal: any = { ...pendingChanges };
if (v) { newVal.name = v }
else { delete newVal.name }
props.dispatch({
type: ArtistWindowStateActions.SetPendingChanges,
value: newVal,
})
}}
/>
const storeLinks = metadata?.storeLinks && metadata?.storeLinks.map((link: string) => {
const store = whichStore(link);
return store &&
});
const [applying, setApplying] = useState(false);
const maybeSubmitButton = pendingChanges && Object.keys(pendingChanges).length > 0 &&
{
setApplying(true);
modifyArtist(props.state.id, pendingChanges || { mbApi_typename: 'artist' })
.then(() => {
setApplying(false);
props.dispatch({
type: ArtistWindowStateActions.Reload
})
})
.catch((e: any) => { handleNotLoggedIn(auth, e) })
}} />
{applying && }
return
{metadata &&
{name}
{storeLinks}
}
{maybeSubmitButton}
Tracks by this artist in your library:
{props.state.tracksByArtist && }
{!props.state.tracksByArtist && }
}