mirror of
https://github.com/austinried/subtracks.git
synced 2025-12-28 17:19:27 +01:00
remove/disable download options
This commit is contained in:
parent
d72258c68e
commit
ad25972774
@ -13,7 +13,7 @@ import FastImage from 'react-native-fast-image'
|
|||||||
import { Menu, MenuOption, MenuOptions, MenuTrigger, renderers } from 'react-native-popup-menu'
|
import { Menu, MenuOption, MenuOptions, MenuTrigger, renderers } from 'react-native-popup-menu'
|
||||||
import IconFA from 'react-native-vector-icons/FontAwesome'
|
import IconFA from 'react-native-vector-icons/FontAwesome'
|
||||||
import IconFA5 from 'react-native-vector-icons/FontAwesome5'
|
import IconFA5 from 'react-native-vector-icons/FontAwesome5'
|
||||||
import IconMat from 'react-native-vector-icons/MaterialIcons'
|
// import IconMat from 'react-native-vector-icons/MaterialIcons'
|
||||||
import CoverArt from './CoverArt'
|
import CoverArt from './CoverArt'
|
||||||
import Star from './Star'
|
import Star from './Star'
|
||||||
|
|
||||||
@ -200,11 +200,11 @@ const OptionViewAlbum = React.memo<{
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const OptionDownload = React.memo<{
|
// const OptionDownload = React.memo<{
|
||||||
itemType: string
|
// itemType: string
|
||||||
}>(({ itemType }) => (
|
// }>(({ itemType }) => (
|
||||||
<ContextMenuIconTextOption IconComponent={IconMat} name="file-download" size={26} text={`Download ${itemType}`} />
|
// <ContextMenuIconTextOption IconComponent={IconMat} name="file-download" size={26} text={`Download ${itemType}`} />
|
||||||
))
|
// ))
|
||||||
|
|
||||||
export type AlbumContextPressableProps = ContextMenuProps & {
|
export type AlbumContextPressableProps = ContextMenuProps & {
|
||||||
album: AlbumListItem
|
album: AlbumListItem
|
||||||
@ -222,7 +222,7 @@ export const AlbumContextPressable: React.FC<AlbumContextPressableProps> = props
|
|||||||
<>
|
<>
|
||||||
<OptionStar id={album.id} type={album.itemType} />
|
<OptionStar id={album.id} type={album.itemType} />
|
||||||
<OptionViewArtist artist={album.artist} artistId={album.artistId} navigation={navigation} />
|
<OptionViewArtist artist={album.artist} artistId={album.artistId} navigation={navigation} />
|
||||||
<OptionDownload itemType={album.itemType} />
|
{/* <OptionDownload itemType={album.itemType} /> */}
|
||||||
</>
|
</>
|
||||||
}>
|
}>
|
||||||
{children}
|
{children}
|
||||||
@ -247,7 +247,7 @@ export const SongContextPressable: React.FC<SongContextPressableProps> = props =
|
|||||||
<OptionStar id={song.id} type={song.itemType} />
|
<OptionStar id={song.id} type={song.itemType} />
|
||||||
<OptionViewArtist artist={song.artist} artistId={song.artistId} navigation={navigation} />
|
<OptionViewArtist artist={song.artist} artistId={song.artistId} navigation={navigation} />
|
||||||
<OptionViewAlbum album={song.album} albumId={song.albumId} navigation={navigation} />
|
<OptionViewAlbum album={song.album} albumId={song.albumId} navigation={navigation} />
|
||||||
<OptionDownload itemType={song.itemType} />
|
{/* <OptionDownload itemType={song.itemType} /> */}
|
||||||
</>
|
</>
|
||||||
}>
|
}>
|
||||||
{children}
|
{children}
|
||||||
@ -269,7 +269,7 @@ export const ArtistContextPressable: React.FC<ArtistContextPressableProps> = pro
|
|||||||
menuOptions={
|
menuOptions={
|
||||||
<>
|
<>
|
||||||
<OptionStar id={artist.id} type={artist.itemType} />
|
<OptionStar id={artist.id} type={artist.itemType} />
|
||||||
<OptionDownload itemType={artist.itemType} />
|
{/* <OptionDownload itemType={artist.itemType} /> */}
|
||||||
</>
|
</>
|
||||||
}>
|
}>
|
||||||
{children}
|
{children}
|
||||||
|
|||||||
@ -18,6 +18,7 @@ const ImageGradientBackground: React.FC<{
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function getColors() {
|
async function getColors() {
|
||||||
|
console.log(`imagePath: ${imagePath}`)
|
||||||
if (imagePath === undefined) {
|
if (imagePath === undefined) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -26,6 +27,7 @@ const ImageGradientBackground: React.FC<{
|
|||||||
|
|
||||||
let res: AndroidImageColors
|
let res: AndroidImageColors
|
||||||
if (cachedResult) {
|
if (cachedResult) {
|
||||||
|
console.log(`cachedResult: ${JSON.stringify(cachedResult)}`)
|
||||||
res = cachedResult as AndroidImageColors
|
res = cachedResult as AndroidImageColors
|
||||||
} else {
|
} else {
|
||||||
const path = `file://${imagePath}`
|
const path = `file://${imagePath}`
|
||||||
@ -33,12 +35,21 @@ const ImageGradientBackground: React.FC<{
|
|||||||
cache: true,
|
cache: true,
|
||||||
key: imagePath,
|
key: imagePath,
|
||||||
})) as AndroidImageColors
|
})) as AndroidImageColors
|
||||||
|
console.log(`res: ${JSON.stringify(res)}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.muted && res.muted !== '#000000') {
|
if (res.muted && res.muted !== '#000000') {
|
||||||
setHighColor(res.muted)
|
setHighColor(res.muted)
|
||||||
} else if (res.darkMuted && res.darkMuted !== '#000000') {
|
} else if (res.darkMuted && res.darkMuted !== '#000000') {
|
||||||
setHighColor(res.darkMuted)
|
setHighColor(res.darkMuted)
|
||||||
|
} else if (res.lightMuted && res.lightMuted !== '#000000') {
|
||||||
|
setHighColor(res.lightMuted)
|
||||||
|
} else if (res.vibrant && res.vibrant !== '#000000') {
|
||||||
|
setHighColor(res.vibrant)
|
||||||
|
} else if (res.darkVibrant && res.darkVibrant !== '#000000') {
|
||||||
|
setHighColor(res.darkVibrant)
|
||||||
|
} else if (res.lightVibrant && res.lightVibrant !== '#000000') {
|
||||||
|
setHighColor(res.lightVibrant)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getColors()
|
getColors()
|
||||||
|
|||||||
@ -26,12 +26,10 @@ const TitleTextSong = React.memo<{
|
|||||||
return (
|
return (
|
||||||
<View style={styles.textLine}>
|
<View style={styles.textLine}>
|
||||||
<Text style={[styles.title, { color: playing ? colors.accent : colors.text.primary }]}>
|
<Text style={[styles.title, { color: playing ? colors.accent : colors.text.primary }]}>
|
||||||
{playing ? (
|
{playing && (
|
||||||
<View style={styles.playingIcon}>
|
<View style={styles.playingIcon}>
|
||||||
<IconFA5 name="play" size={9} color={colors.accent} />
|
<IconFA5 name="play" size={9} color={colors.accent} />
|
||||||
</View>
|
</View>
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}
|
)}
|
||||||
{title}
|
{title}
|
||||||
</Text>
|
</Text>
|
||||||
@ -159,35 +157,29 @@ const ListItem: React.FC<{
|
|||||||
return (
|
return (
|
||||||
<View style={[styles.container, sizeStyle.container]}>
|
<View style={[styles.container, sizeStyle.container]}>
|
||||||
<PressableComponent>
|
<PressableComponent>
|
||||||
{showArt ? coverArt : <></>}
|
{showArt && coverArt}
|
||||||
<View style={styles.text}>
|
<View style={styles.text}>
|
||||||
{title}
|
{title}
|
||||||
{subtitle ? (
|
{subtitle !== undefined && (
|
||||||
<View style={styles.textLine}>
|
<View style={styles.textLine}>
|
||||||
{starred ? (
|
{false && (
|
||||||
<IconMat
|
<IconMat
|
||||||
name="file-download-done"
|
name="file-download-done"
|
||||||
size={17}
|
size={17}
|
||||||
color={colors.text.secondary}
|
color={colors.text.secondary}
|
||||||
style={styles.downloadedIcon}
|
style={styles.downloadedIcon}
|
||||||
/>
|
/>
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}
|
)}
|
||||||
<Text style={styles.subtitle}>{subtitle}</Text>
|
<Text style={styles.subtitle}>{subtitle}</Text>
|
||||||
</View>
|
</View>
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</PressableComponent>
|
</PressableComponent>
|
||||||
<View style={styles.controls}>
|
<View style={styles.controls}>
|
||||||
{showStar ? (
|
{showStar && (
|
||||||
<PressableOpacity onPress={toggleStarred} style={styles.controlItem}>
|
<PressableOpacity onPress={toggleStarred} style={styles.controlItem}>
|
||||||
<Star size={26} starred={starred} />
|
<Star size={26} starred={starred} />
|
||||||
</PressableOpacity>
|
</PressableOpacity>
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|||||||
@ -22,7 +22,10 @@ const ListPlayerControls = React.memo<{
|
|||||||
return (
|
return (
|
||||||
<View style={[styles.controls, style]}>
|
<View style={[styles.controls, style]}>
|
||||||
<View style={styles.controlsSide}>
|
<View style={styles.controlsSide}>
|
||||||
<Button buttonStyle={downloaded ? 'highlight' : 'hollow'} onPress={() => setDownloaded(!downloaded)}>
|
<Button
|
||||||
|
disabled={true}
|
||||||
|
buttonStyle={downloaded ? 'highlight' : 'hollow'}
|
||||||
|
onPress={() => setDownloaded(!downloaded)}>
|
||||||
{downloaded ? (
|
{downloaded ? (
|
||||||
<IconMat name="file-download-done" size={26} color={colors.text.primary} />
|
<IconMat name="file-download-done" size={26} color={colors.text.primary} />
|
||||||
) : (
|
) : (
|
||||||
|
|||||||
@ -106,10 +106,6 @@ export const useCoverArtFile = (coverArt: string = '-1') => {
|
|||||||
}
|
}
|
||||||
}, [cacheItem, client, coverArt, file])
|
}, [cacheItem, client, coverArt, file])
|
||||||
|
|
||||||
// if (file && request && request.promise !== undefined) {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
return { file, request }
|
return { file, request }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,9 +121,5 @@ export const useArtistArtFile = (artistId: string) => {
|
|||||||
}
|
}
|
||||||
}, [artistId, artistInfo, artistInfo?.largeImageUrl, cacheItem, file])
|
}, [artistId, artistInfo, artistInfo?.largeImageUrl, cacheItem, file])
|
||||||
|
|
||||||
// if (file && request && request.promise !== undefined) {
|
|
||||||
// return
|
|
||||||
// }
|
|
||||||
|
|
||||||
return { file, request }
|
return { file, request }
|
||||||
}
|
}
|
||||||
|
|||||||
@ -191,7 +191,7 @@ export const useSetQueue = () => {
|
|||||||
const getQueueShuffled = useCallback(() => !!useStore.getState().shuffleOrder, [])
|
const getQueueShuffled = useCallback(() => !!useStore.getState().shuffleOrder, [])
|
||||||
const setQueueContextType = useStore(selectTrackPlayer.setQueueContextType)
|
const setQueueContextType = useStore(selectTrackPlayer.setQueueContextType)
|
||||||
const setQueueContextId = useStore(selectTrackPlayer.setQueueContextId)
|
const setQueueContextId = useStore(selectTrackPlayer.setQueueContextId)
|
||||||
const getCoverArtPath = useStore(selectCache.getCoverArtPath)
|
const fetchCoverArtFilePath = useStore(selectCache.fetchCoverArtFilePath)
|
||||||
|
|
||||||
return async (
|
return async (
|
||||||
songs: Song[],
|
songs: Song[],
|
||||||
@ -217,7 +217,7 @@ export const useSetQueue = () => {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
coverArtPaths[s.coverArt] = await getCoverArtPath(s.coverArt)
|
coverArtPaths[s.coverArt] = await fetchCoverArtFilePath(s.coverArt)
|
||||||
}
|
}
|
||||||
|
|
||||||
let queue = songs.map(s => mapSongToTrack(s, coverArtPaths))
|
let queue = songs.map(s => mapSongToTrack(s, coverArtPaths))
|
||||||
|
|||||||
@ -5,7 +5,8 @@ import RNFS from 'react-native-fs'
|
|||||||
import { GetState, SetState } from 'zustand'
|
import { GetState, SetState } from 'zustand'
|
||||||
import { Store } from './store'
|
import { Store } from './store'
|
||||||
|
|
||||||
const imageDownloadQueue = new PromiseQueue(10)
|
const imageDownloadQueue = new PromiseQueue(20)
|
||||||
|
const songDownloadQueue = new PromiseQueue(1)
|
||||||
|
|
||||||
export type CacheDownload = CacheFile & CacheRequest
|
export type CacheDownload = CacheFile & CacheRequest
|
||||||
|
|
||||||
@ -13,7 +14,7 @@ export type CacheDirsByServer = Record<string, Record<CacheItemTypeKey, string>>
|
|||||||
export type CacheFilesByServer = Record<string, Record<CacheItemTypeKey, Record<string, CacheFile>>>
|
export type CacheFilesByServer = Record<string, Record<CacheItemTypeKey, Record<string, CacheFile>>>
|
||||||
export type CacheRequestsByServer = Record<string, Record<CacheItemTypeKey, Record<string, CacheRequest>>>
|
export type CacheRequestsByServer = Record<string, Record<CacheItemTypeKey, Record<string, CacheRequest>>>
|
||||||
|
|
||||||
// export type CacheItemsDb = Record<
|
// export type DownloadedItemsByServer = Record<
|
||||||
// string,
|
// string,
|
||||||
// {
|
// {
|
||||||
// songs: { [songId: string]: DownloadedSong }
|
// songs: { [songId: string]: DownloadedSong }
|
||||||
@ -26,22 +27,30 @@ export type CacheRequestsByServer = Record<string, Record<CacheItemTypeKey, Reco
|
|||||||
export type CacheSlice = {
|
export type CacheSlice = {
|
||||||
cacheItem: (key: CacheItemTypeKey, itemId: string, url: string | (() => string | Promise<string>)) => Promise<void>
|
cacheItem: (key: CacheItemTypeKey, itemId: string, url: string | (() => string | Promise<string>)) => Promise<void>
|
||||||
|
|
||||||
// cache: CacheItemsDb
|
// cache: DownloadedItemsByServer
|
||||||
cacheDirs: CacheDirsByServer
|
cacheDirs: CacheDirsByServer
|
||||||
cacheFiles: CacheFilesByServer
|
cacheFiles: CacheFilesByServer
|
||||||
cacheRequests: CacheRequestsByServer
|
cacheRequests: CacheRequestsByServer
|
||||||
|
|
||||||
getCoverArtPath: (coverArt: string) => Promise<string | undefined>
|
fetchCoverArtFilePath: (coverArt: string) => Promise<string | undefined>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const selectCache = {
|
export const selectCache = {
|
||||||
cacheItem: (store: CacheSlice) => store.cacheItem,
|
cacheItem: (store: CacheSlice) => store.cacheItem,
|
||||||
getCoverArtPath: (store: CacheSlice) => store.getCoverArtPath,
|
fetchCoverArtFilePath: (store: CacheSlice) => store.fetchCoverArtFilePath,
|
||||||
|
|
||||||
|
songCacheDir: (store: Store) => {
|
||||||
|
const activeServerId = store.settings.activeServer
|
||||||
|
if (!activeServerId) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
return store.cacheDirs[activeServerId].song
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createCacheSlice = (set: SetState<Store>, get: GetState<Store>): CacheSlice => ({
|
export const createCacheSlice = (set: SetState<Store>, get: GetState<Store>): CacheSlice => ({
|
||||||
// cache: {},
|
// cache: {},
|
||||||
|
|
||||||
cacheDirs: {},
|
cacheDirs: {},
|
||||||
cacheFiles: {},
|
cacheFiles: {},
|
||||||
cacheRequests: {},
|
cacheRequests: {},
|
||||||
@ -58,12 +67,8 @@ export const createCacheSlice = (set: SetState<Store>, get: GetState<Store>): Ca
|
|||||||
}
|
}
|
||||||
|
|
||||||
const inProgress = get().cacheRequests[activeServerId][key][itemId]
|
const inProgress = get().cacheRequests[activeServerId][key][itemId]
|
||||||
if (inProgress) {
|
if (inProgress && inProgress.promise !== undefined) {
|
||||||
if (inProgress.promise !== undefined) {
|
return await inProgress.promise
|
||||||
return await inProgress.promise
|
|
||||||
} else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const existing = get().cacheFiles[activeServerId][key][itemId]
|
const existing = get().cacheFiles[activeServerId][key][itemId]
|
||||||
@ -75,22 +80,41 @@ export const createCacheSlice = (set: SetState<Store>, get: GetState<Store>): Ca
|
|||||||
const urlResult = typeof url === 'string' ? url : url()
|
const urlResult = typeof url === 'string' ? url : url()
|
||||||
const fromUrl = typeof urlResult === 'string' ? urlResult : await urlResult
|
const fromUrl = typeof urlResult === 'string' ? urlResult : await urlResult
|
||||||
|
|
||||||
const promise = imageDownloadQueue
|
const queue = key === 'song' ? songDownloadQueue : imageDownloadQueue
|
||||||
.enqueue(
|
|
||||||
() =>
|
const promise = queue.enqueue(() =>
|
||||||
RNFS.downloadFile({
|
RNFS.downloadFile({
|
||||||
fromUrl,
|
fromUrl,
|
||||||
toFile: path,
|
toFile: path,
|
||||||
}).promise,
|
progressInterval: 100,
|
||||||
)
|
progress: res => {
|
||||||
.then(() => {
|
set(
|
||||||
set(
|
produce<CacheSlice>(state => {
|
||||||
produce<CacheSlice>(state => {
|
state.cacheRequests[activeServerId][key][itemId].progress = Math.max(
|
||||||
state.cacheRequests[activeServerId][key][itemId].progress = 1
|
1,
|
||||||
delete state.cacheRequests[activeServerId][key][itemId].promise
|
res.bytesWritten / (res.contentLength || 1),
|
||||||
}),
|
)
|
||||||
)
|
}),
|
||||||
|
)
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
.promise.then(() => {
|
||||||
|
set(
|
||||||
|
produce<CacheSlice>(state => {
|
||||||
|
state.cacheRequests[activeServerId][key][itemId].progress = 1
|
||||||
|
delete state.cacheRequests[activeServerId][key][itemId].promise
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
set(
|
||||||
|
produce<CacheSlice>(state => {
|
||||||
|
delete state.cacheFiles[activeServerId][key][itemId]
|
||||||
|
delete state.cacheRequests[activeServerId][key][itemId]
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
}),
|
||||||
|
)
|
||||||
set(
|
set(
|
||||||
produce<Store>(state => {
|
produce<Store>(state => {
|
||||||
state.cacheFiles[activeServerId][key][itemId] = {
|
state.cacheFiles[activeServerId][key][itemId] = {
|
||||||
@ -107,7 +131,7 @@ export const createCacheSlice = (set: SetState<Store>, get: GetState<Store>): Ca
|
|||||||
return await promise
|
return await promise
|
||||||
},
|
},
|
||||||
|
|
||||||
getCoverArtPath: async coverArt => {
|
fetchCoverArtFilePath: async coverArt => {
|
||||||
const client = get().client
|
const client = get().client
|
||||||
if (!client) {
|
if (!client) {
|
||||||
return
|
return
|
||||||
@ -128,6 +152,6 @@ export const createCacheSlice = (set: SetState<Store>, get: GetState<Store>): Ca
|
|||||||
}
|
}
|
||||||
|
|
||||||
await get().cacheItem('coverArt', coverArt, () => client.getCoverArtUri({ id: coverArt }))
|
await get().cacheItem('coverArt', coverArt, () => client.getCoverArtUri({ id: coverArt }))
|
||||||
return get().cacheFiles[activeServerId].coverArt[coverArt].path
|
return `file://${get().cacheFiles[activeServerId].coverArt[coverArt].path}`
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user