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 && } }