mirror of
https://github.com/austinried/subtracks.git
synced 2025-12-29 09:29:29 +01:00
tryin to get these arts to handle their own shit
This commit is contained in:
parent
23e6c0caf0
commit
c068eac3e5
@ -1,14 +1,21 @@
|
|||||||
|
import { useAtomValue } from 'jotai/utils';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { ActivityIndicator, View } from 'react-native';
|
||||||
import FastImage from 'react-native-fast-image';
|
import FastImage from 'react-native-fast-image';
|
||||||
import LinearGradient from 'react-native-linear-gradient';
|
import LinearGradient from 'react-native-linear-gradient';
|
||||||
|
import { albumArtAtomFamily } from '../../state/music';
|
||||||
import colors from '../../styles/colors';
|
import colors from '../../styles/colors';
|
||||||
import CoverArt from './CoverArt';
|
import CoverArt from './CoverArt';
|
||||||
|
|
||||||
const AlbumArt: React.FC<{
|
interface AlbumArtProps {
|
||||||
height: number,
|
id: string;
|
||||||
width: number,
|
height: number;
|
||||||
coverArtUri?: string
|
width: number;
|
||||||
}> = ({ height, width, coverArtUri }) => {
|
}
|
||||||
|
|
||||||
|
const AlbumArt: React.FC<AlbumArtProps> = ({ id, height, width }) => {
|
||||||
|
const albumArt = useAtomValue(albumArtAtomFamily(id));
|
||||||
|
|
||||||
const Placeholder = () => (
|
const Placeholder = () => (
|
||||||
<LinearGradient
|
<LinearGradient
|
||||||
colors={[colors.accent, colors.accentLow]}
|
colors={[colors.accent, colors.accentLow]}
|
||||||
@ -26,9 +33,25 @@ const AlbumArt: React.FC<{
|
|||||||
PlaceholderComponent={Placeholder}
|
PlaceholderComponent={Placeholder}
|
||||||
height={height}
|
height={height}
|
||||||
width={width}
|
width={width}
|
||||||
coverArtUri={coverArtUri}
|
coverArtUri={width > 128 ? albumArt?.uri : albumArt?.thumbUri}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default React.memo(AlbumArt);
|
const AlbumArtFallback: React.FC<AlbumArtProps> = ({ height, width }) => (
|
||||||
|
<View style={{
|
||||||
|
height, width,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}>
|
||||||
|
<ActivityIndicator size='small' color={colors.accent} />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
|
||||||
|
const AlbumArtLoader: React.FC<AlbumArtProps> = (props) => (
|
||||||
|
<React.Suspense fallback={<AlbumArtFallback { ...props } />}>
|
||||||
|
<AlbumArt { ...props } />
|
||||||
|
</React.Suspense>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default React.memo(AlbumArtLoader);
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { useNavigation } from '@react-navigation/native';
|
import { useNavigation } from '@react-navigation/native';
|
||||||
import { useAtomValue } from 'jotai/utils';
|
import { useAtomValue } from 'jotai/utils';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { GestureResponderEvent, Image, Pressable, ScrollView, Text, useWindowDimensions, View } from 'react-native';
|
import { GestureResponderEvent, Image, Pressable, Text, useWindowDimensions, View } from 'react-native';
|
||||||
import { useCurrentTrackId, useSetQueue } from '../../hooks/player';
|
import { useCurrentTrackId, useSetQueue } from '../../hooks/player';
|
||||||
import { albumAtomFamily } from '../../state/music';
|
import { albumAtomFamily } from '../../state/music';
|
||||||
import colors from '../../styles/colors';
|
import colors from '../../styles/colors';
|
||||||
@ -100,12 +100,7 @@ const AlbumDetails: React.FC<{
|
|||||||
paddingTop: coverSize / 8,
|
paddingTop: coverSize / 8,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<AlbumArt
|
<AlbumArt id={album.id} height={coverSize} width={coverSize} />
|
||||||
height={coverSize}
|
|
||||||
width={coverSize}
|
|
||||||
coverArtUri={album.coverArtUri}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Text style={{
|
<Text style={{
|
||||||
...text.title,
|
...text.title,
|
||||||
marginTop: 12,
|
marginTop: 12,
|
||||||
|
|||||||
@ -1,14 +1,27 @@
|
|||||||
|
import { useAtom } from 'jotai';
|
||||||
|
import { useAtomValue } from 'jotai/utils';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { View } from 'react-native';
|
import { ActivityIndicator, View } from 'react-native';
|
||||||
import FastImage from 'react-native-fast-image';
|
import FastImage from 'react-native-fast-image';
|
||||||
import LinearGradient from 'react-native-linear-gradient';
|
import LinearGradient from 'react-native-linear-gradient';
|
||||||
|
import { artistArtAtomFamily } from '../../state/music';
|
||||||
import colors from '../../styles/colors';
|
import colors from '../../styles/colors';
|
||||||
import CoverArt from './CoverArt';
|
import CoverArt from './CoverArt';
|
||||||
|
|
||||||
const PlaceholderContainer: React.FC<{
|
interface ArtistArtSizeProps {
|
||||||
height: number,
|
height: number;
|
||||||
width: number,
|
width: number;
|
||||||
}> = ({ height, width, children}) => (
|
};
|
||||||
|
|
||||||
|
interface ArtistArtXUpProps extends ArtistArtSizeProps {
|
||||||
|
coverArtUris: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ArtistArtProps extends ArtistArtSizeProps {
|
||||||
|
id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PlaceholderContainer: React.FC<ArtistArtSizeProps> = ({ height, width, children }) => (
|
||||||
<LinearGradient
|
<LinearGradient
|
||||||
colors={[colors.accent, colors.accentLow]}
|
colors={[colors.accent, colors.accentLow]}
|
||||||
style={{
|
style={{
|
||||||
@ -21,11 +34,7 @@ const PlaceholderContainer: React.FC<{
|
|||||||
</LinearGradient>
|
</LinearGradient>
|
||||||
);
|
);
|
||||||
|
|
||||||
const FourUp: React.FC<{
|
const FourUp: React.FC<ArtistArtXUpProps> = ({ height, width, coverArtUris }) => {
|
||||||
height: number,
|
|
||||||
width: number,
|
|
||||||
coverArtUris: string[];
|
|
||||||
}> = ({ height, width, coverArtUris }) => {
|
|
||||||
const halfHeight = height / 2;
|
const halfHeight = height / 2;
|
||||||
const halfWidth = width / 2;
|
const halfWidth = width / 2;
|
||||||
|
|
||||||
@ -59,11 +68,7 @@ const FourUp: React.FC<{
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const ThreeUp: React.FC<{
|
const ThreeUp: React.FC<ArtistArtXUpProps> = ({ height, width, coverArtUris }) => {
|
||||||
height: number,
|
|
||||||
width: number,
|
|
||||||
coverArtUris: string[];
|
|
||||||
}> = ({ height, width, coverArtUris }) => {
|
|
||||||
const halfHeight = height / 2;
|
const halfHeight = height / 2;
|
||||||
const halfWidth = width / 2;
|
const halfWidth = width / 2;
|
||||||
|
|
||||||
@ -92,11 +97,7 @@ const ThreeUp: React.FC<{
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const TwoUp: React.FC<{
|
const TwoUp: React.FC<ArtistArtXUpProps> = ({ height, width, coverArtUris }) => {
|
||||||
height: number,
|
|
||||||
width: number,
|
|
||||||
coverArtUris: string[];
|
|
||||||
}> = ({ height, width, coverArtUris }) => {
|
|
||||||
const halfHeight = height / 2;
|
const halfHeight = height / 2;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -119,11 +120,7 @@ const TwoUp: React.FC<{
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const OneUp: React.FC<{
|
const OneUp: React.FC<ArtistArtXUpProps> = ({ height, width, coverArtUris }) => {
|
||||||
height: number,
|
|
||||||
width: number,
|
|
||||||
coverArtUris: string[];
|
|
||||||
}> = ({ height, width, coverArtUris }) => {
|
|
||||||
return (
|
return (
|
||||||
<PlaceholderContainer height={height} width={width}>
|
<PlaceholderContainer height={height} width={width}>
|
||||||
<FastImage
|
<FastImage
|
||||||
@ -135,10 +132,7 @@ const OneUp: React.FC<{
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const NoneUp: React.FC<{
|
const NoneUp: React.FC<ArtistArtSizeProps> = ({ height, width }) => {
|
||||||
height: number,
|
|
||||||
width: number,
|
|
||||||
}> = ({ height, width }) => {
|
|
||||||
return (
|
return (
|
||||||
<PlaceholderContainer height={height} width={width}>
|
<PlaceholderContainer height={height} width={width}>
|
||||||
<FastImage
|
<FastImage
|
||||||
@ -153,26 +147,31 @@ const NoneUp: React.FC<{
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const ArtistArt: React.FC<{
|
const ArtistArt: React.FC<ArtistArtProps> = ({ id, height, width }) => {
|
||||||
height: number,
|
const artistArt = useAtomValue(artistArtAtomFamily(id));
|
||||||
width: number,
|
|
||||||
mediumImageUrl?: string;
|
|
||||||
coverArtUris?: string[]
|
|
||||||
}> = ({ height, width, mediumImageUrl, coverArtUris }) => {
|
|
||||||
const Placeholder = () => {
|
const Placeholder = () => {
|
||||||
if (coverArtUris && coverArtUris.length >= 4) {
|
const none = <NoneUp height={height} width={width} />;
|
||||||
|
|
||||||
|
if (!artistArt || !artistArt.coverArtUris) {
|
||||||
|
return none;
|
||||||
|
}
|
||||||
|
const { coverArtUris } = artistArt;
|
||||||
|
|
||||||
|
if (coverArtUris.length >= 4) {
|
||||||
return <FourUp height={height} width={width} coverArtUris={coverArtUris} />;
|
return <FourUp height={height} width={width} coverArtUris={coverArtUris} />;
|
||||||
}
|
}
|
||||||
if (coverArtUris && coverArtUris.length === 3) {
|
if (coverArtUris.length === 3) {
|
||||||
return <ThreeUp height={height} width={width} coverArtUris={coverArtUris} />;
|
return <ThreeUp height={height} width={width} coverArtUris={coverArtUris} />;
|
||||||
}
|
}
|
||||||
if (coverArtUris && coverArtUris.length === 2) {
|
if (coverArtUris.length === 2) {
|
||||||
return <TwoUp height={height} width={width} coverArtUris={coverArtUris} />;
|
return <TwoUp height={height} width={width} coverArtUris={coverArtUris} />;
|
||||||
}
|
}
|
||||||
if (coverArtUris && coverArtUris.length === 1) {
|
if (coverArtUris.length === 1) {
|
||||||
return <OneUp height={height} width={width} coverArtUris={coverArtUris} />;
|
return <OneUp height={height} width={width} coverArtUris={coverArtUris} />;
|
||||||
}
|
}
|
||||||
return <NoneUp height={height} width={width} />;
|
|
||||||
|
return none;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -184,10 +183,26 @@ const ArtistArt: React.FC<{
|
|||||||
PlaceholderComponent={Placeholder}
|
PlaceholderComponent={Placeholder}
|
||||||
height={height}
|
height={height}
|
||||||
width={width}
|
width={width}
|
||||||
coverArtUri={mediumImageUrl}
|
coverArtUri={artistArt?.uri}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default React.memo(ArtistArt);
|
const ArtistArtFallback: React.FC<ArtistArtProps> = ({ height, width }) => (
|
||||||
|
<View style={{
|
||||||
|
height, width,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}>
|
||||||
|
<ActivityIndicator size='small' color={colors.accent} />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
|
||||||
|
const ArtistArtLoader: React.FC<ArtistArtProps> = (props) => (
|
||||||
|
<React.Suspense fallback={<ArtistArtFallback { ...props } />}>
|
||||||
|
<ArtistArt { ...props } />
|
||||||
|
</React.Suspense>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default React.memo(ArtistArtLoader);
|
||||||
|
|||||||
@ -25,12 +25,7 @@ const ArtistDetails: React.FC<{ id: string }> = ({ id }) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Text style={text.paragraph}>{artist.name}</Text>
|
<Text style={text.paragraph}>{artist.name}</Text>
|
||||||
<ArtistArt
|
<ArtistArt id={artist.id} height={200} width={200} />
|
||||||
height={200}
|
|
||||||
width={200}
|
|
||||||
mediumImageUrl={artist.mediumImageUrl}
|
|
||||||
coverArtUris={artist.coverArtUris}
|
|
||||||
/>
|
|
||||||
</GradientScrollView>
|
</GradientScrollView>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,10 +10,9 @@ import GradientFlatList from '../common/GradientFlatList';
|
|||||||
|
|
||||||
const AlbumItem: React.FC<{
|
const AlbumItem: React.FC<{
|
||||||
id: string;
|
id: string;
|
||||||
name: string,
|
name: string;
|
||||||
artist?: string,
|
artist?: string;
|
||||||
coverArtUri?: string
|
}> = ({ id, name, artist, }) => {
|
||||||
} > = ({ id, name, artist, coverArtUri }) => {
|
|
||||||
const navigation = useNavigation();
|
const navigation = useNavigation();
|
||||||
|
|
||||||
const size = 125;
|
const size = 125;
|
||||||
@ -27,11 +26,7 @@ const AlbumItem: React.FC<{
|
|||||||
}}
|
}}
|
||||||
onPress={() => navigation.navigate('AlbumView', { id, title: name })}
|
onPress={() => navigation.navigate('AlbumView', { id, title: name })}
|
||||||
>
|
>
|
||||||
<AlbumArt
|
<AlbumArt id={id} height={size} width={size} />
|
||||||
width={size}
|
|
||||||
height={size}
|
|
||||||
coverArtUri={coverArtUri}
|
|
||||||
/>
|
|
||||||
<View style={{
|
<View style={{
|
||||||
flex: 1,
|
flex: 1,
|
||||||
width: size,
|
width: size,
|
||||||
@ -58,7 +53,7 @@ const AlbumItem: React.FC<{
|
|||||||
const MemoAlbumItem = React.memo(AlbumItem);
|
const MemoAlbumItem = React.memo(AlbumItem);
|
||||||
|
|
||||||
const AlbumListRenderItem: React.FC<{ item: Album }> = ({ item }) => (
|
const AlbumListRenderItem: React.FC<{ item: Album }> = ({ item }) => (
|
||||||
<MemoAlbumItem id={item.id} name={item.name} artist={item.artist} coverArtUri={item.coverArtThumbUri} />
|
<MemoAlbumItem id={item.id} name={item.name} artist={item.artist} />
|
||||||
);
|
);
|
||||||
|
|
||||||
const AlbumsList = () => {
|
const AlbumsList = () => {
|
||||||
|
|||||||
@ -11,7 +11,6 @@ import GradientFlatList from '../common/GradientFlatList';
|
|||||||
|
|
||||||
const ArtistItem: React.FC<{ item: Artist }> = ({ item }) => {
|
const ArtistItem: React.FC<{ item: Artist }> = ({ item }) => {
|
||||||
const navigation = useNavigation();
|
const navigation = useNavigation();
|
||||||
const artistInfo = useAtomValue(artistInfoAtomFamily(item.id));
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Pressable
|
<Pressable
|
||||||
@ -23,19 +22,7 @@ const ArtistItem: React.FC<{ item: Artist }> = ({ item }) => {
|
|||||||
}}
|
}}
|
||||||
onPress={() => navigation.navigate('ArtistView', { id: item.id, title: item.name })}
|
onPress={() => navigation.navigate('ArtistView', { id: item.id, title: item.name })}
|
||||||
>
|
>
|
||||||
<ArtistArt
|
<ArtistArt id={item.id} width={56} height={56} />
|
||||||
width={56}
|
|
||||||
height={56}
|
|
||||||
mediumImageUrl={artistInfo?.mediumImageUrl}
|
|
||||||
coverArtUris={artistInfo?.coverArtUris}
|
|
||||||
/>
|
|
||||||
{/* <Image
|
|
||||||
source={{ uri: 'https://reactnative.dev/img/tiny_logo.png' }}
|
|
||||||
style={{
|
|
||||||
width: 56,
|
|
||||||
height: 56,
|
|
||||||
}}
|
|
||||||
/> */}
|
|
||||||
<Text style={{
|
<Text style={{
|
||||||
...textStyles.paragraph,
|
...textStyles.paragraph,
|
||||||
marginLeft: 12,
|
marginLeft: 12,
|
||||||
|
|||||||
@ -61,16 +61,12 @@ export const useSetQueue = () => {
|
|||||||
const tracks1 = tracks.slice(0, playIndex);
|
const tracks1 = tracks.slice(0, playIndex);
|
||||||
const tracks2 = tracks.slice(playIndex);
|
const tracks2 = tracks.slice(playIndex);
|
||||||
|
|
||||||
console.log('tracks1: ' + JSON.stringify(tracks1.map(t => t.title)));
|
|
||||||
console.log('tracks2: ' + JSON.stringify(tracks2.map(t => t.title)));
|
|
||||||
|
|
||||||
await TrackPlayer.add(tracks2);
|
await TrackPlayer.add(tracks2);
|
||||||
await TrackPlayer.play();
|
await TrackPlayer.play();
|
||||||
|
|
||||||
await TrackPlayer.add(tracks1, playId);
|
await TrackPlayer.add(tracks1, playId);
|
||||||
|
|
||||||
const queue = await TrackPlayer.getQueue();
|
const queue = await TrackPlayer.getQueue();
|
||||||
console.log('queue: ' + JSON.stringify(queue.map(t => t.title)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,11 @@ export interface ArtistInfo extends Artist {
|
|||||||
coverArtUris: string[];
|
coverArtUris: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ArtistArt {
|
||||||
|
uri?: string;
|
||||||
|
coverArtUris: string[];
|
||||||
|
}
|
||||||
|
|
||||||
export interface Album {
|
export interface Album {
|
||||||
id: string;
|
id: string;
|
||||||
artistId?: string;
|
artistId?: string;
|
||||||
@ -24,6 +29,11 @@ export interface Album {
|
|||||||
year?: number;
|
year?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AlbumArt {
|
||||||
|
uri?: string;
|
||||||
|
thumbUri?: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface AlbumWithSongs extends Album {
|
export interface AlbumWithSongs extends Album {
|
||||||
songs: Song[];
|
songs: Song[];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { atom, useAtom } from 'jotai';
|
import { atom, useAtom } from 'jotai';
|
||||||
import { atomFamily, useAtomValue, useUpdateAtom } from 'jotai/utils';
|
import { atomFamily, useAtomValue, useUpdateAtom } from 'jotai/utils';
|
||||||
import { Album as Album, AlbumWithSongs, Artist, ArtistInfo, Song } from '../models/music';
|
import { Album, AlbumArt, AlbumWithSongs, Artist, ArtistArt, ArtistInfo, Song } from '../models/music';
|
||||||
import { SubsonicApiClient } from '../subsonic/api';
|
import { SubsonicApiClient } from '../subsonic/api';
|
||||||
import { AlbumID3Element, ArtistID3Element, ArtistInfo2Element, ChildElement } from '../subsonic/elements';
|
import { AlbumID3Element, ArtistID3Element, ArtistInfo2Element, ChildElement } from '../subsonic/elements';
|
||||||
import { GetArtistResponse } from '../subsonic/responses';
|
import { GetArtistResponse } from '../subsonic/responses';
|
||||||
@ -73,6 +73,26 @@ export const albumAtomFamily = atomFamily((id: string) => atom<AlbumWithSongs |
|
|||||||
return mapAlbumID3WithSongs(response.data.album, response.data.songs, client);
|
return mapAlbumID3WithSongs(response.data.album, response.data.songs, client);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
export const albumArtAtomFamily = atomFamily((id: string) => atom<AlbumArt | undefined>(async (get) => {
|
||||||
|
const server = get(activeServerAtom);
|
||||||
|
if (!server) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const albums = get(albumsAtom);
|
||||||
|
const album = albums.find(a => a.id === id);
|
||||||
|
if (!album) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = new SubsonicApiClient(server);
|
||||||
|
|
||||||
|
return {
|
||||||
|
uri: album.coverArt ? client.getCoverArtUri({ id: album.coverArt }) : undefined,
|
||||||
|
thumbUri: album.coverArt ? client.getCoverArtUri({ id: album.coverArt, size: '256' }) : undefined,
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
|
||||||
export const artistInfoAtomFamily = atomFamily((id: string) => atom<ArtistInfo | undefined>(async (get) => {
|
export const artistInfoAtomFamily = atomFamily((id: string) => atom<ArtistInfo | undefined>(async (get) => {
|
||||||
const server = get(activeServerAtom);
|
const server = get(activeServerAtom);
|
||||||
if (!server) {
|
if (!server) {
|
||||||
@ -87,6 +107,29 @@ export const artistInfoAtomFamily = atomFamily((id: string) => atom<ArtistInfo |
|
|||||||
return mapArtistInfo(artistResponse.data, artistInfoResponse.data.artistInfo, client);
|
return mapArtistInfo(artistResponse.data, artistInfoResponse.data.artistInfo, client);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
export const artistArtAtomFamily = atomFamily((id: string) => atom<ArtistArt | undefined>(async (get) => {
|
||||||
|
const artistInfo = get(artistInfoAtomFamily(id));
|
||||||
|
if (!artistInfo) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const coverArtUris = artistInfo.albums
|
||||||
|
.filter(a => a.coverArtThumbUri !== undefined)
|
||||||
|
.sort((a, b) => {
|
||||||
|
if (b.year && a.year) {
|
||||||
|
return b.year - a.year;
|
||||||
|
} else {
|
||||||
|
return a.name.localeCompare(b.name) - 9000;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map(a => a.coverArtThumbUri) as string[];
|
||||||
|
|
||||||
|
return {
|
||||||
|
coverArtUris,
|
||||||
|
uri: artistInfo.mediumImageUrl,
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
|
||||||
function mapArtistInfo(
|
function mapArtistInfo(
|
||||||
artistResponse: GetArtistResponse,
|
artistResponse: GetArtistResponse,
|
||||||
artistInfo: ArtistInfo2Element,
|
artistInfo: ArtistInfo2Element,
|
||||||
|
|||||||
@ -100,7 +100,7 @@ export class SubsonicApiClient {
|
|||||||
const response = await fetch(this.buildUrl(method, params));
|
const response = await fetch(this.buildUrl(method, params));
|
||||||
const text = await response.text();
|
const text = await response.text();
|
||||||
|
|
||||||
console.log(text);
|
// console.log(text);
|
||||||
|
|
||||||
const xml = new DOMParser().parseFromString(text);
|
const xml = new DOMParser().parseFromString(text);
|
||||||
if (xml.documentElement.getAttribute('status') !== 'ok') {
|
if (xml.documentElement.getAttribute('status') !== 'ok') {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user