mirror of
https://github.com/austinried/subtracks.git
synced 2025-12-29 09:29:29 +01:00
refactored music mapping into state
easier to access client/settings
This commit is contained in:
parent
faabe00c7e
commit
88d0c6089e
@ -1,14 +1,3 @@
|
|||||||
import { SubsonicApiClient } from '@app/subsonic/api'
|
|
||||||
import {
|
|
||||||
AlbumID3Element,
|
|
||||||
ArtistID3Element,
|
|
||||||
ArtistInfo2Element,
|
|
||||||
ChildElement,
|
|
||||||
PlaylistElement,
|
|
||||||
PlaylistWithSongsElement,
|
|
||||||
} from '@app/subsonic/elements'
|
|
||||||
import { GetArtistResponse } from '@app/subsonic/responses'
|
|
||||||
|
|
||||||
export interface Artist {
|
export interface Artist {
|
||||||
itemType: 'artist'
|
itemType: 'artist'
|
||||||
id: string
|
id: string
|
||||||
@ -115,97 +104,3 @@ export type DownloadedArtist = Artist & {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type DownloadedSong = Song
|
export type DownloadedSong = Song
|
||||||
|
|
||||||
export function mapArtistID3toArtist(artist: ArtistID3Element): Artist {
|
|
||||||
return {
|
|
||||||
itemType: 'artist',
|
|
||||||
id: artist.id,
|
|
||||||
name: artist.name,
|
|
||||||
starred: artist.starred,
|
|
||||||
coverArt: artist.coverArt,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapArtistInfo(
|
|
||||||
artistResponse: GetArtistResponse,
|
|
||||||
info: ArtistInfo2Element,
|
|
||||||
topSongs: ChildElement[],
|
|
||||||
client: SubsonicApiClient,
|
|
||||||
): ArtistInfo {
|
|
||||||
const { artist, albums } = artistResponse
|
|
||||||
|
|
||||||
const mappedAlbums = albums.map(mapAlbumID3toAlbum)
|
|
||||||
|
|
||||||
return {
|
|
||||||
...mapArtistID3toArtist(artist),
|
|
||||||
albums: mappedAlbums,
|
|
||||||
largeImageUrl: info.largeImageUrl,
|
|
||||||
topSongs: topSongs.map(s => mapChildToSong(s, client)).slice(0, 5),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapAlbumID3toAlbumListItem(album: AlbumID3Element): AlbumListItem {
|
|
||||||
return {
|
|
||||||
itemType: 'album',
|
|
||||||
id: album.id,
|
|
||||||
name: album.name,
|
|
||||||
artist: album.artist,
|
|
||||||
artistId: album.artistId,
|
|
||||||
starred: album.starred,
|
|
||||||
coverArt: album.coverArt,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapAlbumID3toAlbum(album: AlbumID3Element): Album {
|
|
||||||
return {
|
|
||||||
...mapAlbumID3toAlbumListItem(album),
|
|
||||||
coverArt: album.coverArt,
|
|
||||||
year: album.year,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapChildToSong(child: ChildElement, client: SubsonicApiClient): Song {
|
|
||||||
return {
|
|
||||||
itemType: 'song',
|
|
||||||
id: child.id,
|
|
||||||
album: child.album,
|
|
||||||
albumId: child.albumId,
|
|
||||||
artist: child.artist,
|
|
||||||
artistId: child.artistId,
|
|
||||||
title: child.title,
|
|
||||||
track: child.track,
|
|
||||||
duration: child.duration,
|
|
||||||
starred: child.starred,
|
|
||||||
coverArt: child.coverArt,
|
|
||||||
streamUri: client.streamUri({ id: child.id }),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapAlbumID3WithSongstoAlbumWithSongs(
|
|
||||||
album: AlbumID3Element,
|
|
||||||
songs: ChildElement[],
|
|
||||||
client: SubsonicApiClient,
|
|
||||||
): AlbumWithSongs {
|
|
||||||
return {
|
|
||||||
...mapAlbumID3toAlbum(album),
|
|
||||||
songs: songs.map(s => mapChildToSong(s, client)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapPlaylistListItem(playlist: PlaylistElement): PlaylistListItem {
|
|
||||||
return {
|
|
||||||
itemType: 'playlist',
|
|
||||||
id: playlist.id,
|
|
||||||
name: playlist.name,
|
|
||||||
comment: playlist.comment,
|
|
||||||
coverArt: playlist.coverArt,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapPlaylistWithSongs(playlist: PlaylistWithSongsElement, client: SubsonicApiClient): PlaylistWithSongs {
|
|
||||||
return {
|
|
||||||
...mapPlaylistListItem(playlist),
|
|
||||||
songs: playlist.songs.map(s => mapChildToSong(s, client)),
|
|
||||||
coverArt: playlist.coverArt,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -4,17 +4,9 @@ import {
|
|||||||
Artist,
|
Artist,
|
||||||
ArtistInfo,
|
ArtistInfo,
|
||||||
HomeLists,
|
HomeLists,
|
||||||
mapAlbumID3toAlbumListItem,
|
|
||||||
mapAlbumID3WithSongstoAlbumWithSongs,
|
|
||||||
mapArtistID3toArtist,
|
|
||||||
mapArtistInfo,
|
|
||||||
mapChildToSong,
|
|
||||||
mapPlaylistListItem,
|
|
||||||
mapPlaylistWithSongs,
|
|
||||||
PlaylistListItem,
|
PlaylistListItem,
|
||||||
PlaylistWithSongs,
|
PlaylistWithSongs,
|
||||||
SearchResults,
|
SearchResults,
|
||||||
Song,
|
|
||||||
StarrableItemType,
|
StarrableItemType,
|
||||||
} from '@app/models/music'
|
} from '@app/models/music'
|
||||||
import { Store } from '@app/state/store'
|
import { Store } from '@app/state/store'
|
||||||
@ -72,7 +64,6 @@ export type MusicSlice = {
|
|||||||
albumIdCoverArtRequests: { [id: string]: Promise<void> }
|
albumIdCoverArtRequests: { [id: string]: Promise<void> }
|
||||||
fetchAlbumCoverArt: (id: string) => Promise<void>
|
fetchAlbumCoverArt: (id: string) => Promise<void>
|
||||||
getAlbumCoverArt: (id: string | undefined) => Promise<string | undefined>
|
getAlbumCoverArt: (id: string | undefined) => Promise<string | undefined>
|
||||||
mapSongCoverArtFromAlbum: (songs: Song[]) => Promise<Song[]>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const selectMusic = {
|
export const selectMusic = {
|
||||||
@ -133,15 +124,12 @@ export const createMusicSlice = (set: SetState<Store>, get: GetState<Store>): Mu
|
|||||||
client.getArtistInfo2({ id }),
|
client.getArtistInfo2({ id }),
|
||||||
])
|
])
|
||||||
const topSongsResponse = await client.getTopSongs({ artist: artistResponse.data.artist.name, count: 50 })
|
const topSongsResponse = await client.getTopSongs({ artist: artistResponse.data.artist.name, count: 50 })
|
||||||
const artistInfo = mapArtistInfo(
|
const artistInfo = await get().mapArtistInfo(
|
||||||
artistResponse.data,
|
artistResponse.data,
|
||||||
artistInfoResponse.data.artistInfo,
|
artistInfoResponse.data.artistInfo,
|
||||||
topSongsResponse.data.songs,
|
topSongsResponse.data.songs,
|
||||||
client,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
artistInfo.topSongs = await get().mapSongCoverArtFromAlbum(artistInfo.topSongs)
|
|
||||||
|
|
||||||
set(
|
set(
|
||||||
produce<MusicSlice>(state => {
|
produce<MusicSlice>(state => {
|
||||||
state.artistInfo[id] = artistInfo
|
state.artistInfo[id] = artistInfo
|
||||||
@ -167,9 +155,7 @@ export const createMusicSlice = (set: SetState<Store>, get: GetState<Store>): Mu
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await client.getAlbum({ id })
|
const response = await client.getAlbum({ id })
|
||||||
const album = mapAlbumID3WithSongstoAlbumWithSongs(response.data.album, response.data.songs, client)
|
const album = await get().mapAlbumID3WithSongstoAlbumWithSongs(response.data.album, response.data.songs)
|
||||||
|
|
||||||
album.songs = await get().mapSongCoverArtFromAlbum(album.songs)
|
|
||||||
|
|
||||||
set(
|
set(
|
||||||
produce<MusicSlice>(state => {
|
produce<MusicSlice>(state => {
|
||||||
@ -194,9 +180,7 @@ export const createMusicSlice = (set: SetState<Store>, get: GetState<Store>): Mu
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await client.getPlaylist({ id })
|
const response = await client.getPlaylist({ id })
|
||||||
const playlist = mapPlaylistWithSongs(response.data.playlist, client)
|
const playlist = await get().mapPlaylistWithSongs(response.data.playlist)
|
||||||
|
|
||||||
playlist.songs = await get().mapSongCoverArtFromAlbum(playlist.songs)
|
|
||||||
|
|
||||||
set(
|
set(
|
||||||
produce<MusicSlice>(state => {
|
produce<MusicSlice>(state => {
|
||||||
@ -226,9 +210,11 @@ export const createMusicSlice = (set: SetState<Store>, get: GetState<Store>): Mu
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await client.getArtists()
|
const response = await client.getArtists()
|
||||||
|
const artists = response.data.artists.map(get().mapArtistID3toArtist)
|
||||||
|
|
||||||
set(
|
set(
|
||||||
produce<MusicSlice>(state => {
|
produce<MusicSlice>(state => {
|
||||||
state.artists = response.data.artists.map(mapArtistID3toArtist)
|
state.artists = artists
|
||||||
state.starredArtists = reduceStarred(state.starredArtists, state.artists)
|
state.starredArtists = reduceStarred(state.starredArtists, state.artists)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@ -253,7 +239,8 @@ export const createMusicSlice = (set: SetState<Store>, get: GetState<Store>): Mu
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await client.getPlaylists()
|
const response = await client.getPlaylists()
|
||||||
set({ playlists: response.data.playlists.map(mapPlaylistListItem) })
|
const playlists = response.data.playlists.map(get().mapPlaylistListItem)
|
||||||
|
set({ playlists })
|
||||||
} finally {
|
} finally {
|
||||||
set({ playlistsUpdating: false })
|
set({ playlistsUpdating: false })
|
||||||
}
|
}
|
||||||
@ -275,9 +262,10 @@ export const createMusicSlice = (set: SetState<Store>, get: GetState<Store>): Mu
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await client.getAlbumList2({ type: 'alphabeticalByArtist', size, offset })
|
const response = await client.getAlbumList2({ type: 'alphabeticalByArtist', size, offset })
|
||||||
|
const albums = response.data.albums.map(get().mapAlbumID3toAlbumListItem)
|
||||||
set(
|
set(
|
||||||
produce<MusicSlice>(state => {
|
produce<MusicSlice>(state => {
|
||||||
state.albums = response.data.albums.map(mapAlbumID3toAlbumListItem)
|
state.albums = albums
|
||||||
state.starredAlbums = reduceStarred(state.starredAlbums, state.albums)
|
state.starredAlbums = reduceStarred(state.starredAlbums, state.albums)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@ -311,14 +299,14 @@ export const createMusicSlice = (set: SetState<Store>, get: GetState<Store>): Mu
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await client.search3({ query })
|
const response = await client.search3({ query })
|
||||||
const songs = await get().mapSongCoverArtFromAlbum(response.data.songs.map(a => mapChildToSong(a, client)))
|
|
||||||
|
const artists = response.data.artists.map(get().mapArtistID3toArtist)
|
||||||
|
const albums = response.data.albums.map(get().mapAlbumID3toAlbumListItem)
|
||||||
|
const songs = await get().mapChildrenToSongs(response.data.songs)
|
||||||
|
|
||||||
set(
|
set(
|
||||||
produce<MusicSlice>(state => {
|
produce<MusicSlice>(state => {
|
||||||
state.searchResults = {
|
state.searchResults = { artists, albums, songs }
|
||||||
artists: response.data.artists.map(mapArtistID3toArtist),
|
|
||||||
albums: response.data.albums.map(mapAlbumID3toAlbumListItem),
|
|
||||||
songs: songs,
|
|
||||||
}
|
|
||||||
state.starredSongs = reduceStarred(state.starredSongs, state.searchResults.songs)
|
state.starredSongs = reduceStarred(state.starredSongs, state.searchResults.songs)
|
||||||
state.starredArtists = reduceStarred(state.starredArtists, state.searchResults.artists)
|
state.starredArtists = reduceStarred(state.starredArtists, state.searchResults.artists)
|
||||||
state.starredAlbums = reduceStarred(state.starredAlbums, state.searchResults.albums)
|
state.starredAlbums = reduceStarred(state.starredAlbums, state.searchResults.albums)
|
||||||
@ -359,9 +347,10 @@ export const createMusicSlice = (set: SetState<Store>, get: GetState<Store>): Mu
|
|||||||
for (const type of types) {
|
for (const type of types) {
|
||||||
promises.push(
|
promises.push(
|
||||||
client.getAlbumList2({ type: type as GetAlbumList2Type, size: 20 }).then(response => {
|
client.getAlbumList2({ type: type as GetAlbumList2Type, size: 20 }).then(response => {
|
||||||
|
const list = response.data.albums.map(get().mapAlbumID3toAlbumListItem)
|
||||||
set(
|
set(
|
||||||
produce<MusicSlice>(state => {
|
produce<MusicSlice>(state => {
|
||||||
state.homeLists[type] = response.data.albums.map(mapAlbumID3toAlbumListItem)
|
state.homeLists[type] = list
|
||||||
state.starredAlbums = reduceStarred(state.starredAlbums, state.homeLists[type])
|
state.starredAlbums = reduceStarred(state.starredAlbums, state.homeLists[type])
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
@ -492,15 +481,4 @@ export const createMusicSlice = (set: SetState<Store>, get: GetState<Store>): Mu
|
|||||||
await get().fetchAlbumCoverArt(id)
|
await get().fetchAlbumCoverArt(id)
|
||||||
return get().albumIdCoverArt[id]
|
return get().albumIdCoverArt[id]
|
||||||
},
|
},
|
||||||
|
|
||||||
mapSongCoverArtFromAlbum: async songs => {
|
|
||||||
const mapped: Song[] = []
|
|
||||||
for (const s of songs) {
|
|
||||||
mapped.push({
|
|
||||||
...s,
|
|
||||||
coverArt: await get().getAlbumCoverArt(s.albumId),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
return mapped
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
|||||||
142
app/state/musicmap.ts
Normal file
142
app/state/musicmap.ts
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
import {
|
||||||
|
AlbumListItem,
|
||||||
|
AlbumWithSongs,
|
||||||
|
Artist,
|
||||||
|
ArtistInfo,
|
||||||
|
PlaylistListItem,
|
||||||
|
PlaylistWithSongs,
|
||||||
|
Song,
|
||||||
|
} from '@app/models/music'
|
||||||
|
import {
|
||||||
|
AlbumID3Element,
|
||||||
|
ArtistID3Element,
|
||||||
|
ArtistInfo2Element,
|
||||||
|
ChildElement,
|
||||||
|
PlaylistElement,
|
||||||
|
PlaylistWithSongsElement,
|
||||||
|
} from '@app/subsonic/elements'
|
||||||
|
import { GetArtistResponse } from '@app/subsonic/responses'
|
||||||
|
import { GetState, SetState } from 'zustand'
|
||||||
|
import { Store } from './store'
|
||||||
|
|
||||||
|
export type MusicMapSlice = {
|
||||||
|
mapChildToSong: (child: ChildElement) => Promise<Song>
|
||||||
|
mapChildrenToSongs: (children: ChildElement[]) => Promise<Song[]>
|
||||||
|
mapArtistID3toArtist: (artist: ArtistID3Element) => Artist
|
||||||
|
mapArtistInfo: (
|
||||||
|
artistResponse: GetArtistResponse,
|
||||||
|
info: ArtistInfo2Element,
|
||||||
|
topSongs: ChildElement[],
|
||||||
|
) => Promise<ArtistInfo>
|
||||||
|
mapAlbumID3toAlbumListItem: (album: AlbumID3Element) => AlbumListItem
|
||||||
|
mapAlbumID3toAlbum: (album: AlbumID3Element) => AlbumListItem
|
||||||
|
mapAlbumID3WithSongstoAlbumWithSongs: (album: AlbumID3Element, songs: ChildElement[]) => Promise<AlbumWithSongs>
|
||||||
|
mapPlaylistListItem: (playlist: PlaylistElement) => PlaylistListItem
|
||||||
|
mapPlaylistWithSongs: (playlist: PlaylistWithSongsElement) => Promise<PlaylistWithSongs>
|
||||||
|
}
|
||||||
|
|
||||||
|
class NoClientError extends Error {
|
||||||
|
constructor() {
|
||||||
|
super('no client in state')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const createMusicMapSlice = (set: SetState<Store>, get: GetState<Store>): MusicMapSlice => ({
|
||||||
|
mapChildToSong: async child => {
|
||||||
|
const client = get().client
|
||||||
|
if (!client) {
|
||||||
|
throw new NoClientError()
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
itemType: 'song',
|
||||||
|
id: child.id,
|
||||||
|
album: child.album,
|
||||||
|
albumId: child.albumId,
|
||||||
|
artist: child.artist,
|
||||||
|
artistId: child.artistId,
|
||||||
|
title: child.title,
|
||||||
|
track: child.track,
|
||||||
|
duration: child.duration,
|
||||||
|
starred: child.starred,
|
||||||
|
coverArt: await get().getAlbumCoverArt(child.albumId),
|
||||||
|
streamUri: client.streamUri({ id: child.id }),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mapChildrenToSongs: async children => {
|
||||||
|
const songMaps: Promise<Song>[] = []
|
||||||
|
for (const child of children) {
|
||||||
|
songMaps.push(get().mapChildToSong(child))
|
||||||
|
}
|
||||||
|
return await Promise.all(songMaps)
|
||||||
|
},
|
||||||
|
|
||||||
|
mapArtistID3toArtist: artist => {
|
||||||
|
return {
|
||||||
|
itemType: 'artist',
|
||||||
|
id: artist.id,
|
||||||
|
name: artist.name,
|
||||||
|
starred: artist.starred,
|
||||||
|
coverArt: artist.coverArt,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mapArtistInfo: async (artistResponse, info, topSongs) => {
|
||||||
|
const { artist, albums } = artistResponse
|
||||||
|
|
||||||
|
const mappedAlbums = albums.map(get().mapAlbumID3toAlbum)
|
||||||
|
|
||||||
|
return {
|
||||||
|
...get().mapArtistID3toArtist(artist),
|
||||||
|
albums: mappedAlbums,
|
||||||
|
largeImageUrl: info.largeImageUrl,
|
||||||
|
topSongs: (await get().mapChildrenToSongs(topSongs)).slice(0, 5),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mapAlbumID3toAlbumListItem: album => {
|
||||||
|
return {
|
||||||
|
itemType: 'album',
|
||||||
|
id: album.id,
|
||||||
|
name: album.name,
|
||||||
|
artist: album.artist,
|
||||||
|
artistId: album.artistId,
|
||||||
|
starred: album.starred,
|
||||||
|
coverArt: album.coverArt,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mapAlbumID3toAlbum: album => {
|
||||||
|
return {
|
||||||
|
...get().mapAlbumID3toAlbumListItem(album),
|
||||||
|
coverArt: album.coverArt,
|
||||||
|
year: album.year,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mapAlbumID3WithSongstoAlbumWithSongs: async (album, songs) => {
|
||||||
|
return {
|
||||||
|
...get().mapAlbumID3toAlbum(album),
|
||||||
|
songs: await get().mapChildrenToSongs(songs),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mapPlaylistListItem: playlist => {
|
||||||
|
return {
|
||||||
|
itemType: 'playlist',
|
||||||
|
id: playlist.id,
|
||||||
|
name: playlist.name,
|
||||||
|
comment: playlist.comment,
|
||||||
|
coverArt: playlist.coverArt,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mapPlaylistWithSongs: async playlist => {
|
||||||
|
return {
|
||||||
|
...get().mapPlaylistListItem(playlist),
|
||||||
|
songs: await get().mapChildrenToSongs(playlist.songs),
|
||||||
|
coverArt: playlist.coverArt,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
@ -4,10 +4,12 @@ import AsyncStorage from '@react-native-async-storage/async-storage'
|
|||||||
import create from 'zustand'
|
import create from 'zustand'
|
||||||
import { persist, StateStorage } from 'zustand/middleware'
|
import { persist, StateStorage } from 'zustand/middleware'
|
||||||
import { CacheSlice, createCacheSlice } from './cache'
|
import { CacheSlice, createCacheSlice } from './cache'
|
||||||
|
import { createMusicMapSlice, MusicMapSlice } from './musicmap'
|
||||||
import { createTrackPlayerSlice, TrackPlayerSlice } from './trackplayer'
|
import { createTrackPlayerSlice, TrackPlayerSlice } from './trackplayer'
|
||||||
|
|
||||||
export type Store = SettingsSlice &
|
export type Store = SettingsSlice &
|
||||||
MusicSlice &
|
MusicSlice &
|
||||||
|
MusicMapSlice &
|
||||||
TrackPlayerSlice &
|
TrackPlayerSlice &
|
||||||
CacheSlice & {
|
CacheSlice & {
|
||||||
hydrated: boolean
|
hydrated: boolean
|
||||||
@ -37,6 +39,7 @@ export const useStore = create<Store>(
|
|||||||
(set, get) => ({
|
(set, get) => ({
|
||||||
...createSettingsSlice(set, get),
|
...createSettingsSlice(set, get),
|
||||||
...createMusicSlice(set, get),
|
...createMusicSlice(set, get),
|
||||||
|
...createMusicMapSlice(set, get),
|
||||||
...createTrackPlayerSlice(set, get),
|
...createTrackPlayerSlice(set, get),
|
||||||
...createCacheSlice(set, get),
|
...createCacheSlice(set, get),
|
||||||
|
|
||||||
|
|||||||
@ -1,54 +0,0 @@
|
|||||||
import AsyncStorage from '@react-native-async-storage/async-storage'
|
|
||||||
|
|
||||||
export async function getItem(key: string): Promise<any | null> {
|
|
||||||
try {
|
|
||||||
const item = await AsyncStorage.getItem(key)
|
|
||||||
return item ? JSON.parse(item) : null
|
|
||||||
} catch (e) {
|
|
||||||
console.error(`getItem error (key: ${key})`, e)
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function multiGet(keys: string[]): Promise<[string, any | null][]> {
|
|
||||||
try {
|
|
||||||
const items = await AsyncStorage.multiGet(keys)
|
|
||||||
return items.map(x => [x[0], x[1] ? JSON.parse(x[1]) : null])
|
|
||||||
} catch (e) {
|
|
||||||
console.error('multiGet error', e)
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function setItem(key: string, item: any): Promise<void> {
|
|
||||||
try {
|
|
||||||
await AsyncStorage.setItem(key, JSON.stringify(item))
|
|
||||||
} catch (e) {
|
|
||||||
console.error(`setItem error (key: ${key})`, e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function multiSet(items: string[][]): Promise<void> {
|
|
||||||
try {
|
|
||||||
await AsyncStorage.multiSet(items.map(x => [x[0], JSON.stringify(x[1])]))
|
|
||||||
} catch (e) {
|
|
||||||
console.error('multiSet error', e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getAllKeys(): Promise<string[]> {
|
|
||||||
try {
|
|
||||||
return await AsyncStorage.getAllKeys()
|
|
||||||
} catch (e) {
|
|
||||||
console.error('getAllKeys error', e)
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function multiRemove(keys: string[]): Promise<void> {
|
|
||||||
try {
|
|
||||||
await AsyncStorage.multiRemove(keys)
|
|
||||||
} catch (e) {
|
|
||||||
console.error('multiRemove error', e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,38 +0,0 @@
|
|||||||
import { DownloadedSong } from '@app/models/music'
|
|
||||||
import { getItem, multiGet, multiSet } from '@app/storage/asyncstorage'
|
|
||||||
|
|
||||||
const key = {
|
|
||||||
downloadedSongKeys: '@downloadedSongKeys',
|
|
||||||
downloadedAlbumKeys: '@downloadedAlbumKeys',
|
|
||||||
downloadedArtistKeys: '@downloadedArtistKeys',
|
|
||||||
downloadedPlaylistKeys: '@downloadedPlaylistKeys',
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getDownloadedSongs(): Promise<DownloadedSong[]> {
|
|
||||||
const keysItem = await getItem(key.downloadedSongKeys)
|
|
||||||
const keys: string[] = keysItem ? JSON.parse(keysItem) : []
|
|
||||||
|
|
||||||
const items = await multiGet(keys)
|
|
||||||
return items.map(x => {
|
|
||||||
const parsed = JSON.parse(x[1] as string)
|
|
||||||
return {
|
|
||||||
id: x[0],
|
|
||||||
type: 'song',
|
|
||||||
...parsed,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function setDownloadedSongs(items: DownloadedSong[]): Promise<void> {
|
|
||||||
await multiSet([
|
|
||||||
[key.downloadedSongKeys, JSON.stringify(items.map(x => x.id))],
|
|
||||||
...items.map(x => [
|
|
||||||
x.id,
|
|
||||||
JSON.stringify({
|
|
||||||
name: x.name,
|
|
||||||
album: x.album,
|
|
||||||
artist: x.artist,
|
|
||||||
}),
|
|
||||||
]),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user