You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

138 lines
5.6 KiB

import { Box, LinearProgress, Typography } from '@material-ui/core';
import React, { useCallback, useEffect, useReducer, useState } from 'react';
import { $enum } from 'ts-enum-util';
import { ItemType, QueryElemProperty, QueryResponseType } from '../../../api';
import { queryItems } from '../../../lib/backend/queries';
import { QueryElem, QueryLeafBy, QueryLeafOp } from '../../../lib/query/Query';
import StoreLinkIcon, { ExternalStore, StoreURLIdentifiers } from '../../common/StoreLinkIcon';
var _ = require('lodash');
export default function LinksStatusWidget(props: {
}) {
type Counts = {
songs: number | undefined,
albums: number | undefined,
artists: number | undefined,
};
let [totalCounts, setTotalCounts] = useState<Counts | undefined>(undefined);
let [linkedCounts, setLinkedCounts] = useState<Record<string, Counts>>({});
let queryStoreCount = async (store: ExternalStore, type: ItemType) => {
let whichProp: any = {
[ItemType.Song]: QueryLeafBy.SongStoreLinks,
[ItemType.Artist]: QueryLeafBy.ArtistStoreLinks,
[ItemType.Album]: QueryLeafBy.AlbumStoreLinks,
}
let whichElem: any = {
[ItemType.Song]: 'songs',
[ItemType.Artist]: 'artists',
[ItemType.Album]: 'albums',
}
let r: any = await queryItems(
[type],
{
a: whichProp[type],
leafOp: QueryLeafOp.Like,
b: `%${StoreURLIdentifiers[store]}%`,
},
undefined,
undefined,
QueryResponseType.Count
);
return r[whichElem[type]];
}
// Start retrieving total counts
useEffect(() => {
(async () => {
let counts: any = await queryItems(
[ItemType.Song, ItemType.Artist, ItemType.Album],
undefined,
undefined,
undefined,
QueryResponseType.Count
);
setTotalCounts(counts);
}
)();
}, []);
// Start retrieving counts per store
useEffect(() => {
(async () => {
let promises = $enum(ExternalStore).getValues().map((s: ExternalStore) => {
let songsPromise: Promise<number> = queryStoreCount(s, ItemType.Song);
let albumsPromise: Promise<number> = queryStoreCount(s, ItemType.Album);
let artistsPromise: Promise<number> = queryStoreCount(s, ItemType.Artist);
let updatePromise = Promise.all([songsPromise, albumsPromise, artistsPromise]).then(
(r: any[]) => {
setLinkedCounts((prev: Record<string, Counts>) => {
return {
...prev,
[s]: {
songs: r[0],
artists: r[2],
albums: r[1],
}
}
});
}
)
console.log(s);
return updatePromise;
})
return Promise.all(promises);
}
)();
}, [setLinkedCounts]);
let storeReady = (s: ExternalStore) => {
return s in linkedCounts;
}
return <Box display="flex" flexDirection="column" alignItems="left">
<table>
{$enum(ExternalStore).getValues().map((s: ExternalStore) => {
if (!totalCounts) { return <></>; }
if (!storeReady(s)) { return <></>; }
let tot = totalCounts;
let lin = linkedCounts[s];
let perc = {
songs: Math.round((lin.songs || 0) / (tot.songs || 1) * 100),
artists: Math.round((lin.artists || 0) / (tot.artists || 1) * 100),
albums: Math.round((lin.albums || 0) / (tot.albums || 1) * 100),
}
return <>
{totalCounts && storeReady(s) && <>
<tr>
<td rowSpan={3}>
<Box display="flex" flexDirection="column" alignItems="center">
<StoreLinkIcon whichStore={s} />
<Typography>{s}</Typography>
</Box>
</td>
<td><Typography>Linked artists:</Typography></td>
<td><Box minWidth="200px"><LinearProgress variant="determinate" color="secondary" value={perc.artists} /></Box></td>
<td><Typography>{lin.artists} / {tot.artists}</Typography></td>
</tr>
<tr>
<td><Typography>Linked albums:</Typography></td>
<td><Box minWidth="200px"><LinearProgress variant="determinate" color="secondary" value={perc.albums} /></Box></td>
<td><Typography>{lin.albums} / {tot.albums}</Typography></td>
</tr>
<tr>
<td><Typography>Linked songs:</Typography></td>
<td><Box minWidth="200px"><LinearProgress variant="determinate" color="secondary" value={perc.songs} /></Box></td>
<td><Typography>{lin.songs} / {tot.songs}</Typography></td>
</tr>
<tr><td colSpan={4}>&nbsp;</td></tr>
</>
}
</>;
})}
</table>
</Box >
}